EdDSA#
HACL Packages provides the Ed25519 instantiation of EdDSA, i.e., EdDSA signing and verification on the edwards25519 curve.
Two APIs are exposed: A (simple) “One-Shot” API to sign/verify a single message and a (more efficient) “Precomputed” API to sign multiple messages under the same (precomputed) key.
API Reference#
-
void Hacl_Ed25519_secret_to_public(uint8_t *public_key, uint8_t *private_key)#
Compute the public key from the private key.
- Parameters:
public_key – [out] Points to 32 bytes of valid memory, i.e.,
uint8_t[32]
. Must not overlap the memory location ofprivate_key
.private_key – [in] Points to 32 bytes of valid memory containing the private key, i.e.,
uint8_t[32]
.
One-Shot#
Example
#define HACL_SIGNATURE_ED25519_SECRETKEY_LEN 32
#define HACL_SIGNATURE_ED25519_SECRETKEY_PRECOMP_LEN 96
#define HACL_SIGNATURE_ED25519_PUBLICKEY_LEN 32
#define HACL_SIGNATURE_ED25519_SIGNATURE_LEN 64
// In this example, we create a signature key pair, sign a message, and
// verify the generated signature.
// First, we create a signature key pair.
// Note: HACL does not have a random number generator yet:
//
// https://github.com/hacl-star/hacl-star/issues/26
//
// The `generate_random` function is only used as an
// example, and you must bring your own random.
// 1) Create a secret key.
uint8_t sk[HACL_SIGNATURE_ED25519_SECRETKEY_LEN];
generate_random(sk, HACL_SIGNATURE_ED25519_SECRETKEY_LEN);
// 2) Derive a public key from the secret key.
uint8_t pk[HACL_SIGNATURE_ED25519_PUBLICKEY_LEN];
Hacl_Ed25519_secret_to_public(pk, sk);
// Then, we can sign a message.
// 1) Create a message and allocate memory for the signature.
uint8_t msg[123];
generate_random(msg, 123);
uint8_t signature[HACL_SIGNATURE_ED25519_SIGNATURE_LEN];
// 2) Sign the message with the private key.
Hacl_Ed25519_sign(signature, sk, 123, msg);
// Finally, we can verify the signature we just created by using the public
// key.
bool result = Hacl_Ed25519_verify(pk, 123, msg, signature);
if (result) {
printf("Yay, signature was valid!");
} else {
printf("Naaay, that should not have happened with the code above.");
}
-
void Hacl_Ed25519_sign(uint8_t *signature, uint8_t *private_key, uint32_t msg_len, uint8_t *msg)#
Create an Ed25519 signature.
The function first calls
expand_keys
and then invokessign_expanded
.If one needs to sign several messages under the same private key, it is more efficient to call
expand_keys
only once andsign_expanded
multiple times, for each message.- Parameters:
signature – [out] Points to 64 bytes of valid memory, i.e.,
uint8_t[64]
. Must not overlap the memory locations ofprivate_key
normsg
.private_key – [in] Points to 32 bytes of valid memory containing the private key, i.e.,
uint8_t[32]
.msg_len – [in] Length of
msg
.msg – [in] Points to
msg_len
bytes of valid memory containing the message, i.e.,uint8_t[msg_len]
.
-
bool Hacl_Ed25519_verify(uint8_t *public_key, uint32_t msg_len, uint8_t *msg, uint8_t *signature)#
Verify an Ed25519 signature.
- Parameters:
public_key – Points to 32 bytes of valid memory containing the public key, i.e.,
uint8_t[32]
.msg_len – Length of
msg
.msg – Points to
msg_len
bytes of valid memory containing the message, i.e.,uint8_t[msg_len]
.signature – Points to 64 bytes of valid memory containing the signature, i.e.,
uint8_t[64]
.
- Returns:
Returns
true
if the signature is valid andfalse
otherwise.
Precomputed#
Example
#define HACL_SIGNATURE_ED25519_SECRETKEY_LEN 32
#define HACL_SIGNATURE_ED25519_SECRETKEY_PRECOMP_LEN 96
#define HACL_SIGNATURE_ED25519_PUBLICKEY_LEN 32
#define HACL_SIGNATURE_ED25519_SIGNATURE_LEN 64
// In this example, we use the precomputed API to create multiple signatures
// more efficiently.
// First, we create our signature private key.
// Note: HACL does not have a random number generator yet:
//
// https://github.com/hacl-star/hacl-star/issues/26
//
// The `generate_random` function is only used as an
// example, and you must bring your own random.
uint8_t sk[HACL_SIGNATURE_ED25519_SECRETKEY_LEN];
generate_random(sk, HACL_SIGNATURE_ED25519_SECRETKEY_LEN);
// Then, we precompute an intermediate key that will be used for signing.
uint8_t sk_exp[HACL_SIGNATURE_ED25519_SECRETKEY_PRECOMP_LEN];
Hacl_Ed25519_expand_keys(sk_exp, sk);
// Finally, we use the precomputed key to sign (multiple) messages.
uint8_t msg_1[1337];
generate_random(msg_1, 1337);
uint8_t msg_2[42];
generate_random(msg_2, 42);
uint8_t signature_1[HACL_SIGNATURE_ED25519_SIGNATURE_LEN];
uint8_t signature_2[HACL_SIGNATURE_ED25519_SIGNATURE_LEN];
Hacl_Ed25519_sign_expanded(signature_1, sk_exp, 1337, msg_1);
Hacl_Ed25519_sign_expanded(signature_2, sk_exp, 42, msg_2);
-
void Hacl_Ed25519_expand_keys(uint8_t *expanded_keys, uint8_t *private_key)#
Compute the expanded keys for an Ed25519 signature.
If one needs to sign several messages under the same private key, it is more efficient to call
expand_keys
only once andsign_expanded
multiple times, for each message.- Parameters:
expanded_keys – [out] Points to 96 bytes of valid memory, i.e.,
uint8_t[96]
. Must not overlap the memory location ofprivate_key
.private_key – [in] Points to 32 bytes of valid memory containing the private key, i.e.,
uint8_t[32]
.
-
void Hacl_Ed25519_sign_expanded(uint8_t *signature, uint8_t *expanded_keys, uint32_t msg_len, uint8_t *msg)#
Create an Ed25519 signature with the (precomputed) expanded keys.
If one needs to sign several messages under the same private key, it is more efficient to call
expand_keys
only once andsign_expanded
multiple times, for each message.- Parameters:
signature – [out] Points to 64 bytes of valid memory, i.e.,
uint8_t[64]
. Must not overlap the memory locations ofexpanded_keys
normsg
.expanded_keys – [in] Points to 96 bytes of valid memory, i.e.,
uint8_t[96]
, containing the expanded keys obtained by invokingexpand_keys
.msg_len – [in] Length of
msg
.msg – [in] Points to
msg_len
bytes of valid memory containing the message, i.e.,uint8_t[msg_len]
.