-fix warning
[oweals/gnunet.git] / src / sensor / test_pow_sign.c
1   /*
2    * This file is part of GNUnet.
3    * (C)
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  * @file sensor/test_pow_sign.c
22  * @brief testcase for proof-of-work and signature library functions
23  */
24 #include <inttypes.h>
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "gnunet_sensor_util_lib.h"
28 #include "gnunet_testbed_service.h"
29 #include "gnunet_signatures.h"
30
31 /**
32  * Number of peers to start for the test
33  */
34 #define NUM_PEERS 1
35
36 /**
37  * Size of the message exchanged
38  */
39 #define MSG_SIZE 1024
40
41 /**
42  * Number of matching bits to use for generating proof-of-work
43  */
44 #define MATCHING_BITS 5
45
46 /**
47  * Test timeout
48  */
49 #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
50
51 /**
52  * Test name
53  */
54 static const char *testname = "test_pow_sign";
55
56 /**
57  * Name of GNUNET config file used in this test
58  */
59 static const char *cfg_filename = "test_pow_sign.conf";
60
61 /**
62  * Status of the test to be returned by main()
63  */
64 static int ok = 1;
65
66 /**
67  * Task used to shutdown / expire the test
68  */
69 static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
70
71 /**
72  * Message to be exchanged
73  */
74 static char msg[MSG_SIZE];
75
76 /**
77  * Private key of sending peer
78  */
79 static struct GNUNET_CRYPTO_EddsaPrivateKey *private_key;
80
81 /**
82  * Public key of sending peer
83  */
84 static struct GNUNET_CRYPTO_EddsaPublicKey *public_key;
85
86
87 /**
88  * Shutdown task
89  *
90  * @param cls Closure (unused)
91  * @param tc Task context (unused)
92  */
93 static void
94 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
95 {
96   if (NULL != private_key)
97   {
98     GNUNET_free (private_key);
99     private_key = NULL;
100   }
101   if (NULL != public_key)
102   {
103     GNUNET_free (public_key);
104     public_key = NULL;
105   }
106   GNUNET_SCHEDULER_shutdown ();
107 }
108
109
110 static void
111 pow_cb (void *cls, struct GNUNET_SENSOR_crypto_pow_block *block)
112 {
113   void *response;
114   struct GNUNET_TIME_Absolute end_time;
115   struct GNUNET_TIME_Relative duration;
116
117   end_time = GNUNET_TIME_absolute_get();
118   duration = GNUNET_TIME_absolute_get_difference (block->timestamp, end_time);
119   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
120               "Received block:\n" "pow: %" PRIu64 ".\n", block->pow);
121   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Block generation toke %s.\n",
122               GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_NO));
123   /* Test that the block is valid */
124   GNUNET_assert (MSG_SIZE ==
125                  GNUNET_SENSOR_crypto_verify_pow_sign (block, MATCHING_BITS,
126                                                        public_key, &response));
127   GNUNET_assert (0 == memcmp (msg, response, MSG_SIZE));
128   /* Modify the payload and test that verification returns invalid */
129   block->pow++;
130   GNUNET_assert (0 ==
131                  GNUNET_SENSOR_crypto_verify_pow_sign (block, MATCHING_BITS,
132                                                        public_key, &response));
133   ok = 0;
134   GNUNET_SCHEDULER_cancel (shutdown_task);
135   GNUNET_SCHEDULER_add_now (do_shutdown, NULL);
136 }
137
138
139 /**
140  * Callback to be called when the requested peer information is available
141  *
142  * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information()
143  * @param op the operation this callback corresponds to
144  * @param pinfo the result; will be NULL if the operation has failed
145  * @param emsg error message if the operation has failed; will be NULL if the
146  *          operation is successfull
147  */
148 static void
149 peer_info_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op,
150               const struct GNUNET_TESTBED_PeerInformation *pinfo,
151               const char *emsg)
152 {
153   struct GNUNET_TIME_Absolute timestamp;
154
155   /* generate random data block */
156   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, msg, MSG_SIZE);
157   /* get private and public keys */
158   private_key =
159       GNUNET_CRYPTO_eddsa_key_create_from_configuration (pinfo->result.cfg);
160   GNUNET_assert (NULL != private_key);
161   public_key = GNUNET_new (struct GNUNET_CRYPTO_EddsaPublicKey);
162
163   GNUNET_CRYPTO_eddsa_key_get_public (private_key, public_key);
164   /* create pow and sign */
165   timestamp = GNUNET_TIME_absolute_get ();
166   GNUNET_SENSOR_crypto_pow_sign (msg, MSG_SIZE, &timestamp, public_key,
167                                  private_key, MATCHING_BITS, &pow_cb, NULL);
168   GNUNET_TESTBED_operation_done (op);
169 }
170
171
172 /**
173  * Signature of a main function for a testcase.
174  *
175  * @param cls closure
176  * @param h the run handle
177  * @param num_peers number of peers in 'peers'
178  * @param peers handle to peers run in the testbed.  NULL upon timeout (see
179  *          GNUNET_TESTBED_test_run()).
180  * @param links_succeeded the number of overlay link connection attempts that
181  *          succeeded
182  * @param links_failed the number of overlay link connection attempts that
183  *          failed
184  * @see GNUNET_TESTBED_test_run()
185  */
186 static void
187 test_master (void *cls, struct GNUNET_TESTBED_RunHandle *h,
188              unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers,
189              unsigned int links_succeeded, unsigned int links_failed)
190 {
191   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
192               "%d peers started. %d links succeeded. %d links failed.\n",
193               num_peers, links_succeeded, links_failed);
194   GNUNET_assert (NUM_PEERS == num_peers);
195   GNUNET_assert (0 == links_failed);
196   /* Schedule test timeout */
197   shutdown_task =
198       GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &do_shutdown, NULL);
199   GNUNET_TESTBED_peer_get_information (peers[0],
200                                        GNUNET_TESTBED_PIT_CONFIGURATION,
201                                        &peer_info_cb, peers[0]);
202 }
203
204
205 int
206 main (int argc, char *argv[])
207 {
208   GNUNET_log_setup (testname, "INFO", NULL);
209   if (GNUNET_OK ==
210       GNUNET_TESTBED_test_run (testname, cfg_filename, NUM_PEERS, 0, NULL, NULL,
211                                &test_master, NULL))
212     return ok;
213   return 1;
214 }