gose

A Gleam library for JOSE (JSON Object Signing and Encryption) and COSE (CBOR Object Signing and Encryption).

Core:

gose/key, gose/algorithm, gose/jose/algorithm, gose/cose/key, and gose/cose/algorithm are deprecated shims retained for the v2.x migration window. They will be removed in v3.0. New code should import gose, gose/jose, and gose/cose directly.

JOSE:

COSE:

Types

AES key sizes.

pub type AesKeySize {
  Aes128
  Aes192
  Aes256
}

Constructors

  • Aes128

    128-bit AES key

  • Aes192

    192-bit AES key

  • Aes256

    256-bit AES key

AES key wrapping modes.

pub type AesKwMode {
  AesKw
  AesGcmKw
}

Constructors

  • AesKw

    AES Key Wrap (RFC 3394)

  • AesGcmKw

    AES-GCM Key Wrap

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(SigningAlg)
  KeyEncryptionAlg(KeyEncryptionAlg)
  ContentAlg(ContentAlg)
}

Constructors

ChaCha20-Poly1305 key wrapping variants.

pub type ChaCha20Kw {
  C20PKw
  XC20PKw
}

Constructors

  • C20PKw

    ChaCha20-Poly1305 Key Wrap (12-byte nonce)

  • XC20PKw

    XChaCha20-Poly1305 Key Wrap (24-byte nonce)

Content encryption algorithms.

pub type ContentAlg {
  AesGcm(AesKeySize)
  AesCbcHmac(AesKeySize)
  ChaCha20Poly1305
  XChaCha20Poly1305
}

Constructors

  • AesGcm(AesKeySize)

    AES-GCM content encryption

  • AesCbcHmac(AesKeySize)

    AES-CBC with HMAC composite AEAD (CEK is double the AES key size)

  • ChaCha20Poly1305

    ChaCha20-Poly1305

  • XChaCha20Poly1305

    XChaCha20-Poly1305

Asymmetric signature algorithms.

pub type DigitalSignatureAlg {
  RsaPkcs1(RsaPkcs1Alg)
  RsaPss(RsaPssAlg)
  Ecdsa(EcdsaAlg)
  Eddsa
}

Constructors

  • RsaPkcs1(RsaPkcs1Alg)

    RSA PKCS#1 v1.5 signing

  • RsaPss(RsaPssAlg)

    RSA-PSS signing

  • Ecdsa(EcdsaAlg)

    ECDSA signing

  • Eddsa

    EdDSA (Ed25519 or Ed448, curve determined by key)

ECDH-ES key agreement algorithm variants.

pub type EcdhEsAlg {
  EcdhEsDirect
  EcdhEsAesKw(AesKeySize)
  EcdhEsChaCha20Kw(ChaCha20Kw)
}

Constructors

  • EcdhEsDirect

    ECDH-ES direct key agreement

  • EcdhEsAesKw(AesKeySize)

    ECDH-ES with AES Key Wrap

  • EcdhEsChaCha20Kw(ChaCha20Kw)

    ECDH-ES with ChaCha20-Poly1305 Key Wrap

ECDSA signing algorithm variants.

pub type EcdsaAlg {
  EcdsaP256
  EcdsaP384
  EcdsaP521
  EcdsaSecp256k1
}

Constructors

  • EcdsaP256

    ECDSA using P-256 and SHA-256

  • EcdsaP384

    ECDSA using P-384 and SHA-384

  • EcdsaP521

    ECDSA using P-521 and SHA-512

  • EcdsaSecp256k1

    ECDSA using secp256k1 and SHA-256 (RFC 8812)

Error type for JOSE and COSE operations.

Used by low-level JOSE/COSE primitives. The JWT and CWT layers wrap these errors in their own domain-specific variants for token validation.

pub type GoseError {
  ParseError(String)
  CryptoError(String)
  InvalidState(String)
  VerificationFailed
}

Constructors

  • ParseError(String)

    Parsing failed: invalid base64, malformed JSON, unexpected structure, etc. The String provides a human-readable description of what went wrong.

  • CryptoError(String)

    A cryptographic operation failed: signature verification, decryption, key derivation, etc. The String describes the failure.

  • InvalidState(String)

    An operation was attempted in an invalid state: wrong key type for the chosen algorithm, missing required header field, etc. The String explains which invariant was violated.

  • VerificationFailed

    Signature or MAC verification failed. Intentionally carries no detail to avoid leaking information that could enable oracle attacks.

HMAC signing algorithm variants.

pub type HmacAlg {
  HmacSha256
  HmacSha384
  HmacSha512
}

Constructors

  • HmacSha256

    HMAC using SHA-256

  • HmacSha384

    HMAC using SHA-384

  • HmacSha512

    HMAC using SHA-512

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 encryption algorithms.

pub type KeyEncryptionAlg {
  Direct
  AesKeyWrap(AesKwMode, AesKeySize)
  ChaCha20KeyWrap(ChaCha20Kw)
  RsaEncryption(RsaEncryptionAlg)
  EcdhEs(EcdhEsAlg)
  Pbes2(Pbes2Alg)
}

Constructors

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

MAC algorithms.

pub type MacAlg {
  Hmac(HmacAlg)
}

Constructors

PBES2 key encryption algorithm variants.

pub type Pbes2Alg {
  Pbes2Sha256Aes128Kw
  Pbes2Sha384Aes192Kw
  Pbes2Sha512Aes256Kw
}

Constructors

  • Pbes2Sha256Aes128Kw

    PBES2 with HMAC-SHA-256 and A128KW wrapping

  • Pbes2Sha384Aes192Kw

    PBES2 with HMAC-SHA-384 and A192KW wrapping

  • Pbes2Sha512Aes256Kw

    PBES2 with HMAC-SHA-512 and A256KW wrapping

RSA key encryption algorithm variants.

pub type RsaEncryptionAlg {
  RsaPkcs1v15
  RsaOaepSha1
  RsaOaepSha256
}

Constructors

  • RsaPkcs1v15

    RSAES PKCS1 v1.5 key encryption.

    Security Warning: Vulnerable to padding oracle attacks (Bleichenbacher). Use only for interoperability with legacy systems that require RSA1_5. Prefer RsaOaepSha256 for new applications.

    Note: Decryption may fail on Node.js 20.x (CVE-2023-46809).

  • RsaOaepSha1

    RSAES OAEP using default parameters

  • RsaOaepSha256

    RSAES OAEP using SHA-256 and MGF1 with SHA-256

RSA PKCS#1 v1.5 signing algorithm variants.

pub type RsaPkcs1Alg {
  RsaPkcs1Sha256
  RsaPkcs1Sha384
  RsaPkcs1Sha512
}

Constructors

  • RsaPkcs1Sha256

    RSA PKCSv1.5 using SHA-256

  • RsaPkcs1Sha384

    RSA PKCSv1.5 using SHA-384

  • RsaPkcs1Sha512

    RSA PKCSv1.5 using SHA-512

RSA-PSS signing algorithm variants.

pub type RsaPssAlg {
  RsaPssSha256
  RsaPssSha384
  RsaPssSha512
}

Constructors

  • RsaPssSha256

    RSA-PSS using SHA-256 (RSASSA-PSS)

  • RsaPssSha384

    RSA-PSS using SHA-384 (RSASSA-PSS)

  • RsaPssSha512

    RSA-PSS using SHA-512 (RSASSA-PSS)

Signing and MAC algorithms (union of asymmetric signatures and MACs).

pub type SigningAlg {
  DigitalSignature(DigitalSignatureAlg)
  Mac(MacAlg)
}

Constructors

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, 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, 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), 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), 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, 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, 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 error_message(error: GoseError) -> String

Extract the message string from a GoseError, regardless of variant.

pub fn from_der(der: BitArray) -> Result(Key(kid), 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), 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), 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), 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) = gose.from_octet_bits(secret)
pub fn from_pem(pem: String) -> Result(Key(kid), 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), 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), 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: 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: 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: 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), 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, 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), 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 = gose.generate_ec(ec.P256)
let assert Ok(pub_key) = gose.public_key(private_key)
pub fn rsa_public_key(
  key: Key(kid),
) -> Result(rsa.PublicKey, 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, 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, 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, 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), 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), 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, 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, 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