authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-10-03 14:36:13+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-10-03 14:36:13+02:00
logc31cb992737dd9eb7d910caeaa5259a65eac5b6e
tree9a36b2d674187279dcc815e90dc4db9dd9eb66fd
parent4258dce9198b851be2f99f0c9e682ef00d33b7b5
parenta57cf67863683c83506e864aef9cb0157d8d8d41

Merge pull request 'crypto.ff: don't compare elements with different representations' (#37038) from jedisct1/zig:ff-fixes8 into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37038

1 files changed, 10 insertions(+), 4 deletions(-)

lib/std/crypto/ff.zig+10-4
......@@ -482,12 +482,15 @@ fn Fe_(comptime bits: comptime_int) type {
482482 }
483483
484484 /// Returns `true` if the field elements are equal, in constant time.
485 /// Elements in different representations compare unequal; convert them to the same form to compare values.
485486 pub fn eql(x: Self, y: Self) bool {
486 return x.v.eql(y.v);
487 const values_equal = x.v.eql(y.v);
488 return x.montgomery == y.montgomery and values_equal;
487489 }
488490
489491 /// Compares two field elements in constant time.
490492 pub fn compare(x: Self, y: Self) math.Order {
493 assert(!x.montgomery and !y.montgomery);
491494 return x.v.compare(y.v);
492495 }
493496
......@@ -497,7 +500,9 @@ fn Fe_(comptime bits: comptime_int) type {
497500 }
498501
499502 /// Returns `true` is the element is odd.
503 /// Requires plain form because Montgomery encoding doesn't preserve parity.
500504 pub fn isOdd(self: Self) bool {
505 assert(!self.montgomery);
501506 return self.v.isOdd();
502507 }
503508 };
......@@ -576,6 +581,7 @@ pub fn Modulus(comptime max_bits: comptime_int) type {
576581 const Self = @This();
577582
578583 /// A field element, representing a value within the field defined by this modulus.
584 /// Use elements only with the modulus that created them, even if another modulus has the same size.
579585 pub const Fe = Fe_(max_bits);
580586
581587 const FeUint = Fe.FeUint;
......@@ -1172,7 +1178,7 @@ test "finite field arithmetic" {
11721178 const M = Modulus(256);
11731179 const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233);
11741180 var x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733);
1175 var y = try M.Fe.fromPrimitive(u256, m, 24620149608466364616251608466389896540098571);
1181 const y = try M.Fe.fromPrimitive(u256, m, 24620149608466364616251608466389896540098571);
11761182
11771183 const x_ = try x.toPrimitive(u256);
11781184 try testing.expect((try M.Fe.fromPrimitive(@TypeOf(x_), m, x_)).eql(x));
......@@ -1243,10 +1249,10 @@ test "finite field arithmetic" {
12431249 try testing.expect(add_nm_m.eql(add_m_nm));
12441250
12451251 // Non-montgomery - montgomery
1246 const sub_nm_m = m.sub(x, y);
1247 try testing.expect(!sub_nm_m.montgomery);
12481252 var y_mont = y;
12491253 try m.toMontgomery(&y_mont);
1254 const sub_nm_m = m.sub(x, y_mont);
1255 try testing.expect(!sub_nm_m.montgomery);
12501256 var sub_m_nm = m.sub(x_mont, y);
12511257 try testing.expect(sub_m_nm.montgomery);
12521258 try m.fromMontgomery(&sub_m_nm);