00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "ModExpFunctional.h"
00019 #include "CODEX_Exceptions/BignumExceptions.h"
00020
00021 #include "timing.h"
00022
00023 using namespace CODEX_VSS;
00024
00025 ModExpFunctional::ModExpFunctional( const ArgType& base,
00026 const ArgType& modulus ) :
00027 ShareFunctional(),
00028 m_base( base ),
00029 m_modulus( modulus )
00030 {
00031 }
00032
00033 ModExpFunctional::ModExpFunctional( const CtorArgs& args ) :
00034 ShareFunctional(),
00035 m_base( args.base() ),
00036 m_modulus( args.modulus() )
00037 {
00038 }
00039
00040 ModExpFunctional::~ModExpFunctional()
00041 {
00042 }
00043
00045 void
00046 ModExpFunctional::operator()( const CODEX_ASN1::SecureBigNumber& operand,
00047 CODEX_ASN1::BigNumber& result ) const
00048 {
00049 if ( ! m_modulus.initialized() )
00050 {
00051 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00052 }
00053 if ( ! m_base.initialized() )
00054 {
00055 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00056 }
00057 if ( ! operand.initialized() )
00058 {
00059 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00060 }
00061 #ifdef TIMING
00062 OneWayTimer.start();
00063 #endif
00064
00065 const BIGNUM * op = operand.value();
00066 bool negativeExponent = false;
00067 BIGNUM * temp = 0;
00068 if ( operand.value()->neg )
00069 {
00070
00071
00072
00073
00074
00075
00076
00077 ((BIGNUM*)op)->neg = 0;
00078 negativeExponent = true;
00079 }
00080 const BIGNUM * n = m_modulus.value();
00081 const BIGNUM * b = m_base.value();
00082 BIGNUM * r = 0;
00083 BN_CTX * ctx = 0;
00084 try
00085 {
00086 r = BN_new();
00087 if ( 0 == r )
00088 {
00089 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00090 }
00091 ctx = BN_CTX_new();
00092 if ( 0 == ctx )
00093 {
00094 throw CODEX_Exceptions::BignumContextException( __FILE__ ,
00095 __LINE__ );
00096 }
00097 if ( ! BN_mod_exp( r, b, op, n, ctx ) )
00098 {
00099 throw CODEX_Exceptions::BignumModExpException( __FILE__ ,
00100 __LINE__ );
00101 }
00102 if ( negativeExponent )
00103 {
00104 if ( ! BN_mod_inverse( r, r, n, ctx ) )
00105 {
00106 throw CODEX_Exceptions::BignumModInverseException( __FILE__ ,
00107 __LINE__ );
00108 }
00109 }
00110 BN_CTX_free( ctx );
00111
00112 if ( negativeExponent ) ((BIGNUM*)op)->neg = 1;
00113 }
00114 catch ( ... )
00115 {
00116 if ( 0 != r ) BN_free(r);
00117 if ( 0 != ctx ) BN_CTX_free(ctx);
00118
00119 if ( negativeExponent ) ((BIGNUM*)op)->neg = 1;
00120 #ifdef TIMING
00121 OneWayTimer.cancel();
00122 #endif
00123 throw;
00124 }
00125 result = r;
00126 #ifdef TIMING
00127 OneWayTimer.stop();
00128 #endif
00129 }
00130
00131
00132 ModExpFunctionalArgs::ModExpFunctionalArgs() :
00133 CODEX_ASN1::Base( false )
00134 {
00135 }
00136
00137 ModExpFunctionalArgs::ModExpFunctionalArgs(
00138 const CODEX_ASN1::BigNumber& base,
00139 const CODEX_ASN1::BigNumber& modulus ) :
00140 CODEX_ASN1::Base( true ),
00141 m_base( base ),
00142 m_modulus( modulus )
00143 {
00144 }
00145
00146 ModExpFunctionalArgs::ModExpFunctionalArgs(
00147 const ModExpFunctionalArgs& aOther ) :
00148 CODEX_ASN1::Base( aOther.m_initialized ),
00149 m_base( aOther.m_base ),
00150 m_modulus( aOther.m_modulus )
00151 {
00152 }
00153
00154 ModExpFunctionalArgs::~ModExpFunctionalArgs()
00155 {
00156 }
00157
00158 void
00159 ModExpFunctionalArgs::operator=( const ModExpFunctionalArgs& aOther )
00160 {
00161 m_initialized = aOther.m_initialized;
00162 m_base = aOther.m_base;
00163 m_modulus = aOther.m_modulus;
00164 }
00165
00166 int
00167 ModExpFunctionalArgs::marshal( unsigned char ** pp ) const
00168 {
00169 if ( ! m_base.initialized() ) return 0;
00170 if ( ! m_modulus.initialized() ) return 0;
00171 int r=0;
00172 int ret=0;
00173 unsigned char * p;
00174
00175 ret += m_base.marshal(0);
00176 ret += m_modulus.marshal(0);
00177 M_ASN1_I2D_seq_total();
00178 m_base.marshal(&p);
00179 m_modulus.marshal(&p);
00180 M_ASN1_I2D_finish();
00181 }
00182
00183 void*
00184 ModExpFunctionalArgs::unmarshal( void* bogus,
00185 unsigned char** pp,
00186 long length )
00187 {
00188 if ( m_initialized )
00189 {
00190 return 0;
00191 }
00192 if ( (0 == pp) || (0 == *pp) )
00193 {
00194 return 0;
00195 }
00196
00197 ASN1_CTX c;
00198 c.pp = pp;
00199 c.q = *pp;
00200 c.error = ERR_R_NESTED_ASN1_ERROR;
00201 int i;
00202
00203 M_ASN1_D2I_Init();
00204 M_ASN1_D2I_start_sequence();
00205 M_ASN1_D2I_get(i, m_base.unmarshal);
00206 M_ASN1_D2I_get(i, m_modulus.unmarshal);
00207 if ( !asn1_Finish(&c) )
00208 {
00209 return 0;
00210 }
00211 *pp=c.p;
00212 m_initialized = true;
00213 return this;
00214 err:
00215 return 0;
00216 }