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

ElGamalSchnorrCipherText.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: ElGamalSchnorrCipherText.cc,v 1.3 2004/05/19 15:56:47 mmarsh Exp $
00008 //
00009 // $Log: ElGamalSchnorrCipherText.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:47  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.2  2003/11/04 22:31:47  mmarsh
00014 // *** empty log message ***
00015 //
00016 //
00017 
00018 #include "ElGamal.h"
00019 #include "CODEX_Exceptions/BignumExceptions.h"
00020 
00021 #include "timing.h"
00022 
00023 using namespace CODEX_Ciphers;
00024 
00025 ElGamalSchnorrCipherText::ElGamalSchnorrCipherText()
00026 {
00027 }
00028 
00029 ElGamalSchnorrCipherText::ElGamalSchnorrCipherText( BIGNUM * c1,
00030                                                     BIGNUM * c2,
00031                                                     BIGNUM * h,
00032                                                     BIGNUM * z ) :
00033    ElGamalCipherText( c1, c2 ),
00034    m_h( h ),
00035    m_z( z )
00036 {
00037 }
00038 
00039 ElGamalSchnorrCipherText::ElGamalSchnorrCipherText(
00040    const CODEX_ASN1::BigNumber& c1,
00041    const CODEX_ASN1::BigNumber& c2,
00042    const CODEX_ASN1::BigNumber& h,
00043    const CODEX_ASN1::BigNumber& z ) :
00044    ElGamalCipherText( c1, c2 ),
00045    m_h( h ),
00046    m_z( z )
00047 {
00048 }
00049 
00050 ElGamalSchnorrCipherText::ElGamalSchnorrCipherText(
00051    const ElGamalSchnorrCipherText& aCT ) :
00052    ElGamalCipherText( aCT ),
00053    m_h( aCT.m_h ),
00054    m_z( aCT.m_z )
00055 {
00056 }
00057 
00058 ElGamalSchnorrCipherText::~ElGamalSchnorrCipherText()
00059 {
00060 }
00061 
00062 void
00063 ElGamalSchnorrCipherText::operator=( const ElGamalSchnorrCipherText& aCT )
00064 {
00065    ElGamalCipherText::operator=( aCT );
00066    m_h = aCT.m_h;
00067    m_z = aCT.m_z;
00068 }
00069 
00070 bool
00071 ElGamalSchnorrCipherText::verify( const CODEX_ASN1::BigNumber& g,
00072                                   const CODEX_ASN1::BigNumber& p,
00073                                   const CODEX_ASN1::Base& id,
00074                                   const HashFunction& hashFunc ) const
00075 {
00076 #ifdef TIMING
00077    SchnorrTimer.start();
00078 #endif
00079    const BIGNUM * n    = p.value();
00080    const BIGNUM * gbn  = g.value();
00081    const BIGNUM * z    = m_z.value();
00082    const BIGNUM * h    = m_h.value();
00083    const BIGNUM * c1bn = c1().value();
00084 
00085    BN_CTX *              ctx    = 0;
00086    BIGNUM *              gzc1mh = 0;
00087    BIGNUM *              c1mh   = 0;
00088    unsigned char*        buff   = 0;
00089    BIGNUM *              cprime = 0;
00090    CODEX_ASN1::ustring*  str    = 0;
00091    try
00092    {
00093       ctx = BN_CTX_new();
00094       if ( 0 == ctx )
00095       {
00096          throw CODEX_Exceptions::BignumContextException( __FILE__ , __LINE__ );
00097       }
00098 
00099       gzc1mh = BN_new();
00100       if ( 0 == gzc1mh )
00101       {
00102          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00103       }
00104       // gzc1mh = g^m_z c1^(-m_h)
00105       if ( ! BN_mod_exp( gzc1mh, gbn, z, n, ctx ) )
00106       {
00107          throw CODEX_Exceptions::BignumModExpException( __FILE__ , __LINE__ );
00108       }
00109       c1mh = BN_new();
00110       if ( 0 == c1mh )
00111       {
00112          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00113       }
00114       if ( ! BN_mod_exp( c1mh, c1bn, h, n, ctx ) )
00115       {
00116          throw CODEX_Exceptions::BignumModExpException( __FILE__ , __LINE__ );
00117       }
00118       if ( ! BN_mod_inverse( c1mh, c1mh, n, ctx ) )
00119       {
00120          throw CODEX_Exceptions::BignumModInverseException( __FILE__ ,
00121                                                             __LINE__ );
00122       }
00123       if ( ! BN_mod_mul( gzc1mh, gzc1mh, c1mh, n, ctx ) )
00124       {
00125          throw CODEX_Exceptions::BignumModMulException( __FILE__ , __LINE__ );
00126       }
00127       BN_free(c1mh);
00128       c1mh = 0;
00129       CODEX_ASN1::BigNumber a( gzc1mh );
00130       gzc1mh = 0;
00131 
00132       int length = a.marshal(0);
00133       length += c1().marshal(0);
00134       length += c2().marshal(0);
00135       length += id.marshal(0);
00136       buff = new unsigned char[length];
00137       unsigned char* pBuff = buff;
00138       a.marshal(&pBuff);
00139       c1().marshal(&pBuff);
00140       c2().marshal(&pBuff);
00141       id.marshal(&pBuff);
00142       str = hashFunc( CODEX_ASN1::ustring(buff,length) );
00143       delete [] buff;
00144       buff = 0;
00145 
00146       cprime = BN_new();
00147       if ( 0 == cprime )
00148       {
00149          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00150       }
00151       if ( 0 == BN_bin2bn( str->data(), str->length(), cprime ) )
00152       {
00153          throw CODEX_Exceptions::BignumBin2BNException( __FILE__ , __LINE__ );
00154       }
00155       delete str;
00156       str = 0;
00157 
00158       bool retVal = ( 0 == BN_cmp( cprime, m_h.value() ) );
00159 
00160       BN_CTX_free( ctx );
00161       BN_free(cprime);
00162 
00163 #ifdef TIMING
00164       SchnorrTimer.stop();
00165 #endif
00166       return retVal;
00167    }
00168    catch ( ... )
00169    {
00170       if ( 0 != ctx )    BN_CTX_free(ctx);
00171       if ( 0 != gzc1mh ) BN_free(gzc1mh);
00172       if ( 0 != c1mh )   BN_free(gzc1mh);
00173       if ( 0 != buff )   delete [] buff;
00174       if ( 0 != cprime ) BN_free(cprime);
00175       if ( 0 != str )    delete str;
00176 #ifdef TIMING
00177       SchnorrTimer.stop();
00178 #endif
00179       throw;
00180    }
00181 }
00182 
00183 int
00184 ElGamalSchnorrCipherText::marshal( unsigned char ** pp ) const
00185 {
00186    typedef ElGamalCipherText  BaseType;
00187    int r=0;
00188    int ret=0;
00189    unsigned char * p;
00190 
00191    ret += BaseType::marshal(0);
00192    ret += m_h.marshal(0);
00193    ret += m_z.marshal(0);
00194    M_ASN1_I2D_seq_total();
00195    BaseType::marshal(&p);
00196    m_h.marshal(&p);
00197    m_z.marshal(&p);
00198    M_ASN1_I2D_finish();
00199 }
00200 
00201 void*
00202 ElGamalSchnorrCipherText::unmarshal( void* bogus,
00203                                      unsigned char ** pp,
00204                                      long length )
00205 {
00206    typedef ElGamalCipherText  BaseType;
00207    if ( m_initialized )
00208    {
00209       return NULL;
00210    }
00211    if ( (NULL == pp) || (NULL == *pp) )
00212    {
00213       return NULL;
00214    }
00215    ASN1_CTX c;
00216    c.pp = pp;
00217    c.q = *pp;
00218    c.error = ERR_R_NESTED_ASN1_ERROR;
00219    int i;
00220 
00221    M_ASN1_D2I_Init();
00222    M_ASN1_D2I_start_sequence();
00223    M_ASN1_D2I_get(i, BaseType::unmarshal);
00224    M_ASN1_D2I_get(i, m_h.unmarshal);
00225    M_ASN1_D2I_get(i, m_z.unmarshal);
00226    if ( !asn1_Finish(&c) )
00227    {
00228       return NULL;
00229    }
00230    *pp=c.p;
00231    m_initialized = true;
00232    return this;
00233   err: // needed by ASN.1 macros
00234    return NULL;
00235 }

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