- merge; service API change
[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
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
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   if (0 == len)
66     return 0;
67
68   /* Alice */
69   GNUNET_CRYPTO_ecc_rnd_mpi (edc,
70                              &a, &a_inv);
71   g = GNUNET_new_array (len,
72                         gcry_mpi_point_t);
73   h = GNUNET_new_array (len,
74                         gcry_mpi_point_t);
75   ria = gcry_mpi_new (0);
76   tmp = gcry_mpi_new (0);
77   for (i=0;i<len;i++)
78   {
79     ri = GNUNET_CRYPTO_ecc_random_mod_n (edc);
80     g[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
81                                        ri);
82     /* ria = ri * a */
83     gcry_mpi_mul (ria,
84                   ri,
85                   a);
86     /* tmp = ria + avec[i] */
87     gcry_mpi_add_ui (tmp,
88                      ria,
89                      avec[i]);
90     h[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
91                                        tmp);
92   }
93   gcry_mpi_release (ria);
94   gcry_mpi_release (tmp);
95
96   /* Bob */
97   val = gcry_mpi_new (0);
98   gcry_mpi_set_ui (val, bvec[0]);
99   pg = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
100                                    g[0],
101                                    val);
102   ph = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
103                                    h[0],
104                                    val);
105   for (i=1;i<len;i++)
106   {
107     gcry_mpi_point_t m;
108     gcry_mpi_point_t tmp;
109
110     gcry_mpi_set_ui (val, bvec[i]);
111     m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
112                                     g[i],
113                                     val);
114     tmp = GNUNET_CRYPTO_ecc_add (edc,
115                                  m,
116                                  pg);
117     gcry_mpi_point_release (m);
118     gcry_mpi_point_release (pg);
119     gcry_mpi_point_release (g[i]);
120     pg = tmp;
121
122     m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
123                                     h[i],
124                                     val);
125     tmp = GNUNET_CRYPTO_ecc_add (edc,
126                                  m,
127                                  ph);
128     gcry_mpi_point_release (m);
129     gcry_mpi_point_release (ph);
130     gcry_mpi_point_release (h[i]);
131     ph = tmp;
132   }
133   gcry_mpi_release (val);
134   GNUNET_free (g);
135   GNUNET_free (h);
136
137   /* Alice */
138   pgi = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
139                                     pg,
140                                     a_inv);
141   gsp = GNUNET_CRYPTO_ecc_add (edc,
142                                pgi,
143                                ph);
144   gcry_mpi_point_release (pgi);
145   gcry_mpi_point_release (ph);
146   sp = GNUNET_CRYPTO_ecc_dlog (edc,
147                                gsp);
148   gcry_mpi_point_release (gsp);
149   return sp;
150 }
151
152
153 int
154 main (int argc, char *argv[])
155 {
156   static unsigned int v11[] = { 1, 1, 0 };
157   static unsigned int v22[] = { 2, 2, 0 };
158   static unsigned int v35[] = { 3, 5, 0 };
159   static unsigned int v24[] = { 2, 4, 0 };
160
161   GNUNET_log_setup ("test-ecc-scalarproduct",
162                     "WARNING",
163                     NULL);
164   edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128);
165   GNUNET_assert ( 2 == test_sp (v11, v11));
166   GNUNET_assert ( 4 == test_sp (v22, v11));
167   GNUNET_assert ( 8 == test_sp (v35, v11));
168   GNUNET_assert (26 == test_sp (v35, v24));
169   GNUNET_assert (26 == test_sp (v24, v35));
170   GNUNET_assert (16 == test_sp (v22, v35));
171   GNUNET_CRYPTO_ecc_dlog_release (edc);
172   return 0;
173 }
174
175 /* end of test_ecc_scalarproduct.c */