00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __CODEX_THRESHOLDCRYPTO_COMBINATORICTHRESHOLDELGAMAL_H__
00019 #define __CODEX_THRESHOLDCRYPTO_COMBINATORICTHRESHOLDELGAMAL_H__
00020
00021 #include <fstream>
00022
00023 #include "ThresholdElGamal.h"
00024 #include "CODEX_VSS/Combinatoric.h"
00025
00026 #include "timing.h"
00027
00028 namespace CODEX_ThresholdCrypto
00029 {
00031 template< unsigned int NumT , unsigned int ThreshT >
00032 class ThresholdElGamalCrypto< CODEX_VSS::Combinatoric< NumT , ThreshT > >
00033 {
00034 public :
00036 typedef CODEX_VSS::Combinatoric< NumT , ThreshT > ShareType;
00037
00039 typedef CODEX_VSS::ShareSet< ShareType > SetType;
00040
00042 typedef CODEX_Ciphers::ElGamalCipherText CipherTextType;
00043
00045 ThresholdElGamalCrypto( const CODEX_ASN1::BigNumber& modulus ) :
00046 m_modulus( modulus )
00047 {
00048 }
00049
00053 void decrypt( const ShareType& shares,
00054 const CipherTextType& ciphertext,
00055 ShareType& partials ) const
00056 {
00057 #ifdef TIMING
00058 PartialDecTimer.start();
00059 #endif
00060
00061 CODEX_VSS::ModExpFunctional f( ciphertext.c1(), m_modulus );
00062 shares.apply( f, partials );
00063 #ifdef TIMING
00064 PartialDecTimer.stop();
00065 #endif
00066 }
00067
00081 BIGNUM* thresholdDecrypt( const SetType& partials,
00082 const CipherTextType& ciphertext ) const
00083 {
00084 #ifdef TIMING
00085 ThresholdDecTimer.start();
00086 #endif
00087 for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00088 {
00089 if ( ! partials(i).initialized() )
00090 {
00091 #ifdef TIMING
00092 ThresholdDecTimer.stop();
00093 #endif
00094 return 0;
00095 }
00096 }
00097 const BIGNUM * n = m_modulus.value();
00098 BIGNUM * s = 0;
00099 BN_CTX * ctx = 0;
00100 try
00101 {
00102 ctx = BN_CTX_new();
00103 if ( 0 == ctx )
00104 {
00105 throw CODEX_Exceptions::BignumContextException( __FILE__ ,
00106 __LINE__ );
00107 }
00108 s = BN_new();
00109 if ( 0 == s )
00110 {
00111 throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00112 __LINE__ );
00113 }
00114 BN_one(s);
00115 for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00116 {
00117 const BIGNUM * share = partials(i).value();
00118 if ( ! BN_mod_mul( s, s, share, n, ctx ) )
00119 {
00120 throw CODEX_Exceptions::BignumModMulException( __FILE__ ,
00121 __LINE__ );
00122 }
00123 }
00124
00125
00126
00127 if ( ! BN_mod_inverse( s, s, n, ctx ) )
00128 {
00129 throw
00130 CODEX_Exceptions::BignumModInverseException( __FILE__ ,
00131 __LINE__ );
00132 }
00133 if ( ! BN_mod_mul( s, s, ciphertext.c2().value(), n, ctx ) )
00134 {
00135 throw CODEX_Exceptions::BignumModMulException( __FILE__ ,
00136 __LINE__ );
00137 }
00138 }
00139 catch ( ... )
00140 {
00141 if ( 0 != s ) BN_free(s);
00142 if ( 0 != ctx ) BN_CTX_free(ctx);
00143 #ifdef TIMING
00144 ThresholdDecTimer.stop();
00145 #endif
00146 throw;
00147 }
00148 BN_CTX_free(ctx);
00149 #ifdef TIMING
00150 ThresholdDecTimer.stop();
00151 #endif
00152 return s;
00153 }
00154
00155 private :
00156 CODEX_ASN1::BigNumber m_modulus;
00157 };
00158
00159 }
00160
00161 #endif