diff options
author | Gian Demarmels <gian@demarmels.org> | 2021-12-06 22:44:14 +0100 |
---|---|---|
committer | Lucien Heuzeveldt <lucienclaude.heuzeveldt@students.bfh.ch> | 2021-12-07 20:44:37 +0100 |
commit | 67b56e366bc73cc9d940721067ae0f3c7f554768 (patch) | |
tree | f931e85c18cbde7ca5ed620d073e816964e08ad0 | |
parent | 2bcdfc2f958f5fd2512103c2240f1c24c07524d7 (diff) | |
download | gnunet-67b56e366bc73cc9d940721067ae0f3c7f554768.tar.gz gnunet-67b56e366bc73cc9d940721067ae0f3c7f554768.zip |
add crypto_cs testing and benchmark
-rw-r--r-- | src/util/Makefile.am | 13 | ||||
-rw-r--r-- | src/util/perf_crypto_cs.c | 185 | ||||
-rw-r--r-- | src/util/test_crypto_cs.c | 533 |
3 files changed, 731 insertions, 0 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 771be1ee3..9fda40f51 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -254,6 +254,7 @@ libgnunet_plugin_utiltest_la_LDFLAGS = \ | |||
254 | 254 | ||
255 | if HAVE_BENCHMARKS | 255 | if HAVE_BENCHMARKS |
256 | BENCHMARKS = \ | 256 | BENCHMARKS = \ |
257 | perf_crypto_cs \ | ||
257 | perf_crypto_hash \ | 258 | perf_crypto_hash \ |
258 | perf_crypto_rsa \ | 259 | perf_crypto_rsa \ |
259 | perf_crypto_paillier \ | 260 | perf_crypto_paillier \ |
@@ -290,6 +291,7 @@ check_PROGRAMS = \ | |||
290 | test_container_heap \ | 291 | test_container_heap \ |
291 | test_crypto_symmetric \ | 292 | test_crypto_symmetric \ |
292 | test_crypto_crc \ | 293 | test_crypto_crc \ |
294 | test_crypto_cs \ | ||
293 | test_crypto_ecdsa \ | 295 | test_crypto_ecdsa \ |
294 | test_crypto_eddsa \ | 296 | test_crypto_eddsa \ |
295 | test_crypto_ecdhe \ | 297 | test_crypto_ecdhe \ |
@@ -450,6 +452,12 @@ test_crypto_crc_SOURCES = \ | |||
450 | test_crypto_crc_LDADD = \ | 452 | test_crypto_crc_LDADD = \ |
451 | libgnunetutil.la | 453 | libgnunetutil.la |
452 | 454 | ||
455 | test_crypto_cs_SOURCES = \ | ||
456 | test_crypto_cs.c | ||
457 | test_crypto_cs_LDADD = \ | ||
458 | libgnunetutil.la \ | ||
459 | -lsodium | ||
460 | |||
453 | test_crypto_ecdsa_SOURCES = \ | 461 | test_crypto_ecdsa_SOURCES = \ |
454 | test_crypto_ecdsa.c | 462 | test_crypto_ecdsa.c |
455 | test_crypto_ecdsa_LDADD = \ | 463 | test_crypto_ecdsa_LDADD = \ |
@@ -605,6 +613,11 @@ test_uri_SOURCES = \ | |||
605 | test_uri_LDADD = \ | 613 | test_uri_LDADD = \ |
606 | libgnunetutil.la | 614 | libgnunetutil.la |
607 | 615 | ||
616 | perf_crypto_cs_SOURCES = \ | ||
617 | perf_crypto_cs.c | ||
618 | perf_crypto_cs_LDADD = \ | ||
619 | libgnunetutil.la | ||
620 | |||
608 | perf_crypto_hash_SOURCES = \ | 621 | perf_crypto_hash_SOURCES = \ |
609 | perf_crypto_hash.c | 622 | perf_crypto_hash.c |
610 | perf_crypto_hash_LDADD = \ | 623 | perf_crypto_hash_LDADD = \ |
diff --git a/src/util/perf_crypto_cs.c b/src/util/perf_crypto_cs.c new file mode 100644 index 000000000..a8c72052b --- /dev/null +++ b/src/util/perf_crypto_cs.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2014 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 | * @author Lucien Heuzeveldt <lucienclaude.heuzeveldt@students.bfh.ch> | ||
23 | * @author Gian Demarmels <gian@demarmels.org> | ||
24 | * @file util/perf_crypto_cs.c | ||
25 | * @brief measure performance of Clause Blind Schnorr Signatures | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include <gauger.h> | ||
31 | |||
32 | #define ITER 10 | ||
33 | |||
34 | /** | ||
35 | * Evaluate Clause Blind Schnorr Signature performance. | ||
36 | * | ||
37 | */ | ||
38 | static void | ||
39 | eval () | ||
40 | { | ||
41 | struct GNUNET_TIME_Absolute start; | ||
42 | unsigned int i; | ||
43 | |||
44 | struct GNUNET_CRYPTO_CsPrivateKey priv; | ||
45 | struct GNUNET_CRYPTO_CsPublicKey pub; | ||
46 | |||
47 | struct GNUNET_CRYPTO_CsRSecret r_priv[2]; | ||
48 | struct GNUNET_CRYPTO_CsRPublic r_pub[2]; | ||
49 | |||
50 | char message[] = "test message"; | ||
51 | size_t message_len = strlen ("test message"); | ||
52 | |||
53 | // derive a test nonce | ||
54 | struct GNUNET_CRYPTO_CsNonce nonce; | ||
55 | GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_hkdf (nonce.nonce, | ||
56 | sizeof(nonce.nonce), | ||
57 | GCRY_MD_SHA512, | ||
58 | GCRY_MD_SHA256, | ||
59 | "nonce", | ||
60 | strlen ("nonce"), | ||
61 | "nonce_secret", | ||
62 | strlen ("nonce_secret"), | ||
63 | NULL, | ||
64 | 0)); | ||
65 | |||
66 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]; | ||
67 | struct GNUNET_CRYPTO_CsC blinded_cs[2]; | ||
68 | struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2]; | ||
69 | struct GNUNET_CRYPTO_CsBlindS blinded_s; | ||
70 | struct GNUNET_CRYPTO_CsS signature_scalar; | ||
71 | struct GNUNET_CRYPTO_CsSignature sig; | ||
72 | |||
73 | // BENCHMARK keygen | ||
74 | start = GNUNET_TIME_absolute_get (); | ||
75 | |||
76 | for (i = 0; i < ITER; i++) | ||
77 | { | ||
78 | GNUNET_CRYPTO_cs_private_key_generate (&priv); | ||
79 | GNUNET_CRYPTO_cs_private_key_get_public (&priv, &pub); | ||
80 | } | ||
81 | printf ("10x key generation took %s\n", | ||
82 | GNUNET_STRINGS_relative_time_to_string ( | ||
83 | GNUNET_TIME_absolute_get_duration (start), | ||
84 | GNUNET_YES)); | ||
85 | |||
86 | |||
87 | // BENCHMARK r derive and calc R pub | ||
88 | start = GNUNET_TIME_absolute_get (); | ||
89 | for (i = 0; i < ITER; i++) | ||
90 | { | ||
91 | GNUNET_CRYPTO_cs_r_derive (&nonce, &priv, r_priv); | ||
92 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[0], &r_pub[0]); | ||
93 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[1], &r_pub[1]); | ||
94 | } | ||
95 | printf ("10x r0, r1 derive and R1,R2 calculation took %s\n", | ||
96 | GNUNET_STRINGS_relative_time_to_string ( | ||
97 | GNUNET_TIME_absolute_get_duration (start), | ||
98 | GNUNET_YES)); | ||
99 | |||
100 | |||
101 | // BENCHMARK derive blinding secrets | ||
102 | start = GNUNET_TIME_absolute_get (); | ||
103 | for (i = 0; i < ITER; i++) | ||
104 | { | ||
105 | GNUNET_CRYPTO_cs_blinding_secrets_derive (&nonce, | ||
106 | sizeof(struct | ||
107 | GNUNET_CRYPTO_CsNonce), | ||
108 | bs); | ||
109 | } | ||
110 | printf ("10x derive blinding secrets took %s\n", | ||
111 | GNUNET_STRINGS_relative_time_to_string ( | ||
112 | GNUNET_TIME_absolute_get_duration (start), | ||
113 | GNUNET_YES)); | ||
114 | |||
115 | |||
116 | // BENCHMARK calculating C | ||
117 | start = GNUNET_TIME_absolute_get (); | ||
118 | for (i = 0; i < ITER; i++) | ||
119 | { | ||
120 | GNUNET_CRYPTO_cs_calc_blinded_c (bs, | ||
121 | r_pub, | ||
122 | &pub, | ||
123 | message, | ||
124 | message_len, | ||
125 | blinded_cs, | ||
126 | blinded_r_pub); | ||
127 | } | ||
128 | printf ("10x calculating the blinded c took %s\n", | ||
129 | GNUNET_STRINGS_relative_time_to_string ( | ||
130 | GNUNET_TIME_absolute_get_duration (start), | ||
131 | GNUNET_YES)); | ||
132 | |||
133 | |||
134 | // BENCHMARK sign derive | ||
135 | unsigned int b; | ||
136 | start = GNUNET_TIME_absolute_get (); | ||
137 | for (i = 0; i < ITER; i++) | ||
138 | { | ||
139 | b = GNUNET_CRYPTO_cs_sign_derive (&priv, | ||
140 | r_priv, | ||
141 | blinded_cs, | ||
142 | &nonce, | ||
143 | &blinded_s); | ||
144 | } | ||
145 | printf ("10x signing blinded c took %s\n", | ||
146 | GNUNET_STRINGS_relative_time_to_string ( | ||
147 | GNUNET_TIME_absolute_get_duration (start), | ||
148 | GNUNET_YES)); | ||
149 | |||
150 | |||
151 | // BENCHMARK unblind signature | ||
152 | start = GNUNET_TIME_absolute_get (); | ||
153 | |||
154 | for (i = 0; i < ITER; i++) | ||
155 | { | ||
156 | GNUNET_CRYPTO_cs_unblind (&blinded_s, &bs[b], &signature_scalar); | ||
157 | sig.r_point = blinded_r_pub[b]; | ||
158 | sig.s_scalar = signature_scalar; | ||
159 | } | ||
160 | printf ("10x unblinding s took %s\n", | ||
161 | GNUNET_STRINGS_relative_time_to_string ( | ||
162 | GNUNET_TIME_absolute_get_duration (start), | ||
163 | GNUNET_YES)); | ||
164 | |||
165 | // BENCHMARK verify signature | ||
166 | start = GNUNET_TIME_absolute_get (); | ||
167 | for (i = 0; i < ITER; i++) | ||
168 | { | ||
169 | GNUNET_CRYPTO_cs_verify (&sig, | ||
170 | &pub, | ||
171 | message, | ||
172 | message_len); | ||
173 | } | ||
174 | printf ("10x verifying signatures took %s\n", | ||
175 | GNUNET_STRINGS_relative_time_to_string ( | ||
176 | GNUNET_TIME_absolute_get_duration (start), | ||
177 | GNUNET_YES)); | ||
178 | } | ||
179 | |||
180 | int | ||
181 | main (int argc, char *argv[]) | ||
182 | { | ||
183 | eval (); | ||
184 | return 0; | ||
185 | } | ||
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 | |||
33 | void | ||
34 | test_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 | |||
50 | void | ||
51 | test_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 | |||
85 | void | ||
86 | test_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 | |||
116 | void | ||
117 | test_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 | |||
150 | void | ||
151 | test_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 | |||
185 | void | ||
186 | test_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 | |||
293 | void | ||
294 | test_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 | |||
352 | void | ||
353 | test_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 | |||
400 | void | ||
401 | test_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 | |||
429 | void | ||
430 | test_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 | |||
454 | int | ||
455 | main (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 | } | ||