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_TESTOFDLEQUALITY_VERIFIER_H_ 00021 #define __ALGORITHMS_TESTOFDLEQUALITY_VERIFIER_H_ 00022 00023 #include "algorithms/crypto/eccfp.h" 00024 00025 #include <string.h> 00026 00027 //protocol needs to be executed for 1 round 00028 #define REQ_ROUNDS 1 00029 00030 // Uncomment to enable Debug 00031 #define ENABLE_TESTOFDLEQUALITY_DEBUG 00032 00033 /*PROTOCOL DESCRIPTION 00034 00035 Zero Knowledge Test of Discrete Logarithm Equality 00036 00037 Prover and Verifier agree on an elliptic curve E over a field Fn , a generator 00038 G in E/Fn and H in E/Fn . Prover claims he knows x such that B = x*G and 00039 C = x*H and wants to prove knowledge without revaling x. 00040 00041 Protocol Steps 00042 00043 1. Prover chooses random r and computes K = r*G and L = r*H 00044 2. Prover sends points K, L to Verifier 00045 3. Verifier chooses random c and sends c to Prover 00046 4. Prover computes m = r + cx and sends m to Verfier 00047 5. Verifier checks that m*G = (r + cx)*G = r*G + c*xG = K + cB 00048 6. Verifier checks that m*H = (r + cx)*H = r*H + c*xH = L + cC 00049 */ 00050 00051 namespace wiselib{ 00052 00053 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug> 00054 class TESTOFDLEQUALITYVerify 00055 { 00056 public: 00057 typedef OsModel_P OsModel; 00058 typedef Radio_P Radio; 00059 typedef Debug_P Debug; 00060 00061 typedef TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P> self_t; 00062 typedef typename Radio::node_id_t node_id_t; 00063 typedef typename Radio::size_t size_t; 00064 typedef typename Radio::block_data_t block_data_t; 00065 typedef self_t* self_pointer_t; 00066 00069 TESTOFDLEQUALITYVerify(); 00070 ~TESTOFDLEQUALITYVerify(); 00072 00076 00077 int init( Radio& radio, Debug& debug ) 00078 { 00079 radio_ = &radio; 00080 debug_ = &debug; 00081 return 0; 00082 } 00083 00084 inline int init(); 00085 inline int destruct(); 00086 00087 int enable_radio( void ); 00088 int disable_radio( void ); 00089 00090 //message types 00091 enum MsgHeaders { 00092 START_MSG = 200, 00093 HASH_MSG = 201, 00094 CONT_MSG = 202, 00095 ACCEPT_MSG = 203, 00096 REJECT_MSG = 204 00097 }; 00098 00100 void key_setup(Point *pubkey, Point *pubkey1, Point *pubkey2); 00101 void generate_random(); 00102 bool verify(); 00103 bool verify_msg(); 00104 void final_decision(); 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 //necessary class objects 00121 ECCFP eccfp; 00122 PMP pmp; 00123 00124 //# of rounds (used for seeding and generating the random value) 00125 uint8_t rounds; 00126 00127 //# of successfull rounds 00128 uint8_t success_rounds; 00129 00130 //# of required rounds 00131 uint8_t required_rounds; 00132 00133 //the random private key calculated on the point received by the prover 00134 NN_DIGIT c[NUMWORDS]; 00135 00136 //private key that will be received by the prover in each round 00137 NN_DIGIT Valid[NUMWORDS]; 00138 00139 //public key that both prover and verifier know 00140 Point B; 00141 Point P; 00142 Point C; 00143 00144 //public key A to be received by the prover 00145 Point K; 00146 Point L; 00147 00148 //public key Check for the verifications 00149 Point Check; 00150 Point Check2; 00151 00152 }; 00153 00154 // ----------------------------------------------------------------------- 00155 template<typename OsModel_P, 00156 typename Radio_P, 00157 typename Debug_P> 00158 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00159 TESTOFDLEQUALITYVerify() 00160 : radio_(0), 00161 debug_(0) 00162 {} 00163 00164 // ----------------------------------------------------------------------- 00165 template<typename OsModel_P, 00166 typename Radio_P, 00167 typename Debug_P> 00168 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00169 ~TESTOFDLEQUALITYVerify() 00170 {} 00171 00172 //----------------------------------------------------------------------- 00173 template<typename OsModel_P, 00174 typename Radio_P, 00175 typename Debug_P> 00176 int 00177 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00178 init( void ) 00179 { 00180 enable_radio(); 00181 return 0; 00182 } 00183 //----------------------------------------------------------------------------- 00184 template<typename OsModel_P, 00185 typename Radio_P, 00186 typename Debug_P> 00187 int 00188 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00189 destruct( void ) 00190 { 00191 return disable_radio(); 00192 } 00193 //--------------------------------------------------------------------------- 00194 template<typename OsModel_P, 00195 typename Radio_P, 00196 typename Debug_P> 00197 int 00198 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00199 enable_radio( void ) 00200 { 00201 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00202 debug().debug( "ZKP Test of Dl Verify: Boot for %i\n", radio().id() ); 00203 #endif 00204 00205 radio().enable_radio(); 00206 radio().template reg_recv_callback<self_t, &self_t::receive>( this ); 00207 00208 return 0; 00209 } 00210 //--------------------------------------------------------------------------- 00211 template<typename OsModel_P, 00212 typename Radio_P, 00213 typename Debug_P> 00214 int 00215 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00216 disable_radio( void ) 00217 { 00218 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00219 debug().debug( "ZKP Test of Dl Prove: Disable\n" ); 00220 #endif 00221 return -1; 00222 } 00223 //---------------------------------------------------------------------- 00224 template<typename OsModel_P, 00225 typename Radio_P, 00226 typename Debug_P> 00227 void 00228 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00229 key_setup( Point *pubkey, Point *pubkey1, Point *pubkey2 ) { 00230 00231 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00232 debug().debug("Debug::Start Test of DL equality Interactive ZKP Verifier on::%d \n", radio().id() ); 00233 #endif 00234 rounds=89; 00235 success_rounds=0; 00236 required_rounds=REQ_ROUNDS; 00237 00238 //get first public key available to prover and verifier 00239 eccfp.p_clear(&B); 00240 eccfp.p_copy(&B, pubkey); 00241 00242 //second generator P 00243 eccfp.p_clear(&P); 00244 eccfp.p_copy(&P, pubkey1); 00245 00246 //get second public key C with m as EC discrete log (C=mP) 00247 eccfp.p_clear(&C); 00248 eccfp.p_copy(&C, pubkey2); 00249 } 00250 00251 //------------------------------------------------------------------------------------ 00252 template<typename OsModel_P, 00253 typename Radio_P, 00254 typename Debug_P> 00255 void 00256 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00257 generate_random(){ 00258 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00259 debug().debug("Debug::Generating random number c!\n", radio().id() ); 00260 #endif 00261 00262 //clear the private key c 00263 pmp.AssignZero(c, NUMWORDS); 00264 //and generate random number c 00265 eccfp.gen_private_key(c, rounds); 00266 00267 //send message with c to prover 00268 uint8_t buffer[KEYDIGITS*NN_DIGIT_LEN+2]; 00269 buffer[0]=HASH_MSG; 00270 //place key to buffer after encoding to octet 00271 pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, c, NUMWORDS); 00272 00273 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00274 debug().debug( "Debug::Finished generating random number c!Sending c to prover. ::%d \n", radio().id() ); 00275 #endif 00276 00277 radio().send( Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN+2, buffer); 00278 } 00279 00280 //------------------------------------------------------------------------------------ 00281 template<typename OsModel_P, 00282 typename Radio_P, 00283 typename Debug_P> 00284 bool 00285 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00286 verify(){ 00287 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00288 debug().debug("Debug::Starting first Verification!\n", radio().id() ); 00289 #endif 00290 00291 //verifier checks that sG = K + cB 00292 Point result; 00293 Point result1; 00294 eccfp.p_clear(&result); 00295 eccfp.p_clear(&result1); 00296 eccfp.p_clear(&Check); 00297 00298 //compute sG 00299 eccfp.gen_public_key(&result, Valid); 00300 00301 //compute cB 00302 eccfp.c_mul(&result1, &B, c); 00303 00304 //compute K + cB 00305 eccfp.c_add_affine(&Check, &K, &result1); 00306 00307 //is the result correct??? 00308 //compare point sG with point K+cB 00309 if(eccfp.p_equal(&result, &Check)==true) 00310 { 00311 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00312 debug().debug("Debug::First check SUCCESS!\n", radio().id() ); 00313 #endif 00314 verify_msg(); 00315 return true; 00316 } 00317 else 00318 { 00319 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00320 debug().debug( "Debug::First check FAIL!\n", radio().id() ); 00321 #endif 00322 final_decision(); 00323 return false; 00324 } 00325 } 00326 00327 //------------------------------------------------------------------------------------- 00328 template<typename OsModel_P, 00329 typename Radio_P, 00330 typename Debug_P> 00331 bool 00332 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00333 verify_msg(){ 00334 00335 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00336 debug().debug("Debug::Starting second verification!\n", radio().id() ); 00337 #endif 00338 //verifier checks that sP = L + cC 00339 Point result; 00340 Point result1; 00341 eccfp.p_clear(&result); 00342 eccfp.p_clear(&result1); 00343 eccfp.p_clear(&Check2); 00344 00345 //compute sP 00346 eccfp.c_mul(&result, &P, Valid); 00347 00348 //compute cC 00349 eccfp.c_mul(&result1, &C, c); 00350 00351 //compute L + cC 00352 eccfp.c_add_affine(&Check2, &L, &result1); 00353 00354 //is the result correct??? 00355 //compare sP with L + cC 00356 if(eccfp.p_equal(&Check2, &result)==true) 00357 { 00358 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00359 debug().debug( "Debug::Second check SUCCESS!\n", radio().id()); 00360 #endif 00361 success_rounds++; 00362 final_decision(); 00363 return true; 00364 } 00365 else 00366 { 00367 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00368 debug().debug( "Debug::Second check FAIL!\n", radio().id() ); 00369 #endif 00370 final_decision(); 00371 return false; 00372 } 00373 } 00374 00375 //---------------------------------------------------------------------------------------- 00376 template<typename OsModel_P, 00377 typename Radio_P, 00378 typename Debug_P> 00379 void 00380 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00381 final_decision(){ 00382 00383 //were the round successful??the protocol accepts 00384 if(success_rounds==required_rounds) 00385 { 00386 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00387 debug().debug("Debug::Protocol finished with success.Secret Verified!!Prover HONEST!\n", radio().id() ); 00388 #endif 00389 //send to prover the accept message 00390 block_data_t buffer[1]; 00391 buffer[0]=ACCEPT_MSG; 00392 radio().send(Radio::BROADCAST_ADDRESS,1,buffer); 00393 } 00394 //the round failed, the protocol rejects 00395 else 00396 { 00397 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00398 debug().debug("Debug::Protocol finished without success.Secret NOT Verified!!Prover NOT HONEST\n", radio().id() ); 00399 #endif 00400 block_data_t buffer[1]; 00401 buffer[0]=REJECT_MSG; 00402 radio().send(Radio::BROADCAST_ADDRESS,1,buffer); 00403 } 00404 } 00405 00406 //--------------------------------------------------------------------------- 00407 template<typename OsModel_P, 00408 typename Radio_P, 00409 typename Debug_P> 00410 void 00411 TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>:: 00412 receive( node_id_t from, size_t len, block_data_t *data ) { 00413 00414 if( from == radio().id() ) return; 00415 00416 if(data[0]==START_MSG) 00417 { 00418 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00419 debug().debug("Debug::Received a starting message::%d \n", radio().id()); 00420 #endif 00421 00422 //get points K and L 00423 eccfp.p_clear(&K); 00424 eccfp.p_clear(&L); 00425 //copy the two keys received after decoding 00426 eccfp.octet2point(&K, data+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1)); 00427 eccfp.octet2point(&L, data+2*(KEYDIGITS * NN_DIGIT_LEN +1)+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1)); 00428 00429 //call the task to compute random c 00430 generate_random(); 00431 } 00432 00433 if(data[0]==CONT_MSG) 00434 { 00435 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00436 debug().debug("Debug::Received a continue message::%d \n", radio().id() ); 00437 #endif 00438 00439 //get private key x 00440 pmp.AssignZero(Valid, NUMWORDS); 00441 //decode the private key received 00442 pmp.Decode(Valid, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1); 00443 00444 //call verify 00445 verify(); 00446 00447 } 00448 00449 } 00450 00451 } //end of wiselib namespace 00452 00453 #endif /* TESTOFDLEQUALITY_VERIFIER_H_ */