Module: Rmega::Crypto::AesCtr
Instance Method Summary collapse
Instance Method Details
#decrypt(key, nonce, data) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/rmega/crypto/aes_ctr.rb', line 9 def decrypt(key, nonce, data) raise "invalid nonce" if nonce.size != 4 or !nonce.respond_to?(:pack) raise "invalid key" if key.size != 4 or !key.respond_to?(:pack) mac = [nonce[0], nonce[1], nonce[0], nonce[1]] enc = nil a32 = Utils.str_to_a32 data len = a32.size - 3 last_i = 0 (0..len).step(4) do |i| enc = Aes.encrypt key, nonce 4.times do |m| a32[i+m] = (a32[i+m] || 0) ^ (enc[m] || 0) mac[m] = (mac[m] || 0) ^ (a32[i+m] || 0) end mac = Aes.encrypt key, mac nonce[3] += 1 nonce[2] += 1 if nonce[3] == 0 last_i = i + 4 end if last_i < a32.size v = [0, 0, 0, 0] (last_i..a32.size - 1).step(1) { |m| v[m-last_i] = a32[m] || 0 } enc = Aes.encrypt key, nonce 4.times { |m| v[m] = v[m] ^ enc[m] } j = data.size & 15 m = Utils.str_to_a32 Array.new(j+1).join(255.chr)+Array.new(17-j).join(0.chr) 4.times { |x| mac[x] = mac[x] ^ (v[x] & m[x]) } mac = Aes.encrypt key, mac (last_i..a32.size - 1).step(1) { |j| a32[j] = v[j - last_i] || 0 } end decrypted_data = Utils.a32_to_str(a32, data.size) {data: decrypted_data, mac: mac} end |
#encrypt(key, nonce, data) ⇒ Object
53 54 55 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 81 82 83 84 85 86 87 88 |
# File 'lib/rmega/crypto/aes_ctr.rb', line 53 def encrypt(key, nonce, data) raise "invalid nonce" if nonce.size != 4 or !nonce.respond_to?(:pack) raise "invalid key" if key.size != 4 or !key.respond_to?(:pack) ctr = nonce.dup mac = [ctr[0], ctr[1], ctr[0], ctr[1]] ab32 = Utils.str_to_a32 data len = ab32.size - 3 enc = nil last_i = 0 (0..len).step(4) do |i| 4.times { |x| mac[x] = mac[x] ^ (ab32[i+x] || 0) } mac = Aes.encrypt key, mac enc = Aes.encrypt key, ctr 4.times { |x| ab32[i+x] = (ab32[i+x] || 0) ^ (enc[x] || 0) } ctr[3] += 1 ctr[2] += 1 if ctr[3].zero? last_i = i + 4 end i = last_i if i < ab32.size v = [0, 0, 0, 0] (i..ab32.size - 1).step(1) { |j| v[j - i] = ab32[j] || 0 } 4.times { |x| mac[x] = mac[x] ^ v[x] } mac = Aes.encrypt key, mac enc = Aes.encrypt key, ctr 4.times { |x| v[x] = v[x] ^ enc[x] } (i..ab32.size - 1).step(1) { |j| ab32[j] = v[j - i] || 0 } end decrypted_data = Utils.a32_to_str ab32, data.size {data: decrypted_data, mac: mac} end |