Skip to content

Class: Sign ​

Defined in: signatures.ts:392

Single-algorithm signatures: ML-DSA-44/65/87 or SLH-DSA (FIPS 205), matching quantum-safe-py's Sign. Hedged by default.

Note: quantum-safe-py's context handling is a message prefix, not FIPS 204's native context parameter, so these signatures verify under a generic ML-DSA library only if it reconstructs len(ctx) ‖ ctx ‖ prefix ‖ message. For interoperable signatures use the standards-mode JWT.

Example ​

ts
const signer = new Sign(); // ML-DSA-65
using pair = signer.generateKeyPair();
const sm = signer.sign(utf8('hello'), pair.secretKey, { context: utf8('myapp-v1') });
signer.verify(sm, pair.publicKey);

Extends ​

  • BaseSigner

Constructors ​

Constructor ​

new Sign(algorithm?, options?): Sign

Defined in: signatures.ts:400

Creates a single-algorithm signer.

Parameters ​

algorithm? ​

"ML-DSA-44" | "ML-DSA-65" | "ML-DSA-87" | "ML-DSA-44-v2" | "ML-DSA-65-v2" | "ML-DSA-87-v2" | "SLH-DSA-SHAKE-128s" | "SLH-DSA-SHAKE-128f" | "SLH-DSA-SHAKE-192s" | "SLH-DSA-SHAKE-192f" | "SLH-DSA-SHAKE-256s" | "SLH-DSA-SHAKE-256f" | "SLH-DSA-SHA2-128s" | "SLH-DSA-SHA2-128f" | "SLH-DSA-SHA2-192s" | "SLH-DSA-SHA2-192f" | "SLH-DSA-SHA2-256s" | "SLH-DSA-SHA2-256f" = DEFAULT_SIGNATURE

An ML-DSA or SLH-DSA name (see sigSuites()), including the -v2 ML-DSA names. Default ML-DSA-65.

options? ​
hedged? ​

boolean

Prefix each signature with 32 random bytes. Default true; has no effect for -v2 names.

Returns ​

Sign

Throws ​

if algorithm is not a supported single-algorithm suite.

Throws ​

if init() has not completed.

Overrides ​

BaseSigner.constructor

Properties ​

algorithm ​

readonly algorithm: SignatureAlgorithm

Defined in: signatures.ts:189

Canonical algorithm string.

Inherited from ​

BaseSigner.algorithm


hedged ​

readonly hedged: boolean

Defined in: signatures.ts:202

True when each signature is prefixed with 32 random bytes (default; see quantum-safe-py).

On a verifier this is also a security setting: the signed bytes are len(ctx) || ctx || prefix || message and the prefix length is stored in the unsigned signature blob, so a verifier that accepted any prefix length would let anyone move bytes between the prefix and the message of a valid signature and obtain a "valid" signature on a different message (a prefix or suffix of the signed one). Verification therefore requires the prefix length to be exactly 32 when hedged is true and 0 when it is false. To verify signatures made without hedging (quantum-safe-py hedged=False), construct the verifier with { hedged: false }. Does not apply to the -v2 formats, which have no prefix (and always hedge inside ML-DSA).

Inherited from ​

BaseSigner.hedged


info ​

readonly info: SuiteInfo

Defined in: signatures.ts:191

Suite metadata (NIST level, CNSA 2.0 status, format, ...).

Inherited from ​

BaseSigner.info

Methods ​

generateKeyPair() ​

generateKeyPair(): KeyPair

Defined in: signatures.ts:242

Generates a signing key pair. Free it (or use using) when done.

Returns ​

KeyPair

A new key pair for this signer's algorithm.

Throws ​

if init() has not completed.

Inherited from ​

BaseSigner.generateKeyPair


generateStandardKeyPair() ​

generateStandardKeyPair(): StandardKeyPair

Defined in: signatures.ts:411

Generates a standards-mode key pair (a 32-byte seed and the FIPS 204 public key) for this signer's ML-DSA level. Free it or use using.

Returns ​

StandardKeyPair

A new StandardKeyPair.

Throws ​

for an algorithm without a standards-mode signer (SLH-DSA and the -v2 names).


isValid() ​

isValid(signed, publicKey, options?): boolean

Defined in: signatures.ts:358

Like verify but returns a boolean instead of throwing VerificationError.

Parameters ​

signed ​

SignedMessage

The signed message to check.

publicKey ​

PublicKey

Public key of the signer.

options? ​
expectedContext? ​

Uint8Array<ArrayBufferLike>

The context the message must carry. Default: empty.

Returns ​

boolean

true when valid, false on a verification failure.

Throws ​

if key and message algorithms differ.

Throws ​

if an argument has the wrong type.

Inherited from ​

BaseSigner.isValid


sign() ​

sign(message, secretKey, options?): SignedMessage

Defined in: signatures.ts:256

Signs message.

Parameters ​

message ​

Uint8Array

The bytes to sign; must not be empty.

secretKey ​

SecretKey

Secret key for this signer's algorithm.

options? ​

SignOptions = {}

See SignOptions; context defaults to empty. signedAt is set to the current time in seconds.

Returns ​

SignedMessage

A self-contained SignedMessage.

Throws ​

if the key belongs to a different algorithm.

Throws ​

for an empty message or a context over 255 bytes.

Throws ​

if the core fails to produce a signature.

Inherited from ​

BaseSigner.sign


signRaw() ​

signRaw(message, key, options?): Uint8Array

Defined in: signatures.ts:465

Signs message as standard FIPS 204 ML-DSA.Sign: the message is signed exactly as given, context is FIPS 204's native context (at most 255 bytes), and the randomness is FIPS 204's own. Returns the bare signature: no prefix, no wrapper, no metadata. Any FIPS 204 implementation verifies it from the same message, context and public key (quantum-safe-py: Sign.verify_raw).

Use Sign.sign (a SignedMessage) when both ends are quantum-safe; use this when the other side is not.

Parameters ​

message ​

Uint8Array

The bytes to sign.

key ​

StandardKeyPair

A key pair from Sign.generateStandardKeyPair or Sign.standardKeyPairFromSeed at this signer's level.

options? ​
context? ​

Uint8Array<ArrayBufferLike>

FIPS 204 context, at most 255 bytes. Default: empty.

Returns ​

Uint8Array

The bare FIPS 204 signature bytes.

Throws ​

if the key belongs to a different level.

Throws ​

for a context over 255 bytes, a key that is not a StandardKeyPair, or an algorithm without a standards-mode signer.

Example ​

ts
const signer = new Sign('ML-DSA-65');
using pair = signer.generateStandardKeyPair();
const sig = signer.signRaw(utf8('hello'), pair, { context: utf8('myapp') });
signer.verifyRaw(utf8('hello'), sig, pair.publicKey, { context: utf8('myapp') });

signStandard() ​

signStandard(message, key, options?): Uint8Array

Defined in: signatures.ts:513

The standard FIPS 204 signature of message. Identical to Sign.signRaw; the name says what it is.

Parameters ​

message ​

Uint8Array

The bytes to sign.

key ​

StandardKeyPair

A standards-mode key pair at this signer's level.

options? ​
context? ​

Uint8Array<ArrayBufferLike>

FIPS 204 context, at most 255 bytes. Default: empty.

Returns ​

Uint8Array

The bare FIPS 204 signature bytes.

Throws ​

if the key belongs to a different level.

Throws ​

for a context over 255 bytes or a key that is not a StandardKeyPair.


signWithFingerprint() ​

signWithFingerprint(message, keyPair, options?): SignedMessage

Defined in: signatures.ts:283

Signs and records keyPair.publicKey.fingerprint() in the message.

Parameters ​

message ​

Uint8Array

The bytes to sign; must not be empty.

keyPair ​

KeyPair

Key pair for this signer's algorithm; its secret key signs.

options? ​

Omit<SignOptions, "signerFingerprint"> = {}

Signing options without signerFingerprint; context defaults to empty.

Returns ​

SignedMessage

A self-contained SignedMessage carrying the signer's fingerprint.

Throws ​

if the key belongs to a different algorithm.

Throws ​

for an empty message or a context over 255 bytes.

Inherited from ​

BaseSigner.signWithFingerprint


standardKeyPairFromSeed() ​

standardKeyPairFromSeed(seed): StandardKeyPair

Defined in: signatures.ts:429

Rebuilds a standards-mode key pair from its 32-byte seed. The seed is copied into WebAssembly memory; wipe your own copy. If deriving the public key fails, the copied seed is freed before the error propagates.

Parameters ​

seed ​

Uint8Array

The 32-byte ML-DSA seed.

Returns ​

StandardKeyPair

A StandardKeyPair that owns the copied seed.

Throws ​

if the seed is not 32 bytes, or the algorithm has no standards-mode signer (SLH-DSA and the -v2 names).


verify() ​

verify(signed, publicKey, options?): void

Defined in: signatures.ts:308

Verifies a signed message. For hybrids both signatures must be valid.

The signature covers the message's context, and this method requires it to equal options.expectedContext (default: empty, i.e. no context), so a signature made for one purpose cannot be accepted for another. Pass the context you signed with. (Reading the context from the message itself would let an attacker choose it.)

Parameters ​

signed ​

SignedMessage

The signed message to check.

publicKey ​

PublicKey

Public key of the signer, for this signer's algorithm.

options? ​
expectedContext? ​

Uint8Array<ArrayBufferLike>

The context the message must carry. Default: empty.

Returns ​

void

Throws ​

if the signature does not verify, or the context differs from expectedContext (no detail on why, by design).

Throws ​

if key and message algorithms differ.

Throws ​

if an argument has the wrong type.

Example ​

ts
const sm = signer.sign(utf8('hello'), pair.secretKey, { context: utf8('myapp-v1') });
signer.verify(sm, pair.publicKey, { expectedContext: utf8('myapp-v1') }); // throws VerificationError on failure

Inherited from ​

BaseSigner.verify


verifyBytes() ​

verifyBytes(message, signature, publicKey, options?): void

Defined in: signatures.ts:338

Verifies a detached message + signature blob + context without a SignedMessage. The inputs are copied once so the checks and the verification see the same bytes.

Parameters ​

message ​

Uint8Array

The signed message bytes.

signature ​

Uint8Array

The signature blob (SignedMessage.signature).

publicKey ​

PublicKey

Public key of the signer, for this signer's algorithm.

options? ​
context? ​

Uint8Array<ArrayBufferLike>

The context the signature was made with. Default: empty.

Returns ​

void

Throws ​

if the signature does not verify (no detail on why, by design).

Throws ​

if the key belongs to a different algorithm.

Throws ​

if an argument has the wrong type.

Inherited from ​

BaseSigner.verifyBytes


verifyRaw() ​

verifyRaw(message, signature, publicKey, options?): void

Defined in: signatures.ts:487

Verifies a standard FIPS 204 signature made by any implementation (including quantum-safe-py Sign.sign_raw). publicKey is the FIPS 204 encoded key as bytes, or a PublicKey of this signer's algorithm.

Parameters ​

message ​

Uint8Array

The signed bytes.

signature ​

Uint8Array

The bare FIPS 204 signature.

publicKey ​

PublicKey | Uint8Array<ArrayBufferLike>

The FIPS 204 encoded public key, or a PublicKey of this signer's algorithm.

options? ​
context? ​

Uint8Array<ArrayBufferLike>

FIPS 204 context the signature was made with, at most 255 bytes. Default: empty.

Returns ​

void

Throws ​

if the signature, message or context is wrong (no detail on which, by design).

Throws ​

if a PublicKey belongs to a different algorithm.

Throws ​

for a context over 255 bytes, a wrong argument type, or an algorithm without a standards-mode signer.


verifyStandard() ​

verifyStandard(message, signature, publicKey, options?): void

Defined in: signatures.ts:527

Verifies a standard FIPS 204 signature. Identical to Sign.verifyRaw.

Parameters ​

message ​

Uint8Array

The signed bytes.

signature ​

Uint8Array

The bare FIPS 204 signature.

publicKey ​

PublicKey | Uint8Array<ArrayBufferLike>

The FIPS 204 encoded public key, or a PublicKey of this signer's algorithm.

options? ​
context? ​

Uint8Array<ArrayBufferLike>

FIPS 204 context the signature was made with. Default: empty.

Returns ​

void

Throws ​

if the signature, message or context is wrong.

Throws ​

if a PublicKey belongs to a different algorithm.

Throws ​

for a context over 255 bytes or a wrong argument type.

Apache-2.0.