| ... | ... | @@ -385,24 +385,23 @@ pub const Ed25519 = struct { |
| 385 | 385 | ); |
| 386 | 386 | } |
| 387 | 387 | |
| 388 | | /// Create a Signer, that can be used for incremental signing. |
| 389 | | /// Note that the signature is not deterministic. |
| 390 | | pub fn signer( |
| 388 | /// Create a signer that can be used for incremental signing, using a custom base nonce. |
| 389 | /// `base_nonce` must be unique for each signed message; otherwise, the secret key can |
| 390 | /// be trivially recovered by an attacker. |
| 391 | /// It can be generated using a cryptographically secure random number generator. |
| 392 | pub fn signerWithBaseNonce( |
| 391 | 393 | key_pair: KeyPair, |
| 392 | | /// If set, should be something unique for each message, such as a |
| 393 | | /// random nonce, or a counter. |
| 394 | base_nonce: [32]u8, |
| 395 | /// If set, should be something unique for each message, such as a counter. |
| 394 | 396 | noise: ?[noise_length]u8, |
| 395 | | io: std.Io, |
| 396 | 397 | ) (IdentityElementError || KeyMismatchError || NonCanonicalError || WeakPublicKeyError)!Signer { |
| 397 | 398 | if (!mem.eql(u8, &key_pair.secret_key.publicKeyBytes(), &key_pair.public_key.toBytes())) { |
| 398 | 399 | return error.KeyMismatch; |
| 399 | 400 | } |
| 400 | 401 | const scalar_and_prefix = key_pair.secret_key.scalarAndPrefix(); |
| 401 | | var entropy: [noise_length]u8 = undefined; |
| 402 | | io.random(&entropy); |
| 403 | 402 | var h = Sha512.init(.{}); |
| 404 | 403 | h.update(&scalar_and_prefix.prefix); |
| 405 | | h.update(&entropy); |
| 404 | h.update(&base_nonce); |
| 406 | 405 | if (noise) |*z| { |
| 407 | 406 | h.update(z); |
| 408 | 407 | } |
| ... | ... | @@ -412,6 +411,20 @@ pub const Ed25519 = struct { |
| 412 | 411 | |
| 413 | 412 | return Signer.init(scalar_and_prefix.scalar, nonce, key_pair.public_key); |
| 414 | 413 | } |
| 414 | |
| 415 | /// Create a Signer, that can be used for incremental signing. |
| 416 | /// Note that the signature is not deterministic. |
| 417 | pub fn signer( |
| 418 | key_pair: KeyPair, |
| 419 | /// If set, should be something unique for each message, such as a |
| 420 | /// random nonce, or a counter. |
| 421 | noise: ?[noise_length]u8, |
| 422 | io: std.Io, |
| 423 | ) (IdentityElementError || KeyMismatchError || NonCanonicalError || WeakPublicKeyError)!Signer { |
| 424 | var base_nonce: [32]u8 = undefined; |
| 425 | io.random(&base_nonce); |
| 426 | return key_pair.signerWithBaseNonce(base_nonce, noise); |
| 427 | } |
| 415 | 428 | }; |
| 416 | 429 | |
| 417 | 430 | /// A (signature, message, public_key) tuple for batch verification |