qrcrypt/xchacha.py

29 lines
1.8 KiB
Python

import chacha20
import chapoly_aead
leu=lambda b:sum(b[i]<<(i*8)for i in range(len(b)))
def hchacha20(key, nonce):
counter = leu(nonce[:4])
nonce = nonce[4:]
state = chacha20.chacha20_block(key, counter, nonce, do_final_add = False)
return state[:16] + state[48:]
def enc(aad, key, nonce, plaintext):
subkey = hchacha20(key, nonce[:16])
chacha20_nonce = b'\x00'*4 + nonce[16:]
return chapoly_aead.chapoly_aead_enc(aad, subkey, chacha20_nonce, plaintext)
def dec(aad, key, nonce, ciphertext):
subkey = hchacha20(key, nonce[:16])
chacha20_nonce = b'\x00'*4 + nonce[16:]
return chapoly_aead.chapoly_aead_dec(aad, subkey, chacha20_nonce, ciphertext)
if __name__ == '__main__':
plaintext = bytes.fromhex('4c 61 64 69 65 73 20 61 6e 64 20 47 65 6e 74 6c 65 6d 65 6e 20 6f 66 20 74 68 65 20 63 6c 61 73 73 20 6f 66 20 27 39 39 3a 20 49 66 20 49 20 63 6f 75 6c 64 20 6f 66 66 65 72 20 79 6f 75 20 6f 6e 6c 79 20 6f 6e 65 20 74 69 70 20 66 6f 72 20 74 68 65 20 66 75 74 75 72 65 2c 20 73 75 6e 73 63 72 65 65 6e 20 77 6f 75 6c 64 20 62 65 20 69 74 2e')
aad = bytes.fromhex('50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7')
key = bytes.fromhex('80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f')
nonce = b'@ABCDEFGHIJKLMNOPQRSTUVW'
ciphertext = enc(aad, key, nonce, plaintext)
print(ciphertext == bytes.fromhex('bd 6d 17 9d 3e 83 d4 3b 95 76 57 94 93 c0 e9 39 57 2a 17 00 25 2b fa cc be d2 90 2c 21 39 6c bb 73 1c 7f 1b 0b 4a a6 44 0b f3 a8 2f 4e da 7e 39 ae 64 c6 70 8c 54 c2 16 cb 96 b7 2e 12 13 b4 52 2f 8c 9b a4 0d b5 d9 45 b1 1b 69 b9 82 c1 bb 9e 3f 3f ac 2b c3 69 48 8f 76 b2 38 35 65 d3 ff f9 21 f9 66 4c 97 63 7d a9 76 88 12 f6 15 c6 8b 13 b5 2e c0:87:59:24:c1:c7:98:79:47:de:af:d8:78:0a:cf:49'.replace(':', '')))
print(plaintext == dec(aad, key, nonce, ciphertext))