Class: Megar::Crypto::AesCtr
- Inherits:
-
Object
- Object
- Megar::Crypto::AesCtr
- Defined in:
- lib/megar/crypto/aes_ctr.rb
Overview
Implements AES COUNTER mode using base AES CBC implementation provided by OpenSSL
Instance Attribute Summary collapse
-
#iv ⇒ Object
Returns the value of attribute iv.
-
#key ⇒ Object
Returns the value of attribute key.
Instance Method Summary collapse
-
#a32_to_str(a) ⇒ Object
TODO: refactor to pull this method from a shared lib.
- #initialize(options = {}) ⇒ AesCtr constructor
- #packing ⇒ Object
-
#str_to_a32(b, signed = true) ⇒ Object
TODO: refactor to pull this method from a shared lib.
-
#update(chunk) ⇒ Object
Returns the encrypted binary string of
chunk
(provided as binary string).
Constructor Details
#initialize(options = {}) ⇒ AesCtr
10 11 12 13 |
# File 'lib/megar/crypto/aes_ctr.rb', line 10 def initialize(={}) self.key = [:key] self.iv = [:iv] end |
Instance Attribute Details
#iv ⇒ Object
Returns the value of attribute iv.
5 6 7 |
# File 'lib/megar/crypto/aes_ctr.rb', line 5 def iv @iv end |
#key ⇒ Object
Returns the value of attribute key.
4 5 6 |
# File 'lib/megar/crypto/aes_ctr.rb', line 4 def key @key end |
Instance Method Details
#a32_to_str(a) ⇒ Object
TODO: refactor to pull this method from a shared lib.
69 70 71 72 73 |
# File 'lib/megar/crypto/aes_ctr.rb', line 69 def a32_to_str(a) b = '' (a.size * 4).times { |i| b << ((a[i>>2] >> (24-(i & 3)*8)) & 255).chr } b end |
#packing ⇒ Object
15 16 17 |
# File 'lib/megar/crypto/aes_ctr.rb', line 15 def packing 'l>*' end |
#str_to_a32(b, signed = true) ⇒ Object
TODO: refactor to pull this method from a shared lib.
58 59 60 61 62 63 64 65 66 |
# File 'lib/megar/crypto/aes_ctr.rb', line 58 def str_to_a32(b,signed=true) a = Array.new((b.length+3) >> 2,0) b.length.times { |i| a[i>>2] |= (b.getbyte(i) << (24-(i & 3)*8)) } if signed a.pack('l>*').unpack('l>*') else a end end |
#update(chunk) ⇒ Object
Returns the encrypted binary string of chunk
(provided as binary string). Repeated calls will continue the counter sequence.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/megar/crypto/aes_ctr.rb', line 29 def update(chunk) a32 = str_to_a32(chunk) last_i = 0 (0..a32.size - 3).step(4) do |i| enc = Megar::Crypto::Aes.new(key: key).encrypt(iv) 4.times do |m| a32[i+m] = (a32[i+m] || 0) ^ (enc[m] || 0) end iv[3] += 1 iv[2] += 1 if iv[3] == 0 last_i = i + 4 end remainder = a32.size % 4 if remainder > 0 v = [0, 0, 0, 0] (last_i..a32.size - 1).step(1) { |m| v[m-last_i] = a32[m] || 0 } enc = Megar::Crypto::Aes.new(key: key).encrypt(iv) 4.times { |m| v[m] = v[m] ^ enc[m] } (last_i..a32.size - 1).step(1) { |j| a32[j] = v[j - last_i] || 0 } end a32_to_str(a32)[0..chunk.size - 1] end |