00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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:
00234 return NULL;
00235 }