Module: JOSE::JWA::SHA3
Constant Summary collapse
- ROUNDS5 =
(0...5).to_a.freeze
- ROUNDS23 =
(0...23).to_a.freeze
- ROUNDS24 =
(0...24).to_a.freeze
- ROUNDS25 =
(0...25).to_a.freeze
- ROUNDSBY5 =
[0, 5, 10, 15, 20].freeze
- ROTATIONS =
[ 0,1,62,28,27,36,44,6,55,20,3,10,43,25,39,41,45,15, 21,8,18,2,61,56,14 ].freeze
- PERMUTATION =
[ 1,6,9,22,14,20,2,12,13,19,23,15,4,24,21,8,16,5,3, 18,17,11,7,10 ].freeze
- RC =
[ 0x0000000000000001,0x0000000000008082,0x800000000000808a, 0x8000000080008000,0x000000000000808b,0x0000000080000001, 0x8000000080008081,0x8000000000008009,0x000000000000008a, 0x0000000000000088,0x0000000080008009,0x000000008000000a, 0x000000008000808b,0x800000000000008b,0x8000000000008089, 0x8000000000008003,0x8000000000008002,0x8000000000000080, 0x000000000000800a,0x800000008000000a,0x8000000080008081, 0x8000000000008080,0x0000000080000001,0x8000000080008008 ].freeze
Instance Method Summary collapse
-
#reinterpret_to_octets(w) ⇒ Object
Reinterpret word array w to octet array and return it.
-
#reinterpret_to_words_and_xor(s, b) ⇒ Object
Reinterpret octet array b to word array and XOR it to state s.
-
#rol(x, b) ⇒ Object
Rotate a word x by b places to the left.
-
#sha3_224(msg) ⇒ Object
Implementations of actual SHA-3 functions.
- #sha3_256(msg) ⇒ Object
- #sha3_384(msg) ⇒ Object
- #sha3_512(msg) ⇒ Object
-
#sha3_raw(msg, r_w, o_p, e_b) ⇒ Object
(semi-)generic SHA-3 implementation.
-
#sha3_transform(s) ⇒ Object
Do the SHA-3 state transform on state s.
- #shake128(msg, olen) ⇒ Object
- #shake256(msg, olen) ⇒ Object
Instance Method Details
#reinterpret_to_octets(w) ⇒ Object
Reinterpret word array w to octet array and return it.
86 87 88 89 90 91 92 |
# File 'lib/jose/jwa/sha3.rb', line 86 def reinterpret_to_octets(w) mp = ''.force_encoding('BINARY') (0...(w.length)).each do |j| mp << OpenSSL::BN.new(w[j]).to_s(2).rjust(8, JOSE::JWA::ZERO_PAD).reverse end return mp end |
#reinterpret_to_words_and_xor(s, b) ⇒ Object
Reinterpret octet array b to word array and XOR it to state s.
76 77 78 79 80 81 82 83 |
# File 'lib/jose/jwa/sha3.rb', line 76 def reinterpret_to_words_and_xor(s, b) (0...(b.length/8)).each do |j| block = b[(8*j)..-1][0...8] block = block.pack(JOSE::JWA::UCHAR_PACK) if block.is_a?(Array) s[j] ^= OpenSSL::BN.new(block.reverse, 2).to_i end return s end |
#rol(x, b) ⇒ Object
Rotate a word x by b places to the left.
33 34 35 |
# File 'lib/jose/jwa/sha3.rb', line 33 def rol(x, b) return ((x << b) | (x >> (64 - b))) & (2**64-1) end |
#sha3_224(msg) ⇒ Object
Implementations of actual SHA-3 functions.
126 127 128 |
# File 'lib/jose/jwa/sha3.rb', line 126 def sha3_224(msg) return sha3_raw(msg,18,6,28) end |
#sha3_256(msg) ⇒ Object
130 131 132 |
# File 'lib/jose/jwa/sha3.rb', line 130 def sha3_256(msg) return sha3_raw(msg,17,6,32) end |
#sha3_384(msg) ⇒ Object
134 135 136 |
# File 'lib/jose/jwa/sha3.rb', line 134 def sha3_384(msg) return sha3_raw(msg,13,6,48) end |
#sha3_512(msg) ⇒ Object
138 139 140 |
# File 'lib/jose/jwa/sha3.rb', line 138 def sha3_512(msg) return sha3_raw(msg,9,6,64) end |
#sha3_raw(msg, r_w, o_p, e_b) ⇒ Object
(semi-)generic SHA-3 implementation
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/jose/jwa/sha3.rb', line 95 def sha3_raw(msg, r_w, o_p, e_b) r_b = 8 * r_w s = [0]*25 # Handle whole blocks. idx = 0 blocks = msg.bytesize / r_b (0...blocks).each do |i| reinterpret_to_words_and_xor(s, msg[idx..-1][0...r_b]) idx += r_b sha3_transform(s) end # Handle last block padding. m = msg[idx..-1].unpack(JOSE::JWA::UCHAR_PACK) m.push(o_p) while m.length < r_b m.push(0) end m[-1] |= 128 # Handle padded last block. reinterpret_to_words_and_xor(s, m) sha3_transform(s) # Output. out = ''.force_encoding('BINARY') while out.length < e_b out << reinterpret_to_octets(s[0...r_w]) sha3_transform(s) end return out[0...e_b] end |
#sha3_transform(s) ⇒ Object
Do the SHA-3 state transform on state s.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/jose/jwa/sha3.rb', line 38 def sha3_transform(s) ROUNDS24.each do |rnd| # AddColumnParity (Theta) c = [0]*5 d = [0]*5 ROUNDS25.each do |i| c[i % 5] ^= s[i] end ROUNDS5.each do |i| d[i] = c[(i+4) % 5] ^ rol(c[(i+1) % 5], 1) end ROUNDS25.each do |i| s[i] ^= d[i % 5] end # RotateWords (Rho). ROUNDS25.each do |i| s[i] = rol(s[i], ROTATIONS[i]) end # PermuteWords (Pi) t = s[PERMUTATION[0]] ROUNDS23.each do |i| s[PERMUTATION[i]] = s[PERMUTATION[i+1]] end s[PERMUTATION[-1]] = t # NonlinearMixRows (Chi) ROUNDSBY5.each do |i| t = [s[i],s[i+1],s[i+2],s[i+3],s[i+4],s[i],s[i+1]] ROUNDS5.each do |j| s[i+j] = t[j]^((~t[j+1])&(t[j+2])) end end # AddRoundConstant (Iota) s[0] ^= RC[rnd] end return s end |
#shake128(msg, olen) ⇒ Object
142 143 144 |
# File 'lib/jose/jwa/sha3.rb', line 142 def shake128(msg,olen) return sha3_raw(msg,21,31,olen) end |
#shake256(msg, olen) ⇒ Object
146 147 148 |
# File 'lib/jose/jwa/sha3.rb', line 146 def shake256(msg,olen) return sha3_raw(msg,17,31,olen) end |