[#1] Add cryptography methods

Signed-off-by: ilyas585 <niyazov2023@gmail.com>
This commit is contained in:
ilyas585 2025-02-12 11:52:47 +03:00
parent 480d288e2a
commit 19282f13cc
14 changed files with 268 additions and 0 deletions

8
tests/conftest.py Normal file
View file

@ -0,0 +1,8 @@
import pytest
from tests.helpers.models import ClientCryptograpy
@pytest.fixture(scope="session")
def client_cryptography():
return ClientCryptograpy()

View file

@ -0,0 +1,39 @@
import pytest
from tests.helpers.models import ClientCryptograpy
from tests.helpers.convert import convert_bytes_format_127_to_256
from tests.helpers.resources import WIF, PRIVATE_KEY
@pytest.mark.crypto
class TestKeyExtension:
def test_get_private_key_from_wif_success(self, client_cryptography: ClientCryptograpy):
private_key = client_cryptography.key_extension.get_private_key_from_wif(WIF)
assert len(private_key) == 32, f"Not correct len of private key, expected: 32 Actual: {len(private_key)} "
assert isinstance(private_key, bytes), f"Not correct type of private key, Expected bytes, Actual: {type(private_key)}"
assert private_key == bytes(convert_bytes_format_127_to_256(PRIVATE_KEY)), \
f"Not match private key, Expected: {PRIVATE_KEY}, Actual: {private_key}"
def test_get_private_key_empty_wif(self, client_cryptography: ClientCryptograpy):
with pytest.raises(ValueError, match="Empty"):
client_cryptography.key_extension.get_private_key_from_wif("")
def test_get_private_key_incorrect_wif(self, client_cryptography: ClientCryptograpy):
with pytest.raises(ValueError, match="Invalid checksum"):
client_cryptography.key_extension.get_private_key_from_wif("AAAAAAABBBBBBBBBBBCCCCCCCDDDDDDDDDDDDDDDDD")
def test_get_public_key(self, client_cryptography: ClientCryptograpy):
private_key = client_cryptography.key_extension.get_private_key_from_wif(WIF)
public_key = client_cryptography.key_extension.get_public_key(private_key)
assert len(public_key) == 33, f"Not correct len of public key, expected: 33 Actual: {len(private_key)} "
assert isinstance(public_key, bytes), f"Not correct type of public key, Expected bytes, Actual: {type(private_key)}"
def test_get_public_key_empty(self, client_cryptography: ClientCryptograpy):
with pytest.raises(ValueError, match="Empty"):
client_cryptography.key_extension.get_public_key(b"")
def test_get_public_key_invalid_private_key(self, client_cryptography: ClientCryptograpy):
with pytest.raises(ValueError):
client_cryptography.key_extension.get_public_key(b"invalid_private_key")

View file

@ -0,0 +1,55 @@
import pytest
from tests.helpers.models import ClientCryptograpy
from tests.helpers.resources import WIF, MESSAGE_IN_BYTES
@pytest.mark.crypto
class TestSignAndVerify:
def test_sign_rfc6979_success(self, client_cryptography: ClientCryptograpy):
private_key = client_cryptography.key_extension.get_private_key_from_wif(WIF)
signature = client_cryptography.signer.sign_rfc6979(private_key, MESSAGE_IN_BYTES)
assert len(signature) == 64, f"Incorrect len of signature, Expected: 64, Actual: {len(signature)}"
assert isinstance(signature, bytes), f"Not correct type of signature, Expected bytes, Actual: {type(signature)}"
def test_sign_success(self, client_cryptography: ClientCryptograpy):
private_key = client_cryptography.key_extension.get_private_key_from_wif(WIF)
signature = client_cryptography.signer.sign(private_key, MESSAGE_IN_BYTES)
assert 0x04 == signature[0], "First byte is not expected node marker"
assert isinstance(signature, bytes), f"Not correct type of signature, Expected bytes, Actual: {type(signature)}"
@pytest.mark.parametrize("message", [MESSAGE_IN_BYTES, b""])
def test_verify_rfc6979_success(self, client_cryptography: ClientCryptograpy, message: bytes):
private_key = client_cryptography.key_extension.get_private_key_from_wif(WIF)
public_key = client_cryptography.key_extension.get_public_key(private_key)
signature = client_cryptography.signer.sign_rfc6979(private_key, message)
assert client_cryptography.verifier.verify_rfc6979(public_key, message, signature) is True
@pytest.mark.parametrize("message", [MESSAGE_IN_BYTES, b""])
def test_verify_success(self, client_cryptography: ClientCryptograpy, message: bytes):
private_key = client_cryptography.key_extension.get_private_key_from_wif(WIF)
public_key = client_cryptography.key_extension.get_public_key(private_key)
signature = client_cryptography.signer.sign(private_key, message)
# skip first byte, because it marker of version for node
assert client_cryptography.verifier.verify(public_key, message, signature[1:]) is True
# = = = = = = = = = = = = = = = = = = = = = NEGATIVE cases = = = = = = = = = = = = = = = = = = = = =
def test_verify_empty_public_key(self, client_cryptography: ClientCryptograpy):
with pytest.raises(ValueError, match="Incorrect public key"):
client_cryptography.verifier.verify(b'', b"Test message", b"signature")
def test_verify_invalid_signature(self, client_cryptography: ClientCryptograpy):
invalid_signature = b"invalid_signature"
private_key = client_cryptography.key_extension.get_private_key_from_wif(WIF)
public_key = client_cryptography.key_extension.get_public_key(private_key)
assert not client_cryptography.verifier.verify(public_key, MESSAGE_IN_BYTES, invalid_signature), "Verified invalid signature"
def test_sign_empty_key(self, client_cryptography: ClientCryptograpy):
with pytest.raises(ValueError, match="Incorrect private key"):
client_cryptography.signer.sign(b'', MESSAGE_IN_BYTES)

18
tests/helpers/convert.py Normal file
View file

@ -0,0 +1,18 @@
def convert_bytes_format_127_to_256(numbers: list[int]):
new_list = []
for num in numbers:
if num > 0:
new_list.append(num)
else:
new_list.append(num + 256)
return new_list
def convert_bytes_format_256_to_127(numbers: list[int]):
new_list = []
for num in numbers:
if num < 128:
new_list.append(num)
else:
new_list.append(num - 256)
return new_list

10
tests/helpers/models.py Normal file
View file

@ -0,0 +1,10 @@
from frostfs_api.cryptography.key_extension import KeyExtension
from frostfs_api.cryptography.verifier import Verifier
from frostfs_api.cryptography.signer import Signer
class ClientCryptograpy:
def __init__(self):
self.key_extension = KeyExtension()
self.signer = Signer()
self.verifier = Verifier()

View file

@ -0,0 +1,6 @@
WIF = "L1YS4myg3xHPvi3FHeLaEt7G8upwJaWL5YLV7huviuUtXFpzBMqZ"
PRIVATE_KEY = [
-128, -5, 30, -36, -118, 85, -67, -6, 81, 43, 93, -38, 106, 21, -88, 127, 15, 125, -79, -17, -40, 77, -15,
122, -88, 72, 109, -47, 125, -80, -40, -38
]
MESSAGE_IN_BYTES = b"any message in bytes format"