Wiselib
wiselib.testing/algorithms/crypto/ZeroKnowledgeProofsFp/ZKPofSingleBit-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_ZKPOFSINGLEBIT_VERIFIER_H_
00021 #define __ALGORITHMS_ZKPOFSINGLEBIT_VERIFIER_H_
00022 
00023 #include "algorithms/crypto/eccfp.h"
00024 #include <string.h>
00025 
00026 //protocol needs to be executed for 1 round
00027 #define REQ_ROUNDS 1
00028 
00029 // Uncomment to enable Debug
00030 #define ENABLE_ZKPOFSINGLEBIT_DEBUG
00031 
00032 /* PROTOCOL DESCRIPTION
00033 
00034 Zero Knowledge Proof of Single Bit
00035 
00036 Prover and Verifier agree on an elliptic curve E over a field Fn , a generator
00037 G in E/Fn and H in E/Fn . Prover knows x and h such that B = x*G + h*H
00038 where h = +1 or -1.He wishes to convince Verifier that he really does know x and
00039 that h really is {+,-}1 without revealing x nor the sign bit.
00040 
00041 Protocol Steps
00042 
00043 1. Prover generates random s, d, w
00044 2. Prover computes A = s*G - d*(B+hH) and C = w*G
00045 3. If h =-1 Prover swaps(A,C) and sends A,C to Verifier
00046 4. Verifier generates random c and sends c to Prover
00047 5. Prover computes e = c-d and t = w + xe
00048 6. If h =-1 Prover swaps(d,e) and swaps(s,t)
00049 7. Prover sends to Verifier d, e, s, t
00050 8. Verifier checks that e + d = c, s*G = A + d(B + H)
00051 and that t*G = C + e(B-H)
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 ZKPOFSINGLEBITVerify
00058    {
00059    public:
00060       typedef OsModel_P OsModel;
00061       typedef Radio_P Radio;
00062       typedef Debug_P Debug;
00063 
00064       typedef ZKPOFSINGLEBITVerify<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       ZKPOFSINGLEBITVerify();
00073       ~ZKPOFSINGLEBITVerify();
00075 
00079 
00080       //message types
00081       //message types
00082       enum MsgHeaders {
00083         START_MSG = 200,
00084         RAND_MSG = 201,
00085         CONT_MSG = 202,
00086         ACCEPT_MSG = 203,
00087         REJECT_MSG = 204
00088          };
00089 
00090       int init( Radio& radio, Debug& debug )
00091      {
00092        radio_ = &radio;
00093        debug_ = &debug;
00094        return 0;
00095      }
00096 
00097      inline int init();
00098      inline int destruct();
00099 
00100      int enable_radio( void );
00101      int disable_radio( void );
00102 
00104       void key_setup(Point *pubkey1, Point *pubkey2);
00105       void generate_random();
00106       bool verify();
00107       bool verify_msg();
00108       void final_decision();
00109 
00110    protected:
00111            void receive( node_id_t from, size_t len, block_data_t *data );
00112 
00113    private:
00114 
00115    Radio& radio()
00116    { return *radio_; }
00117 
00118    Debug& debug()
00119    { return *debug_; }
00120 
00121    typename Radio::self_pointer_t radio_;
00122    typename Debug::self_pointer_t debug_;
00123 
00124    //necessary class objects
00125    ECCFP eccfp;
00126    PMP pmp;
00127 
00128    //# of rounds
00129    uint8_t rounds;
00130 
00131       //# of successfull rounds
00132    uint8_t success_rounds;
00133 
00134    //# of required rounds
00135    uint8_t required_rounds;
00136 
00137    //the hash calculated on the point received by the prover
00138    NN_DIGIT c[NUMWORDS];
00139 
00140    //private keys that will be received by the prover
00141    NN_DIGIT d[NUMWORDS];
00142    NN_DIGIT e[NUMWORDS];
00143    NN_DIGIT s[NUMWORDS];
00144    NN_DIGIT t[NUMWORDS];
00145 
00146    //public key that both prover and verifier know
00147    Point P;
00148    Point C;
00149 
00150    //public key A to be received by the prover
00151    Point K;
00152    Point L;
00153 
00154    };
00155 
00156    // -----------------------------------------------------------------------
00157    template<typename OsModel_P,
00158          typename Radio_P,
00159          typename Debug_P>
00160    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00161 	ZKPOFSINGLEBITVerify()
00162    :radio_(0),
00163     debug_(0)
00164    {}
00165 
00166    // -----------------------------------------------------------------------
00167    template<typename OsModel_P,
00168          typename Radio_P,
00169          typename Debug_P>
00170    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00171 	~ZKPOFSINGLEBITVerify()
00172    {}
00173 
00174    //-----------------------------------------------------------------------
00175    template<typename OsModel_P,
00176                typename Radio_P,
00177                typename Debug_P>
00178    int
00179    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00180 	init( void )
00181    {
00182      enable_radio();
00183      return 0;
00184    }
00185    //-----------------------------------------------------------------------------
00186    template<typename OsModel_P,
00187          typename Radio_P,
00188          typename Debug_P>
00189    int
00190    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00191 	destruct( void )
00192    {
00193      return disable_radio();
00194    }
00195    //---------------------------------------------------------------------------
00196    template<typename OsModel_P,
00197          typename Radio_P,
00198          typename Debug_P>
00199    int
00200    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00201 	enable_radio( void )
00202    {
00203 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00204       debug().debug( "ZKP Of Single Bit Verifier: Boot for %i\n", radio().id() );
00205 #endif
00206 
00207      radio().enable_radio();
00208      radio().template reg_recv_callback<self_t, &self_t::receive>( this );
00209 
00210      return 0;
00211    }
00212    //---------------------------------------------------------------------------
00213    template<typename OsModel_P,
00214          typename Radio_P,
00215          typename Debug_P>
00216    int
00217    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00218 	disable_radio( void )
00219    {
00220 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00221       debug().debug( "ZKP of single bit Verify: Disable\n" );
00222 #endif
00223      return -1;
00224    }
00225 
00226    //----------------------------------------------------------------------
00227    template<typename OsModel_P,
00228             typename Radio_P,
00229             typename Debug_P>
00230    void
00231    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00232 	key_setup( Point *pubkey1, Point *pubkey2 ) {
00233 
00234 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00235       debug().debug("Debug::Start ZKP of Single Bit Verifier on::%d \n", radio().id() );
00236 #endif
00237       rounds=89;
00238       success_rounds=0;
00239       required_rounds=REQ_ROUNDS;
00240 
00241       //second generator P
00242       eccfp.p_clear(&P);
00243       eccfp.p_copy(&P, pubkey1);
00244 
00245       //get second public key
00246       eccfp.p_clear(&C);
00247       eccfp.p_copy(&C, pubkey2);
00248 
00249    }
00250    //------------------------------------------------------------------------------------
00251       template<typename OsModel_P,
00252          typename Radio_P,
00253          typename Debug_P>
00254       void
00255       ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00256 		generate_random(){
00257 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00258          debug().debug("Debug::Generating random number c!\n", radio().id() );
00259 #endif
00260 
00261          //clear the private key c
00262          pmp.AssignZero(c, NUMWORDS);
00263          //and generate random number c
00264          eccfp.gen_private_key(c, rounds);
00265 
00266          uint8_t buffer[KEYDIGITS*NN_DIGIT_LEN+2];
00267          buffer[0]=RAND_MSG;
00268          //convert c to octet and place to buffer
00269          pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, c, NUMWORDS);
00270 
00271 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00272          debug().debug("Debug::Finished generating random number c!Sending c to prover. ::%d \n", radio().id() );
00273 #endif
00274          //send message
00275          radio().send(Radio::BROADCAST_ADDRESS, KEYDIGITS*NN_DIGIT_LEN+2 , buffer);
00276       }
00277 
00278    //------------------------------------------------------------------------------------
00279    template<typename OsModel_P,
00280             typename Radio_P,
00281             typename Debug_P>
00282    bool
00283    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00284 	verify(){
00285 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00286       debug().debug("Debug::Starting Verify!\n", radio().id() );
00287 #endif
00288 
00289       //first check that e = c + d
00290       NN_DIGIT mid[NUMWORDS];
00291       pmp.AssignZero(mid, NUMWORDS);
00292       pmp.ModAdd(mid, d, e, param.r, NUMWORDS);
00293 
00294       if(pmp.Cmp(mid, c, NUMWORDS) == 0)
00295       {
00296 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00297          debug().debug("Debug::First Check SUCCESS!\n", radio().id() );
00298 #endif
00299       }
00300       else
00301       {
00302 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00303          debug().debug("Debug::First Check FAIL!\n", radio().id() );
00304 #endif
00305       }
00306 
00307       //verifier then checks that sG = K + d( C + P)
00308       Point result;
00309       Point result1;
00310       Point result2;
00311       Point result3;
00312       Point Check;
00313 
00314       eccfp.p_clear(&result);
00315       eccfp.p_clear(&result1);
00316       eccfp.p_clear(&result2);
00317       eccfp.p_clear(&result3);
00318       eccfp.p_clear(&Check);
00319 
00320       //compute sG
00321       eccfp.gen_public_key(&result, s);
00322 
00323       //compute C+P
00324       eccfp.c_add_affine(&result1, &C, &P);
00325       //compute d(C+P)
00326       eccfp.c_mul(&result2, &result1, d);
00327 
00328       //compute K + d(C + P)
00329       eccfp.c_add_affine(&Check, &K, &result2);
00330 
00331       //is the result correct???
00332       if(eccfp.p_equal(&result, &Check)==true)
00333       {
00334 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00335          debug().debug("Debug::Second check SUCCESS!\n", radio().id() );
00336 #endif
00337          verify_msg();
00338          return true;
00339       }
00340       else
00341       {
00342 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00343          debug().debug("Debug::Second check FAIL!\n", radio().id() );
00344 #endif
00345          final_decision();
00346          return false;
00347       }
00348    }
00349 
00350    //-------------------------------------------------------------------------------------
00351       template<typename OsModel_P,
00352          typename Radio_P,
00353          typename Debug_P>
00354       bool
00355       ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00356 		verify_msg(){
00357 
00358 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00359          debug().debug("Debug::Starting verify message!\n", radio().id() );
00360 #endif
00361          //verifier checks that tG = L + e (C-P)
00362          Point result;
00363          Point result1;
00364          Point result2;
00365          Point result3;
00366          Point Check2;
00367 
00368          eccfp.p_clear(&result);
00369          eccfp.p_clear(&result1);
00370          eccfp.p_clear(&result2);
00371          eccfp.p_clear(&result3);
00372          eccfp.p_clear(&Check2);
00373 
00374          //compute C-P
00375          //subtraction in F_{p} if P=(x,y) then -P=(x,-y)
00376          eccfp.p_copy(&result, &P);
00377          pmp.ModNeg(result.y, result.y, param.p, NUMWORDS);
00378          eccfp.c_add_affine(&result1, &C, &result);
00379 
00380          //compute e(C-P)
00381          eccfp.c_mul(&result2, &result1, e);
00382 
00383          //compute L + e(C-P)
00384          eccfp.c_add_affine(&result3, &L, &result2);
00385 
00386          //compute tG
00387          eccfp.gen_public_key(&Check2, t);
00388 
00389          //is the result correct???
00390          if(eccfp.p_equal(&Check2, &result3)== true)
00391          {
00392 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00393             debug().debug("Debug::Third check SUCCESS!\n", radio().id() );
00394 #endif
00395             success_rounds++;
00396             final_decision();
00397             return true;
00398          }
00399          else
00400          {
00401 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00402             debug().debug("Debug::Third check FAIL!\n", radio().id() );
00403 #endif
00404             final_decision();
00405             return false;
00406          }
00407 
00408       }
00409 
00410    //----------------------------------------------------------------------------------------
00411    template<typename OsModel_P,
00412             typename Radio_P,
00413             typename Debug_P>
00414    void
00415    ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00416 	final_decision(){
00417 
00418       //were the round successful??the protocol accepts
00419       if(success_rounds==required_rounds)
00420       {
00421 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00422          debug().debug("Debug::Protocol finished with success.Secret Verified!!Prover HONEST!\n", radio().id() );
00423 #endif
00424          //send to prover the accept message
00425          block_data_t buffer[1];
00426          buffer[0]=ACCEPT_MSG;
00427          radio().send(Radio::BROADCAST_ADDRESS, 1, buffer);
00428       }
00429       //the round failed, the protocol rejects
00430       else
00431       {
00432 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00433          debug().debug("Debug::Protocol finished without success.Secret NOT Verified!!Prover NOT HONEST\n", radio().id() );
00434 #endif
00435          block_data_t buffer[1];
00436          buffer[0]=REJECT_MSG;
00437          radio().send(Radio::BROADCAST_ADDRESS, 1, buffer);
00438       }
00439    }
00440 
00441    //---------------------------------------------------------------------------
00442       template<typename OsModel_P,
00443          typename Radio_P,
00444          typename Debug_P>
00445       void
00446       ZKPOFSINGLEBITVerify<OsModel_P, Radio_P, Debug_P>::
00447 		receive( node_id_t from, size_t len, block_data_t *data ) {
00448 
00449          if( from == radio().id() ) return;
00450 
00451          if(data[0]==START_MSG)
00452          {
00453 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00454             debug().debug("Debug::Received a starting message::%d \n", radio().id());
00455 #endif
00456 
00457             //get points K and L
00458             eccfp.p_clear(&K);
00459             eccfp.p_clear(&L);
00460             //convert octet received to point K
00461             eccfp.octet2point(&K, data+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00462             //convert octet received to point K
00463             eccfp.octet2point(&L, data+2*(KEYDIGITS*NN_DIGIT_LEN+1)+1, 2*(KEYDIGITS * NN_DIGIT_LEN +1));
00464 
00465             //call the task to compute random c
00466             generate_random();
00467          }
00468 
00469          if(data[0]==CONT_MSG)
00470          {
00471 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00472             debug().debug("Debug::Received a continue message with private keys::%d \n", radio().id() );
00473 #endif
00474 
00475             //get private keys d,e,s,t
00476             pmp.AssignZero(d, NUMWORDS);
00477             pmp.AssignZero(e, NUMWORDS);
00478             pmp.AssignZero(s, NUMWORDS);
00479             pmp.AssignZero(t, NUMWORDS);
00480 
00481             pmp.Decode(d, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1);
00482             pmp.Decode(e, NUMWORDS, data+KEYDIGITS * NN_DIGIT_LEN +1+1, KEYDIGITS * NN_DIGIT_LEN +1);
00483             pmp.Decode(s, NUMWORDS, data+2*(KEYDIGITS * NN_DIGIT_LEN +1)+1, KEYDIGITS * NN_DIGIT_LEN +1);
00484             pmp.Decode(t, NUMWORDS, data+3*(KEYDIGITS * NN_DIGIT_LEN +1)+1, KEYDIGITS * NN_DIGIT_LEN +1);
00485 
00486             //call the task for verification
00487             verify();
00488          }
00489 
00490       }
00491 
00492 } //end of wiselib namespace
00493 
00494 #endif /* ZKPOFSINGLEBIT_VERIFIER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines