mirror of
https://github.com/ziglang/zig.git
synced 2025-12-18 04:03:14 +00:00
Address more review issues
This commit is contained in:
parent
263c444738
commit
bcef123d90
@ -19,10 +19,8 @@ pub const Curve25519 = struct {
|
|||||||
return p.x.toBytes();
|
return p.x.toBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the Curve25519 base point.
|
/// The Curve25519 base point.
|
||||||
pub inline fn basePoint() Curve25519 {
|
pub const basePoint = Curve25519{ .x = Fe.curve25519BasePoint };
|
||||||
return .{ .x = Fe.curve25519BasePoint };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the encoding of a Curve25519 point is canonical.
|
/// Check that the encoding of a Curve25519 point is canonical.
|
||||||
pub fn rejectNonCanonical(s: [32]u8) !void {
|
pub fn rejectNonCanonical(s: [32]u8) !void {
|
||||||
@ -103,7 +101,7 @@ pub const Curve25519 = struct {
|
|||||||
|
|
||||||
test "curve25519" {
|
test "curve25519" {
|
||||||
var s = [32]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
|
var s = [32]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
const p = try Curve25519.basePoint().clampedMul(s);
|
const p = try Curve25519.basePoint.clampedMul(s);
|
||||||
try p.rejectIdentity();
|
try p.rejectIdentity();
|
||||||
var buf: [128]u8 = undefined;
|
var buf: [128]u8 = undefined;
|
||||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E6F2A4D1C28EE5C7AD0329268255A468AD407D2672824C0C0EB30EA6EF450145");
|
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E6F2A4D1C28EE5C7AD0329268255A468AD407D2672824C0C0EB30EA6EF450145");
|
||||||
|
|||||||
@ -19,12 +19,19 @@ pub const Ed25519 = struct {
|
|||||||
pub const noise_length = 32;
|
pub const noise_length = 32;
|
||||||
|
|
||||||
/// Derive a key pair from a secret seed.
|
/// Derive a key pair from a secret seed.
|
||||||
|
///
|
||||||
|
/// As in RFC 8032, an Ed25519 public key is generated by hashing
|
||||||
|
/// the secret key using the SHA-512 function, and interpreting the
|
||||||
|
/// bit-swapped, clamped lower-half of the output as the secret scalar.
|
||||||
|
///
|
||||||
|
/// For this reason, an EdDSA secret key is commonly called a seed,
|
||||||
|
/// from which the actual secret is derived.
|
||||||
pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 {
|
pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 {
|
||||||
var az: [Sha512.digest_length]u8 = undefined;
|
var az: [Sha512.digest_length]u8 = undefined;
|
||||||
var h = Sha512.init();
|
var h = Sha512.init();
|
||||||
h.update(&seed);
|
h.update(&seed);
|
||||||
h.final(&az);
|
h.final(&az);
|
||||||
const p = try Curve.basePoint().clampedMul(az[0..32].*);
|
const p = try Curve.basePoint.clampedMul(az[0..32].*);
|
||||||
var keypair: [keypair_length]u8 = undefined;
|
var keypair: [keypair_length]u8 = undefined;
|
||||||
mem.copy(u8, &keypair, &seed);
|
mem.copy(u8, &keypair, &seed);
|
||||||
mem.copy(u8, keypair[seed_length..], &p.toBytes());
|
mem.copy(u8, keypair[seed_length..], &p.toBytes());
|
||||||
@ -57,7 +64,7 @@ pub const Ed25519 = struct {
|
|||||||
var nonce64: [64]u8 = undefined;
|
var nonce64: [64]u8 = undefined;
|
||||||
h.final(&nonce64);
|
h.final(&nonce64);
|
||||||
const nonce = Curve.scalar.reduce64(nonce64);
|
const nonce = Curve.scalar.reduce64(nonce64);
|
||||||
const r = try Curve.basePoint().mul(nonce);
|
const r = try Curve.basePoint.mul(nonce);
|
||||||
|
|
||||||
var sig: [signature_length]u8 = undefined;
|
var sig: [signature_length]u8 = undefined;
|
||||||
mem.copy(u8, sig[0..32], &r.toBytes());
|
mem.copy(u8, sig[0..32], &r.toBytes());
|
||||||
@ -95,7 +102,7 @@ pub const Ed25519 = struct {
|
|||||||
const hram = Curve.scalar.reduce64(hram64);
|
const hram = Curve.scalar.reduce64(hram64);
|
||||||
|
|
||||||
const p = try a.neg().mul(hram);
|
const p = try a.neg().mul(hram);
|
||||||
const check = (try Curve.basePoint().mul(s.*)).add(p).toBytes();
|
const check = (try Curve.basePoint.mul(s.*)).add(p).toBytes();
|
||||||
if (mem.eql(u8, &check, r) == false) {
|
if (mem.eql(u8, &check, r) == false) {
|
||||||
return error.InvalidSignature;
|
return error.InvalidSignature;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,20 +50,16 @@ pub const Edwards25519 = struct {
|
|||||||
return Fe.rejectNonCanonical(s, true);
|
return Fe.rejectNonCanonical(s, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the Edwards25519 base point.
|
/// The edwards25519 base point.
|
||||||
pub inline fn basePoint() Edwards25519 {
|
pub const basePoint = Edwards25519{
|
||||||
return .{
|
|
||||||
.x = Fe{ .limbs = .{ 3990542415680775, 3398198340507945, 4322667446711068, 2814063955482877, 2839572215813860 } },
|
.x = Fe{ .limbs = .{ 3990542415680775, 3398198340507945, 4322667446711068, 2814063955482877, 2839572215813860 } },
|
||||||
.y = Fe{ .limbs = .{ 1801439850948184, 1351079888211148, 450359962737049, 900719925474099, 1801439850948198 } },
|
.y = Fe{ .limbs = .{ 1801439850948184, 1351079888211148, 450359962737049, 900719925474099, 1801439850948198 } },
|
||||||
.z = Fe.one,
|
.z = Fe.one,
|
||||||
.t = Fe{ .limbs = .{ 1841354044333475, 16398895984059, 755974180946558, 900171276175154, 1821297809914039 } },
|
.t = Fe{ .limbs = .{ 1841354044333475, 16398895984059, 755974180946558, 900171276175154, 1821297809914039 } },
|
||||||
.is_base = true,
|
.is_base = true,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
inline fn identityElement() Edwards25519 {
|
const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero };
|
||||||
return .{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reject the neutral element.
|
/// Reject the neutral element.
|
||||||
pub fn rejectIdentity(p: Edwards25519) !void {
|
pub fn rejectIdentity(p: Edwards25519) !void {
|
||||||
@ -121,16 +117,16 @@ pub const Edwards25519 = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fn pcSelect(pc: [16]Edwards25519, b: u8) Edwards25519 {
|
inline fn pcSelect(pc: [16]Edwards25519, b: u8) Edwards25519 {
|
||||||
var t = Edwards25519.identityElement();
|
var t = Edwards25519.identityElement;
|
||||||
comptime var i: u8 = 0;
|
comptime var i: u8 = 0;
|
||||||
inline while (i < 16) : (i += 1) {
|
inline while (i < 16) : (i += 1) {
|
||||||
t.cMov(pc[i], ((@as(usize, (b ^ i)) -% 1) >> 8) & 1);
|
t.cMov(pc[i], ((@as(usize, b ^ i) -% 1) >> 8) & 1);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pcMul(pc: [16]Edwards25519, s: [32]u8) !Edwards25519 {
|
fn pcMul(pc: [16]Edwards25519, s: [32]u8) !Edwards25519 {
|
||||||
var q = Edwards25519.identityElement();
|
var q = Edwards25519.identityElement;
|
||||||
var pos: usize = 252;
|
var pos: usize = 252;
|
||||||
while (true) : (pos -= 4) {
|
while (true) : (pos -= 4) {
|
||||||
q = q.dbl().dbl().dbl().dbl();
|
q = q.dbl().dbl().dbl().dbl();
|
||||||
@ -144,7 +140,7 @@ pub const Edwards25519 = struct {
|
|||||||
|
|
||||||
fn precompute(p: Edwards25519) [16]Edwards25519 {
|
fn precompute(p: Edwards25519) [16]Edwards25519 {
|
||||||
var pc: [16]Edwards25519 = undefined;
|
var pc: [16]Edwards25519 = undefined;
|
||||||
pc[0] = Edwards25519.identityElement();
|
pc[0] = Edwards25519.identityElement;
|
||||||
pc[1] = p;
|
pc[1] = p;
|
||||||
var i: usize = 2;
|
var i: usize = 2;
|
||||||
while (i < 16) : (i += 1) {
|
while (i < 16) : (i += 1) {
|
||||||
@ -153,11 +149,14 @@ pub const Edwards25519 = struct {
|
|||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _mul(p: Edwards25519, s: [32]u8) !Edwards25519 {
|
/// Multiply an Edwards25519 point by a scalar without clamping it.
|
||||||
|
/// Return error.WeakPublicKey if the resulting point is
|
||||||
|
/// the identity element.
|
||||||
|
pub fn mul(p: Edwards25519, s: [32]u8) !Edwards25519 {
|
||||||
var pc: [16]Edwards25519 = undefined;
|
var pc: [16]Edwards25519 = undefined;
|
||||||
if (p.is_base) {
|
if (p.is_base) {
|
||||||
@setEvalBranchQuota(10000);
|
@setEvalBranchQuota(10000);
|
||||||
pc = comptime precompute(Edwards25519.basePoint());
|
pc = comptime precompute(Edwards25519.basePoint);
|
||||||
} else {
|
} else {
|
||||||
pc = precompute(p);
|
pc = precompute(p);
|
||||||
pc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
pc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
||||||
@ -174,20 +173,13 @@ pub const Edwards25519 = struct {
|
|||||||
pub fn clampedMul(p: Edwards25519, s: [32]u8) !Edwards25519 {
|
pub fn clampedMul(p: Edwards25519, s: [32]u8) !Edwards25519 {
|
||||||
var t: [32]u8 = s;
|
var t: [32]u8 = s;
|
||||||
scalar.clamp(&t);
|
scalar.clamp(&t);
|
||||||
return _mul(p, t);
|
return mul(p, t);
|
||||||
}
|
|
||||||
|
|
||||||
/// Multiply an Edwards25519 point by a scalar without clamping it.
|
|
||||||
/// Return error.WeakPublicKey if the resulting point is
|
|
||||||
/// the identity element.
|
|
||||||
pub fn mul(p: Edwards25519, s: [32]u8) !Edwards25519 {
|
|
||||||
return _mul(p, s);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test "edwards25519 packing/unpacking" {
|
test "edwards25519 packing/unpacking" {
|
||||||
const s = [_]u8{170} ++ [_]u8{0} ** 31;
|
const s = [_]u8{170} ++ [_]u8{0} ** 31;
|
||||||
var b = Edwards25519.basePoint();
|
var b = Edwards25519.basePoint;
|
||||||
const pk = try b.mul(s);
|
const pk = try b.mul(s);
|
||||||
var buf: [128]u8 = undefined;
|
var buf: [128]u8 = undefined;
|
||||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{pk.toBytes()}), "074BC7E0FCBD587FDBC0969444245FADC562809C8F6E97E949AF62484B5B81A6");
|
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{pk.toBytes()}), "074BC7E0FCBD587FDBC0969444245FADC562809C8F6E97E949AF62484B5B81A6");
|
||||||
|
|||||||
@ -43,10 +43,8 @@ pub const Ristretto255 = struct {
|
|||||||
return p.p.rejectIdentity();
|
return p.p.rejectIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the base point (Ristretto is a curve in desguise).
|
/// The base point (Ristretto is a curve in desguise).
|
||||||
pub inline fn basePoint() Ristretto255 {
|
pub const basePoint = Ristretto255{ .p = Curve.basePoint };
|
||||||
return .{ .p = Curve.basePoint() };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decode a Ristretto255 representative.
|
/// Decode a Ristretto255 representative.
|
||||||
pub fn fromBytes(s: [32]u8) !Ristretto255 {
|
pub fn fromBytes(s: [32]u8) !Ristretto255 {
|
||||||
@ -130,7 +128,7 @@ pub const Ristretto255 = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
test "ristretto255" {
|
test "ristretto255" {
|
||||||
const p = Ristretto255.basePoint();
|
const p = Ristretto255.basePoint;
|
||||||
var buf: [256]u8 = undefined;
|
var buf: [256]u8 = undefined;
|
||||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76");
|
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76");
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ pub const X25519 = struct {
|
|||||||
std.debug.assert(public_key.len >= minimum_key_length);
|
std.debug.assert(public_key.len >= minimum_key_length);
|
||||||
var s: [32]u8 = undefined;
|
var s: [32]u8 = undefined;
|
||||||
mem.copy(u8, &s, private_key[0..32]);
|
mem.copy(u8, &s, private_key[0..32]);
|
||||||
if (Curve.basePoint().clampedMul(s)) |q| {
|
if (Curve.basePoint.clampedMul(s)) |q| {
|
||||||
mem.copy(u8, public_key, q.toBytes()[0..]);
|
mem.copy(u8, public_key, q.toBytes()[0..]);
|
||||||
return true;
|
return true;
|
||||||
} else |_| {
|
} else |_| {
|
||||||
@ -52,7 +52,7 @@ test "x25519 public key calculation from secret key" {
|
|||||||
try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||||
try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
|
try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
|
||||||
std.testing.expect(X25519.createPublicKey(pk_calculated[0..], &sk));
|
std.testing.expect(X25519.createPublicKey(pk_calculated[0..], &sk));
|
||||||
std.testing.expect(std.mem.eql(u8, &pk_calculated, &pk_expected));
|
std.testing.expectEqual(pk_calculated, pk_expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "x25519 rfc7748 vector1" {
|
test "x25519 rfc7748 vector1" {
|
||||||
@ -64,7 +64,7 @@ test "x25519 rfc7748 vector1" {
|
|||||||
var output: [32]u8 = undefined;
|
var output: [32]u8 = undefined;
|
||||||
|
|
||||||
std.testing.expect(X25519.create(output[0..], secret_key[0..], public_key[0..]));
|
std.testing.expect(X25519.create(output[0..], secret_key[0..], public_key[0..]));
|
||||||
std.testing.expect(std.mem.eql(u8, &output, expected_output[0..]));
|
std.testing.expectEqual(output, expected_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "x25519 rfc7748 vector2" {
|
test "x25519 rfc7748 vector2" {
|
||||||
@ -76,7 +76,7 @@ test "x25519 rfc7748 vector2" {
|
|||||||
var output: [32]u8 = undefined;
|
var output: [32]u8 = undefined;
|
||||||
|
|
||||||
std.testing.expect(X25519.create(output[0..], secret_key[0..], public_key[0..]));
|
std.testing.expect(X25519.create(output[0..], secret_key[0..], public_key[0..]));
|
||||||
std.testing.expect(std.mem.eql(u8, &output, expected_output[0..]));
|
std.testing.expectEqual(output, expected_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "x25519 rfc7748 one iteration" {
|
test "x25519 rfc7748 one iteration" {
|
||||||
@ -91,11 +91,11 @@ test "x25519 rfc7748 one iteration" {
|
|||||||
var output: [32]u8 = undefined;
|
var output: [32]u8 = undefined;
|
||||||
std.testing.expect(X25519.create(output[0..], &k, &u));
|
std.testing.expect(X25519.create(output[0..], &k, &u));
|
||||||
|
|
||||||
std.mem.copy(u8, u[0..], k[0..]);
|
mem.copy(u8, u[0..], k[0..]);
|
||||||
std.mem.copy(u8, k[0..], output[0..]);
|
mem.copy(u8, k[0..], output[0..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std.testing.expect(std.mem.eql(u8, k[0..], expected_output[0..]));
|
std.testing.expectEqual(k, expected_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "x25519 rfc7748 1,000 iterations" {
|
test "x25519 rfc7748 1,000 iterations" {
|
||||||
@ -115,11 +115,11 @@ test "x25519 rfc7748 1,000 iterations" {
|
|||||||
var output: [32]u8 = undefined;
|
var output: [32]u8 = undefined;
|
||||||
std.testing.expect(X25519.create(output[0..], &k, &u));
|
std.testing.expect(X25519.create(output[0..], &k, &u));
|
||||||
|
|
||||||
std.mem.copy(u8, u[0..], k[0..]);
|
mem.copy(u8, u[0..], k[0..]);
|
||||||
std.mem.copy(u8, k[0..], output[0..]);
|
mem.copy(u8, k[0..], output[0..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std.testing.expect(std.mem.eql(u8, k[0..], expected_output));
|
std.testing.expectEqual(k, expected_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "x25519 rfc7748 1,000,000 iterations" {
|
test "x25519 rfc7748 1,000,000 iterations" {
|
||||||
@ -138,9 +138,9 @@ test "x25519 rfc7748 1,000,000 iterations" {
|
|||||||
var output: [32]u8 = undefined;
|
var output: [32]u8 = undefined;
|
||||||
std.testing.expect(X25519.create(output[0..], &k, &u));
|
std.testing.expect(X25519.create(output[0..], &k, &u));
|
||||||
|
|
||||||
std.mem.copy(u8, u[0..], k[0..]);
|
mem.copy(u8, u[0..], k[0..]);
|
||||||
std.mem.copy(u8, k[0..], output[0..]);
|
mem.copy(u8, k[0..], output[0..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std.testing.expect(std.mem.eql(u8, k[0..], expected_output));
|
std.testing.expectEqual(k[0..], expected_output);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user