def jwk(key: EllipticCurvePublicKey) -> dict: return { 'kty': 'EC', 'crv': 'P-256', 'x': b64url(key.public_numbers().x.to_bytes(32, 'big')), 'y': b64url(key.public_numbers().y.to_bytes(32, 'big')), }
def _generate_ecc_seed(key: ec.EllipticCurvePublicKey, hashAlg: int, label: bytes) -> Tuple[bytes, bytes]: halg = _get_digest(hashAlg) if halg is None: raise ValueError(f"unsupported digest algorithm {hashAlg}") ekey = ec.generate_private_key(key.curve, default_backend()) epubnum = ekey.public_key().public_numbers() plength = int(key.curve.key_size / 8) # FIXME ceiling here exbytes = epubnum.x.to_bytes(plength, "big") eybytes = epubnum.y.to_bytes(plength, "big") # workaround marshal of TPMS_ECC_POINT secret = (len(exbytes).to_bytes(length=2, byteorder="big") + exbytes + len(eybytes).to_bytes(length=2, byteorder="big") + eybytes) shared_key = ekey.exchange(ec.ECDH(), key) pubnum = key.public_numbers() xbytes = pubnum.x.to_bytes(plength, "big") seed = kdfe(hashAlg, shared_key, label, exbytes, xbytes, halg.digest_size * 8) return (seed, secret)
def compress_pubkey(public_key: EllipticCurvePublicKey): uncompressed = public_key.public_numbers().encode_point() key_size = public_key.curve.key_size return bytes([2 + (uncompressed[-1] & 1)]) + uncompressed[1:key_size // 8 + 1]