-simplify
[oweals/gnunet.git] / src / scalarproduct / test_ecc_scalarproduct.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2015 Christian Grothoff (and other contributing authors)
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_point_t *g;
54   gcry_mpi_point_t *h;
55   gcry_mpi_point_t pg;
56   gcry_mpi_point_t ph;
57   gcry_mpi_point_t pgi;
58   gcry_mpi_point_t gsp;
59   int sp;
60
61   /* determine length */
62   for (len=0;0 != avec[len];len++) ;
63   if (0 == len)
64     return 0;
65
66   /* Alice */
67   GNUNET_CRYPTO_ecc_rnd_mpi (edc,
68                              &a, &a_inv);
69   g = GNUNET_new_array (len,
70                         gcry_mpi_point_t);
71   h = GNUNET_new_array (len,
72                         gcry_mpi_point_t);
73   for (i=0;i<len;i++)
74   {
75     gcry_mpi_t tmp;
76     gcry_mpi_t ria;
77
78     ri = GNUNET_CRYPTO_ecc_random_mod_n (edc);
79     g[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
80                                        ri);
81     /* ria = ri * a */
82     ria = gcry_mpi_new (0);
83     gcry_mpi_mul (ria,
84                   ri,
85                   a);
86     /* tmp = ria + avec[i] */
87     tmp = gcry_mpi_new (0);
88     gcry_mpi_add_ui (tmp,
89                      ria,
90                      avec[i]);
91     gcry_mpi_release (ria);
92     h[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
93                                        tmp);
94     gcry_mpi_release (tmp);
95   }
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 */