GNUnet  0.17.5
Functions | Variables
crypto_cs.c File Reference

Clause Blind Schnorr signatures using Curve25519. More...

#include "platform.h"
#include "gnunet_crypto_lib.h"
#include <sodium.h>
#include <gcrypt.h>
Include dependency graph for crypto_cs.c:

Go to the source code of this file.


void GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv)
void GNUNET_CRYPTO_cs_private_key_get_public (const struct GNUNET_CRYPTO_CsPrivateKey *priv, struct GNUNET_CRYPTO_CsPublicKey *pub)
 Extract the public key of the given private key. More...
static void map_to_scalar_subgroup (struct GNUNET_CRYPTO_Cs25519Scalar *scalar)
 Maps 32 random bytes to a scalar. More...
void GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce, const char *seed, const struct GNUNET_CRYPTO_CsPrivateKey *lts, struct GNUNET_CRYPTO_CsRSecret r[2])
 Derive a new secret r pair r0 and r1. More...
void GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, struct GNUNET_CRYPTO_CsRPublic *r_pub)
 Extract the public R of the given secret r. More...
void GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct GNUNET_CRYPTO_CsNonce *blind_seed, struct GNUNET_CRYPTO_CsBlindingSecret bs[2])
 Derives new random blinding factors. More...
static void cs_full_domain_hash (const struct GNUNET_CRYPTO_CsRPublic *r_dash, const void *msg, size_t msg_len, const struct GNUNET_CRYPTO_CsPublicKey *pub, struct GNUNET_CRYPTO_CsC *c)
 Computes a Hash of (R', m) mapped to a Curve25519 scalar. More...
static void calc_r_dash (const struct GNUNET_CRYPTO_CsBlindingSecret *bs, const struct GNUNET_CRYPTO_CsRPublic *r_pub, const struct GNUNET_CRYPTO_CsPublicKey *pub, struct GNUNET_CRYPTO_CsRPublic *blinded_r_pub)
 calculate R' More...
void GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], const struct GNUNET_CRYPTO_CsRPublic r_pub[2], const struct GNUNET_CRYPTO_CsPublicKey *pub, const void *msg, size_t msg_len, struct GNUNET_CRYPTO_CsC blinded_c[2], struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2])
 Calculate two blinded c's Comment: One would be insecure due to Wagner's algorithm solving ROS. More...
unsigned int GNUNET_CRYPTO_cs_sign_derive (const struct GNUNET_CRYPTO_CsPrivateKey *priv, const struct GNUNET_CRYPTO_CsRSecret r[2], const struct GNUNET_CRYPTO_CsC c[2], const struct GNUNET_CRYPTO_CsNonce *nonce, struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar)
 Sign a blinded c This function derives b from a nonce and a longterm secret In original papers b is generated randomly To provide abort-idempotency, b needs to be derived but still need to be UNPREDICTABLE. More...
void GNUNET_CRYPTO_cs_unblind (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, const struct GNUNET_CRYPTO_CsBlindingSecret *bs, struct GNUNET_CRYPTO_CsS *signature_scalar)
 Unblind a blind-signed signature using a c that was blinded. More...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig, const struct GNUNET_CRYPTO_CsPublicKey *pub, const void *msg, size_t msg_len)
 Verify whether the given message corresponds to the given signature and the signature is valid with respect to the given public key. More...


static const unsigned char L_BIG_ENDIAN [32]

Detailed Description

Clause Blind Schnorr signatures using Curve25519.

Lucien Heuzeveldt
Gian Demarmels

Definition in file crypto_cs.c.

Function Documentation

◆ map_to_scalar_subgroup()

static void map_to_scalar_subgroup ( struct GNUNET_CRYPTO_Cs25519Scalar scalar)

Maps 32 random bytes to a scalar.

This is necessary because libsodium expects scalar to be in the prime order subgroup.

[in,out]scalarcontaining 32 byte char array, is modified to be in prime order subgroup

Definition at line 67 of file crypto_cs.c.

68 {
69  /* perform clamping as described in RFC7748 */
70  scalar->d[0] &= 248;
71  scalar->d[31] &= 127;
72  scalar->d[31] |= 64;
73 }
unsigned char d[crypto_core_ed25519_SCALARBYTES]
32 byte scalar

References GNUNET_CRYPTO_Cs25519Scalar::d.

Referenced by GNUNET_CRYPTO_cs_blinding_secrets_derive(), and GNUNET_CRYPTO_cs_r_derive().

Here is the caller graph for this function:

◆ cs_full_domain_hash()

static void cs_full_domain_hash ( const struct GNUNET_CRYPTO_CsRPublic r_dash,
const void *  msg,
size_t  msg_len,
const struct GNUNET_CRYPTO_CsPublicKey pub,

Computes a Hash of (R', m) mapped to a Curve25519 scalar.

hashinitial hash of the message to be signed
pubdenomination public key (used as salt)
[out]cC containing scalar

Definition at line 149 of file crypto_cs.c.

154 {
155  // SHA-512 hash of R' and message
156  size_t r_m_concat_len = sizeof(struct GNUNET_CRYPTO_CsRPublic) + msg_len;
157  char r_m_concat[r_m_concat_len];
158  memcpy (r_m_concat, r_dash, sizeof(struct GNUNET_CRYPTO_CsRPublic));
159  memcpy (r_m_concat + sizeof(struct GNUNET_CRYPTO_CsRPublic), msg, msg_len);
160  struct GNUNET_HashCode prehash;
162  GNUNET_CRYPTO_hash (r_m_concat,
163  r_m_concat_len,
164  &prehash);
166  // modulus converted to MPI representation
167  gcry_mpi_t l_mpi;
170  sizeof(L_BIG_ENDIAN));
172  // calculate full domain hash
173  gcry_mpi_t c_mpi;
175  l_mpi,
176  pub,
177  sizeof(struct GNUNET_CRYPTO_CsPublicKey),
178  &prehash,
179  sizeof(struct GNUNET_HashCode),
180  "Curve25519FDH");
181  gcry_mpi_release (l_mpi);
183  // convert c from mpi
184  unsigned char c_big_endian[256 / 8];
185  GNUNET_CRYPTO_mpi_print_unsigned (c_big_endian,
186  sizeof(c_big_endian),
187  c_mpi);
188  gcry_mpi_release (c_mpi);
189  for (size_t i = 0; i<32; i++)
190  c->scalar.d[i] = c_big_endian[31 - i];
191 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static const unsigned char L_BIG_ENDIAN[32]
Definition: crypto_cs.c:134
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void GNUNET_CRYPTO_mpi_scan_unsigned(gcry_mpi_t *result, const void *data, size_t size)
Convert data buffer into MPI value.
Definition: crypto_mpi.c:131
void GNUNET_CRYPTO_kdf_mod_mpi(gcry_mpi_t *r, gcry_mpi_t n, const void *xts, size_t xts_len, const void *skm, size_t skm_len, const char *ctx)
Deterministically generate a pseudo-random number uniformly from the integers modulo a libgcrypt mpi.
Definition: crypto_kdf.c:94
void GNUNET_CRYPTO_mpi_print_unsigned(void *buf, size_t size, gcry_mpi_t val)
Output the given MPI value to the given buffer in network byte order.
Definition: crypto_mpi.c:78
struct GNUNET_CRYPTO_Cs25519Scalar scalar
The public information of an Schnorr key pair.
the public R (derived from r) used in c
A 512-bit hashcode.

References GNUNET_CRYPTO_Cs25519Scalar::d, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_kdf_mod_mpi(), GNUNET_CRYPTO_mpi_print_unsigned(), GNUNET_CRYPTO_mpi_scan_unsigned(), L_BIG_ENDIAN, msg, pub, and GNUNET_CRYPTO_CsC::scalar.

Referenced by GNUNET_CRYPTO_cs_calc_blinded_c().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calc_r_dash()

static void calc_r_dash ( const struct GNUNET_CRYPTO_CsBlindingSecret bs,
const struct GNUNET_CRYPTO_CsRPublic r_pub,
const struct GNUNET_CRYPTO_CsPublicKey pub,
struct GNUNET_CRYPTO_CsRPublic blinded_r_pub 

calculate R'

bsblinding secret
pubpublic key

Definition at line 203 of file crypto_cs.c.

207 {
208  // R'i = Ri + alpha i*G + beta i*pub
209  struct GNUNET_CRYPTO_Cs25519Point alpha_mul_base;
210  GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (
211  alpha_mul_base.y,
212  bs->alpha.d));
213  struct GNUNET_CRYPTO_Cs25519Point beta_mul_pub;
214  GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (beta_mul_pub.y,
215  bs->beta.d,
216  pub->point.y));
217  struct GNUNET_CRYPTO_Cs25519Point alpha_mul_base_plus_beta_mul_pub;
218  GNUNET_assert (0 == crypto_core_ed25519_add (
219  alpha_mul_base_plus_beta_mul_pub.y,
220  alpha_mul_base.y,
221  beta_mul_pub.y));
222  GNUNET_assert (0 == crypto_core_ed25519_add (blinded_r_pub->point.y,
223  r_pub->point.y,
224  alpha_mul_base_plus_beta_mul_pub.
225  y));
226 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned char y[crypto_core_ed25519_BYTES]
This is a point on the Curve25519.
struct GNUNET_CRYPTO_Cs25519Scalar alpha
struct GNUNET_CRYPTO_Cs25519Scalar beta
struct GNUNET_CRYPTO_Cs25519Point point

References GNUNET_CRYPTO_CsBlindingSecret::alpha, GNUNET_CRYPTO_CsBlindingSecret::beta, GNUNET_CRYPTO_Cs25519Scalar::d, GNUNET_assert, GNUNET_CRYPTO_CsRPublic::point, pub, and GNUNET_CRYPTO_Cs25519Point::y.

Referenced by GNUNET_CRYPTO_cs_calc_blinded_c().

Here is the caller graph for this function:

Variable Documentation


const unsigned char L_BIG_ENDIAN[32]
Initial value:
= {
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7,
0x9c, 0xd6, 0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed

Definition at line 134 of file crypto_cs.c.

Referenced by cs_full_domain_hash().