aboutsummaryrefslogtreecommitdiff
path: root/src/contrib/service/scalarproduct/test_ecc_scalarproduct.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/service/scalarproduct/test_ecc_scalarproduct.c')
-rw-r--r--src/contrib/service/scalarproduct/test_ecc_scalarproduct.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/contrib/service/scalarproduct/test_ecc_scalarproduct.c b/src/contrib/service/scalarproduct/test_ecc_scalarproduct.c
new file mode 100644
index 000000000..85460cb05
--- /dev/null
+++ b/src/contrib/service/scalarproduct/test_ecc_scalarproduct.c
@@ -0,0 +1,212 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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_ecc_scalarproduct.c
23 * @brief testcase for math behind ECC SP calculation
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include <gcrypt.h>
29
30/**
31 * Global context.
32 */
33static struct GNUNET_CRYPTO_EccDlogContext *edc;
34
35
36/**
37 * Perform SP calculation.
38 *
39 * @param avec 0-terminated vector of Alice's values
40 * @param bvec 0-terminated vector of Bob's values
41 * @return avec * bvec
42 */
43static int
44test_sp (const unsigned int *avec,
45 const unsigned int *bvec)
46{
47 unsigned int len;
48 struct GNUNET_CRYPTO_EccScalar a;
49 struct GNUNET_CRYPTO_EccScalar a_neg;
50 struct GNUNET_CRYPTO_EccPoint *g;
51 struct GNUNET_CRYPTO_EccPoint *h;
52 struct GNUNET_CRYPTO_EccPoint pg;
53 struct GNUNET_CRYPTO_EccPoint ph;
54
55 /* determine length */
56 for (len = 0; 0 != avec[len]; len++)
57 ;
58 if (0 == len)
59 return 0;
60
61 /* Alice */
62 GNUNET_CRYPTO_ecc_rnd_mpi (&a,
63 &a_neg);
64 g = GNUNET_new_array (len,
65 struct GNUNET_CRYPTO_EccPoint);
66 h = GNUNET_new_array (len,
67 struct GNUNET_CRYPTO_EccPoint);
68 for (unsigned int i = 0; i < len; i++)
69 {
70 struct GNUNET_CRYPTO_EccScalar tmp;
71 struct GNUNET_CRYPTO_EccScalar ri;
72 struct GNUNET_CRYPTO_EccScalar ria;
73
74 GNUNET_CRYPTO_ecc_random_mod_n (&ri);
75 GNUNET_assert (GNUNET_OK ==
76 GNUNET_CRYPTO_ecc_dexp_mpi (&ri,
77 &g[i]));
78 /* ria = ri * a mod L, where L is the order of the main subgroup */
79 crypto_core_ed25519_scalar_mul (ria.v,
80 ri.v,
81 a.v);
82 /* tmp = ria + avec[i] */
83 {
84 int64_t val = avec[i];
85 struct GNUNET_CRYPTO_EccScalar vali;
86
87 GNUNET_assert (INT64_MIN != val);
88 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
89 &vali);
90 if (val > 0)
91 crypto_core_ed25519_scalar_add (tmp.v,
92 ria.v,
93 vali.v);
94 else
95 crypto_core_ed25519_scalar_sub (tmp.v,
96 ria.v,
97 vali.v);
98 }
99 /* h[i] = g^tmp = g^{ria + avec[i]} */
100 GNUNET_assert (GNUNET_OK ==
101 GNUNET_CRYPTO_ecc_dexp_mpi (&tmp,
102 &h[i]));
103 }
104
105 /* Bob */
106 for (unsigned int i = 0; i < len; i++)
107 {
108 struct GNUNET_CRYPTO_EccPoint gm;
109 struct GNUNET_CRYPTO_EccPoint hm;
110
111 {
112 int64_t val = bvec[i];
113 struct GNUNET_CRYPTO_EccScalar vali;
114
115 GNUNET_assert (INT64_MIN != val);
116 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
117 &vali);
118 if (val < 0)
119 crypto_core_ed25519_scalar_negate (vali.v,
120 vali.v);
121 /* gm = g[i]^vali */
122 GNUNET_assert (GNUNET_OK ==
123 GNUNET_CRYPTO_ecc_pmul_mpi (&g[i],
124 &vali,
125 &gm));
126 /* hm = h[i]^vali */
127 GNUNET_assert (GNUNET_OK ==
128 GNUNET_CRYPTO_ecc_pmul_mpi (&h[i],
129 &vali,
130 &hm));
131 }
132 if (0 != i)
133 {
134 /* pg += gm */
135 GNUNET_assert (GNUNET_OK ==
136 GNUNET_CRYPTO_ecc_add (&gm,
137 &pg,
138 &pg));
139 /* ph += hm */
140 GNUNET_assert (GNUNET_OK ==
141 GNUNET_CRYPTO_ecc_add (&hm,
142 &ph,
143 &ph));
144 }
145 else
146 {
147 pg = gm;
148 ph = hm;
149 }
150 }
151 GNUNET_free (g);
152 GNUNET_free (h);
153
154 /* Alice */
155 {
156 struct GNUNET_CRYPTO_EccPoint pgi;
157 struct GNUNET_CRYPTO_EccPoint gsp;
158
159 /* pgi = pg^inv */
160 GNUNET_assert (GNUNET_OK ==
161 GNUNET_CRYPTO_ecc_pmul_mpi (&pg,
162 &a_neg,
163 &pgi));
164 /* gsp = pgi + ph */
165 GNUNET_assert (GNUNET_OK ==
166 GNUNET_CRYPTO_ecc_add (&pgi,
167 &ph,
168 &gsp));
169 return GNUNET_CRYPTO_ecc_dlog (edc,
170 &gsp);
171 }
172}
173
174
175/**
176 * Macro that checks that @a want is equal to @a have and
177 * if not returns with a failure code.
178 */
179#define CHECK(want,have) do { \
180 if (want != have) { \
181 GNUNET_break (0); \
182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
183 "Wanted %d, got %d\n", want, have); \
184 GNUNET_CRYPTO_ecc_dlog_release (edc); \
185 return 1; \
186 } } while (0)
187
188
189int
190main (int argc, char *argv[])
191{
192 static unsigned int v11[] = { 1, 1, 0 };
193 static unsigned int v22[] = { 2, 2, 0 };
194 static unsigned int v35[] = { 3, 5, 0 };
195 static unsigned int v24[] = { 2, 4, 0 };
196
197 GNUNET_log_setup ("test-ecc-scalarproduct",
198 "WARNING",
199 NULL);
200 edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128);
201 CHECK (2, test_sp (v11, v11));
202 CHECK (4, test_sp (v22, v11));
203 CHECK (8, test_sp (v35, v11));
204 CHECK (26, test_sp (v35, v24));
205 CHECK (26, test_sp (v24, v35));
206 CHECK (16, test_sp (v22, v35));
207 GNUNET_CRYPTO_ecc_dlog_release (edc);
208 return 0;
209}
210
211
212/* end of test_ecc_scalarproduct.c */