mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Added a few speed-ups to the DES code
This commit is contained in:
parent
2faf9ef606
commit
731631a7d7
@ -1,6 +1,7 @@
|
|||||||
# Re-modified for use in MS LIT decryption. Un-reversed the bytebit[] array.
|
# Re-modified for use in MS LIT decryption. Un-reversed the bytebit[] array.
|
||||||
# Substituted Microsoft's absurd modified S-boxes. Modified the encrypt/decrypt
|
# Substituted Microsoft's absurd modified S-boxes. Modified the
|
||||||
# methods to handle more than one block at a time.
|
# encrypt/decrypt methods to handle more than one block at a time. Added a few
|
||||||
|
# speed-ups supported by modern versions of Python. Added option 'psyco' use.
|
||||||
#
|
#
|
||||||
# And lo, all the previous notices follow:
|
# And lo, all the previous notices follow:
|
||||||
|
|
||||||
@ -125,30 +126,30 @@ class DesCipher:
|
|||||||
pcr = [0]*56 #new int[56];
|
pcr = [0]*56 #new int[56];
|
||||||
kn = [0]*32 #new int[32];
|
kn = [0]*32 #new int[32];
|
||||||
|
|
||||||
for j in range(56):
|
for j in xrange(56):
|
||||||
l = pc1[j]
|
l = pc1[j]
|
||||||
m = l & 07
|
m = l & 07
|
||||||
pc1m[j] = ((keyBlock[l >> 3] & bytebit[m]) != 0)
|
pc1m[j] = ((keyBlock[l >> 3] & bytebit[m]) != 0)
|
||||||
for i in range(16):
|
for i in xrange(16):
|
||||||
if encrypting:
|
if encrypting:
|
||||||
m = i << 1
|
m = i << 1
|
||||||
else:
|
else:
|
||||||
m = (15-i) << 1
|
m = (15-i) << 1
|
||||||
n = m + 1
|
n = m + 1
|
||||||
kn[m] = kn[n] = 0
|
kn[m] = kn[n] = 0
|
||||||
for j in range(28):
|
for j in xrange(28):
|
||||||
l = j + totrot[i]
|
l = j + totrot[i]
|
||||||
if l < 28:
|
if l < 28:
|
||||||
pcr[j] = pc1m[l]
|
pcr[j] = pc1m[l]
|
||||||
else:
|
else:
|
||||||
pcr[j] = pc1m[l - 28]
|
pcr[j] = pc1m[l - 28]
|
||||||
for j in range(28, 56):
|
for j in xrange(28, 56):
|
||||||
l = j + totrot[i]
|
l = j + totrot[i]
|
||||||
if l < 56:
|
if l < 56:
|
||||||
pcr[j] = pc1m[l]
|
pcr[j] = pc1m[l]
|
||||||
else:
|
else:
|
||||||
pcr[j] = pc1m[l - 28]
|
pcr[j] = pc1m[l - 28]
|
||||||
for j in range(24):
|
for j in xrange(24):
|
||||||
if pcr[pc2[j]] != 0:
|
if pcr[pc2[j]] != 0:
|
||||||
kn[m] |= bigbyte[j]
|
kn[m] |= bigbyte[j]
|
||||||
if pcr[pc2[j+24]] != 0:
|
if pcr[pc2[j+24]] != 0:
|
||||||
@ -163,7 +164,7 @@ class DesCipher:
|
|||||||
|
|
||||||
rawi = 0
|
rawi = 0
|
||||||
KnLi = 0
|
KnLi = 0
|
||||||
for i in range(16):
|
for i in xrange(16):
|
||||||
raw0 = raw[rawi]
|
raw0 = raw[rawi]
|
||||||
rawi += 1
|
rawi += 1
|
||||||
raw1 = raw[rawi]
|
raw1 = raw[rawi]
|
||||||
@ -187,11 +188,10 @@ class DesCipher:
|
|||||||
if len(clearText) % 8 != 0:
|
if len(clearText) % 8 != 0:
|
||||||
raise TypeError, "length must be multiple of block size"
|
raise TypeError, "length must be multiple of block size"
|
||||||
result = []
|
result = []
|
||||||
while clearText:
|
for base in xrange(0, len(clearText), 8):
|
||||||
result.append(struct.pack(
|
result.append(struct.pack(
|
||||||
">LL", *self.des(struct.unpack(">LL", clearText[:8]),
|
">LL", *self.des(struct.unpack(">LL", clearText[base:base+8]),
|
||||||
self.encryptKeys)))
|
self.encryptKeys)))
|
||||||
clearText = clearText[8:]
|
|
||||||
return ''.join(result)
|
return ''.join(result)
|
||||||
|
|
||||||
#/ Decrypt a block of eight bytes.
|
#/ Decrypt a block of eight bytes.
|
||||||
@ -199,11 +199,10 @@ class DesCipher:
|
|||||||
if len(cipherText) % 8 != 0:
|
if len(cipherText) % 8 != 0:
|
||||||
raise TypeError, "length must be multiple of block size"
|
raise TypeError, "length must be multiple of block size"
|
||||||
result = []
|
result = []
|
||||||
while cipherText:
|
for base in xrange(0, len(cipherText), 8):
|
||||||
result.append(struct.pack(
|
result.append(struct.pack(
|
||||||
">LL", *self.des(struct.unpack(">LL", cipherText[:8]),
|
">LL", *self.des(struct.unpack(">LL", cipherText[base:base+8]),
|
||||||
self.decryptKeys)))
|
self.decryptKeys)))
|
||||||
cipherText = cipherText[8:]
|
|
||||||
return ''.join(result)
|
return ''.join(result)
|
||||||
|
|
||||||
# The DES function.
|
# The DES function.
|
||||||
@ -234,7 +233,7 @@ class DesCipher:
|
|||||||
right ^= work
|
right ^= work
|
||||||
leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffffL
|
leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffffL
|
||||||
|
|
||||||
for round in range(8):
|
for round in xrange(8):
|
||||||
work = ((right << 28) | (right >> 4)) & 0xffffffffL
|
work = ((right << 28) | (right >> 4)) & 0xffffffffL
|
||||||
work ^= keys[keysi]
|
work ^= keys[keysi]
|
||||||
keysi += 1
|
keysi += 1
|
||||||
@ -322,6 +321,7 @@ pc2 = [
|
|||||||
45, 41, 49, 35, 28, 31,
|
45, 41, 49, 35, 28, 31,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Microsoft's modified S-boxes for LIT file encryption
|
||||||
SP1 = [
|
SP1 = [
|
||||||
0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
|
0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
|
||||||
0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
|
0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
|
||||||
@ -473,6 +473,14 @@ def new(key):
|
|||||||
block_size = 8
|
block_size = 8
|
||||||
key_size = 8
|
key_size = 8
|
||||||
|
|
||||||
|
try:
|
||||||
|
import psyco
|
||||||
|
psyco.bind(DesCipher.deskey)
|
||||||
|
psyco.bind(DesCipher.cookey)
|
||||||
|
psyco.bind(DesCipher.des)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
#test only:
|
#test only:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
des = DesCipher("\x01\x23\x45\x67\x89\xab\xcd\xef")
|
des = DesCipher("\x01\x23\x45\x67\x89\xab\xcd\xef")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user