Per #1229: Signature and public-key types lack `Hash`, which prevents
use in `HashMap` / `HashSet` keys and similar collections.
- ecdsa: Signature, DER Signature, SignatureWithOid
- ed25519: Signature, pkcs8::PublicKeyBytes
- ed448: Signature, pkcs8::PublicKeyBytes
- ml-dsa: Signature, VerifyingKey
- slh-dsa: Signature, VerifyingKey
Where a trivial derive works (ed25519, ed448), uses derive. Where
generic bounds or upstream gaps require it, uses a manual impl over
the canonical serialized bytes (`to_bytes` / `encode` / `as_bytes`),
which is the natural Hash domain for these types anyway.
Closes#1229
Adds an internal type for opportunistic heap offload which uses `Box`
when the `alloc` feature is available and falls back to stack allocation
when it is not.
So far it's only used for the `z` component of `Signature` but is useful
elsewhere, e.g. for `VerifyingKey`.
It's so generally useful it should probably get extracted somewhere, to
`module-lattice` at the very least, but this is enough to get started.
Releases the following, which all now depend either directly or
transitively on `pkcs8` v0.11 (which had breaking changes in the final
release)
- `dsa` v0.7.0-rc.15
- `ecdsa` v0.17.0-rc.18
- `ed25519` v3.0.0-rc.5
- `ed448` v0.5.0-rc.6
- `ml-dsa` v0.1.0-rc.9
- `slh-dsa` v0.2.0-rc.5
- `xmss` v0.1.0-pre.1
Per maintainer suggestion on #1275, replace the curve-specific
`FieldBytesSize / 2` minimum with an absolute 16-byte / 128-bit
floor. The old rule rejected legitimate pairings like SHA-256 with
P-521 (permitted by e.g. XML Signature); the new rule still catches
egregious digest misuse without those false positives.
Closes#1275
This high-level method can plug into various strategies for efficiently
implementing `aG + bP`, including using basepoint tables, wNAF, or
linear combinations, depending on what crate features are enabled and
what curve-specific optimizations have been implemented.
The existing Drop impl for ExpandedSigningKey (gated on the zeroize
feature) zeroizes rho, K, tr, s1, s2, and t0 but skips the
NTT-domain derived values s1_hat, s2_hat, and t0_hat.
The NTT is invertible, so s1_hat in memory is equivalent to having
s1. This leaves secret key material unzeroized after drop.
Add s1_hat, s2_hat, and t0_hat to the Drop impl. All three are
NttVector types which implement Zeroize via module-lattice.
A_hat (the public matrix derived from rho) is not zeroized here
because NttMatrix does not implement Zeroize in module-lattice.
A_hat is derived from public data (rho) so this is lower priority,
but a follow-up PR to module-lattice could add Zeroize for NttMatrix
for completeness.
This reworks the API to make KeyGen::from_seed return a
`SeededSigningKey` instead of a `KeyPair`.
The `SeededSigningKey` effectively replaces the `KeyPair`, and instead
of eagerly generating the VerifyingKey (implementing
`signature::KeypairRef`), it implements `signature::Keypair` and makes
the verifying key when requested.
This reduces the depth of the stack when calling from_seed and reduces
the size of the stack by 207kb using ML-DSA-87 in debug/tests builds
(the heaviest consumers).
This is an API break.