Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update user keys to specs #165

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
Loading