diff options
-rw-r--r-- | src/lib/libcrypto/curve25519/curve25519.c | 51 | ||||
-rw-r--r-- | src/lib/libcrypto/curve25519/curve25519.h | 28 | ||||
-rw-r--r-- | src/lib/libcrypto/curve25519/curve25519_internal.h | 6 |
3 files changed, 40 insertions, 45 deletions
diff --git a/src/lib/libcrypto/curve25519/curve25519.c b/src/lib/libcrypto/curve25519/curve25519.c index 8d29379eb2..56373db923 100644 --- a/src/lib/libcrypto/curve25519/curve25519.c +++ b/src/lib/libcrypto/curve25519/curve25519.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: curve25519.c,v 1.10 2022/11/08 17:07:17 jsing Exp $ */ | 1 | /* $OpenBSD: curve25519.c,v 1.11 2022/11/09 17:39:29 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2015, Google Inc. | 3 | * Copyright (c) 2015, Google Inc. |
4 | * | 4 | * |
@@ -4615,14 +4615,30 @@ sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, | |||
4615 | s[31] = s11 >> 17; | 4615 | s[31] = s11 >> 17; |
4616 | } | 4616 | } |
4617 | 4617 | ||
4618 | void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) { | 4618 | void ED25519_public_from_private(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH], |
4619 | uint8_t seed[32]; | 4619 | const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) { |
4620 | arc4random_buf(seed, 32); | 4620 | uint8_t az[SHA512_DIGEST_LENGTH]; |
4621 | ED25519_keypair_from_seed(out_public_key, out_private_key, seed); | 4621 | SHA512(private_key, 32, az); |
4622 | |||
4623 | az[0] &= 248; | ||
4624 | az[31] &= 63; | ||
4625 | az[31] |= 64; | ||
4626 | |||
4627 | ge_p3 A; | ||
4628 | x25519_ge_scalarmult_base(&A, az); | ||
4629 | ge_p3_tobytes(out_public_key, &A); | ||
4630 | } | ||
4631 | |||
4632 | void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH], | ||
4633 | uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]) { | ||
4634 | arc4random_buf(out_private_key, 32); | ||
4635 | |||
4636 | ED25519_public_from_private(out_public_key, out_private_key); | ||
4622 | } | 4637 | } |
4623 | 4638 | ||
4624 | int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, | 4639 | int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, |
4625 | const uint8_t private_key[64]) { | 4640 | const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH], |
4641 | const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) { | ||
4626 | uint8_t az[SHA512_DIGEST_LENGTH]; | 4642 | uint8_t az[SHA512_DIGEST_LENGTH]; |
4627 | SHA512(private_key, 32, az); | 4643 | SHA512(private_key, 32, az); |
4628 | 4644 | ||
@@ -4644,7 +4660,7 @@ int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, | |||
4644 | 4660 | ||
4645 | SHA512_Init(&hash_ctx); | 4661 | SHA512_Init(&hash_ctx); |
4646 | SHA512_Update(&hash_ctx, out_sig, 32); | 4662 | SHA512_Update(&hash_ctx, out_sig, 32); |
4647 | SHA512_Update(&hash_ctx, private_key + 32, 32); | 4663 | SHA512_Update(&hash_ctx, public_key, 32); |
4648 | SHA512_Update(&hash_ctx, message, message_len); | 4664 | SHA512_Update(&hash_ctx, message, message_len); |
4649 | uint8_t hram[SHA512_DIGEST_LENGTH]; | 4665 | uint8_t hram[SHA512_DIGEST_LENGTH]; |
4650 | SHA512_Final(hram, &hash_ctx); | 4666 | SHA512_Final(hram, &hash_ctx); |
@@ -4656,7 +4672,8 @@ int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, | |||
4656 | } | 4672 | } |
4657 | 4673 | ||
4658 | int ED25519_verify(const uint8_t *message, size_t message_len, | 4674 | int ED25519_verify(const uint8_t *message, size_t message_len, |
4659 | const uint8_t signature[64], const uint8_t public_key[32]) { | 4675 | const uint8_t signature[ED25519_SIGNATURE_LENGTH], |
4676 | const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]) { | ||
4660 | ge_p3 A; | 4677 | ge_p3 A; |
4661 | if ((signature[63] & 224) != 0 || | 4678 | if ((signature[63] & 224) != 0 || |
4662 | x25519_ge_frombytes_vartime(&A, public_key) != 0) { | 4679 | x25519_ge_frombytes_vartime(&A, public_key) != 0) { |
@@ -4692,24 +4709,6 @@ int ED25519_verify(const uint8_t *message, size_t message_len, | |||
4692 | return timingsafe_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; | 4709 | return timingsafe_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; |
4693 | } | 4710 | } |
4694 | 4711 | ||
4695 | void ED25519_keypair_from_seed(uint8_t out_public_key[32], | ||
4696 | uint8_t out_private_key[64], | ||
4697 | const uint8_t seed[32]) { | ||
4698 | uint8_t az[SHA512_DIGEST_LENGTH]; | ||
4699 | SHA512(seed, 32, az); | ||
4700 | |||
4701 | az[0] &= 248; | ||
4702 | az[31] &= 63; | ||
4703 | az[31] |= 64; | ||
4704 | |||
4705 | ge_p3 A; | ||
4706 | x25519_ge_scalarmult_base(&A, az); | ||
4707 | ge_p3_tobytes(out_public_key, &A); | ||
4708 | |||
4709 | memcpy(out_private_key, seed, 32); | ||
4710 | memcpy(out_private_key + 32, out_public_key, 32); | ||
4711 | } | ||
4712 | |||
4713 | /* Replace (f,g) with (g,f) if b == 1; | 4712 | /* Replace (f,g) with (g,f) if b == 1; |
4714 | * replace (f,g) with (f,g) if b == 0. | 4713 | * replace (f,g) with (f,g) if b == 0. |
4715 | * | 4714 | * |
diff --git a/src/lib/libcrypto/curve25519/curve25519.h b/src/lib/libcrypto/curve25519/curve25519.h index 164f2e9e7f..8b84c889cd 100644 --- a/src/lib/libcrypto/curve25519/curve25519.h +++ b/src/lib/libcrypto/curve25519/curve25519.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: curve25519.h,v 1.4 2022/11/06 16:31:19 jsing Exp $ */ | 1 | /* $OpenBSD: curve25519.h,v 1.5 2022/11/09 17:39:29 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2015, Google Inc. | 3 | * Copyright (c) 2015, Google Inc. |
4 | * | 4 | * |
@@ -67,31 +67,27 @@ int X25519(uint8_t out_shared_key[X25519_KEY_LENGTH], | |||
67 | * | 67 | * |
68 | * Ed25519 is a signature scheme using a twisted Edwards curve that is | 68 | * Ed25519 is a signature scheme using a twisted Edwards curve that is |
69 | * birationally equivalent to curve25519. | 69 | * birationally equivalent to curve25519. |
70 | * | ||
71 | * Note that, unlike RFC 8032's formulation, our private key representation | ||
72 | * includes a public key suffix to make multiple key signing operations with the | ||
73 | * same key more efficient. The RFC 8032 private key is referred to in this | ||
74 | * implementation as the "seed" and is the first 32 bytes of our private key. | ||
75 | */ | 70 | */ |
76 | 71 | ||
77 | #define ED25519_PRIVATE_KEY_LEN 64 | 72 | #define ED25519_PRIVATE_KEY_LENGTH 32 |
78 | #define ED25519_PUBLIC_KEY_LEN 32 | 73 | #define ED25519_PUBLIC_KEY_LENGTH 32 |
79 | #define ED25519_SIGNATURE_LEN 64 | 74 | #define ED25519_SIGNATURE_LENGTH 64 |
80 | 75 | ||
81 | /* | 76 | /* |
82 | * ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly | 77 | * ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly |
83 | * generated, public/private key pair. | 78 | * generated, public/private key pair. |
84 | */ | 79 | */ |
85 | void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], | 80 | void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH], |
86 | uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]); | 81 | uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]); |
87 | 82 | ||
88 | /* | 83 | /* |
89 | * ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from | 84 | * ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from |
90 | * |message| using |private_key|. It returns one on success or zero on | 85 | * |message| using |public_key| and |private_key|. It returns one on success |
91 | * allocation failure. | 86 | * or zero on allocation failure. |
92 | */ | 87 | */ |
93 | int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, | 88 | int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, |
94 | const uint8_t private_key[ED25519_PRIVATE_KEY_LEN]); | 89 | const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH], |
90 | const uint8_t private_key_seed[ED25519_PRIVATE_KEY_LENGTH]); | ||
95 | 91 | ||
96 | /* | 92 | /* |
97 | * ED25519_verify returns one iff |signature| is a valid signature by | 93 | * ED25519_verify returns one iff |signature| is a valid signature by |
@@ -99,8 +95,8 @@ int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, | |||
99 | * otherwise. | 95 | * otherwise. |
100 | */ | 96 | */ |
101 | int ED25519_verify(const uint8_t *message, size_t message_len, | 97 | int ED25519_verify(const uint8_t *message, size_t message_len, |
102 | const uint8_t signature[ED25519_SIGNATURE_LEN], | 98 | const uint8_t signature[ED25519_SIGNATURE_LENGTH], |
103 | const uint8_t public_key[ED25519_PUBLIC_KEY_LEN]); | 99 | const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]); |
104 | #endif | 100 | #endif |
105 | 101 | ||
106 | #if defined(__cplusplus) | 102 | #if defined(__cplusplus) |
diff --git a/src/lib/libcrypto/curve25519/curve25519_internal.h b/src/lib/libcrypto/curve25519/curve25519_internal.h index 9d2ee9b4d7..0a98781651 100644 --- a/src/lib/libcrypto/curve25519/curve25519_internal.h +++ b/src/lib/libcrypto/curve25519/curve25519_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: curve25519_internal.h,v 1.4 2022/11/08 17:07:17 jsing Exp $ */ | 1 | /* $OpenBSD: curve25519_internal.h,v 1.5 2022/11/09 17:39:29 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2015, Google Inc. | 3 | * Copyright (c) 2015, Google Inc. |
4 | * | 4 | * |
@@ -94,8 +94,8 @@ void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], | |||
94 | void x25519_scalar_mult_generic(uint8_t out[32], const uint8_t scalar[32], | 94 | void x25519_scalar_mult_generic(uint8_t out[32], const uint8_t scalar[32], |
95 | const uint8_t point[32]); | 95 | const uint8_t point[32]); |
96 | 96 | ||
97 | void ED25519_keypair_from_seed(uint8_t out_public_key[32], | 97 | void ED25519_public_from_private(uint8_t out_public_key[32], |
98 | uint8_t out_private_key[64], const uint8_t seed[32]); | 98 | const uint8_t private_key[32]); |
99 | 99 | ||
100 | __END_HIDDEN_DECLS | 100 | __END_HIDDEN_DECLS |
101 | 101 | ||