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
00023 ElGamalCipherText::ElGamalCipherText() :
00024 CODEX_ASN1::Base( false )
00025 {
00026 }
00027
00028 ElGamalCipherText::ElGamalCipherText( BIGNUM * c1, BIGNUM * c2 ) :
00029 CODEX_ASN1::Base( true ),
00030 m_c1( c1 ),
00031 m_c2( c2 )
00032 {
00033 }
00034
00035 ElGamalCipherText::ElGamalCipherText( const CODEX_ASN1::BigNumber& c1,
00036 const CODEX_ASN1::BigNumber& c2 ) :
00037 CODEX_ASN1::Base( true ),
00038 m_c1( c1 ),
00039 m_c2( c2 )
00040 {
00041 }
00042
00043 ElGamalCipherText::ElGamalCipherText( const ElGamalCipherText& aCT ) :
00044 CODEX_ASN1::Base( aCT.m_initialized ),
00045 m_c1( aCT.m_c1 ),
00046 m_c2( aCT.m_c2 )
00047 {
00048 }
00049
00050 ElGamalCipherText::~ElGamalCipherText()
00051 {
00052 }
00053
00054 void
00055 ElGamalCipherText::operator=( const ElGamalCipherText& aCT )
00056 {
00057 m_initialized = aCT.m_initialized;
00058 m_c1 = aCT.m_c1;
00059 m_c2 = aCT.m_c2;
00060 }
00061
00062 bool
00063 ElGamalCipherText::operator<( const ElGamalCipherText& aCT ) const
00064 {
00065
00066
00067
00068 if ( m_c1 < aCT.c1() ) return true;
00069 if ( aCT.c1() < m_c1 ) return false;
00070 if ( m_c2 < aCT.c2() ) return true;
00071 return false;
00072 }
00073
00074 bool
00075 ElGamalCipherText::operator==( const ElGamalCipherText& aCT ) const
00076 {
00077 if ( m_c1 != aCT.c1() ) return false;
00078 if ( m_c2 != aCT.c2() ) return false;
00079 return true;
00080 }
00081
00082 bool
00083 ElGamalCipherText::operator!=( const ElGamalCipherText& aCT ) const
00084 {
00085 return ( ! operator==(aCT) );
00086 }
00087
00088
00089 ElGamalCipherText*
00090 ElGamalCipherText::blind( const ElGamalCipherText& aOther,
00091 const CODEX_ASN1::BigNumber& modulus ) const
00092 {
00093 ElGamalCipherText* retVal = 0;
00094
00095 const BIGNUM * kc1 = m_c1.value();
00096 const BIGNUM * kc2 = m_c2.value();
00097
00098 const BIGNUM * bc1 = aOther.m_c1.value();
00099 const BIGNUM * bc2 = aOther.m_c2.value();
00100
00101 const BIGNUM * n = modulus.value();
00102
00103 BIGNUM * bk1 = 0;
00104 BIGNUM * bk2 = 0;
00105 BN_CTX * ctx = 0;
00106 try
00107 {
00108 ctx = BN_CTX_new();
00109 if ( 0 == ctx )
00110 {
00111 throw CODEX_Exceptions::BignumContextException( __FILE__ , __LINE__ );
00112 }
00113
00114 bk1 = BN_new();
00115 if ( 0 == bk1 )
00116 {
00117 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00118 }
00119 if ( ! BN_mod_mul( bk1, bc1, kc1, n, ctx ) )
00120 {
00121 throw CODEX_Exceptions::BignumModMulException( __FILE__ , __LINE__ );
00122 }
00123
00124 bk2 = BN_new();
00125 if ( 0 == bk2 )
00126 {
00127 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00128 }
00129 if ( ! BN_mod_mul( bk2, bc2, kc2, n, ctx ) )
00130 {
00131 throw CODEX_Exceptions::BignumModMulException( __FILE__ , __LINE__ );
00132 }
00133
00134 retVal = new ElGamalCipherText( bk1, bk2 );
00135 bk1 = 0;
00136 bk2 = 0;
00137 BN_CTX_free( ctx );
00138 ctx = 0;
00139 return retVal;
00140 }
00141 catch ( ... )
00142 {
00143 if ( 0 != ctx ) BN_CTX_free( ctx );
00144 if ( 0 != bk1 ) BN_free( bk1 );
00145 if ( 0 != bk2 ) BN_free( bk2 );
00146 throw;
00147 }
00148 }
00149
00150 int
00151 ElGamalCipherText::marshal( unsigned char ** pp ) const
00152 {
00153 int r=0;
00154 int ret=0;
00155 unsigned char * p;
00156
00157 ret += m_c1.marshal(0);
00158 ret += m_c2.marshal(0);
00159 M_ASN1_I2D_seq_total();
00160 m_c1.marshal(&p);
00161 m_c2.marshal(&p);
00162 M_ASN1_I2D_finish();
00163 }
00164
00165 void*
00166 ElGamalCipherText::unmarshal( void* bogus, unsigned char ** pp, long length )
00167 {
00168 if ( m_initialized )
00169 {
00170 return NULL;
00171 }
00172 if ( (NULL == pp) || (NULL == *pp) )
00173 {
00174 return NULL;
00175 }
00176 ASN1_CTX c;
00177 c.pp = pp;
00178 c.q = *pp;
00179 c.error = ERR_R_NESTED_ASN1_ERROR;
00180 int i;
00181
00182 M_ASN1_D2I_Init();
00183 M_ASN1_D2I_start_sequence();
00184 M_ASN1_D2I_get(i, m_c1.unmarshal);
00185 M_ASN1_D2I_get(i, m_c2.unmarshal);
00186 if ( !asn1_Finish(&c) )
00187 {
00188 return NULL;
00189 }
00190 *pp=c.p;
00191 m_initialized = true;
00192 return this;
00193 err:
00194 return NULL;
00195 }