diff --git a/lib/std/crypto/25519/ed25519.zig b/lib/std/crypto/25519/ed25519.zig index 149191040a..7d136fc12d 100644 --- a/lib/std/crypto/25519/ed25519.zig +++ b/lib/std/crypto/25519/ed25519.zig @@ -181,7 +181,7 @@ pub const Ed25519 = struct { const hram = Curve.scalar.reduce64(hram64); const sb_ah = try Curve.basePoint.mulDoubleBasePublic(self.s, self.a.neg(), hram); - if (self.expected_r.sub(sb_ah).clearCofactor().rejectIdentity()) |_| { + if (self.expected_r.sub(sb_ah).rejectLowOrder()) { return error.SignatureVerificationFailed; } else |_| {} } diff --git a/lib/std/crypto/25519/edwards25519.zig b/lib/std/crypto/25519/edwards25519.zig index f7b07738a2..840f4b67d5 100644 --- a/lib/std/crypto/25519/edwards25519.zig +++ b/lib/std/crypto/25519/edwards25519.zig @@ -83,6 +83,19 @@ pub const Edwards25519 = struct { return p.dbl().dbl().dbl(); } + /// Check that the point does not generate a low-order group. + /// Return a `WeakPublicKey` error if it does. + pub fn rejectLowOrder(p: Edwards25519) WeakPublicKeyError!void { + const zi = p.z.invert(); + const x = p.x.mul(zi); + const y = p.y.mul(zi); + const x_neg = x.neg(); + const iy = Fe.sqrtm1.mul(y); + if (x.isZero() or y.isZero() or iy.equivalent(x) or iy.equivalent(x_neg)) { + return error.WeakPublicKey; + } + } + /// Flip the sign of the X coordinate. pub inline fn neg(p: Edwards25519) Edwards25519 { return .{ .x = p.x.neg(), .y = p.y, .z = p.z, .t = p.t.neg() };