class Crypt::Gost
gost.rb
Adapted by Richard Kernahan from C++ code written by Wei Dai of the Crypto++ project www.eskimo.com/~weidai/cryptlib.html
Constants
- ULONG
Public Class Methods
new(userKey)
click to toggle source
# File lib/crypt/gost.rb, line 18 def initialize(userKey) # These are the S-boxes given in Applied Cryptography 2nd Ed., p. 333 @sBox = [ [4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3], [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9], [5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11], [7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3], [6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2], [4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14], [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12], [1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12] ] # These are the S-boxes given in the GOST source code listing in Applied # Cryptography 2nd Ed., p. 644. They appear to be from the DES S-boxes # [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 ], # [ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 ], # [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 ], # [ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 ], # [ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 ], # [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 ], # [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 ], # [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 ] # precalculate the S table @sTable = precalculate_S_table() # derive the 32-byte key from the user-supplied key userKeyLength = userKey.length @key = userKey[0..31].unpack('C'*32) if (userKeyLength < 32) userKeyLength.upto(31) { @key << 0 } end end
Public Instance Methods
block_size()
click to toggle source
# File lib/crypt/gost.rb, line 13 def block_size return(8) end
decrypt_block(block)
click to toggle source
# File lib/crypt/gost.rb, line 130 def decrypt_block(block) xl, xr = block.unpack('NN') xl, xr = decrypt_pair(xl, xr) decrypted = [xl, xr].pack('NN') return(decrypted) end
decrypt_pair(xl, xr)
click to toggle source
# File lib/crypt/gost.rb, line 99 def decrypt_pair(xl, xr) xr ^= f(xl+@key[0]) xl ^= f(xr+@key[1]) xr ^= f(xl+@key[2]) xl ^= f(xr+@key[3]) xr ^= f(xl+@key[4]) xl ^= f(xr+@key[5]) xr ^= f(xl+@key[6]) xl ^= f(xr+@key[7]) 3.times { xr ^= f(xl+@key[7]) xl ^= f(xr+@key[6]) xr ^= f(xl+@key[5]) xl ^= f(xr+@key[4]) xr ^= f(xl+@key[3]) xl ^= f(xr+@key[2]) xr ^= f(xl+@key[1]) xl ^= f(xr+@key[0]) } return([xr, xl]) end
encrypt_block(block)
click to toggle source
# File lib/crypt/gost.rb, line 122 def encrypt_block(block) xl, xr = block.unpack('NN') xl, xr = encrypt_pair(xl, xr) encrypted = [xl, xr].pack('NN') return(encrypted) end
encrypt_pair(xl, xr)
click to toggle source
# File lib/crypt/gost.rb, line 76 def encrypt_pair(xl, xr) 3.times { xr ^= f(xl+@key[0]) xl ^= f(xr+@key[1]) xr ^= f(xl+@key[2]) xl ^= f(xr+@key[3]) xr ^= f(xl+@key[4]) xl ^= f(xr+@key[5]) xr ^= f(xl+@key[6]) xl ^= f(xr+@key[7]) } xr ^= f(xl+@key[7]) xl ^= f(xr+@key[6]) xr ^= f(xl+@key[5]) xl ^= f(xr+@key[4]) xr ^= f(xl+@key[3]) xl ^= f(xr+@key[2]) xr ^= f(xl+@key[1]) xl ^= f(xr+@key[0]) return([xr, xl]) end
f(longWord)
click to toggle source
# File lib/crypt/gost.rb, line 69 def f(longWord) longWord = longWord % ULONG a, b, c, d = [longWord].pack('L').unpack('CCCC') return(@sTable[3][d] ^ @sTable[2][c] ^ @sTable[1][b] ^ @sTable[0][a]) end
precalculate_S_table()
click to toggle source
# File lib/crypt/gost.rb, line 55 def precalculate_S_table() sTable = [[], [], [], []] 0.upto(3) { |i| 0.upto(255) { |j| t = @sBox[2*i][j % 16] | (@sBox[2*i+1][j/16] << 4) u = (8*i + 11) % 32 v = (t << u) | (t >> (32-u)) sTable[i][j] = (v % ULONG) } } return(sTable) end