2 from array
import array
14 """ Base class for all blockciphers
17 def __init__(self
,key
,mode
,IV
):
22 self
.chain
= ECB(self
.blocksize
)
23 elif mode
== MODE_CBC
:
24 self
.chain
= CBC(self
.blocksize
,IV
)
25 elif mode
== MODE_CTR
:
26 self
.chain
= CTR(self
.blocksize
,IV
)
27 elif mode
== MODE_XTS
:
30 def encrypt(self
,plaintext
):
31 if self
.mode
== MODE_XTS
:
32 return self
.chain
.update(plaintext
,'e',self
.cipher
,self
.cipher2
)
34 return self
.chain
.update(plaintext
,'e',self
.cipher
)
36 def decrypt(self
,ciphertext
):
37 if self
.mode
== MODE_XTS
:
38 return self
.chain
.update(ciphertext
,'d',self
.cipher
,self
.cipher2
)
40 return self
.chain
.update(ciphertext
,'d',self
.cipher
)
43 def __init__(self
, blocksize
):
45 self
.blocksize
= blocksize
47 def update(self
, plaintext
,ed
,codebook
):
50 ed = 'e' or 'd' = encrypt or decrypt => encrypt() or decrypt() from BlockCipher will pass the right one
51 codebook = encrypt/decrypt will pass "self.cipher.encrypt()" or "decrypt()"
54 self
.cache
+= plaintext
55 if len(self
.cache
) < self
.blocksize
:
57 for i
in range(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
59 output_blocks
.append(codebook
.encrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
61 output_blocks
.append(codebook
.decrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
62 self
.cache
= self
.cache
[i
+self
.blocksize
:]
63 return ''.join(output_blocks
)
66 """finalizes the chain by padding
68 padding codebooktion can be provided as an argument
69 no way to finalize with standart pycrypto API
70 => finalize when submitted plaintext or ciphertext == '' ?
75 def __init__(self
, blocksize
, IV
):
78 self
.blocksize
= blocksize
80 def update(self
, input,ed
,codebook
):
87 if len(self
.cache
) < self
.blocksize
:
89 for i
in range(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
90 self
.IV
= codebook
.encrypt(xor(self
.cache
[i
:i
+self
.blocksize
],self
.IV
))
91 encrypted_blocks
.append(self
.IV
)
92 self
.cache
= self
.cache
[i
+self
.blocksize
:]
93 return ''.join(encrypted_blocks
)
97 if len(self
.cache
) < self
.blocksize
:
99 for i
in range(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
100 plaintext
= xor(self
.IV
,codebook
.decrypt(self
.cache
[i
:i
+ self
.blocksize
]))
101 self
.IV
= self
.cache
[i
:i
+ self
.blocksize
]
102 decrypted_blocks
.append(plaintext
)
103 self
.cache
= self
.cache
[i
+self
.blocksize
:]
104 return ''.join(decrypted_blocks
)
108 """finalizes the chain by padding
110 padding codebooktion can be provided as an argument
111 no way to finalize with standart pycrypto API
112 => finalize when submitted plaintext or ciphertext == '' ?
119 Implemented so it can be accessed as a stream cipher.
122 # mogelijkheid om slecht een aantal bytes van IV te gebruiken als counter
123 def __init__(self
, blocksize
, IV
):
126 self
.blocksize
= blocksize
129 def update(self
, data
,ed
,codebook
):
130 from binascii
import unhexlify
,hexlify
138 # fancier version of CTR mode might have to deal with different
139 # endianness options for the counter, etc.
141 blocksize
= self
.blocksize
143 output
= array('B', data
)
148 block
= codebook
.encrypt(self
.IV
)
149 keystream
= array('B', block
[xpos
% blocksize
:])
150 self
.IV
= long2string( (long(hexlify(self
.IV
),16)+1)%pow(2,(len(self
.IV
)*8)) )
151 output
[i
] ^
= keystream
.pop(0)
153 return output
.tostring()
163 def update(self
, data
, ed
, codebook
, codebook2
,i
=0,n
=0):
164 """Perform a XTS decrypt operation."""
168 for c
in reversed(str):
180 def xorstring16(a
, b
):
183 new
+= chr(ord(a
[p
]) ^
ord(b
[p
]))
186 def gf2pow128powof2(n
):
187 """2^n in GF(2^128)."""
190 return reduce(gf2pow128mul
, (2 for x
in xrange(n
)), 1)
195 for i
in xrange(len(self
.cache
) // 16):
197 n_txt
= struct
.pack('< Q', n
) + '\x00' * 8
198 e_k2_n
= codebook2
.encrypt(n_txt
)
201 a_i
= gf2pow128powof2(i
)
203 # e_mul_a = E_K2(n) mul (a pow i)
204 e_mul_a
= gf2pow128mul(str2int(e_k2_n
), a_i
)
205 e_mul_a
= int2str(e_mul_a
)
206 e_mul_a
= '\x00' * (16 - len(e_mul_a
)) + e_mul_a
208 # C = E_K1(P xor e_mul_a) xor e_mul_a
210 output
+= xorstring16(e_mul_a
, codebook
.decrypt(xorstring16(e_mul_a
, self
.cache
[i
*16:(i
+1)*16])))
212 output
+= xorstring16(e_mul_a
, codebook
.encrypt(xorstring16(e_mul_a
, self
.cache
[i
*16:(i
+1)*16])))
214 self
.cache
= self
.cache
[(i
+1)*16:]