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.
This commit is contained in:
27
lib/crypto/math/math.ww
Normal file
27
lib/crypto/math/math.ww
Normal file
@@ -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);
|
||||
};
|
||||
Reference in New Issue
Block a user