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:

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-D in HMAC / CMAC / KMAC / GMAC — countermeasures.

  • Ed25519 SHA-512 inside ed25519_sign — addressed by the same T2-D once the masked SHA-512 is plumbed through.

  • RFC 6979 HMAC-DRBG-SHA-2 inside rfc6979_k — feeds sk_bytes through 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 T2-D)

hash::sha256::Sha256

CT by construction

Add MaskedSha256 for masked HMAC

hash::sha512::Sha512

CT by construction

Add MaskedSha512 for masked HMAC + Ed25519

hash::sha3::*

CT by construction (Keccak)

Unchanged

hash::blake2::*

CT by construction

Unchanged (no keyed-mode SCA concern in arcana flows)

hash::sha1::*, hash::ripemd160::*

CT by construction; legacy

Unchanged