mirror of
https://github.com/morgan9e/noiseprotocol
synced 2026-04-14 00:14:05 +09:00
Implementing NoiseProtocol (WIP), binding crypto
noise/noise_protocol.py - added maps of cryptofunctions that will be used, finished protocol name splitting noise/patterns.py - added map of patterns requirements.txt - switching to pycryptodome as a source of cipher and hashing functions, and ed25519 package for that curve
This commit is contained in:
@@ -1,19 +1,72 @@
|
||||
from functools import partial
|
||||
|
||||
from .patterns import patterns_map
|
||||
from .constants import MAX_PROTOCOL_NAME_LEN
|
||||
from Crypto.Cipher import AES, ChaCha20
|
||||
from Crypto.Hash import BLAKE2b, BLAKE2s, SHA256, SHA512
|
||||
import ed25519
|
||||
|
||||
dh_map = {
|
||||
'25519': ed25519.create_keypair,
|
||||
'448': None # TODO implement
|
||||
}
|
||||
|
||||
cipher_map = {
|
||||
'AESGCM': partial(AES.new, mode=AES.MODE_GCM),
|
||||
'ChaChaPoly': lambda key: ChaCha20.new(key=key)
|
||||
}
|
||||
|
||||
hash_map = {
|
||||
'BLAKE2b': BLAKE2b, # TODO PARTIALS
|
||||
'BLAKE2s': BLAKE2s, # TODO PARTIALS
|
||||
'SHA256': SHA256, # TODO PARTIALS
|
||||
'SHA512': SHA512 # TODO PARTIALS
|
||||
}
|
||||
|
||||
|
||||
class NoiseProtocol(object):
|
||||
methods = {
|
||||
'pattern': patterns_map,
|
||||
'dh': dh_map,
|
||||
|
||||
}
|
||||
def __init__(self, protocol_name: bytes):
|
||||
if len(protocol_name) > MAX_PROTOCOL_NAME_LEN:
|
||||
raise Exception('Protocol name too long, has to be at most {} chars long'.format(MAX_PROTOCOL_NAME_LEN))
|
||||
raise ValueError('Protocol name too long, has to be at most {} chars long'.format(MAX_PROTOCOL_NAME_LEN))
|
||||
|
||||
self.pattern = None
|
||||
self.name = protocol_name
|
||||
data_dict = self._split_protocol_name()
|
||||
self.pattern = patterns_map[data_dict['pattern']]
|
||||
self.pattern_modifiers = None
|
||||
self.dh = None
|
||||
self.dh_modifiers = None
|
||||
self.cipher = None
|
||||
self.cipher_modifiers = None
|
||||
self.hash = None
|
||||
self.hash_modifiers = None
|
||||
|
||||
def _split_protocol_name(self):
|
||||
unpacked = self.name.split('_')
|
||||
if unpacked[0] != 'Noise':
|
||||
raise ValueError(f'Noise protocol name shall begin with Noise! Provided: {self.name}')
|
||||
|
||||
pattern = ''
|
||||
modifiers_str = None
|
||||
for i, char in enumerate(unpacked[1]):
|
||||
if char.isupper():
|
||||
pattern += char
|
||||
else:
|
||||
modifiers_str = unpacked[1][i+1:] # Will be empty string if it exceeds string size
|
||||
break
|
||||
modifiers = modifiers_str.split('+') if modifiers_str else []
|
||||
|
||||
data = {'pattern': 'Pattern' + pattern,
|
||||
'dh': unpacked[2],
|
||||
'cipher': unpacked[3],
|
||||
'hash': unpacked[4],
|
||||
'pattern_modifiers': modifiers}
|
||||
|
||||
# Validate if we know everything that Noise Protocol is supposed to use
|
||||
# TODO validation
|
||||
|
||||
return data
|
||||
|
||||
|
||||
class KeyPair(object):
|
||||
|
||||
@@ -168,3 +168,22 @@ class PatternIX(Pattern):
|
||||
[TOKEN_E, TOKEN_S],
|
||||
[TOKEN_E, TOKEN_EE, TOKEN_SE, TOKEN_S, TOKEN_ES]
|
||||
]
|
||||
|
||||
|
||||
patterns_map = {
|
||||
'PatternN': PatternN,
|
||||
'PatternK': PatternN,
|
||||
'PatternX': PatternN,
|
||||
'PatternNN': PatternNN,
|
||||
'PatternKN': PatternKN,
|
||||
'PatternNK': PatternNK,
|
||||
'PatternKK': PatternKK,
|
||||
'PatternNX': PatternNX,
|
||||
'PatternKX': PatternKX,
|
||||
'PatternXN': PatternXN,
|
||||
'PatternIN': PatternIN,
|
||||
'PatternXK': PatternXK,
|
||||
'PatternIK': PatternIK,
|
||||
'PatternXX': PatternXX,
|
||||
'PatternIX': PatternIX,
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
pytest
|
||||
pynacl
|
||||
pycryptodome
|
||||
ed25519
|
||||
|
||||
Reference in New Issue
Block a user