個人的な課題として、Ruby で SIMON ブロック暗号を実装しようとしています。データを操作するための最良の方法を見つける際に、いくつかの問題に直面しています。この質問に関連する完全なコードは、https ://github.com/Rami114/Personal/blob/master/Simon/Simon.rb にあります。
SIMON には、XOR、シフト、および循環シフトの両方の操作が必要です。最後の操作では BigNums を使用する必要があるため、バイト配列でより複雑で低速な二重ループではなく、数学で左循環シフトを実行できます。
文字列を BigNum に変換して元に戻すより良い方法はありますか。
String -> BigNum (N は 64、pt は平文の文字列)
pt = pt.chars.each_slice(N/8).map {|x| x.join.unpack('b*')[0].to_i(2)}.to_a
そこで、文字列を個々の文字に分割し、N サイズの配列 (SIMON のワード サイズ) にスライスし、各セットを BigNum にアンパックします。それはうまく機能しているようで、元に戻すことができます。
現在、私の SIMON コードは現在壊れていますが、それは私が考えている/望んでいる数学であり、コードではありません。逆変換は次のとおりです (ct は暗号文を表す bignum の配列です)。
ct.map { |x| [x.to_s(2).rjust(128,'0')].pack('b*') }.join
bignum は幅が定義されていないため、文字列を右揃えにする必要があるようです。そのため、先頭に 0 がありません。残念ながら、パックでは、適切な出力を得るために定義された with が必要です。
これは有効な変換方法ですか? より良い方法はありますか?どちらの数もわかりませんが、ここの誰かが助けてくれることを願っています。
E: @torimus の場合、私が使用している循環シフトの実装 (上記のリンクから)
def self.lcs (bytes, block_size, shift)
((bytes << shift) | (bytes >> (block_size - shift))) & ((1<< block_size)-1)
end