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_ZKPVERIFIER_H_ 00021 #define __ALGORITHMS_CRYPTO_ZKPVERIFIER_H_ 00022 00023 #include "algorithms/crypto/eccfp.h" 00024 #include "algorithms/crypto/pmp.h" 00025 #include <string.h> 00026 00027 //how many times the protocol must execute 00028 #define REQ_ROUNDS 6 00029 00030 // Uncomment to enable Debug 00031 #define ENABLE_ZKP_DEBUG 00032 00033 /* 00034 PROTOCOL DESCRIPTION 00035 00036 Given an elliptive curve E over a field Fn , a generator point G in E/Fn and 00037 B in E/Fn Prover wants to prove in zero-knowledge that he knows x such that 00038 B =x*G 00039 00040 Protocol Steps 00041 00042 1. Prover generates random r and computes A = r*G 00043 2. Prover sends A to Verifier 00044 3. Verifier flips a coin and informs the Prover about the outcome 00045 4. In case of HEADS Prover sends r to Verifier who checks that r*G = A 00046 5. In case of TAILS Prover sends m = x + r to Verifier who checks that m*G=A+B 00047 00048 The above steps are repeated until Verifier is convinced that Prover knows 00049 x with probability 1-2^{-k} for k iterations. 00050 */ 00051 00052 namespace wiselib { 00053 00054 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug> 00055 class ZKPVerify 00056 { 00057 public: 00058 typedef OsModel_P OsModel; 00059 typedef Radio_P Radio; 00060 typedef Debug_P Debug; 00061 00062 typedef ZKPVerify<OsModel_P, Radio_P, Debug_P> self_t; 00063 typedef typename Radio::node_id_t node_id_t; 00064 typedef typename Radio::size_t size_t; 00065 typedef typename Radio::block_data_t block_data_t; 00066 typedef self_t* self_pointer_t; 00067 00070 ZKPVerify(); 00071 ~ZKPVerify(); 00073 00077 00078 //message types 00079 enum MsgHeaders { 00080 START_MSG = 200, 00081 COIN_MSG = 201, 00082 HEADS_MSG = 202, 00083 TAILS_MSG = 203, 00084 ACCEPT_MSG =204, 00085 REJECT_MSG =205, 00086 RESTART_MSG = 206 00087 }; 00088 00089 int init( Radio& radio, Debug& debug ) 00090 { 00091 radio_ = &radio; 00092 debug_ = &debug; 00093 return 0; 00094 } 00095 00096 inline int init(); 00097 inline int destruct(); 00098 00099 int enable_radio( void ); 00100 int disable_radio( void ); 00101 00103 void key_setup(Point *pubkey); 00104 bool coin_flip(uint8_t b); 00105 void verify_tails(); 00106 void verify_heads(); 00107 void final_decision(); 00108 00109 protected: 00110 void receive( node_id_t from, size_t len, block_data_t *data ); 00111 00112 private: 00113 00114 Radio& radio() 00115 { return *radio_; } 00116 00117 Debug& debug() 00118 { return *debug_; } 00119 00120 typename Radio::self_pointer_t radio_; 00121 typename Debug::self_pointer_t debug_; 00122 00123 //necessary class objects 00124 ECCFP eccfp; 00125 PMP pmp; 00126 00127 //# of rounds the protocol is executed 00128 uint8_t rounds; 00129 00130 //# of successful rounds 00131 uint8_t success_rounds; 00132 00133 //# of required rounds 00134 uint8_t required_rounds; 00135 00136 //public key that will be received by the prover in each round 00137 Point A; 00138 //private key that will be received by the prover in each round 00139 NN_DIGIT Valid[NUMWORDS]; 00140 00141 //public key that both prover and verifier know 00142 Point B; 00143 00144 }; 00145 00146 // ----------------------------------------------------------------------- 00147 template<typename OsModel_P, 00148 typename Radio_P, 00149 typename Debug_P> 00150 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00151 ZKPVerify() 00152 : radio_(0), 00153 debug_(0) 00154 {} 00155 00156 // ----------------------------------------------------------------------- 00157 template<typename OsModel_P, 00158 typename Radio_P, 00159 typename Debug_P> 00160 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00161 ~ZKPVerify() 00162 {} 00163 00164 //----------------------------------------------------------------------- 00165 template<typename OsModel_P, 00166 typename Radio_P, 00167 typename Debug_P> 00168 int 00169 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00170 init( void ) 00171 { 00172 enable_radio(); 00173 00174 return 0; 00175 } 00176 //----------------------------------------------------------------------------- 00177 template<typename OsModel_P, 00178 typename Radio_P, 00179 typename Debug_P> 00180 int 00181 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00182 destruct( void ) 00183 { 00184 return disable_radio(); 00185 } 00186 //--------------------------------------------------------------------------- 00187 template<typename OsModel_P, 00188 typename Radio_P, 00189 typename Debug_P> 00190 int 00191 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00192 enable_radio( void ) 00193 { 00194 #ifdef ENABLE_ZKP_DEBUG 00195 debug().debug( "ZKPProve: Boot for %i\n", radio().id() ); 00196 #endif 00197 00198 radio().enable_radio(); 00199 radio().template reg_recv_callback<self_t, &self_t::receive>( this ); 00200 00201 return 0; 00202 } 00203 //--------------------------------------------------------------------------- 00204 template<typename OsModel_P, 00205 typename Radio_P, 00206 typename Debug_P> 00207 int 00208 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00209 disable_radio( void ) 00210 { 00211 #ifdef ENABLE_ZKP_DEBUG 00212 debug().debug( "ZKPProve: Disable\n" ); 00213 #endif 00214 return -1; 00215 } 00216 //---------------------------------------------------------------------- 00217 template<typename OsModel_P, 00218 typename Radio_P, 00219 typename Debug_P> 00220 void 00221 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00222 key_setup( Point *pubkey ) { 00223 00224 #ifdef ENABLE_ZKP_DEBUG 00225 debug().debug("debug().Start ZKP Verifier on::%d \n", radio().id() ); 00226 #endif 00227 rounds=0; 00228 success_rounds=0; 00229 required_rounds=REQ_ROUNDS; 00230 00231 //public key available to prover and verifier 00232 eccfp.p_clear(&B); 00233 eccfp.p_copy(&B, pubkey); 00234 } 00235 00236 //---------------------------------------------------------------------------- 00237 template<typename OsModel_P, 00238 typename Radio_P, 00239 typename Debug_P> 00240 bool 00241 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00242 coin_flip(uint8_t b){ 00243 00244 block_data_t msg[2]; 00245 msg[0]=COIN_MSG; 00246 00247 //simulate the flip of a coin 00248 if(b % 2 ==0) 00249 { 00250 #ifdef ENABLE_ZKP_DEBUG 00251 debug().debug("debug::Coin flip was heads::%d \n", radio().id() ); 00252 #endif 00253 00254 msg[1]=0; 00255 //send the coin message 00256 radio().send( Radio::BROADCAST_ADDRESS, 2, msg); 00257 return true; 00258 } 00259 else 00260 { 00261 #ifdef ENABLE_ZKP_DEBUG 00262 debug().debug("debug::Coin flip was tails::%d \n", radio().id() ); 00263 #endif 00264 msg[1]=1; 00265 //send the coin message 00266 radio().send(Radio::BROADCAST_ADDRESS, 2, msg); 00267 return false; 00268 } 00269 } 00270 00271 //------------------------------------------------------------------------------------ 00272 template<typename OsModel_P, 00273 typename Radio_P, 00274 typename Debug_P> 00275 void 00276 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00277 verify_heads(){ 00278 00279 //check if the heads content is valid 00280 Point result; 00281 eccfp.p_clear(&result); 00282 00283 //check that A = rG 00284 eccfp.gen_public_key(&result, Valid); 00285 00286 //is the result correct??? 00287 if(eccfp.p_equal(&result, &A)== true) 00288 { 00289 success_rounds++; 00290 #ifdef ENABLE_ZKP_DEBUG 00291 debug().debug("debug::Heads content verified \n", radio().id() ); 00292 #endif 00293 } 00294 //check if required rounds are completed 00295 final_decision(); 00296 00297 } 00298 00299 //------------------------------------------------------------------------------------- 00300 template<typename OsModel_P, 00301 typename Radio_P, 00302 typename Debug_P> 00303 void 00304 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00305 verify_tails(){ 00306 00307 //check if tails content is valid 00308 Point result1; 00309 Point result2; 00310 eccfp.p_clear(&result1); 00311 eccfp.p_clear(&result2); 00312 00313 //check that rG = A+B 00314 eccfp.gen_public_key(&result1, Valid); 00315 eccfp.c_add_affine(&result2, &B, &A); 00316 00317 //is the result correct??? 00318 if(eccfp.p_equal(&result1, &result2)== true) 00319 { 00320 success_rounds++; 00321 #ifdef ENABLE_ZKP_DEBUG 00322 debug().debug("debug::Tails content verified \n", radio().id() ); 00323 #endif 00324 } 00325 00326 //check if required rounds are completed 00327 final_decision(); 00328 00329 } 00330 00331 //---------------------------------------------------------------------------------------- 00332 template<typename OsModel_P, 00333 typename Radio_P, 00334 typename Debug_P> 00335 void 00336 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00337 final_decision(){ 00338 00339 //are the required rounds accomplished? 00340 if(rounds!=required_rounds) 00341 { 00342 block_data_t buffer[1]; 00343 buffer[0]=RESTART_MSG; 00344 #ifdef ENABLE_ZKP_DEBUG 00345 debug().debug( "debug().Sending restart message to prover.\n", radio().id() ); 00346 #endif 00347 radio().send( Radio::BROADCAST_ADDRESS, 1, buffer); 00348 } 00349 else 00350 { 00351 //were the rounds all successful??the protocol accepts 00352 if(success_rounds==required_rounds) 00353 { 00354 #ifdef ENABLE_ZKP_DEBUG 00355 debug().debug("debug::Protocol finished with success.Secret Verified!!Prover HONEST!\n", radio().id() ); 00356 #endif 00357 //send to prover the accept message 00358 block_data_t buffer[1]; 00359 buffer[0]=ACCEPT_MSG; 00360 radio().send(Radio::BROADCAST_ADDRESS, 1, buffer); 00361 } 00362 //some rounds failed, the protocol rejects 00363 else 00364 { 00365 #ifdef ENABLE_ZKP_DEBUG 00366 debug().debug( "debug::Protocol finished without success.Secret NOT Verified!!Prover NOT HONEST\n", radio().id()); 00367 #endif 00368 block_data_t buffer[1]; 00369 buffer[0]=REJECT_MSG; 00370 radio().send(Radio::BROADCAST_ADDRESS, 1, buffer); 00371 } 00372 } 00373 } 00374 00375 //--------------------------------------------------------------------------- 00376 template<typename OsModel_P, 00377 typename Radio_P, 00378 typename Debug_P> 00379 void 00380 ZKPVerify<OsModel_P, Radio_P, Debug_P>:: 00381 receive( node_id_t from, size_t len, block_data_t *data ) { 00382 00383 if( from == radio().id() ) return; 00384 00385 if(data[0]==START_MSG) 00386 { 00387 #ifdef ENABLE_ZKP_DEBUG 00388 debug().debug( "debug::Received a starting message::%d \n", radio().id()); 00389 #endif 00390 rounds++; 00391 //get Verify point A from the message 00392 eccfp.p_clear(&A); 00393 00394 //convert octet received to point A 00395 eccfp.octet2point(&A, data+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1)); 00396 00397 //flip the coin 00398 coin_flip(rounds); 00399 } 00400 00401 if(data[0]==HEADS_MSG) 00402 { 00403 #ifdef ENABLE_ZKP_DEBUG 00404 debug().debug("debug::Received a heads content message::%d \n", radio().id()); 00405 #endif 00406 00407 //clear the private key and store it 00408 pmp.AssignZero(Valid, NUMWORDS); 00409 //decode the private key received 00410 pmp.Decode(Valid, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1); 00411 00412 //check if the heads content is valid 00413 verify_heads(); 00414 } 00415 00416 00417 if(data[0]==TAILS_MSG) 00418 { 00419 #ifdef ENABLE_ZKP_DEBUG 00420 debug().debug("debug::Received a tails content message::%d \n", radio().id() ); 00421 #endif 00422 00423 //clear the private key and store it 00424 pmp.AssignZero(Valid, NUMWORDS); 00425 //decode the private key received 00426 pmp.Decode(Valid, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1); 00427 00428 //check if the tails content is valid 00429 verify_tails(); 00430 } 00431 } 00432 00433 } //end of namespace 00434 00435 #endif /* ZKP_VERIFIER_H_ */ 00436