From fdd87e56bf8c8b00af28e810e4f086a32a1cd633 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Tue, 2 Jun 2026 07:19:03 +0900 Subject: [PATCH] lib/crypto/math: add rotl32/rotr32 (sha256 prereq) Subset port of ref/hare/crypto/math/bits.ha: the 32-bit rotations sha256's message schedule and compression need. The wider bits.ha surface (rotl64/rotr64, the constant-time compare family, xor) lands as callers arrive. rotr32 is exercised end-to-end by the sha256 NIST digest vectors, so no standalone @test ships here. --- lib/crypto/math/math.ww | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lib/crypto/math/math.ww diff --git a/lib/crypto/math/math.ww b/lib/crypto/math/math.ww new file mode 100644 index 00000000..4cbecb54 --- /dev/null +++ b/lib/crypto/math/math.ww @@ -0,0 +1,27 @@ +// crypto/math — bit-rotation helpers for crypto primitives. Subset port +// of ref/hare/crypto/math/bits.ha: the 32-bit rotations sha256 needs. +// +// The wider bits.ha surface (rotl64/rotr64, the constant-time compare +// family — eqslice/equ32/gtu32/…, xor, mul) lands as callers arrive; +// only rotl32/rotr32 are pulled in for crypto/sha256. rotr32 is +// exercised end-to-end by the sha256 NIST digest vectors (the message +// schedule and compression both lean on it), so no standalone @test is +// shipped here — the digest is the stronger oracle. +package math; + +// rotl32 — rotate `x` left by `k` bits. `k` may be negative to rotate +// right instead; see [[rotr32]]. ref/hare/crypto/math/bits.ha:9. +// Hare's `const` locals are `let` (ww has no `const`). `int` is an 8B +// machine word here vs Hare's 4B; the `k: u32` truncation makes the +// width difference invisible to the masked shift count. +export fn rotl32(x: u32, k: int) u32 = { + let n: u32 = 32u32; + let s: u32 = (k: u32) & (n - 1u32); + return x << s | x >> (n - s); +}; + +// rotr32 — rotate `x` right by `k` bits. `k` may be negative to rotate +// left instead; see [[rotl32]]. ref/hare/crypto/math/bits.ha:17. +export fn rotr32(x: u32, k: int) u32 = { + return rotl32(x, -k); +};