gose/key

Format-neutral key type for JOSE and COSE operations.

Use gose/jose/jwk for JSON (JWK) serialization and gose/cose/key for CBOR (COSE_Key) serialization.

Example

import gose/key
import kryptos/ec

// Generate an EC key and attach metadata
let k =
  key.generate_ec(ec.P256)
  |> key.with_kid("my-signing-key")

Supported Key Types

Types

Algorithm union type for the key alg field. A key can specify either a signing algorithm or a key encryption algorithm.

pub type Alg {
  SigningAlg(algorithm.SigningAlg)
  KeyEncryptionAlg(algorithm.KeyEncryptionAlg)
  ContentAlg(algorithm.ContentAlg)
}

Constructors

A cryptographic key.

Use constructor functions like from_octet_bits, from_der, from_pem, or generate_* to create keys.

pub opaque type Key(kid)

Key Operations parameter.

Identifies the operation(s) for which the key is intended.

pub type KeyOp {
  Sign
  Verify
  Encrypt
  Decrypt
  WrapKey
  UnwrapKey
  DeriveKey
  DeriveBits
}

Constructors

  • Sign

    Compute digital signature or MAC

  • Verify

    Verify digital signature or MAC

  • Encrypt

    Encrypt content

  • Decrypt

    Decrypt content and validate decryption

  • WrapKey

    Encrypt key

  • UnwrapKey

    Decrypt key and validate decryption

  • DeriveKey

    Derive key

  • DeriveBits

    Derive bits not to be used as a key

Key type identifier (kty parameter).

pub type KeyType {
  OctKeyType
  RsaKeyType
  EcKeyType
  OkpKeyType
}

Constructors

  • OctKeyType

    Symmetric key (oct)

  • RsaKeyType

    RSA key

  • EcKeyType

    Elliptic Curve key

  • OkpKeyType

    Octet Key Pair (EdDSA, XDH)

Public Key Use parameter.

Indicates whether the key is for signing or encryption.

pub type KeyUse {
  Signing
  Encrypting
}

Constructors

  • Signing

    Key is used for signature operations

  • Encrypting

    Key is used for encryption operations

Values

pub fn alg(key: Key(kid)) -> Result(Alg, Nil)

Get the algorithm (alg) parameter.

pub fn ec_curve(
  key: Key(kid),
) -> Result(ec.Curve, gose.GoseError)

Get the curve used by an EC key.

Returns an error if the key is not an EC key.

pub fn ec_public_key(
  key: Key(kid),
) -> Result(ec.PublicKey, gose.GoseError)

Extract the EC public key.

Works with both EC private keys (extracts the public component) and EC public keys.

Returns an error if the key is not an EC key.

pub fn ec_public_key_coordinates(
  key: Key(kid),
) -> Result(#(BitArray, BitArray), gose.GoseError)

Get the x and y coordinates from an EC public key.

The coordinates are returned as raw big-endian bytes, padded to the coordinate size for the curve.

Returns an error if the key is not an EC key.

pub fn ec_public_key_from_coordinates(
  curve: ec.Curve,
  x x: BitArray,
  y y: BitArray,
) -> Result(Key(kid), gose.GoseError)

Create an EC public key from curve and x,y coordinates (big-endian bytes).

pub fn eddsa_curve(
  key: Key(kid),
) -> Result(eddsa.Curve, gose.GoseError)

Get the curve used by an EdDSA key.

Returns an error if the key is not an EdDSA key.

pub fn eddsa_public_key(
  key: Key(kid),
) -> Result(eddsa.PublicKey, gose.GoseError)

Extract the EdDSA public key.

Works with both EdDSA private keys (extracts the public component) and EdDSA public keys.

Returns an error if the key is not an EdDSA key.

pub fn from_der(
  der: BitArray,
) -> Result(Key(kid), gose.GoseError)

Create a key from DER-encoded data.

Auto-detects key type (RSA, EC, EdDSA, XDH) and format (PKCS#1, PKCS#8, SPKI). Supports both private and public keys.

pub fn from_eddsa_bits(
  curve: eddsa.Curve,
  private_bits private_bits: BitArray,
) -> Result(Key(kid), gose.GoseError)

Create an EdDSA key pair from raw private key bytes.

The public key is derived from the private key. This is the inverse of to_octet_bits for EdDSA private keys.

pub fn from_eddsa_public_bits(
  curve: eddsa.Curve,
  public_bits public_bits: BitArray,
) -> Result(Key(kid), gose.GoseError)

Create an EdDSA public key from raw bytes.

This is the inverse of to_octet_bits for EdDSA public keys.

pub fn from_octet_bits(
  secret: BitArray,
) -> Result(Key(kid), gose.GoseError)

Create a symmetric key from raw bytes.

Used for HMAC signing (HS256/384/512) and direct encryption. Returns an error if the secret is empty.

Example

let secret = crypto.random_bytes(32)
let assert Ok(key) = key.from_octet_bits(secret)
pub fn from_pem(pem: String) -> Result(Key(kid), gose.GoseError)

Create a key from PEM-encoded data.

Auto-detects key type (RSA, EC, EdDSA, XDH) and format (PKCS#1, PKCS#8, SPKI). Supports both private and public keys.

pub fn from_xdh_bits(
  curve: xdh.Curve,
  private_bits private_bits: BitArray,
) -> Result(Key(kid), gose.GoseError)

Create an XDH key pair from raw private key bytes.

The public key is derived from the private key. This is the inverse of to_octet_bits for XDH private keys.

pub fn from_xdh_public_bits(
  curve: xdh.Curve,
  public_bits public_bits: BitArray,
) -> Result(Key(kid), gose.GoseError)

Create an XDH public key from raw bytes.

This is the inverse of to_octet_bits for XDH public keys.

pub fn generate_aes_kw_key(
  size: algorithm.AesKeySize,
) -> Key(kid)

Generate a symmetric key for AES Key Wrap.

The key size is derived from the AES variant:

  • Aes128 → 16 bytes
  • Aes192 → 24 bytes
  • Aes256 → 32 bytes
pub fn generate_chacha20_kw_key() -> Key(kid)

Generate a symmetric key for ChaCha20-Poly1305 Key Wrap (C20PKW / XC20PKW).

Always generates a 32-byte key, as both ChaCha20 and XChaCha20 use 256-bit keys.

pub fn generate_ec(curve: ec.Curve) -> Key(kid)

Generate a new EC key pair for the given curve.

Supported curves: P256, P384, P521, Secp256k1.

pub fn generate_eddsa(curve: eddsa.Curve) -> Key(kid)

Generate a new EdDSA key pair for the given curve.

Supported curves: Ed25519, Ed448.

pub fn generate_enc_key(enc: algorithm.ContentAlg) -> Key(kid)

Generate a symmetric key for JWE content encryption.

The key size is derived from the encryption algorithm:

  • AesGcm(Aes128) → 16 bytes
  • AesGcm(Aes192) → 24 bytes
  • AesGcm(Aes256) → 32 bytes
  • AesCbcHmac(Aes128) → 32 bytes (16 + 16 for MAC)
  • AesCbcHmac(Aes192) → 48 bytes (24 + 24 for MAC)
  • AesCbcHmac(Aes256) → 64 bytes (32 + 32 for MAC)
  • ChaCha20Poly1305 → 32 bytes
  • XChaCha20Poly1305 → 32 bytes
pub fn generate_hmac_key(alg: algorithm.HmacAlg) -> Key(kid)

Generate a symmetric key for HMAC signing.

The key size is derived from the algorithm:

  • HmacSha256 → 32 bytes
  • HmacSha384 → 48 bytes
  • HmacSha512 → 64 bytes
pub fn generate_rsa(
  bits: Int,
) -> Result(Key(kid), gose.GoseError)

Generate a new RSA key pair with the given key size in bits. Common sizes are 2048, 3072, and 4096. Keys smaller than 2048 bits are not recommended for security.

pub fn generate_xdh(curve: xdh.Curve) -> Key(kid)

Generate a new XDH key pair for key agreement.

Supported curves: X25519, X448.

pub fn key_ops(key: Key(kid)) -> Result(List(KeyOp), Nil)

Get the key operations parameter.

pub fn key_type(key: Key(kid)) -> KeyType

Get the key type (kty) for this key.

pub fn key_use(key: Key(kid)) -> Result(KeyUse, Nil)

Get the public key use parameter.

pub fn kid(key: Key(kid)) -> Result(kid, Nil)

Get the key ID (kid) parameter.

The return type depends on the key’s kid type parameter:

  • Key(String) (from JWK) → Result(String, Nil)
  • Key(BitArray) (from COSE) → Result(BitArray, Nil)
pub fn octet_key_size(
  key: Key(kid),
) -> Result(Int, gose.GoseError)

Get the size of an octet (symmetric) key in bytes.

Returns an error if the key is not an octet key.

pub fn public_key(
  key: Key(kid),
) -> Result(Key(kid), gose.GoseError)

Extract the public key from an asymmetric key.

For private keys, extracts the corresponding public key. For public keys, returns the key unchanged. Returns an error for symmetric octet keys.

When extracting a public key, key_ops are filtered to public-safe operations:

  • Sign is mapped to Verify
  • Decrypt and UnwrapKey are removed (private-only)
  • Other operations are preserved

Example

let private_key = key.generate_ec(ec.P256)
let assert Ok(pub_key) = key.public_key(private_key)
pub fn rsa_public_key(
  key: Key(kid),
) -> Result(rsa.PublicKey, gose.GoseError)

Extract the RSA public key.

Works with both RSA private keys (extracts the public component) and RSA public keys.

Returns an error if the key is not an RSA key.

pub fn to_der(key: Key(kid)) -> Result(BitArray, gose.GoseError)

Serialize a key to DER format.

Supports RSA, EC, EdDSA, and XDH keys (both private and public). Uses PKCS#8 for private keys and SPKI for public keys.

pub fn to_octet_bits(
  key: Key(kid),
) -> Result(BitArray, gose.GoseError)

Export the raw bytes of a key.

Supported key types:

  • Octet keys: returns the secret bytes
  • EdDSA/XDH private keys: returns the private key bytes (d)
  • EdDSA/XDH public keys: returns the public key bytes (x)
pub fn to_pem(key: Key(kid)) -> Result(String, gose.GoseError)

Serialize a key to PEM format.

Supports RSA, EC, EdDSA, and XDH keys (both private and public). Uses PKCS#8 for private keys and SPKI for public keys.

pub fn with_alg(key: Key(kid), alg: Alg) -> Key(kid)

Set the algorithm (alg) metadata parameter on a key.

pub fn with_key_ops(
  key: Key(kid),
  ops: List(KeyOp),
) -> Result(Key(kid), gose.GoseError)

Set the key operations parameter.

Per RFC 7517, the values should be consistent with key_use if both are present:

  • Signing use implies Sign and/or Verify operations
  • Encrypting use implies Encrypt, Decrypt, WrapKey, UnwrapKey, DeriveKey, DeriveBits

Returns an error if the list is empty, contains duplicates, or is incompatible with the key’s existing key_use.

pub fn with_key_use(
  key: Key(kid),
  use_: KeyUse,
) -> Result(Key(kid), gose.GoseError)

Set the public key use parameter.

Returns an error if the key already has key_ops that are incompatible with the specified use, or if the use is incompatible with the key type per RFC 8037 (EdDSA keys can only be used for signing, XDH keys can only be used for encryption).

pub fn with_kid(key: Key(a), kid: String) -> Key(String)

Set the key ID (kid) metadata parameter on a key.

pub fn with_kid_bits(key: Key(a), kid: BitArray) -> Key(BitArray)

Set the key ID (kid) metadata parameter on a key using raw bytes.

In COSE (RFC 9052), kid is a bstr that may contain arbitrary bytes. For JWK interoperability where kid is a JSON string, use with_kid.

pub fn xdh_curve(
  key: Key(kid),
) -> Result(xdh.Curve, gose.GoseError)

Get the curve used by an XDH key.

Returns an error if the key is not an XDH key.

pub fn xdh_public_key(
  key: Key(kid),
) -> Result(xdh.PublicKey, gose.GoseError)

Extract the XDH public key (X25519/X448).

Works with both XDH private keys (extracts the public component) and XDH public keys.

Returns an error if the key is not an XDH key.

Search Document