Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DLProof.cc

00001 /*
00002  * Copyright 2003 Michael A. Marsh, Cornell University. All rights reserved.
00003  * This software is released under the modified BSD license.
00004  * See the file LICENSE in the top-level directory for details.
00005  */
00006 //
00007 // $Id: DLProof.cc,v 1.3 2004/05/19 15:57:00 mmarsh Exp $
00008 //
00009 // $Log: DLProof.cc,v $
00010 // Revision 1.3  2004/05/19 15:57:00  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.2  2003/11/04 22:21:34  mmarsh
00014 // General code cleanup.
00015 //
00016 //
00017 
00018 #include "DLProof.h"
00019 #include "CODEX_VSS/ModExpFunctional.h"
00020 #include "CODEX_Exceptions/BignumExceptions.h"
00021 
00022 #include "timing.h"
00023 
00024 using namespace CODEX_ThresholdCrypto;
00025 
00026 DLProof::DLProof() :
00027    CODEX_ASN1::Base( false )
00028 {
00029 }
00030 
00032 DLProof::DLProof( const BIGNUM * g1,
00033                   const BIGNUM * g2,
00034                   const BIGNUM * n,
00035                   const BIGNUM * max,
00036                   const BIGNUM * x,
00037                   const CODEX_Ciphers::HashFunction& H ) :
00038    CODEX_ASN1::Base( true )
00039 {
00040    if ( ( 0 == g1  ) ||
00041         ( 0 == g2  ) ||
00042         ( 0 == n   ) ||
00043         ( 0 == max ) ||
00044         ( 0 == x   ) )
00045    {
00046       throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00047    }
00048 
00049 #ifdef TIMING
00050    DLProofTimer.start();
00051 #endif
00052 
00053    BIGNUM * maxBN = (BIGNUM*) max; // CAST
00054 
00055    BIGNUM * r1  = 0;
00056    BIGNUM * r2  = 0;
00057    BIGNUM * t   = 0;
00058    BIGNUM * k   = 0;
00059    BIGNUM * hBN = 0;
00060    BIGNUM * xh  = 0;
00061    BN_CTX * ctx = 0;
00062 
00063    unsigned char* buff = 0;
00064    CODEX_ASN1::ustring* str = 0;
00065 
00066    try
00067    {
00068       ctx = BN_CTX_new();
00069       if ( 0 == ctx )
00070       {
00071          throw CODEX_Exceptions::BignumContextException( __FILE__ , __LINE__ );
00072       }
00073       k = BN_new();
00074       if ( 0 == k )
00075       {
00076          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00077       }
00078       do
00079       {
00080          if ( ! BN_rand_range( k, maxBN ) )
00081          {
00082          throw CODEX_Exceptions::BignumRandRangeException( __FILE__ ,
00083                                                            __LINE__ );
00084          }
00085       } while ( 0 >= BN_cmp( k , BN_value_one() ) );
00086 
00087       r1 = BN_new();
00088       if ( 0 == r1 )
00089       {
00090          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00091       }
00092       if ( ! BN_mod_exp( r1, g1, k, n, ctx ) )
00093       {
00094          throw CODEX_Exceptions::BignumModExpException( __FILE__ , __LINE__ );
00095       }
00096       m_r1 = CODEX_ASN1::BigNumber( r1 );
00097       r1 = 0;
00098 
00099       r2 = BN_new();
00100       if ( 0 == r2 )
00101       {
00102          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00103       }
00104       if ( ! BN_mod_exp( r2, g2, k, n, ctx ) )
00105       {
00106          throw CODEX_Exceptions::BignumModExpException( __FILE__ , __LINE__ );
00107       }
00108       m_r2 = CODEX_ASN1::BigNumber( r2 );
00109       r2 = 0;
00110 
00111       int length = 0;
00112       length += m_r1.marshal(0);
00113       length += m_r2.marshal(0);
00114       buff = new unsigned char[ length ];
00115       unsigned char* pBuff = buff;
00116       m_r1.marshal(&pBuff);
00117       m_r2.marshal(&pBuff);
00118       str = H( CODEX_ASN1::ustring( buff, length ) );
00119       delete [] buff;
00120       buff = 0;
00121       hBN = BN_new();
00122       if ( 0 == hBN )
00123       {
00124          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00125       }
00126       if ( 0 == BN_bin2bn( str->data(), str->length(), hBN ) )
00127       {
00128          throw CODEX_Exceptions::BignumBin2BNException( __FILE__ , __LINE__ );
00129       }
00130       delete str;
00131       str = 0;
00132 
00133       // The rest of the calculations are performed over the integers, since
00134       // we don't a priori know phi(n).  This means t might be negative.
00135       xh = BN_new();
00136       if ( 0 == xh )
00137       {
00138          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00139       }
00140       if ( ! BN_mul( xh, x, hBN, ctx ) )
00141       {
00142          throw CODEX_Exceptions::BignumMulException( __FILE__ , __LINE__ );
00143       }
00144       BN_free(hBN);
00145       hBN = 0;
00146 
00147       t = BN_new();
00148       if ( 0 == t )
00149       {
00150          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00151       }
00152       if ( ! BN_sub( t, k, xh ) )
00153       {
00154          throw CODEX_Exceptions::BignumSubException( __FILE__ , __LINE__ );
00155       }
00156       m_t = CODEX_ASN1::BigNumber(t);
00157 
00158       BN_clear_free(k);
00159       BN_clear_free(xh);
00160       BN_CTX_free(ctx);
00161 #ifdef TIMING
00162       DLProofTimer.stop();
00163 #endif
00164    }
00165    catch ( ... )
00166    {
00167       if ( 0 != r1 ) BN_free(r1);
00168       if ( 0 != r2 ) BN_free(r2);
00169       if ( 0 != t ) BN_free(t);
00170       if ( 0 != k ) BN_clear_free(t);
00171       if ( 0 != hBN ) BN_free(hBN);
00172       if ( 0 != xh ) BN_clear_free(xh);
00173       if ( 0 != ctx ) BN_CTX_free(ctx);
00174       if ( 0 != buff ) delete [] buff;
00175       if ( 0 != str ) delete str;
00176 #ifdef TIMING
00177       DLProofTimer.stop();
00178 #endif
00179       throw;
00180    }
00181 }
00182 
00183 DLProof::DLProof( const DLProof& aOther ) :
00184    CODEX_ASN1::Base( aOther.m_initialized ),
00185    m_r1( aOther.m_r1 ),
00186    m_r2( aOther.m_r2 ),
00187    m_t( aOther.m_t)
00188 {
00189 }
00190 
00191 DLProof::~DLProof()
00192 {
00193 }
00194 
00195 void
00196 DLProof::operator=( const DLProof& aOther )
00197 {
00198    m_initialized = aOther.m_initialized;
00199    m_r1 = aOther.m_r1;
00200    m_r2 = aOther.m_r2;
00201    m_t = aOther.m_t;
00202 }
00203 
00204 bool
00205 DLProof::verify( const BIGNUM * g1,
00206                  const BIGNUM * g2,
00207                  const BIGNUM * y1,
00208                  const BIGNUM * y2,
00209                  const BIGNUM * n,
00210                  const CODEX_Ciphers::HashFunction& H ) const
00211 {
00212    if ( ( 0 == g1 ) ||
00213         ( 0 == g2 ) ||
00214         ( 0 == y1 ) ||
00215         ( 0 == y2 ) ||
00216         ( 0 == n  ) )
00217    {
00218       throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00219    }
00220 
00221 #ifdef TIMING
00222    DLProofVerifyTimer.start();
00223 #endif
00224 
00225    // We will exploit the fact that ModExpFunctional treats negative exponents
00226    // correctly and not duplicate the code.
00227    CODEX_VSS::ModExpFunctional f1(BN_dup(g1),BN_dup(n));
00228    CODEX_VSS::ModExpFunctional f2(BN_dup(g2),BN_dup(n));
00229    CODEX_ASN1::SecureBigNumber g1t;
00230    CODEX_ASN1::SecureBigNumber g2t;
00231 
00232    BIGNUM * h   = 0;
00233    BIGNUM * y1h = 0;
00234    BIGNUM * y2h = 0;
00235    BIGNUM * r1  = 0;
00236    BIGNUM * r2  = 0;
00237    BN_CTX * ctx = 0;
00238 
00239    unsigned char* buff = 0;
00240    CODEX_ASN1::ustring* str = 0;
00241 
00242    try
00243    {
00244       bool retVal = true;
00245 
00246       int length = 0;
00247       length += m_r1.marshal(0);
00248       length += m_r2.marshal(0);
00249       buff = new unsigned char[ length ];
00250       unsigned char* pBuff = buff;
00251       m_r1.marshal(&pBuff);
00252       m_r2.marshal(&pBuff);
00253       str = H( CODEX_ASN1::ustring( buff, length ) );
00254       delete [] buff;
00255       buff = 0;
00256       h = BN_new();
00257       if ( 0 == h )
00258       {
00259          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00260       }
00261       if ( 0 == BN_bin2bn( str->data(), str->length(), h ) )
00262       {
00263          throw CODEX_Exceptions::BignumBin2BNException( __FILE__ , __LINE__ );
00264       }
00265       delete str;
00266       str = 0;
00267 
00268       ctx = BN_CTX_new();
00269       if ( 0 == ctx )
00270       {
00271          throw CODEX_Exceptions::BignumContextException( __FILE__ , __LINE__ );
00272       }
00273 
00274       y1h = BN_new();
00275       if ( 0 == y1h )
00276       {
00277          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00278       }
00279       if ( ! BN_mod_exp( y1h, y1, h, n, ctx ) )
00280       {
00281          throw CODEX_Exceptions::BignumModExpException( __FILE__ , __LINE__ );
00282       }
00283 
00284       y2h = BN_new();
00285       if ( 0 == y2h )
00286       {
00287          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00288       }
00289       if ( ! BN_mod_exp( y2h, y2, h, n, ctx ) )
00290       {
00291          throw CODEX_Exceptions::BignumModExpException( __FILE__ , __LINE__ );
00292       }
00293 
00294       BN_free(h);
00295       h = 0;
00296 
00297       f1( m_t, g1t );
00298       f2( m_t, g2t );
00299 
00300       r1 = BN_new();
00301       if ( 0 == r1 )
00302       {
00303          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00304       }
00305       if ( ! BN_mod_mul( r1, y1h, g1t.value(), n, ctx ) )
00306       {
00307          throw CODEX_Exceptions::BignumModMulException( __FILE__ , __LINE__ );
00308       }
00309       BN_free(y1h);
00310       y1h = 0;
00311 
00312       r2 = BN_new();
00313       if ( 0 == r2 )
00314       {
00315          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00316       }
00317       if ( ! BN_mod_mul( r2, y2h, g2t.value(), n, ctx ) )
00318       {
00319          throw CODEX_Exceptions::BignumModMulException( __FILE__ , __LINE__ );
00320       }
00321       BN_free(y2h);
00322       y2h = 0;
00323 
00324       BN_CTX_free(ctx);
00325       ctx = 0;
00326 
00327       if ( 0 != BN_cmp( r1, m_r1.value() ) ) retVal = false;
00328       if ( 0 != BN_cmp( r2, m_r2.value() ) ) retVal = false;
00329       BN_free(r1);
00330       BN_free(r2);
00331 
00332 #ifdef TIMING
00333       DLProofVerifyTimer.stop();
00334 #endif
00335       return retVal;
00336    }
00337    catch ( ... )
00338    {
00339       if ( 0 != h ) BN_free(h);
00340       if ( 0 != y1h ) BN_free(y1h);
00341       if ( 0 != y2h ) BN_free(y2h);
00342       if ( 0 != r1 ) BN_free(r1);
00343       if ( 0 != r2 ) BN_free(r2);
00344       if ( 0 != ctx ) BN_CTX_free(ctx);
00345       if ( 0 != buff ) delete [] buff;
00346       if ( 0 != str ) delete str;
00347 #ifdef TIMING
00348       DLProofVerifyTimer.stop();
00349 #endif
00350       throw;
00351    }
00352 }
00353 
00354 int
00355 DLProof::marshal( unsigned char ** pp ) const
00356 {
00357    int r=0;
00358    int ret=0;
00359    unsigned char * p;
00360 
00361    ret += m_r1.marshal(0);
00362    ret += m_r2.marshal(0);
00363    ret += m_t.marshal(0);
00364    M_ASN1_I2D_seq_total();
00365    m_r1.marshal(&p);
00366    m_r2.marshal(&p);
00367    m_t.marshal(&p);
00368    M_ASN1_I2D_finish();
00369 }
00370 
00371 void*
00372 DLProof::unmarshal( void* bogus, unsigned char ** pp, long length )
00373 {
00374    if ( m_initialized )
00375    {
00376       return 0;
00377    }
00378    if ( (0 == pp) || (0 == *pp) )
00379    {
00380       return 0;
00381    }
00382    ASN1_CTX c;
00383    c.pp = pp;
00384    c.q = *pp;
00385    c.error = ERR_R_NESTED_ASN1_ERROR;
00386    int i;
00387 
00388    M_ASN1_D2I_Init();
00389    M_ASN1_D2I_start_sequence();
00390    M_ASN1_D2I_get(i, m_r1.unmarshal);
00391    M_ASN1_D2I_get(i, m_r2.unmarshal);
00392    M_ASN1_D2I_get(i, m_t.unmarshal);
00393    if ( !asn1_Finish(&c) )
00394    {
00395       return 0;
00396    }
00397    *pp=c.p;
00398    m_initialized = true;
00399    return this;
00400   err: // needed by ASN.1 macros
00401    return 0;
00402 }

Generated on Fri May 6 17:39:11 2005 for COrnell Data EXchange (CODEX) by  doxygen 1.4.1