Add sign and verify capability to Identity
This commit is contained in:
parent
1d40bbebc5
commit
fcf9911121
@ -4,7 +4,7 @@ import re
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import bip39
|
import bip39
|
||||||
from ed25519 import SigningKey, VerifyingKey, create_keypair
|
from ed25519 import BadSignatureError, SigningKey, VerifyingKey, create_keypair
|
||||||
|
|
||||||
from .base32 import base32_bytes_to_string, base32_string_to_bytes
|
from .base32 import base32_bytes_to_string, base32_string_to_bytes
|
||||||
from .exc import ValidationError
|
from .exc import ValidationError
|
||||||
@ -23,8 +23,8 @@ class Identity:
|
|||||||
|
|
||||||
_KEY_PATTERN = f'b[{B32_CHAR}]{{52}}'
|
_KEY_PATTERN = f'b[{B32_CHAR}]{{52}}'
|
||||||
_NAME_PATTERN = f'[{ALPHA_LOWER}][{ALPHA_LOWER_OR_DIGIT}]{{3}}'
|
_NAME_PATTERN = f'[{ALPHA_LOWER}][{ALPHA_LOWER_OR_DIGIT}]{{3}}'
|
||||||
_PATTERN = f'^@{_NAME_PATTERN}\\.{_KEY_PATTERN}$'
|
|
||||||
_SECRET_PATTERN = f'^{_KEY_PATTERN}$'
|
_SECRET_PATTERN = f'^{_KEY_PATTERN}$'
|
||||||
|
PATTERN = f'^@{_NAME_PATTERN}\\.{_KEY_PATTERN}$'
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -143,3 +143,23 @@ class Identity:
|
|||||||
mnemonic = bip39.encode_bytes(seed)
|
mnemonic = bip39.encode_bytes(seed)
|
||||||
|
|
||||||
return f'{self.name} {mnemonic}'
|
return f'{self.name} {mnemonic}'
|
||||||
|
|
||||||
|
def sign(self, data: str) -> str:
|
||||||
|
"""Sign data"""
|
||||||
|
|
||||||
|
if not self.sign_key:
|
||||||
|
raise TypeError('This identity doesn’t have a signing key')
|
||||||
|
|
||||||
|
return base32_bytes_to_string(self.sign_key.sign(data.encode('utf-8')))
|
||||||
|
|
||||||
|
def verify(self, data: str, signature: str) -> bool:
|
||||||
|
"""Verify if data is signed by us"""
|
||||||
|
|
||||||
|
signature_bytes = base32_string_to_bytes(signature)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.verify_key.verify(signature_bytes, data.encode('utf-8'))
|
||||||
|
except BadSignatureError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
@ -199,3 +199,56 @@ def test_eq_other(identity: Identity) -> None:
|
|||||||
|
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
assert identity == 1
|
assert identity == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_sign_nokey() -> None:
|
||||||
|
"""Test if Identity.sign() fails if the identity doesn’t have a signing key available"""
|
||||||
|
|
||||||
|
identity_str = '@test.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya'
|
||||||
|
identity = Identity.from_address(identity_str)
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
identity.sign('test data')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.id_key_seed(TEST_SEED)
|
||||||
|
@pytest.mark.id_name('test')
|
||||||
|
def test_sign(identity: Identity) -> None:
|
||||||
|
"""Test if Identity.sign() works as expected"""
|
||||||
|
|
||||||
|
assert (
|
||||||
|
identity.sign('test data')
|
||||||
|
== 'b6gyis42cvdfhsp7xx3jb4773ebbqoq4zhdo4pyeitskefrfkkzxwdkwjkjpq2oyglpngx4tpzzezeedp7eb'
|
||||||
|
'x4i3vkpq7wj6odjinacy'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.id_key_seed(TEST_SEED)
|
||||||
|
@pytest.mark.id_name('test')
|
||||||
|
def test_verify(identity: Identity) -> None:
|
||||||
|
"""Test if Identity.verify works as expected"""
|
||||||
|
|
||||||
|
assert (
|
||||||
|
identity.verify(
|
||||||
|
'test data',
|
||||||
|
'b6gyis42cvdfhsp7xx3jb4773ebbqoq4zhdo4pyeitskefrfkkzxwdkwjkjpq2oyglpngx4tpzzezeedp7eb'
|
||||||
|
'x4i3vkpq7wj6odjinacy',
|
||||||
|
)
|
||||||
|
is True
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
identity.verify(
|
||||||
|
'test date',
|
||||||
|
'b6gyis42cvdfhsp7xx3jb4773ebbqoq4zhdo4pyeitskefrfkkzxwdkwjkjpq2oyglpngx4tpzzezeedp7eb'
|
||||||
|
'x4i3vkpq7wj6odjinacy',
|
||||||
|
)
|
||||||
|
is False
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
identity.verify(
|
||||||
|
'test data',
|
||||||
|
'b6gyis42cvdfhsp7xx3jb4773ebbqoq4zhdo4pyeitskefrfkkzxwdkwjkjpq2oyglpngx4tpzzezeedp7eb'
|
||||||
|
'x4i3vkpq7wj6odjinacq',
|
||||||
|
)
|
||||||
|
is False
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user