Class: HybridSign
Defined in: signatures.ts:542
Hybrid classical + post-quantum signatures (default Ed25519+ML-DSA-65), matching quantum-safe-py's HybridSign. Both sub-signatures are verified unconditionally and both must be valid.
Example
const signer = new HybridSign('Ed25519+ML-DSA-87'); // CNSA 2.0 parameter setExtends
BaseSigner
Constructors
Constructor
new HybridSign(
algorithm?,options?):HybridSign
Defined in: signatures.ts:550
Parameters
algorithm?
"Ed25519+ML-DSA-44" | "Ed25519+ML-DSA-65" | "Ed25519+ML-DSA-87" | "P-256+ML-DSA-44" | "P-256+ML-DSA-65" | "P-384+ML-DSA-87" | "Ed25519+ML-DSA-44-v2" | "Ed25519+ML-DSA-65-v2" | "Ed25519+ML-DSA-87-v2" | "P-256+ML-DSA-44-v2" | "P-256+ML-DSA-65-v2" | "P-384+ML-DSA-87-v2"
Default Ed25519+ML-DSA-65-v2. With hedged: false and no algorithm the original format Ed25519+ML-DSA-65 is used, because -v2 is always hedged inside ML-DSA and has no unhedged mode.
options?
hedged?
boolean
Prefix each signature with 32 random bytes. Default true; has no effect for -v2 names.
Returns
HybridSign
Throws
if algorithm is not a supported hybrid signature suite.
Throws
if init() has not completed.
Overrides
BaseSigner.constructor
Properties
algorithm
readonlyalgorithm:SignatureAlgorithm
Defined in: signatures.ts:189
Canonical algorithm string.
Inherited from
BaseSigner.algorithm
hedged
readonlyhedged: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
readonlyinfo: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
A new key pair for this signer's algorithm.
Throws
if init() has not completed.
Inherited from
BaseSigner.generateKeyPair
isValid()
isValid(
signed,publicKey,options?):boolean
Defined in: signatures.ts:358
Like verify but returns a boolean instead of throwing VerificationError.
Parameters
signed
The signed message to check.
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
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
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
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
Key pair for this signer's algorithm; its secret key signs.
options?
Omit<SignOptions, "signerFingerprint"> = {}
Signing options without signerFingerprint; context defaults to empty.
Returns
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
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
The signed message to check.
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
const sm = signer.sign(utf8('hello'), pair.secretKey, { context: utf8('myapp-v1') });
signer.verify(sm, pair.publicKey, { expectedContext: utf8('myapp-v1') }); // throws VerificationError on failureInherited 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
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