summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/curve25519/curve25519.c
diff options
context:
space:
mode:
authorjsing <>2022-11-09 17:39:29 +0000
committerjsing <>2022-11-09 17:39:29 +0000
commita9fdcf2b38e7f119a0b1e428a0f9cae93f210ed4 (patch)
treef0cbe11399d675629473425a560232c59fa77acb /src/lib/libcrypto/curve25519/curve25519.c
parent7953c7887126268033a9ff20ea8d4c61f7d5441c (diff)
downloadopenbsd-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.c51
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
4618void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) { 4618void 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
4632void 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
4624int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, 4639int 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
4658int ED25519_verify(const uint8_t *message, size_t message_len, 4674int 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
4695void 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 *