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