commit 133af73a88d86dcdc0bcb01580df9a4c739101ae
parent 759fbe88d16e39bd3a3571c0ebf56a115ddbe3d9
Author: Thomas Bracht Laumann Jespersen <t@laumann.xyz>
Date: Thu, 18 Mar 2021 10:02:18 +0100
crypto/math: Add rot{l,r}64
For SHA-512 implementations we need 64-bit variants of the left and
right bit rotations.
Diffstat:
1 file changed, 26 insertions(+), 0 deletions(-)
diff --git a/crypto/math/bits.ha b/crypto/math/bits.ha
@@ -20,3 +20,29 @@ export fn rotr32(x: u32, k: int) u32 = rotl32(x, -k);
assert(rotl32(a, 32) == 0b11110000111100001111000011110000u32);
assert(rotl32(a, 64) == 0b11110000111100001111000011110000u32);
};
+
+// Rotates a 64-bit unsigned integer left by k bits. k may be negative to rotate
+// rigt instead, or see [rotr64].
+export fn rotl64(x: u64, k: int) u64 = {
+ const n = 64u64;
+ const s = k: u64 & (n - 1);
+ return x << s | x >> (n - s);
+};
+
+// Rotates a 64-bit unsigned integer right by k bits. k may be negative to rotate
+// left instead, or see [rotl64].
+export fn rotr64(x: u64, k: int) u64 = rotl64(x, -k);
+
+@test fn lrot64() void = {
+ let a = 1u64;
+ assert(rotl64(a, 1) == 0b10);
+ assert(rotl64(a, -1) == 0b1000000000000000000000000000000000000000000000000000000000000000);
+ assert(rotl64(a, 39) == (1u64 << 39));
+
+ let a = 0b1111000011110000111100001111000011110000111100001111000011110000u64;
+ assert(rotl64(a, 64) == a);
+ assert(rotl64(a, 0) == a);
+ assert(rotl64(a, 2) == 0b1100001111000011110000111100001111000011110000111100001111000011u64);
+ assert(rotl64(a, -2) == 0b0011110000111100001111000011110000111100001111000011110000111100u64);
+
+};