00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __CODEX_VSS_COMBINATORICSPLITTING_H__
00019 #define __CODEX_VSS_COMBINATORICSPLITTING_H__
00020
00021 #include "CODEX_ASN1/SecureBigNumber.h"
00022 #include "CODEX_Exceptions/BignumExceptions.h"
00023
00024 namespace CODEX_VSS
00025 {
00029 template< unsigned int NShares >
00030 class CombinatoricSplitting
00031 {
00032 public :
00034 CombinatoricSplitting( const CODEX_ASN1::BigNumber& minVal,
00035 const CODEX_ASN1::BigNumber& maxVal,
00036 const CODEX_ASN1::SecureBigNumber& secret );
00037
00039 CombinatoricSplitting( const CODEX_ASN1::BigNumber& maxVal,
00040 const CODEX_ASN1::SecureBigNumber& secret );
00041
00043 virtual ~CombinatoricSplitting();
00044
00046 const CODEX_ASN1::SecureBigNumber& share( unsigned int i ) const;
00047
00048 private :
00049 CODEX_ASN1::SecureBigNumber m_shares[ NShares ];
00050 };
00051
00052 template< unsigned int NShares >
00053 CombinatoricSplitting< NShares >::CombinatoricSplitting(
00054 const CODEX_ASN1::BigNumber& minVal,
00055 const CODEX_ASN1::BigNumber& maxVal,
00056 const CODEX_ASN1::SecureBigNumber& secret )
00057 {
00058 BIGNUM * m = 0;
00059 BIGNUM * temp = 0;
00060 BIGNUM * total = 0;
00061 BIGNUM * remainder = 0;
00062 try
00063 {
00064 m = BN_new();
00065 if ( 0 == m )
00066 {
00067 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00068 }
00069 total = BN_new();
00070 if ( 0 == total )
00071 {
00072 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00073 }
00074 remainder = BN_new();
00075 if ( 0 == remainder )
00076 {
00077 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00078 }
00079
00080 if ( ! BN_sub( m, maxVal.value(), minVal.value() ) )
00081 {
00082 throw CODEX_Exceptions::BignumSubException( __FILE__ , __LINE__ );
00083 }
00084 if ( ! BN_add( m, m, BN_value_one() ) )
00085 {
00086 throw CODEX_Exceptions::BignumAddException( __FILE__ , __LINE__ );
00087 }
00088
00089 for ( unsigned int i = 0 ; i < NShares - 1 ; ++i )
00090 {
00091 temp = BN_new();
00092 if ( 0 == temp )
00093 {
00094 throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00095 __LINE__ );
00096 }
00097 if ( ! BN_rand_range( temp, m ) )
00098 {
00099 throw CODEX_Exceptions::BignumRandRangeException( __FILE__ ,
00100 __LINE__ );
00101 }
00102 if ( ! BN_add( temp, temp, minVal.value() ) )
00103 {
00104 throw CODEX_Exceptions::BignumAddException( __FILE__ ,
00105 __LINE__ );
00106 }
00107
00108 if ( ! BN_add( total, total, temp ) )
00109 {
00110 throw CODEX_Exceptions::BignumAddException( __FILE__ ,
00111 __LINE__ );
00112 }
00113 m_shares[i] = CODEX_ASN1::SecureBigNumber( temp );
00114 temp = 0;
00115 }
00116
00117 if ( ! BN_sub( remainder, secret.value(), total ) )
00118 {
00119 throw CODEX_Exceptions::BignumSubException( __FILE__ , __LINE__ );
00120 }
00121 m_shares[NShares-1] = CODEX_ASN1::SecureBigNumber( remainder );
00122 BN_free(m);
00123 }
00124 catch ( ... )
00125 {
00126 if ( 0 != m ) BN_free(m);
00127 if ( 0 != temp ) BN_clear_free(temp);
00128 if ( 0 != total ) BN_clear_free(total);
00129 if ( 0 != remainder ) BN_clear_free(remainder);
00130 throw;
00131 }
00132 }
00133
00134 template< unsigned int NShares >
00135 CombinatoricSplitting< NShares >::CombinatoricSplitting(
00136 const CODEX_ASN1::BigNumber& maxVal,
00137 const CODEX_ASN1::SecureBigNumber& secret )
00138 {
00139 BIGNUM * m = 0;
00140 BIGNUM * temp = 0;
00141 BIGNUM * total = 0;
00142 BIGNUM * remainder = 0;
00143 try
00144 {
00145 m = BN_new();
00146 if ( 0 == m )
00147 {
00148 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00149 }
00150 total = BN_new();
00151 if ( 0 == total )
00152 {
00153 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00154 }
00155 remainder = BN_new();
00156 if ( 0 == remainder )
00157 {
00158 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00159 }
00160
00161 if ( ! BN_add( m, maxVal.value(), BN_value_one() ) )
00162 {
00163 throw CODEX_Exceptions::BignumAddException( __FILE__ , __LINE__ );
00164 }
00165
00166 for ( unsigned int i = 0 ; i < NShares - 1 ; ++i )
00167 {
00168 temp = BN_new();
00169 if ( 0 == temp )
00170 {
00171 throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00172 __LINE__ );
00173 }
00174 if ( ! BN_rand_range( temp, m ) )
00175 {
00176 throw CODEX_Exceptions::BignumRandRangeException( __FILE__ ,
00177 __LINE__ );
00178 }
00179
00180 if ( ! BN_add( total, total, temp ) )
00181 {
00182 throw CODEX_Exceptions::BignumAddException( __FILE__ ,
00183 __LINE__ );
00184 }
00185 m_shares[i] = CODEX_ASN1::SecureBigNumber( temp );
00186 temp = 0;
00187 }
00188
00189 if ( ! BN_sub( remainder, secret.value(), total ) )
00190 {
00191 throw CODEX_Exceptions::BignumSubException( __FILE__ , __LINE__ );
00192 }
00193 m_shares[NShares-1] = CODEX_ASN1::SecureBigNumber( remainder );
00194 BN_free(m);
00195 }
00196 catch ( ... )
00197 {
00198 if ( 0 != m ) BN_free(m);
00199 if ( 0 != temp ) BN_clear_free(temp);
00200 if ( 0 != total ) BN_clear_free(total);
00201 if ( 0 != remainder ) BN_clear_free(remainder);
00202 throw;
00203 }
00204 }
00205
00206 template< unsigned int NShares >
00207 CombinatoricSplitting< NShares >::~CombinatoricSplitting()
00208 {
00209 }
00210
00211 template< unsigned int NShares >
00212 const CODEX_ASN1::SecureBigNumber&
00213 CombinatoricSplitting< NShares >::share( unsigned int i ) const
00214 {
00215 if ( i >= NShares )
00216 {
00217 throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00218 }
00219 return m_shares[ i ];
00220 }
00221
00222 }
00223
00224 #endif