Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 00020 #ifndef __ALGORITHMS_CRYPTO_ZKPPROVER_H_ 00021 #define __ALGORITHMS_CRYPTO_ZKPPROVER_H_ 00022 00023 #include "algorithms/crypto/eccfp.h" 00024 #include "algorithms/crypto/pmp.h" 00025 #include <string.h> 00026 00027 //Uncomment to enable Debug 00028 #define ENABLE_ZKP_DEBUG 00029 00030 /* 00031 PROTOCOL DESCRIPTION 00032 00033 Given an elliptive curve E over a field Fn , a generator point G in E/Fn and 00034 B in E/Fn Prover wants to prove in zero-knowledge that he knows x such that 00035 B =x*G 00036 00037 Protocol Steps 00038 00039 1. Prover generates random r and computes A = r*G 00040 2. Prover sends A to Verifier 00041 3. Verifier flips a coin and informs the Prover about the outcome 00042 4. In case of HEADS Prover sends r to Verifier who checks that r*G = A 00043 5. In case of TAILS Prover sends m = x + r to Verifier who checks that m*G=A+B 00044 00045 The above steps are repeated until Verifier is convinced that Prover knows 00046 x with probability 1-2^{-k} for k iterations. 00047 */ 00048 00049 namespace wiselib { 00050 00051 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug> 00052 class ZKPProve 00053 { 00054 public: 00055 typedef OsModel_P OsModel; 00056 typedef Radio_P Radio; 00057 typedef Debug_P Debug; 00058 00059 typedef ZKPProve<OsModel_P, Radio_P, Debug_P> self_t; 00060 typedef typename Radio::node_id_t node_id_t; 00061 typedef typename Radio::size_t size_t; 00062 typedef typename Radio::block_data_t block_data_t; 00063 typedef self_t* self_pointer_t; 00064 00067 ZKPProve(); 00068 ~ZKPProve(); 00070 00071 int init( Radio& radio, Debug& debug ) 00072 { 00073 radio_ = &radio; 00074 debug_ = &debug; 00075 return 0; 00076 } 00077 00078 inline int init(); 00079 inline int destruct(); 00080 00081 int enable_radio( void ); 00082 int disable_radio( void ); 00083 00087 00088 //message types 00089 enum MsgHeaders { 00090 START_MSG = 200, 00091 COIN_MSG = 201, 00092 HEADS_MSG = 202, 00093 TAILS_MSG = 203, 00094 ACCEPT_MSG =204, 00095 REJECT_MSG =205, 00096 RESTART_MSG = 206 00097 }; 00098 00100 void key_setup(NN_DIGIT *privkey , Point *pubkey); 00101 void start_proof(); 00102 void send_tails(); 00103 void send_heads(); 00104 00105 00106 protected: 00107 void receive( node_id_t from, size_t len, block_data_t *data ); 00108 00109 private: 00110 00111 Radio& radio() 00112 { return *radio_; } 00113 00114 Debug& debug() 00115 { return *debug_; } 00116 00117 typename Radio::self_pointer_t radio_; 00118 typename Debug::self_pointer_t debug_; 00119 00120 //eccfp class object 00121 ECCFP eccfp; 00122 PMP pmp; 00123 00124 //rounds of the protocol used for seeding the rand function 00125 uint8_t rounds; 00126 00127 //private key that only the prover knows 00128 NN_DIGIT m[NUMWORDS]; 00129 00130 //public key that both prover and verifier know 00131 Point B; 00132 00133 //private key r that is generated in every round and 00134 //its corresponding public key 00135 NN_DIGIT r[NUMWORDS]; 00136 Point Verify; 00137 00138 }; 00139 00140 // ----------------------------------------------------------------------- 00141 template<typename OsModel_P, 00142 typename Radio_P, 00143 typename Debug_P> 00144 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00145 ZKPProve() 00146 : radio_(0), 00147 debug_(0) 00148 {} 00149 00150 // ----------------------------------------------------------------------- 00151 template<typename OsModel_P, 00152 typename Radio_P, 00153 typename Debug_P> 00154 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00155 ~ZKPProve() 00156 {} 00157 //----------------------------------------------------------------------- 00158 template<typename OsModel_P, 00159 typename Radio_P, 00160 typename Debug_P> 00161 int 00162 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00163 init( void ) 00164 { 00165 enable_radio(); 00166 00167 return 0; 00168 } 00169 //----------------------------------------------------------------------------- 00170 template<typename OsModel_P, 00171 typename Radio_P, 00172 typename Debug_P> 00173 int 00174 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00175 destruct( void ) 00176 { 00177 return disable_radio(); 00178 } 00179 //--------------------------------------------------------------------------- 00180 template<typename OsModel_P, 00181 typename Radio_P, 00182 typename Debug_P> 00183 int 00184 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00185 enable_radio( void ) 00186 { 00187 #ifdef ENABLE_ZKP_DEBUG 00188 debug().debug( "ZKPProve: Boot for %i\n", radio().id() ); 00189 #endif 00190 00191 radio().enable_radio(); 00192 radio().template reg_recv_callback<self_t, &self_t::receive>( this ); 00193 00194 return 0; 00195 } 00196 //--------------------------------------------------------------------------- 00197 template<typename OsModel_P, 00198 typename Radio_P, 00199 typename Debug_P> 00200 int 00201 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00202 disable_radio( void ) 00203 { 00204 #ifdef ENABLE_ZKP_DEBUG 00205 debug().debug( "ZKPProve: Disable\n" ); 00206 #endif 00207 return -1; 00208 } 00209 //---------------------------------------------------------------------------- 00210 template<typename OsModel_P, 00211 typename Radio_P, 00212 typename Debug_P> 00213 void 00214 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00215 key_setup( NN_DIGIT *privkey , Point *pubkey ) 00216 { 00217 rounds=0; 00218 00219 //copy keys to local variables 00220 //prover's private secret key 00221 pmp.AssignZero(m, NUMWORDS); 00222 pmp.Assign(m, privkey, NUMWORDS); 00223 00224 //public key available to prover and verifier 00225 eccfp.p_clear(&B); 00226 eccfp.p_copy(&B, pubkey); 00227 } 00228 00229 //--------------------------------------------------------------------------- 00230 template<typename OsModel_P, 00231 typename Radio_P, 00232 typename Debug_P> 00233 void 00234 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00235 start_proof( void ) { 00236 00237 #ifdef ENABLE_ZKP_DEBUG 00238 debug().debug("Debug::Start ZKP Prover on::%d \n", radio().id() ); 00239 #endif 00240 00241 rounds++; 00242 //clear the private key and public key 00243 pmp.AssignZero(r, NUMWORDS); 00244 eccfp.p_clear(&Verify); 00245 00246 #ifdef ENABLE_ZKP_DEBUG 00247 debug().debug("Debug::Generating random r and computing A=rG ::%d \n", radio().id() ); 00248 #endif 00249 00250 //generate random r and compute pubKey A=rG 00251 eccfp.gen_private_key(r, rounds); 00252 eccfp.gen_public_key(&Verify, r); 00253 00254 //place the verify key in the buffer and send the message 00255 block_data_t msg[2*(KEYDIGITS*NN_DIGIT_LEN + 1) + 1]; 00256 msg[0]=START_MSG; 00257 00258 //convert point to octet 00259 eccfp.point2octet(msg+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify, FALSE); 00260 00261 #ifdef ENABLE_ZKP_DEBUG 00262 debug().debug( "Debug::Sending start message to verifier! ::%d \n", radio().id() ); 00263 #endif 00264 radio().send( Radio::BROADCAST_ADDRESS, 2*(KEYDIGITS*NN_DIGIT_LEN +1) +1, msg); 00265 } 00266 00267 //------------------------------------------------------------------------ 00268 template<typename OsModel_P, 00269 typename Radio_P, 00270 typename Debug_P> 00271 void 00272 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00273 send_tails( void ) { 00274 00275 #ifdef ENABLE_ZKP_DEBUG 00276 debug().debug( "Debug::Creating tails content::%d \n", radio().id() ); 00277 #endif 00278 00279 //if the coin was tails the prover creates x= m + r and sends to verifier 00280 NN_DIGIT x[NUMWORDS]; 00281 pmp.AssignZero(x, NUMWORDS); 00282 pmp.ModAdd(x, r, m, param.r, NUMWORDS); 00283 00284 //if it is tails send to verifier m+r 00285 block_data_t buffer[KEYDIGITS*NN_DIGIT_LEN + 2]; 00286 buffer[0]=TAILS_MSG; 00287 00288 //convert x to octet 00289 pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, x, NUMWORDS); 00290 00291 #ifdef ENABLE_ZKP_DEBUG 00292 debug().debug( "Debug::Sending Tails Content::%d \n", radio().id() ); 00293 #endif 00294 radio().send(Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN + 2, buffer); 00295 } 00296 00297 //----------------------------------------------------------------------------- 00298 template<typename OsModel_P, 00299 typename Radio_P, 00300 typename Debug_P> 00301 void 00302 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00303 send_heads( void ) { 00304 00305 #ifdef ENABLE_ZKP_DEBUG 00306 debug().debug( "Debug::Creating heads content::%d \n", radio().id() ); 00307 #endif 00308 //if the coin was heads prover sends to verifier the private key r 00309 block_data_t buffer[KEYDIGITS*NN_DIGIT_LEN + 2]; 00310 buffer[0]=HEADS_MSG; 00311 //convert r to octet 00312 pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, r, NUMWORDS); 00313 00314 #ifdef ENABLE_ZKP_DEBUG 00315 debug().debug("Debug::Sending Heads Content::%d \n", radio().id() ); 00316 #endif 00317 radio().send( Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN + 2, buffer); 00318 00319 } 00320 00321 //--------------------------------------------------------------------------- 00322 template<typename OsModel_P, 00323 typename Radio_P, 00324 typename Debug_P> 00325 void 00326 ZKPProve<OsModel_P, Radio_P, Debug_P>:: 00327 receive( node_id_t from, size_t len, block_data_t *data ) { 00328 00329 if( from == radio().id( ) ) return; 00330 00331 if(data[0]==COIN_MSG) 00332 { 00333 #ifdef ENABLE_ZKP_DEBUG 00334 debug().debug( "Debug::Received a coin message::%d \n", radio().id()); 00335 #endif 00336 if(data[1]==1) 00337 { 00338 send_tails(); 00339 } 00340 else 00341 { 00342 send_heads(); 00343 } 00344 } 00345 00346 if(data[0]==RESTART_MSG) 00347 { 00348 #ifdef ENABLE_ZKP_DEBUG 00349 debug().debug( "Debug::Received a restart message. Re-starting the steps.::%d \n", radio().id()); 00350 #endif 00351 start_proof(); 00352 } 00353 00354 if(data[0]==ACCEPT_MSG) 00355 { 00356 #ifdef ENABLE_ZKP_DEBUG 00357 debug().debug( "Debug::I got ACCEPTED from the verifier.YESSS!::%d \n", radio().id()); 00358 #endif 00359 } 00360 00361 if(data[0]==REJECT_MSG) 00362 { 00363 #ifdef ENABLE_ZKP_DEBUG 00364 debug().debug( "Debug::I got REJECTED from the verifier.NOOO!::%d \n", radio().id()); 00365 #endif 00366 } 00367 00368 } 00369 00370 } //end of wiselib namespace 00371 00372 #endif /* ZKP_PROVER_H_ */