GNUnet  0.11.x
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.

Functions

void GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv)
 IMPLEMENTATION NOTICE: More...
 
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 this is necessary because libsodium expects scalar to be in the prime order subgroup More...
 
void GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce, 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...
 

Variables

static const unsigned char L_BIG_ENDIAN [32]
 

Detailed Description

Clause Blind Schnorr signatures using Curve25519.

Author
Lucien Heuzeveldt lucie.nosp@m.ncla.nosp@m.ude.h.nosp@m.euze.nosp@m.veldt.nosp@m.@stu.nosp@m.dents.nosp@m..bfh.nosp@m..ch
Gian Demarmels gian@.nosp@m.dema.nosp@m.rmels.nosp@m..org

Definition in file crypto_cs.c.

Function Documentation

◆ GNUNET_CRYPTO_cs_private_key_generate()

void GNUNET_CRYPTO_cs_private_key_generate ( struct GNUNET_CRYPTO_CsPrivateKey priv)

IMPLEMENTATION NOTICE:

Create a new random private key.

This is an implementation of the Clause Blind Schnorr Signature Scheme using Curve25519. Further details about the Clause Blind Schnorr Signature Scheme can be found here: https://eprint.iacr.org/2019/877.pdf

We use libsodium wherever possible. Create a new random private key.

Parameters
[out]privwhere to write the fresh private key

Definition at line 49 of file crypto_cs.c.

50 {
51  crypto_core_ed25519_scalar_random (priv->scalar.d);
52 }
unsigned char d[crypto_core_ed25519_SCALARBYTES]
32 byte scalar
struct GNUNET_CRYPTO_Cs25519Scalar scalar

References GNUNET_CRYPTO_Cs25519Scalar::d, and GNUNET_CRYPTO_CsPrivateKey::scalar.

◆ GNUNET_CRYPTO_cs_private_key_get_public()

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.

Parameters
privthe private key
[out]pubwhere to write the public key

Definition at line 62 of file crypto_cs.c.

65 {
66  GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (pub->point.y,
67  priv->scalar.d));
68 }
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References GNUNET_CRYPTO_Cs25519Scalar::d, GNUNET_assert, pub, and GNUNET_CRYPTO_CsPrivateKey::scalar.

◆ map_to_scalar_subgroup()

static void map_to_scalar_subgroup ( struct GNUNET_CRYPTO_Cs25519Scalar scalar)
static

maps 32 random bytes to a scalar this is necessary because libsodium expects scalar to be in the prime order subgroup

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

Definition at line 77 of file crypto_cs.c.

78 {
79  // perform clamping as described in RFC7748
80  scalar->d[0] &= 248;
81  scalar->d[31] &= 127;
82  scalar->d[31] |= 64;
83 }

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:

◆ GNUNET_CRYPTO_cs_r_derive()

void GNUNET_CRYPTO_cs_r_derive ( const struct GNUNET_CRYPTO_CsNonce nonce,
const struct GNUNET_CRYPTO_CsPrivateKey lts,
struct GNUNET_CRYPTO_CsRSecret  r[2] 
)

Derive a new secret r pair r0 and r1.

In original papers r is generated randomly To provide abort-idempotency, r needs to be derived but still needs to be UNPREDICTABLE To ensure unpredictability a new nonce should be used when a new r needs to be derived. Uses HKDF internally. Comment: Can be done in one HKDF shot and split output.

Parameters
nonceis a random nonce
ltsis a long-term-secret in form of a private key
[out]rarray containing derived secrets r0 and r1

Definition at line 99 of file crypto_cs.c.

102 {
105  sizeof (struct GNUNET_CRYPTO_CsRSecret)
106  * 2,
107  GCRY_MD_SHA512,
108  GCRY_MD_SHA256,
109  "r",
110  strlen ("r"),
111  lts,
112  sizeof (*lts),
113  nonce,
114  sizeof (*nonce),
115  NULL,
116  0));
117 
118  map_to_scalar_subgroup (&r[0].scalar);
119  map_to_scalar_subgroup (&r[1].scalar);
120 }
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 prim...
Definition: crypto_cs.c:77
@ GNUNET_YES
Definition: gnunet_common.h:97
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf(void *result, size_t out_len, int xtr_algo, int prf_algo, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_hkdf.c:343
the private r used in the signature

References GNUNET_assert, GNUNET_CRYPTO_hkdf(), GNUNET_YES, and map_to_scalar_subgroup().

Here is the call graph for this function:

◆ GNUNET_CRYPTO_cs_r_get_public()

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.

Parameters
r_privthe private key
[out]r_pubwhere to write the public key

Definition at line 130 of file crypto_cs.c.

132 {
133  GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (r_pub->point.y,
134  r_priv->scalar.d));
135 }
unsigned char y[crypto_core_ed25519_BYTES]
This is a point on the Curve25519.
struct GNUNET_CRYPTO_Cs25519Point point
struct GNUNET_CRYPTO_Cs25519Scalar scalar

References GNUNET_CRYPTO_Cs25519Scalar::d, GNUNET_assert, GNUNET_CRYPTO_CsRPublic::point, GNUNET_CRYPTO_CsRSecret::scalar, and GNUNET_CRYPTO_Cs25519Point::y.

◆ GNUNET_CRYPTO_cs_blinding_secrets_derive()

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.

In original papers blinding factors are generated randomly To provide abort-idempotency, blinding factors need to be derived but still need to be UNPREDICTABLE To ensure unpredictability a new nonce has to be used. Uses HKDF internally

Parameters
secretis secret to derive blinding factors
secret_lensecret length
[out]bsarray containing the two derived blinding secrets

Definition at line 150 of file crypto_cs.c.

154 {
156  GNUNET_CRYPTO_hkdf (bs,
157  sizeof (struct
159  * 2,
160  GCRY_MD_SHA512,
161  GCRY_MD_SHA256,
162  "alphabeta",
163  strlen ("alphabeta"),
164  blind_seed,
165  sizeof(*blind_seed),
166  NULL,
167  0));
168  map_to_scalar_subgroup (&bs[0].alpha);
169  map_to_scalar_subgroup (&bs[0].beta);
170  map_to_scalar_subgroup (&bs[1].alpha);
171  map_to_scalar_subgroup (&bs[1].beta);
172 }
static float beta
Percentage of total peer number in the view to send random PULLs to.
static float alpha
Percentage of total peer number in the view to send random PUSHes to.
Secret used for blinding (alpha and beta).

References alpha, beta, GNUNET_assert, GNUNET_CRYPTO_hkdf(), GNUNET_YES, and map_to_scalar_subgroup().

Here is the call 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,
struct GNUNET_CRYPTO_CsC c 
)
static

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

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

Definition at line 196 of file crypto_cs.c.

201 {
202  // SHA-512 hash of R' and message
203  size_t r_m_concat_len = sizeof(struct GNUNET_CRYPTO_CsRPublic) + msg_len;
204  char r_m_concat[r_m_concat_len];
205  memcpy (r_m_concat, r_dash, sizeof(struct GNUNET_CRYPTO_CsRPublic));
206  memcpy (r_m_concat + sizeof(struct GNUNET_CRYPTO_CsRPublic), msg, msg_len);
207  struct GNUNET_HashCode prehash;
208  GNUNET_CRYPTO_hash (r_m_concat, r_m_concat_len, &prehash);
209 
210  // modulus converted to MPI representation
211  gcry_mpi_t l_mpi;
213 
214  // calculate full domain hash
215  gcry_mpi_t c_mpi;
217  l_mpi,
218  pub,
219  sizeof(struct GNUNET_CRYPTO_CsPublicKey),
220  &prehash,
221  sizeof(struct GNUNET_HashCode),
222  "Curve25519FDH");
223  gcry_mpi_release (l_mpi);
224 
225  // convert c from mpi
226  unsigned char c_big_endian[256 / 8];
227  GNUNET_CRYPTO_mpi_print_unsigned (c_big_endian, sizeof(c_big_endian), c_mpi);
228  gcry_mpi_release (c_mpi);
229  for (size_t i = 0; i<32; i++)
230  c->scalar.d[i] = c_big_endian[31 - i];
231 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static const unsigned char L_BIG_ENDIAN[32]
Definition: crypto_cs.c:181
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:127
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
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
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 
)
static

calculate R'

Parameters
bsblinding secret
r_pubR
pubpublic key
[out]blinded_r_pubR'

Definition at line 243 of file crypto_cs.c.

247 {
248  // R'i = Ri + alpha i*G + beta i*pub
249  struct GNUNET_CRYPTO_Cs25519Point alpha_mul_base;
250  GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (
251  alpha_mul_base.y,
252  bs->alpha.d));
253  struct GNUNET_CRYPTO_Cs25519Point beta_mul_pub;
254  GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (beta_mul_pub.y,
255  bs->beta.d,
256  pub->point.y));
257  struct GNUNET_CRYPTO_Cs25519Point alpha_mul_base_plus_beta_mul_pub;
258  GNUNET_assert (0 == crypto_core_ed25519_add (
259  alpha_mul_base_plus_beta_mul_pub.y,
260  alpha_mul_base.y,
261  beta_mul_pub.y));
262  GNUNET_assert (0 == crypto_core_ed25519_add (blinded_r_pub->point.y,
263  r_pub->point.y,
264  alpha_mul_base_plus_beta_mul_pub.
265  y));
266 }
struct GNUNET_CRYPTO_Cs25519Scalar alpha
struct GNUNET_CRYPTO_Cs25519Scalar beta

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:

◆ GNUNET_CRYPTO_cs_calc_blinded_c()

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.

Parameters
bsarray of the two blinding factor structs each containing alpha and beta
r_pubarray of the two signer's nonce R
pubthe public key of the signer
msgthe message to blind in preparation for signing
msg_lenlength of message msg
[out]blinded_carray of the two blinded c's
[out]blinded_r_pubarray of the two blinded R

Definition at line 282 of file crypto_cs.c.

291 {
292  // for i 0/1: R'i = Ri + alpha i*G + beta i*pub
293  calc_r_dash (&bs[0], &r_pub[0], pub, &blinded_r_pub[0]);
294  calc_r_dash (&bs[1], &r_pub[1], pub, &blinded_r_pub[1]);
295 
296  // for i 0/1: c'i = H(R'i, msg)
297  struct GNUNET_CRYPTO_CsC c_dash_0;
298  struct GNUNET_CRYPTO_CsC c_dash_1;
299  cs_full_domain_hash (&blinded_r_pub[0], msg, msg_len, pub, &c_dash_0);
300  cs_full_domain_hash (&blinded_r_pub[1], msg, msg_len, pub, &c_dash_1);
301 
302  // for i 0/1: ci = c'i + beta i mod p
303  crypto_core_ed25519_scalar_add (blinded_c[0].scalar.d,
304  c_dash_0.scalar.d,
305  bs[0].beta.d);
306  crypto_core_ed25519_scalar_add (blinded_c[1].scalar.d,
307  c_dash_1.scalar.d,
308  bs[1].beta.d);
309 }
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'
Definition: crypto_cs.c:243
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.
Definition: crypto_cs.c:196
Schnorr c to be signed.

References GNUNET_CRYPTO_CsBlindingSecret::beta, calc_r_dash(), cs_full_domain_hash(), GNUNET_CRYPTO_Cs25519Scalar::d, msg, pub, and GNUNET_CRYPTO_CsC::scalar.

Here is the call graph for this function:

◆ GNUNET_CRYPTO_cs_sign_derive()

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.

To ensure unpredictability a new nonce has to be used for every signature HKDF is used internally for derivation r0 and r1 can be derived prior by using GNUNET_CRYPTO_cs_r_derive

Parameters
privprivate key to use for the signing and as LTS in HKDF
rarray of the two secret nonce from the signer
carray of the two blinded c to sign c_b
nonceis a random nonce
[out]blinded_signature_scalarwhere to write the signature
Returns
0 or 1 for b (see Clause Blind Signature Scheme)

Definition at line 329 of file crypto_cs.c.

336 {
337  uint32_t hkdf_out;
338 
339  // derive clause session identifier b (random bit)
341  GNUNET_CRYPTO_hkdf (&hkdf_out,
342  sizeof (hkdf_out),
343  GCRY_MD_SHA512,
344  GCRY_MD_SHA256,
345  "b",
346  strlen ("b"),
347  priv,
348  sizeof (*priv),
349  nonce,
350  sizeof (*nonce),
351  NULL,
352  0));
353  unsigned int b = hkdf_out % 2;
354 
355  // s = r_b + c_b priv
356  struct GNUNET_CRYPTO_Cs25519Scalar c_b_mul_priv;
357  crypto_core_ed25519_scalar_mul (c_b_mul_priv.d,
358  c[b].scalar.d,
359  priv->scalar.d);
360  crypto_core_ed25519_scalar_add (blinded_signature_scalar->scalar.d,
361  r[b].scalar.d,
362  c_b_mul_priv.d);
363 
364  return b;
365 }
struct GNUNET_CRYPTO_Cs25519Scalar scalar

References GNUNET_CRYPTO_Cs25519Scalar::d, GNUNET_assert, GNUNET_CRYPTO_hkdf(), GNUNET_YES, GNUNET_CRYPTO_CsRSecret::scalar, GNUNET_CRYPTO_CsBlindS::scalar, GNUNET_CRYPTO_CsPrivateKey::scalar, and GNUNET_CRYPTO_CsC::scalar.

Here is the call graph for this function:

◆ GNUNET_CRYPTO_cs_unblind()

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.

Parameters
blinded_signature_scalarthe signature made on the blinded c
bsthe blinding factors used in the blinding
[out]signature_scalarwhere to write the unblinded signature

Definition at line 376 of file crypto_cs.c.

380 {
381  crypto_core_ed25519_scalar_add (signature_scalar->scalar.d,
382  blinded_signature_scalar->scalar.d,
383  bs->alpha.d);
384 }
struct GNUNET_CRYPTO_Cs25519Scalar scalar

References GNUNET_CRYPTO_CsBlindingSecret::alpha, GNUNET_CRYPTO_Cs25519Scalar::d, GNUNET_CRYPTO_CsBlindS::scalar, and GNUNET_CRYPTO_CsS::scalar.

◆ GNUNET_CRYPTO_cs_verify()

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.

Parameters
sigsignature that is being validated
pubpublic key of the signer
msgis the message that should be signed by sig (message is used to calculate c)
msg_lenis the message length
Returns
GNUNET_YES on success, GNUNET_SYSERR if signature invalid

Definition at line 376 of file crypto_cs.c.

402 {
403  // calculate c' = H(R, m)
404  struct GNUNET_CRYPTO_CsC c_dash;
405  cs_full_domain_hash (&sig->r_point, msg, msg_len, pub, &c_dash);
406 
407  // s'G ?= R' + c' pub
408  struct GNUNET_CRYPTO_Cs25519Point sig_scal_mul_base;
409  GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (
410  sig_scal_mul_base.y,
411  sig->s_scalar.scalar.d));
412  struct GNUNET_CRYPTO_Cs25519Point c_dash_mul_pub;
413  GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (c_dash_mul_pub.y,
414  c_dash.scalar.d,
415  pub->point.y));
416  struct GNUNET_CRYPTO_Cs25519Point R_add_c_dash_mul_pub;
417  GNUNET_assert (0 == crypto_core_ed25519_add (R_add_c_dash_mul_pub.y,
418  sig->r_point.point.y,
419  c_dash_mul_pub.y));
420 
421  return 0 == GNUNET_memcmp (&sig_scal_mul_base,
422  &R_add_c_dash_mul_pub)
423  ? GNUNET_OK
424  : GNUNET_SYSERR;
425 }
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
struct GNUNET_CRYPTO_CsS s_scalar
Schnorr signatures are composed of a scalar s and a curve point.
struct GNUNET_CRYPTO_CsRPublic r_point

Variable Documentation

◆ L_BIG_ENDIAN

const unsigned char L_BIG_ENDIAN[32]
static
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 181 of file crypto_cs.c.

Referenced by cs_full_domain_hash().