Skip to content

Commit

Permalink
update user keys to specs
Browse files Browse the repository at this point in the history
  • Loading branch information
popenta committed Dec 4, 2024
1 parent b9484a7 commit a2d83d3
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 43 deletions.
2 changes: 1 addition & 1 deletion multiversx_sdk/wallet/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self) -> None:
super().__init__("Bad length of secret key")


class InvalidPublicKeyLength(Exception):
class InvalidPublicKeyLengthError(Exception):
def __init__(self) -> None:
super().__init__("Bad length of public key")

Expand Down
11 changes: 0 additions & 11 deletions multiversx_sdk/wallet/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@

from typing import Protocol

ISignature = bytes


class IRandomness(Protocol):
salt: bytes
iv: bytes
id: str


class IAddress(Protocol):
def to_bech32(self) -> str:
...

def to_hex(self) -> str:
...
17 changes: 11 additions & 6 deletions multiversx_sdk/wallet/user_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
from multiversx_sdk.core.address import Address
from multiversx_sdk.wallet.constants import (USER_PUBKEY_LENGTH,
USER_SEED_LENGTH)
from multiversx_sdk.wallet.errors import (InvalidPublicKeyLength,
from multiversx_sdk.wallet.errors import (InvalidPublicKeyLengthError,
InvalidSecretKeyLengthError)
from multiversx_sdk.wallet.interfaces import ISignature


class UserSecretKey:
Expand All @@ -24,15 +23,15 @@ def generate(cls) -> 'UserSecretKey':
return UserSecretKey(secret_key)

@classmethod
def from_string(cls, buffer_hex: str) -> 'UserSecretKey':
def new_from_string(cls, buffer_hex: str) -> 'UserSecretKey':
buffer = bytes.fromhex(buffer_hex)
return UserSecretKey(buffer)

def generate_public_key(self) -> 'UserPublicKey':
public_key = bytes(nacl.signing.SigningKey(self.buffer).verify_key)
return UserPublicKey(public_key)

def sign(self, data: bytes) -> ISignature:
def sign(self, data: bytes) -> bytes:
signing_key = nacl.signing.SigningKey(self.buffer)
signed = signing_key.sign(data)
signature = signed.signature
Expand All @@ -41,6 +40,9 @@ def sign(self, data: bytes) -> ISignature:
def hex(self) -> str:
return self.buffer.hex()

def get_bytes(self) -> bytes:
return self.buffer

def __str__(self) -> str:
return UserSecretKey.__name__

Expand All @@ -51,11 +53,11 @@ def __repr__(self) -> str:
class UserPublicKey:
def __init__(self, buffer: bytes) -> None:
if len(buffer) != USER_PUBKEY_LENGTH:
raise InvalidPublicKeyLength()
raise InvalidPublicKeyLengthError()

self.buffer = bytes(buffer)

def verify(self, data: bytes, signature: ISignature) -> bool:
def verify(self, data: bytes, signature: bytes) -> bool:
verify_key = nacl.signing.VerifyKey(self.buffer)

try:
Expand All @@ -67,6 +69,9 @@ def verify(self, data: bytes, signature: ISignature) -> bool:
def to_address(self, hrp: Optional[str] = None) -> Address:
return Address(self.buffer, hrp)

def get_bytes(self) -> bytes:
return self.buffer

def hex(self) -> str:
return self.buffer.hex()

Expand Down
5 changes: 2 additions & 3 deletions multiversx_sdk/wallet/user_signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from typing import List

from multiversx_sdk.wallet.errors import CannotSignError
from multiversx_sdk.wallet.interfaces import ISignature
from multiversx_sdk.wallet.user_keys import UserPublicKey, UserSecretKey
from multiversx_sdk.wallet.user_pem import UserPEM
from multiversx_sdk.wallet.user_wallet import UserWallet
Expand Down Expand Up @@ -31,13 +30,13 @@ def from_wallet(cls, path: Path, password: str) -> 'UserSigner':
secret_key = UserWallet.load_secret_key(path, password)
return UserSigner(secret_key)

def sign(self, data: bytes) -> ISignature:
def sign(self, data: bytes) -> bytes:
try:
return self._try_sign(data)
except Exception as err:
raise CannotSignError() from err

def _try_sign(self, data: bytes) -> ISignature:
def _try_sign(self, data: bytes) -> bytes:
signature = self.secret_key.sign(data)
return signature

Expand Down
20 changes: 10 additions & 10 deletions multiversx_sdk/wallet/user_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ def test_user_secret_key_create():
buffer_hex = "413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9"
buffer = bytes.fromhex(buffer_hex)
secret_key = UserSecretKey(buffer)
secret_key_from_string = UserSecretKey.from_string(buffer_hex)
secret_key_from_string = UserSecretKey.new_from_string(buffer_hex)

assert secret_key.hex() == buffer_hex
assert secret_key_from_string.hex() == buffer_hex


def test_user_secret_key_generate_public_key():
assert UserSecretKey.from_string("413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9").generate_public_key().hex() == "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1"
assert UserSecretKey.from_string("b8ca6f8203fb4b545a8e83c5384da033c415db155b53fb5b8eba7ff5a039d639").generate_public_key().hex() == "8049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f8"
assert UserSecretKey.from_string("e253a571ca153dc2aee845819f74bcc9773b0586edead15a94cb7235a5027436").generate_public_key().hex() == "b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba"
assert UserSecretKey.new_from_string("413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9").generate_public_key().hex() == "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1"
assert UserSecretKey.new_from_string("b8ca6f8203fb4b545a8e83c5384da033c415db155b53fb5b8eba7ff5a039d639").generate_public_key().hex() == "8049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f8"
assert UserSecretKey.new_from_string("e253a571ca153dc2aee845819f74bcc9773b0586edead15a94cb7235a5027436").generate_public_key().hex() == "b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba"


def test_user_signer_from_pem_file():
Expand All @@ -53,21 +53,21 @@ def test_load_signers_from_pem():


def test_user_wallet_to_keyfile_object_using_known_test_wallets_with_their_randomness():
alice_secret_key = UserSecretKey.from_string("413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9")
alice_secret_key = UserSecretKey.new_from_string("413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9")
alice_wallet = UserWallet.from_secret_key(alice_secret_key, "password", Randomness(
salt=bytes.fromhex("4903bd0e7880baa04fc4f886518ac5c672cdc745a6bd13dcec2b6c12e9bffe8d"),
iv=bytes.fromhex("033182afaa1ebaafcde9ccc68a5eac31"),
id="0dc10c02-b59b-4bac-9710-6b2cfa4284ba"
))

bob_secret_key = UserSecretKey.from_string("b8ca6f8203fb4b545a8e83c5384da033c415db155b53fb5b8eba7ff5a039d639")
bob_secret_key = UserSecretKey.new_from_string("b8ca6f8203fb4b545a8e83c5384da033c415db155b53fb5b8eba7ff5a039d639")
bob_wallet = UserWallet.from_secret_key(bob_secret_key, "password", Randomness(
salt=bytes.fromhex("18304455ac2dbe2a2018bda162bd03ef95b81622e99d8275c34a6d5e6932a68b"),
iv=bytes.fromhex("18378411e31f6c4e99f1435d9ab82831"),
id="85fdc8a7-7119-479d-b7fb-ab4413ed038d"
))

carol_secret_key = UserSecretKey.from_string("e253a571ca153dc2aee845819f74bcc9773b0586edead15a94cb7235a5027436")
carol_secret_key = UserSecretKey.new_from_string("e253a571ca153dc2aee845819f74bcc9773b0586edead15a94cb7235a5027436")
carol_wallet = UserWallet.from_secret_key(carol_secret_key, "password", Randomness(
salt=bytes.fromhex("4f2f5530ce28dc0210962589b908f52714f75c8fb79ff18bdd0024c43c7a220b"),
iv=bytes.fromhex("258ed2b4dc506b4dc9d274b0449b0eb0"),
Expand All @@ -92,19 +92,19 @@ def test_user_wallet_to_keyfile_object_using_known_test_wallets_with_their_rando


def test_user_wallet_encrypt_then_decrypt():
alice_secret_key = UserSecretKey.from_string("413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9")
alice_secret_key = UserSecretKey.new_from_string("413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9")
alice_wallet = UserWallet.from_secret_key(alice_secret_key, "password")
alice_keyfile_object = alice_wallet.to_dict("erd")
decrypted_secret_key = UserWallet.decrypt_secret_key(alice_keyfile_object, "password")
assert decrypted_secret_key.buffer == alice_secret_key.buffer

bob_secret_key = UserSecretKey.from_string("b8ca6f8203fb4b545a8e83c5384da033c415db155b53fb5b8eba7ff5a039d639")
bob_secret_key = UserSecretKey.new_from_string("b8ca6f8203fb4b545a8e83c5384da033c415db155b53fb5b8eba7ff5a039d639")
bob_wallet = UserWallet.from_secret_key(bob_secret_key, "password")
bob_keyfile_object = bob_wallet.to_dict("erd")
decrypted_secret_key = UserWallet.decrypt_secret_key(bob_keyfile_object, "password")
assert decrypted_secret_key.buffer == bob_secret_key.buffer

carol_secret_key = UserSecretKey.from_string("e253a571ca153dc2aee845819f74bcc9773b0586edead15a94cb7235a5027436")
carol_secret_key = UserSecretKey.new_from_string("e253a571ca153dc2aee845819f74bcc9773b0586edead15a94cb7235a5027436")
carol_wallet = UserWallet.from_secret_key(carol_secret_key, "password")
carol_keyfile_object = carol_wallet.to_dict("erd")
decrypted_secret_key = UserWallet.decrypt_secret_key(carol_keyfile_object, "password")
Expand Down
7 changes: 3 additions & 4 deletions multiversx_sdk/wallet/user_verifer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from multiversx_sdk.core.address import Address
from multiversx_sdk.wallet.interfaces import IAddress, ISignature
from multiversx_sdk.wallet.user_keys import UserPublicKey


Expand All @@ -8,10 +7,10 @@ def __init__(self, public_key: UserPublicKey) -> None:
self.public_key = public_key

@classmethod
def from_address(cls, address: IAddress) -> 'UserVerifier':
buffer: bytes = Address.new_from_bech32(address.to_bech32()).get_public_key()
def from_address(cls, address: Address) -> 'UserVerifier':
buffer: bytes = address.get_public_key()
public_key = UserPublicKey(buffer)
return UserVerifier(public_key)

def verify(self, data: bytes, signature: ISignature) -> bool:
def verify(self, data: bytes, signature: bytes) -> bool:
return self.public_key.verify(data, signature)
5 changes: 2 additions & 3 deletions multiversx_sdk/wallet/validator_keys.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from multiversx_sdk.wallet.constants import (VALIDATOR_PUBKEY_LENGTH,
VALIDATOR_SECRETKEY_LENGTH)
from multiversx_sdk.wallet.errors import InvalidSecretKeyLengthError
from multiversx_sdk.wallet.interfaces import ISignature
from multiversx_sdk.wallet.libraries.bls_facade import BLSFacade


Expand All @@ -26,7 +25,7 @@ def generate_public_key(self) -> 'ValidatorPublicKey':
public_key_bytes = BLSFacade().generate_public_key(self.buffer)
return ValidatorPublicKey(public_key_bytes)

def sign(self, data: bytes) -> ISignature:
def sign(self, data: bytes) -> bytes:
signature = BLSFacade().compute_message_signature(data, self.buffer)
return signature

Expand All @@ -52,7 +51,7 @@ def from_string(cls, buffer_hex: str) -> 'ValidatorPublicKey':
buffer = bytes.fromhex(buffer_hex)
return ValidatorPublicKey(buffer)

def verify(self, data: bytes, signature: ISignature) -> bool:
def verify(self, data: bytes, signature: bytes) -> bool:
ok = BLSFacade().verify_message_signature(self.buffer, data, signature)
return ok

Expand Down
5 changes: 2 additions & 3 deletions multiversx_sdk/wallet/validator_signer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from pathlib import Path

from multiversx_sdk.wallet.errors import CannotSignError
from multiversx_sdk.wallet.interfaces import ISignature
from multiversx_sdk.wallet.validator_keys import (ValidatorPublicKey,
ValidatorSecretKey)
from multiversx_sdk.wallet.validator_pem import ValidatorPEM
Expand All @@ -20,13 +19,13 @@ def from_pem_file(cls, path: Path, index: int = 0) -> 'ValidatorSigner':
secret_key = ValidatorPEM.from_file(path, index).secret_key
return ValidatorSigner(secret_key)

def sign(self, data: bytes) -> ISignature:
def sign(self, data: bytes) -> bytes:
try:
return self._try_sign(data)
except Exception as err:
raise CannotSignError() from err

def _try_sign(self, data: bytes) -> ISignature:
def _try_sign(self, data: bytes) -> bytes:
signature = self.secret_key.sign(data)
return signature

Expand Down
3 changes: 1 addition & 2 deletions multiversx_sdk/wallet/validator_verifier.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from multiversx_sdk.wallet.interfaces import ISignature
from multiversx_sdk.wallet.validator_keys import ValidatorPublicKey


Expand All @@ -11,5 +10,5 @@ def from_string(cls, buffer_hex: str) -> 'ValidatorVerifier':
public_key = ValidatorPublicKey.from_string(buffer_hex)
return ValidatorVerifier(public_key)

def verify(self, data: bytes, signature: ISignature) -> bool:
def verify(self, data: bytes, signature: bytes) -> bool:
return self.public_key.verify(data, signature)

0 comments on commit a2d83d3

Please sign in to comment.