|
| 1 | +"""Unit tests for crypto_utils module.""" |
| 2 | +from cryptography.hazmat.primitives.asymmetric import ec |
| 3 | +import pytest |
| 4 | + |
| 5 | +from hiero_sdk_python.utils.crypto_utils import ( |
| 6 | + compress_point_unchecked, |
| 7 | + compress_with_cryptography, |
| 8 | + decompress_point, |
| 9 | + keccak256, |
| 10 | +) |
| 11 | + |
| 12 | +pytestmark = pytest.mark.unit |
| 13 | + |
| 14 | + |
| 15 | +def test_keccak256(): |
| 16 | + """Test keccak256 hashing.""" |
| 17 | + # Known vector: empty string -> c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 |
| 18 | + assert keccak256(b"").hex() == "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" |
| 19 | + |
| 20 | + # "hello" -> 1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8 |
| 21 | + assert keccak256(b"hello").hex() == "1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8" |
| 22 | + |
| 23 | + # "Transfer" -> 461a29a8a7db848c0827103038dd4776114eb182e0717208d0a793574936353d |
| 24 | + assert keccak256(b"Transfer").hex() == "f099cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" |
| 25 | + |
| 26 | + |
| 27 | +def test_compress_point_unchecked(): |
| 28 | + """Test point compression logic.""" |
| 29 | + # Use cryptography to generate a valid point |
| 30 | + priv = ec.generate_private_key(ec.SECP256K1()) |
| 31 | + pub = priv.public_key() |
| 32 | + nums = pub.public_numbers() |
| 33 | + x = nums.x |
| 34 | + y = nums.y |
| 35 | + |
| 36 | + compressed = compress_point_unchecked(x, y) |
| 37 | + assert len(compressed) == 33 |
| 38 | + |
| 39 | + # Verify expected prefix |
| 40 | + expected_prefix = 0x03 if y % 2 else 0x02 |
| 41 | + assert compressed[0] == expected_prefix |
| 42 | + assert int.from_bytes(compressed[1:], "big") == x |
| 43 | + |
| 44 | + |
| 45 | +def test_decompress_point(): |
| 46 | + """Test point decompression logic.""" |
| 47 | + priv = ec.generate_private_key(ec.SECP256K1()) |
| 48 | + pub = priv.public_key() |
| 49 | + nums = pub.public_numbers() |
| 50 | + |
| 51 | + # Create valid compressed point |
| 52 | + compressed = compress_point_unchecked(nums.x, nums.y) |
| 53 | + |
| 54 | + # Test decompression |
| 55 | + x, y = decompress_point(compressed) |
| 56 | + assert x == nums.x |
| 57 | + assert y == nums.y |
| 58 | + |
| 59 | + # Test uncompressed 65-byte format (0x04 + x + y) |
| 60 | + uncompressed = b'\x04' + nums.x.to_bytes(32, 'big') + nums.y.to_bytes(32, 'big') |
| 61 | + x2, y2 = decompress_point(uncompressed) |
| 62 | + assert x2 == nums.x |
| 63 | + assert y2 == nums.y |
| 64 | + |
| 65 | + # Test invalid length |
| 66 | + with pytest.raises(ValueError, match="Not recognized"): |
| 67 | + decompress_point(b'\x04' * 10) |
| 68 | + |
| 69 | + # Test invalid prefix |
| 70 | + with pytest.raises(ValueError, match="Not recognized"): |
| 71 | + # 0x05 is invalid prefix for 33-byte point |
| 72 | + invalid_point = b'\x05' + nums.x.to_bytes(32, 'big') |
| 73 | + decompress_point(invalid_point) |
| 74 | + |
| 75 | + |
| 76 | +def test_compress_with_cryptography(): |
| 77 | + """Test compression using cryptography library.""" |
| 78 | + priv = ec.generate_private_key(ec.SECP256K1()) |
| 79 | + pub = priv.public_key() |
| 80 | + nums = pub.public_numbers() |
| 81 | + |
| 82 | + # Create uncompressed |
| 83 | + uncompressed = b'\x04' + nums.x.to_bytes(32, 'big') + nums.y.to_bytes(32, 'big') |
| 84 | + |
| 85 | + compressed_via_lib = compress_with_cryptography(uncompressed) |
| 86 | + compressed_manual = compress_point_unchecked(nums.x, nums.y) |
| 87 | + |
| 88 | + assert compressed_via_lib == compressed_manual |
0 commit comments