summaryrefslogtreecommitdiff
path: root/libs/libsodium/src/crypto_vrf
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2024-06-21 14:29:17 +0300
committerGeorge Hazan <george.hazan@gmail.com>2024-06-21 14:29:17 +0300
commit46ea86584a9787c8b9dc3983cf23d9b5b93b5841 (patch)
treefbaf3793ae2170f7982f08a62c028a23cd9afedd /libs/libsodium/src/crypto_vrf
parent82e75be329dd0f30c0281ef9c3c08488b89d109f (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.c72
-rw-r--r--libs/libsodium/src/crypto_vrf/rfc9381/keypair.c40
-rw-r--r--libs/libsodium/src/crypto_vrf/rfc9381/prove.c69
-rw-r--r--libs/libsodium/src/crypto_vrf/rfc9381/verify.c116
-rw-r--r--libs/libsodium/src/crypto_vrf/rfc9381/vrf.c31
-rw-r--r--libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h10
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