Wiselib
wiselib.testing/algorithms/crypto/ZeroKnowledgeProofsFp/zkp-prover.h
Go to the documentation of this file.
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_ZKPPROVER_H_
00021 #define __ALGORITHMS_CRYPTO_ZKPPROVER_H_
00022 
00023 #include "algorithms/crypto/eccfp.h"
00024 #include "algorithms/crypto/pmp.h"
00025 #include <string.h>
00026 
00027 //Uncomment to enable Debug
00028 #define ENABLE_ZKP_DEBUG
00029 
00030 /*
00031 PROTOCOL DESCRIPTION
00032 
00033 Given an elliptive curve E over a field Fn , a generator point G in E/Fn and
00034 B in E/Fn Prover wants to prove in zero-knowledge that he knows x such that
00035 B =x*G
00036 
00037 Protocol Steps
00038 
00039 1. Prover generates random r and computes A = r*G
00040 2. Prover sends A to Verifier
00041 3. Verifier flips a coin and informs the Prover about the outcome
00042 4. In case of HEADS Prover sends r to Verifier who checks that r*G = A
00043 5. In case of TAILS Prover sends m = x + r to Verifier who checks that m*G=A+B
00044 
00045 The above steps are repeated until Verifier is convinced that Prover knows
00046 x with probability 1-2^{-k} for k iterations.
00047 */
00048 
00049 namespace wiselib {
00050 
00051 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug>
00052    class ZKPProve
00053    {
00054    public:
00055       typedef OsModel_P OsModel;
00056       typedef Radio_P Radio;
00057       typedef Debug_P Debug;
00058 
00059       typedef ZKPProve<OsModel_P, Radio_P, Debug_P> self_t;
00060      typedef typename Radio::node_id_t node_id_t;
00061      typedef typename Radio::size_t size_t;
00062      typedef typename Radio::block_data_t block_data_t;
00063      typedef self_t* self_pointer_t;
00064 
00067       ZKPProve();
00068       ~ZKPProve();
00070 
00071      int init( Radio& radio, Debug& debug )
00072      {
00073        radio_ = &radio;
00074        debug_ = &debug;
00075        return 0;
00076      }
00077 
00078      inline int init();
00079      inline int destruct();
00080 
00081      int enable_radio( void );
00082      int disable_radio( void );
00083 
00087 
00088       //message types
00089       enum MsgHeaders {
00090            START_MSG = 200,
00091            COIN_MSG  = 201,
00092            HEADS_MSG = 202,
00093            TAILS_MSG = 203,
00094            ACCEPT_MSG =204,
00095            REJECT_MSG =205,
00096            RESTART_MSG = 206
00097        };
00098 
00100       void key_setup(NN_DIGIT *privkey , Point *pubkey);
00101       void start_proof();
00102       void send_tails();
00103       void send_heads();
00104 
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     //eccfp class object
00121     ECCFP eccfp;
00122     PMP pmp;
00123 
00124     //rounds of the protocol used for seeding the rand function
00125    uint8_t rounds;
00126 
00127    //private key that only the prover knows
00128    NN_DIGIT m[NUMWORDS];
00129 
00130    //public key that both prover and verifier know
00131    Point B;
00132 
00133    //private key r that is generated in every round and
00134    //its corresponding public key
00135    NN_DIGIT r[NUMWORDS];
00136    Point Verify;
00137 
00138    };
00139 
00140    // -----------------------------------------------------------------------
00141    template<typename OsModel_P,
00142       typename Radio_P,
00143       typename Debug_P>
00144    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00145 	ZKPProve()
00146    : radio_(0),
00147      debug_(0)
00148    {}
00149 
00150    // -----------------------------------------------------------------------
00151    template<typename OsModel_P,
00152       typename Radio_P,
00153       typename Debug_P>
00154    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00155 	~ZKPProve()
00156    {}
00157    //-----------------------------------------------------------------------
00158    template<typename OsModel_P,
00159          typename Radio_P,
00160          typename Debug_P>
00161    int
00162    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00163    init( void )
00164    {
00165      enable_radio();
00166 
00167      return 0;
00168    }
00169    //-----------------------------------------------------------------------------
00170    template<typename OsModel_P,
00171          typename Radio_P,
00172          typename Debug_P>
00173    int
00174    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00175    destruct( void )
00176    {
00177      return disable_radio();
00178    }
00179    //---------------------------------------------------------------------------
00180    template<typename OsModel_P,
00181          typename Radio_P,
00182          typename Debug_P>
00183    int
00184    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00185    enable_radio( void )
00186    {
00187 #ifdef ENABLE_ZKP_DEBUG
00188      debug().debug( "ZKPProve: Boot for %i\n", radio().id() );
00189 #endif
00190 
00191      radio().enable_radio();
00192      radio().template reg_recv_callback<self_t, &self_t::receive>( this );
00193 
00194      return 0;
00195    }
00196    //---------------------------------------------------------------------------
00197    template<typename OsModel_P,
00198          typename Radio_P,
00199          typename Debug_P>
00200    int
00201    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00202    disable_radio( void )
00203    {
00204 #ifdef ENABLE_ZKP_DEBUG
00205      debug().debug( "ZKPProve: Disable\n" );
00206 #endif
00207      return -1;
00208    }
00209    //----------------------------------------------------------------------------
00210    template<typename OsModel_P,
00211       typename Radio_P,
00212       typename Debug_P>
00213    void
00214    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00215 	key_setup( NN_DIGIT *privkey , Point *pubkey )
00216    {
00217       rounds=0;
00218 
00219       //copy keys to local variables
00220       //prover's private secret key
00221       pmp.AssignZero(m, NUMWORDS);
00222       pmp.Assign(m, privkey, NUMWORDS);
00223 
00224       //public key available to prover and verifier
00225       eccfp.p_clear(&B);
00226       eccfp.p_copy(&B, pubkey);
00227    }
00228 
00229    //---------------------------------------------------------------------------
00230    template<typename OsModel_P,
00231       typename Radio_P,
00232       typename Debug_P>
00233    void
00234    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00235 	start_proof( void ) {
00236 
00237 #ifdef ENABLE_ZKP_DEBUG
00238       debug().debug("Debug::Start ZKP Prover on::%d \n", radio().id() );
00239 #endif
00240 
00241       rounds++;
00242       //clear the private key and public key
00243       pmp.AssignZero(r, NUMWORDS);
00244       eccfp.p_clear(&Verify);
00245 
00246 #ifdef ENABLE_ZKP_DEBUG
00247       debug().debug("Debug::Generating random r and computing A=rG ::%d \n", radio().id() );
00248 #endif
00249 
00250       //generate random r and compute pubKey A=rG
00251       eccfp.gen_private_key(r, rounds);
00252       eccfp.gen_public_key(&Verify, r);
00253 
00254       //place the verify key in the buffer and send the message
00255       block_data_t msg[2*(KEYDIGITS*NN_DIGIT_LEN + 1) + 1];
00256       msg[0]=START_MSG;
00257 
00258       //convert point to octet
00259       eccfp.point2octet(msg+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify, FALSE);
00260 
00261 #ifdef ENABLE_ZKP_DEBUG
00262       debug().debug( "Debug::Sending start message to verifier! ::%d \n", radio().id() );
00263 #endif
00264       radio().send( Radio::BROADCAST_ADDRESS, 2*(KEYDIGITS*NN_DIGIT_LEN +1) +1, msg);
00265    }
00266 
00267    //------------------------------------------------------------------------
00268    template<typename OsModel_P,
00269    typename Radio_P,
00270    typename Debug_P>
00271    void
00272    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00273 	send_tails( void ) {
00274 
00275 #ifdef ENABLE_ZKP_DEBUG
00276       debug().debug( "Debug::Creating tails content::%d \n", radio().id() );
00277 #endif
00278 
00279       //if the coin was tails the prover creates x= m + r and sends to verifier
00280       NN_DIGIT x[NUMWORDS];
00281       pmp.AssignZero(x, NUMWORDS);
00282       pmp.ModAdd(x, r, m, param.r, NUMWORDS);
00283 
00284       //if it is tails send to verifier m+r
00285       block_data_t buffer[KEYDIGITS*NN_DIGIT_LEN + 2];
00286       buffer[0]=TAILS_MSG;
00287 
00288       //convert x to octet
00289       pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, x, NUMWORDS);
00290 
00291 #ifdef ENABLE_ZKP_DEBUG
00292       debug().debug( "Debug::Sending Tails Content::%d \n", radio().id() );
00293 #endif
00294       radio().send(Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN + 2, buffer);
00295    }
00296 
00297    //-----------------------------------------------------------------------------
00298    template<typename OsModel_P,
00299       typename Radio_P,
00300       typename Debug_P>
00301    void
00302    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00303 	send_heads( void ) {
00304 
00305 #ifdef ENABLE_ZKP_DEBUG
00306       debug().debug( "Debug::Creating heads content::%d \n", radio().id() );
00307 #endif
00308       //if the coin was heads prover sends to verifier the private key r
00309       block_data_t buffer[KEYDIGITS*NN_DIGIT_LEN + 2];
00310       buffer[0]=HEADS_MSG;
00311       //convert r to octet
00312       pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, r, NUMWORDS);
00313 
00314 #ifdef ENABLE_ZKP_DEBUG
00315       debug().debug("Debug::Sending Heads Content::%d \n", radio().id() );
00316 #endif
00317       radio().send( Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN + 2, buffer);
00318 
00319    }
00320 
00321    //---------------------------------------------------------------------------
00322    template<typename OsModel_P,
00323       typename Radio_P,
00324       typename Debug_P>
00325    void
00326    ZKPProve<OsModel_P, Radio_P, Debug_P>::
00327 	receive( node_id_t from, size_t len, block_data_t *data ) {
00328 
00329       if( from == radio().id( ) ) return;
00330 
00331       if(data[0]==COIN_MSG)
00332       {
00333 #ifdef ENABLE_ZKP_DEBUG
00334          debug().debug( "Debug::Received a coin message::%d \n", radio().id());
00335 #endif
00336          if(data[1]==1)
00337          {
00338             send_tails();
00339          }
00340          else
00341          {
00342             send_heads();
00343          }
00344       }
00345 
00346       if(data[0]==RESTART_MSG)
00347       {
00348 #ifdef ENABLE_ZKP_DEBUG
00349          debug().debug( "Debug::Received a restart message. Re-starting the steps.::%d \n", radio().id());
00350 #endif
00351          start_proof();
00352       }
00353 
00354       if(data[0]==ACCEPT_MSG)
00355       {
00356 #ifdef ENABLE_ZKP_DEBUG
00357          debug().debug( "Debug::I got ACCEPTED from the verifier.YESSS!::%d \n", radio().id());
00358 #endif
00359       }
00360 
00361       if(data[0]==REJECT_MSG)
00362       {
00363 #ifdef ENABLE_ZKP_DEBUG
00364          debug().debug( "Debug::I got REJECTED from the verifier.NOOO!::%d \n", radio().id());
00365 #endif
00366       }
00367 
00368    }
00369 
00370 } //end of wiselib namespace
00371 
00372 #endif /* ZKP_PROVER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines