Class: Crypt::Blowfish

Inherits:
Object
  • Object
show all
Includes:
BlowfishTables, CBC
Defined in:
lib/crypt/blowfish.rb

Constant Summary collapse

ULONG =
0x100000000

Constants included from BlowfishTables

Crypt::BlowfishTables::INITIALPARRAY, Crypt::BlowfishTables::INITIALSBOXES

Instance Method Summary collapse

Methods included from CBC

#carefully_open_file, #decrypt_file, #decrypt_stream, #decrypt_string, #encrypt_file, #encrypt_stream, #encrypt_string, #generate_initialization_vector

Constructor Details

#initialize(key) ⇒ Blowfish

Returns a new instance of Blowfish.



21
22
23
24
25
26
27
# File 'lib/crypt/blowfish.rb', line 21

def initialize(key)
  @key = key
  raise "Bad key length: the key must be 1-56 bytes." unless (key.length.between?(1,56))
  @p_array = []
  @s_boxes = []
  setup_blowfish()
end

Instance Method Details

#block_sizeObject



16
17
18
# File 'lib/crypt/blowfish.rb', line 16

def block_size
  return(8)
end

#decrypt_block(block) ⇒ Object



101
102
103
104
105
106
# File 'lib/crypt/blowfish.rb', line 101

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) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/crypt/blowfish.rb', line 80

def decrypt_pair(xl, xr)
  17.downto(2) { |i|
      xl = (xl ^ @p_array[i]) % ULONG
      xr = (xr ^ f(xl)) % ULONG
      xl, xr = xr, xl
  }
  xl, xr = xr, xl
  xr = (xr ^ @p_array[1]) % ULONG
  xl = (xl ^ @p_array[0]) % ULONG
  return([xl, xr])
end

#encrypt_block(block) ⇒ Object



93
94
95
96
97
98
# File 'lib/crypt/blowfish.rb', line 93

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) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/crypt/blowfish.rb', line 67

def encrypt_pair(xl, xr)
  0.upto(15) { |i|
      xl = (xl ^ @p_array[i]) % ULONG
      xr = (xr ^ f(xl)) % ULONG
      xl, xr = xr, xl
  }
  xl, xr = xr, xl
  xr = (xr ^ @p_array[16]) % ULONG
  xl = (xl ^ @p_array[17]) % ULONG
  return([xl, xr])
end

#f(x) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/crypt/blowfish.rb', line 30

def f(x)
  a, b, c, d = [x].pack('N').unpack('CCCC')
  y = (@s_boxes[0][a] + @s_boxes[1][b]) % ULONG
  y = (y ^ @s_boxes[2][c]) % ULONG
  y = (y + @s_boxes[3][d]) % ULONG
  return(y)
end

#setup_blowfishObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/crypt/blowfish.rb', line 39

def setup_blowfish()
  @s_boxes = Array.new(4) { |i| INITIALSBOXES[i].clone }
  @p_array = INITIALPARRAY.clone
  keypos = 0
  0.upto(17) { |i|
    data = 0
    4.times {
      data = ((data << 8) | @key.getbyte(keypos)) % ULONG
      keypos = (keypos.next) % @key.length
    }
    @p_array[i] = (@p_array[i] ^ data) % ULONG
  }
  l = 0
  r = 0
  0.step(17, 2) { |i|
    l, r = encrypt_pair(l, r)
    @p_array[i]   = l
    @p_array[i+1] = r
  }
  0.upto(3) { |i|
    0.step(255, 2) { |j|
      l, r = encrypt_pair(l, r)
      @s_boxes[i][j]   = l
      @s_boxes[i][j+1] = r
    }
  }
end