glitch in the license text detected by hyazinthe, thank you!
[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 */
16 /**
17  * @file util/test_ecc_scalarproduct.c
18  * @brief testcase for math behind ECC SP calculation
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_util_lib.h"
23 #include <gcrypt.h>
24
25 /**
26  * Global context.
27  */
28 static struct GNUNET_CRYPTO_EccDlogContext *edc;
29
30
31 /**
32  * Perform SP calculation.
33  *
34  * @param avec 0-terminated vector of Alice's values
35  * @param bvec 0-terminated vector of Bob's values
36  * @return avec * bvec
37  */
38 static int
39 test_sp (const unsigned int *avec,
40          const unsigned int *bvec)
41 {
42   unsigned int len;
43   unsigned int i;
44   gcry_mpi_t a;
45   gcry_mpi_t a_inv;
46   gcry_mpi_t ri;
47   gcry_mpi_t val;
48   gcry_mpi_t ria;
49   gcry_mpi_t tmp;
50   gcry_mpi_point_t *g;
51   gcry_mpi_point_t *h;
52   gcry_mpi_point_t pg;
53   gcry_mpi_point_t ph;
54   gcry_mpi_point_t pgi;
55   gcry_mpi_point_t gsp;
56   int sp;
57
58   /* determine length */
59   for (len=0;0 != avec[len];len++) ;
60   if (0 == len)
61     return 0;
62
63   /* Alice */
64   GNUNET_CRYPTO_ecc_rnd_mpi (edc,
65                              &a, &a_inv);
66   g = GNUNET_new_array (len,
67                         gcry_mpi_point_t);
68   h = GNUNET_new_array (len,
69                         gcry_mpi_point_t);
70   ria = gcry_mpi_new (0);
71   tmp = gcry_mpi_new (0);
72   for (i=0;i<len;i++)
73   {
74     ri = GNUNET_CRYPTO_ecc_random_mod_n (edc);
75     g[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
76                                        ri);
77     /* ria = ri * a */
78     gcry_mpi_mul (ria,
79                   ri,
80                   a);
81     /* tmp = ria + avec[i] */
82     gcry_mpi_add_ui (tmp,
83                      ria,
84                      avec[i]);
85     h[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
86                                        tmp);
87   }
88   gcry_mpi_release (ria);
89   gcry_mpi_release (tmp);
90
91   /* Bob */
92   val = gcry_mpi_new (0);
93   gcry_mpi_set_ui (val, bvec[0]);
94   pg = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
95                                    g[0],
96                                    val);
97   ph = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
98                                    h[0],
99                                    val);
100   for (i=1;i<len;i++)
101   {
102     gcry_mpi_point_t m;
103     gcry_mpi_point_t tmp;
104
105     gcry_mpi_set_ui (val, bvec[i]);
106     m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
107                                     g[i],
108                                     val);
109     tmp = GNUNET_CRYPTO_ecc_add (edc,
110                                  m,
111                                  pg);
112     gcry_mpi_point_release (m);
113     gcry_mpi_point_release (pg);
114     gcry_mpi_point_release (g[i]);
115     pg = tmp;
116
117     m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
118                                     h[i],
119                                     val);
120     tmp = GNUNET_CRYPTO_ecc_add (edc,
121                                  m,
122                                  ph);
123     gcry_mpi_point_release (m);
124     gcry_mpi_point_release (ph);
125     gcry_mpi_point_release (h[i]);
126     ph = tmp;
127   }
128   gcry_mpi_release (val);
129   GNUNET_free (g);
130   GNUNET_free (h);
131
132   /* Alice */
133   pgi = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
134                                     pg,
135                                     a_inv);
136   gsp = GNUNET_CRYPTO_ecc_add (edc,
137                                pgi,
138                                ph);
139   gcry_mpi_point_release (pgi);
140   gcry_mpi_point_release (ph);
141   sp = GNUNET_CRYPTO_ecc_dlog (edc,
142                                gsp);
143   gcry_mpi_point_release (gsp);
144   return sp;
145 }
146
147
148 int
149 main (int argc, char *argv[])
150 {
151   static unsigned int v11[] = { 1, 1, 0 };
152   static unsigned int v22[] = { 2, 2, 0 };
153   static unsigned int v35[] = { 3, 5, 0 };
154   static unsigned int v24[] = { 2, 4, 0 };
155
156   GNUNET_log_setup ("test-ecc-scalarproduct",
157                     "WARNING",
158                     NULL);
159   edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128);
160   GNUNET_assert ( 2 == test_sp (v11, v11));
161   GNUNET_assert ( 4 == test_sp (v22, v11));
162   GNUNET_assert ( 8 == test_sp (v35, v11));
163   GNUNET_assert (26 == test_sp (v35, v24));
164   GNUNET_assert (26 == test_sp (v24, v35));
165   GNUNET_assert (16 == test_sp (v22, v35));
166   GNUNET_CRYPTO_ecc_dlog_release (edc);
167   return 0;
168 }
169
170 /* end of test_ecc_scalarproduct.c */