diff options
| author | jsing <> | 2022-11-09 17:39:29 +0000 |
|---|---|---|
| committer | jsing <> | 2022-11-09 17:39:29 +0000 |
| commit | a9fdcf2b38e7f119a0b1e428a0f9cae93f210ed4 (patch) | |
| tree | f0cbe11399d675629473425a560232c59fa77acb /src/lib/libcrypto/curve25519/curve25519.c | |
| parent | 7953c7887126268033a9ff20ea8d4c61f7d5441c (diff) | |
| download | openbsd-a9fdcf2b38e7f119a0b1e428a0f9cae93f210ed4.tar.gz openbsd-a9fdcf2b38e7f119a0b1e428a0f9cae93f210ed4.tar.bz2 openbsd-a9fdcf2b38e7f119a0b1e428a0f9cae93f210ed4.zip | |
Rework ED25519 API.
BoringSSL implemented a compound private key, which includes a copy of the
public key as a performance optimisation for signing. However, this does
not readily match with how EVP works, makes the ED25519 API inconsistent
with the X25519 API, diverges from th RFC and does not align with the
OpenSSL API. Instead, the caller can readily compute the public key and
pass this in to the signing process.
ok tb@
Diffstat (limited to 'src/lib/libcrypto/curve25519/curve25519.c')
| -rw-r--r-- | src/lib/libcrypto/curve25519/curve25519.c | 51 |
1 files changed, 25 insertions, 26 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 | * |
