srctree

clickingbuttons parent b87baad0 7cf3167e
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>

inlinesplit
lib/std/crypto/ff.zig added: 32, removed: 7, total 25
@@ -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);
}