| ... | ... | @@ -1,3 +1,4 @@ |
| 1 | const builtin = @import("builtin"); |
| 1 | 2 | const std = @import("std"); |
| 2 | 3 | const crypto = std.crypto; |
| 3 | 4 | const debug = std.debug; |
| ... | ... | @@ -268,18 +269,17 @@ pub const Ed25519 = struct { |
| 268 | 269 | } |
| 269 | 270 | |
| 270 | 271 | /// Create a KeyPair from a secret key. |
| 271 | | pub fn fromSecretKey(secret_key: SecretKey) IdentityElementError!KeyPair { |
| 272 | | const pk_p = try Curve.fromBytes(secret_key.publicKeyBytes()); |
| 273 | | |
| 272 | pub fn fromSecretKey(secret_key: SecretKey) (NonCanonicalError || EncodingError || IdentityElementError)!KeyPair { |
| 274 | 273 | // It is critical for EdDSA to use the correct public key. |
| 275 | 274 | // In order to enforce this, a SecretKey implicitly includes a copy of the public key. |
| 276 | 275 | // In Debug mode, we can still afford checking that the public key is correct for extra safety. |
| 277 | | if (std.builtin.mode == .Debug) { |
| 278 | | const recomputed_kp = try create(secret_key[0..seed_length].*); |
| 279 | | debug.assert(recomputed_kp.public_key.p.toBytes() == pk_p.toBytes()); |
| 276 | if (builtin.mode == .Debug) { |
| 277 | const pk_p = try Curve.fromBytes(secret_key.publicKeyBytes()); |
| 278 | const recomputed_kp = try create(secret_key.seed()); |
| 279 | debug.assert(mem.eql(u8, &recomputed_kp.public_key.toBytes(), &pk_p.toBytes())); |
| 280 | 280 | } |
| 281 | 281 | return KeyPair{ |
| 282 | | .public_key = PublicKey{ .p = pk_p }, |
| 282 | .public_key = try PublicKey.fromBytes(secret_key.publicKeyBytes()), |
| 283 | 283 | .secret_key = secret_key, |
| 284 | 284 | }; |
| 285 | 285 | } |
| ... | ... | @@ -674,3 +674,10 @@ test "ed25519 signatures with streaming" { |
| 674 | 674 | verifier.update("age"); |
| 675 | 675 | try verifier.verify(); |
| 676 | 676 | } |
| 677 | |
| 678 | test "ed25519 key pair from secret key" { |
| 679 | const kp = try Ed25519.KeyPair.create(null); |
| 680 | const kp2 = try Ed25519.KeyPair.fromSecretKey(kp.secret_key); |
| 681 | try std.testing.expectEqualSlices(u8, &kp.secret_key.toBytes(), &kp2.secret_key.toBytes()); |
| 682 | try std.testing.expectEqualSlices(u8, &kp.public_key.toBytes(), &kp2.public_key.toBytes()); |
| 683 | } |