-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.py
77 lines (61 loc) · 2.86 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from config import ffi, lib
import sys
def encrypt(message, password):
# Create 16 byte random salt
assert lib.crypto_pwhash_saltbytes() == 16
salt = ffi.new("unsigned char[]", lib.crypto_pwhash_saltbytes())
lib.randombytes_buf(salt, lib.crypto_pwhash_saltbytes())
# Create 12 byte random nonce
assert lib.crypto_aead_chacha20poly1305_ietf_npubbytes() == 12
nonce = ffi.new("unsigned char[]",
lib.crypto_aead_chacha20poly1305_ietf_npubbytes())
lib.randombytes_buf(nonce,
lib.crypto_aead_chacha20poly1305_ietf_npubbytes())
key = ffi.new("unsigned char[]",
lib.crypto_aead_chacha20poly1305_ietf_keybytes())
# pwhash salt and create key.
if lib.crypto_pwhash(key, lib.crypto_aead_chacha20poly1305_ietf_keybytes(),
password, len(password), salt,
lib.crypto_pwhash_opslimit_moderate(),
lib.crypto_pwhash_memlimit_moderate(),
lib.crypto_pwhash_alg_default()) != 0:
print("Out of memory")
return None
ciphertext = ffi.new("unsigned char[]",
len(message) + lib.crypto_aead_chacha20poly1305_ietf_abytes())
ciphertext_len = ffi.new("unsigned long long *")
# Encrypt message to ciphertext
retcode = lib.crypto_aead_chacha20poly1305_ietf_encrypt(
ciphertext, ciphertext_len, message, len(message), ffi.NULL, 0,
ffi.NULL, nonce, key)
assert retcode == 0
return (ffi.buffer(salt, lib.crypto_pwhash_saltbytes())[:],
ffi.buffer(nonce,
lib.crypto_aead_chacha20poly1305_ietf_npubbytes())[:],
ffi.buffer(ciphertext, ciphertext_len[0])[:])
def decrypt(salt, nonce, ciphertext, password):
key = ffi.new("unsigned char[]",
lib.crypto_aead_chacha20poly1305_ietf_keybytes())
# pwhash salt and create key.
if lib.crypto_pwhash(key, lib.crypto_aead_chacha20poly1305_ietf_keybytes(),
password, len(password), salt,
lib.crypto_pwhash_opslimit_moderate(),
lib.crypto_pwhash_memlimit_moderate(),
lib.crypto_pwhash_alg_default()) != 0:
print("Out of memory")
return None
max_decrypted_size = (len(ciphertext) -
lib.crypto_aead_chacha20poly1305_ietf_abytes())
decrypted = ffi.new("unsigned char[]", max_decrypted_size)
decrypted_len = ffi.new("unsigned long long *")
# Decrypt message.
retcode = lib.crypto_aead_chacha20poly1305_ietf_decrypt(
decrypted, decrypted_len, ffi.NULL, ciphertext, len(ciphertext),
ffi.NULL, 0, nonce, key)
assert retcode == 0
return ffi.buffer(decrypted, decrypted_len[0])[:]
message = b"Foo bar foo"
password = b"Correct Horse Battery"
salt, nonce, ciphertext = encrypt(message, password)
result = decrypt(salt, nonce, ciphertext, password)
assert result == message