00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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;
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
00134
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
00226
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:
00401 return 0;
00402 }