| ... | @@ -256,6 +256,7 @@ pub fn Ecdsa(comptime C: type, comptime H: type) type { | ... | @@ -256,6 +256,7 @@ pub fn Ecdsa(comptime C: type, comptime H: type) type { |
| 256 | const r = try Curve.scalar.Scalar.fromBytes(sig.r, .big); | 256 | const r = try Curve.scalar.Scalar.fromBytes(sig.r, .big); |
| 257 | const s = try Curve.scalar.Scalar.fromBytes(sig.s, .big); | 257 | const s = try Curve.scalar.Scalar.fromBytes(sig.s, .big); |
| 258 | if (r.isZero() or s.isZero()) return error.IdentityElement; | 258 | if (r.isZero() or s.isZero()) return error.IdentityElement; |
| | 259 | try public_key.p.rejectIdentity(); |
| 259 | | 260 | |
| 260 | return Verifier{ | 261 | return Verifier{ |
| 261 | .h = Hash.init(.{}), | 262 | .h = Hash.init(.{}), |
| ... | @@ -287,13 +288,19 @@ pub fn Ecdsa(comptime C: type, comptime H: type) type { | ... | @@ -287,13 +288,19 @@ pub fn Ecdsa(comptime C: type, comptime H: type) type { |
| 287 | const s_inv = self.s.invert(); | 288 | const s_inv = self.s.invert(); |
| 288 | const v1 = z.mul(s_inv).toBytes(.little); | 289 | const v1 = z.mul(s_inv).toBytes(.little); |
| 289 | const v2 = self.r.mul(s_inv).toBytes(.little); | 290 | const v2 = self.r.mul(s_inv).toBytes(.little); |
| 290 | const v1g = try Curve.basePoint.mulPublic(v1, .little); | 291 | const v = Curve.mulDoubleBasePublic(Curve.basePoint, v1, self.public_key.p, v2, .little) catch |
| 291 | const v2pk = try self.public_key.p.mulPublic(v2, .little); | | |
| 292 | const vxs = v1g.add(v2pk).affineCoordinates().x.toBytes(.big); | | |
| 293 | const vr = reduceToScalar(Curve.Fe.encoded_length, vxs); | | |
| 294 | if (!self.r.equivalent(vr)) { | | |
| 295 | return error.SignatureVerificationFailed; | 292 | return error.SignatureVerificationFailed; |
| | 293 | |
| | 294 | const Fe = Curve.Fe; |
| | 295 | const n = Curve.scalar.field_order; |
| | 296 | comptime std.debug.assert(n < Fe.field_order and Fe.field_order < 2 * n); |
| | 297 | const r = Fe.fromBytes(self.r.toBytes(.little), .little) catch unreachable; |
| | 298 | if (v.x.equivalent(r.mul(v.z))) return; |
| | 299 | if (r.toInt() < Fe.field_order - n) { |
| | 300 | const n_fe = comptime Fe.fromInt(n) catch unreachable; |
| | 301 | if (v.x.equivalent(r.add(n_fe).mul(v.z))) return; |
| 296 | } | 302 | } |
| | 303 | return error.SignatureVerificationFailed; |
| 297 | } | 304 | } |
| 298 | | 305 | |
| 299 | /// Verify that the signature is valid for the entire message. | 306 | /// Verify that the signature is valid for the entire message. |