Wiselib
wiselib.testing/algorithms/crypto/ZeroKnowledgeProofsFp/zkp-verifier.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_ZKPVERIFIER_H_
00021 #define __ALGORITHMS_CRYPTO_ZKPVERIFIER_H_
00022 
00023 #include "algorithms/crypto/eccfp.h"
00024 #include "algorithms/crypto/pmp.h"
00025 #include <string.h>
00026 
00027 //how many times the protocol must execute
00028 #define REQ_ROUNDS 6
00029 
00030 // Uncomment to enable Debug
00031 #define ENABLE_ZKP_DEBUG
00032 
00033 /*
00034 PROTOCOL DESCRIPTION
00035 
00036 Given an elliptive curve E over a field Fn , a generator point G in E/Fn and
00037 B in E/Fn Prover wants to prove in zero-knowledge that he knows x such that
00038 B =x*G
00039 
00040 Protocol Steps
00041 
00042 1. Prover generates random r and computes A = r*G
00043 2. Prover sends A to Verifier
00044 3. Verifier flips a coin and informs the Prover about the outcome
00045 4. In case of HEADS Prover sends r to Verifier who checks that r*G = A
00046 5. In case of TAILS Prover sends m = x + r to Verifier who checks that m*G=A+B
00047 
00048 The above steps are repeated until Verifier is convinced that Prover knows
00049 x with probability 1-2^{-k} for k iterations.
00050 */
00051 
00052 namespace wiselib {
00053 
00054 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug>
00055    class ZKPVerify
00056    {
00057    public:
00058       typedef OsModel_P OsModel;
00059       typedef Radio_P Radio;
00060       typedef Debug_P Debug;
00061 
00062       typedef ZKPVerify<OsModel_P, Radio_P, Debug_P> self_t;
00063      typedef typename Radio::node_id_t node_id_t;
00064      typedef typename Radio::size_t size_t;
00065      typedef typename Radio::block_data_t block_data_t;
00066      typedef self_t* self_pointer_t;
00067 
00070       ZKPVerify();
00071       ~ZKPVerify();
00073 
00077 
00078       //message types
00079       enum MsgHeaders {
00080            START_MSG = 200,
00081            COIN_MSG  = 201,
00082            HEADS_MSG = 202,
00083            TAILS_MSG = 203,
00084            ACCEPT_MSG =204,
00085            REJECT_MSG =205,
00086            RESTART_MSG = 206
00087        };
00088 
00089       int init( Radio& radio, Debug& debug )
00090      {
00091        radio_ = &radio;
00092        debug_ = &debug;
00093        return 0;
00094      }
00095 
00096      inline int init();
00097      inline int destruct();
00098 
00099      int enable_radio( void );
00100      int disable_radio( void );
00101 
00103       void key_setup(Point *pubkey);
00104       bool coin_flip(uint8_t b);
00105       void verify_tails();
00106       void verify_heads();
00107       void final_decision();
00108 
00109    protected:
00110            void receive( node_id_t from, size_t len, block_data_t *data );
00111 
00112    private:
00113 
00114    Radio& radio()
00115    { return *radio_; }
00116 
00117    Debug& debug()
00118    { return *debug_; }
00119 
00120    typename Radio::self_pointer_t radio_;
00121    typename Debug::self_pointer_t debug_;
00122 
00123     //necessary class objects
00124     ECCFP eccfp;
00125     PMP pmp;
00126 
00127     //# of rounds the protocol is executed
00128    uint8_t rounds;
00129 
00130    //# of successful rounds
00131    uint8_t success_rounds;
00132 
00133    //# of required rounds
00134    uint8_t required_rounds;
00135 
00136    //public key that will be received by the prover in each round
00137    Point A;
00138    //private key that will be received by the prover in each round
00139    NN_DIGIT Valid[NUMWORDS];
00140 
00141    //public key that both prover and verifier know
00142    Point B;
00143 
00144    };
00145 
00146    // -----------------------------------------------------------------------
00147    template<typename OsModel_P,
00148          typename Radio_P,
00149          typename Debug_P>
00150    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00151 	ZKPVerify()
00152    : radio_(0),
00153      debug_(0)
00154    {}
00155 
00156    // -----------------------------------------------------------------------
00157    template<typename OsModel_P,
00158          typename Radio_P,
00159          typename Debug_P>
00160    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00161 	~ZKPVerify()
00162    {}
00163 
00164    //-----------------------------------------------------------------------
00165    template<typename OsModel_P,
00166          typename Radio_P,
00167          typename Debug_P>
00168    int
00169    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00170 	init( void )
00171    {
00172      enable_radio();
00173 
00174      return 0;
00175    }
00176    //-----------------------------------------------------------------------------
00177    template<typename OsModel_P,
00178          typename Radio_P,
00179          typename Debug_P>
00180    int
00181    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00182 	destruct( void )
00183    {
00184      return disable_radio();
00185    }
00186    //---------------------------------------------------------------------------
00187    template<typename OsModel_P,
00188          typename Radio_P,
00189          typename Debug_P>
00190    int
00191    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00192 	enable_radio( void )
00193    {
00194 #ifdef ENABLE_ZKP_DEBUG
00195       debug().debug( "ZKPProve: Boot for %i\n", radio().id() );
00196 #endif
00197 
00198      radio().enable_radio();
00199      radio().template reg_recv_callback<self_t, &self_t::receive>( this );
00200 
00201      return 0;
00202    }
00203    //---------------------------------------------------------------------------
00204    template<typename OsModel_P,
00205          typename Radio_P,
00206          typename Debug_P>
00207    int
00208    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00209 	disable_radio( void )
00210    {
00211 #ifdef ENABLE_ZKP_DEBUG
00212       debug().debug( "ZKPProve: Disable\n" );
00213 #endif
00214      return -1;
00215    }
00216    //----------------------------------------------------------------------
00217    template<typename OsModel_P,
00218             typename Radio_P,
00219             typename Debug_P>
00220    void
00221    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00222 	key_setup( Point *pubkey ) {
00223 
00224 #ifdef ENABLE_ZKP_DEBUG
00225       debug().debug("debug().Start ZKP Verifier on::%d \n", radio().id() );
00226 #endif
00227       rounds=0;
00228       success_rounds=0;
00229       required_rounds=REQ_ROUNDS;
00230 
00231       //public key available to prover and verifier
00232       eccfp.p_clear(&B);
00233       eccfp.p_copy(&B, pubkey);
00234    }
00235 
00236    //----------------------------------------------------------------------------
00237    template<typename OsModel_P,
00238             typename Radio_P,
00239             typename Debug_P>
00240    bool
00241    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00242 	coin_flip(uint8_t b){
00243 
00244       block_data_t msg[2];
00245       msg[0]=COIN_MSG;
00246 
00247       //simulate the flip of a coin
00248       if(b % 2 ==0)
00249       {
00250 #ifdef ENABLE_ZKP_DEBUG
00251          debug().debug("debug::Coin flip was heads::%d \n", radio().id() );
00252 #endif
00253 
00254          msg[1]=0;
00255          //send the coin message
00256          radio().send( Radio::BROADCAST_ADDRESS, 2, msg);
00257          return true;
00258       }
00259       else
00260       {
00261 #ifdef ENABLE_ZKP_DEBUG
00262          debug().debug("debug::Coin flip was tails::%d \n", radio().id() );
00263 #endif
00264          msg[1]=1;
00265          //send the coin message
00266          radio().send(Radio::BROADCAST_ADDRESS, 2, msg);
00267          return false;
00268       }
00269    }
00270 
00271    //------------------------------------------------------------------------------------
00272    template<typename OsModel_P,
00273             typename Radio_P,
00274             typename Debug_P>
00275    void
00276    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00277 	verify_heads(){
00278 
00279       //check if the heads content is valid
00280       Point result;
00281       eccfp.p_clear(&result);
00282 
00283       //check that A = rG
00284       eccfp.gen_public_key(&result, Valid);
00285 
00286       //is the result correct???
00287       if(eccfp.p_equal(&result, &A)== true)
00288       {
00289          success_rounds++;
00290 #ifdef ENABLE_ZKP_DEBUG
00291          debug().debug("debug::Heads content verified \n", radio().id() );
00292 #endif
00293       }
00294       //check if required rounds are completed
00295       final_decision();
00296 
00297    }
00298 
00299    //-------------------------------------------------------------------------------------
00300    template<typename OsModel_P,
00301             typename Radio_P,
00302             typename Debug_P>
00303    void
00304    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00305 	verify_tails(){
00306 
00307       //check if tails content is valid
00308       Point result1;
00309       Point result2;
00310       eccfp.p_clear(&result1);
00311       eccfp.p_clear(&result2);
00312 
00313       //check that rG = A+B
00314       eccfp.gen_public_key(&result1, Valid);
00315       eccfp.c_add_affine(&result2, &B, &A);
00316 
00317       //is the result correct???
00318       if(eccfp.p_equal(&result1, &result2)== true)
00319       {
00320          success_rounds++;
00321 #ifdef ENABLE_ZKP_DEBUG
00322          debug().debug("debug::Tails content verified \n", radio().id() );
00323 #endif
00324       }
00325 
00326       //check if required rounds are completed
00327       final_decision();
00328 
00329    }
00330 
00331    //----------------------------------------------------------------------------------------
00332    template<typename OsModel_P,
00333             typename Radio_P,
00334             typename Debug_P>
00335    void
00336    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00337 	final_decision(){
00338 
00339       //are the required rounds accomplished?
00340       if(rounds!=required_rounds)
00341       {
00342          block_data_t buffer[1];
00343          buffer[0]=RESTART_MSG;
00344 #ifdef ENABLE_ZKP_DEBUG
00345          debug().debug( "debug().Sending restart message to prover.\n", radio().id() );
00346 #endif
00347          radio().send( Radio::BROADCAST_ADDRESS, 1, buffer);
00348       }
00349       else
00350       {
00351          //were the rounds all successful??the protocol accepts
00352          if(success_rounds==required_rounds)
00353          {
00354 #ifdef ENABLE_ZKP_DEBUG
00355             debug().debug("debug::Protocol finished with success.Secret Verified!!Prover HONEST!\n", radio().id() );
00356 #endif
00357             //send to prover the accept message
00358             block_data_t buffer[1];
00359             buffer[0]=ACCEPT_MSG;
00360             radio().send(Radio::BROADCAST_ADDRESS, 1, buffer);
00361          }
00362          //some rounds failed, the protocol rejects
00363          else
00364          {
00365 #ifdef ENABLE_ZKP_DEBUG
00366             debug().debug( "debug::Protocol finished without success.Secret NOT Verified!!Prover NOT HONEST\n", radio().id());
00367 #endif
00368             block_data_t buffer[1];
00369             buffer[0]=REJECT_MSG;
00370             radio().send(Radio::BROADCAST_ADDRESS, 1, buffer);
00371          }
00372       }
00373    }
00374 
00375    //---------------------------------------------------------------------------
00376    template<typename OsModel_P,
00377             typename Radio_P,
00378             typename Debug_P>
00379    void
00380    ZKPVerify<OsModel_P, Radio_P, Debug_P>::
00381 	receive( node_id_t from, size_t len, block_data_t *data ) {
00382 
00383       if( from == radio().id() ) return;
00384 
00385       if(data[0]==START_MSG)
00386       {
00387 #ifdef ENABLE_ZKP_DEBUG
00388          debug().debug( "debug::Received a starting message::%d \n", radio().id());
00389 #endif
00390          rounds++;
00391          //get Verify point A from the message
00392          eccfp.p_clear(&A);
00393 
00394          //convert octet received to point A
00395          eccfp.octet2point(&A, data+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00396 
00397          //flip the coin
00398          coin_flip(rounds);
00399       }
00400 
00401       if(data[0]==HEADS_MSG)
00402       {
00403 #ifdef ENABLE_ZKP_DEBUG
00404          debug().debug("debug::Received a heads content message::%d \n", radio().id());
00405 #endif
00406 
00407          //clear the private key and store it
00408          pmp.AssignZero(Valid, NUMWORDS);
00409          //decode the private key received
00410          pmp.Decode(Valid, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1);
00411 
00412          //check if the heads content is valid
00413          verify_heads();
00414       }
00415 
00416 
00417       if(data[0]==TAILS_MSG)
00418       {
00419 #ifdef ENABLE_ZKP_DEBUG
00420          debug().debug("debug::Received a tails content message::%d \n", radio().id() );
00421 #endif
00422 
00423          //clear the private key and store it
00424          pmp.AssignZero(Valid, NUMWORDS);
00425          //decode the private key received
00426          pmp.Decode(Valid, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1);
00427 
00428          //check if the tails content is valid
00429          verify_tails();
00430       }
00431    }
00432 
00433 } //end of namespace
00434 
00435 #endif /* ZKP_VERIFIER_H_ */
00436 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines