duckdb-cudasp-extension/scripts/decompress_tweak_key.py
2025-10-28 10:50:49 +02:00

75 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""
Decompress the tweak_key from compressed SEC1 format to uncompressed little-endian x||y format.
"""
import sys
import os
# Add gECC scripts to path
script_dir = os.path.dirname(os.path.abspath(__file__))
gecc_scripts_dir = os.path.join(script_dir, '..', 'gECC', 'scripts')
sys.path.insert(0, gecc_scripts_dir)
from constants import SECP256K1_q
p = SECP256K1_q
# Compressed tweak_key
compressed_hex = "024ac253c216532e961988e2a8ce266a447c894c781e52ef6cee902361db960004"
print("=== Decompressing tweak_key ===\n")
print(f"Compressed form: {compressed_hex}")
# Parse prefix and x-coordinate
prefix = int(compressed_hex[0:2], 16)
x_hex = compressed_hex[2:]
x = int(x_hex, 16)
print(f"Prefix: 0x{prefix:02x} ({'even y' if prefix == 0x02 else 'odd y'})")
print(f"X (big-endian): {x:064x}")
# Decompress: compute y from x
# y^2 = x^3 + 7 (mod p)
y_squared = (pow(x, 3, p) + 7) % p
# Compute square root using Tonelli-Shanks (or use pow for p ≡ 3 mod 4)
# For secp256k1, p ≡ 3 mod 4, so we can use: y = y_squared^((p+1)/4) mod p
y = pow(y_squared, (p + 1) // 4, p)
# Choose the correct y based on parity
if (y % 2) == (prefix % 2):
# y has correct parity
pass
else:
# Negate y
y = p - y
print(f"Y (big-endian): {y:064x}")
# Verify the point is on the curve
y_squared_check = (y * y) % p
x_cubed_plus_7 = (pow(x, 3, p) + 7) % p
if y_squared_check == x_cubed_plus_7:
print("✓ Point is on the curve")
else:
print("✗ ERROR: Point is NOT on the curve!")
sys.exit(1)
print()
# Convert to little-endian format for our test
x_le_bytes = x.to_bytes(32, 'big')[::-1] # Reverse to little-endian
y_le_bytes = y.to_bytes(32, 'big')[::-1] # Reverse to little-endian
uncompressed_le = x_le_bytes + y_le_bytes
print("=== Uncompressed little-endian x||y format ===")
print(f"X (little-endian): {x_le_bytes.hex()}")
print(f"Y (little-endian): {y_le_bytes.hex()}")
print()
print(f"Full uncompressed (64 bytes, little-endian x||y):")
print(f" {uncompressed_le.hex()}")
print()
print(f"BLOB format:")
print(f" BLOB '\\x{uncompressed_le.hex()}'")