HAWK was withdrawn from NIST standardization on 2026-07-29. The HAWK design team (Léo Ducas et al.) withdrew HAWK from NIST's additional-signature standardization process following the key-recovery attack of Straznickas & Weis (Anthropic), "HAWK-n Key Recovery Reduces to SVP in Dimension n/2+1." The team confirmed the attack approximately halves the lattice-reduction block size required to recover an equivalent secret key, and stated that naïve countermeasures (doubling parameters, higher-rank modules) make HAWK uncompetitive.
This crate is a faithful Rust port of the upstream HAWK reference C implementation (github.com/hawk-sign/dev@1b9fef5, MIT licensed). The port is byte-exact against that reference, but the scheme it implements is cryptographically broken. Earlier releases described this crate as "testnet-ready"; that framing is retracted — the crate is now suitable only for research, reproducibility, and reference.
Do not use this crate to secure live funds, production authentication, or any setting where a compromise has material consequences.
- What it is. Straznickas & Weis (Anthropic), eprint 2026/1593: a public, unconditional, deterministic polynomial-time reduction from HAWK-n key recovery to poly(n) calls to an exact-SVP oracle in dimension n/2+1 (vs. the designers' assumed ≈dimension n). The lever is a nontrivial automorphism of the key lattice — the Galois involution τ: ζ ↦ −ζ — which is recoverable as a shortest vector of a public rank-n lattice (Ducas's block reduction on that near-hypercubic class); the van Gent–Pulles descent then extracts an equivalent secret key. It reads only the public key.
- Impact on HAWK-512 (this crate's only parameter set): key-recovery cost drops from the designers' claimed ≈2¹⁵⁰ gates to ≤2¹⁰⁸ gates (AGPS20 model). HAWK-512 no longer meets its claimed NIST Level I security. HAWK-256 has been recovered end-to-end in practice, in a few hours on a single server.
- Why the port cannot fix it. The attack targets the scheme's mathematics, not any implementation detail. Nothing in this port (sampler, encoding, zeroization, constant-time work below) affects it; a byte-exact port faithfully reproduces the vulnerability. It does not transfer to Falcon, and is evaded only by conductors m ∈ {pᵏ, 2pᵏ} for odd prime p (equivalently, cyclotomic conductors m > 4 with cyclic (ℤ/m)ˣ) — not a change available within HAWK's parameter sets.
The break above needs only the public key. Independent work shows HAWK is also fragile when signing leaks, which is a different threat model and is not addressed by anything in this port:
- Sign leakage. Brinkmann, Kraus & May, "Halfspace Learning for Lattice Signature Key Recovery from Signs" (eprint 2026/1366): leaking the sign — or merely the Hamming weight — of a randomness coordinate recovers a HAWK key from 30 signatures in about 10 minutes at the 128-bit level in the noise-free model, tolerating up to 35% sign error. The method is not HAWK-specific (Falcon falls at 100 signatures, ML-DSA at 190,000), but HAWK is the scheme this crate ships.
- Sampler leakage. Chi, Lee & Lee, "HAWK with Hint: Algebraic Key Recovery from Side-Channel Leakage" (eprint 2026/699): only partial sampler leakage is needed, because HAWK's public algebraic structure amplifies it. Full-coefficient leakage recovers a HAWK-1024 key from a single signature; the exact-sign hint model reached 100% success over 100 independently generated keys from 14 signatures on the reference implementation.
Both require observing the signer, so they do not change the conclusion for a signer in isolation. They do mean the ≤2¹⁰⁸-gate figure is not what an attacker who can watch signing actually faces.
The measures below concern the implementation only. They do not — and cannot — address the scheme-level break described above; they are documented because the port's fidelity and implementation hygiene remain useful for research and reference:
- Secret key zeroization.
HawkSecretKeyderiveszeroize::ZeroizeOnDrop, so itsf,g,f_cap(F),g_cap(G), andseedfields are zeroed when dropped. Verified by the explicit unit testzeroize_on_drop_clears_secret_material. - Constant-time public-key equality.
HawkPublicKey::ct_equsessubtle::ConstantTimeEqto avoid early-exit byte-by-byte comparison. - Opaque verify errors.
verify_innercollapses every internal rejection intoHawkError::InvalidSignature. TheVerifyRejectvariants that name which check failed are#[doc(hidden)]and test-only, so the public API never reveals the failing check (which would aid malleability attacks). - FFI cross-check. 50 tests in
tests/cross_check.rscover every primitive — mp31 arithmetic, NTT, big-int (zint31), fixed-point FFT, Gaussian sampler, NTRU solver, keygen, sign, verify. 49 byte-diff against the vendored C reference (47 proptest-driven at proptest's 256-case default, a few blocks lower; plus 2 direct diffs); the 50th is a Rust-only round-trip. All are gated behind--features cross-check-reference-c, which builds the C reference and runs bindgen, so they do not run under a defaultcargo testor in CI. - Fault-injection survey (
tests/fault_survey.rs). Drives the real signing inner loop through a doc-hidden seam and injects plausible faults — truncated noise, forced and skipped sym-break, single-coefficient flips, sign flips, skipped norm rejection — then feeds each faulted signature to the real verifier. Every model runs over 8 deterministic keys alongside an un-faulted control that must accept, proving the harness reproduces production. The suite also asserts that the opaqueverify()and the labelled internal path never disagree on accept/reject. - Residual BUFF probing (
tests/buff_residual.rs). The 0.1.1KeyNormCheckfloor closes the constant-q00weak-key class but does not prove full BUFF restoration. This suite probes the explicitly-open residual classes against the real verifier: S-CEO / S-DEO key substitution, non-constant weak keys that pass the floor, and PolyQnorm soundness on(q00, q01)pairs that are not a genuine||(f,g)||²form. - NIST KAT pin. The generated PQCsignKAT_HAWK-512.rsp from the reference harness is committed; case 0's 1024-byte pubkey and 184-byte secret key are asserted byte-for-byte against the Rust implementation.
- Fuzz targets. Three
cargo-fuzzharnesses (fuzz_decode_pubkey,fuzz_decode_signature,fuzz_verify) assert that decoders and the verify pipeline never panic on arbitrary inputs. Stable-Rust proptest mirrors run in CI. - Malformed-input proptests. Corrupting the trailing zero-padding region of a valid pubkey or signature is asserted to return
Err(HawkError::Malformed*)with no panic. Pathological all-zeros / all-ones buffers exercise the unary tail decoder. - Timing smoke tests. A dudect-style coarse test asserts that
signtimings for two different keys stay within 20% of each other; catches gross timing regressions (e.g., an accidental data-dependent early-exit).
The port preserves the branchless / mask-based idioms of the upstream C reference. In particular:
- Modular arithmetic (
mp_add,mp_sub,mp_half,mp_montymul,mp_div) uses the upstream's sign-bit-mask pattern for conditional operations. - The Gaussian sampler (
sig_gauss_alt) uses CDT comparisons without data-dependent branches. - The sym-break check (
poly_symbreak) is a linear scan with carry-forward, not an early-exit. - Public-key equality is constant-time (
ct_eq). - Secret material is zeroed on drop (
ZeroizeOnDrop).
However:
- Rust's default bounds checks on slice indexing panic on out-of-range access. Since our code uses
wrapping_*arithmetic and explicit index math, OOB accesses shouldn't occur with well-formed inputs — and the fuzz harness + malformed-input proptests exercise adversarial inputs against the decode/verify boundary. - Allocator behavior (via
Vec<u16>,Vec<u32>, etc.) is implementation-defined. Timing side-channels involving heap allocation are theoretically possible. - No formal constant-time audit (e.g., dudect, ctgrind, Jasmin) has been performed. The built-in timing smoke test is a regression guard, not a proof.
- The signing-side leakage attacks described above are out of scope for this section: they exploit information the signer emits while signing, not the branch structure of this port. A constant-time implementation does not defend against them.
As of 2026-07-29 the upstream HAWK team has withdrawn HAWK from NIST
standardization (see the status section above). Their pre-existing warning, as
recorded verbatim in c-reference/PROVENANCE.md (the upstream README itself is
not part of what we vendored), was already:
This code was written for the on-ramp call for post-quantum signature schemes, organized by NIST and currently serves research purposes. There was no security review yet so use at own risk.
That warning is now superseded by the confirmed key-recovery break, not merely an absence of review.
Current release: 0.1.3. 0.1.2 and 0.1.3 are documentation-only — no code
behaviour changed — so everything in this document applies to them unchanged.
The latest security-relevant changes shipped in 0.1.1: two issues found and fixed
(see CHANGELOG.md for detail). Both were reproduced against this crate before
being fixed, and both carry regression tests. If you are on 0.1.0, upgrade — it
is a drop-in change with no API break.
- Weak-key BUFF break at verify (Dao, eprint 2026/1298). The verifier
accepted maliciously formed public keys with a tiny
q00[0], under which a single trivial signature verified for essentially every message (measured: 256 of 256). Fixed by aKeyNormCheckfloor rejectingq00[0] < 2080. Honestly generated keys were never affected, and EUF/SUF-CMA security under honest keys was not affected — only the BUFF add-on properties. - Signing could emit an unserializable signature. An in-bounds
s1can still overflow the fixed 555-byte Golomb-Rice buffer in aggregate; signing now resigns on overflow instead of returning a signature that fails to encode. Observed in practice stalling a live testnet on block commit.
If you find a security issue in this port, please report it privately via GitHub Security Advisories rather than opening a public issue, so a fix can be prepared before disclosure.
If the issue is in HAWK itself rather than this port, please also contact the upstream HAWK team (https://github.com/hawk-sign/dev).