add attestation API
[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
177 /* end of test_ecc_scalarproduct.c */