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