Wiselib
wiselib.testing/algorithms/crypto/ZeroKnowledgeProofsFp/schnorr-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_SCHNORRZKP_PROVER_H_
00021 #define __ALGORITHMS_CRYPTO_SHCNORRZKP_PROVER_H_
00022 
00023 
00024 #include "algorithms/crypto/eccfp.h"
00025 #include <string.h>
00026 
00027 //Uncomment to enable Debug
00028 #define ENABLE_SCHNORRZKP_DEBUG
00029 
00030 /* PROTOCOL DESCRIPTION
00031 
00032 Schnorr's Protocol
00033 
00034 Prover and Verifier agree on an elliptic curve E over a field Fn , a generator
00035 G in E/Fn . They both know B in E/Fn and Prover claims he knows x such
00036 that B = x * G.
00037 
00038 Protocol Steps
00039 
00040 1. Prover generates random r and computes A = r * G
00041 2. Prover sends A to Verifier
00042 3. Verifier computes c = HASH(G, B, A) and sends c to Prover
00043 4. Prover computes m = r + cx and sends m to Verifier
00044 5 Verifier checks that P = m*G-c*B =(r+cx)*G-c*B = r*G+cx*G - c*xG = A
00045 and that HASH(G, B, P ) = c.
00046 */
00047 
00048 namespace wiselib {
00049 
00050 template<typename OsModel_P, typename Radio_P = typename OsModel_P::Radio, typename Debug_P = typename OsModel_P::Debug>
00051    class SCHNORRZKPProve
00052    {
00053    public:
00054       typedef OsModel_P OsModel;
00055       typedef Radio_P Radio;
00056       typedef Debug_P Debug;
00057 
00058       typedef SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P> self_t;
00059      typedef typename Radio::node_id_t node_id_t;
00060      typedef typename Radio::size_t size_t;
00061      typedef typename Radio::block_data_t block_data_t;
00062      typedef self_t* self_pointer_t;
00063 
00066       SCHNORRZKPProve();
00067       ~SCHNORRZKPProve();
00069 
00070       int init( Radio& radio, Debug& debug )
00071      {
00072        radio_ = &radio;
00073        debug_ = &debug;
00074        return 0;
00075      }
00076 
00080 
00081       inline int init();
00082      inline int destruct();
00083 
00084      int enable_radio( void );
00085      int disable_radio( void );
00086 
00087       //message types
00088       enum MsgHeaders {
00089         START_MSG = 200,
00090         HASH_MSG = 201,
00091         CONT_MSG = 202,
00092         ACCEPT_MSG = 203,
00093         REJECT_MSG = 204
00094        };
00095 
00097       void key_setup(NN_DIGIT *privkey , Point *pubkey);
00098       void start_proof();
00099       void send_key();
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    uint16_t rounds;
00121 
00122    //private key that only the prover knows
00123    NN_DIGIT m[NUMWORDS];
00124 
00125    //public key that both prover and verifier know
00126    Point B;
00127 
00128    //private key r that is generated in every round and
00129    //its corresponding public key
00130    NN_DIGIT r[NUMWORDS];
00131    Point Verify;
00132 
00133    //the hash that will be received from verifier
00134    NN_DIGIT Hash[NUMWORDS];
00135 
00136    //data that will be sent to the verifier
00137    NN_DIGIT x[NUMWORDS];
00138 
00139    };
00140 
00141    // -----------------------------------------------------------------------
00142    template<typename OsModel_P,
00143       typename Radio_P,
00144       typename Debug_P>
00145    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00146 	SCHNORRZKPProve()
00147    :radio_(0),
00148     debug_(0)
00149    {}
00150 
00151    // -----------------------------------------------------------------------
00152    template<typename OsModel_P,
00153       typename Radio_P,
00154       typename Debug_P>
00155    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00156 	~SCHNORRZKPProve()
00157    {}
00158    //-----------------------------------------------------------------------
00159    template<typename OsModel_P,
00160          typename Radio_P,
00161          typename Debug_P>
00162    int
00163    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00164    init( void )
00165    {
00166      enable_radio();
00167      return 0;
00168    }
00169    //-----------------------------------------------------------------------------
00170    template<typename OsModel_P,
00171          typename Radio_P,
00172          typename Debug_P>
00173    int
00174    SCHNORRZKPProve<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    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00185    enable_radio( void )
00186    {
00187 #ifdef ENABLE_SCHNORRZKP_DEBUG
00188      debug().debug( "Debug::SCHNORR-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    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00202    disable_radio( void )
00203    {
00204 #ifdef ENABLE_SCHNORRZKP_DEBUG
00205      debug().debug( "SCHNORR-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    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00215 	key_setup( NN_DIGIT *privkey , Point *pubkey  ) {
00216 
00217       rounds=1;
00218 
00219       //copy the keys to the local variables
00220       pmp.AssignZero(m, NUMWORDS);
00221       pmp.Assign(m, privkey, NUMWORDS);
00222 
00223       //public key available to prover and verifier
00224       eccfp.p_clear(&B);
00225       eccfp.p_copy(&B, pubkey);
00226    }
00227 
00228    //---------------------------------------------------------------------------
00229    template<typename OsModel_P,
00230             typename Radio_P,
00231             typename Debug_P>
00232    void
00233    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00234 	start_proof( void ) {
00235 
00236 #ifdef ENABLE_SCHNORRZKP_DEBUG
00237       debug().debug("Debug::Starting Schnorr Interactive ZKP Prover on::%d \n", radio().id() );
00238 #endif
00239 
00240       //if the protocol is booting generate random r and compute A=rG
00241       //and send A  to verifier
00242       rounds++;
00243 
00244       //clear private and public key
00245       pmp.AssignZero(r, NUMWORDS);
00246       eccfp.p_clear(&Verify);
00247 
00248 #ifdef ENABLE_SCHNORRZKP_DEBUG
00249       debug().debug("Debug::Generating random r and compute A=rG. ::%d \n", radio().id() );
00250 #endif
00251 
00252       //generate random r and compute pubKey A=rG
00253       eccfp.gen_private_key(r, rounds);
00254       eccfp.gen_public_key(&Verify, r);
00255 
00256       //place the verify key in the buffer and send the message
00257       block_data_t msg[2*(KEYDIGITS*NN_DIGIT_LEN + 1) + 1];
00258       msg[0]=START_MSG;
00259 
00260       //convert point to octet
00261       eccfp.point2octet(msg+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify, FALSE);
00262 
00263 #ifdef ENABLE_SCHNORRZKP_DEBUG
00264       debug().debug("Debug::Finished calculations!Sending verify key to verifier. ::%d \n", radio().id() );
00265 #endif
00266       radio().send(Radio::BROADCAST_ADDRESS, 2*(KEYDIGITS*NN_DIGIT_LEN + 1) +1, msg);
00267    }
00268 
00269    //------------------------------------------------------------------------
00270    template<typename OsModel_P,
00271             typename Radio_P,
00272             typename Debug_P>
00273    void
00274    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00275 	send_key( void ) {
00276 
00277 #ifdef ENABLE_SCHNORRZKP_DEBUG
00278       debug().debug("Debug::Creating the new private key ::%d \n", radio().id() );
00279 #endif
00280 
00281       //prover computes x= r + cm
00282       //and sends x to verifier
00283 
00284       //clear private key x
00285       pmp.AssignZero(x, NUMWORDS);
00286 
00287       NN_DIGIT mid2[NUMWORDS];
00288       pmp.AssignZero(mid2, NUMWORDS);
00289 
00290       //first compute cm
00291       pmp.ModMult(mid2, Hash, m, param.r, NUMWORDS);
00292       //then add r+cm
00293       pmp.ModAdd(x, r, mid2, param.r, NUMWORDS);
00294 
00295       //send the message with x to verifier
00296       //if it is tails send to verifier m+r
00297       block_data_t buffer[KEYDIGITS*NN_DIGIT_LEN + 2];
00298       buffer[0]=CONT_MSG;
00299 
00300       //convert x to octet
00301       pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, x, NUMWORDS);
00302 
00303 #ifdef ENABLE_SCHNORRZKP_DEBUG
00304       debug().debug("Debug::Sending the new private key x to verifier::%d \n", radio().id() );
00305 #endif
00306       radio().send(Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN +2 , buffer);
00307    }
00308 
00309    //---------------------------------------------------------------------------
00310    template<typename OsModel_P,
00311             typename Radio_P,
00312             typename Debug_P>
00313    void
00314    SCHNORRZKPProve<OsModel_P, Radio_P, Debug_P>::
00315 	receive( node_id_t from, size_t len, block_data_t *data ) {
00316 
00317       if( from == radio().id() ) return;
00318 
00319       if(data[0]==HASH_MSG)
00320       {
00321 
00322 #ifdef ENABLE_SCHNORRZKP_DEBUG
00323          debug().debug("Debug::Received a hash message. Calling the send_key task.::%d \n", radio().id() );
00324 #endif
00325 
00326          //clear the private key and store it
00327          pmp.AssignZero(Hash, NUMWORDS);
00328          //decode the private key received
00329          pmp.Decode(Hash, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1);
00330 
00331          //calling the send_key task
00332          send_key();
00333       }
00334 
00335       if(data[0]==ACCEPT_MSG)
00336       {
00337 #ifdef ENABLE_SCHNORRZKP_DEBUG
00338          debug().debug("Debug::I got ACCEPTED from the verifier.YESSS!::%d \n", radio().id() );
00339 #endif
00340       }
00341 
00342       if(data[0]==REJECT_MSG)
00343       {
00344 #ifdef ENABLE_SCHNORRZKP_DEBUG
00345          debug().debug("Debug::I got REJECTED from the verifier.NOOO!::%d \n", radio().id() );
00346 #endif
00347       }
00348 
00349    }
00350 
00351 } //end of wiselib namespace
00352 
00353 #endif /* SCHNORRZKP_PROVER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines