| ... | ... | @@ -843,7 +843,7 @@ const ct_protected = struct { |
| 843 | 843 | |
| 844 | 844 | // Compares two big integers in constant time, returning true if x >= y. |
| 845 | 845 | fn limbsCmpGeq(x: anytype, y: @TypeOf(x)) bool { |
| 846 | | return !ct.limbsCmpLt(x, y); |
| 846 | return !limbsCmpLt(x, y); |
| 847 | 847 | } |
| 848 | 848 | |
| 849 | 849 | // Multiplies two limbs and returns the result as a wide limb. |
| ... | ... | @@ -878,11 +878,11 @@ const ct_unprotected = struct { |
| 878 | 878 | |
| 879 | 879 | // Compares two big integers in constant time, returning true if x < y. |
| 880 | 880 | fn limbsCmpLt(x: anytype, y: @TypeOf(x)) bool { |
| 881 | | assert(x.limbs_count() == y.limbs_count()); |
| 882 | | const x_limbs = x.limbs.constSlice(); |
| 883 | | const y_limbs = y.limbs.constSlice(); |
| 881 | const x_limbs = x.limbsConst(); |
| 882 | const y_limbs = y.limbsConst(); |
| 883 | assert(x_limbs.len == y_limbs.len); |
| 884 | 884 | |
| 885 | | var i = x.limbs_count(); |
| 885 | var i = x_limbs.len; |
| 886 | 886 | while (i != 0) { |
| 887 | 887 | i -= 1; |
| 888 | 888 | if (x_limbs[i] != y_limbs[i]) { |
| ... | ... | @@ -894,7 +894,7 @@ const ct_unprotected = struct { |
| 894 | 894 | |
| 895 | 895 | // Compares two big integers in constant time, returning true if x >= y. |
| 896 | 896 | fn limbsCmpGeq(x: anytype, y: @TypeOf(x)) bool { |
| 897 | | return !ct.limbsCmpLt(x, y); |
| 897 | return !limbsCmpLt(x, y); |
| 898 | 898 | } |
| 899 | 899 | |
| 900 | 900 | // Multiplies two limbs and returns the result as a wide limb. |
| ... | ... | @@ -961,3 +961,28 @@ test "finite field arithmetic" { |
| 961 | 961 | try testing.expect(x_sq3.eql(x_sq4)); |
| 962 | 962 | try m.fromMontgomery(&x); |
| 963 | 963 | } |
| 964 | |
| 965 | fn testCt(ct_: anytype) !void { |
| 966 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 967 | |
| 968 | const l0: Limb = 0; |
| 969 | const l1: Limb = 1; |
| 970 | try testing.expectEqual(l1, ct_.select(true, l1, l0)); |
| 971 | try testing.expectEqual(l0, ct_.select(false, l1, l0)); |
| 972 | try testing.expectEqual(false, ct_.eql(l1, l0)); |
| 973 | try testing.expectEqual(true, ct_.eql(l1, l1)); |
| 974 | |
| 975 | const M = Modulus(256); |
| 976 | const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233); |
| 977 | const x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733); |
| 978 | const y = try M.Fe.fromPrimitive(u256, m, 24620149608466364616251608466389896540098571); |
| 979 | try testing.expectEqual(false, ct_.limbsCmpLt(x.v, y.v)); |
| 980 | try testing.expectEqual(true, ct_.limbsCmpGeq(x.v, y.v)); |
| 981 | |
| 982 | try testing.expectEqual(WideLimb{ .hi = 0, .lo = 0x88 }, ct_.mulWide(1 << 3, (1 << 4) + 1)); |
| 983 | } |
| 984 | |
| 985 | test ct { |
| 986 | try testCt(ct_protected); |
| 987 | try testCt(ct_unprotected); |
| 988 | } |