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_ZKPOFSINGLEBIT_PROVER_H_ 00021 #define __ALGORITHMS_CRYPTO_ZKPOFSINGLEBIT_PROVER_H_ 00022 00023 #include "algorithms/crypto/eccfp.h" 00024 #include <string.h> 00025 00026 //Uncomment to enable Debug 00027 #define ENABLE_ZKPOFSINGLEBIT_DEBUG 00028 00029 /* PROTOCOL DESCRIPTION 00030 00031 Zero Knowledge Proof of Single Bit 00032 00033 Prover and Verifier agree on an elliptic curve E over a field Fn , a generator 00034 G in E/Fn and H in E/Fn . Prover knows x and h such that B = x*G + h*H 00035 where h = +1 or -1.He wishes to convince Verifier that he really does know x and 00036 that h really is {+,-}1 without revealing x nor the sign bit. 00037 00038 Protocol Steps 00039 00040 1. Prover generates random s, d, w 00041 2. Prover computes A = s*G - d*(B+hH) and C = w*G 00042 3. If h = -1 Prover swaps(A,C) and sends A,C to Verifier 00043 4. Verifier generates random c and sends c to Prover 00044 5. Prover computes e = c-d and t = w + xe 00045 6. If h =-1 Prover swaps(d,e) and swaps(s,t) 00046 7. Prover sends to Verifier d, e, s, t 00047 8. Verifier checks that e + d = c, s*G = A + d(B + H) 00048 and that t*G = C + e(B-H) 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 ZKPOFSINGLEBITProve 00055 { 00056 public: 00057 typedef OsModel_P OsModel; 00058 typedef Radio_P Radio; 00059 typedef Debug_P Debug; 00060 00061 typedef ZKPOFSINGLEBITProve<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 ZKPOFSINGLEBITProve(); 00070 ~ZKPOFSINGLEBITProve(); 00072 00076 00077 //message types 00078 enum MsgHeaders { 00079 START_MSG = 200, 00080 RAND_MSG = 201, 00081 CONT_MSG = 202, 00082 ACCEPT_MSG = 203, 00083 REJECT_MSG = 204 00084 }; 00085 00086 int init( Radio& radio, Debug& debug ) 00087 { 00088 radio_ = &radio; 00089 debug_ = &debug; 00090 return 0; 00091 } 00092 00093 inline int init(); 00094 inline int destruct(); 00095 00096 int enable_radio( void ); 00097 int disable_radio( void ); 00098 00100 void key_setup(NN_DIGIT *privkey, Point *pubkey1, Point *pubkey2, int8_t sign); 00101 void start_proof(); 00102 void send_key(); 00103 void swap_keys(NN_DIGIT *a, NN_DIGIT *b); 00104 void swap_points(Point *P1, Point *P2); 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 //rounds of the protocol used for seeding the rand function 00125 uint8_t rounds; 00126 00127 //sign bit only the prover knows 00128 int8_t h; 00129 00130 //private key that only the prover knows 00131 NN_DIGIT m[NUMWORDS]; 00132 00133 //private keys to be generated by prover 00134 NN_DIGIT s[NUMWORDS]; 00135 NN_DIGIT d[NUMWORDS]; 00136 NN_DIGIT w[NUMWORDS]; 00137 00138 //public keys that both prover and verifier know 00139 //Point B; 00140 Point P; 00141 Point C; 00142 00143 //public keys to send to verifier with the first message 00144 Point Verify; 00145 Point Verify2; 00146 00147 //the random private key that will be received from verifier 00148 NN_DIGIT c[NUMWORDS]; 00149 00150 //data that will be sent to the verifier 00151 NN_DIGIT x[NUMWORDS]; 00152 00153 }; 00154 00155 // ----------------------------------------------------------------------- 00156 template<typename OsModel_P, 00157 typename Radio_P, 00158 typename Debug_P> 00159 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00160 ZKPOFSINGLEBITProve() 00161 :radio_(0), 00162 debug_(0) 00163 {} 00164 00165 // ----------------------------------------------------------------------- 00166 template<typename OsModel_P, 00167 typename Radio_P, 00168 typename Debug_P> 00169 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00170 ~ZKPOFSINGLEBITProve() 00171 {} 00172 00173 //----------------------------------------------------------------------- 00174 template<typename OsModel_P, 00175 typename Radio_P, 00176 typename Debug_P> 00177 int 00178 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00179 init( void ) 00180 { 00181 enable_radio(); 00182 return 0; 00183 } 00184 //----------------------------------------------------------------------------- 00185 template<typename OsModel_P, 00186 typename Radio_P, 00187 typename Debug_P> 00188 int 00189 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00190 destruct( void ) 00191 { 00192 return disable_radio(); 00193 } 00194 //--------------------------------------------------------------------------- 00195 template<typename OsModel_P, 00196 typename Radio_P, 00197 typename Debug_P> 00198 int 00199 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00200 enable_radio( void ) 00201 { 00202 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00203 debug().debug( "ZKP Of Single Bit Prove: Boot for %i\n", radio().id() ); 00204 #endif 00205 00206 radio().enable_radio(); 00207 radio().template reg_recv_callback<self_t, &self_t::receive>( this ); 00208 00209 return 0; 00210 } 00211 //--------------------------------------------------------------------------- 00212 template<typename OsModel_P, 00213 typename Radio_P, 00214 typename Debug_P> 00215 int 00216 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00217 disable_radio( void ) 00218 { 00219 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00220 debug().debug( "ZKP of single bit Prove: Disable\n" ); 00221 #endif 00222 return -1; 00223 } 00224 00225 //----------------------------------------------------------------------- 00226 template<typename OsModel_P, 00227 typename Radio_P, 00228 typename Debug_P> 00229 void 00230 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00231 key_setup( NN_DIGIT *privkey, Point *pubkey1, Point *pubkey2, int8_t sign ) { 00232 00233 rounds=1; 00234 00235 h=sign; //get the sign 00236 00237 //prover's private secret key 00238 pmp.AssignZero(m, NUMWORDS); 00239 pmp.Assign(m, privkey, NUMWORDS); 00240 00241 //get generator P 00242 eccfp.p_clear(&P); 00243 eccfp.p_copy(&P, pubkey1); 00244 00245 //get the final point C = mG + hP 00246 eccfp.p_clear(&C); 00247 eccfp.p_copy(&C, pubkey2); 00248 } 00249 //-------------------------------------------------------------------------- 00250 template<typename OsModel_P, 00251 typename Radio_P, 00252 typename Debug_P> 00253 void 00254 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00255 swap_keys( NN_DIGIT *a, NN_DIGIT *b ) 00256 { 00257 NN_DIGIT mid[NUMWORDS]; 00258 pmp.AssignZero(mid, NUMWORDS); 00259 pmp.Assign(mid, a, NUMWORDS); 00260 pmp.Assign(a, b, NUMWORDS ); 00261 pmp.Assign(b, mid, NUMWORDS); 00262 } 00263 //-------------------------------------------------------------------------- 00264 template<typename OsModel_P, 00265 typename Radio_P, 00266 typename Debug_P> 00267 void 00268 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00269 swap_points( Point * P1, Point * P2 ) 00270 { 00271 Point Mid; 00272 eccfp.p_clear(&Mid); 00273 eccfp.p_copy(&Mid, P1); 00274 eccfp.p_copy(P1, P2); 00275 eccfp.p_copy(P2, &Mid); 00276 } 00277 //--------------------------------------------------------------------------- 00278 template<typename OsModel_P, 00279 typename Radio_P, 00280 typename Debug_P> 00281 void 00282 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00283 start_proof( void ) { 00284 00285 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00286 debug().debug("Debug::Starting ZKP of Single Bit Prover on::%d \n", radio().id() ); 00287 #endif 00288 00289 //if the protocol is booting generate random s,d,w 00290 rounds++; 00291 00292 //clear private keys 00293 pmp.AssignZero(s, NUMWORDS); 00294 pmp.AssignZero(d, NUMWORDS); 00295 pmp.AssignZero(w, NUMWORDS); 00296 00297 //generate private keys 00298 eccfp.gen_private_key(s, rounds); 00299 eccfp.gen_private_key(d, rounds+1); 00300 eccfp.gen_private_key(w, rounds+11); 00301 00302 //compute Verify = sG - d(B+hH) 00303 eccfp.p_clear(&Verify); 00304 00305 Point result; 00306 Point result1; 00307 Point result2; 00308 Point result3; 00309 00310 eccfp.p_clear(&result); 00311 eccfp.p_clear(&result1); 00312 eccfp.p_clear(&result2); 00313 eccfp.p_clear(&result3); 00314 00315 //first compute sG 00316 eccfp.gen_public_key(&result, s); 00317 00318 //then compute Verify2 = wG 00319 eccfp.p_clear(&Verify2); 00320 eccfp.gen_public_key(&Verify2, w); 00321 00322 if(h == 1) 00323 { 00324 //in case where h = +1 no swap is needed 00325 00326 //compute B+H 00327 eccfp.c_add_affine(&result1, &C, &P); 00328 //compute d(B+H) 00329 eccfp.c_mul(&result2, &result1, d); 00330 //compute Verify = sG -d(B+H) 00331 //subtraction in F_{p} if P=(x,y) then -P=(x,-y) 00332 pmp.ModNeg(result2.y, result2.y, param.p, NUMWORDS); 00333 eccfp.c_add_affine(&Verify, &result, &result2); 00334 } 00335 else 00336 { 00337 //in case where h=-1 swap is needed 00338 00339 //compute B-H 00340 eccfp.p_copy(&result1, &P); 00341 pmp.ModNeg(result1.y, result1.y, param.p, NUMWORDS); 00342 eccfp.c_add_affine(&result2, &C, &result1); 00343 //compute d(B-H) 00344 eccfp.c_mul(&result3, &result2, d); 00345 //compute Verify = sG -d(B-H) 00346 //subtraction in F_{p} if P=(x,y) then -P=(x,-y) 00347 pmp.ModNeg(result3.y, result3.y, param.p, NUMWORDS); 00348 eccfp.c_add_affine(&Verify, &result, &result3); 00349 00350 swap_points(&Verify, &Verify2); 00351 } 00352 00353 //send the message with K,L to verifier 00354 block_data_t buffer[4*(KEYDIGITS*NN_DIGIT_LEN+1)+1]; 00355 buffer[0]=START_MSG; 00356 //convert first point to octet and place to buffer 00357 eccfp.point2octet(buffer+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify, FALSE); 00358 //convert second point to octet and place to buffer 00359 eccfp.point2octet(buffer+2*(KEYDIGITS*NN_DIGIT_LEN+1)+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify2, FALSE); 00360 00361 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00362 debug().debug("Debug::Finished calculations!Sending 2 verify keys to verifier. ::%d \n", radio().id()); 00363 #endif 00364 radio().send(Radio::BROADCAST_ADDRESS, 4*(KEYDIGITS*NN_DIGIT_LEN+1)+1 , buffer); 00365 } 00366 00367 //------------------------------------------------------------------------ 00368 template<typename OsModel_P, 00369 typename Radio_P, 00370 typename Debug_P> 00371 void 00372 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00373 send_key( void ) { 00374 00375 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00376 debug().debug("Debug::Creating the new private keys ::%d \n", radio().id() ); 00377 #endif 00378 00379 //prover computes e,s,t 00380 NN_DIGIT e[NUMWORDS]; 00381 NN_DIGIT t[NUMWORDS]; 00382 00383 //clear private keys e,t 00384 pmp.AssignZero(e, NUMWORDS); 00385 pmp.AssignZero(t, NUMWORDS); 00386 00387 //compute e = c - d 00388 pmp.ModSub(e, c, d, param.r, NUMWORDS); 00389 //pmp.Mod(e, e, NUMWORDS, param.r, NUMWORDS); 00390 00391 NN_DIGIT mid2[NUMWORDS]; 00392 pmp.AssignZero(mid2, NUMWORDS); 00393 00394 //first compute me 00395 pmp.ModMult(mid2, m, e, param.r, NUMWORDS); 00396 //then add t = w + me 00397 pmp.ModAdd(t, w, mid2, param.r, NUMWORDS); 00398 00399 //in case of -1 swap d <-> e and s <-> t 00400 if(h == -1) 00401 { 00402 swap_keys(d, e); 00403 swap_keys(s, t); 00404 } 00405 00406 //send the message with d,e,s,t to verifier 00407 block_data_t buffer[4*(KEYDIGITS*NN_DIGIT_LEN+1)+1]; 00408 buffer[0]=CONT_MSG; 00409 00410 //convert keys to octet and place to buffer 00411 pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, d, NUMWORDS); 00412 pmp.Encode(buffer+KEYDIGITS * NN_DIGIT_LEN +1+1, KEYDIGITS * NN_DIGIT_LEN +1, e, NUMWORDS); 00413 pmp.Encode(buffer+2*(KEYDIGITS * NN_DIGIT_LEN +1)+1, KEYDIGITS * NN_DIGIT_LEN +1, s, NUMWORDS); 00414 pmp.Encode(buffer+3*(KEYDIGITS * NN_DIGIT_LEN +1)+1, KEYDIGITS * NN_DIGIT_LEN +1, t, NUMWORDS); 00415 00416 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00417 debug().debug("Debug::Sending the new private keys d,e,s,t to verifier::%d \n", radio().id() ); 00418 #endif 00419 radio().send(Radio::BROADCAST_ADDRESS, 4*(KEYDIGITS*NN_DIGIT_LEN+1)+1, buffer); 00420 } 00421 00422 //--------------------------------------------------------------------------- 00423 template<typename OsModel_P, 00424 typename Radio_P, 00425 typename Debug_P> 00426 void 00427 ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>:: 00428 receive( node_id_t from, size_t len, block_data_t *data ) { 00429 00430 if( from == radio().id() ) return; 00431 00432 if(data[0]==RAND_MSG) 00433 { 00434 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00435 debug().debug("Debug::Received a random message. Calling the send_key task.::%d \n", radio().id() ); 00436 #endif 00437 00438 //clear the hash and decode the random c received from verifier 00439 pmp.AssignZero(c, NUMWORDS); 00440 pmp.Decode(c, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1); 00441 00442 //calling the send_key task 00443 send_key(); 00444 } 00445 00446 if(data[0]==ACCEPT_MSG) 00447 { 00448 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00449 debug().debug("Debug::I got ACCEPTED from the verifier.YESSS!::%d \n", radio().id() ); 00450 #endif 00451 } 00452 00453 if(data[0]==REJECT_MSG) 00454 { 00455 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG 00456 debug().debug("Debug::I got REJECTED from the verifier.NOOO!::%d \n", radio().id() ); 00457 #endif 00458 } 00459 00460 } 00461 00462 } //end of wiselib namespace 00463 00464 #endif /* ZKPOFSINGLEBIT_PROVER_H_ */