Add sign and verify capability to Identity

This commit is contained in:
Gergely Polonkai 2022-05-04 14:30:14 +02:00
parent 1d40bbebc5
commit fcf9911121
No known key found for this signature in database
GPG Key ID: 2D2885533B869ED4
2 changed files with 75 additions and 2 deletions

View File

@ -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 doesnt 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

View File

@ -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 doesnt 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
)