paragraph for gnunet devs that don't know how to use the web
[oweals/gnunet.git] / src / util / test_crypto_ecdsa.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2002-2013 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 */
19 /**
20  * @file util/test_crypto_ecdsa.c
21  * @brief testcase for ECC ECDSA public key crypto
22  * @author Christian Grothoff
23  */
24 #include "platform.h"
25 #include "gnunet_util_lib.h"
26 #include "gnunet_signatures.h"
27 #include <gcrypt.h>
28
29 #define ITER 25
30
31 #define PERF GNUNET_YES
32
33
34 static struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
35
36
37 static int
38 testSignVerify ()
39 {
40   struct GNUNET_CRYPTO_EcdsaSignature sig;
41   struct GNUNET_CRYPTO_EccSignaturePurpose purp;
42   struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
43   int i;
44   struct GNUNET_TIME_Absolute start;
45   int ok = GNUNET_OK;
46
47   FPRINTF (stderr, "%s",  "W");
48   GNUNET_CRYPTO_ecdsa_key_get_public (key, &pkey);
49   start = GNUNET_TIME_absolute_get ();
50   purp.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
51   purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
52
53   for (i = 0; i < ITER; i++)
54   {
55     FPRINTF (stderr, "%s",  "."); fflush (stderr);
56     if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_sign (key, &purp, &sig))
57     {
58       FPRINTF (stderr,
59                "%s",
60                "GNUNET_CRYPTO_ecdsa_sign returned SYSERR\n");
61       ok = GNUNET_SYSERR;
62       continue;
63     }
64     if (GNUNET_SYSERR ==
65         GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST, &purp, &sig,
66                                     &pkey))
67     {
68       printf ("GNUNET_CRYPTO_ecdsa_verify failed!\n");
69       ok = GNUNET_SYSERR;
70       continue;
71     }
72     if (GNUNET_SYSERR !=
73         GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
74                                     &purp, &sig, &pkey))
75     {
76       printf ("GNUNET_CRYPTO_ecdsa_verify failed to fail!\n");
77       ok = GNUNET_SYSERR;
78       continue;
79     }
80   }
81   printf ("%d ECDSA sign/verify operations %s\n", ITER,
82           GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES));
83   return ok;
84 }
85
86
87 static int
88 testDeriveSignVerify ()
89 {
90   struct GNUNET_CRYPTO_EcdsaSignature sig;
91   struct GNUNET_CRYPTO_EccSignaturePurpose purp;
92   struct GNUNET_CRYPTO_EcdsaPrivateKey *dpriv;
93   struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
94   struct GNUNET_CRYPTO_EcdsaPublicKey dpub;
95
96   dpriv = GNUNET_CRYPTO_ecdsa_private_key_derive (key, "test-derive", "test-CTX");
97   GNUNET_CRYPTO_ecdsa_key_get_public (key, &pkey);
98   GNUNET_CRYPTO_ecdsa_public_key_derive (&pkey, "test-derive", "test-CTX", &dpub);
99   purp.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
100   purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
101
102   if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_sign (dpriv, &purp, &sig))
103   {
104     FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_ecdsa_sign returned SYSERR\n");
105     GNUNET_free (dpriv);
106     return GNUNET_SYSERR;
107   }
108   if (GNUNET_SYSERR ==
109       GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST,
110                                   &purp, &sig,
111                                   &dpub))
112   {
113     printf ("GNUNET_CRYPTO_ecdsa_verify failed!\n");
114     GNUNET_free (dpriv);
115     return GNUNET_SYSERR;
116   }
117   if (GNUNET_SYSERR !=
118       GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST,
119                                   &purp, &sig,
120                                   &pkey))
121   {
122     printf ("GNUNET_CRYPTO_ecdsa_verify failed to fail!\n");
123     GNUNET_free (dpriv);
124     return GNUNET_SYSERR;
125   }
126   if (GNUNET_SYSERR !=
127       GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
128                                   &purp, &sig, &dpub))
129   {
130     printf ("GNUNET_CRYPTO_ecdsa_verify failed to fail!\n");
131     GNUNET_free (dpriv);
132     return GNUNET_SYSERR;
133   }
134   GNUNET_free (dpriv);
135   return GNUNET_OK;
136 }
137
138
139 #if PERF
140 static int
141 testSignPerformance ()
142 {
143   struct GNUNET_CRYPTO_EccSignaturePurpose purp;
144   struct GNUNET_CRYPTO_EcdsaSignature sig;
145   struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
146   int i;
147   struct GNUNET_TIME_Absolute start;
148   int ok = GNUNET_OK;
149
150   purp.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
151   purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
152   FPRINTF (stderr, "%s",  "W");
153   GNUNET_CRYPTO_ecdsa_key_get_public (key, &pkey);
154   start = GNUNET_TIME_absolute_get ();
155   for (i = 0; i < ITER; i++)
156   {
157     FPRINTF (stderr, "%s",  "."); fflush (stderr);
158     if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_sign (key, &purp, &sig))
159     {
160       FPRINTF (stderr, "%s",
161                "GNUNET_CRYPTO_ecdsa_sign returned SYSERR\n");
162       ok = GNUNET_SYSERR;
163       continue;
164     }
165   }
166   printf ("%d ECC sign operations %s\n", ITER,
167           GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
168                                                   GNUNET_YES));
169   return ok;
170 }
171 #endif
172
173
174 static void
175 perf_keygen ()
176 {
177   struct GNUNET_TIME_Absolute start;
178   struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
179   int i;
180
181   FPRINTF (stderr, "%s",  "W");
182   start = GNUNET_TIME_absolute_get ();
183   for (i=0;i<10;i++)
184   {
185     fprintf (stderr, "."); fflush (stderr);
186     pk = GNUNET_CRYPTO_ecdsa_key_create ();
187     GNUNET_free (pk);
188   }
189   for (;i<25;i++)
190     fprintf (stderr, ".");
191   fflush (stderr);
192   printf ("10 ECDSA keys created in %s\n",
193           GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES));
194 }
195
196
197 int
198 main (int argc, char *argv[])
199 {
200   int failure_count = 0;
201
202   if (! gcry_check_version ("1.6.0"))
203   {
204     FPRINTF (stderr,
205              _
206              ("libgcrypt has not the expected version (version %s is required).\n"),
207              "1.6.0");
208     return 0;
209   }
210   if (getenv ("GNUNET_GCRYPT_DEBUG"))
211     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
212   GNUNET_log_setup ("test-crypto-ecc", "WARNING", NULL);
213   key = GNUNET_CRYPTO_ecdsa_key_create ();
214   if (GNUNET_OK != testDeriveSignVerify ())
215   {
216     failure_count++;
217     fprintf (stderr,
218              "\n\n%d TESTS FAILED!\n\n", failure_count);
219     return -1;
220   }
221 #if PERF
222   if (GNUNET_OK != testSignPerformance ())
223     failure_count++;
224 #endif
225   if (GNUNET_OK != testSignVerify ())
226     failure_count++;
227   GNUNET_free (key);
228   perf_keygen ();
229
230   if (0 != failure_count)
231   {
232     fprintf (stderr,
233              "\n\n%d TESTS FAILED!\n\n",
234              failure_count);
235     return -1;
236   }
237   return 0;
238 }
239
240 /* end of test_crypto_ecdsa.c */