Wiselib
wiselib.testing/algorithms/crypto/ZeroKnowledgeProofsFp/ZKPofSingleBit-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_ZKPOFSINGLEBIT_PROVER_H_
00021 #define __ALGORITHMS_CRYPTO_ZKPOFSINGLEBIT_PROVER_H_
00022 
00023 #include "algorithms/crypto/eccfp.h"
00024 #include <string.h>
00025 
00026 //Uncomment to enable Debug
00027 #define ENABLE_ZKPOFSINGLEBIT_DEBUG
00028 
00029 /* PROTOCOL DESCRIPTION
00030 
00031 Zero Knowledge Proof of Single Bit
00032 
00033 Prover and Verifier agree on an elliptic curve E over a field Fn , a generator
00034 G in E/Fn and H in E/Fn . Prover knows x and h such that B = x*G + h*H
00035 where h = +1 or -1.He wishes to convince Verifier that he really does know x and
00036 that h really is {+,-}1 without revealing x nor the sign bit.
00037 
00038 Protocol Steps
00039 
00040 1. Prover generates random s, d, w
00041 2. Prover computes A = s*G - d*(B+hH) and C = w*G
00042 3. If h = -1 Prover swaps(A,C) and sends A,C to Verifier
00043 4. Verifier generates random c and sends c to Prover
00044 5. Prover computes e = c-d and t = w + xe
00045 6. If h =-1 Prover swaps(d,e) and swaps(s,t)
00046 7. Prover sends to Verifier d, e, s, t
00047 8. Verifier checks that e + d = c, s*G = A + d(B + H)
00048 and that t*G = C + e(B-H)
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 ZKPOFSINGLEBITProve
00055    {
00056    public:
00057       typedef OsModel_P OsModel;
00058       typedef Radio_P Radio;
00059       typedef Debug_P Debug;
00060 
00061       typedef ZKPOFSINGLEBITProve<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      ZKPOFSINGLEBITProve();
00070       ~ZKPOFSINGLEBITProve();
00072 
00076 
00077       //message types
00078       enum MsgHeaders {
00079         START_MSG = 200,
00080         RAND_MSG = 201,
00081         CONT_MSG = 202,
00082         ACCEPT_MSG = 203,
00083         REJECT_MSG = 204
00084        };
00085 
00086       int init( Radio& radio, Debug& debug )
00087      {
00088        radio_ = &radio;
00089        debug_ = &debug;
00090        return 0;
00091      }
00092 
00093      inline int init();
00094      inline int destruct();
00095 
00096      int enable_radio( void );
00097      int disable_radio( void );
00098 
00100       void key_setup(NN_DIGIT *privkey, Point *pubkey1, Point *pubkey2, int8_t sign);
00101       void start_proof();
00102       void send_key();
00103       void swap_keys(NN_DIGIT *a, NN_DIGIT *b);
00104       void swap_points(Point *P1, Point *P2);
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    //rounds of the protocol used for seeding the rand function
00125    uint8_t rounds;
00126 
00127    //sign bit only the prover knows
00128    int8_t h;
00129 
00130    //private key that only the prover knows
00131    NN_DIGIT m[NUMWORDS];
00132 
00133    //private keys to be generated by prover
00134    NN_DIGIT s[NUMWORDS];
00135    NN_DIGIT d[NUMWORDS];
00136    NN_DIGIT w[NUMWORDS];
00137 
00138    //public keys that both prover and verifier know
00139    //Point B;
00140    Point P;
00141    Point C;
00142 
00143    //public keys to send to verifier with the first message
00144    Point Verify;
00145    Point Verify2;
00146 
00147    //the random private key that will be received from verifier
00148    NN_DIGIT c[NUMWORDS];
00149 
00150    //data that will be sent to the verifier
00151    NN_DIGIT x[NUMWORDS];
00152 
00153    };
00154 
00155    // -----------------------------------------------------------------------
00156    template<typename OsModel_P,
00157       typename Radio_P,
00158       typename Debug_P>
00159    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00160 	ZKPOFSINGLEBITProve()
00161    :radio_(0),
00162     debug_(0)
00163    {}
00164 
00165    // -----------------------------------------------------------------------
00166    template<typename OsModel_P,
00167       typename Radio_P,
00168       typename Debug_P>
00169    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00170 	~ZKPOFSINGLEBITProve()
00171    {}
00172 
00173    //-----------------------------------------------------------------------
00174    template<typename OsModel_P,
00175             typename Radio_P,
00176             typename Debug_P>
00177    int
00178    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00179 	init( void )
00180    {
00181      enable_radio();
00182      return 0;
00183    }
00184    //-----------------------------------------------------------------------------
00185    template<typename OsModel_P,
00186          typename Radio_P,
00187          typename Debug_P>
00188    int
00189    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00190 	destruct( void )
00191    {
00192      return disable_radio();
00193    }
00194    //---------------------------------------------------------------------------
00195    template<typename OsModel_P,
00196          typename Radio_P,
00197          typename Debug_P>
00198    int
00199    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00200 	enable_radio( void )
00201    {
00202 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00203       debug().debug( "ZKP Of Single Bit Prove: Boot for %i\n", radio().id() );
00204 #endif
00205 
00206      radio().enable_radio();
00207      radio().template reg_recv_callback<self_t, &self_t::receive>( this );
00208 
00209      return 0;
00210    }
00211    //---------------------------------------------------------------------------
00212    template<typename OsModel_P,
00213          typename Radio_P,
00214          typename Debug_P>
00215    int
00216    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00217 	disable_radio( void )
00218    {
00219 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00220       debug().debug( "ZKP of single bit Prove: Disable\n" );
00221 #endif
00222      return -1;
00223    }
00224 
00225    //-----------------------------------------------------------------------
00226    template<typename OsModel_P,
00227             typename Radio_P,
00228             typename Debug_P>
00229    void
00230    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00231 	key_setup( NN_DIGIT *privkey, Point *pubkey1, Point *pubkey2, int8_t sign ) {
00232 
00233       rounds=1;
00234 
00235       h=sign;  //get the sign
00236 
00237       //prover's private secret key
00238       pmp.AssignZero(m, NUMWORDS);
00239       pmp.Assign(m, privkey, NUMWORDS);
00240 
00241       //get generator P
00242       eccfp.p_clear(&P);
00243       eccfp.p_copy(&P, pubkey1);
00244 
00245       //get the final point C = mG + hP
00246       eccfp.p_clear(&C);
00247       eccfp.p_copy(&C, pubkey2);
00248    }
00249    //--------------------------------------------------------------------------
00250    template<typename OsModel_P,
00251             typename Radio_P,
00252             typename Debug_P>
00253    void
00254    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00255 	swap_keys( NN_DIGIT *a, NN_DIGIT *b )
00256    {
00257       NN_DIGIT mid[NUMWORDS];
00258       pmp.AssignZero(mid, NUMWORDS);
00259       pmp.Assign(mid, a, NUMWORDS);
00260       pmp.Assign(a, b, NUMWORDS );
00261       pmp.Assign(b, mid, NUMWORDS);
00262    }
00263    //--------------------------------------------------------------------------
00264    template<typename OsModel_P,
00265             typename Radio_P,
00266             typename Debug_P>
00267    void
00268    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00269 	swap_points( Point * P1, Point * P2 )
00270    {
00271       Point Mid;
00272       eccfp.p_clear(&Mid);
00273       eccfp.p_copy(&Mid, P1);
00274       eccfp.p_copy(P1, P2);
00275       eccfp.p_copy(P2, &Mid);
00276    }
00277    //---------------------------------------------------------------------------
00278    template<typename OsModel_P,
00279             typename Radio_P,
00280             typename Debug_P>
00281    void
00282    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00283 	start_proof( void ) {
00284 
00285 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00286       debug().debug("Debug::Starting ZKP of Single Bit Prover on::%d \n", radio().id() );
00287 #endif
00288 
00289       //if the protocol is booting generate random s,d,w
00290       rounds++;
00291 
00292       //clear private keys
00293       pmp.AssignZero(s, NUMWORDS);
00294       pmp.AssignZero(d, NUMWORDS);
00295       pmp.AssignZero(w, NUMWORDS);
00296 
00297       //generate private keys
00298       eccfp.gen_private_key(s, rounds);
00299       eccfp.gen_private_key(d, rounds+1);
00300       eccfp.gen_private_key(w, rounds+11);
00301 
00302       //compute Verify = sG - d(B+hH)
00303       eccfp.p_clear(&Verify);
00304 
00305       Point result;
00306       Point result1;
00307       Point result2;
00308       Point result3;
00309 
00310       eccfp.p_clear(&result);
00311       eccfp.p_clear(&result1);
00312       eccfp.p_clear(&result2);
00313       eccfp.p_clear(&result3);
00314 
00315       //first compute sG
00316       eccfp.gen_public_key(&result, s);
00317 
00318       //then compute Verify2 = wG
00319       eccfp.p_clear(&Verify2);
00320       eccfp.gen_public_key(&Verify2, w);
00321 
00322       if(h == 1)
00323       {
00324          //in case where h = +1 no swap is needed
00325 
00326          //compute B+H
00327          eccfp.c_add_affine(&result1, &C, &P);
00328          //compute d(B+H)
00329          eccfp.c_mul(&result2, &result1, d);
00330          //compute Verify = sG -d(B+H)
00331          //subtraction in F_{p} if P=(x,y) then -P=(x,-y)
00332          pmp.ModNeg(result2.y, result2.y, param.p, NUMWORDS);
00333          eccfp.c_add_affine(&Verify, &result, &result2);
00334       }
00335       else
00336       {
00337          //in case where h=-1 swap is needed
00338 
00339          //compute B-H
00340          eccfp.p_copy(&result1, &P);
00341          pmp.ModNeg(result1.y, result1.y, param.p, NUMWORDS);
00342          eccfp.c_add_affine(&result2, &C, &result1);
00343          //compute d(B-H)
00344          eccfp.c_mul(&result3, &result2, d);
00345          //compute Verify = sG -d(B-H)
00346          //subtraction in F_{p} if P=(x,y) then -P=(x,-y)
00347          pmp.ModNeg(result3.y, result3.y, param.p, NUMWORDS);
00348          eccfp.c_add_affine(&Verify, &result, &result3);
00349 
00350          swap_points(&Verify, &Verify2);
00351       }
00352 
00353       //send the message with K,L to verifier
00354       block_data_t buffer[4*(KEYDIGITS*NN_DIGIT_LEN+1)+1];
00355       buffer[0]=START_MSG;
00356       //convert first point to octet and place to buffer
00357       eccfp.point2octet(buffer+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify, FALSE);
00358       //convert second point to octet and place to buffer
00359       eccfp.point2octet(buffer+2*(KEYDIGITS*NN_DIGIT_LEN+1)+1, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &Verify2, FALSE);
00360 
00361 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00362       debug().debug("Debug::Finished calculations!Sending 2 verify keys to verifier. ::%d \n", radio().id());
00363 #endif
00364       radio().send(Radio::BROADCAST_ADDRESS, 4*(KEYDIGITS*NN_DIGIT_LEN+1)+1 , buffer);
00365    }
00366 
00367    //------------------------------------------------------------------------
00368    template<typename OsModel_P,
00369             typename Radio_P,
00370             typename Debug_P>
00371    void
00372    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00373 	send_key( void ) {
00374 
00375 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00376       debug().debug("Debug::Creating the new private keys ::%d \n", radio().id() );
00377 #endif
00378 
00379       //prover computes e,s,t
00380       NN_DIGIT e[NUMWORDS];
00381       NN_DIGIT t[NUMWORDS];
00382 
00383       //clear private keys e,t
00384       pmp.AssignZero(e, NUMWORDS);
00385       pmp.AssignZero(t, NUMWORDS);
00386 
00387       //compute e = c - d
00388       pmp.ModSub(e, c, d, param.r, NUMWORDS);
00389       //pmp.Mod(e, e, NUMWORDS, param.r, NUMWORDS);
00390 
00391       NN_DIGIT mid2[NUMWORDS];
00392       pmp.AssignZero(mid2, NUMWORDS);
00393 
00394       //first compute me
00395       pmp.ModMult(mid2, m, e, param.r, NUMWORDS);
00396       //then add t = w + me
00397       pmp.ModAdd(t, w, mid2, param.r, NUMWORDS);
00398 
00399       //in case of -1 swap d <-> e and s <-> t
00400       if(h == -1)
00401       {
00402          swap_keys(d, e);
00403          swap_keys(s, t);
00404       }
00405 
00406       //send the message with d,e,s,t to verifier
00407       block_data_t buffer[4*(KEYDIGITS*NN_DIGIT_LEN+1)+1];
00408       buffer[0]=CONT_MSG;
00409 
00410       //convert keys to octet and place to buffer
00411       pmp.Encode(buffer+1, KEYDIGITS * NN_DIGIT_LEN +1, d, NUMWORDS);
00412       pmp.Encode(buffer+KEYDIGITS * NN_DIGIT_LEN +1+1, KEYDIGITS * NN_DIGIT_LEN +1, e, NUMWORDS);
00413       pmp.Encode(buffer+2*(KEYDIGITS * NN_DIGIT_LEN +1)+1, KEYDIGITS * NN_DIGIT_LEN +1, s, NUMWORDS);
00414       pmp.Encode(buffer+3*(KEYDIGITS * NN_DIGIT_LEN +1)+1, KEYDIGITS * NN_DIGIT_LEN +1, t, NUMWORDS);
00415 
00416 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00417       debug().debug("Debug::Sending the new private keys d,e,s,t to verifier::%d \n", radio().id() );
00418 #endif
00419       radio().send(Radio::BROADCAST_ADDRESS, 4*(KEYDIGITS*NN_DIGIT_LEN+1)+1, buffer);
00420    }
00421 
00422    //---------------------------------------------------------------------------
00423    template<typename OsModel_P,
00424             typename Radio_P,
00425             typename Debug_P>
00426    void
00427    ZKPOFSINGLEBITProve<OsModel_P, Radio_P, Debug_P>::
00428 	receive( node_id_t from, size_t len, block_data_t *data ) {
00429 
00430       if( from == radio().id() ) return;
00431 
00432       if(data[0]==RAND_MSG)
00433       {
00434 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00435          debug().debug("Debug::Received a random message. Calling the send_key task.::%d \n", radio().id() );
00436 #endif
00437 
00438          //clear the hash and decode the random c received from verifier
00439          pmp.AssignZero(c, NUMWORDS);
00440          pmp.Decode(c, NUMWORDS, data+1, KEYDIGITS * NN_DIGIT_LEN +1);
00441 
00442          //calling the send_key task
00443          send_key();
00444       }
00445 
00446       if(data[0]==ACCEPT_MSG)
00447       {
00448 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00449          debug().debug("Debug::I got ACCEPTED from the verifier.YESSS!::%d \n", radio().id() );
00450 #endif
00451       }
00452 
00453       if(data[0]==REJECT_MSG)
00454       {
00455 #ifdef ENABLE_ZKPOFSINGLEBIT_DEBUG
00456          debug().debug("Debug::I got REJECTED from the verifier.NOOO!::%d \n", radio().id() );
00457 #endif
00458       }
00459 
00460    }
00461 
00462 } //end of wiselib namespace
00463 
00464 #endif /* ZKPOFSINGLEBIT_PROVER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines