class GostMagma::Magma

Base abstract class

Constants

BigEndian

's' stands for native-endian byte order but 'n' stands for network (big-endian) byte order

BlockLengthInBytes

class constants

KeyLengthInBytes

Protected Class Methods

decryptBlock(input, keys) click to toggle source
# File lib/gost_magma/magma.rb, line 120
def self.decryptBlock(input, keys)
  tmp_input = input.reverse
  tmp_output = decryptBlockUintKey(tmp_input, keys)
  output = tmp_output.reverse
end
decryptBlockUintKey(input, keys) click to toggle source
# File lib/gost_magma/magma.rb, line 107
def self.decryptBlockUintKey(input, keys)
  right = uint8ToUint32(input[0..3])
  left = uint8ToUint32(input[4..-1])
  right, left = decryptCycle(right, left, keys)
  output = uint32ToUint8(left) + uint32ToUint8(right)
end
decryptCycle(right, left, keys) click to toggle source
# File lib/gost_magma/magma.rb, line 80
def self.decryptCycle(right, left, keys)
  right, left = encryptRound(right, left, keys[0], keys[1])
  right, left = encryptRound(right, left, keys[2], keys[3])
  right, left = encryptRound(right, left, keys[4], keys[5])
  right, left = encryptRound(right, left, keys[6], keys[7])
  right, left = encryptRound(right, left, keys[7], keys[6])
  right, left = encryptRound(right, left, keys[5], keys[4])
  right, left = encryptRound(right, left, keys[3], keys[2])
  right, left = encryptRound(right, left, keys[1], keys[0])
  right, left = encryptRound(right, left, keys[7], keys[6])
  right, left = encryptRound(right, left, keys[5], keys[4])
  right, left = encryptRound(right, left, keys[3], keys[2])
  right, left = encryptRound(right, left, keys[1], keys[0])
  right, left = encryptRound(right, left, keys[7], keys[6])
  right, left = encryptRound(right, left, keys[5], keys[4])
  right, left = encryptRound(right, left, keys[3], keys[2])
  right, left = encryptRound(right, left, keys[1], keys[0])
  [right, left]
end
encryptBlock(input, keys) click to toggle source
# File lib/gost_magma/magma.rb, line 114
def self.encryptBlock(input, keys)
  tmp_input = input.reverse 
  tmp_output = encryptBlockUintKey(tmp_input, keys)
  output = tmp_output.reverse
end
encryptBlockUintKey(input, keys) click to toggle source
# File lib/gost_magma/magma.rb, line 100
def self.encryptBlockUintKey(input, keys)
  right = uint8ToUint32(input[0..3])
  left = uint8ToUint32(input[4..-1])
  right, left = encryptCycle(right, left, keys)
  output = uint32ToUint8(left) + uint32ToUint8(right)
end
encryptCycle(right, left, keys) click to toggle source
# File lib/gost_magma/magma.rb, line 60
def self.encryptCycle(right, left, keys)
  right, left = encryptRound(right, left, keys[0], keys[1])
  right, left = encryptRound(right, left, keys[2], keys[3])
  right, left = encryptRound(right, left, keys[4], keys[5])
  right, left = encryptRound(right, left, keys[6], keys[7])
  right, left = encryptRound(right, left, keys[0], keys[1])
  right, left = encryptRound(right, left, keys[2], keys[3])
  right, left = encryptRound(right, left, keys[4], keys[5])
  right, left = encryptRound(right, left, keys[6], keys[7])
  right, left = encryptRound(right, left, keys[0], keys[1])
  right, left = encryptRound(right, left, keys[2], keys[3])
  right, left = encryptRound(right, left, keys[4], keys[5])
  right, left = encryptRound(right, left, keys[6], keys[7])
  right, left = encryptRound(right, left, keys[7], keys[6])
  right, left = encryptRound(right, left, keys[5], keys[4])
  right, left = encryptRound(right, left, keys[3], keys[2])
  right, left = encryptRound(right, left, keys[1], keys[0])
  [right, left]
end
encryptRound(right, left, key1, key2) click to toggle source
# File lib/gost_magma/magma.rb, line 50
def self.encryptRound(right, left, key1, key2)
  t = (key1 + right) & 0xffffffff
  left ^= TzTable[0][t & 0xff] ^ TzTable[1][(t >> 8) & 0xff] ^
    TzTable[2][(t >> 16) & 0xff] ^ TzTable[3][t >> 24 & 0xff]
  t = (key2 + left) & 0xffffffff
  right ^= TzTable[0][t & 0xff] ^ TzTable[1][(t >> 8) & 0xff] ^
    TzTable[2][(t >> 16) & 0xff] ^ TzTable[3][(t >> 24) & 0xff]
  [right, left]
end
incrementModulo(counter, size) click to toggle source

Increment CTR counter

# File lib/gost_magma/magma.rb, line 127
def self.incrementModulo(counter, size)
  lastIndex = size - 1
  (0...size).each do |i|
    if counter[lastIndex - i].ord > 0xfe then  
      counter[lastIndex - i] = (counter[lastIndex - i].ord - 0xff).chr  
    else 
      counter[lastIndex - i] = (counter[lastIndex - i].ord + 1).chr 
      break 
    end  
  end
  counter
end
padd(incomplete_block) click to toggle source
# File lib/gost_magma/magma.rb, line 154
def self.padd(incomplete_block)
  padding_len = BlockLengthInBytes - (incomplete_block.length % BlockLengthInBytes)
  padded_block = incomplete_block.dup
  padded_block += 0x80.chr
  padding_len -= 1
  if padding_len > 0 then
    padded_block += 0.chr * padding_len
  end
  padded_block
end
printBytes(bytes, line_size = 16) click to toggle source
# File lib/gost_magma/magma.rb, line 13
def self.printBytes(bytes, line_size = 16)
  bytes.unpack('H*')[0].scan(/.{1,#{line_size}}/).each{|s| puts(s)}
end
shiftLeftOne(block) click to toggle source

block - byte string

# File lib/gost_magma/magma.rb, line 141
def self.shiftLeftOne(block)
  (0...(BlockLengthInBytes-1)).each do |i|
    ri1 = block[i+1].ord
    ri = block[i].ord << 1
    ri &= 0xfe
    ri |= (ri1 >> 7) & 0x1
    block[i] = ri.chr
  end
  ri = block[BlockLengthInBytes-1].ord << 1
  block[BlockLengthInBytes-1] = (ri & 0xfe).chr
  block
end
uint32ToUint8(n) click to toggle source

Unload 32-bit number to 8-byte string (native-endian, adding leading zeroes)

# File lib/gost_magma/magma.rb, line 38
def self.uint32ToUint8(n)
  bytes = uint32ToUint8BE(n)    
  bytes.reverse! unless BigEndian   
  bytes
end
uint32ToUint8BE(n) click to toggle source

Unload 32-bit number to 8-byte string (big-endian, adding leading zeroes)

# File lib/gost_magma/magma.rb, line 27
def self.uint32ToUint8BE(n)
  str = n.to_s(16) # big-endian
  len = str.length
  # add leading zeroes
  str.insert(0, '0'*(8 - len)) if len < 8
  # To byte string
  bytes = [str].pack('H*')
end
uint8ToUint32(bytes) click to toggle source

Unpacks 8-byte string to 32-bit number (native-endian)

# File lib/gost_magma/magma.rb, line 46
def self.uint8ToUint32(bytes)
  bytes.unpack('L*')[0]
end
zeroBlock() click to toggle source
# File lib/gost_magma/magma.rb, line 21
def self.zeroBlock
  ("\x00"*BlockLengthInBytes).force_encoding('BINARY')
end
zeroBytes(n) click to toggle source
# File lib/gost_magma/magma.rb, line 17
def self.zeroBytes(n)
  ("\x00"*n).force_encoding('BINARY')
end