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_TESTOFDLEQUALITY_PROVER_H_ 00021 #define __ALGORITHMS_CRYPTO_TESTOFDLEQUALITY_PROVER_H_ 00022 00023 #include "algorithms/crypto/eccfp.h" 00024 #include <string.h> 00025 00026 //Uncomment to enable Debug 00027 #define ENABLE_TESTOFDLEQUALITY_DEBUG 00028 00029 /*PROTOCOL DESCRIPTION 00030 00031 Zero Knowledge Test of Discrete Logarithm Equality 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 claims he knows x such that B = x*G and 00035 C = x*H and wants to prove knowledge without revaling x. 00036 00037 Protocol Steps 00038 00039 1. Prover chooses random r and computes K = r*G and L = r*H 00040 2. Prover sends points K, L to Verifier 00041 3. Verifier chooses random c and sends c to Prover 00042 4. Prover computes m = r + cx and sends m to Verfier 00043 5. Verifier checks that m*G = (r + cx)*G = r*G + c*xG = K + cB 00044 6. Verifier checks that m*H = (r + cx)*H = r*H + c*xH = L + cC 00045 */ 00046 00047 namespace wiselib { 00048 00049 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug> 00050 class TESTOFDLEQUALITYProve 00051 { 00052 public: 00053 typedef OsModel_P OsModel; 00054 typedef Radio_P Radio; 00055 typedef Debug_P Debug; 00056 00057 typedef TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P> self_t; 00058 typedef typename Radio::node_id_t node_id_t; 00059 typedef typename Radio::size_t size_t; 00060 typedef typename Radio::block_data_t block_data_t; 00061 typedef self_t* self_pointer_t; 00062 00065 TESTOFDLEQUALITYProve(); 00066 ~TESTOFDLEQUALITYProve(); 00068 00072 00073 //message types 00074 enum MsgHeaders { 00075 START_MSG = 200, 00076 HASH_MSG = 201, 00077 CONT_MSG = 202, 00078 ACCEPT_MSG = 203, 00079 REJECT_MSG = 204 00080 }; 00081 00082 int init( Radio& radio, Debug& debug ) 00083 { 00084 radio_ = &radio; 00085 debug_ = &debug; 00086 return 0; 00087 } 00088 00089 inline int init(); 00090 inline int destruct(); 00091 00092 int enable_radio( void ); 00093 int disable_radio( void ); 00094 00096 void key_setup(NN_DIGIT *privkey, Point *pubkey, Point *pubkey1, Point *pubkey2); 00097 void start_proof(); 00098 void send_key(); 00099 00100 00101 protected: 00102 void receive( node_id_t from, size_t len, block_data_t *data ); 00103 00104 private: 00105 00106 Radio& radio() 00107 { return *radio_; } 00108 00109 Debug& debug() 00110 { return *debug_; } 00111 00112 typename Radio::self_pointer_t radio_; 00113 typename Debug::self_pointer_t debug_; 00114 00115 //necessary class objects 00116 ECCFP eccfp; 00117 PMP pmp; 00118 00119 //rounds of the protocol used for seeding the rand function 00120 uint8_t rounds; 00121 00122 //private key that only the prover knows 00123 NN_DIGIT m[NUMWORDS]; 00124 00125 //public keys that both prover and verifier know 00126 Point B; 00127 Point C; 00128 Point P; 00129 00130 //private key r that is generated in the beginning of the protocol 00131 //its corresponding public keys (2 in this case) 00132 NN_DIGIT r[NUMWORDS]; 00133 Point Verify; 00134 Point Verify2; 00135 00136 //the hash that will be received from verifier 00137 NN_DIGIT Hash[NUMWORDS]; 00138 00139 //data that will be sent to the verifier 00140 NN_DIGIT x[NUMWORDS]; 00141 00142 }; 00143 00144 // ----------------------------------------------------------------------- 00145 template<typename OsModel_P, 00146 typename Radio_P, 00147 typename Debug_P> 00148 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00149 TESTOFDLEQUALITYProve() 00150 :radio_(0), 00151 debug_(0) 00152 {} 00153 00154 // ----------------------------------------------------------------------- 00155 template<typename OsModel_P, 00156 typename Radio_P, 00157 typename Debug_P> 00158 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00159 ~TESTOFDLEQUALITYProve() 00160 {} 00161 00162 //----------------------------------------------------------------------- 00163 template<typename OsModel_P, 00164 typename Radio_P, 00165 typename Debug_P> 00166 int 00167 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00168 init( void ) 00169 { 00170 enable_radio(); 00171 return 0; 00172 } 00173 //----------------------------------------------------------------------------- 00174 template<typename OsModel_P, 00175 typename Radio_P, 00176 typename Debug_P> 00177 int 00178 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00179 destruct( void ) 00180 { 00181 return disable_radio(); 00182 } 00183 //--------------------------------------------------------------------------- 00184 template<typename OsModel_P, 00185 typename Radio_P, 00186 typename Debug_P> 00187 int 00188 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00189 enable_radio( void ) 00190 { 00191 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00192 debug().debug( "ZKP Test of Dl Prove: Boot for %i\n", radio().id() ); 00193 #endif 00194 00195 radio().enable_radio(); 00196 radio().template reg_recv_callback<self_t, &self_t::receive>( this ); 00197 00198 return 0; 00199 } 00200 //--------------------------------------------------------------------------- 00201 template<typename OsModel_P, 00202 typename Radio_P, 00203 typename Debug_P> 00204 int 00205 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00206 disable_radio( void ) 00207 { 00208 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00209 debug().debug( "ZKP Test of Dl Prove: Disable\n" ); 00210 #endif 00211 return -1; 00212 } 00213 00214 //----------------------------------------------------------------------- 00215 template<typename OsModel_P, 00216 typename Radio_P, 00217 typename Debug_P> 00218 void 00219 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00220 key_setup( NN_DIGIT *privkey, Point *pubkey, Point *pubkey1, Point *pubkey2) { 00221 00222 rounds=1; 00223 00224 //copy prover's private secret key to local variable 00225 pmp.AssignZero(m, NUMWORDS); 00226 pmp.Assign(m, privkey, NUMWORDS); 00227 00228 //get first public key available to prover and verifier 00229 //first public key with m as DL (B=mG) 00230 eccfp.p_clear(&B); 00231 eccfp.p_copy(&B, pubkey); 00232 00233 //second generator P 00234 eccfp.p_clear(&P); 00235 eccfp.p_copy(&P, pubkey1); 00236 00237 //get second public key C with m as EC discrete log (C=mP) 00238 eccfp.p_clear(&C); 00239 eccfp.p_copy(&C, pubkey2); 00240 00241 } 00242 00243 //--------------------------------------------------------------------------- 00244 template<typename OsModel_P, 00245 typename Radio_P, 00246 typename Debug_P> 00247 void 00248 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00249 start_proof( void ) { 00250 00251 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00252 debug().debug("Debug::Starting Test of DL Equality Interactive ZKP Prover on::%d \n", radio().id() ); 00253 #endif 00254 00255 //if the protocol is booting generate random r and compute K=rG and L=rP 00256 //and send K,L to verifier 00257 rounds++; 00258 00259 //clear private and public key 00260 pmp.AssignZero(r, NUMWORDS); 00261 eccfp.p_clear(&Verify); 00262 eccfp.p_clear(&Verify2); 00263 00264 //generate random r and compute K=rG and L=rP 00265 eccfp.gen_private_key(r, rounds); 00266 //K=rG 00267 eccfp.gen_public_key(&Verify, r); 00268 //L=rP 00269 eccfp.c_mul(&Verify2, &P, r); 00270 00271 //send the message with K,L to verifier 00272 uint8_t buffer[4*(KEYDIGITS*NN_DIGIT_LEN +1)+1]; 00273 buffer[0]=START_MSG; 00274 //place the two points to buffer after encoding them to octets 00275 eccfp.point2octet(buffer+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify, FALSE); 00276 eccfp.point2octet(buffer+2*(KEYDIGITS*NN_DIGIT_LEN + 1)+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify2, FALSE); 00277 00278 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00279 debug().debug( "Debug::Finished calculations!Sending 2 verify keys to verifier. ::%d \n", radio().id() ); 00280 #endif 00281 radio().send(Radio::BROADCAST_ADDRESS, 4*(KEYDIGITS*NN_DIGIT_LEN +1)+1, buffer); 00282 } 00283 00284 //------------------------------------------------------------------------ 00285 template<typename OsModel_P, 00286 typename Radio_P, 00287 typename Debug_P> 00288 void 00289 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00290 send_key( void ) { 00291 00292 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00293 debug().debug( "Debug::Creating the new private key ::%d \n", radio().id()); 00294 #endif 00295 00296 //prover computes x= r + cm 00297 //and sends x to verifier 00298 00299 //clear private key x 00300 pmp.AssignZero(x, NUMWORDS); 00301 NN_DIGIT mid2[NUMWORDS]; 00302 pmp.AssignZero(mid2, NUMWORDS); 00303 00304 //first compute cm 00305 pmp.ModMult(mid2, Hash, m, param.r, NUMWORDS); 00306 //then add r+cm 00307 pmp.ModAdd(x, r, mid2, param.r, NUMWORDS); 00308 00309 //send the message with x to verifier 00310 uint8_t buffer[KEYDIGITS*NN_DIGIT_LEN+2]; 00311 buffer[0]=CONT_MSG; 00312 00313 //convert x to octet 00314 pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, x, NUMWORDS); 00315 00316 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00317 debug().debug("Debug::Sending the new private key x to verifier::%d \n", radio().id() ); 00318 #endif 00319 radio().send(Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN+2 , buffer); 00320 } 00321 00322 //--------------------------------------------------------------------------- 00323 template<typename OsModel_P, 00324 typename Radio_P, 00325 typename Debug_P> 00326 void 00327 TESTOFDLEQUALITYProve<OsModel_P, Radio_P, Debug_P>:: 00328 receive( node_id_t from, size_t len, block_data_t *data ) { 00329 00330 if( from == radio().id() ) return; 00331 00332 if(data[0]==HASH_MSG) 00333 { 00334 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00335 debug().debug("Debug::Received a hash message. Calling the send_key task.::%d \n", radio().id() ); 00336 #endif 00337 00338 //clear the hash and place the random c received from verifier 00339 pmp.AssignZero(Hash, NUMWORDS); 00340 //decode the private key received 00341 pmp.Decode(Hash, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1); 00342 00343 //calling the send_key task 00344 send_key(); 00345 } 00346 00347 if(data[0]==ACCEPT_MSG) 00348 { 00349 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00350 debug().debug( "Debug::I got ACCEPTED from the verifier.YESSS!::%d \n", radio().id() ); 00351 #endif 00352 } 00353 00354 if(data[0]==REJECT_MSG) 00355 { 00356 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG 00357 debug().debug( "Debug::I got REJECTED from the verifier.NOOO!::%d \n", radio().id() ); 00358 #endif 00359 } 00360 00361 } 00362 00363 } //end of wiselib namespace 00364 00365 #endif /* TESTOFDLEQUALITY_PROVER_H_ */