Skip to content

Conversation

@adityashirsatrao007
Copy link
Owner

Fixes hiero-ledger#993. Adds unit tests for keccak256, compress_point, and decompress_point in crypto_utils.py.

Copilot AI review requested due to automatic review settings December 8, 2025 13:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds unit tests for the crypto_utils module to address issue hiero-ledger#993. The tests cover the core cryptographic utility functions: keccak256 for hashing, compress_point_unchecked and compress_with_cryptography for point compression, and decompress_point for point decompression on the secp256k1 elliptic curve.

Key Changes:

  • Adds comprehensive tests for Keccak-256 hashing with known test vectors
  • Tests elliptic curve point compression and decompression functionality
  • Validates both compressed (33-byte) and uncompressed (65-byte) point formats

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +39 to +64
def test_decompress_point():
"""Test point decompression logic."""
priv = ec.generate_private_key(ec.SECP256K1())
pub = priv.public_key()
nums = pub.public_numbers()

# Create valid compressed point
compressed = compress_point_unchecked(nums.x, nums.y)

# Test decompression
x, y = decompress_point(compressed)
assert x == nums.x
assert y == nums.y

# Test uncompressed 65-byte format (0x04 + x + y)
uncompressed = b'\x04' + nums.x.to_bytes(32, 'big') + nums.y.to_bytes(32, 'big')
x2, y2 = decompress_point(uncompressed)
assert x2 == nums.x
assert y2 == nums.y

Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for error handling in decompress_point. The function raises ValueError when the input is not a valid compressed or uncompressed point (see crypto_utils.py line 51). Consider adding a test case like:

def test_decompress_point_invalid_format():
    \"\"\"Test that invalid point format raises ValueError.\"\"\"
    with pytest.raises(ValueError, match="Not recognized as compressed or uncompressed SEC1 point"):
        decompress_point(b"invalid")

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +22
def test_keccak256():
"""Test keccak256 hashing."""
# Known vector: empty string -> c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
assert keccak256(b"").hex() == "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"

# "hello" -> 1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
assert keccak256(b"hello").hex() == "1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8"

Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for error handling in keccak256. The function raises RuntimeError when the pycryptodome library is not available (see crypto_utils.py line 24). Consider adding a test case to verify this behavior or at least document that it's tested elsewhere.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 88
"""Unit tests for crypto_utils module."""
from cryptography.hazmat.primitives.asymmetric import ec

from hiero_sdk_python.utils.crypto_utils import (
compress_point_unchecked,
compress_with_cryptography,
decompress_point,
keccak256,
)


def test_keccak256():
"""Test keccak256 hashing."""
# Known vector: empty string -> c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
assert keccak256(b"").hex() == "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"

# "hello" -> 1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
assert keccak256(b"hello").hex() == "1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8"


def test_compress_point_unchecked():
"""Test point compression logic."""
# Use cryptography to generate a valid point
priv = ec.generate_private_key(ec.SECP256K1())
pub = priv.public_key()
nums = pub.public_numbers()
x = nums.x
y = nums.y

compressed = compress_point_unchecked(x, y)
assert len(compressed) == 33

# Verify expected prefix
expected_prefix = 0x03 if y % 2 else 0x02
assert compressed[0] == expected_prefix
assert int.from_bytes(compressed[1:], "big") == x


def test_decompress_point():
"""Test point decompression logic."""
priv = ec.generate_private_key(ec.SECP256K1())
pub = priv.public_key()
nums = pub.public_numbers()

# Create valid compressed point
compressed = compress_point_unchecked(nums.x, nums.y)

# Test decompression
x, y = decompress_point(compressed)
assert x == nums.x
assert y == nums.y

# Test uncompressed 65-byte format (0x04 + x + y)
uncompressed = b'\x04' + nums.x.to_bytes(32, 'big') + nums.y.to_bytes(32, 'big')
x2, y2 = decompress_point(uncompressed)
assert x2 == nums.x
assert y2 == nums.y


def test_compress_with_cryptography():
"""Test compression using cryptography library."""
priv = ec.generate_private_key(ec.SECP256K1())
pub = priv.public_key()
nums = pub.public_numbers()

# Create uncompressed
uncompressed = b'\x04' + nums.x.to_bytes(32, 'big') + nums.y.to_bytes(32, 'big')

compressed_via_lib = compress_with_cryptography(uncompressed)
compressed_manual = compress_point_unchecked(nums.x, nums.y)

assert compressed_via_lib == compressed_manual
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test file naming convention in this codebase is test_<module>.py, not <module>_test.py. This file should be renamed to test_crypto_utils.py to match other test files like test_entity_id_helper.py, test_key_utils.py, etc.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +14


Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing pytest import and pytestmark = pytest.mark.unit marker. All other unit test files in this codebase include these. Add:

import pytest

pytestmark = pytest.mark.unit

after the imports and before the first test function.

Suggested change
import pytest
pytestmark = pytest.mark.unit

Copilot uses AI. Check for mistakes.
@adityashirsatrao007 adityashirsatrao007 force-pushed the test/issue-993-crypto-utils branch 3 times, most recently from 27a104f to 3e36344 Compare December 10, 2025 09:48
@github-actions
Copy link

Hi, this is MergeConflictBot.
Your pull request cannot be merged because it contains merge conflicts.

Please resolve these conflicts locally and push the changes.

To assist you, please read:

Thank you for contributing!

From the Hiero Python SDK Team

@adityashirsatrao007 adityashirsatrao007 force-pushed the test/issue-993-crypto-utils branch 2 times, most recently from 0a2de6e to a66e0a6 Compare December 10, 2025 10:22
@adityashirsatrao007 adityashirsatrao007 changed the base branch from feat/add-acceptance-criteria-template to main December 10, 2025 10:22
@adityashirsatrao007 adityashirsatrao007 force-pushed the test/issue-993-crypto-utils branch 2 times, most recently from d1d5713 to 6d5e74e Compare December 10, 2025 11:15
dependabot bot and others added 6 commits December 10, 2025 11:17
…iero-ledger#1026)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: adityashirsatrao007 <adityashirsatrao007@gmail.com>
Signed-off-by: adityashirsatrao007 <adityashirsatrao007@gmail.com>
Signed-off-by: adityashirsatrao007 <adityashirsatrao007@gmail.com>
Signed-off-by: adityashirsatrao007 <adityashirsatrao007@gmail.com>
Signed-off-by: adityashirsatrao007 <adityashirsatrao007@gmail.com>
@adityashirsatrao007 adityashirsatrao007 force-pushed the test/issue-993-crypto-utils branch from 6d5e74e to 0fdd761 Compare December 10, 2025 11:20
@github-actions
Copy link

Hello, this is the Office Hour Bot.

This is a reminder that the Hiero Python SDK Office Hours are scheduled in approximately 4 hours (14:00 UTC).

This session provides an opportunity to ask questions regarding this Pull Request or receive assistance from a maintainer.

Details:

Disclaimer: This is an automated reminder. Please verify the schedule here to be notified of any changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create tests/unit/crypto_utils_test.py

2 participants