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