Skip to content

Commit a4eac66

Browse files
authored
Merge branch 'main' into inactivity-unify-bot
Signed-off-by: Akshat8510 <akshat230405@gmail.com>
2 parents 73eb47a + aff0f16 commit a4eac66

File tree

2 files changed

+92
-3
lines changed

2 files changed

+92
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
1010
- Unified the inactivity-unassign bot into a single script with `DRY_RUN` support, and fixed handling of cross-repo PR references for stale detection.
1111
- Modularized `transfer_transaction_fungible` example by introducing `account_balance_query()` & `transfer_transaction()`.Renamed `transfer_tokens()``main()`
1212
- Phase 2 of the inactivity-unassign bot:Automatically detects stale open pull requests (no commit activity for 21+ days), comments with a helpful InactivityBot message, closes the stale PR, and unassigns the contributor from the linked issue.
13-
- Added **str**() to CustomFixedFee and updated examples and tests accordingly.
13+
- Added `__str__()` to CustomFixedFee and updated examples and tests accordingly.
14+
- Added unit tests for `crypto_utils` (#993)
1415
- Added a github template for good first issues
1516
- Added `.github/workflows/bot-assignment-check.yml` to limit non-maintainers to 2 concurrent issue assignments.
16-
- Added all missing fields to **str**() method and updated `test_tokem_info.py`
17+
- Added all missing fields to `__str__()` method and updated `test_tokem_info.py`
1718
- Add examples/tokens/token_create_transaction_pause_key.py example demonstrating token pause/unpause behavior and pause key usage (#833)
1819
- Added `docs/sdk_developers/training/transaction_lifecycle.md` to explain the typical lifecycle of executing a transaction using the Hedera Python SDK.
1920
- Add inactivity bot workflow to unassign stale issue assignees (#952)
2021
- Made custom fraction fee end to end
2122
- feat: AccountCreateTransaction now supports both PrivateKey and PublicKey [#939](https://github.com/hiero-ledger/hiero-sdk-python/issues/939)
2223
- Added Acceptance Criteria section to Good First Issue template for better contributor guidance (#997)
23-
- Added __str__() to CustomRoyaltyFee and updated examples and tests accordingly (#986)
24+
- Added `__str__()` to CustomRoyaltyFee and updated examples and tests accordingly (#986)
2425
- Restore bug and feature request issue templates (#996)(https://github.com/hiero-ledger/hiero-sdk-python/issues/996)
2526
- Support selecting specific node account ID(s) for queries and transactions and added `Network._get_node()` with updated execution flow (#362)
2627
- Add TLS support with two-stage control (`set_transport_security()` and `set_verify_certificates()`) for encrypted connections to Hedera networks. TLS is enabled by default for hosted networks (mainnet, testnet, previewnet) and disabled for local networks (solo, localhost) (#855)

tests/unit/test_crypto_utils.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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

Comments
 (0)