From df909da5d87fda01245c564858522c6c57dd8a75 Mon Sep 17 00:00:00 2001 From: Chris Heyes <22148308+hazeycode@users.noreply.github.com> Date: Sun, 21 May 2023 12:00:48 +0100 Subject: [PATCH] std.crypto: expose Fe isOdd & add basic parity tests for each pcurve (#15734) * std Secp256k1 Scalar: expose Fe isOdd & add basic parity test * std.crypto: also add Scalar.isOdd convenience fn for p256 and p384 curves --- lib/std/crypto/pcurves/p256/scalar.zig | 5 +++++ lib/std/crypto/pcurves/p384/scalar.zig | 5 +++++ lib/std/crypto/pcurves/secp256k1/scalar.zig | 5 +++++ lib/std/crypto/pcurves/tests/p256.zig | 6 ++++++ lib/std/crypto/pcurves/tests/p384.zig | 6 ++++++ lib/std/crypto/pcurves/tests/secp256k1.zig | 6 ++++++ 6 files changed, 33 insertions(+) diff --git a/lib/std/crypto/pcurves/p256/scalar.zig b/lib/std/crypto/pcurves/p256/scalar.zig index 4e88d1fee7..9506a5e57a 100644 --- a/lib/std/crypto/pcurves/p256/scalar.zig +++ b/lib/std/crypto/pcurves/p256/scalar.zig @@ -109,6 +109,11 @@ pub const Scalar = struct { return n.fe.isZero(); } + /// Return true if the scalar is odd. + pub fn isOdd(n: Scalar) bool { + return n.fe.isOdd(); + } + /// Return true if a and b are equivalent. pub fn equivalent(a: Scalar, b: Scalar) bool { return a.fe.equivalent(b.fe); diff --git a/lib/std/crypto/pcurves/p384/scalar.zig b/lib/std/crypto/pcurves/p384/scalar.zig index ef257ab7ce..499305bfec 100644 --- a/lib/std/crypto/pcurves/p384/scalar.zig +++ b/lib/std/crypto/pcurves/p384/scalar.zig @@ -98,6 +98,11 @@ pub const Scalar = struct { return n.fe.isZero(); } + /// Return true if the scalar is odd. + pub fn isOdd(n: Scalar) bool { + return n.fe.isOdd(); + } + /// Return true if a and b are equivalent. pub fn equivalent(a: Scalar, b: Scalar) bool { return a.fe.equivalent(b.fe); diff --git a/lib/std/crypto/pcurves/secp256k1/scalar.zig b/lib/std/crypto/pcurves/secp256k1/scalar.zig index e0b5e053e3..2a40c9bf96 100644 --- a/lib/std/crypto/pcurves/secp256k1/scalar.zig +++ b/lib/std/crypto/pcurves/secp256k1/scalar.zig @@ -109,6 +109,11 @@ pub const Scalar = struct { return n.fe.isZero(); } + /// Return true if the scalar is odd. + pub fn isOdd(n: Scalar) bool { + return n.fe.isOdd(); + } + /// Return true if a and b are equivalent. pub fn equivalent(a: Scalar, b: Scalar) bool { return a.fe.equivalent(b.fe); diff --git a/lib/std/crypto/pcurves/tests/p256.zig b/lib/std/crypto/pcurves/tests/p256.zig index eab69d351e..716f730dc7 100644 --- a/lib/std/crypto/pcurves/tests/p256.zig +++ b/lib/std/crypto/pcurves/tests/p256.zig @@ -134,3 +134,9 @@ test "p256 scalar inverse" { const inverse = scalar.invert(); try std.testing.expectEqualSlices(u8, &out, &inverse.toBytes(.Big)); } + +test "p256 scalar parity" { + try std.testing.expect(P256.scalar.Scalar.zero.isOdd() == false); + try std.testing.expect(P256.scalar.Scalar.one.isOdd()); + try std.testing.expect(P256.scalar.Scalar.one.dbl().isOdd() == false); +} diff --git a/lib/std/crypto/pcurves/tests/p384.zig b/lib/std/crypto/pcurves/tests/p384.zig index cba1d91a81..1763cfcfa5 100644 --- a/lib/std/crypto/pcurves/tests/p384.zig +++ b/lib/std/crypto/pcurves/tests/p384.zig @@ -144,3 +144,9 @@ test "p384 scalar inverse" { const sqr = try sq.sqrt(); try testing.expect(sqr.equivalent(scalar)); } + +test "p384 scalar parity" { + try std.testing.expect(P384.scalar.Scalar.zero.isOdd() == false); + try std.testing.expect(P384.scalar.Scalar.one.isOdd()); + try std.testing.expect(P384.scalar.Scalar.one.dbl().isOdd() == false); +} diff --git a/lib/std/crypto/pcurves/tests/secp256k1.zig b/lib/std/crypto/pcurves/tests/secp256k1.zig index 32fca87691..b651f01e04 100644 --- a/lib/std/crypto/pcurves/tests/secp256k1.zig +++ b/lib/std/crypto/pcurves/tests/secp256k1.zig @@ -135,3 +135,9 @@ test "secp256k1 scalar inverse" { const inverse = scalar.invert(); try std.testing.expectEqualSlices(u8, &out, &inverse.toBytes(.Big)); } + +test "secp256k1 scalar parity" { + try std.testing.expect(Secp256k1.scalar.Scalar.zero.isOdd() == false); + try std.testing.expect(Secp256k1.scalar.Scalar.one.isOdd()); + try std.testing.expect(Secp256k1.scalar.Scalar.one.dbl().isOdd() == false); +}