00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <fstream>
00022 #include <sstream>
00023 #include <openssl/ssl.h>
00024 #include <openssl/conf.h>
00025 #include <unistd.h>
00026
00027 #include "CODEX_Ciphers/RSA.h"
00028 #include "CODEX_Ciphers/RSAPlaintextPK.h"
00029 #include "CODEX_Ciphers/VarRSA.h"
00030 #include "CODEX_Ciphers/ElGamal.h"
00031 #include "CODEX_Ciphers/SHA1HashFunction.h"
00032 #include "CODEX_Server/ConfigurationExceptions.h"
00033 #include "CODEX_Server/ServerState.h"
00034 #include "CODEX_ThresholdCrypto/CombinatoricThresholdRSA.h"
00035
00036 #include "timing.h"
00037
00038 using namespace CODEX_Server;
00039 using namespace std;
00040
00041 int main( int argc, char** argv )
00042 {
00043 #ifndef TIMING
00044 cerr << "Timing must be configured" << endl;
00045 return 1;
00046 #else
00047
00048 SSLeay_add_ssl_algorithms();
00049
00050 int arg = 0;
00051 string fname;
00052 string config_section;
00053 string usage_string(
00054 "Usage: cryptosystem_comparison -c <config_file> [-s <section>]");
00055 while ( -1 != arg )
00056 {
00057 arg = getopt(argc,argv,"c:s:");
00058 switch(arg)
00059 {
00060 case 'c' :
00061 fname = optarg;
00062 break;
00063 case 's' :
00064 config_section = optarg;
00065 break;
00066 case ':' :
00067 case '?' :
00068 cerr << usage_string << endl;
00069 ::exit(1);
00070 }
00071 }
00072 if ( 0 == fname.size() )
00073 {
00074 cerr << usage_string << endl;
00075 ::exit(1);
00076 }
00077
00078 unsigned int nerror = 0;
00079 try
00080 {
00081 CONF* conf = NCONF_new(NCONF_default());
00082 if ( 0 == NCONF_load(conf,fname.c_str(),0) )
00083 {
00084 throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00085 __LINE__ ,
00086 fname );
00087 }
00088 char* section = (char*) config_section.c_str();
00089
00090 const unsigned int N = ServerState::nServers;
00091 const unsigned int T = 1 + ServerState::nFaults;
00092
00093 long dummy;
00094 if ( ! NCONF_get_number_e(conf,section,"nhosts",&dummy) )
00095 {
00096 throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00097 fname, "nhosts" );
00098 }
00099 if ( N != dummy )
00100 {
00101 throw BCBadValueException( __FILE__ , __LINE__ , fname, "nhosts" );
00102 }
00103 if ( ! NCONF_get_number_e(conf,section,"nfaults",&dummy) )
00104 {
00105 throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00106 fname, "nfaults" );
00107 }
00108 if ( (T-1) != dummy )
00109 {
00110 throw BCBadValueException( __FILE__ , __LINE__ , fname, "nfaults" );
00111 }
00112
00113 const char* pubKeyFile =
00114 NCONF_get_string(conf,section,"service_cert_file");
00115 if ( 0 == pubKeyFile )
00116 {
00117 throw BCBadValueException( __FILE__ , __LINE__ ,
00118 fname, "service_cert_file" );
00119 }
00120 CODEX_ASN1::Certificate cert;
00121 cert.fromPEMFile( pubKeyFile );
00122 CODEX_Ciphers::RSAPublicKey pubKey( cert.value() );
00123
00124 const char* privKeyFile =
00125 NCONF_get_string(conf,section,"private_key_file");
00126 if ( 0 == privKeyFile )
00127 {
00128 throw BCBadValueException( __FILE__ , __LINE__ ,
00129 fname, "private_key_file" );
00130 }
00131 const char* privKeyPasswd =
00132 NCONF_get_string(conf,section,"private_key_passwd");
00133 CODEX_Ciphers::RSAPrivateKey privKey;
00134 privKey.fromPEMFile( privKeyFile, privKeyPasswd );
00135
00136 const char* pubEGKeyFile =
00137 NCONF_get_string(conf,section,"public_eg_key_file");
00138 if ( 0 == pubEGKeyFile )
00139 {
00140 throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00141 fname, "public_eg_key_file" );
00142 }
00143 const char* privEGKeyFile =
00144 NCONF_get_string(conf,section,"private_eg_key_file");
00145 if ( 0 == privEGKeyFile )
00146 {
00147 throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00148 fname, "private_eg_key_file" );
00149 }
00150
00151 CODEX_Server::SignedAugmentedEGPublicKey signedPubEGKey;
00152 ifstream is(pubEGKeyFile);
00153 if ( ! is.is_open() )
00154 {
00155 throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00156 __LINE__ ,
00157 pubEGKeyFile );
00158 }
00159 string s;
00160 char ch;
00161 while ( is.get(ch) )
00162 {
00163 s.push_back(ch);
00164 }
00165
00166
00167 unsigned int length = s.length();
00168
00169 unsigned char* p = new unsigned char[length];
00170 unsigned char* pOrig = p;
00171 for ( unsigned int i = 0 ; i < length ; ++i )
00172 {
00173 p[i] = s.data()[i];
00174 }
00175 if ( 0 == signedPubEGKey.unmarshal(0,&p,length) )
00176 {
00177 delete [] pOrig;
00178 throw PublicKeyNotFoundException( __FILE__ , __LINE__ );
00179 }
00180 delete [] pOrig;
00181 const CODEX_Ciphers::ElGamalPublicKey& pubEGKey =
00182 signedPubEGKey.key().key();
00183 CODEX_Ciphers::ElGamalPrivateKey privEGKey;
00184 privEGKey.fromFile( privEGKeyFile );
00185
00186 typedef CODEX_VSS::ModExpFunctional OneWay;
00187 typedef CODEX_VSS::Combinatoric< N , T > ShareType;
00188 typedef CODEX_VSS::LabeledShare< ShareType , OneWay > LSType;
00189 typedef CODEX_VSS::SecretWitness< ShareType , OneWay > WitnessType;
00190
00191 const char* output_dir =
00192 NCONF_get_string(conf,section,"output_directory");
00193 if ( 0 == output_dir )
00194 {
00195 throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00196 fname, "output_directory" );
00197 }
00198
00199 WitnessType rsaWitness;
00200 ostringstream rwstr;
00201 rwstr << output_dir << "/rsa.witness\0";
00202 rsaWitness.fromFile( rwstr.str().c_str() );
00203
00204 WitnessType egWitness;
00205 ostringstream ewstr;
00206 ewstr << output_dir << "/elgamal.witness\0";
00207 egWitness.fromFile( ewstr.str().c_str() );
00208
00209 LSType rsaSharings[N];
00210 LSType elgamalSharings[N];
00211 for ( unsigned int i = 0 ; i < N ; ++i )
00212 {
00213 ostringstream rstr;
00214 rstr << output_dir << "/rsa." << i << ".shares" << '\0';
00215 rsaSharings[i].fromFile( rstr.str().c_str() );
00216 ostringstream estr;
00217 estr << output_dir << "/elgamal." << i << ".shares" << '\0';
00218 elgamalSharings[i].fromFile( estr.str().c_str() );
00219 }
00220
00221
00222 NCONF_free( conf );
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 const CODEX_ASN1::SecureBigNumber& plaintext = privKey.d();
00242 const CODEX_Ciphers::HashFunction& hashFunc =
00243 ServerState::instance()->hashFunc();
00244
00245 const BIGNUM * bmax = ( pubKey.n() > pubEGKey.p() ) ?
00246 pubEGKey.p().value() :
00247 pubKey.n().value();
00248
00249 BIGNUM * r = 0;
00250 BIGNUM * b = 0;
00251
00252 CODEX_Ciphers::VarRSAPublicKey varRSAEncKey( pubKey );
00253 CODEX_Ciphers::VarRSACipherText* rsaEncryption = 0;
00254 CODEX_Ciphers::RSAPlaintextPK* rsaProof = 0;
00255 CODEX_Ciphers::RSACipherText* rsaBlindingCipher = 0;
00256 CODEX_Ciphers::VarRSABlindCipherText* rsaBlindEncryption = 0;
00257
00258 CODEX_Ciphers::ElGamalSchnorrCipherText* egEncryption = 0;
00259 CODEX_Ciphers::ElGamalSchnorrCipherText* egBlindingCipher = 0;
00260 CODEX_Ciphers::ElGamalCipherText* egBlindEncryption = 0;
00261
00262 try
00263 {
00264 r = BN_new();
00265 if ( 0 == r )
00266 {
00267 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00268 }
00269 rsaEncryption =
00270 varRSAEncKey.encrypt( plaintext.value(), hashFunc, r );
00271 rsaProof =
00272 new CODEX_Ciphers::RSAPlaintextPK( r, pubKey, pubKey, hashFunc );
00273 r = 0;
00274
00275 egEncryption =
00276 pubEGKey.encryptS( plaintext.value(), pubKey, hashFunc );
00277 }
00278 catch ( ... )
00279 {
00280 if ( 0 != r ) BN_clear_free(r);
00281 if ( 0 != rsaEncryption ) delete rsaEncryption;
00282 if ( 0 != rsaProof ) delete rsaProof;
00283 if ( 0 != egEncryption ) delete egEncryption;
00284 throw;
00285 }
00286
00287 CODEX_ThresholdCrypto::ThresholdVarRSACrypto< ShareType >
00288 tRSA( pubKey.n() );
00289 CODEX_ThresholdCrypto::ThresholdElGamalCrypto< ShareType >
00290 tEG( pubEGKey.p() );
00291
00292 ShareType rsaDecShares;
00293 ShareType egDecShares;
00294
00295
00296 for ( unsigned int i = 0 ; i < 100000 ; ++i )
00297 {
00298 if ( 0 == i%1000 )
00299 {
00300 PartialDecTimer.print(cout);
00301 PartialRSADecTimer.print(cout);
00302 SchnorrTimer.print(cout);
00303 RSAPPKTimer.print(cout);
00304
00305 PartialDecTimer.clear();
00306 PartialRSADecTimer.clear();
00307 SchnorrTimer.clear();
00308 RSAPPKTimer.clear();
00309 }
00310 try
00311 {
00312
00313 if ( ! egEncryption->verify( pubEGKey.g(),
00314 pubEGKey.p(),
00315 pubKey,
00316 hashFunc ) )
00317 {
00318 cerr << "Failed to verify Schnorr proof!" << endl;
00319 return 1;
00320 }
00321 if ( ! rsaProof->verify( rsaEncryption->c1(),
00322 pubKey,
00323 pubKey,
00324 hashFunc ) )
00325 {
00326 cerr << "Failed to verify RSA proof!" << endl;
00327 return 1;
00328 }
00329
00330
00331 b = BN_new();
00332 if ( 0 == b )
00333 {
00334 throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00335 __LINE__ );
00336 }
00337 if ( ! BN_rand_range( b, (BIGNUM*)bmax ) )
00338 {
00339 throw CODEX_Exceptions::BignumRandRangeException( __FILE__ ,
00340 __LINE__ );
00341 }
00342 rsaBlindingCipher = pubKey.encrypt( b );
00343 egBlindingCipher = pubEGKey.encryptS( b, pubKey, hashFunc );
00344 BN_clear_free( b );
00345 b = 0;
00346
00347
00348 rsaBlindEncryption =
00349 rsaEncryption->blind( *rsaBlindingCipher, pubKey.n() );
00350 egBlindEncryption =
00351 egEncryption->blind( *egBlindingCipher, pubEGKey.p() );
00352
00353
00354 tRSA.decrypt( rsaSharings[0].share(),
00355 *rsaBlindEncryption,
00356 rsaDecShares );
00357 tEG.decrypt( elgamalSharings[0].share(),
00358 *egBlindEncryption,
00359 egDecShares );
00360
00361 delete rsaBlindingCipher;
00362 delete egBlindingCipher;
00363 delete rsaBlindEncryption;
00364 delete egBlindEncryption;
00365 }
00366 catch ( ... )
00367 {
00368 if ( 0 != b ) BN_clear_free(b);
00369 if ( 0 != rsaBlindingCipher ) delete rsaBlindingCipher;
00370 if ( 0 != egBlindingCipher ) delete egBlindingCipher;
00371 if ( 0 != rsaBlindEncryption ) delete rsaBlindEncryption;
00372 if ( 0 != egBlindEncryption ) delete egBlindEncryption;
00373 throw;
00374 }
00375 }
00376
00377 delete rsaEncryption;
00378 delete rsaProof;
00379 delete egEncryption;
00380
00381 }
00382 catch ( CODEX_Exceptions::ExceptionBase& e )
00383 {
00384 e.report();
00385 return 1;
00386 }
00387
00388 PartialDecTimer.print(cout);
00389 PartialRSADecTimer.print(cout);
00390 SchnorrTimer.print(cout);
00391 RSAPPKTimer.print(cout);
00392
00393 return 0;
00394 #endif
00395 }