Commit f3667e8a80
Changed files (3)
lib
std
crypto
lib/std/crypto/25519/curve25519.zig
@@ -39,6 +39,11 @@ pub const Curve25519 = struct {
}
}
+ /// Multiply a point by the cofactor
+ pub fn clearCofactor(p: Edwards25519) Edwards25519 {
+ return p.dbl().dbl().dbl();
+ }
+
fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) !Curve25519 {
var x1 = p.x;
var x2 = Fe.one;
lib/std/crypto/25519/ed25519.zig
@@ -97,6 +97,7 @@ pub const Ed25519 = struct {
try Curve.rejectNonCanonical(public_key);
const a = try Curve.fromBytes(public_key);
try a.rejectIdentity();
+ const expected_r = try Curve.fromBytes(r.*);
var h = Sha512.init(.{});
h.update(r);
@@ -106,11 +107,11 @@ pub const Ed25519 = struct {
h.final(&hram64);
const hram = Curve.scalar.reduce64(hram64);
- const p = try a.neg().mul(hram);
- const check = (try Curve.basePoint.mul(s.*)).add(p).toBytes();
- if (mem.eql(u8, &check, r) == false) {
+ const ah = try a.neg().mul(hram);
+ const sb_ah = (try Curve.basePoint.mul(s.*)).add(ah);
+ if (expected_r.sub(sb_ah).clearCofactor().rejectIdentity()) |_| {
return error.InvalidSignature;
- }
+ } else |_| {}
}
};
lib/std/crypto/25519/edwards25519.zig
@@ -73,6 +73,11 @@ pub const Edwards25519 = struct {
}
}
+ /// Multiply a point by the cofactor
+ pub fn clearCofactor(p: Edwards25519) Edwards25519 {
+ return p.dbl().dbl().dbl();
+ }
+
/// 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() };
@@ -114,6 +119,11 @@ pub const Edwards25519 = struct {
};
}
+ /// Substract two Edwards25519 points.
+ pub fn sub(p: Edwards25519, q: Edwards25519) Edwards25519 {
+ return p.add(q.neg());
+ }
+
inline fn cMov(p: *Edwards25519, a: Edwards25519, c: u64) void {
p.x.cMov(a.x, c);
p.y.cMov(a.y, c);
@@ -217,3 +227,17 @@ test "edwards25519 packing/unpacking" {
std.testing.expectError(error.WeakPublicKey, small_p.mul(s));
}
}
+
+test "edwards25519 point addition/substraction" {
+ var s1: [32]u8 = undefined;
+ var s2: [32]u8 = undefined;
+ try std.crypto.randomBytes(&s1);
+ try std.crypto.randomBytes(&s2);
+ const p = try Edwards25519.basePoint.clampedMul(s1);
+ const q = try Edwards25519.basePoint.clampedMul(s2);
+ const r = p.add(q).add(q).sub(q).sub(q);
+ try r.rejectIdentity();
+ std.testing.expectError(error.IdentityElement, r.sub(p).rejectIdentity());
+ std.testing.expectError(error.IdentityElement, p.sub(p).rejectIdentity());
+ std.testing.expectError(error.IdentityElement, p.sub(q).add(q).sub(p).rejectIdentity());
+}