authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-09-24 20:07:01+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-09-24 20:07:01+02:00
logd037c6c19d2021001ecf20884a4219aec88f151a
treed2a8e3ab089b43da51e45c8d1b6a82a59462d61e
parentc34e2a6b884cb30ac4466efbe961584b62730c8f
parentc157ae2957e317afd2f5d9095e1450abbd5f1ef9

Merge pull request 'crypto.x25519: recoverPublicKey and generateDeterministic cannot fail' (#36158) from jedisct1/zig:x25519smulterr into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36158

2 files changed, 9 insertions(+), 15 deletions(-)

lib/std/crypto/25519/x25519.zig+8-14
......@@ -32,24 +32,18 @@ pub const X25519 = struct {
3232 /// Deterministically derive a key pair from a cryptograpically secure secret seed.
3333 ///
3434 /// Except in tests, applications should generally call `generate()` instead of this function.
35 pub fn generateDeterministic(seed: [seed_length]u8) IdentityElementError!KeyPair {
36 const kp = KeyPair{
37 .public_key = try X25519.recoverPublicKey(seed),
35 pub fn generateDeterministic(seed: [seed_length]u8) KeyPair {
36 return .{
37 .public_key = X25519.recoverPublicKey(seed),
3838 .secret_key = seed,
3939 };
40 return kp;
4140 }
4241
4342 /// Generate a new, random key pair.
4443 pub fn generate(io: std.Io) KeyPair {
4544 var random_seed: [seed_length]u8 = undefined;
46 while (true) {
47 io.random(&random_seed);
48 return generateDeterministic(random_seed) catch {
49 @branchHint(.unlikely);
50 continue;
51 };
52 }
45 io.random(&random_seed);
46 return generateDeterministic(random_seed);
5347 }
5448
5549 /// Create a key pair from an Ed25519 key pair
......@@ -68,8 +62,8 @@ pub const X25519 = struct {
6862 };
6963
7064 /// Compute the public key for a given private key.
71 pub fn recoverPublicKey(secret_key: [secret_length]u8) IdentityElementError![public_length]u8 {
72 const q = try Curve.basePoint.clampedMul(secret_key);
65 pub fn recoverPublicKey(secret_key: [secret_length]u8) [public_length]u8 {
66 const q = Curve.basePoint.clampedMul(secret_key) catch unreachable;
7367 return q.toBytes();
7468 }
7569
......@@ -96,7 +90,7 @@ test "public key calculation from secret key" {
9690 var pk_expected: [32]u8 = undefined;
9791 _ = try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
9892 _ = try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
99 const pk_calculated = try X25519.recoverPublicKey(sk);
93 const pk_calculated = X25519.recoverPublicKey(sk);
10094 try std.testing.expectEqual(pk_calculated, pk_expected);
10195}
10296
lib/std/crypto/tls/Client.zig+1-1
......@@ -1370,7 +1370,7 @@ const KeyShare = struct {
13701370 .ml_kem768_kp = try .generateDeterministic(seed[0..64].*),
13711371 .secp256r1_kp = try .generateDeterministic(seed[64..96].*),
13721372 .secp384r1_kp = try .generateDeterministic(seed[96..144].*),
1373 .x25519_kp = try .generateDeterministic(seed[144..176].*),
1373 .x25519_kp = .generateDeterministic(seed[144..176].*),
13741374 .sk_buf = undefined,
13751375 .sk_len = 0,
13761376 };