mirror of
https://github.com/morgan9e/noiseprotocol
synced 2026-04-14 00:14:05 +09:00
noise/functions.py * Wrapped cryptoalgorithms in maps with appropriate wrapper classes * Probably finished Hash wrapper (to verify when we test first outputs in tests) noise/noise_protocol.py * Slightly renamed attributes containing wrapped cryptoalgorithms * Added placeholders for protocol State objects * Now checks if given protocol_name is of bytes() noise/state.py * HandshakeState: remove handshake_pattern argument and take it from given NoiseProtocol instance instead. * HandshakeState: save NoiseProtocol instance in the HandshakeState instance and vice versa * SymmetricState: implemented initialize_symmetric() and mix_hash() * SymmetricState: save NoiseProtocol instance in the SymmetricState instance and vice versa * CipherState: implemented initialize_key() as class constructor * CipherState: save NoiseProtocol instance in the CipherState instance and vice versa tests/test_vectors.py * Changes to reflect new signature of HandshakeState * Fix - strings read from .json are now casted to bytes()
93 lines
2.3 KiB
Python
93 lines
2.3 KiB
Python
from .crypto import ed448
|
|
|
|
from Crypto.Cipher import AES, ChaCha20
|
|
from Crypto.Hash import BLAKE2b, BLAKE2s, SHA256, SHA512
|
|
import ed25519
|
|
|
|
|
|
class DH(object):
|
|
def __init__(self, method):
|
|
self.method = method
|
|
self.dhlen = 0
|
|
self.dh = None
|
|
|
|
def generate_keypair(self) -> 'KeyPair':
|
|
pass
|
|
|
|
|
|
class Cipher(object):
|
|
def __init__(self, method):
|
|
pass
|
|
|
|
def encrypt(self, k, n, ad, plaintext):
|
|
pass
|
|
|
|
def decrypt(self, k, n, ad, ciphertext):
|
|
pass
|
|
|
|
|
|
class Hash(object):
|
|
def __init__(self, method):
|
|
if method == 'SHA256':
|
|
self.hashlen = 32
|
|
self.blocklen = 64
|
|
self.hash = self._hash_sha256
|
|
elif method == 'SHA512':
|
|
self.hashlen = 64
|
|
self.blocklen = 128
|
|
self.hash = self._hash_sha512
|
|
elif method == 'BLAKE2s':
|
|
self.hashlen = 32
|
|
self.blocklen = 64
|
|
self.hash = self._hash_blake2s
|
|
elif method == 'BLAKE2b':
|
|
self.hashlen = 64
|
|
self.blocklen = 128
|
|
self.hash = self._hash_blake2b
|
|
|
|
def _hash_sha256(self, data):
|
|
return SHA256.new(data).digest()
|
|
|
|
def _hash_sha512(self, data):
|
|
return SHA512.new(data).digest()
|
|
|
|
def _hash_blake2s(self, data):
|
|
return BLAKE2s.new(data=data, digest_bytes=self.hashlen).digest()
|
|
|
|
def _hash_blake2b(self, data):
|
|
return BLAKE2b.new(data=data, digest_bytes=self.hashlen).digest()
|
|
|
|
|
|
class KeyPair(object):
|
|
def __init__(self, public=b'', private=b''):
|
|
# TODO: Maybe switch to properties?
|
|
self.public = public
|
|
self.private = private
|
|
if private and not public:
|
|
self.derive_public_key()
|
|
|
|
def derive_public_key(self):
|
|
pass
|
|
|
|
|
|
# Available crypto functions
|
|
# TODO: Check if it's safe to use one instance globally per cryptoalgorithm - i.e. if wrapper only provides interface
|
|
# If not - switch to partials(?)
|
|
dh_map = {
|
|
'25519': DH('ed25519'),
|
|
'448': DH('ed448')
|
|
}
|
|
|
|
cipher_map = {
|
|
'AESGCM': Cipher('AESGCM'),
|
|
'ChaChaPoly': Cipher('ChaCha20')
|
|
}
|
|
|
|
hash_map = {
|
|
# TODO benchmark pycryptodome vs hashlib implementation
|
|
'BLAKE2s': Hash('BLAKE2s'),
|
|
'BLAKE2b': Hash('BLAKE2b'),
|
|
'SHA256': Hash('SHA256'),
|
|
'SHA512': Hash('SHA512')
|
|
}
|