| author | |
| committer | |
| log | 7411be3c9e6d169108456f03b3cbb9b476ee7498 |
| tree | ac2d936d1236034cc4a274a493bed1ded0bc05b4 |
| parent | 609716524169c538b7f12666c3f9bb46a0aeeb3c |
| signature |
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.2 files changed, 14 insertions(+), 1 deletions(-)
lib/std/crypto/25519/ed25519.zig+1-1| ... | ... | @@ -181,7 +181,7 @@ pub const Ed25519 = struct { |
| 181 | 181 | const hram = Curve.scalar.reduce64(hram64); |
| 182 | 182 | |
| 183 | 183 | const sb_ah = try Curve.basePoint.mulDoubleBasePublic(self.s, self.a.neg(), hram); |
| 184 | if (self.expected_r.sub(sb_ah).clearCofactor().rejectIdentity()) |_| { | |
| 184 | if (self.expected_r.sub(sb_ah).rejectLowOrder()) { | |
| 185 | 185 | return error.SignatureVerificationFailed; |
| 186 | 186 | } else |_| {} |
| 187 | 187 | } |
lib/std/crypto/25519/edwards25519.zig+13| ... | ... | @@ -83,6 +83,19 @@ pub const Edwards25519 = struct { |
| 83 | 83 | return p.dbl().dbl().dbl(); |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | /// Check that the point does not generate a low-order group. | |
| 87 | /// Return a `WeakPublicKey` error if it does. | |
| 88 | pub fn rejectLowOrder(p: Edwards25519) WeakPublicKeyError!void { | |
| 89 | const zi = p.z.invert(); | |
| 90 | const x = p.x.mul(zi); | |
| 91 | const y = p.y.mul(zi); | |
| 92 | const x_neg = x.neg(); | |
| 93 | const iy = Fe.sqrtm1.mul(y); | |
| 94 | if (x.isZero() or y.isZero() or iy.equivalent(x) or iy.equivalent(x_neg)) { | |
| 95 | return error.WeakPublicKey; | |
| 96 | } | |
| 97 | } | |
| 98 | ||
| 86 | 99 | /// Flip the sign of the X coordinate. |
| 87 | 100 | pub inline fn neg(p: Edwards25519) Edwards25519 { |
| 88 | 101 | return .{ .x = p.x.neg(), .y = p.y, .z = p.z, .t = p.t.neg() }; |