Commit 7cf3167e98

clickingbuttons <clickingbuttons@pm.me>
2024-04-23 22:29:36
std.crypto: make ff.ct_unprotected.limbsCmpLt compile (#19741)
* std.crypto: make ff.ct_unprotected.limbsCmpLt compile * std.crypto: add ff.ct test * fix testCt to work on x86 * disable test on stage2-c --------- Co-authored-by: Frank Denis <124872+jedisct1@users.noreply.github.com>
1 parent b87baad
Changed files (1)
lib
std
crypto
lib/std/crypto/ff.zig
@@ -843,7 +843,7 @@ const ct_protected = struct {
 
     // Compares two big integers in constant time, returning true if x >= y.
     fn limbsCmpGeq(x: anytype, y: @TypeOf(x)) bool {
-        return !ct.limbsCmpLt(x, y);
+        return !limbsCmpLt(x, y);
     }
 
     // Multiplies two limbs and returns the result as a wide limb.
@@ -878,11 +878,11 @@ const ct_unprotected = struct {
 
     // Compares two big integers in constant time, returning true if x < y.
     fn limbsCmpLt(x: anytype, y: @TypeOf(x)) bool {
-        assert(x.limbs_count() == y.limbs_count());
-        const x_limbs = x.limbs.constSlice();
-        const y_limbs = y.limbs.constSlice();
+        const x_limbs = x.limbsConst();
+        const y_limbs = y.limbsConst();
+        assert(x_limbs.len == y_limbs.len);
 
-        var i = x.limbs_count();
+        var i = x_limbs.len;
         while (i != 0) {
             i -= 1;
             if (x_limbs[i] != y_limbs[i]) {
@@ -894,7 +894,7 @@ const ct_unprotected = struct {
 
     // Compares two big integers in constant time, returning true if x >= y.
     fn limbsCmpGeq(x: anytype, y: @TypeOf(x)) bool {
-        return !ct.limbsCmpLt(x, y);
+        return !limbsCmpLt(x, y);
     }
 
     // Multiplies two limbs and returns the result as a wide limb.
@@ -961,3 +961,28 @@ test "finite field arithmetic" {
     try testing.expect(x_sq3.eql(x_sq4));
     try m.fromMontgomery(&x);
 }
+
+fn testCt(ct_: anytype) !void {
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
+
+    const l0: Limb = 0;
+    const l1: Limb = 1;
+    try testing.expectEqual(l1, ct_.select(true, l1, l0));
+    try testing.expectEqual(l0, ct_.select(false, l1, l0));
+    try testing.expectEqual(false, ct_.eql(l1, l0));
+    try testing.expectEqual(true, ct_.eql(l1, l1));
+
+    const M = Modulus(256);
+    const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233);
+    const x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733);
+    const y = try M.Fe.fromPrimitive(u256, m, 24620149608466364616251608466389896540098571);
+    try testing.expectEqual(false, ct_.limbsCmpLt(x.v, y.v));
+    try testing.expectEqual(true, ct_.limbsCmpGeq(x.v, y.v));
+
+    try testing.expectEqual(WideLimb{ .hi = 0, .lo = 0x88 }, ct_.mulWide(1 << 3, (1 << 4) + 1));
+}
+
+test ct {
+    try testCt(ct_protected);
+    try testCt(ct_unprotected);
+}