src/util: Use make 4.0 assignment operator
[oweals/gnunet.git] / src / util / test_crypto_paillier.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2014 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_crypto_paillier.c
23  * @brief testcase paillier crypto
24  * @author Christian Fuchs
25  * @author Florian Dold
26  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include <gcrypt.h>
30
31
32 static int
33 test_crypto ()
34 {
35   gcry_mpi_t plaintext;
36   gcry_mpi_t plaintext_result;
37   struct GNUNET_CRYPTO_PaillierCiphertext ciphertext;
38   struct GNUNET_CRYPTO_PaillierPublicKey public_key;
39   struct GNUNET_CRYPTO_PaillierPrivateKey private_key;
40   int ret = 0;
41
42   GNUNET_CRYPTO_paillier_create (&public_key,
43                                  &private_key);
44   GNUNET_assert (NULL != (plaintext = gcry_mpi_new (0)));
45   GNUNET_assert (NULL != (plaintext_result = gcry_mpi_new (0)));
46   gcry_mpi_randomize (plaintext,
47                       GNUNET_CRYPTO_PAILLIER_BITS / 2,
48                       GCRY_WEAK_RANDOM);
49
50   GNUNET_CRYPTO_paillier_encrypt (&public_key,
51                                   plaintext,
52                                   0 /* 0 hom ops */,
53                                   &ciphertext);
54   GNUNET_CRYPTO_paillier_decrypt (&private_key,
55                                   &public_key,
56                                   &ciphertext,
57                                   plaintext_result);
58   if (0 != gcry_mpi_cmp (plaintext,
59                          plaintext_result))
60   {
61     fprintf (stderr,
62              "Paillier decryption failed with plaintext of size %u\n",
63              gcry_mpi_get_nbits (plaintext));
64     gcry_log_debugmpi ("\n",
65                        plaintext);
66     gcry_log_debugmpi ("\n",
67                        plaintext_result);
68     ret = 1;
69   }
70   gcry_mpi_release (plaintext);
71   gcry_mpi_release (plaintext_result);
72   return ret;
73 }
74
75
76 static int
77 test_hom_simple (unsigned int a,
78                  unsigned int b)
79 {
80   gcry_mpi_t m1;
81   gcry_mpi_t m2;
82   gcry_mpi_t result;
83   gcry_mpi_t hom_result;
84   struct GNUNET_CRYPTO_PaillierCiphertext c1;
85   struct GNUNET_CRYPTO_PaillierCiphertext c2;
86   struct GNUNET_CRYPTO_PaillierCiphertext c_result;
87   struct GNUNET_CRYPTO_PaillierPublicKey public_key;
88   struct GNUNET_CRYPTO_PaillierPrivateKey private_key;
89   int ret = 0;
90
91   GNUNET_CRYPTO_paillier_create (&public_key,
92                                  &private_key);
93
94   GNUNET_assert (NULL != (m1 = gcry_mpi_new (0)));
95   GNUNET_assert (NULL != (m2 = gcry_mpi_new (0)));
96   GNUNET_assert (NULL != (result = gcry_mpi_new (0)));
97   GNUNET_assert (NULL != (hom_result = gcry_mpi_new (0)));
98   m1 = gcry_mpi_set_ui (m1, a);
99   m2 = gcry_mpi_set_ui (m2, b);
100   gcry_mpi_add (result,
101                 m1,
102                 m2);
103   GNUNET_CRYPTO_paillier_encrypt (&public_key,
104                                   m1,
105                                   2,
106                                   &c1);
107   GNUNET_CRYPTO_paillier_encrypt (&public_key,
108                                   m2,
109                                   2,
110                                   &c2);
111   GNUNET_CRYPTO_paillier_hom_add (&public_key,
112                                   &c1,
113                                   &c2,
114                                   &c_result);
115   GNUNET_CRYPTO_paillier_decrypt (&private_key,
116                                   &public_key,
117                                   &c_result,
118                                   hom_result);
119   if (0 != gcry_mpi_cmp (result, hom_result))
120   {
121     fprintf (stderr,
122              "GNUNET_CRYPTO_paillier failed simple math!\n");
123     gcry_log_debugmpi ("got ", hom_result);
124     gcry_log_debugmpi ("wanted ", result);
125     ret = 1;
126   }
127   gcry_mpi_release (m1);
128   gcry_mpi_release (m2);
129   gcry_mpi_release (result);
130   gcry_mpi_release (hom_result);
131   return ret;
132 }
133
134
135 static int
136 test_hom ()
137 {
138   int ret;
139   gcry_mpi_t m1;
140   gcry_mpi_t m2;
141   gcry_mpi_t result;
142   gcry_mpi_t hom_result;
143   struct GNUNET_CRYPTO_PaillierCiphertext c1;
144   struct GNUNET_CRYPTO_PaillierCiphertext c2;
145   struct GNUNET_CRYPTO_PaillierCiphertext c_result;
146   struct GNUNET_CRYPTO_PaillierPublicKey public_key;
147   struct GNUNET_CRYPTO_PaillierPrivateKey private_key;
148
149   GNUNET_CRYPTO_paillier_create (&public_key,
150                                  &private_key);
151
152   GNUNET_assert (NULL != (m1 = gcry_mpi_new (0)));
153   GNUNET_assert (NULL != (m2 = gcry_mpi_new (0)));
154   GNUNET_assert (NULL != (result = gcry_mpi_new (0)));
155   GNUNET_assert (NULL != (hom_result = gcry_mpi_new (0)));
156   m1 = gcry_mpi_set_ui (m1, 1);
157   /* m1 = m1 * 2 ^ (GCPB - 3) */
158   gcry_mpi_mul_2exp (m1,
159                      m1,
160                      GNUNET_CRYPTO_PAILLIER_BITS - 3);
161   m2 = gcry_mpi_set_ui (m2, 15);
162   /* m1 = m1 * 2 ^ (GCPB / 2) */
163   gcry_mpi_mul_2exp (m2,
164                      m2,
165                      GNUNET_CRYPTO_PAILLIER_BITS / 2);
166   gcry_mpi_add (result,
167                 m1,
168                 m2);
169
170   if (1 != (ret = GNUNET_CRYPTO_paillier_encrypt (&public_key,
171                                                   m1,
172                                                   2,
173                                                   &c1)))
174   {
175     fprintf (stderr,
176              "GNUNET_CRYPTO_paillier_encrypt 1 failed, should return 1 allowed operation, got %d!\n",
177              ret);
178     ret = 1;
179     goto out;
180   }
181   if (2 != (ret = GNUNET_CRYPTO_paillier_encrypt (&public_key,
182                                                   m2,
183                                                   2,
184                                                   &c2)))
185   {
186     fprintf (stderr,
187              "GNUNET_CRYPTO_paillier_encrypt 2 failed, should return 2 allowed operation, got %d!\n",
188              ret);
189     ret = 1;
190     goto out;
191   }
192
193   if (0 != (ret = GNUNET_CRYPTO_paillier_hom_add (&public_key,
194                                                   &c1,
195                                                   &c2,
196                                                   &c_result)))
197   {
198     fprintf (stderr,
199              "GNUNET_CRYPTO_paillier_hom_add failed, expected 0 remaining operations, got %d!\n",
200              ret);
201     ret = 1;
202     goto out;
203   }
204
205   GNUNET_CRYPTO_paillier_decrypt (&private_key,
206                                   &public_key,
207                                   &c_result,
208                                   hom_result);
209
210   if (0 != gcry_mpi_cmp (result, hom_result))
211   {
212     fprintf (stderr,
213              "GNUNET_CRYPTO_paillier miscalculated with large numbers!\n");
214     gcry_log_debugmpi ("got", hom_result);
215     gcry_log_debugmpi ("wanted", result);
216     ret = 1;
217   }
218 out:
219   gcry_mpi_release (m1);
220   gcry_mpi_release (m2);
221   gcry_mpi_release (result);
222   gcry_mpi_release (hom_result);
223   return ret;
224 }
225
226
227 int
228 main (int argc,
229       char *argv[])
230 {
231   int ret;
232   ret = test_crypto ();
233   if (0 != ret)
234     return ret;
235   ret = test_hom_simple (2,4);
236   if (0 != ret)
237     return ret;
238   ret = test_hom_simple (13,17);
239   if (0 != ret)
240     return ret;
241   ret = test_hom ();
242   return ret;
243 }
244
245 /* end of test_crypto_paillier.c */