Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion tests/python/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ behave>=1.2.6

# Cryptographic utilities
pynacl>=1.5.0
ecdsa>=0.19.0
cryptography>=46.0.5
coincurve>=21.0.0

# Hex/bytes utilities
hexbytes>=1.0.0
Expand Down
95 changes: 65 additions & 30 deletions tests/python/steps/auth_key_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
PrivateKey as Ed25519PrivateKey,
)
from behave import given, when, then
from support.ecdsa_compat import (
NIST256P_AVAILABLE,
SECP256K1_AVAILABLE,
NIST256p,
SECP256k1,
SigningKey,
)
from support.vectors import get_signature_vectors
import sys
import os
import hashlib
Expand Down Expand Up @@ -61,33 +69,31 @@ def step_given_typed_public_key(context, key_type):
context.world.public_key_bytes = bytes(context.world.ed25519_public_key.key)
context.world.scheme_id = 0x00
elif key_type == "Secp256k1":
try:
from ecdsa import SECP256k1, SigningKey

private_key = SigningKey.generate(curve=SECP256k1)
# Compressed public key (33 bytes)
context.world.public_key_bytes = private_key.get_verifying_key().to_string(
"compressed"
)
context.world.scheme_id = 0x01
except ImportError:
if not SECP256K1_AVAILABLE:
context.world.set_error(
ImportError("ecdsa library not available for Secp256k1")
ImportError("Secp256k1 crypto backend not available")
Comment on lines +72 to +74
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

Error message inconsistency: secp256k1_steps.py uses "ecdsa library not available" while this file uses "Secp256k1 crypto backend not available" and "P-256 crypto backend not available". For consistency across the test suite, consider updating secp256k1_steps.py to use similar descriptive error messages, or use the same error message format in both files.

Copilot uses AI. Check for mistakes.
)
elif key_type == "Secp256r1":
try:
from ecdsa import NIST256p, SigningKey
return

private_key = SigningKey.generate(curve=NIST256p)
# Compressed public key (33 bytes)
context.world.public_key_bytes = private_key.get_verifying_key().to_string(
"compressed"
)
context.world.scheme_id = 0x02
except ImportError:
private_key = SigningKey.generate(curve=SECP256k1)
# Compressed public key (33 bytes)
context.world.public_key_bytes = private_key.get_verifying_key().to_string(
"compressed"
)
context.world.scheme_id = 0x01
elif key_type == "Secp256r1":
if not NIST256P_AVAILABLE:
context.world.set_error(
ImportError("ecdsa library not available for Secp256r1")
ImportError("P-256 crypto backend not available")
)
return

private_key = SigningKey.generate(curve=NIST256p)
# Compressed public key (33 bytes)
context.world.public_key_bytes = private_key.get_verifying_key().to_string(
"compressed"
)
context.world.scheme_id = 0x02
elif key_type == "MultiEd25519":
context.world.scheme_id = 0x01
elif key_type == "MultiKey":
Expand Down Expand Up @@ -125,20 +131,49 @@ def step_given_ed25519_from_test_vectors(context):

@given("Secp256k1 public key from test vectors")
def step_given_secp256k1_from_test_vectors(context):
try:
from ecdsa import SECP256k1, SigningKey
if not SECP256K1_AVAILABLE:
context.world.set_error(
ImportError("Secp256k1 crypto backend not available")
)
return

# Generate a deterministic Secp256k1 key for test vectors
private_key = SigningKey.generate(curve=SECP256k1)
try:
# Intentionally deterministic for reproducible vector-based assertions.
# This step is used for test-vector scenarios, not randomness checks.
secp_vectors = get_signature_vectors().get("secp256k1", {}).get(
"key_vectors", []
)
if not secp_vectors:
raise ValueError("missing secp256k1 key vectors in signatures.json")

key_vector = next(
(
vector
for vector in secp_vectors
if vector.get("name") == "secp256k1_key_from_seed"
),
secp_vectors[0],
)
private_key_hex = key_vector.get("input", {}).get("private_key_hex")
if not private_key_hex:
raise ValueError("missing private_key_hex in secp256k1 key vector")

normalized_hex = (
private_key_hex[2:]
if private_key_hex.startswith("0x")
else private_key_hex
)
private_key = SigningKey.from_string(
bytes.fromhex(normalized_hex),
curve=SECP256k1,
)
context.world.public_key_bytes = private_key.get_verifying_key().to_string(
"compressed"
)
context.world.scheme_id = 0x01
context.world.clear_error()
except ImportError:
context.world.set_error(
ImportError("ecdsa library not available for Secp256k1")
)
except Exception as e:
context.world.set_error(e)


# =============================================================================
Expand Down
9 changes: 7 additions & 2 deletions tests/python/steps/secp256k1_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@

# Try to import secp256k1 support
try:
from ecdsa import SECP256k1, SigningKey, VerifyingKey, BadSignatureError
from support.ecdsa_compat import (
BadSignatureError,
SECP256K1_AVAILABLE,
SECP256k1,
SigningKey,
VerifyingKey,
)

SECP256K1_AVAILABLE = True
except ImportError:
SECP256K1_AVAILABLE = False

Expand Down
Loading
Loading