Skip to contents

Signs message so a reader can tell it came from the key's holder and was not changed since. Pass a manifest (a list, from morie_capsule_manifest()) to sign its canonical digest (rmoriebricklayer::mnfdgst()), or a string such as the SHA-256 of a provenance file. This is rmoriebricklayer::cpssign(); verify with rmoriebricklayer::cpsvrf().

Usage

morie_capsule_sign(
  message,
  key,
  scheme = NULL,
  context = NULL,
  deterministic = FALSE,
  prehash = "none"
)

Arguments

message

A string, a raw vector, or a manifest (a list) whose digest is signed.

key

A key from rmoriebricklayer::fipskg() or rmoriebricklayer::pqckg(), or a shared secret for "hmac".

scheme

NULL (taken from key), "xmss" or "hmac".

context

Optional context string (at most 255 bytes) bound into a standardised signature, so one key can sign for two purposes.

deterministic

TRUE for the deterministic variant of the standardised schemes (the signature depends only on key, message and context).

prehash

"none" (the default) or a hash for HashML-DSA / HashSLH-DSA, as in cpssign().

Value

A bricklayer_signature list (scheme, signature, and per scheme context, prehash or the XMSS fields).

Details

The schemes are the ones rmoriebricklayer offers: a standardised key from rmoriebricklayer::fipskg() (ML-DSA-44, -65 or -87, FIPS 204; any SLH-DSA set, FIPS 205), whose scheme is taken from the key; an XMSS key from rmoriebricklayer::pqckg() (scheme = "xmss", stateful: advance the key with rmoriebricklayer::xmssadv() after every signature); or a shared secret string (scheme = "hmac", HMAC-SHA-256, symmetric). For new work a fipskg() key is the simplest: it signs any number of messages with no state to keep.

Errors: message not one string, a raw vector or a list; scheme not NULL or one string; deterministic not TRUE or FALSE; and every refusal of cpssign() (a key of the wrong kind for the scheme, a context over 255 bytes, an unknown pre-hash, an exhausted XMSS key).

Examples

man <- morie_capsule_manifest(list(project = "demo"), env = FALSE)
key <- rmoriebricklayer::fipskg("ML-DSA-44")
sig <- morie_capsule_sign(man, key, context = "release")
sig$scheme
#> [1] "ML-DSA-44"
rmoriebricklayer::cpsvrf(rmoriebricklayer::mnfdgst(man), sig, key,
                         ctx = "release")
#> [1] TRUE

# a shared secret
tag <- morie_capsule_sign("sha256:abc", "shared-secret", scheme = "hmac")
rmoriebricklayer::cpsvrf("sha256:abc", tag, "shared-secret")
#> [1] TRUE

# a number is not a message
try(morie_capsule_sign(1, key))
#> Error : `message` must be one string, a raw vector or a manifest (a list)