"""Extract the byte representations PersonalizationApplet expects from PEM-encoded P-256 keys produced by ``aliro-trustgen init``. The applet stores raw scalars / raw uncompressed-point coordinates with fixed lengths (32 / 64 bytes), so we strip PEM/DER framing and BigInteger sign-padding here. """ from cryptography.hazmat.primitives.asymmetric import ec P256_COORD_LEN = 32 def extract_priv_scalar(private_key: ec.EllipticCurvePrivateKey) -> bytes: """Return the 32-byte big-endian P-256 private scalar.""" if not isinstance(private_key.curve, ec.SECP256R1): raise ValueError(f"expected P-256 (secp256r1), got {private_key.curve.name}") return _to_fixed_be(private_key.private_numbers().private_value, P256_COORD_LEN) def extract_pub_xy(public_key: ec.EllipticCurvePublicKey) -> bytes: """Return the 64-byte uncompressed point (x || y) without the 0x04 tag.""" if not isinstance(public_key.curve, ec.SECP256R1): raise ValueError(f"expected P-256 (secp256r1), got {public_key.curve.name}") nums = public_key.public_numbers() return _to_fixed_be(nums.x, P256_COORD_LEN) + _to_fixed_be(nums.y, P256_COORD_LEN) def _to_fixed_be(value: int, length: int) -> bytes: """Big-endian unsigned, zero-padded to exactly ``length`` bytes.""" return value.to_bytes(length, "big")