1 | from binascii import a2b_hex, b2a_hex |
---|
2 | import random |
---|
3 | import xsalsa, aes |
---|
4 | from pycryptopp.hash import sha256, hkdf, comp4p |
---|
5 | |
---|
6 | def randstr(n): |
---|
7 | return ''.join(map(chr, map(random.randrange, [0]*n, [256]*n))) |
---|
8 | |
---|
9 | class CipherCombiner(object): |
---|
10 | def __init__(self, key = None, iv = None): |
---|
11 | self.cipher1 = aes.AES |
---|
12 | self.cipher2 = xsalsa.XSalsa |
---|
13 | self.keyhash = sha256.SHA256 |
---|
14 | self.info = "pycryptopp cipher combiner" |
---|
15 | self.salt = None |
---|
16 | |
---|
17 | if key is not None: |
---|
18 | self.key = key |
---|
19 | self.keylen = len(key) |
---|
20 | pos = self.keylen - 32 |
---|
21 | self.key1 = key[:pos] |
---|
22 | self.key2 = key[pos:] |
---|
23 | |
---|
24 | self.iv1 = None |
---|
25 | self.iv2 = None |
---|
26 | |
---|
27 | if iv is not None: |
---|
28 | assert len(iv) == 40 |
---|
29 | self.iv1 = iv[:16] |
---|
30 | self.iv2 = iv[16:] |
---|
31 | |
---|
32 | def setHKDFHash(self, hash): |
---|
33 | self.keyhash = hash |
---|
34 | |
---|
35 | def setHKDFInfo(self, info): |
---|
36 | self.info = info |
---|
37 | |
---|
38 | def setHKDFIkm(self, ikm): |
---|
39 | self.ikm = ikm |
---|
40 | |
---|
41 | def setHKDFSalt(self, salt): |
---|
42 | self.salt = salt |
---|
43 | |
---|
44 | def generate_key(self, ikm, keylen): |
---|
45 | hk = hkdf.new(ikm, keylen, self.salt, self.info, self.keyhash) |
---|
46 | hk.extract() |
---|
47 | self.key = hk.expand() |
---|
48 | self.keylen = len(key) |
---|
49 | pos = self.keylen - 32 |
---|
50 | self.key1 = key[:pos] |
---|
51 | self.key2 = key[pos:] |
---|
52 | |
---|
53 | def setCombinerIV(self, iv): |
---|
54 | assert len(iv) == 40 |
---|
55 | self.iv1 = iv[:16] |
---|
56 | self.iv2 = iv[16:] |
---|
57 | |
---|
58 | def process(self, plaintext): |
---|
59 | # stage1_cipher = self.c1(self.key1, self.iv1).process(plaintext) |
---|
60 | # cipher = self.c2(self.key2, self.iv2).process(stage1_cipher) |
---|
61 | if self.iv1 is None: |
---|
62 | stage1_cipher = self.cipher1(self.key1).process(plaintext) |
---|
63 | else: |
---|
64 | stage1_cipher = self.cipher1(self.key1, self.iv1).process(plaintext) |
---|
65 | |
---|
66 | if self.iv2 is None: |
---|
67 | cipher = self.cipher2(self.key2).process(stage1_cipher) |
---|
68 | else: |
---|
69 | cipher = self.cipher2(self.key2, self.iv2).process(stage1_cipher) |
---|
70 | |
---|
71 | return cipher |
---|
72 | |
---|
73 | |
---|
74 | def start_up_self_test(): |
---|
75 | """ |
---|
76 | This is a quick test intended to detect major errors such as the library being miscompiled and segfaulting. |
---|
77 | """ |
---|
78 | enc0 = "884fecf1f3945eaae55d3892eb79170b" |
---|
79 | from binascii import a2b_hex, b2a_hex |
---|
80 | |
---|
81 | key = "\x00"*16 + a2b_hex("1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389") |
---|
82 | iv = "\x00"*16 + a2b_hex("69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37") |
---|
83 | cryptor= CipherCombiner(key, iv) |
---|
84 | ct = cryptor.process("\x00"*16) |
---|
85 | if enc0 != b2a_hex(ct): |
---|
86 | raise Exception("pycryptopp failed startup self-test. Please run pycryptopp unit test.") |
---|
87 | |
---|
88 | enc1 = "35e2091fcbaf2793132f34a704d83518e945d4ad340fc39c926df59960acb4cbeaab29cdec65e2df079f9dbfb1dd4439197ed3aabbac2bb95bce77971d476a59" |
---|
89 | key = "2b7e151628aed2a6abf7158809cf4f3ca6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff88030" |
---|
90 | iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff9e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c" |
---|
91 | cryptor = CipherCombiner(a2b_hex(key),a2b_hex(iv)) |
---|
92 | ct = cryptor.process(a2b_hex("62fde0b7ab1709b3da46adba120e767dcef54fe53aabf78190496114e241986b8bcb6a143c90edab50fd0701fb36b5982eb31eac0ee96265793d43fc2d9257af")) |
---|
93 | if enc1 != b2a_hex(ct): |
---|
94 | raise Exception("pycryptopp failed startup self-test. Please run pycryptopp unit test.") |
---|
95 | |
---|
96 | enc2 = "ab6b7bbef841450800c800fd8fb2b58ba7cd3f10cbdf92cd1586f77d82a5dc64a3600f43ab23d1860422bf167959e75ebcddf16ed3670255a84e4bfbad16120e" |
---|
97 | key = "2b7e151628aed2a6abf7158809cf4f3c9e1da239d155f52ad37f75c7368a536668b051952923ad44f57e75ab588e475a" |
---|
98 | iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeffaf06f17859dffa799891c4288f6635b5c5a45eee9017fd72" |
---|
99 | cryptor = CipherCombiner(a2b_hex(key),a2b_hex(iv)) |
---|
100 | ct = cryptor.process(a2b_hex("956d23b6d2cc8ecc0b7aa7b69a8aca5c61e64d7a2cc94808d6d7eed0f8540255d679c3300239f3dcd63730b5c09854d7680115ca86295b846298ad56788ee995")) |
---|
101 | if enc2 != b2a_hex(ct): |
---|
102 | raise Exception("pycryptopp failed startup self-test. Please run pycryptopp unit test.") |
---|
103 | |
---|
104 | enc3 = "a0f5ae79a23644451a127688f3402fa9c86f44b15e063e9f5d0cc791c5f55beccbdacfc97dda3f5a8a516cf0dbfe" |
---|
105 | key = "2b7e151628aed2a6abf7158809cf4f3cd5c7f6797b7e7e9c1d7fd2610b2abf2bc5a7885fb3ff78092fb3abe8986d35e2" |
---|
106 | iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff744e17312b27969d826444640e9c4a378ae334f185369c95" |
---|
107 | cryptor = CipherCombiner(a2b_hex(key),a2b_hex(iv)) |
---|
108 | ct = cryptor.process(a2b_hex("1c99976e4cce2c325fab4245367c71bdbc0f340a044974a5efea7e2442b8b7e64c0efc1bf74c1d7243baa67b8d5d")) |
---|
109 | if enc3 != b2a_hex(ct): |
---|
110 | raise Exception("pycryptopp failed startup self-test. Please run pycryptopp unit test.") |
---|
111 | |
---|
112 | enc4 = "089abe" |
---|
113 | key = "2b7e151628aed2a6abf7158809cf4f3c6799d76e5ffb5b4920bc2768bafd3f8c16554e65efcf9a16f4683a7a06927c11" |
---|
114 | iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff61ab951921e54ff06d9b77f313a4e49df7a057d5fd627989" |
---|
115 | cryptor = CipherCombiner(a2b_hex(key),a2b_hex(iv)) |
---|
116 | ct = cryptor.process(a2b_hex("2ce6d8")) |
---|
117 | if enc4 != b2a_hex(ct): |
---|
118 | raise Exception("pycryptopp failed startup self-test. Please run pycryptopp unit test.") |
---|
119 | |
---|
120 | enc5 = "b15b6f196570e60fa1a1b3c5e2cffb4262cc6c6df9c34c0311d81b88dea4873c5b2c5c9857d2c89b1182dab437449c7c319b438bd668099d06f5f10fe3b2609b" |
---|
121 | key = "2b7e151628aed2a6abf7158809cf4f3cf68238c08365bb293d26980a606488d09c2f109edafa0bbae9937b5cc219a49c" |
---|
122 | iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff5190b51e9b708624820b5abdf4e40fad1fb950ad1adc2d26" |
---|
123 | cryptor = CipherCombiner(a2b_hex(key),a2b_hex(iv)) |
---|
124 | ct = cryptor.process(a2b_hex("2c2dd5fd5d842869bb49deaea46748ace63f420d0cf867a0b24fcc454959e29e1e64a9674414d22d920eefad3ca4054f3058ab30703eb352c4ccdc6174957eb9")) |
---|
125 | if enc5 != b2a_hex(ct): |
---|
126 | raise Exception("pycryptopp failed startup self-test. Please run pycryptopp unit test.") |
---|
127 | |
---|
128 | |
---|
129 | |
---|
130 | |
---|
131 | |
---|
132 | |
---|
133 | |
---|
134 | |
---|
135 | |
---|