BoundedAuthorityProtocol.V3.EcJwk (Bounded Authority Protocol v1.0.0)

Copy Markdown View Source

Exact public P-256 EC JWK encoding, decoding, and RFC 7638 thumbprints for the BAP3-ES256-SHA256 suite.

The raw public key is the 65-byte uncompressed SEC1 point 0x04 || x || y; the wire JWK is exactly {"crv":"P-256","kty":"EC","x":…,"y":…}. The decoded point is validated on-curve by pure arithmetic before any crypto backend call, so the closed rejection is deterministic across backends.

Summary

Functions

Decodes an exact public EC JWK to the raw 65-byte uncompressed SEC1 point.

Encodes one raw 65-byte uncompressed SEC1 public key as the canonical public EC JWK.

Returns the raw 32-byte SHA-256 RFC 7638 thumbprint of a raw 65-byte uncompressed SEC1 P-256 public key (0x04 || x || y).

Returns the canonical base64url RFC 7638 thumbprint.

Returns the exact RFC 7638 public EC thumbprint preimage.

Returns the raw 32-byte SHA-256 RFC 7638 thumbprint of an exact public EC JWK.

Functions

decode_public(jwk, limits)

@spec decode_public(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, binary()} | {:error, :invalid}

Decodes an exact public EC JWK to the raw 65-byte uncompressed SEC1 point.

encode_public(public_key, limits)

@spec encode_public(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, binary()} | {:error, :invalid}

Encodes one raw 65-byte uncompressed SEC1 public key as the canonical public EC JWK.

public_key_thumbprint_raw(public_key, limits)

@spec public_key_thumbprint_raw(
  binary(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) ::
  {:ok, binary()} | {:error, :invalid}

Returns the raw 32-byte SHA-256 RFC 7638 thumbprint of a raw 65-byte uncompressed SEC1 P-256 public key (0x04 || x || y).

Equivalent to encode_public/2 followed by thumbprint_raw/2. Use it to compute the holder confirmation a BoundedAuthorityProtocol.V3.Grant carries: pass the raw digest as holder_thumbprint (the producer base64url-encodes it into the cnf.jkt claim). A point that fails BoundedAuthorityProtocol.Es256.acceptable_public_key?/1 is {:error, :invalid}.

Example

iex> public_key =
...>   Base.decode16!(
...>     "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" <>
...>       "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
...>   )
iex> {:ok, digest} = BoundedAuthorityProtocol.V3.EcJwk.public_key_thumbprint_raw(public_key, %{})
iex> Base.url_encode64(digest, padding: false)
"xx0BcA-wMohw8atYDJOe6peGModklG2wRHBlXHMvl0M"

thumbprint(jwk, limits)

@spec thumbprint(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, binary()} | {:error, :invalid}

Returns the canonical base64url RFC 7638 thumbprint.

thumbprint_preimage(jwk, limits)

@spec thumbprint_preimage(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, binary()} | {:error, :invalid}

Returns the exact RFC 7638 public EC thumbprint preimage.

thumbprint_raw(jwk, limits)

@spec thumbprint_raw(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, binary()} | {:error, :invalid}

Returns the raw 32-byte SHA-256 RFC 7638 thumbprint of an exact public EC JWK.

This is the digest thumbprint/2 base64url-encodes. The JWK must be the exact canonical member set decode_public/2 accepts, carrying an on-curve P-256 point; anything else is {:error, :invalid}.

Example

iex> jwk =
...>   ~s({"crv":"P-256","kty":"EC","x":"axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpY","y":"T-NC4v4af5uO5-tKfA-eFivOM1drMV7Oy7ZAaDe_UfU"})
iex> {:ok, digest} = BoundedAuthorityProtocol.V3.EcJwk.thumbprint_raw(jwk, %{})
iex> Base.url_encode64(digest, padding: false)
"xx0BcA-wMohw8atYDJOe6peGModklG2wRHBlXHMvl0M"