Class: Rex::Crypto::Chacha20
- Inherits:
-
Object
- Object
- Rex::Crypto::Chacha20
- Defined in:
- lib/rex/crypto/chacha20.rb
Instance Attribute Summary collapse
-
#chacha_ctx ⇒ Object
readonly
Returns the value of attribute chacha_ctx.
Instance Method Summary collapse
- #chacha20_block_func ⇒ Object
- #chacha20_crypt(data) ⇒ Object
- #chacha20_ctx_setup(key, iv, position = 1) ⇒ Object
- #chacha20_update_ctx ⇒ Object
-
#initialize(key, iv) ⇒ Chacha20
constructor
A new instance of Chacha20.
- #quarter_round(x, a, b, c, d) ⇒ Object
- #reset_cipher(key, iv) ⇒ Object
- #rotate(v, c) ⇒ Object
Constructor Details
#initialize(key, iv) ⇒ Chacha20
Returns a new instance of Chacha20.
8 9 10 11 12 13 |
# File 'lib/rex/crypto/chacha20.rb', line 8 def initialize(key, iv) raise TypeError unless key.is_a? String raise TypeError unless iv.is_a? String @chacha_ctx = chacha20_ctx_setup(key, iv) end |
Instance Attribute Details
#chacha_ctx ⇒ Object (readonly)
Returns the value of attribute chacha_ctx.
6 7 8 |
# File 'lib/rex/crypto/chacha20.rb', line 6 def chacha_ctx @chacha_ctx end |
Instance Method Details
#chacha20_block_func ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/rex/crypto/chacha20.rb', line 56 def chacha20_block_func chacha_state = @chacha_ctx.dup (1..10).each do |round| quarter_round(chacha_state, 0, 4, 8, 12) quarter_round(chacha_state, 1, 5, 9, 13) quarter_round(chacha_state, 2, 6, 10, 14) quarter_round(chacha_state, 3, 7, 11, 15) quarter_round(chacha_state, 0, 5, 10, 15) quarter_round(chacha_state, 1, 6, 11, 12) quarter_round(chacha_state, 2, 7, 8, 13) quarter_round(chacha_state, 3, 4, 9, 14) end keystream_arr = [] (0..15).each do |index| keystream_ch = (chacha_state[index] + @chacha_ctx[index]) & 0xffffffff keystream_arr << (keystream_ch & 0xff) keystream_arr << (keystream_ch >> 8 & 0xff) keystream_arr << (keystream_ch >> 16 & 0xff) keystream_arr << (keystream_ch >> 24 & 0xff) end keystream_arr end |
#chacha20_crypt(data) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rex/crypto/chacha20.rb', line 34 def chacha20_crypt(data) num_blocks = data.length / 64 if data.length % 64 != 0 num_blocks += 1 end keystream = [] (1..num_blocks).each do |block| keystream << chacha20_block_func chacha20_update_ctx end keystream = keystream.flatten enc = [] i = 0 data.unpack("c*").each do |a| enc << (a.ord ^ keystream[i]) i += 1 end enc.pack("c*").force_encoding('ASCII-8BIT') end |
#chacha20_ctx_setup(key, iv, position = 1) ⇒ Object
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/rex/crypto/chacha20.rb', line 23 def chacha20_ctx_setup(key, iv, position=1) chacha_constants = [1634760805, 857760878, 2036477234, 1797285236] chacha_ctx = chacha_constants chacha_ctx += key.unpack('V8') chacha_ctx[12] = position chacha_ctx += iv.unpack('VVV') chacha_ctx end |
#chacha20_update_ctx ⇒ Object
19 20 21 |
# File 'lib/rex/crypto/chacha20.rb', line 19 def chacha20_update_ctx @chacha_ctx[12] = (@chacha_ctx[12] + 1) & 0xffffffff end |
#quarter_round(x, a, b, c, d) ⇒ Object
86 87 88 89 90 91 92 93 94 95 |
# File 'lib/rex/crypto/chacha20.rb', line 86 def quarter_round(x, a, b, c, d) x[a] = (x[a] + x[b]) & 0xffffffff x[d] = rotate(x[d] ^ x[a], 16) x[c] = (x[c] + x[d]) & 0xffffffff x[b] = rotate(x[b] ^ x[c], 12) x[a] = (x[a] + x[b]) & 0xffffffff x[d] = rotate(x[d] ^ x[a], 8) x[c] = (x[c] + x[d]) & 0xffffffff x[b] = rotate(x[b] ^ x[c], 7) end |
#reset_cipher(key, iv) ⇒ Object
15 16 17 |
# File 'lib/rex/crypto/chacha20.rb', line 15 def reset_cipher(key, iv) @chacha_ctx = chacha20_ctx_setup(key, iv) end |
#rotate(v, c) ⇒ Object
82 83 84 |
# File 'lib/rex/crypto/chacha20.rb', line 82 def rotate(v, c) ((v << c) & 0xffffffff) | v >> (32 - c) end |