-/* $OpenBSD: curve25519.c,v 1.10 2022/11/08 17:07:17 jsing Exp $ */
+/* $OpenBSD: curve25519.c,v 1.11 2022/11/09 17:39:29 jsing Exp $ */
/*
* Copyright (c) 2015, Google Inc.
*
s[31] = s11 >> 17;
}
-void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) {
- uint8_t seed[32];
- arc4random_buf(seed, 32);
- ED25519_keypair_from_seed(out_public_key, out_private_key, seed);
+void ED25519_public_from_private(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH],
+ const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) {
+ uint8_t az[SHA512_DIGEST_LENGTH];
+ SHA512(private_key, 32, az);
+
+ az[0] &= 248;
+ az[31] &= 63;
+ az[31] |= 64;
+
+ ge_p3 A;
+ x25519_ge_scalarmult_base(&A, az);
+ ge_p3_tobytes(out_public_key, &A);
+}
+
+void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH],
+ uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]) {
+ arc4random_buf(out_private_key, 32);
+
+ ED25519_public_from_private(out_public_key, out_private_key);
}
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
- const uint8_t private_key[64]) {
+ const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH],
+ const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) {
uint8_t az[SHA512_DIGEST_LENGTH];
SHA512(private_key, 32, az);
SHA512_Init(&hash_ctx);
SHA512_Update(&hash_ctx, out_sig, 32);
- SHA512_Update(&hash_ctx, private_key + 32, 32);
+ SHA512_Update(&hash_ctx, public_key, 32);
SHA512_Update(&hash_ctx, message, message_len);
uint8_t hram[SHA512_DIGEST_LENGTH];
SHA512_Final(hram, &hash_ctx);
}
int ED25519_verify(const uint8_t *message, size_t message_len,
- const uint8_t signature[64], const uint8_t public_key[32]) {
+ const uint8_t signature[ED25519_SIGNATURE_LENGTH],
+ const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]) {
ge_p3 A;
if ((signature[63] & 224) != 0 ||
x25519_ge_frombytes_vartime(&A, public_key) != 0) {
return timingsafe_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
}
-void ED25519_keypair_from_seed(uint8_t out_public_key[32],
- uint8_t out_private_key[64],
- const uint8_t seed[32]) {
- uint8_t az[SHA512_DIGEST_LENGTH];
- SHA512(seed, 32, az);
-
- az[0] &= 248;
- az[31] &= 63;
- az[31] |= 64;
-
- ge_p3 A;
- x25519_ge_scalarmult_base(&A, az);
- ge_p3_tobytes(out_public_key, &A);
-
- memcpy(out_private_key, seed, 32);
- memcpy(out_private_key + 32, out_public_key, 32);
-}
-
/* Replace (f,g) with (g,f) if b == 1;
* replace (f,g) with (f,g) if b == 0.
*
-/* $OpenBSD: curve25519.h,v 1.4 2022/11/06 16:31:19 jsing Exp $ */
+/* $OpenBSD: curve25519.h,v 1.5 2022/11/09 17:39:29 jsing Exp $ */
/*
* Copyright (c) 2015, Google Inc.
*
*
* Ed25519 is a signature scheme using a twisted Edwards curve that is
* birationally equivalent to curve25519.
- *
- * Note that, unlike RFC 8032's formulation, our private key representation
- * includes a public key suffix to make multiple key signing operations with the
- * same key more efficient. The RFC 8032 private key is referred to in this
- * implementation as the "seed" and is the first 32 bytes of our private key.
*/
-#define ED25519_PRIVATE_KEY_LEN 64
-#define ED25519_PUBLIC_KEY_LEN 32
-#define ED25519_SIGNATURE_LEN 64
+#define ED25519_PRIVATE_KEY_LENGTH 32
+#define ED25519_PUBLIC_KEY_LENGTH 32
+#define ED25519_SIGNATURE_LENGTH 64
/*
* ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly
* generated, public/private key pair.
*/
-void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
- uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]);
+void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH],
+ uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]);
/*
* ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from
- * |message| using |private_key|. It returns one on success or zero on
- * allocation failure.
+ * |message| using |public_key| and |private_key|. It returns one on success
+ * or zero on allocation failure.
*/
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
- const uint8_t private_key[ED25519_PRIVATE_KEY_LEN]);
+ const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH],
+ const uint8_t private_key_seed[ED25519_PRIVATE_KEY_LENGTH]);
/*
* ED25519_verify returns one iff |signature| is a valid signature by
* otherwise.
*/
int ED25519_verify(const uint8_t *message, size_t message_len,
- const uint8_t signature[ED25519_SIGNATURE_LEN],
- const uint8_t public_key[ED25519_PUBLIC_KEY_LEN]);
+ const uint8_t signature[ED25519_SIGNATURE_LENGTH],
+ const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]);
#endif
#if defined(__cplusplus)