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 using namespace CODEX_Ciphers;
00022 using namespace CODEX_Exceptions;
00023 using CODEX_ASN1::BigNumber;
00024 using CODEX_ASN1::SecureBigNumber;
00025
00026 void
00027 ElGamalKeyPairGenerator::operator()( ElGamalPublicKey*& pubKey,
00028 ElGamalPrivateKey*& privKey,
00029 BIGNUM * p,
00030 BIGNUM * g )
00031 {
00032 bool ownP = false;
00033 bool ownG = false;
00034
00035 BIGNUM * p1 = 0;
00036 BN_CTX * ctx = 0;
00037 BIGNUM * q = 0;
00038 BIGNUM * temp = 0;
00039 BIGNUM * x = 0;
00040 BIGNUM * y = 0;
00041
00042 try
00043 {
00044 if ( 0 == p )
00045 {
00046
00047 ownP = true;
00048 p = BN_new();
00049 if ( 0 == p )
00050 {
00051 throw BignumNullException( __FILE__ , __LINE__ );
00052 }
00053 if ( 0 == BN_generate_prime( p, m_numBits, 1, 0, 0, 0, 0 ) )
00054 {
00055 throw BignumGeneratePrimeException( __FILE__ , __LINE__ );
00056 }
00057 }
00058 else
00059 {
00060 p = BN_dup(p);
00061 ownP = true;
00062 }
00063
00064 p1 = BN_new();
00065 if ( 0 == p1 )
00066 {
00067 throw BignumNullException( __FILE__ , __LINE__ );
00068 }
00069 if ( ! BN_sub(p1,p,BN_value_one()) )
00070 {
00071 throw BignumSubException( __FILE__ , __LINE__ );
00072 }
00073
00074 q = BN_new();
00075 if ( 0 == q )
00076 {
00077 throw BignumNullException( __FILE__ , __LINE__ );
00078 }
00079 if ( ! BN_rshift1(q,p1) )
00080 {
00081 throw BignumRshiftException( __FILE__ , __LINE__ );
00082 }
00083
00084 ctx = BN_CTX_new();
00085 if ( 0 == ctx )
00086 {
00087 throw BignumContextException( __FILE__ , __LINE__ );
00088 }
00089
00090 if ( 0 == g )
00091 {
00092
00093 g = BN_new();
00094 if ( 0 == g )
00095 {
00096 throw BignumNullException( __FILE__ , __LINE__ );
00097 }
00098 ownG = true;
00099 bool flag;
00100 temp = BN_new();
00101 if ( 0 == temp )
00102 {
00103 throw BignumNullException( __FILE__ , __LINE__ );
00104 }
00105 do
00106 {
00107 flag = false;
00108 if ( ! BN_rand_range(g,p) )
00109 {
00110 throw BignumRandRangeException( __FILE__ , __LINE__ );
00111 }
00112 if ( 0 >= BN_cmp( g, BN_value_one() ) )
00113 {
00114 flag = true;
00115 }
00116 else
00117 {
00118
00119 if ( ! BN_mod_mul(temp, g, g, p, ctx) )
00120 {
00121 throw BignumModMulException( __FILE__ , __LINE__ );
00122 }
00123 if ( 0 == BN_cmp( temp, BN_value_one() ) )
00124 {
00125 flag = true;
00126 }
00127 else
00128 {
00129 if ( ! BN_mod_exp(temp, g, q, p, ctx) )
00130 {
00131 throw BignumModExpException( __FILE__ , __LINE__ );
00132 }
00133 if ( 0 == BN_cmp( temp, BN_value_one() ) )
00134 {
00135 flag = true;
00136 }
00137 }
00138 }
00139 } while ( flag );
00140 BN_free( temp );
00141 temp = 0;
00142
00143
00144
00145
00146 if ( ! BN_mod_sqr( g, g, p, ctx ) )
00147 {
00148 throw BignumModMulException( __FILE__ , __LINE__ );
00149 }
00150 }
00151 else
00152 {
00153 g = BN_dup(g);
00154 ownG = true;
00155 }
00156
00157
00158 x = BN_new();
00159 if ( 0 == x )
00160 {
00161 throw BignumNullException( __FILE__ , __LINE__ );
00162 }
00163 do
00164 {
00165
00166 if ( ! BN_rand_range(x,q) )
00167 {
00168 throw BignumRandRangeException( __FILE__ , __LINE__ );
00169 }
00170 } while ( 0 >= BN_cmp( g, BN_value_one() ) );
00171
00172
00173 y = BN_new();
00174 if ( 0 == y )
00175 {
00176 throw BignumNullException( __FILE__ , __LINE__ );
00177 }
00178 if ( ! BN_mod_exp(y, g, x, p, ctx) )
00179 {
00180 throw BignumModExpException( __FILE__ , __LINE__ );
00181 }
00182
00183 pubKey = new ElGamalPublicKey( p, g, y );
00184 privKey = new ElGamalPrivateKey( x );
00185
00186 BN_CTX_free(ctx);
00187 BN_free(p1);
00188 BN_free( q );
00189 }
00190 catch ( ... )
00191 {
00192 if ( ownP && ( 0 != p ) ) BN_free(p);
00193 if ( ownG && ( 0 != g ) ) BN_free(g);
00194
00195 if ( 0 != p1 ) BN_free(p1);
00196 if ( 0 != q ) BN_free(q);
00197 if ( 0 != temp ) BN_free(temp);
00198 if ( 0 != x ) BN_clear_free(x);
00199 if ( 0 != y ) BN_free(y);
00200 if ( 0 != ctx ) BN_CTX_free(ctx);
00201 throw;
00202 }
00203 }