R API
nqalgs
Section titled “nqalgs”Algorithms and their sizes
nqalgs()Lists every signature and key encapsulation algorithm the bundled library provides, with the sizes in bytes of its keys, signatures, ciphertexts and shared secrets.
Value
A data frame with one row per algorithm and the columns name,
type ("sig" or "kem"), pk, sk, sig, ct and ss (sizes
in bytes; NA where they do not apply) and id (the library’s
number for the algorithm).
Examples
nqalgs()nqcapid, nqfiles, nqprove
Section titled “nqcapid, nqfiles, nqprove”Capsule ids, files and proofs
nqcapid(dir)
nqfiles(dir)
nqprove(dir, paths)nqcapid() gives a capsule’s id: the SHA-256 of the bytes its seal
signs, which nqseal() records for its inputs. nqfiles() lists the
files a capsule’s manifest holds. Neither checks anything: use
nqcheck() for that.
Arguments
dir: Path of the capsule folder.paths: The files to prove, as the manifest lists them (/between folders).
Value
nqcapid(): a raw vector of 32 bytes. nqfiles(): a data
frame with the columns path, size and sha256 (64 hex digits),
in manifest order. nqprove(): the proof, a raw vector.
Details
nqprove() writes a proof (noqtis-proof-1, JSON) that some files are
in a format 2 capsule: the seal, the manifest’s head and, per file, its
entry and Merkle audit path (RFC 9162). The proof holds nothing of the
capsule’s other files. nqcheck(proof = ) checks it, alone or against
the files.
Examples
d <- file.path(tempdir(), "proved")dir.create(d)writeLines("one", file.path(d, "a.txt"))writeLines("two", file.path(d, "b.txt"))k <- nqkeygen("ML-DSA-44")nqseal(d, k$sk, k$pk, "ML-DSA-44", format = 2)nqfiles(d)p <- nqprove(d, "a.txt")attr(nqcheck(NULL, k$pk, proof = p), "ok")nqcapid(d)unlink(d, recursive = TRUE)nqdsse, nqdsseverify
Section titled “nqdsse, nqdsseverify”DSSE envelopes
nqdsse(sk, pk, payload, type, alg)
nqdsseverify(pk, env, alg)nqdsse() wraps a payload in a DSSE envelope (the in-toto and SLSA
signing wrapper), signed with any signature algorithm of nqalgs()
over the envelope’s pre-authentication encoding, as canonical JSON with
payload, payloadType and one signature whose keyid is the hex
SHA-256 of pk. nqdsseverify() checks one.
Arguments
sk, pk: The key pair (nqdsse()), or the public key to check with (nqdsseverify()).payload: The payload: a raw vector, or one string, taken as its UTF-8 bytes.type: The payload type, 1 to 255 printable ASCII characters with no space, quote or backslash, such as"application/vnd.in-toto+json".alg: Signature algorithm name.env: The envelope: a raw vector, or one string.
Value
nqdsse(): the envelope, a raw vector. nqdsseverify(): a
list with type and payload (a raw vector) when one of the
envelope’s signatures verifies under pk, NULL when none does; an
error when env is not an envelope.
Examples
k <- nqkeygen("ML-DSA-65")e <- nqdsse(k$sk, k$pk, '{"a":1}', "application/json", "ML-DSA-65")v <- nqdsseverify(k$pk, e, "ML-DSA-65")rawToChar(v$payload)nqencap, nqdecap
Section titled “nqencap, nqdecap”Key encapsulation
nqencap(pk, alg, seed = NULL)
nqdecap(sk, ct, alg)nqencap() makes a fresh shared secret and its ciphertext for a public
key (ML-KEM, FIPS 203, or HQC); nqdecap() recovers the shared secret
from the ciphertext with the secret key.
Arguments
pk: Public key, a raw vector (as fromnqkeygen()).alg: Key encapsulation algorithm name, one of the"kem"rows ofnqalgs().seed:NULL(the default) for fresh randomness, or the standard’s encapsulation seed as a raw vector (m, 32 bytes, for ML-KEM; m and salt for HQC), for test vectors.sk: Secret key, a raw vector.ct: Ciphertext, a raw vector.
Value
nqencap(): a list with the raw vectors ct (ciphertext) and
ss (shared secret). nqdecap(): the shared secret, a raw vector.
Details
Decapsulation uses implicit rejection, as FIPS 203 and HQC require: a changed ciphertext gives an unrelated pseudorandom secret, not an error. Only a key or ciphertext of the wrong length is an error.
Examples
k <- nqkeygen("ML-KEM-768")e <- nqencap(k$pk, "ML-KEM-768")identical(nqdecap(k$sk, e$ct, "ML-KEM-768"), e$ss)nqhash, nqhmac
Section titled “nqhash, nqhmac”Hashes and HMAC
nqhash(x, alg = "sha256", file = FALSE, hex = FALSE, len = NULL)
nqhmac(key, x, alg = "sha256", hex = FALSE)nqhash() computes a SHA-2 (FIPS 180-4), SHA-3 or SHAKE (FIPS 202)
digest of a raw vector, a string or a file; nqhmac() computes an HMAC.
Arguments
x: A raw vector, or one string (hashed as its UTF-8 bytes), or, withfile = TRUE, the path of a file.alg: Hash name.file:TRUEto hash the file at pathx, read in chunks of 1 MiB.hex:TRUEto return lowercase hexadecimal text instead of raw bytes.len: For SHAKE only, the output length in bytes (default 32 for SHAKE128 and 64 for SHAKE256).key: HMAC key, a raw vector or one string.
Value
The digest, a raw vector, or a string when hex = TRUE.
Details
Hash names: "sha224", "sha256", "sha384", "sha512",
"sha512-224", "sha512-256", "sha3-224", "sha3-256",
"sha3-384", "sha3-512", "shake128", "shake256" (case is
ignored).
Examples
nqhash("abc", hex = TRUE)nqhash(charToRaw("abc"), "sha3-256")nqhash("abc", "shake128", len = 16)f <- tempfile()writeBin(charToRaw("abc"), f)nqhash(f, file = TRUE, hex = TRUE)unlink(f)nqhmac("key", "The quick brown fox jumps over the lazy dog", hex = TRUE)nqidcard, nqidcheck
Section titled “nqidcard, nqidcheck”Identity cards for a signing key
nqidcard( sk, pk, alg, name, orcid = NULL, email = NULL, url = NULL, affil = NULL, at = Sys.time())
nqidcheck(card, pk = NULL)An identity card (noqtis-idcard-1, canonical JSON) ties a signing
key to who holds it: a name and, when given, an ORCID iD, an e-mail
address, a web page and an affiliation, signed by the key itself under
the card’s own context, so that a card is never taken for a seal or a
key statement. nqidcard() makes one; nqidcheck() checks one.
Arguments
sk, pk: The key pair the card is for; fornqidcheck(),pkisNULLor the public key the card must be for.alg: Its signature algorithm.name: Your name: 1 to 255 bytes of text, no control character, no space at either end.orcid:NULL, or your ORCID iD ("0000-0002-1825-0097"or itshttps://orcid.org/address); its check digit must be right, and the card holds the bare iD.email:NULL, or an e-mail address (local@domain.tld, at most 254 bytes).url:NULL, or anhttps://web page (at most 1024 bytes).affil:NULL, or your affiliation, asname.at: When the card is made: aPOSIXcttime or seconds since 1970 (UTC); default now.card: A card: a raw vector, or the path of a card file.
Value
nqidcard(): the card, a raw vector (write it with
writeBin()). nqidcheck(): a list with name, orcid, email,
url, affil (NULL for a field the card has not), created,
alg, pk and key_sha256 when the card verifies (and is for
pk); NULL when its signature does not verify or it is for another
key. Input that is not a card is an error.
Details
A card is self-signed: it shows that whoever holds the key wrote it and
that it is unchanged, not that the name is true. Give the key’s SHA-256
(key_sha256) where people already know you, or let readers pin your
public key with pk. The key must be post-quantum: Ed25519 alone is
refused. noqtis check --card names the sealer of a capsule from its
card.
Examples
k <- nqkeygen("ML-DSA-44")card <- nqidcard(k$sk, k$pk, "ML-DSA-44", "Ada Lovelace", orcid = "0000-0002-1825-0097")nqidcheck(card, k$pk)$orcidnqkeygen
Section titled “nqkeygen”Generate a key pair
nqkeygen(alg, seed = NULL)Generates a signature key pair (ML-DSA, SLH-DSA, Ed25519, the hybrids ML-DSA-44/65/87+Ed25519) or a key encapsulation key pair (ML-KEM, HQC).
Arguments
alg: Algorithm name, one ofnqalgs()$name(case is ignored).seed:NULL(the default) for fresh randomness from the operating system, or a raw vector holding the standard’s seed for deterministic key generation: xi (32 bytes) for ML-DSA; SK.seed, SK.prf and PK.seed (3n bytes) for SLH-DSA; the 32-byte private key for Ed25519; xi and the Ed25519 key (64 bytes) for a hybrid; d and z (64 bytes) for ML-KEM; the HQC seed.
Value
A list with the raw vectors pk (public key) and sk (secret
key) in the standard’s encoding, and alg, the algorithm name.
Examples
k <- nqkeygen("ML-DSA-44")length(k$pk)k2 <- nqkeygen("ML-KEM-512", seed = as.raw(0:63))nqrand
Section titled “nqrand”Random bytes from the operating system
nqrand(n)Bytes from the operating system’s cryptographically secure generator,
the same source key generation uses (see the Randomness section of
noqtis-package). Independent of set.seed().
Arguments
n: Number of bytes.
Value
A raw vector of length n.
Examples
nqrand(16)nqreadkey, nqwritekey
Section titled “nqreadkey, nqwritekey”Read and write the command-line tool’s key files
nqreadkey(path)
nqwritekey(path, key, alg, kind = c("sec", "pub"), force = FALSE)nqreadkey() reads a key file written by noqtis keygen (or by
nqwritekey()), as strictly as the command-line tool reads it: the
exact header line noqtis-key-1 <algorithm> <pub|sec>, then the key as
padded base64 with LF or CRLF line ends and no other character,
canonical padding, and exactly the algorithm’s key size.
nqwritekey() writes one.
Arguments
path: The key file.key: The key, a raw vector ($pkor$skofnqkeygen()).alg: The algorithm name, one ofnqalgs()$name(case is ignored).kind:"pub"for a public key,"sec"for a secret key.force:TRUEto replace an existing file; it is removed first, so the new file never inherits its permissions.
Value
nqreadkey(): a list with alg (the algorithm name as the
library spells it), kind ("pub" or "sec") and key (a raw
vector). nqwritekey(): path, invisibly.
Details
A secret key file is created readable by its owner only (on
Windows it takes the folder’s permissions). An existing file is never
replaced unless force = TRUE. R’s base64 here is not constant time:
read secret key files where timing cannot be observed.
Examples
k <- nqkeygen("ML-DSA-44")f <- tempfile()nqwritekey(f, k$sk, "ML-DSA-44", "sec")identical(nqreadkey(f)$key, k$sk)readLines(f, n = 1)nqrotate, nqrevoke
Section titled “nqrotate, nqrevoke”Rotate or revoke a seal key
nqrotate(sk, pk, alg, nsk, npk, nalg, at = Sys.time(), reason = NULL)
nqrevoke(sk, pk, alg, at = Sys.time(), reason = NULL)A key statement (noqtis-keys-1, canonical JSON) says that a signing
key is replaced by a new one from a given time (nqrotate(), signed by
both keys) or revoked from then (nqrevoke(), signed by the key).
nqcheck() follows statements from a trusted key with its keys
argument. Both algorithms must be post-quantum: Ed25519 alone is
refused.
Arguments
sk, pk: The key pair the statement is about.alg: Its signature algorithm.nsk, npk: The new key pair.nalg: The new key pair’s algorithm.at: When the statement takes effect: aPOSIXcttime or seconds since 1970 (UTC); default now.reason:NULL, or up to 255 bytes of text kept in the statement.
Value
The statement, a raw vector (write it with writeBin()).
Examples
old <- nqkeygen("ML-DSA-44")new <- nqkeygen("ML-DSA-65")s <- nqrotate(old$sk, old$pk, "ML-DSA-44", new$sk, new$pk, "ML-DSA-65", reason = "yearly")cat(rawToChar(s))nqseal, nqcheck
Section titled “nqseal, nqcheck”Seal and check a capsule
nqseal( dir, sk, pk, alg, meta = NULL, format = if (is.null(inputs)) 1L else 2L, inputs = NULL)
nqcheck( dir, pk = NULL, anchors = NULL, only = NULL, lineage = NULL, keys = NULL, proof = NULL)A capsule is a signed record of the exact files in a folder.
nqseal() writes noqtis.json (the manifest: every regular file with
its size, SHA-256 and SHA3-256) and noqtis.sig (the signature over the
manifest) into the folder. nqcheck() checks a folder against its seal
and reports every check.
Arguments
dir: Path of the folder.sk: Secret key, a raw vector (as fromnqkeygen()).pk: Public key, a raw vector; fornqseal()it must pair withskand is written into the seal; fornqcheck(),NULLaccepts the key in the seal (thekeyrow then says so), otherwise the seal must be made with this key.alg: Signature algorithm name, one of the"sig"rows ofnqalgs().meta:NULL, or one string of JSON text (an object) stored in the manifest under"meta".format:1(the default) or2. Format 2 adds a Merkle tree over the files to the manifest and signs its head, so thatnqprove()can show some files without the others.inputs:NULL, or the folders of the capsules this one was made from (format 2, the default with it). Each is recorded by its id (nqcapid()) under its name:names(inputs)where given, else the folder’s last component. Check the inputs first.anchors:NULL, or a list of up to 32 raw vectors, DER encoded certificates of trusted timestamp authorities; the seal must then carry an RFC 3161 timestamp token that verifies under one of them.only:NULL, or the paths (as the manifest lists them,/between folders) of the files to check; the others are not read, andpartialrows say so.lineage:NULL, or capsule folders among which the inputs of a format 2 capsule are found by id and checked, with no key pinned, to 64 levels; onelineagerow per input.keys:NULL, or key statements fromnqrotate()ornqrevoke()(a list of raw vectors, or a character vector of files), at most 32; they needpk. The seal may then be by a keypkwas rotated to, and must carry a verified timestamp from before its key was rotated away or revoked.proof:NULL, or a proof fromnqprove()(a raw vector or the path of a file), checked instead of the folder: its seal, its signature over the manifest’s head and each proven entry.dirmay then beNULL; given, the proven files in it are checked too.only,lineageandkeysdo not apply.
Value
nqseal(): the paths of the two files written, invisibly.
nqcheck(): a data frame with one row per check and the columns
check, ok (logical) and detail; its attribute "ok" is TRUE
only when every check passed.
Details
The creation time in the manifest is the SOURCE_DATE_EPOCH
environment variable when set, else the clock. Sealing refuses a folder
that holds a symbolic link or a special file. Capsules are the same
files the noqtis command-line tool writes and checks.
The library makes no network requests: an RFC 3161 timestamp is added
to a seal by other tools, and nqcheck() verifies it when anchors is
given.
Examples
d <- file.path(tempdir(), "capsule")dir.create(d)writeLines("hello", file.path(d, "a.txt"))k <- nqkeygen("ML-DSA-44")nqseal(d, k$sk, k$pk, "ML-DSA-44", meta = '{"project":"demo"}')r <- nqcheck(d, k$pk)rattr(r, "ok")writeLines("hellO", file.path(d, "a.txt"))attr(nqcheck(d, k$pk), "ok")attr(nqcheck(d, k$pk, only = "b.txt"), "ok")unlink(d, recursive = TRUE)nqsign, nqverify
Section titled “nqsign, nqverify”Sign and verify
nqsign(sk, msg, alg, ctx = NULL, det = FALSE, ph = NULL, rnd = NULL)
nqverify(pk, msg, sig, alg, ctx = NULL, ph = NULL)nqsign() signs a message with ML-DSA (FIPS 204), SLH-DSA (FIPS 205),
Ed25519 (RFC 8032) or a hybrid ML-DSA+Ed25519, whose signature verifies
only when both parts do; nqverify() checks such a signature.
Arguments
sk: Secret key, a raw vector (as fromnqkeygen()).msg: The message: a raw vector, or one string, which is signed as its UTF-8 bytes.alg: Signature algorithm name, one of the"sig"rows ofnqalgs().ctx:NULLor a context string (raw vector or string, at most 255 bytes), bound into the signature; verification needs the same one.det:FALSE(the default) for hedged signing with fresh randomness;TRUEfor the deterministic variant (all-zero per-signature randomness).ph:NULLfor the pure algorithm, or a hash name (seenqhash()) for HashML-DSA / HashSLH-DSA, which hashmsgwith it first.rnd:NULL, or the standard’s per-signature randomness as a raw vector (32 bytes for ML-DSA and the hybrids, n bytes for SLH-DSA, none for Ed25519), for test vectors; it overridesdet.pk: Public key, a raw vector.sig: Signature, a raw vector.
Value
nqsign(): the signature, a raw vector. nqverify(): TRUE
when the signature verifies, FALSE otherwise (including a signature,
key or context of the wrong length or encoding).
Examples
k <- nqkeygen("ML-DSA-44")s <- nqsign(k$sk, "hello", "ML-DSA-44")nqverify(k$pk, "hello", s, "ML-DSA-44")nqverify(k$pk, "hellO", s, "ML-DSA-44")Version of the bundled noqtis library
nqver()Version of the bundled noqtis library
Value
A string, the version of the C library compiled into this package.
Examples
nqver()