Wiselib
wiselib.testing/algorithms/crypto/ZeroKnowledgeProofsFp/TestofDLEquality-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_TESTOFDLEQUALITY_VERIFIER_H_
00021 #define __ALGORITHMS_TESTOFDLEQUALITY_VERIFIER_H_
00022 
00023 #include "algorithms/crypto/eccfp.h"
00024 
00025 #include <string.h>
00026 
00027 //protocol needs to be executed for 1 round
00028 #define REQ_ROUNDS 1
00029 
00030 // Uncomment to enable Debug
00031 #define ENABLE_TESTOFDLEQUALITY_DEBUG
00032 
00033 /*PROTOCOL DESCRIPTION
00034 
00035 Zero Knowledge Test of Discrete Logarithm Equality
00036 
00037 Prover and Verifier agree on an elliptic curve E over a field Fn , a generator
00038 G in E/Fn and H in E/Fn . Prover claims he knows x such that B = x*G and
00039 C = x*H and wants to prove knowledge without revaling x.
00040 
00041 Protocol Steps
00042 
00043 1. Prover chooses random r and computes K = r*G and L = r*H
00044 2. Prover sends points K, L to Verifier
00045 3. Verifier chooses random c and sends c to Prover
00046 4. Prover computes m = r + cx and sends m to Verfier
00047 5. Verifier checks that m*G = (r + cx)*G = r*G + c*xG = K + cB
00048 6. Verifier checks that m*H = (r + cx)*H = r*H + c*xH = L + cC
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 TESTOFDLEQUALITYVerify
00055    {
00056    public:
00057       typedef OsModel_P OsModel;
00058       typedef Radio_P Radio;
00059       typedef Debug_P Debug;
00060 
00061       typedef TESTOFDLEQUALITYVerify<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       TESTOFDLEQUALITYVerify();
00070       ~TESTOFDLEQUALITYVerify();
00072 
00076 
00077       int init( Radio& radio, Debug& debug )
00078      {
00079        radio_ = &radio;
00080        debug_ = &debug;
00081        return 0;
00082      }
00083 
00084      inline int init();
00085      inline int destruct();
00086 
00087      int enable_radio( void );
00088      int disable_radio( void );
00089 
00090       //message types
00091       enum MsgHeaders {
00092         START_MSG = 200,
00093         HASH_MSG = 201,
00094         CONT_MSG = 202,
00095         ACCEPT_MSG = 203,
00096         REJECT_MSG = 204
00097        };
00098 
00100       void key_setup(Point *pubkey, Point *pubkey1, Point *pubkey2);
00101       void generate_random();
00102       bool verify();
00103       bool verify_msg();
00104       void final_decision();
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     //# of rounds (used for seeding and generating the random value)
00125    uint8_t rounds;
00126 
00127       //# of successfull rounds
00128    uint8_t success_rounds;
00129 
00130    //# of required rounds
00131    uint8_t required_rounds;
00132 
00133    //the random private key calculated on the point received by the prover
00134    NN_DIGIT c[NUMWORDS];
00135 
00136    //private key that will be received by the prover in each round
00137    NN_DIGIT Valid[NUMWORDS];
00138 
00139    //public key that both prover and verifier know
00140    Point B;
00141    Point P;
00142    Point C;
00143 
00144    //public key A to be received by the prover
00145    Point K;
00146    Point L;
00147 
00148    //public key Check for the verifications
00149    Point Check;
00150    Point Check2;
00151 
00152    };
00153 
00154    // -----------------------------------------------------------------------
00155    template<typename OsModel_P,
00156          typename Radio_P,
00157          typename Debug_P>
00158    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00159 	TESTOFDLEQUALITYVerify()
00160    : radio_(0),
00161      debug_(0)
00162    {}
00163 
00164    // -----------------------------------------------------------------------
00165    template<typename OsModel_P,
00166          typename Radio_P,
00167          typename Debug_P>
00168    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00169 	~TESTOFDLEQUALITYVerify()
00170    {}
00171 
00172    //-----------------------------------------------------------------------
00173    template<typename OsModel_P,
00174                typename Radio_P,
00175                typename Debug_P>
00176    int
00177    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00178 	init( void )
00179    {
00180      enable_radio();
00181      return 0;
00182    }
00183    //-----------------------------------------------------------------------------
00184    template<typename OsModel_P,
00185          typename Radio_P,
00186          typename Debug_P>
00187    int
00188    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00189 	destruct( void )
00190    {
00191      return disable_radio();
00192    }
00193    //---------------------------------------------------------------------------
00194    template<typename OsModel_P,
00195          typename Radio_P,
00196          typename Debug_P>
00197    int
00198    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00199 	enable_radio( void )
00200    {
00201 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00202       debug().debug( "ZKP Test of Dl Verify: Boot for %i\n", radio().id() );
00203 #endif
00204 
00205      radio().enable_radio();
00206      radio().template reg_recv_callback<self_t, &self_t::receive>( this );
00207 
00208      return 0;
00209    }
00210    //---------------------------------------------------------------------------
00211    template<typename OsModel_P,
00212          typename Radio_P,
00213          typename Debug_P>
00214    int
00215    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00216 	disable_radio( void )
00217    {
00218 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00219       debug().debug( "ZKP Test of Dl Prove: Disable\n" );
00220 #endif
00221      return -1;
00222    }
00223    //----------------------------------------------------------------------
00224    template<typename OsModel_P,
00225             typename Radio_P,
00226             typename Debug_P>
00227    void
00228    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00229 	key_setup( Point *pubkey, Point *pubkey1, Point *pubkey2 ) {
00230 
00231 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00232       debug().debug("Debug::Start Test of DL equality Interactive ZKP Verifier on::%d \n", radio().id() );
00233 #endif
00234       rounds=89;
00235       success_rounds=0;
00236       required_rounds=REQ_ROUNDS;
00237 
00238       //get first public key available to prover and verifier
00239       eccfp.p_clear(&B);
00240       eccfp.p_copy(&B, pubkey);
00241 
00242       //second generator P
00243       eccfp.p_clear(&P);
00244       eccfp.p_copy(&P, pubkey1);
00245 
00246       //get second public key C with m as EC discrete log (C=mP)
00247       eccfp.p_clear(&C);
00248       eccfp.p_copy(&C, pubkey2);
00249    }
00250 
00251    //------------------------------------------------------------------------------------
00252    template<typename OsModel_P,
00253                typename Radio_P,
00254                typename Debug_P>
00255    void
00256    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00257 	generate_random(){
00258 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00259       debug().debug("Debug::Generating random number c!\n", radio().id() );
00260 #endif
00261 
00262       //clear the private key c
00263       pmp.AssignZero(c, NUMWORDS);
00264       //and generate random number c
00265       eccfp.gen_private_key(c, rounds);
00266 
00267       //send message with c to prover
00268       uint8_t buffer[KEYDIGITS*NN_DIGIT_LEN+2];
00269       buffer[0]=HASH_MSG;
00270       //place key to buffer after encoding to octet
00271       pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, c, NUMWORDS);
00272 
00273 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00274       debug().debug( "Debug::Finished generating random number c!Sending c to prover. ::%d \n", radio().id() );
00275 #endif
00276 
00277       radio().send( Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN+2, buffer);
00278    }
00279 
00280    //------------------------------------------------------------------------------------
00281    template<typename OsModel_P,
00282             typename Radio_P,
00283             typename Debug_P>
00284    bool
00285    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00286 	verify(){
00287 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00288       debug().debug("Debug::Starting first Verification!\n", radio().id() );
00289 #endif
00290 
00291       //verifier checks that sG = K + cB
00292       Point result;
00293       Point result1;
00294       eccfp.p_clear(&result);
00295       eccfp.p_clear(&result1);
00296       eccfp.p_clear(&Check);
00297 
00298       //compute sG
00299       eccfp.gen_public_key(&result, Valid);
00300 
00301       //compute cB
00302       eccfp.c_mul(&result1, &B, c);
00303 
00304       //compute K + cB
00305       eccfp.c_add_affine(&Check, &K, &result1);
00306 
00307       //is the result correct???
00308       //compare point sG with point K+cB
00309       if(eccfp.p_equal(&result, &Check)==true)
00310       {
00311 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00312          debug().debug("Debug::First check SUCCESS!\n", radio().id() );
00313 #endif
00314          verify_msg();
00315          return true;
00316       }
00317       else
00318       {
00319 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00320          debug().debug( "Debug::First check FAIL!\n", radio().id() );
00321 #endif
00322          final_decision();
00323          return false;
00324       }
00325    }
00326 
00327    //-------------------------------------------------------------------------------------
00328    template<typename OsModel_P,
00329             typename Radio_P,
00330             typename Debug_P>
00331    bool
00332    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00333 	verify_msg(){
00334 
00335 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00336       debug().debug("Debug::Starting second verification!\n", radio().id() );
00337 #endif
00338       //verifier checks that sP = L + cC
00339       Point result;
00340       Point result1;
00341       eccfp.p_clear(&result);
00342       eccfp.p_clear(&result1);
00343       eccfp.p_clear(&Check2);
00344 
00345       //compute sP
00346       eccfp.c_mul(&result, &P, Valid);
00347 
00348       //compute cC
00349       eccfp.c_mul(&result1, &C, c);
00350 
00351       //compute L + cC
00352       eccfp.c_add_affine(&Check2, &L, &result1);
00353 
00354       //is the result correct???
00355       //compare sP with L + cC
00356       if(eccfp.p_equal(&Check2, &result)==true)
00357       {
00358 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00359          debug().debug( "Debug::Second check SUCCESS!\n", radio().id());
00360 #endif
00361          success_rounds++;
00362          final_decision();
00363          return true;
00364       }
00365       else
00366       {
00367 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00368          debug().debug( "Debug::Second check FAIL!\n", radio().id() );
00369 #endif
00370          final_decision();
00371          return false;
00372       }
00373    }
00374 
00375    //----------------------------------------------------------------------------------------
00376    template<typename OsModel_P,
00377             typename Radio_P,
00378             typename Debug_P>
00379    void
00380    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00381 	final_decision(){
00382 
00383       //were the round successful??the protocol accepts
00384       if(success_rounds==required_rounds)
00385       {
00386 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00387          debug().debug("Debug::Protocol finished with success.Secret Verified!!Prover HONEST!\n", radio().id() );
00388 #endif
00389          //send to prover the accept message
00390          block_data_t buffer[1];
00391          buffer[0]=ACCEPT_MSG;
00392          radio().send(Radio::BROADCAST_ADDRESS,1,buffer);
00393       }
00394       //the round failed, the protocol rejects
00395       else
00396       {
00397 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00398          debug().debug("Debug::Protocol finished without success.Secret NOT Verified!!Prover NOT HONEST\n", radio().id() );
00399 #endif
00400          block_data_t buffer[1];
00401          buffer[0]=REJECT_MSG;
00402          radio().send(Radio::BROADCAST_ADDRESS,1,buffer);
00403       }
00404    }
00405 
00406    //---------------------------------------------------------------------------
00407    template<typename OsModel_P,
00408             typename Radio_P,
00409             typename Debug_P>
00410    void
00411    TESTOFDLEQUALITYVerify<OsModel_P, Radio_P, Debug_P>::
00412 	receive( node_id_t from, size_t len, block_data_t *data ) {
00413 
00414       if( from == radio().id() ) return;
00415 
00416       if(data[0]==START_MSG)
00417       {
00418 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00419          debug().debug("Debug::Received a starting message::%d \n", radio().id());
00420 #endif
00421 
00422          //get points K and L
00423          eccfp.p_clear(&K);
00424          eccfp.p_clear(&L);
00425          //copy the two keys received after decoding
00426          eccfp.octet2point(&K, data+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00427          eccfp.octet2point(&L, data+2*(KEYDIGITS * NN_DIGIT_LEN +1)+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00428 
00429          //call the task to compute random c
00430          generate_random();
00431       }
00432 
00433       if(data[0]==CONT_MSG)
00434       {
00435 #ifdef ENABLE_TESTOFDLEQUALITY_DEBUG
00436          debug().debug("Debug::Received a continue message::%d \n", radio().id() );
00437 #endif
00438 
00439          //get private key x
00440          pmp.AssignZero(Valid, NUMWORDS);
00441          //decode the private key received
00442          pmp.Decode(Valid, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1);
00443 
00444          //call verify
00445          verify();
00446 
00447       }
00448 
00449    }
00450 
00451 } //end of wiselib namespace
00452 
00453 #endif /* TESTOFDLEQUALITY_VERIFIER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines