prepare for separation of ecc module:
- move encrypt/sign functions elsewhere - remove local dependencies in ecc.py, ecc_fast.py (except logging)
This commit is contained in:
@@ -34,7 +34,7 @@ from typing import Union, Mapping, Optional
|
||||
from .util import assert_bytes, InvalidPassword, to_bytes, to_string, WalletFileException, versiontuple
|
||||
from .i18n import _
|
||||
from .logging import get_logger
|
||||
|
||||
from . import ecc
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
@@ -443,3 +443,41 @@ def chacha20_decrypt(*, key: bytes, nonce: bytes, data: bytes) -> bytes:
|
||||
decryptor = cipher.decryptor()
|
||||
return decryptor.update(data)
|
||||
raise Exception("no chacha20 backend found")
|
||||
|
||||
|
||||
def ecies_encrypt_message(ec_pubkey, message: bytes, *, magic: bytes = b'BIE1') -> bytes:
|
||||
"""
|
||||
ECIES encryption/decryption methods; AES-128-CBC with PKCS7 is used as the cipher; hmac-sha256 is used as the mac
|
||||
"""
|
||||
assert_bytes(message)
|
||||
ephemeral = ecc.ECPrivkey.generate_random_key()
|
||||
ecdh_key = (ec_pubkey * ephemeral.secret_scalar).get_public_key_bytes(compressed=True)
|
||||
key = hashlib.sha512(ecdh_key).digest()
|
||||
iv, key_e, key_m = key[0:16], key[16:32], key[32:]
|
||||
ciphertext = aes_encrypt_with_iv(key_e, iv, message)
|
||||
ephemeral_pubkey = ephemeral.get_public_key_bytes(compressed=True)
|
||||
encrypted = magic + ephemeral_pubkey + ciphertext
|
||||
mac = hmac_oneshot(key_m, encrypted, hashlib.sha256)
|
||||
return base64.b64encode(encrypted + mac)
|
||||
|
||||
|
||||
def ecies_decrypt_message(ec_privkey, encrypted: Union[str, bytes], *, magic: bytes=b'BIE1') -> bytes:
|
||||
encrypted = base64.b64decode(encrypted) # type: bytes
|
||||
if len(encrypted) < 85:
|
||||
raise Exception('invalid ciphertext: length')
|
||||
magic_found = encrypted[:4]
|
||||
ephemeral_pubkey_bytes = encrypted[4:37]
|
||||
ciphertext = encrypted[37:-32]
|
||||
mac = encrypted[-32:]
|
||||
if magic_found != magic:
|
||||
raise Exception('invalid ciphertext: invalid magic bytes')
|
||||
try:
|
||||
ephemeral_pubkey = ecc.ECPubkey(ephemeral_pubkey_bytes)
|
||||
except ecc.InvalidECPointException as e:
|
||||
raise Exception('invalid ciphertext: invalid ephemeral pubkey') from e
|
||||
ecdh_key = (ephemeral_pubkey * ec_privkey.secret_scalar).get_public_key_bytes(compressed=True)
|
||||
key = hashlib.sha512(ecdh_key).digest()
|
||||
iv, key_e, key_m = key[0:16], key[16:32], key[32:]
|
||||
if mac != hmac_oneshot(key_m, encrypted[:-32], hashlib.sha256):
|
||||
raise InvalidPassword()
|
||||
return aes_decrypt_with_iv(key_e, iv, ciphertext)
|
||||
|
||||
Reference in New Issue
Block a user