strict-flower

aes.rb

Jan 8th, 2019
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 4.07 KB | None | 0 0
  1. =begin
  2. Copyright 2018 strict-flower
  3.  
  4. Permission is hereby granted, free of charge, to any person obtaining a
  5. copy of this software and associated documentation files (the "Software"),
  6. to deal in the Software without restriction, including without limitation
  7. the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. and/or sell copies of the Software, and to permit persons to whom the
  9. Software is furnished to do so, subject to the following conditions:
  10.  
  11. The above copyright notice and this permission notice shall be included in
  12. all copies or substantial portions of the Software.
  13.  
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. IN THE SOFTWARE.
  21. =end
  22.  
  23. require_relative './aes_table' # https://pastebin.com/UWLstSg8
  24. require 'matrix'
  25.  
  26. # Galois field implementation (simple ver)
  27. class Fixnum
  28.   alias_method :integer_add, :+
  29.   alias_method :integer_sub, :-
  30.   alias_method :integer_mul, :*
  31.   alias_method :integer_div, :/
  32.  
  33.   def +(other)
  34.     self ^ other.to_i
  35.   end
  36.  
  37.   def -(other)
  38.     self + other
  39.   end
  40.  
  41.   def -@
  42.     self
  43.   end
  44.  
  45.   def /(other)
  46.     raise 1 # assertion
  47.   end
  48.  
  49.   def *(other)
  50.     if self == 0
  51.       0
  52.     elsif self == 1
  53.       other
  54.     else
  55.       other = other.to_i
  56.       if other == 0
  57.         0
  58.       elsif other == 1
  59.         self
  60.       else
  61.         if $mult_table.keys.include?(other)
  62.           $mult_table[other][self]
  63.         elsif $mult_table.keys.include?(self)
  64.           $mult_table[self][other]
  65.         else
  66.           raise "Invalid Argument"
  67.         end
  68.       end
  69.     end
  70.   end
  71. end
  72.  
  73. class AESMatrix < Matrix
  74.   def self.to_mat(data)
  75.     data = data.to_a
  76.     raise unless data.length == 16
  77.     AESMatrix.columns(data.each_slice(4).to_a)
  78.   end
  79.  
  80.   def to_a
  81.     t.rows.flatten
  82.   end
  83. end
  84.  
  85. def SubBytes(t)
  86.   t.map{|x| $sbox[x]}
  87. end
  88.  
  89. def SubBytesInv(t)
  90.   t.map{|x| $sboxinv[x]}
  91. end
  92.  
  93. $P = AESMatrix.to_mat([2, 1, 1, 3, 3, 2, 1, 1, 1, 3, 2, 1, 1, 1, 3, 2])
  94. $PInv = AESMatrix.to_mat([14, 9, 13, 11, 11, 14, 9, 13, 13, 11, 14, 9, 9, 13, 11, 14])
  95.  
  96. def MixColumns(t)
  97.   t * $P
  98. end
  99.  
  100. def MixColumnsInv(t)
  101.   t * $PInv
  102. end
  103.  
  104. def ShiftRows(t)
  105.   m = t[0, 0..3]
  106.   m << t[1, 1..3]
  107.   m << t[1, 0]
  108.   m << t[2, 2..3]
  109.   m << t[2, 0..1]
  110.   m << t[3, 3..3]
  111.   m << t[3, 0..2]
  112.   m.flatten!
  113.   AESMatrix.rows(m.each_slice(4).to_a)
  114. end
  115.  
  116. def ShiftRowsInv(t)
  117.   m = t[0, 0..3]
  118.   m << t[1, 3]
  119.   m << t[1, 0..2]
  120.   m << t[2, 2..3]
  121.   m << t[2, 0..1]
  122.   m << t[3, 1..3]
  123.   m << t[3, 0]
  124.   m.flatten!
  125.   AESMatrix.rows(m.each_slice(4).to_a)
  126. end
  127.  
  128. def AddRoundKey(t, key)
  129.   t + key
  130. end
  131.  
  132. alias AddRoundKeyInv AddRoundKey
  133.  
  134. def RoundFunc(r, state, key)
  135.   state = SubBytes(state)
  136.   state = ShiftRows(state)
  137.   if r != $r - 1
  138.     state = MixColumns(state)
  139.   end
  140.   AddRoundKey(state, key)
  141. end
  142.  
  143. def RoundFuncInv(r, state, key)
  144.   AddRoundKeyInv(state, key)
  145.   if r != $r - 1
  146.     state = MixColumnsInv(state)
  147.   end
  148.   state = SubBytesInv(state)
  149.   ShiftRowsInv(state)
  150. end
  151.  
  152. def encrypt(m, key)
  153.   state = AESMatrix.to_mat(m)
  154.   key = AESMatrix.to_mat(key)
  155.  
  156.   state = AddRoundKey(state, key)
  157.   $r.times { |r|
  158.     state = RoundFunc(r, state, key)
  159.     puts r
  160.   }
  161.   state.to_a
  162. end
  163.  
  164. def decrypt(c, key)
  165.   state = AESMatrix.to_mat(c)
  166.   key = AESMatrix.to_mat(key)
  167.  
  168.   $r.times { |_r|
  169.     r = $r.integer_sub(_r).integer_sub(1)
  170.     state = RoundFuncInv(r, state, key)
  171.   }
  172.   AddRoundKeyInv(state, key).to_a
  173. end
  174.  
  175. $r = 10
  176. m = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
  177. k = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  178.  
  179. p encrypt(m, k)
  180. p decrypt(encrypt(m, k), k)
  181.  
  182. raise unless 1 + 1 == 0
  183. raise unless $PInv * $P == AESMatrix.I(4)
  184. raise unless $P * $PInv == AESMatrix.I(4)
  185. raise unless $P + $P == AESMatrix.zero(4)
Advertisement
Add Comment
Please, Sign In to add comment