00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <fstream>
00019 #include "VarRSA.h"
00020 #include "BIGNUM_xor.h"
00021 #include "CODEX_Exceptions/BignumExceptions.h"
00022
00023 #include "timing.h"
00024
00025 using namespace CODEX_Ciphers;
00026 using namespace CODEX_Exceptions;
00027
00028 VarRSAPublicKey::VarRSAPublicKey( const RSAPublicKey& aKey ) :
00029 m_key( aKey )
00030 {
00031 }
00032
00033 VarRSACipherText*
00034 VarRSAPublicKey::encrypt( const BIGNUM * message,
00035 const HashFunction& hashFunc,
00036 BIGNUM * r ) const
00037 {
00038 if ( 0 == message )
00039 {
00040 throw BignumNullException( __FILE__ , __LINE__ );
00041 }
00042
00043 BIGNUM * c1 = 0;
00044 BIGNUM * c2 = 0;
00045 bool ownR = false;
00046 BIGNUM * temp = 0;
00047 BN_CTX * ctx = 0;
00048 unsigned char* buff = 0;
00049 CODEX_ASN1::ustring* tempStr = 0;
00050 try
00051 {
00052 ctx = BN_CTX_new();
00053 if ( 0 == ctx )
00054 {
00055 throw BignumContextException( __FILE__ , __LINE__ );
00056 }
00057
00058 if ( 0 == r )
00059 {
00060 ownR = true;
00061 r = BN_new();
00062 if ( 0 == r )
00063 {
00064 throw BignumNullException( __FILE__ , __LINE__ );
00065 }
00066 }
00067
00068 do
00069 {
00070 if ( ! BN_rand_range( r, (BIGNUM*)(n().value()) ) )
00071 {
00072 throw BignumRandRangeException( __FILE__ , __LINE__ );
00073 }
00074 }
00075 while ( 0 >= BN_cmp( r, BN_value_one() ) );
00076
00077
00078 c1 = exponentiate( r );
00079 CODEX_ASN1::SecureBigNumber rbn( BN_dup(r) );
00080 if ( ownR )
00081 {
00082 BN_clear_free( r );
00083 r = 0;
00084 }
00085
00086
00087 c2 = BN_new();
00088 if ( 0 == c2 )
00089 {
00090 throw BignumNullException( __FILE__ , __LINE__ );
00091 }
00092 int length = rbn.marshal(0);
00093 buff = new unsigned char[length];
00094 unsigned char* pBuff = buff;
00095 rbn.marshal(&pBuff);
00096 tempStr = hashFunc( CODEX_ASN1::ustring(buff,length),
00097 BN_num_bits(n().value()) );
00098 temp = BN_new();
00099 if ( 0 == temp )
00100 {
00101 throw BignumNullException( __FILE__ , __LINE__ );
00102 }
00103 if ( 0 == BN_bin2bn( tempStr->data(), tempStr->length(), c2 ) )
00104 {
00105 throw BignumBin2BNException( __FILE__ , __LINE__ );
00106 }
00107 if ( ! BN_mod( temp, c2, n().value(), ctx ) )
00108 {
00109 throw BignumModException( __FILE__ , __LINE__ );
00110 }
00111 delete tempStr;
00112 tempStr = 0;
00113 delete [] buff;
00114 buff = 0;
00115
00116 BIGNUM_xor( c2, temp, message );
00117 BN_clear_free( temp );
00118 BN_CTX_free( ctx );
00119
00120
00121 return new VarRSACipherText( c1, c2 );
00122 }
00123 catch ( ... )
00124 {
00125 if ( 0 != c1 ) BN_free( c1 );
00126 if ( 0 != c2 ) BN_free( c2 );
00127 if ( ownR && r ) BN_clear_free( r );
00128 if ( 0 != temp ) BN_clear_free( temp );
00129 if ( 0 != ctx ) BN_CTX_free( ctx );
00130 if ( 0 != tempStr ) delete tempStr;
00131 if ( 0 != buff ) delete [] buff;
00132 throw;
00133 }
00134 }