uncrustify as demanded.
[oweals/gnunet.git] / src / scalarproduct / test_ecc_scalarproduct.c
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  */
33 static 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  */
43 static int
44 test_sp(const unsigned int *avec,
45         const unsigned int *bvec)
46 {
47   unsigned int len;
48   unsigned int i;
49   gcry_mpi_t a;
50   gcry_mpi_t a_inv;
51   gcry_mpi_t ri;
52   gcry_mpi_t val;
53   gcry_mpi_t ria;
54   gcry_mpi_t tmp;
55   gcry_mpi_point_t *g;
56   gcry_mpi_point_t *h;
57   gcry_mpi_point_t pg;
58   gcry_mpi_point_t ph;
59   gcry_mpi_point_t pgi;
60   gcry_mpi_point_t gsp;
61   int sp;
62
63   /* determine length */
64   for (len = 0; 0 != avec[len]; len++)
65     ;
66   if (0 == len)
67     return 0;
68
69   /* Alice */
70   GNUNET_CRYPTO_ecc_rnd_mpi(edc,
71                             &a, &a_inv);
72   g = GNUNET_new_array(len,
73                        gcry_mpi_point_t);
74   h = GNUNET_new_array(len,
75                        gcry_mpi_point_t);
76   ria = gcry_mpi_new(0);
77   tmp = gcry_mpi_new(0);
78   for (i = 0; i < len; i++)
79     {
80       ri = GNUNET_CRYPTO_ecc_random_mod_n(edc);
81       g[i] = GNUNET_CRYPTO_ecc_dexp_mpi(edc,
82                                         ri);
83       /* ria = ri * a */
84       gcry_mpi_mul(ria,
85                    ri,
86                    a);
87       /* tmp = ria + avec[i] */
88       gcry_mpi_add_ui(tmp,
89                       ria,
90                       avec[i]);
91       h[i] = GNUNET_CRYPTO_ecc_dexp_mpi(edc,
92                                         tmp);
93     }
94   gcry_mpi_release(ria);
95   gcry_mpi_release(tmp);
96
97   /* Bob */
98   val = gcry_mpi_new(0);
99   gcry_mpi_set_ui(val, bvec[0]);
100   pg = GNUNET_CRYPTO_ecc_pmul_mpi(edc,
101                                   g[0],
102                                   val);
103   ph = GNUNET_CRYPTO_ecc_pmul_mpi(edc,
104                                   h[0],
105                                   val);
106   for (i = 1; i < len; i++)
107     {
108       gcry_mpi_point_t m;
109       gcry_mpi_point_t tmp;
110
111       gcry_mpi_set_ui(val, bvec[i]);
112       m = GNUNET_CRYPTO_ecc_pmul_mpi(edc,
113                                      g[i],
114                                      val);
115       tmp = GNUNET_CRYPTO_ecc_add(edc,
116                                   m,
117                                   pg);
118       gcry_mpi_point_release(m);
119       gcry_mpi_point_release(pg);
120       gcry_mpi_point_release(g[i]);
121       pg = tmp;
122
123       m = GNUNET_CRYPTO_ecc_pmul_mpi(edc,
124                                      h[i],
125                                      val);
126       tmp = GNUNET_CRYPTO_ecc_add(edc,
127                                   m,
128                                   ph);
129       gcry_mpi_point_release(m);
130       gcry_mpi_point_release(ph);
131       gcry_mpi_point_release(h[i]);
132       ph = tmp;
133     }
134   gcry_mpi_release(val);
135   GNUNET_free(g);
136   GNUNET_free(h);
137
138   /* Alice */
139   pgi = GNUNET_CRYPTO_ecc_pmul_mpi(edc,
140                                    pg,
141                                    a_inv);
142   gsp = GNUNET_CRYPTO_ecc_add(edc,
143                               pgi,
144                               ph);
145   gcry_mpi_point_release(pgi);
146   gcry_mpi_point_release(ph);
147   sp = GNUNET_CRYPTO_ecc_dlog(edc,
148                               gsp);
149   gcry_mpi_point_release(gsp);
150   return sp;
151 }
152
153
154 int
155 main(int argc, char *argv[])
156 {
157   static unsigned int v11[] = { 1, 1, 0 };
158   static unsigned int v22[] = { 2, 2, 0 };
159   static unsigned int v35[] = { 3, 5, 0 };
160   static unsigned int v24[] = { 2, 4, 0 };
161
162   GNUNET_log_setup("test-ecc-scalarproduct",
163                    "WARNING",
164                    NULL);
165   edc = GNUNET_CRYPTO_ecc_dlog_prepare(128, 128);
166   GNUNET_assert(2 == test_sp(v11, v11));
167   GNUNET_assert(4 == test_sp(v22, v11));
168   GNUNET_assert(8 == test_sp(v35, v11));
169   GNUNET_assert(26 == test_sp(v35, v24));
170   GNUNET_assert(26 == test_sp(v24, v35));
171   GNUNET_assert(16 == test_sp(v22, v35));
172   GNUNET_CRYPTO_ecc_dlog_release(edc);
173   return 0;
174 }
175
176 /* end of test_ecc_scalarproduct.c */