std.crypto.edwards25519: add a rejectLowOrder() function (#13668)
Does what the name says: rejects generators of low-order groups. `clearCofactor()` was previously used to do it, but for e.g. cofactored signature verification, we don't need the result of an actual multiplication. Only check that we didn't end up with a low-order point, which is a faster operation.
This commit is contained in:
@@ -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 |_| {}
|
||||
}
|
||||
|
||||
@@ -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() };
|
||||
|
||||
Reference in New Issue
Block a user