Hash functions — countermeasures
- Spec:
FIPS 180-4 (SHA-1, SHA-2 family), FIPS 202 (SHA-3, SHAKE), NIST SP 800-185 (cSHAKE), RFC 7693 (BLAKE2), ISO/IEC 10118-3 (RIPEMD-160)
- Crate path:
arcana::hash::*- Cargo feature:
none — all hashes compiled unconditionally.
Plain (unkeyed) hash functions are not SCA-sensitive in isolation: they have no secret input, so there is nothing to leak. They become SCA-relevant only when a secret is fed in:
HMAC keyed mode → see HMAC / CMAC / KMAC / GMAC — countermeasures.
Ed25519 nonce derivation
r = H(prefix ‖ M) mod ℓand challengek = H(R ‖ A ‖ M) mod ℓ→ see EdDSA / Ed25519 — countermeasures.RFC 6979 deterministic ECDSA nonce derivation (HMAC-DRBG inside
rfc6979_k) → see ECDSA / ECDH — countermeasures.RSA-PSS / OAEP MGF1 mask generation (when the seed contains secret data) → see RSA — countermeasures.
This chapter is therefore short — it documents the two CT properties the hash implementations must guarantee, even when unkeyed, because they will be invoked from the keyed paths above.
Required CT properties
CT-1: no secret-dependent branches
Every hash function in arcana::hash::* must:
Process exactly one fixed-length compression-function call per block, with no early-exit.
Use bitwise rotations / shifts / additions, no table lookups indexed by secret-derived values.
Have a CT padding step (compute the final block length without branching on whether padding fits in the current block).
Status per family
SHA-1 / SHA-2 (256, 384, 512, 224, 512/224, 512/256): CT by construction. Compression function is a fixed-iteration loop; rotations are by constants; additions have no carry-on-the-key branches (CDPA is a power leak, not a timing leak). Audit confirmed.
SHA-3 / SHAKE / cSHAKE (Keccak-f[1600]): CT by construction. No table-based S-box. Rho rotations are by constants. Confirmed.
BLAKE2b / BLAKE2s: CT by construction. The G-function is XOR/ADD/ROTR composition over fixed positions.
RIPEMD-160: CT by construction.
CT-2: no secret-leak through error paths
The streaming hash::Hasher API (new, update,
finalize) does not have a “wrong size” branch on user
input — over-large inputs simply consume more compression-function
calls. The only error path is “buffer too small” on the byte
output, which is checked by debug_assert-equivalent (not on
secret input).
DPA / CDPA on the keyed-input path
The [BDT+23] result (CDPA on HMAC-SHA-2) applies to any usage of SHA-2 where a secret feeds the compression function. In arcana that is:
HMAC-SHA-256/384/512 — addressed by
T2-Din HMAC / CMAC / KMAC / GMAC — countermeasures.Ed25519 SHA-512 inside
ed25519_sign— addressed by the sameT2-Donce the masked SHA-512 is plumbed through.RFC 6979 HMAC-DRBG-SHA-2 inside
rfc6979_k— feedssk_bytesthrough HMAC-SHA-2; same vulnerability, same mitigation.
The Keccak-based primitives (SHA-3 / SHAKE / cSHAKE / KMAC) are
not vulnerable to the CDPA result because Keccak has no
arithmetic addition in its round function (the only carry chain
is in ι’s XOR with a round constant, which is public). They
inherit standard SPA / DPA concerns on the secret-loading step,
but no analogue of CDPA. RFC 6979 is HMAC-SHA-2 specifically; a
HashML-DSA-style future arcana variant could prefer
HMAC-SHAKE-256-DRBG as a defensive default — but RFC 6979 is the
standard and we keep it.
Code path summary
Path |
Today (2026-04-21) |
Target (post |
|---|---|---|
|
CT by construction |
Add |
|
CT by construction |
Add |
|
CT by construction (Keccak) |
Unchanged |
|
CT by construction |
Unchanged (no keyed-mode SCA concern in arcana flows) |
|
CT by construction; legacy |
Unchanged |