zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit cd8f0aa4ca174ae1d43232d20f27120bcd74e71f (tree)
parent 22380c78b1f9fd714ea6c89d2b902846ccf2e4f9
Author: Frank Denis <github@pureftpd.org>
Date:   Wed,  7 Jan 2026 23:02:46 +0100

Add signerWithBaseNonce

Diffstat:
Mlib/std/crypto/25519/ed25519.zig | 31++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/lib/std/crypto/25519/ed25519.zig b/lib/std/crypto/25519/ed25519.zig @@ -385,24 +385,23 @@ pub const Ed25519 = struct { ); } - /// Create a Signer, that can be used for incremental signing. - /// Note that the signature is not deterministic. - pub fn signer( + /// Create a signer that can be used for incremental signing, using a custom base nonce. + /// `base_nonce` must be unique for each signed message; otherwise, the secret key can + /// be trivially recovered by an attacker. + /// It can be generated using a cryptographically secure random number generator. + pub fn signerWithBaseNonce( key_pair: KeyPair, - /// If set, should be something unique for each message, such as a - /// random nonce, or a counter. + base_nonce: [32]u8, + /// If set, should be something unique for each message, such as a counter. noise: ?[noise_length]u8, - io: std.Io, ) (IdentityElementError || KeyMismatchError || NonCanonicalError || WeakPublicKeyError)!Signer { if (!mem.eql(u8, &key_pair.secret_key.publicKeyBytes(), &key_pair.public_key.toBytes())) { return error.KeyMismatch; } const scalar_and_prefix = key_pair.secret_key.scalarAndPrefix(); - var entropy: [noise_length]u8 = undefined; - io.random(&entropy); var h = Sha512.init(.{}); h.update(&scalar_and_prefix.prefix); - h.update(&entropy); + h.update(&base_nonce); if (noise) |*z| { h.update(z); } @@ -412,6 +411,20 @@ pub const Ed25519 = struct { return Signer.init(scalar_and_prefix.scalar, nonce, key_pair.public_key); } + + /// Create a Signer, that can be used for incremental signing. + /// Note that the signature is not deterministic. + pub fn signer( + key_pair: KeyPair, + /// If set, should be something unique for each message, such as a + /// random nonce, or a counter. + noise: ?[noise_length]u8, + io: std.Io, + ) (IdentityElementError || KeyMismatchError || NonCanonicalError || WeakPublicKeyError)!Signer { + var base_nonce: [32]u8 = undefined; + io.random(&base_nonce); + return key_pair.signerWithBaseNonce(base_nonce, noise); + } }; /// A (signature, message, public_key) tuple for batch verification