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.c533
1 files changed, 533 insertions, 0 deletions
diff --git a/src/util/test_crypto_cs.c b/src/util/test_crypto_cs.c
new file mode 100644
index 000000000..2978fec0a
--- /dev/null
+++ b/src/util/test_crypto_cs.c
@@ -0,0 +1,533 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014,2015 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
33void
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 memcpy (&other_priv.scalar, &priv->scalar, sizeof(other_priv.scalar));
41
42 GNUNET_CRYPTO_cs_private_key_generate (priv);
43
44 GNUNET_assert (0 != memcmp (&other_priv.scalar,
45 &priv->scalar,
46 sizeof(other_priv.scalar)));
47}
48
49
50void
51test_generate_pub (const struct GNUNET_CRYPTO_CsPrivateKey *priv,
52 struct GNUNET_CRYPTO_CsPublicKey *pub)
53{
54 /* TEST 1
55 * Check that pubkey is set
56 */
57 struct GNUNET_CRYPTO_CsPublicKey other_pub;
58 memcpy (&other_pub.point, &pub->point, sizeof(other_pub.point));
59
60 GNUNET_CRYPTO_cs_private_key_get_public (priv, pub);
61
62 GNUNET_assert (0 != memcmp (&other_pub.point,
63 &pub->point,
64 sizeof(other_pub.point)));
65
66 /* TEST 2
67 * Check that pubkey is a valid point
68 */
69 GNUNET_assert (1 == 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 memcpy (&other_pub.point, &pub->point, sizeof(other_pub.point));
75
76 for (int i = 0; i<ITER; i++) {
77 GNUNET_CRYPTO_cs_private_key_get_public (priv, pub);
78 GNUNET_assert (0 == memcmp (&other_pub.point,
79 &pub->point,
80 sizeof(other_pub.point)));
81 }
82}
83
84
85void
86test_derive_rsecret (const struct GNUNET_CRYPTO_CsNonce *nonce,
87 const struct GNUNET_CRYPTO_CsPrivateKey *priv,
88 struct GNUNET_CRYPTO_CsRSecret r[2])
89{
90 /* TEST 1
91 * Check that r are set
92 */
93 struct GNUNET_CRYPTO_CsPrivateKey other_r[2];
94 memcpy (&other_r[0], &r[0], sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2);
95
96 GNUNET_CRYPTO_cs_r_derive (nonce, priv, r);
97
98 GNUNET_assert (0 != memcmp (&other_r[0],
99 &r[0],
100 sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2));
101
102 /* TEST 2
103 * Check if function gives the same result for the same input.
104 * This test ensures that the derivation is deterministic.
105 */
106 memcpy (&other_r[0], &r[0], sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2);
107 for (int i = 0; i<ITER; i++) {
108 GNUNET_CRYPTO_cs_r_derive (nonce, priv, r);
109 GNUNET_assert (0 == memcmp (&other_r[0],
110 &r[0],
111 sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2));
112 }
113}
114
115
116void
117test_generate_rpublic (const struct GNUNET_CRYPTO_CsRSecret *r_priv,
118 struct GNUNET_CRYPTO_CsRPublic *r_pub)
119{
120 /* TEST 1
121 * Check that r_pub is set
122 */
123 struct GNUNET_CRYPTO_CsRPublic other_r_pub;
124 memcpy (&other_r_pub.point, &r_pub->point, sizeof(other_r_pub.point));
125
126 GNUNET_CRYPTO_cs_r_get_public (r_priv, r_pub);
127
128 GNUNET_assert (0 != memcmp (&other_r_pub.point,
129 &r_pub->point,
130 sizeof(other_r_pub.point)));
131
132 /* TEST 2
133 * Check that r_pub is a valid point
134 */
135 GNUNET_assert (1 == crypto_core_ed25519_is_valid_point (r_pub->point.y));
136
137 /* TEST 3
138 * Check if function gives the same result for the same output
139 */
140 memcpy (&other_r_pub.point, &r_pub->point, sizeof(other_r_pub.point));
141 for (int i = 0; i<ITER; i++) {
142 GNUNET_CRYPTO_cs_r_get_public (r_priv, r_pub);
143 GNUNET_assert (0 == memcmp (&other_r_pub.point,
144 &r_pub->point,
145 sizeof(other_r_pub.point)));
146 }
147}
148
149
150void
151test_derive_blindingsecrets (const void *secret,
152 size_t secret_len,
153 struct GNUNET_CRYPTO_CsBlindingSecret bs[2])
154{
155 /* TEST 1
156 * Check that blinding secrets are set
157 */
158 struct GNUNET_CRYPTO_CsBlindingSecret other_bs[2];
159 memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret)
160 * 2);
161
162 GNUNET_CRYPTO_cs_blinding_secrets_derive (secret, secret_len, bs);
163
164 GNUNET_assert (0 != memcmp (&other_bs[0],
165 &bs[0],
166 sizeof(struct GNUNET_CRYPTO_CsBlindingSecret)
167 * 2));
168
169 /* TEST 2
170 * Check if function gives the same result for the same input.
171 * This test ensures that the derivation is deterministic.
172 */
173 memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret)
174 * 2);
175 for (int i = 0; i<ITER; i++) {
176 GNUNET_CRYPTO_cs_blinding_secrets_derive (secret, secret_len, bs);
177 GNUNET_assert (0 == memcmp (&other_bs[0],
178 &bs[0],
179 sizeof(struct GNUNET_CRYPTO_CsBlindingSecret)
180 * 2));
181 }
182}
183
184
185void
186test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2],
187 const struct GNUNET_CRYPTO_CsRPublic r_pub[2],
188 const struct GNUNET_CRYPTO_CsPublicKey *pub,
189 const void *msg,
190 size_t msg_len,
191 struct GNUNET_CRYPTO_CsC blinded_cs[2],
192 struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2])
193{
194 /* TEST 1
195 * Check that the blinded c's and blinded r's
196 */
197 struct GNUNET_CRYPTO_CsC other_blinded_c[2];
198 memcpy (&other_blinded_c[0],
199 &blinded_cs[0],
200 sizeof(struct GNUNET_CRYPTO_CsC) * 2);
201
202 struct GNUNET_CRYPTO_CsRPublic other_blinded_r_pub[2];
203 memcpy (&other_blinded_r_pub[0],
204 &blinded_r_pub[0],
205 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2);
206
207 GNUNET_CRYPTO_cs_calc_blinded_c (bs,
208 r_pub,
209 pub,
210 msg,
211 msg_len,
212 blinded_cs,
213 blinded_r_pub);
214
215 GNUNET_assert (0 != memcmp (&other_blinded_c[0],
216 &blinded_cs[0],
217 sizeof(struct GNUNET_CRYPTO_CsC) * 2));
218 GNUNET_assert (0 != memcmp (&other_blinded_r_pub[0],
219 &blinded_r_pub[0],
220 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2));
221
222 /* TEST 2
223 * Check if R' - aG -bX = R for b = 0
224 * This test does the opposite operations and checks wether the equation is still correct.
225 */
226 for (unsigned int b = 0; b <= 1; b++) {
227 struct GNUNET_CRYPTO_Cs25519Point aG;
228 struct GNUNET_CRYPTO_Cs25519Point bX;
229 struct GNUNET_CRYPTO_Cs25519Point r_min_aG;
230 struct GNUNET_CRYPTO_CsRPublic res;
231
232 GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (
233 aG.y,
234 bs[b].alpha.d));
235
236 GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (
237 bX.y,
238 bs[b].beta.d,
239 pub->point.y));
240
241 GNUNET_assert (0 == crypto_core_ed25519_sub (
242 r_min_aG.y,
243 blinded_r_pub[b].point.y,
244 aG.y));
245
246 GNUNET_assert (0 == crypto_core_ed25519_sub (
247 res.point.y,
248 r_min_aG.y,
249 bX.y));
250
251 GNUNET_assert (0 == memcmp (&res, &r_pub[b], sizeof(struct
252 GNUNET_CRYPTO_CsRPublic)));
253 }
254
255
256
257 /* TEST 3
258 * Check that the blinded r_pubs' are valid points
259 */
260 GNUNET_assert (1 == crypto_core_ed25519_is_valid_point (
261 blinded_r_pub[0].point.y));
262 GNUNET_assert (1 == crypto_core_ed25519_is_valid_point (
263 blinded_r_pub[1].point.y));
264
265 /* TEST 4
266 * Check if function gives the same result for the same input.
267 */
268 memcpy (&other_blinded_c[0],
269 &blinded_cs[0],
270 sizeof(struct GNUNET_CRYPTO_CsC) * 2);
271 memcpy (&other_blinded_r_pub[0],
272 &blinded_r_pub[0],
273 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2);
274
275 for (int i = 0; i<ITER; i++) {
276 GNUNET_CRYPTO_cs_calc_blinded_c (bs,
277 r_pub,
278 pub,
279 msg,
280 msg_len,
281 blinded_cs,
282 blinded_r_pub);
283 GNUNET_assert (0 == memcmp (&other_blinded_c[0],
284 &blinded_cs[0],
285 sizeof(struct GNUNET_CRYPTO_CsC) * 2));
286 GNUNET_assert (0 == memcmp (&other_blinded_r_pub[0],
287 &blinded_r_pub[0],
288 sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2));
289 }
290}
291
292
293void
294test_blind_sign (unsigned int *b,
295 const struct GNUNET_CRYPTO_CsPrivateKey *priv,
296 const struct GNUNET_CRYPTO_CsRSecret r[2],
297 const struct GNUNET_CRYPTO_CsC c[2],
298 const struct GNUNET_CRYPTO_CsNonce *nonce,
299 struct GNUNET_CRYPTO_CsBlindS *blinded_s)
300{
301 /* TEST 1
302 * Check that blinded_s is set
303 */
304 struct GNUNET_CRYPTO_CsC other_blinded_s;
305 memcpy (&other_blinded_s, blinded_s, sizeof(struct GNUNET_CRYPTO_CsBlindS));
306
307 *b = GNUNET_CRYPTO_cs_sign_derive (priv,
308 r,
309 c,
310 nonce,
311 blinded_s);
312
313 GNUNET_assert (0 == *b || 1 == *b);
314 GNUNET_assert (0 != memcmp (&other_blinded_s,
315 blinded_s,
316 sizeof(struct GNUNET_CRYPTO_CsBlindS)));
317
318 /* TEST 2
319 * Check if s := rb + cbX
320 * This test does the opposite operations and checks wether the equation is still correct.
321 */
322 struct GNUNET_CRYPTO_Cs25519Scalar cb_mul_x;
323 struct GNUNET_CRYPTO_Cs25519Scalar s_min_rb;
324
325 crypto_core_ed25519_scalar_mul (cb_mul_x.d,
326 c[*b].scalar.d,
327 priv->scalar.d);
328
329 crypto_core_ed25519_scalar_sub (s_min_rb.d,
330 blinded_s->scalar.d,
331 r[*b].scalar.d);
332
333 GNUNET_assert (0 == memcmp (&s_min_rb, &cb_mul_x, sizeof(struct
334 GNUNET_CRYPTO_Cs25519Scalar)));
335
336 /* TEST 3
337 * Check if function gives the same result for the same input.
338 */
339 memcpy (&other_blinded_s, blinded_s, sizeof(struct GNUNET_CRYPTO_CsBlindS));
340 unsigned int other_b;
341 for (int i = 0; i<ITER; i++) {
342 other_b = GNUNET_CRYPTO_cs_sign_derive (priv, r, c, nonce, blinded_s);
343
344 GNUNET_assert (other_b == *b);
345 GNUNET_assert (0 == memcmp (&other_blinded_s,
346 blinded_s,
347 sizeof(struct GNUNET_CRYPTO_CsBlindS)));
348 }
349}
350
351
352void
353test_unblinds (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar,
354 const struct GNUNET_CRYPTO_CsBlindingSecret *bs,
355 struct GNUNET_CRYPTO_CsS *signature_scalar)
356{
357 /* TEST 1
358 * Check that signature_scalar is set
359 */
360 struct GNUNET_CRYPTO_CsS other_signature_scalar;
361 memcpy (&other_signature_scalar,
362 signature_scalar,
363 sizeof(struct GNUNET_CRYPTO_CsS));
364
365 GNUNET_CRYPTO_cs_unblind (blinded_signature_scalar, bs, signature_scalar);
366
367 GNUNET_assert (0 != memcmp (&other_signature_scalar,
368 signature_scalar,
369 sizeof(struct GNUNET_CRYPTO_CsS)));
370
371 /* TEST 2
372 * Check if s' := s + a mod p
373 * This test does the opposite operations and checks wether the equation is still correct.
374 */
375 struct GNUNET_CRYPTO_Cs25519Scalar s_min_a;
376
377 crypto_core_ed25519_scalar_sub (s_min_a.d,
378 signature_scalar->scalar.d,
379 bs->alpha.d);
380
381 GNUNET_assert (0 == memcmp (&s_min_a, &blinded_signature_scalar->scalar,
382 sizeof(struct
383 GNUNET_CRYPTO_Cs25519Scalar)));
384
385 /* TEST 3
386 * Check if function gives the same result for the same input.
387 */
388 memcpy (&other_signature_scalar, signature_scalar,
389 sizeof(struct GNUNET_CRYPTO_CsS));
390
391 for (int i = 0; i<ITER; i++) {
392 GNUNET_CRYPTO_cs_unblind (blinded_signature_scalar, bs, signature_scalar);
393 GNUNET_assert (0 == memcmp (&other_signature_scalar,
394 signature_scalar,
395 sizeof(struct GNUNET_CRYPTO_CsS)));
396 }
397}
398
399
400void
401test_blind_verify (const struct GNUNET_CRYPTO_CsSignature *sig,
402 const struct GNUNET_CRYPTO_CsPublicKey *pub,
403 const struct GNUNET_CRYPTO_CsC *c)
404{
405 /* TEST 1
406 * Test verifies the blinded signature sG == Rb + cbX
407 */
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
413 struct GNUNET_CRYPTO_Cs25519Point c_mul_pub;
414 GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (c_mul_pub.y,
415 c->scalar.d,
416 pub->point.y));
417
418 struct GNUNET_CRYPTO_Cs25519Point r_add_c_mul_pub;
419 GNUNET_assert (0 == crypto_core_ed25519_add (r_add_c_mul_pub.y,
420 sig->r_point.point.y,
421 c_mul_pub.y));
422
423 GNUNET_assert (0 == memcmp (sig_scal_mul_base.y,
424 r_add_c_mul_pub.y,
425 sizeof(struct GNUNET_CRYPTO_Cs25519Point)));
426}
427
428
429void
430test_verify (const struct GNUNET_CRYPTO_CsSignature *sig,
431 const struct GNUNET_CRYPTO_CsPublicKey *pub,
432 const void *msg,
433 size_t msg_len)
434{
435 /* TEST 1
436 * Test simple verification
437 */
438 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_cs_verify (sig,
439 pub,
440 msg,
441 msg_len));
442 /* TEST 2
443 * Test verification of "wrong" message
444 */
445 char other_msg[] = "test massege";
446 size_t other_msg_len = strlen ("test massege");
447 GNUNET_assert (GNUNET_SYSERR == GNUNET_CRYPTO_cs_verify (sig,
448 pub,
449 other_msg,
450 other_msg_len));
451}
452
453
454int
455main (int argc,
456 char *argv[])
457{
458 printf ("Test started\n");
459
460 // ---------- actions performed by signer
461 char message[] = "test message";
462 size_t message_len = strlen ("test message");
463
464 struct GNUNET_CRYPTO_CsPrivateKey priv;
465 test_create_priv (&priv);
466
467 struct GNUNET_CRYPTO_CsPublicKey pub;
468 test_generate_pub (&priv, &pub);
469
470 // derive nonce
471 struct GNUNET_CRYPTO_CsNonce nonce;
472 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_hkdf (nonce.nonce,
473 sizeof(nonce.nonce),
474 GCRY_MD_SHA512,
475 GCRY_MD_SHA256,
476 "nonce",
477 strlen ("nonce"),
478 "nonce_secret",
479 strlen ("nonce_secret"),
480 NULL,
481 0));
482
483 // generate r, R
484 struct GNUNET_CRYPTO_CsRSecret r_secrets[2];
485 test_derive_rsecret (&nonce, &priv, r_secrets);
486
487 struct GNUNET_CRYPTO_CsRPublic r_publics[2];
488 test_generate_rpublic (&r_secrets[0], &r_publics[0]);
489 test_generate_rpublic (&r_secrets[1], &r_publics[1]);
490
491 // ---------- actions performed by user
492
493 // generate blinding secrets
494 struct GNUNET_CRYPTO_CsBlindingSecret blindingsecrets[2];
495 test_derive_blindingsecrets (&nonce,
496 sizeof(nonce),
497 blindingsecrets);
498
499 // calculate blinded c's
500 struct GNUNET_CRYPTO_CsC blinded_cs[2];
501 struct GNUNET_CRYPTO_CsRPublic blinded_r_pubs[2];
502 test_calc_blindedc (blindingsecrets,
503 r_publics,
504 &pub,
505 message,
506 message_len,
507 blinded_cs,
508 blinded_r_pubs);
509
510 // ---------- actions performed by signer
511 // sign blinded c's and get b and s in return
512 unsigned int b;
513 struct GNUNET_CRYPTO_CsBlindS blinded_s;
514 test_blind_sign (&b, &priv, r_secrets, blinded_cs, &nonce, &blinded_s);
515
516 // verify blinded signature
517 struct GNUNET_CRYPTO_CsSignature blinded_signature;
518 blinded_signature.r_point = r_publics[b];
519 blinded_signature.s_scalar.scalar = blinded_s.scalar;
520 test_blind_verify (&blinded_signature, &pub, &blinded_cs[b]);
521
522 // ---------- actions performed by user
523 struct GNUNET_CRYPTO_CsS sig_scalar;
524 test_unblinds (&blinded_s, &blindingsecrets[b], &sig_scalar);
525
526 // verify unblinded signature
527 struct GNUNET_CRYPTO_CsSignature signature;
528 signature.r_point = blinded_r_pubs[b];
529 signature.s_scalar = sig_scalar;
530 test_verify (&signature, &pub, message, message_len);
531
532 return 0;
533}