diff options
| author | George Hazan <george.hazan@gmail.com> | 2024-06-21 14:29:17 +0300 |
|---|---|---|
| committer | George Hazan <george.hazan@gmail.com> | 2024-06-21 14:29:17 +0300 |
| commit | 46ea86584a9787c8b9dc3983cf23d9b5b93b5841 (patch) | |
| tree | fbaf3793ae2170f7982f08a62c028a23cd9afedd /libs/libsodium/src/crypto_vrf | |
| parent | 82e75be329dd0f30c0281ef9c3c08488b89d109f (diff) | |
fixes #4477 (libsodium: update to 1.0.20)
Diffstat (limited to 'libs/libsodium/src/crypto_vrf')
| -rw-r--r-- | libs/libsodium/src/crypto_vrf/crypto_vrf.c | 72 | ||||
| -rw-r--r-- | libs/libsodium/src/crypto_vrf/rfc9381/keypair.c | 40 | ||||
| -rw-r--r-- | libs/libsodium/src/crypto_vrf/rfc9381/prove.c | 69 | ||||
| -rw-r--r-- | libs/libsodium/src/crypto_vrf/rfc9381/verify.c | 116 | ||||
| -rw-r--r-- | libs/libsodium/src/crypto_vrf/rfc9381/vrf.c | 31 | ||||
| -rw-r--r-- | libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h | 10 |
6 files changed, 338 insertions, 0 deletions
diff --git a/libs/libsodium/src/crypto_vrf/crypto_vrf.c b/libs/libsodium/src/crypto_vrf/crypto_vrf.c new file mode 100644 index 0000000000..52f024dd64 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/crypto_vrf.c @@ -0,0 +1,72 @@ + +#include "crypto_vrf.h" + +size_t +crypto_vrf_publickeybytes(void) +{ + return crypto_vrf_PUBLICKEYBYTES; +} + +size_t +crypto_vrf_secretkeybytes(void) +{ + return crypto_vrf_SECRETKEYBYTES; +} + +size_t +crypto_vrf_seedbytes(void) +{ + return crypto_vrf_SEEDBYTES; +} + +size_t +crypto_vrf_proofbytes(void) +{ + return crypto_vrf_PROOFBYTES; +} + +size_t +crypto_vrf_outputbytes(void) +{ + return crypto_vrf_OUTPUTBYTES; +} + +const char * +crypto_vrf_primitive(void) +{ + return crypto_vrf_PRIMITIVE; +} + +int +crypto_vrf_keypair(unsigned char *pk, unsigned char *sk) +{ + return crypto_vrf_rfc9381_keypair(pk, sk); +} + +int +crypto_vrf_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + return crypto_vrf_rfc9381_seed_keypair(pk, sk, seed); +} + +int +crypto_vrf_prove(unsigned char *proof, const unsigned char *m, const unsigned long long mlen, + const unsigned char *skpk) +{ + return crypto_vrf_rfc9381_prove(proof, m, mlen, skpk); +} + +int +crypto_vrf_verify(unsigned char *output, const unsigned char *pk, + const unsigned char *proof, const unsigned char *m, + const unsigned long long mlen) +{ + return crypto_vrf_rfc9381_verify(output, pk, proof, m, mlen); +} + +int +crypto_vrf_proof_to_hash(unsigned char *hash, const unsigned char *proof) +{ + return crypto_vrf_rfc9381_proof_to_hash(hash, proof); +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/keypair.c b/libs/libsodium/src/crypto_vrf/rfc9381/keypair.c new file mode 100644 index 0000000000..ecefa5e054 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/keypair.c @@ -0,0 +1,40 @@ +#include <string.h> + +#include "crypto_hash_sha512.h" +#include "crypto_vrf_rfc9381.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_vrf_rfc9381_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + ge25519_p3 A; + + crypto_hash_sha512(sk, seed, 32); + sk[0] &= 248; + sk[31] &= 127; + sk[31] |= 64; + + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(pk, &A); + + memmove(sk, seed, 32); + memmove(sk + 32, pk, 32); + + return 0; +} + +int +crypto_vrf_rfc9381_keypair(unsigned char *pk, unsigned char *sk) +{ + unsigned char seed[32]; + int ret; + + randombytes_buf(seed, sizeof seed); + ret = crypto_vrf_rfc9381_seed_keypair(pk, sk, seed); + sodium_memzero(seed, sizeof seed); + + return ret; +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/prove.c b/libs/libsodium/src/crypto_vrf/rfc9381/prove.c new file mode 100644 index 0000000000..1dffed2774 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/prove.c @@ -0,0 +1,69 @@ +#include <string.h> +#include <stdlib.h> + +#include "crypto_hash_sha512.h" +#include "crypto_vrf_rfc9381.h" +#include "private/ed25519_ref10.h" +#include "utils.h" +#include "vrf_rfc9381.h" + + +int +crypto_vrf_rfc9381_prove(unsigned char *proof, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + + crypto_hash_sha512_state hs; + unsigned char az[64]; + unsigned char H_string[32]; + unsigned char kB_string[32], kH_string[32]; + unsigned char string_to_hash[32 + mlen]; + unsigned char challenge[64], nonce[64]; + ge25519_p3 H, Gamma, kB, kH; + + crypto_hash_sha512(az, sk, 32); + az[0] &= 248; + az[31] &= 127; + az[31] |= 64; + + memmove(string_to_hash, sk + 32, 32); + memmove(string_to_hash + 32, m, mlen); + ge25519_from_string(H_string, "ECVRF_edwards25519_XMD:SHA-512_ELL2_NU_\4", string_to_hash, 32 + mlen, 2); /* elligator2 */ + + ge25519_frombytes(&H, H_string); + ge25519_scalarmult(&Gamma, az, &H); + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, az + 32, 32); + crypto_hash_sha512_update(&hs, H_string, 32); + crypto_hash_sha512_final(&hs, nonce); + + sc25519_reduce(nonce); + ge25519_scalarmult_base(&kB, nonce); + ge25519_scalarmult(&kH, nonce, &H); + + ge25519_p3_tobytes(proof, &Gamma); + ge25519_p3_tobytes(kB_string, &kB); + ge25519_p3_tobytes(kH_string, &kH); + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, &SUITE, 1); + crypto_hash_sha512_update(&hs, &TWO, 1); + crypto_hash_sha512_update(&hs, sk + 32, 32); + crypto_hash_sha512_update(&hs, H_string, 32); + crypto_hash_sha512_update(&hs, proof, 32); + crypto_hash_sha512_update(&hs, kB_string, 32); + crypto_hash_sha512_update(&hs, kH_string, 32); + crypto_hash_sha512_update(&hs, &ZERO, 1); + crypto_hash_sha512_final(&hs, challenge); + + memmove(proof + 32, challenge, 16); + memset(challenge + 16, 0, 48); /* we zero out the last 48 bytes of the challenge */ + sc25519_muladd(proof + 48, challenge, az, nonce); + + sodium_memzero(az, sizeof az); + sodium_memzero(nonce, sizeof nonce); + + return 0; +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/verify.c b/libs/libsodium/src/crypto_vrf/rfc9381/verify.c new file mode 100644 index 0000000000..40bcbb503b --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/verify.c @@ -0,0 +1,116 @@ +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#include "crypto_hash_sha512.h" +#include "crypto_vrf_rfc9381.h" +#include "private/ed25519_ref10.h" +#include "vrf_rfc9381.h" +#include "crypto_verify_16.h" + +int +crypto_vrf_rfc9381_proof_to_hash(unsigned char *beta, + const unsigned char *pi) +{ + ge25519_p3 Gamma; + unsigned char gamma_string[32]; + + if (ge25519_is_canonical(pi) == 0 || + ge25519_frombytes(&Gamma, pi) != 0) { + return -1; + } + + if (pi[48 + 31] & 240 && + sc25519_is_canonical(pi + 48) == 0) { + return -1; + } + + ge25519_clear_cofactor(&Gamma); + ge25519_p3_tobytes(gamma_string, &Gamma); + + /* beta_string = Hash(suite_string || three_string || point_to_string(cofactor * Gamma) || zero_string ) */ + crypto_hash_sha512_state hs; + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, &SUITE, 1); + crypto_hash_sha512_update(&hs, &THREE, 1); + crypto_hash_sha512_update(&hs, gamma_string, 32); + crypto_hash_sha512_update(&hs, &ZERO, 1); + crypto_hash_sha512_final(&hs, beta); + + return 0; +} + +static int +vrf_verify(const unsigned char *pi, + const unsigned char *alpha, unsigned long long alphalen, + const ge25519_p3 *Y_point) +{ + unsigned char H_string[32], U_string[32], V_string[32], Y_string[32]; + unsigned char cn[32], c[32], s[32]; + unsigned char string_to_hash[32 + alphalen], challenge[64]; + + crypto_hash_sha512_state hs; + ge25519_p2 U, V; + ge25519_p3 H, Gamma; + ge25519_p1p1 tmp_p1p1_point; + ge25519_cached tmp_cached_point; + + ge25519_p3_tobytes(Y_string, Y_point); + + if (ge25519_is_canonical(pi) == 0 || + ge25519_frombytes(&Gamma, pi) != 0) { + return -1; + } + + memmove(c, pi + 32, 16); /* c = pi[32:48] */ + memmove(s, pi + 48, 32); /* s = pi[48:80] */ + + if (s[31] & 240 && + sc25519_is_canonical(s) == 0) { + return -1; + } + + memset(c + 16, 0, 16); + + memmove(string_to_hash, Y_string, 32); + memmove(string_to_hash + 32, alpha, alphalen); + ge25519_from_string(H_string, "ECVRF_edwards25519_XMD:SHA-512_ELL2_NU_\4", string_to_hash, 32 + alphalen, 2); /* elligator2 */ + + ge25519_frombytes(&H, H_string); + sc25519_negate(cn, c); /* negate scalar c */ + + ge25519_double_scalarmult_vartime(&U, cn, Y_point, s, NULL); + + ge25519_double_scalarmult_vartime(&V, cn, &Gamma, s, &H); + + ge25519_tobytes(U_string, &U); + ge25519_tobytes(V_string, &V); + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, &SUITE, 1); + crypto_hash_sha512_update(&hs, &TWO, 1); + crypto_hash_sha512_update(&hs, Y_string, 32); + crypto_hash_sha512_update(&hs, H_string, 32); + crypto_hash_sha512_update(&hs, pi, 32); + crypto_hash_sha512_update(&hs, U_string, 32); + crypto_hash_sha512_update(&hs, V_string, 32); + crypto_hash_sha512_update(&hs, &ZERO, 1); + crypto_hash_sha512_final(&hs, challenge); + + return crypto_verify_16(c, challenge); +} + +int +crypto_vrf_rfc9381_verify(unsigned char *output, + const unsigned char *pk, + const unsigned char *proof, + const unsigned char *msg, const unsigned long long msglen) +{ + ge25519_p3 Y; + if (ge25519_frombytes(&Y, pk) == 0 && ge25519_has_small_order(&Y) == 0 && + ge25519_is_canonical(pk) == 1 && (vrf_verify(proof, msg, msglen, &Y) == 0)) { + return crypto_vrf_rfc9381_proof_to_hash(output, proof); + } else { + return -1; + } +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/vrf.c b/libs/libsodium/src/crypto_vrf/rfc9381/vrf.c new file mode 100644 index 0000000000..f6660b9dd6 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/vrf.c @@ -0,0 +1,31 @@ +#include "crypto_vrf_rfc9381.h" + +size_t +crypto_vrf_rfc9381_bytes(void) +{ + return crypto_vrf_rfc9381_BYTES; +} + +size_t +crypto_vrf_rfc9381_outputbytes(void) +{ + return crypto_vrf_rfc9381_OUTPUTBYTES; +} + +size_t +crypto_vrf_rfc9381_seedbytes(void) +{ + return crypto_vrf_rfc9381_SEEDBYTES; +} + +size_t +crypto_vrf_rfc9381_publickeybytes(void) +{ + return crypto_vrf_rfc9381_PUBLICKEYBYTES; +} + +size_t +crypto_vrf_rfc9381_secretkeybytes(void) +{ + return crypto_vrf_rfc9381_SECRETKEYBYTES; +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h b/libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h new file mode 100644 index 0000000000..2d263632e5 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h @@ -0,0 +1,10 @@ +#ifndef vrf_rfc9381_H +#define vrf_rfc9381_H + +static const unsigned char SUITE = 0x04; /* ECVRF-ED25519-SHA512-ELL2 */ + +static const unsigned char ZERO = 0x00; +static const unsigned char TWO = 0x02; +static const unsigned char THREE = 0x03; + +#endif |
