Class: Crypt::IDEA
- Inherits:
-
Object
show all
- Includes:
- CBC
- Defined in:
- lib/crypt/idea.rb
Constant Summary
collapse
- ULONG =
0x100000000
- USHORT =
0x10000
- ENCRYPT =
0
- DECRYPT =
1
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(key128, mode) ⇒ IDEA
Returns a new instance of IDEA.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/crypt/idea.rb', line 25
def initialize(key128, mode)
if (key128.class == String)
digest = Digest::MD5.digest(key128)
key128 = digest.unpack('n'*8)
end
raise "Key must be 128 bits (8 words)" unless (key128.class == Array) && (key128.length == 8)
raise "Mode must be IDEA::ENCRYPT or IDEA::DECRYPT" unless ((mode == ENCRYPT) | (mode == DECRYPT))
if (mode == ENCRYPT)
@subkeys = generate_encryption_subkeys(key128)
else (mode == DECRYPT)
@subkeys = generate_decryption_subkeys(key128)
end
end
|
Instance Method Details
#block_size ⇒ Object
20
21
22
|
# File 'lib/crypt/idea.rb', line 20
def block_size
return(8)
end
|
#crypt_pair(l, r) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/crypt/idea.rb', line 111
def crypt_pair(l, r)
word = [l, r].pack('NN').unpack('nnnn')
k = @subkeys[0..51]
8.downto(1) { |i|
word[0] = mul(word[0], k.shift)
word[1] = (word[1] + k.shift) % USHORT
word[2] = (word[2] + k.shift) % USHORT
word[3] = mul(word[3], k.shift)
t2 = word[0] ^ word[2]
t2 = mul(t2, k.shift)
t1 = (t2 + (word[1] ^ word[3])) % USHORT
t1 = mul(t1, k.shift)
t2 = (t1 + t2) % USHORT
word[0] ^= t1
word[3] ^= t2
t2 ^= word[1]
word[1] = word[2] ^ t1
word[2] = t2
}
result = []
result << mul(word[0], k.shift)
result << (word[2] + k.shift) % USHORT
result << (word[1] + k.shift) % USHORT
result << mul(word[3], k.shift)
two_longs = result.pack('nnnn').unpack('NN')
return(two_longs)
end
|
#decrypt_block(block) ⇒ Object
147
148
149
150
151
152
|
# File 'lib/crypt/idea.rb', line 147
def decrypt_block(block)
xl, xr = block.unpack('NN')
xl, xr = crypt_pair(xl, xr)
decrypted = [xl, xr].pack('NN')
return(decrypted)
end
|
#encrypt_block(block) ⇒ Object
139
140
141
142
143
144
|
# File 'lib/crypt/idea.rb', line 139
def encrypt_block(block)
xl, xr = block.unpack('NN')
xl, xr = crypt_pair(xl, xr)
encrypted = [xl, xr].pack('NN')
return(encrypted)
end
|
#generate_decryption_subkeys(key) ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/crypt/idea.rb', line 87
def generate_decryption_subkeys(key)
encrypt_keys = generate_encryption_subkeys(key)
decrypt_keys = []
decrypt_keys[48] = mul_inv(encrypt_keys.shift)
decrypt_keys[49] = (-encrypt_keys.shift) % USHORT
decrypt_keys[50] = (-encrypt_keys.shift) % USHORT
decrypt_keys[51] = mul_inv(encrypt_keys.shift)
42.step(0, -6) { |i|
decrypt_keys[i+4] = encrypt_keys.shift % USHORT
decrypt_keys[i+5] = encrypt_keys.shift % USHORT
decrypt_keys[i] = mul_inv(encrypt_keys.shift)
if (i ==0)
decrypt_keys[1] = (-encrypt_keys.shift) % USHORT
decrypt_keys[2] = (-encrypt_keys.shift) % USHORT
else
decrypt_keys[i+2] = (-encrypt_keys.shift) % USHORT
decrypt_keys[i+1] = (-encrypt_keys.shift) % USHORT
end
decrypt_keys[i+3] = mul_inv(encrypt_keys.shift)
}
return(decrypt_keys)
end
|
#generate_encryption_subkeys(key) ⇒ Object
75
76
77
78
79
80
81
82
83
84
|
# File 'lib/crypt/idea.rb', line 75
def generate_encryption_subkeys(key)
encrypt_keys = []
encrypt_keys[0..7] = key.dup
8.upto(51) { |i|
a = ((i + 1) % 8 > 0) ? (i-7) : (i-15)
b = ((i + 2) % 8 < 2) ? (i-14) : (i-6)
encrypt_keys[i] = ((encrypt_keys[a] << 9) | (encrypt_keys[b] >> 7)) % USHORT
}
return(encrypt_keys)
end
|
#mul(a, b) ⇒ Object
42
43
44
45
46
47
|
# File 'lib/crypt/idea.rb', line 42
def mul(a, b)
modulus = 0x10001
return((1 - b) % USHORT) if (a == 0)
return((1 - a) % USHORT) if (b == 0)
return((a * b) % modulus)
end
|
#mul_inv(x) ⇒ Object
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/crypt/idea.rb', line 50
def mul_inv(x)
modulus = 0x10001
x = x.to_i % USHORT
return(x) if (x <= 1)
t1 = USHORT / x
y = modulus % x
if (y == 1)
inv = (1 - t1) & 0xFFFF
return(inv)
end
t0 = 1
while (y != 1)
q = x / y
x = x % y
t0 = t0 + (q * t1)
return(t0) if (x == 1)
q = y / x
y = y % x
t1 = t1 + (q * t0)
end
inv = (1 - t1) & 0xFFFF
return(inv)
end
|