Wiselib
wiselib.testing/algorithms/crypto/ZeroKnowledgeProofsFp/schnorr-zkpnint-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 "algorithms/crypto/sha1.h"
00026 
00027 #include <string.h>
00028 
00029 //protocol needs to be executed for 1 round
00030 #define REQ_ROUNDS 1
00031 
00032 // Uncomment to enable Debug
00033 #define ENABLE_ZKPNINT_DEBUG
00034 
00035 /* PROTOCOL DESCRIPTION
00036 
00037 Non-interactive Schnorr's Protocol
00038 
00039 Prover and Verifier agree on an elliptic curve E over a field Fn , a generator
00040 G in E/Fn , P in E/Fn and a hash function HASH (e.g. SHA-1). Both know
00041 B in E/Fn and Prover claims that he knows x such that B = x*G.
00042 
00043 Protocol Steps
00044 
00045 1. Prover generates random r and computes A = r*G
00046 2. Prover computes c = HASH(x*P, r*P, r*G)
00047 3. Prover computes s = r + cx
00048 4. Prover sends to Verifier the message : " s||x*P ||r*P ||r*G "
00049 5. Verifier computes c = HASH(x*P, r*P, r*G)
00050 6. Verifier checks that s*G = (r + cx)*G = r*G + cx*G = r*G + c*B
00051 7. Verifier checks that s*P = (r + cx)*P = r*P + cx*P = r*P + c*xP
00052 */
00053 
00054 namespace wiselib {
00055 
00056 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug>
00057    class ZKPNINTVerify
00058    {
00059    public:
00060       typedef OsModel_P OsModel;
00061       typedef Radio_P Radio;
00062       typedef Debug_P Debug;
00063 
00064       typedef ZKPNINTVerify<OsModel_P, Radio_P, Debug_P> self_t;
00065      typedef typename Radio::node_id_t node_id_t;
00066      typedef typename Radio::size_t size_t;
00067      typedef typename Radio::block_data_t block_data_t;
00068      typedef self_t* self_pointer_t;
00069 
00072       ZKPNINTVerify();
00073       ~ZKPNINTVerify();
00075 
00079 
00080       //message types
00081       //message types
00082       enum MsgHeaders {
00083         START_MSG = 200,
00084         START_MSG_CONT = 201,
00085         ACCEPT_MSG = 202,
00086         REJECT_MSG = 203
00087        };
00088 
00090       void key_setup(Point *pubkey, Point *pubkey2);
00091       bool verify();
00092       bool verify_msg();
00093       void final_decision();
00094 
00095       int init( Radio& radio, Debug& debug )
00096      {
00097        radio_ = &radio;
00098        debug_ = &debug;
00099        return 0;
00100      }
00101 
00102      inline int init();
00103      inline int destruct();
00104 
00105      int enable_radio( void );
00106      int disable_radio( void );
00107 
00108    protected:
00109            void receive( node_id_t from, size_t len, block_data_t *data );
00110 
00111    private:
00112 
00113    Radio& radio()
00114    { return *radio_; }
00115 
00116    Debug& debug()
00117    { return *debug_; }
00118 
00119    typename Radio::self_pointer_t radio_;
00120    typename Debug::self_pointer_t debug_;
00121 
00122     //necessary class objects
00123    ECCFP eccfp;
00124    PMP pmp;
00125 
00126    //# of successfull rounds
00127    uint8_t success_rounds;
00128 
00129    //# of required rounds
00130    uint8_t required_rounds;
00131 
00132    //the hash calculated on the points received by the prover
00133    NN_DIGIT c[NUMWORDS];
00134 
00135    //private key that will be received by the prover
00136    NN_DIGIT s[NUMWORDS];
00137 
00138    //public key that both prover and verifier know
00139    Point B;
00140 
00141    //public key that represents the message
00142    Point P;
00143 
00144    //public keys mP and rP and A to be received by the prover
00145    Point A;
00146    Point MP;
00147    Point RP;
00148 
00149    };
00150 
00151    // -----------------------------------------------------------------------
00152    template<typename OsModel_P,
00153          typename Radio_P,
00154          typename Debug_P>
00155    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00156 	ZKPNINTVerify()
00157    : radio_(0),
00158      debug_(0)
00159    {}
00160 
00161    // -----------------------------------------------------------------------
00162    template<typename OsModel_P,
00163          typename Radio_P,
00164          typename Debug_P>
00165    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00166 	~ZKPNINTVerify()
00167    {}
00168 
00169    //-----------------------------------------------------------------------
00170    template<typename OsModel_P,
00171          typename Radio_P,
00172          typename Debug_P>
00173    int
00174    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00175 	init( void )
00176    {
00177      enable_radio();
00178      return 0;
00179    }
00180    //-----------------------------------------------------------------------------
00181    template<typename OsModel_P,
00182          typename Radio_P,
00183          typename Debug_P>
00184    int
00185    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00186 	destruct( void )
00187    {
00188      return disable_radio();
00189    }
00190    //---------------------------------------------------------------------------
00191    template<typename OsModel_P,
00192          typename Radio_P,
00193          typename Debug_P>
00194    int
00195    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00196 	enable_radio( void )
00197    {
00198 #ifdef ENABLE_ZKPNINT_DEBUG
00199       debug().debug( "ZKPProve: Boot for %i\n", radio().id() );
00200 #endif
00201 
00202      radio().enable_radio();
00203      radio().template reg_recv_callback<self_t, &self_t::receive>( this );
00204 
00205      return 0;
00206    }
00207    //---------------------------------------------------------------------------
00208    template<typename OsModel_P,
00209          typename Radio_P,
00210          typename Debug_P>
00211    int
00212    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00213 	disable_radio( void )
00214    {
00215 #ifdef ENABLE_ZKPNINT_DEBUG
00216       debug().debug( "ZKPProve: Disable\n" );
00217 #endif
00218      return -1;
00219    }
00220 
00221    //----------------------------------------------------------------------
00222    template<typename OsModel_P,
00223             typename Radio_P,
00224             typename Debug_P>
00225    void
00226    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00227 	key_setup( Point *pubkey, Point *pubkey2 ) {
00228 
00229 #ifdef ENABLE_ZKPNINT_DEBUG
00230       debug().debug("Debug::Start ZKP Non-interactive Verifier on::%d \n", radio().id() );
00231 #endif
00232       success_rounds=0;
00233       required_rounds=REQ_ROUNDS;
00234 
00235       //public key available to prover and verifier
00236       eccfp.p_clear(&B);
00237       eccfp.p_copy(&B, pubkey);
00238 
00239       //message available to prover and verifier
00240       eccfp.p_clear(&P);
00241       eccfp.p_copy(&P, pubkey2);
00242 
00243    }
00244 
00245    //------------------------------------------------------------------------------------
00246    template<typename OsModel_P,
00247             typename Radio_P,
00248             typename Debug_P>
00249    bool
00250    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00251 	verify(){
00252 #ifdef ENABLE_ZKPNINT_DEBUG
00253       debug().debug("Debug::Starting Verify!\n", radio().id() );
00254 #endif
00255 
00256       //compute c=HASH(mP, rP, A)
00257       block_data_t input[6*(KEYDIGITS * NN_DIGIT_LEN +1)];
00258       for(int16_t i=0; i< 6*(KEYDIGITS*NN_DIGIT_LEN +1); i++)
00259       {
00260          input[i]=0;
00261       }
00262       block_data_t b[20];
00263       //convert point mP to octet and place to input
00264       eccfp.point2octet(input, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &MP, FALSE);
00265       //convert point rP to octet and place to input
00266       eccfp.point2octet(input + 2*(KEYDIGITS*NN_DIGIT_LEN + 1), 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &RP, FALSE);
00267       //convert point A to octet and place to input
00268       eccfp.point2octet(input + 4*(KEYDIGITS*NN_DIGIT_LEN + 1), 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &A, FALSE);
00269 
00270       //digest
00271       SHA1Context sha;
00272       SHA1::SHA1Reset(&sha);
00273       SHA1::SHA1Update(&sha, input, 6*(KEYDIGITS * NN_DIGIT_LEN +1));
00274       SHA1::SHA1Digest(&sha, b);
00275 
00276       //place the hash in a key
00277       NN_DIGIT key[NUMWORDS];
00278       pmp.AssignZero(key, NUMWORDS);
00279       //decode the private key received
00280       pmp.Decode(key, NUMWORDS, b, 20);
00281       //mod n the hash output
00282       pmp.AssignZero(c, NUMWORDS);
00283       pmp.Mod(c, key, NUMWORDS, param.r, NUMWORDS);
00284 
00285       //check that sG = A + cB
00286       Point result;
00287       Point result1;
00288       Point result2;
00289       eccfp.p_clear(&result);
00290       eccfp.p_clear(&result1);
00291       eccfp.p_clear(&result2);
00292 
00293       //compute sG
00294       eccfp.gen_public_key(&result, s);
00295       //compute cB
00296       eccfp.c_mul(&result1, &B, c);
00297       //compute A + cB
00298       eccfp.c_add_affine(&result2, &A, &result1);
00299 
00300       //is the result correct???
00301       if(eccfp.p_equal(&result, &result2)==true)
00302       {
00303 #ifdef ENABLE_ZKPNINT_DEBUG
00304          debug().debug("Debug::First check SUCCESS!\n", radio().id() );
00305 #endif
00306          verify_msg();
00307          return true;
00308       }
00309       else
00310       {
00311 #ifdef ENABLE_ZKPNINT_DEBUG
00312          debug().debug("Debug::First check FAIL!\n", radio().id() );
00313 #endif
00314          final_decision();
00315          return false;
00316       }
00317    }
00318 
00319    //-------------------------------------------------------------------------------------
00320    template<typename OsModel_P,
00321             typename Radio_P,
00322             typename Debug_P>
00323    bool
00324    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00325 	verify_msg(){
00326 
00327 #ifdef ENABLE_ZKPNINT_DEBUG
00328       debug().debug("Debug::Starting verify message!\n", radio().id() );
00329 #endif
00330 
00331       //now check that sP = rP + cmP
00332       Point result;
00333       Point result1;
00334       Point result2;
00335       eccfp.p_clear(&result);
00336       eccfp.p_clear(&result1);
00337       eccfp.p_clear(&result2);
00338 
00339       //compute sP
00340       eccfp.c_mul(&result, &P, s);
00341       //compute c*MP
00342       eccfp.c_mul(&result1, &MP, c);
00343       //compute rP + cMP
00344       eccfp.c_add_affine(&result2, &RP, &result1);
00345 
00346       //is the result correct???
00347       if(eccfp.p_equal(&result, &result2)==true)
00348       {
00349 #ifdef ENABLE_ZKPNINT_DEBUG
00350          debug().debug("Debug::Second check SUCCESS!\n", radio().id() );
00351 #endif
00352          success_rounds++;
00353          final_decision();
00354          return true;
00355       }
00356       else
00357       {
00358 #ifdef ENABLE_ZKPNINT_DEBUG
00359          debug().debug("Debug::Second check FAIL!\n", radio().id());
00360 #endif
00361          final_decision();
00362          return false;
00363       }
00364 
00365    }
00366 
00367    //----------------------------------------------------------------------------------------
00368    template<typename OsModel_P,
00369             typename Radio_P,
00370             typename Debug_P>
00371    void
00372    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00373 	final_decision(){
00374 
00375       //were the round successful??the protocol accepts
00376       if(success_rounds==required_rounds)
00377       {
00378 #ifdef ENABLE_ZKPNINT_DEBUG
00379          debug().debug("Debug::Protocol finished with success.Secret Verified!!Prover HONEST!\n", radio().id() );
00380 #endif
00381          //send to prover the accept message
00382          block_data_t buffer[1];
00383          buffer[0]=ACCEPT_MSG;
00384          radio().send(Radio::BROADCAST_ADDRESS, 1, buffer);
00385       }
00386       //some rounds failed, the protocol rejects
00387       else
00388       {
00389 #ifdef ENABLE_ZKPNINT_DEBUG
00390          debug().debug("Debug::Protocol finished without success.Secret NOT Verified!!Prover NOT HONEST\n", radio().id() );
00391 #endif
00392          block_data_t buffer[1];
00393          buffer[0]=REJECT_MSG;
00394          radio().send(Radio::BROADCAST_ADDRESS, 1, buffer);
00395       }
00396    }
00397 
00398    //---------------------------------------------------------------------------
00399    template<typename OsModel_P,
00400             typename Radio_P,
00401             typename Debug_P>
00402    void
00403    ZKPNINTVerify<OsModel_P, Radio_P, Debug_P>::
00404 	receive( node_id_t from, size_t len, block_data_t *data ) {
00405 
00406       if( from == radio().id() ) return;
00407 
00408       if(data[0]==START_MSG)
00409       {
00410 #ifdef ENABLE_ZKPNINT_DEBUG
00411          debug().debug("Debug::Received a starting message::%d \n", radio().id() );
00412 #endif
00413          //get s and point mP
00414 
00415          //first get s and clear Valid
00416          //then get s and place to Valid
00417          pmp.AssignZero(s, NUMWORDS);
00418          //decode the private key received
00419          pmp.Decode(s, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1);
00420 
00421          //then get point mP
00422          eccfp.p_clear(&MP);
00423          //convert octet received to point MP
00424          eccfp.octet2point(&MP, data+ 1 + (KEYDIGITS*NN_DIGIT_LEN+1), 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00425       }
00426 
00427       if(data[0]==START_MSG_CONT)
00428       {
00429 #ifdef ENABLE_ZKPNINT_DEBUG
00430          debug().debug("Debug::Received a continue starting message::%d \n", radio().id() );
00431 #endif
00432 
00433          //first get rP
00434          eccfp.p_clear(&RP);
00435          eccfp.octet2point(&RP, data+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00436 
00437          //then get rG
00438          eccfp.p_clear(&A);
00439          eccfp.octet2point(&A, data+ 1 + 2*(KEYDIGITS*NN_DIGIT_LEN+1), 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00440 
00441 #ifdef ENABLE_ZKPNINT_DEBUG
00442          debug().debug("Debug::Calling the function verify()::%d \n", radio().id() );
00443 #endif
00444          //call verify
00445          verify();
00446       }
00447 
00448    }
00449 
00450 } //end of namespace
00451 
00452 #endif /* ZKP_VERIFIER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines