aboutsummaryrefslogtreecommitdiff
path: root/src/util/test_crypto_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/test_crypto_cs.c')
-rw-r--r--src/util/test_crypto_cs.c609
1 files changed, 0 insertions, 609 deletions
diff --git a/src/util/test_crypto_cs.c b/src/util/test_crypto_cs.c
deleted file mode 100644
index a56ff7421..000000000
--- a/src/util/test_crypto_cs.c
+++ /dev/null
@@ -1,609 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021,2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file util/test_crypto_cs.c
23 * @brief testcase for utility functions for clause blind schnorr signature scheme cryptography
24 * @author Lucien Heuzeveldt <lucienclaude.heuzeveldt@students.bfh.ch>
25 * @author Gian Demarmels <gian@demarmels.org>
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include <sodium.h>
30
31#define ITER 25
32
33static void
34test_create_priv (struct GNUNET_CRYPTO_CsPrivateKey *priv)
35{
36 /* TEST 1
37 * Check that privkey is set
38 */
39 struct GNUNET_CRYPTO_CsPrivateKey other_priv;
40
41 other_priv = *priv;
42 GNUNET_CRYPTO_cs_private_key_generate (priv);
43 GNUNET_assert (0 !=
44 GNUNET_memcmp (&other_priv.scalar,
45 &priv->scalar));
46}
47
48
49static void
50test_generate_pub (const struct GNUNET_CRYPTO_CsPrivateKey *priv,
51 struct GNUNET_CRYPTO_CsPublicKey *pub)
52{
53 /* TEST 1
54 * Check that pubkey is set
55 */
56 struct GNUNET_CRYPTO_CsPublicKey other_pub;
57
58 other_pub = *pub;
59 GNUNET_CRYPTO_cs_private_key_get_public (priv,
60 pub);
61 GNUNET_assert (0 !=
62 GNUNET_memcmp (&other_pub.point,
63 &pub->point));
64
65 /* TEST 2
66 * Check that pubkey is a valid point
67 */
68 GNUNET_assert (1 ==
69 crypto_core_ed25519_is_valid_point (pub->point.y));
70
71 /* TEST 3
72 * Check if function gives the same result for the same output
73 */
74 other_pub = *pub;
75 for (unsigned int i = 0; i<ITER; i++)
76 {
77 GNUNET_CRYPTO_cs_private_key_get_public (priv,
78 pub);
79 GNUNET_assert (0 ==
80 GNUNET_memcmp (&other_pub.point,
81 &pub->point));
82 }
83}
84
85
86static void
87test_derive_rsecret (const struct GNUNET_CRYPTO_CsNonce *nonce,
88 const struct GNUNET_CRYPTO_CsPrivateKey *priv,
89 struct GNUNET_CRYPTO_CsRSecret r[2])
90{
91 /* TEST 1
92 * Check that r are set
93 */
94 struct GNUNET_CRYPTO_CsPrivateKey other_r[2];
95
96 memcpy (other_r,
97 r,
98 sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2);
99 GNUNET_CRYPTO_cs_r_derive (nonce,
100 "nw",
101 priv,
102 r);
103 GNUNET_assert (0 !=
104 memcmp (&other_r[0],
105 &r[0],
106 sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2));
107
108 /* TEST 2
109 * Check if function gives the same result for the same input.
110 * This test ensures that the derivation is deterministic.
111 */
112 memcpy (other_r,
113 r,
114 sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2);
115 for (unsigned int i = 0; i<ITER; i++)
116 {
117 GNUNET_CRYPTO_cs_r_derive (nonce,
118 "nw",
119 priv,
120 r);
121 GNUNET_assert (0 ==
122 memcmp (other_r,
123 r,
124 sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2));
125 }
126}
127
128
129static void
130test_generate_rpublic (const struct GNUNET_CRYPTO_CsRSecret *r_priv,
131 struct GNUNET_CRYPTO_CsRPublic *r_pub)
132{
133 /* TEST 1
134 * Check that r_pub is set
135 */
136 struct GNUNET_CRYPTO_CsRPublic other_r_pub;
137
138 other_r_pub = *r_pub;
139 GNUNET_CRYPTO_cs_r_get_public (r_priv,
140 r_pub);
141 GNUNET_assert (0 !=
142 GNUNET_memcmp (&other_r_pub.point,
143 &r_pub->point));
144 /* TEST 2
145 * Check that r_pub is a valid point
146 */
147 GNUNET_assert (1 ==
148 crypto_core_ed25519_is_valid_point (r_pub->point.y));
149
150 /* TEST 3
151 * Check if function gives the same result for the same output
152 */
153 other_r_pub.point = r_pub->point;
154 for (int i = 0; i<ITER; i++)
155 {
156 GNUNET_CRYPTO_cs_r_get_public (r_priv,
157 r_pub);
158 GNUNET_assert (0 ==
159 GNUNET_memcmp (&other_r_pub.point,
160 &r_pub->point));
161 }
162}
163
164
165static void
166test_derive_blindingsecrets (const struct GNUNET_CRYPTO_CsNonce *blind_seed,
167 struct GNUNET_CRYPTO_CsBlindingSecret bs[2])
168{
169 /* TEST 1
170 * Check that blinding secrets are set
171 */
172 struct GNUNET_CRYPTO_CsBlindingSecret other_bs[2];
173
174 memcpy (other_bs,
175 bs,
176 sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) * 2);
177
178 GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs);
179
180 GNUNET_assert (0 !=
181 memcmp (other_bs,
182 bs,
183 sizeof(struct GNUNET_CRYPTO_CsBlindingSecret)
184 * 2));
185
186 /* TEST 2
187 * Check if function gives the same result for the same input.
188 * This test ensures that the derivation is deterministic.
189 */
190 memcpy (other_bs,
191 bs,
192 sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) * 2);
193 for (unsigned int i = 0; i<ITER; i++)
194 {
195 GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs);
196 GNUNET_assert (0 == memcmp (&other_bs[0],
197 &bs[0],
198 sizeof(struct GNUNET_CRYPTO_CsBlindingSecret)
199 * 2));
200 }
201}
202
203
204static void
205test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2],
206 const struct GNUNET_CRYPTO_CsRPublic r_pub[2],
207 const struct GNUNET_CRYPTO_CsPublicKey *pub,
208 const void *msg,
209 size_t msg_len,
210 struct GNUNET_CRYPTO_CsC blinded_cs[2],
211 struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2])
212{
213 /* TEST 1
214 * Check that the blinded c's and blinded r's
215 */
216 struct GNUNET_CRYPTO_CsC other_blinded_c[2];
217
218 memcpy (&other_blinded_c[0],
219 &blinded_cs[0],
220 sizeof(struct GNUNET_CRYPTO_CsC) * 2);
221
222 struct GNUNET_CRYPTO_CsRPublic other_blinded_r_pub[2];
223 memcpy (&other_blinded_r_pub[0],
224 &blinded_r_pub[0],
225 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2);
226
227 GNUNET_CRYPTO_cs_calc_blinded_c (bs,
228 r_pub,
229 pub,
230 msg,
231 msg_len,
232 blinded_cs,
233 blinded_r_pub);
234
235 GNUNET_assert (0 != memcmp (&other_blinded_c[0],
236 &blinded_cs[0],
237 sizeof(struct GNUNET_CRYPTO_CsC) * 2));
238 GNUNET_assert (0 != memcmp (&other_blinded_r_pub[0],
239 &blinded_r_pub[0],
240 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2));
241
242 /* TEST 2
243 * Check if R' - aG -bX = R for b = 0
244 * This test does the opposite operations and checks whether the equation is still correct.
245 */
246 for (unsigned int b = 0; b <= 1; b++)
247 {
248 struct GNUNET_CRYPTO_Cs25519Point aG;
249 struct GNUNET_CRYPTO_Cs25519Point bX;
250 struct GNUNET_CRYPTO_Cs25519Point r_min_aG;
251 struct GNUNET_CRYPTO_CsRPublic res;
252
253 GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (
254 aG.y,
255 bs[b].alpha.d));
256
257 GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (
258 bX.y,
259 bs[b].beta.d,
260 pub->point.y));
261
262 GNUNET_assert (0 == crypto_core_ed25519_sub (
263 r_min_aG.y,
264 blinded_r_pub[b].point.y,
265 aG.y));
266
267 GNUNET_assert (0 == crypto_core_ed25519_sub (
268 res.point.y,
269 r_min_aG.y,
270 bX.y));
271
272 GNUNET_assert (0 == memcmp (&res, &r_pub[b], sizeof(struct
273 GNUNET_CRYPTO_CsRPublic)));
274 }
275
276
277 /* TEST 3
278 * Check that the blinded r_pubs' are valid points
279 */
280 GNUNET_assert (1 == crypto_core_ed25519_is_valid_point (
281 blinded_r_pub[0].point.y));
282 GNUNET_assert (1 == crypto_core_ed25519_is_valid_point (
283 blinded_r_pub[1].point.y));
284
285 /* TEST 4
286 * Check if function gives the same result for the same input.
287 */
288 memcpy (&other_blinded_c[0],
289 &blinded_cs[0],
290 sizeof(struct GNUNET_CRYPTO_CsC) * 2);
291 memcpy (&other_blinded_r_pub[0],
292 &blinded_r_pub[0],
293 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2);
294
295 for (unsigned int i = 0; i<ITER; i++)
296 {
297 GNUNET_CRYPTO_cs_calc_blinded_c (bs,
298 r_pub,
299 pub,
300 msg,
301 msg_len,
302 blinded_cs,
303 blinded_r_pub);
304 GNUNET_assert (0 == memcmp (&other_blinded_c[0],
305 &blinded_cs[0],
306 sizeof(struct GNUNET_CRYPTO_CsC) * 2));
307 GNUNET_assert (0 == memcmp (&other_blinded_r_pub[0],
308 &blinded_r_pub[0],
309 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2));
310 }
311}
312
313
314static void
315test_blind_sign (unsigned int *b,
316 const struct GNUNET_CRYPTO_CsPrivateKey *priv,
317 const struct GNUNET_CRYPTO_CsRSecret r[2],
318 const struct GNUNET_CRYPTO_CsC c[2],
319 const struct GNUNET_CRYPTO_CsNonce *nonce,
320 struct GNUNET_CRYPTO_CsBlindS *blinded_s)
321{
322 /* TEST 1
323 * Check that blinded_s is set
324 */
325 struct GNUNET_CRYPTO_CsC other_blinded_s;
326 memcpy (&other_blinded_s, blinded_s, sizeof(struct GNUNET_CRYPTO_CsBlindS));
327
328 *b = GNUNET_CRYPTO_cs_sign_derive (priv,
329 r,
330 c,
331 nonce,
332 blinded_s);
333
334 GNUNET_assert (0 == *b || 1 == *b);
335 GNUNET_assert (0 != memcmp (&other_blinded_s,
336 blinded_s,
337 sizeof(struct GNUNET_CRYPTO_CsBlindS)));
338
339 /* TEST 2
340 * Check if s := rb + cbX
341 * This test does the opposite operations and checks whether the equation is still correct.
342 */
343 struct GNUNET_CRYPTO_Cs25519Scalar cb_mul_x;
344 struct GNUNET_CRYPTO_Cs25519Scalar s_min_rb;
345
346 crypto_core_ed25519_scalar_mul (cb_mul_x.d,
347 c[*b].scalar.d,
348 priv->scalar.d);
349
350 crypto_core_ed25519_scalar_sub (s_min_rb.d,
351 blinded_s->scalar.d,
352 r[*b].scalar.d);
353
354 GNUNET_assert (0 == memcmp (&s_min_rb, &cb_mul_x, sizeof(struct
355 GNUNET_CRYPTO_Cs25519Scalar)));
356
357 /* TEST 3
358 * Check if function gives the same result for the same input.
359 */
360 memcpy (&other_blinded_s, blinded_s, sizeof(struct GNUNET_CRYPTO_CsBlindS));
361 for (unsigned int i = 0; i<ITER; i++)
362 {
363 unsigned int other_b;
364
365 other_b = GNUNET_CRYPTO_cs_sign_derive (priv, r, c, nonce, blinded_s);
366
367 GNUNET_assert (other_b == *b);
368 GNUNET_assert (0 == memcmp (&other_blinded_s,
369 blinded_s,
370 sizeof(struct GNUNET_CRYPTO_CsBlindS)));
371 }
372}
373
374
375static void
376test_unblinds (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar,
377 const struct GNUNET_CRYPTO_CsBlindingSecret *bs,
378 struct GNUNET_CRYPTO_CsS *signature_scalar)
379{
380 /* TEST 1
381 * Check that signature_scalar is set
382 */
383 struct GNUNET_CRYPTO_CsS other_signature_scalar;
384 memcpy (&other_signature_scalar,
385 signature_scalar,
386 sizeof(struct GNUNET_CRYPTO_CsS));
387
388 GNUNET_CRYPTO_cs_unblind (blinded_signature_scalar, bs, signature_scalar);
389
390 GNUNET_assert (0 != memcmp (&other_signature_scalar,
391 signature_scalar,
392 sizeof(struct GNUNET_CRYPTO_CsS)));
393
394 /* TEST 2
395 * Check if s' := s + a mod p
396 * This test does the opposite operations and checks whether the equation is still correct.
397 */
398 struct GNUNET_CRYPTO_Cs25519Scalar s_min_a;
399
400 crypto_core_ed25519_scalar_sub (s_min_a.d,
401 signature_scalar->scalar.d,
402 bs->alpha.d);
403
404 GNUNET_assert (0 == memcmp (&s_min_a, &blinded_signature_scalar->scalar,
405 sizeof(struct
406 GNUNET_CRYPTO_Cs25519Scalar)));
407
408 /* TEST 3
409 * Check if function gives the same result for the same input.
410 */
411 memcpy (&other_signature_scalar, signature_scalar,
412 sizeof(struct GNUNET_CRYPTO_CsS));
413
414 for (unsigned int i = 0; i<ITER; i++)
415 {
416 GNUNET_CRYPTO_cs_unblind (blinded_signature_scalar, bs, signature_scalar);
417 GNUNET_assert (0 == memcmp (&other_signature_scalar,
418 signature_scalar,
419 sizeof(struct GNUNET_CRYPTO_CsS)));
420 }
421}
422
423
424static void
425test_blind_verify (const struct GNUNET_CRYPTO_CsSignature *sig,
426 const struct GNUNET_CRYPTO_CsPublicKey *pub,
427 const struct GNUNET_CRYPTO_CsC *c)
428{
429 /* TEST 1
430 * Test verifies the blinded signature sG == Rb + cbX
431 */
432 struct GNUNET_CRYPTO_Cs25519Point sig_scal_mul_base;
433 GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (
434 sig_scal_mul_base.y,
435 sig->s_scalar.scalar.d));
436
437 struct GNUNET_CRYPTO_Cs25519Point c_mul_pub;
438 GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (c_mul_pub.y,
439 c->scalar.d,
440 pub->point.y));
441
442 struct GNUNET_CRYPTO_Cs25519Point r_add_c_mul_pub;
443 GNUNET_assert (0 == crypto_core_ed25519_add (r_add_c_mul_pub.y,
444 sig->r_point.point.y,
445 c_mul_pub.y));
446
447 GNUNET_assert (0 == memcmp (sig_scal_mul_base.y,
448 r_add_c_mul_pub.y,
449 sizeof(struct GNUNET_CRYPTO_Cs25519Point)));
450}
451
452
453static void
454test_verify (const struct GNUNET_CRYPTO_CsSignature *sig,
455 const struct GNUNET_CRYPTO_CsPublicKey *pub,
456 const void *msg,
457 size_t msg_len)
458{
459 /* TEST 1
460 * Test simple verification
461 */
462 GNUNET_assert (GNUNET_YES ==
463 GNUNET_CRYPTO_cs_verify (sig,
464 pub,
465 msg,
466 msg_len));
467 /* TEST 2
468 * Test verification of "wrong" message
469 */
470 char other_msg[] = "test massege";
471 size_t other_msg_len = strlen ("test massege");
472 GNUNET_assert (GNUNET_SYSERR ==
473 GNUNET_CRYPTO_cs_verify (sig,
474 pub,
475 other_msg,
476 other_msg_len));
477}
478
479
480int
481main (int argc,
482 char *argv[])
483{
484 printf ("Test started\n");
485
486 // ---------- actions performed by signer
487 char message[] = "test message";
488 size_t message_len = strlen ("test message");
489
490 struct GNUNET_CRYPTO_CsPrivateKey priv;
491
492 memset (&priv,
493 42,
494 sizeof (priv));
495 test_create_priv (&priv);
496
497 struct GNUNET_CRYPTO_CsPublicKey pub;
498
499 memset (&pub,
500 42,
501 sizeof (pub));
502 test_generate_pub (&priv,
503 &pub);
504
505 // derive nonce
506 struct GNUNET_CRYPTO_CsNonce nonce;
507 GNUNET_assert (GNUNET_YES ==
508 GNUNET_CRYPTO_kdf (nonce.nonce,
509 sizeof(nonce.nonce),
510 "nonce",
511 strlen ("nonce"),
512 "nonce_secret",
513 strlen ("nonce_secret"),
514 NULL,
515 0));
516
517 // generate r, R
518 struct GNUNET_CRYPTO_CsRSecret r_secrets[2];
519
520 memset (r_secrets,
521 42,
522 sizeof (r_secrets));
523 test_derive_rsecret (&nonce,
524 &priv,
525 r_secrets);
526
527 struct GNUNET_CRYPTO_CsRPublic r_publics[2];
528
529 memset (r_publics,
530 42,
531 sizeof (r_publics));
532 test_generate_rpublic (&r_secrets[0],
533 &r_publics[0]);
534 test_generate_rpublic (&r_secrets[1],
535 &r_publics[1]);
536
537 // ---------- actions performed by user
538
539 // generate blinding secrets
540 struct GNUNET_CRYPTO_CsBlindingSecret blindingsecrets[2];
541
542 memset (blindingsecrets,
543 42,
544 sizeof (blindingsecrets));
545 test_derive_blindingsecrets (&nonce,
546 blindingsecrets);
547
548 // calculate blinded c's
549 struct GNUNET_CRYPTO_CsC blinded_cs[2];
550 struct GNUNET_CRYPTO_CsRPublic blinded_r_pubs[2];
551
552 memset (blinded_cs,
553 42,
554 sizeof (blinded_cs));
555 memset (blinded_r_pubs,
556 42,
557 sizeof (blinded_r_pubs));
558 test_calc_blindedc (blindingsecrets,
559 r_publics,
560 &pub,
561 message,
562 message_len,
563 blinded_cs,
564 blinded_r_pubs);
565
566 // ---------- actions performed by signer
567 // sign blinded c's and get b and s in return
568 unsigned int b;
569 struct GNUNET_CRYPTO_CsBlindS blinded_s;
570
571 memset (&blinded_s,
572 42,
573 sizeof (blinded_s));
574 test_blind_sign (&b,
575 &priv,
576 r_secrets,
577 blinded_cs,
578 &nonce,
579 &blinded_s);
580
581 // verify blinded signature
582 struct GNUNET_CRYPTO_CsSignature blinded_signature;
583
584 blinded_signature.r_point = r_publics[b];
585 blinded_signature.s_scalar.scalar = blinded_s.scalar;
586 test_blind_verify (&blinded_signature,
587 &pub,
588 &blinded_cs[b]);
589
590 // ---------- actions performed by user
591 struct GNUNET_CRYPTO_CsS sig_scalar;
592
593 memset (&sig_scalar,
594 42,
595 sizeof (sig_scalar));
596 test_unblinds (&blinded_s,
597 &blindingsecrets[b],
598 &sig_scalar);
599
600 // verify unblinded signature
601 struct GNUNET_CRYPTO_CsSignature signature;
602 signature.r_point = blinded_r_pubs[b];
603 signature.s_scalar = sig_scalar;
604 test_verify (&signature,
605 &pub,
606 message,
607 message_len);
608 return 0;
609}