Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

Combinatoric.h

00001 /*
00002  * Copyright 2003 Michael A. Marsh, Cornell University. All rights reserved.
00003  * This software is released under the modified BSD license.
00004  * See the file LICENSE in the top-level directory for details.
00005  */
00006 //
00007 // $Id: Combinatoric.h,v 1.3 2004/05/19 15:57:00 mmarsh Exp $
00008 //
00009 // $Log: Combinatoric.h,v $
00010 // Revision 1.3  2004/05/19 15:57:00  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.2  2003/11/04 22:31:52  mmarsh
00014 // *** empty log message ***
00015 //
00016 //
00017 
00018 #ifndef __CODEX_VSS_COMBINATORIC_H__
00019 #define __CODEX_VSS_COMBINATORIC_H__
00020 
00021 #include <fstream>
00022 
00023 #include "CODEX_ASN1/SecureBigNumber.h"
00024 #include "CODEX_ASN1/Integer.h"
00025 #include "CODEX_Exceptions/BignumExceptions.h"
00026 #include "CODEX_Exceptions/FileExceptions.h"
00027 #include "ShareFunctional.h"
00028 #include "ShareSet.h"
00029 #include "CombinatoricScenario.h"
00030 #include "Range.h"
00031 
00032 namespace CODEX_VSS
00033 {
00037    template< int N , int T >
00038    struct choose
00039    {
00045          static const unsigned int value = N*choose<N-1,T-1>::value/T;
00046    };
00047 
00049    template< int N >
00050    struct choose<N,0>
00051    {
00053          static const unsigned int value = 1;
00054    };
00055 
00057    template< int N >
00058    struct choose<N,1>
00059    {
00061          static const unsigned int value = N;
00062    };
00063 
00068    template< unsigned int NumT , unsigned int ThreshT >
00069    class Combinatoric : public CODEX_ASN1::Base
00070    {
00071       public :
00073          typedef CODEX_ASN1::SecureBigNumber  ValueType;
00074 
00079          static const unsigned int NumShares = choose<NumT,ThreshT-1>::value+1;
00080 
00082          Combinatoric();
00083 
00085          Combinatoric( const Combinatoric<NumT,ThreshT>& aOther );
00086 
00088          Combinatoric( const ShareSet< Combinatoric<NumT,ThreshT> >& shareSet,
00089                        unsigned int partNum );
00090 
00092          virtual ~Combinatoric();
00093 
00095          void operator=( const Combinatoric<NumT,ThreshT>& aOther );
00096 
00104          void operator+=( const Combinatoric<NumT,ThreshT>& aOther );
00105 
00111          void setShare( unsigned int i,
00112                         const CODEX_ASN1::SecureBigNumber& share );
00113 
00118          const CODEX_ASN1::SecureBigNumber& share( unsigned int i ) const;
00119 
00121          unsigned int count() const;
00122 
00129          void apply( const ShareFunctional& func,
00130                      Combinatoric<NumT,ThreshT>& result ) const;
00131 
00137          void recover( CODEX_ASN1::SecureBigNumber& result ) const;
00138 
00139          int marshal( unsigned char ** pp ) const;
00140 
00141          void* unmarshal( void* bogus, unsigned char ** pp, long length );
00142 
00144          void toFile( const char* fname ) const;
00145 
00147          void* fromFile( const char* fname );
00148 
00149       private :
00150          CODEX_ASN1::SecureBigNumber  m_shares[ NumShares ];
00151    };
00152 
00153    template< unsigned int NumT , unsigned int ThreshT >
00154    Combinatoric<NumT,ThreshT>::Combinatoric() :
00155       CODEX_ASN1::Base( false )
00156    {
00157    }
00158 
00159    template< unsigned int NumT , unsigned int ThreshT >
00160    Combinatoric<NumT,ThreshT>::Combinatoric(
00161       const Combinatoric<NumT,ThreshT>& aOther ) :
00162       CODEX_ASN1::Base( aOther.m_initialized )
00163    {
00164       for ( unsigned int i = 0 ; i < NumShares ; ++i )
00165       {
00166          m_shares[i] = aOther.m_shares[i];
00167       }
00168    }
00169 
00170    template< unsigned int NumT , unsigned int ThreshT >
00171    Combinatoric<NumT,ThreshT>::Combinatoric(
00172       const ShareSet< Combinatoric<NumT,ThreshT> >& shareSet,
00173       unsigned int partNum ) :
00174       CODEX_ASN1::Base( true )
00175    {
00176       typedef CombinatoricScenario<NumT,ThreshT-1>  CSType;
00177       CSType* cs = CSType::instance();
00178       for ( unsigned int i = 0 ; i < NumShares ; ++i )
00179       {
00180          // Every participant gets the last share.
00181          if ( ( NumShares == (i+1) ) ||
00182               ( ! cs->inScenario( partNum, i ) ) )
00183          {
00184             m_shares[i] = shareSet(i);
00185          }
00186       }
00187    }
00188 
00189    template< unsigned int NumT , unsigned int ThreshT >
00190    Combinatoric<NumT,ThreshT>::~Combinatoric()
00191    {
00192    }
00193 
00194    template< unsigned int NumT , unsigned int ThreshT >
00195    void
00196    Combinatoric<NumT,ThreshT>::operator=(
00197       const Combinatoric<NumT,ThreshT>& aOther )
00198    {
00199       m_initialized = aOther.m_initialized;
00200       for ( unsigned int i = 0 ; i < NumShares ; ++i )
00201       {
00202          m_shares[i] = aOther.m_shares[i];
00203       }
00204    }
00205 
00206    template< unsigned int NumT , unsigned int ThreshT >
00207    void
00208    Combinatoric<NumT,ThreshT>::operator+=(
00209       const Combinatoric<NumT,ThreshT>& aOther )
00210    {
00211       if ( ! aOther.m_initialized )
00212       {
00213          return;
00214       }
00215       m_initialized = true;
00216       for ( unsigned int i = 0 ; i < NumShares ; ++i )
00217       {
00218          if ( ! m_shares[i].initialized() )
00219          {
00220             m_shares[i] = aOther.m_shares[i];
00221          }
00222       }
00223    }
00224 
00225    template< unsigned int NumT , unsigned int ThreshT >
00226    void
00227    Combinatoric<NumT,ThreshT>::setShare(
00228       unsigned int i,
00229       const CODEX_ASN1::SecureBigNumber& share )
00230    {
00231       if ( i >= NumShares )
00232       {
00233          throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00234       }
00235       m_shares[i] = share;
00236       m_initialized = true;
00237    }
00238 
00239    template< unsigned int NumT , unsigned int ThreshT >
00240    const CODEX_ASN1::SecureBigNumber&
00241    Combinatoric<NumT,ThreshT>::share( unsigned int i ) const
00242    {
00243       if ( i >= NumShares )
00244       {
00245          throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00246       }
00247       return m_shares[i];
00248    }
00249 
00250    template< unsigned int NumT , unsigned int ThreshT >
00251    unsigned int
00252    Combinatoric<NumT,ThreshT>::count() const
00253    {
00254       unsigned int retVal = 0;
00255       for ( unsigned int i = 0 ; i < NumShares ; ++i )
00256       {
00257          if ( m_shares[i].initialized() )
00258          {
00259             ++retVal;
00260          }
00261       }
00262       return retVal;
00263    }
00264 
00265    template< unsigned int NumT , unsigned int ThreshT >
00266    void
00267    Combinatoric<NumT,ThreshT>::apply( const ShareFunctional& func,
00268                                       Combinatoric<NumT,ThreshT>& result )
00269       const
00270    {
00271       result.m_initialized = true;
00272       for ( unsigned int i = 0 ; i < NumShares ; ++i )
00273       {
00274          if ( m_shares[i].initialized() )
00275          {
00276             func( m_shares[i] , result.m_shares[i] );
00277          }
00278       }
00279    }
00280 
00281    template< unsigned int NumT , unsigned int ThreshT >
00282    void
00283    Combinatoric<NumT,ThreshT>::recover( CODEX_ASN1::SecureBigNumber& result )
00284       const
00285    {
00286       if ( result.initialized() )
00287       {
00288          result = CODEX_ASN1::SecureBigNumber(); // reset
00289       }
00290       if ( ! m_initialized )
00291       {
00292          return;
00293       }
00294       for ( unsigned int i = 0 ; i < NumShares ; ++i )
00295       {
00296          if ( ! m_shares[i].initialized() )
00297          {
00298             return;
00299          }
00300       }
00301       BIGNUM * r = 0;
00302       try
00303       {
00304          r = BN_new();
00305          if ( 0 == r )
00306          {
00307             throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00308          }
00309          if ( ! BN_zero(r) )
00310          {
00311             throw CODEX_Exceptions::BignumSetWordException( __FILE__ ,
00312                                                             __LINE__ );
00313          }
00314          for ( unsigned int i = 0 ; i < NumShares ; ++i )
00315          {
00316             if ( ! BN_add( r, r, m_shares[i].value() ) )
00317             {
00318                throw CODEX_Exceptions::BignumAddException( __FILE__ ,
00319                                                            __LINE__ );
00320             }
00321          }
00322          result = CODEX_ASN1::SecureBigNumber( r );
00323       }
00324       catch ( ... )
00325       {
00326          if ( 0 != r ) BN_clear_free(r);
00327          throw;
00328       }
00329    }
00330 
00331    template< unsigned int NumT , unsigned int ThreshT >
00332    int
00333    Combinatoric<NumT,ThreshT>::marshal( unsigned char ** pp ) const
00334    {
00335       int r=0;
00336       int ret=0;
00337       unsigned char * p;
00338 
00339       CODEX_ASN1::Integer isSet[NumShares];
00340       for ( unsigned int counter = 0 ; counter < NumShares ; ++counter )
00341       {
00342          isSet[counter] =
00343             CODEX_ASN1::Integer( m_shares[counter].initialized() ? 1 : 0 );
00344       }
00345       for ( unsigned int counter = 0 ; counter < NumShares ; ++counter )
00346       {
00347          ret += isSet[counter].marshal(0);
00348          if ( isSet[counter].value() )
00349          {
00350             ret += m_shares[counter].marshal(0);
00351          }
00352       }
00353       M_ASN1_I2D_seq_total();
00354       for ( unsigned int counter = 0 ; counter < NumShares ; ++counter )
00355       {
00356          isSet[counter].marshal(&p);
00357          if ( isSet[counter].value() )
00358          {
00359             m_shares[counter].marshal(&p);
00360          }
00361       }
00362       M_ASN1_I2D_finish();
00363    }
00364 
00365    template< unsigned int NumT , unsigned int ThreshT >
00366    void*
00367    Combinatoric<NumT,ThreshT>::unmarshal( void* bogus,
00368                                           unsigned char ** pp,
00369                                           long length )
00370    {
00371       if ( m_initialized )
00372       {
00373          return 0;
00374       }
00375       if ( (0 == pp) || (0 == *pp) )
00376       {
00377          return 0;
00378       }
00379       ASN1_CTX c;
00380       c.pp = pp;
00381       c.q = *pp;
00382       c.error = ERR_R_NESTED_ASN1_ERROR;
00383       int i;
00384 
00385       M_ASN1_D2I_Init();
00386       M_ASN1_D2I_start_sequence();
00387       for ( unsigned int counter = 0 ; counter < NumShares ; ++counter )
00388       {
00389          CODEX_ASN1::Integer isSet;
00390          M_ASN1_D2I_get(i, isSet.unmarshal);
00391          if ( isSet.value() )
00392          {
00393             M_ASN1_D2I_get(i, m_shares[counter].unmarshal);
00394          }
00395       }
00396       if ( !asn1_Finish(&c) )
00397       {
00398          return 0;
00399       }
00400       *pp=c.p;
00401       m_initialized = true;
00402       return this;
00403      err: // needed by ASN.1 macros
00404       return 0;
00405    }
00406 
00407    template< unsigned int NumT , unsigned int ThreshT >
00408    void
00409    Combinatoric<NumT,ThreshT>::toFile( const char* fname ) const
00410    {
00411       int length = marshal(0);
00412       if ( 0 == length ) return;
00413       unsigned char* buff = new unsigned char[length];
00414       unsigned char* p = buff;
00415       marshal(&p);
00416       ofstream os(fname);
00417       if ( ! os.is_open() )
00418       {
00419          delete [] buff;
00420          throw CODEX_Exceptions::FileCannotCreateException( __FILE__ ,
00421                                                             __LINE__ ,
00422                                                             fname );
00423       }
00424       for ( int i = 0 ; i < length ; ++i )
00425       {
00426          os << buff[i];
00427       }
00428       os.close();
00429       delete [] buff;
00430    }
00431 
00432    template< unsigned int NumT , unsigned int ThreshT >
00433    void*
00434    Combinatoric<NumT,ThreshT>::fromFile( const char* fname )
00435    {
00436       ifstream is(fname);
00437       if ( ! is.is_open() )
00438       {
00439          throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00440                                                           __LINE__ ,
00441                                                           fname );
00442       }
00443       string s;
00444       char ch;
00445       while ( is.get(ch) )
00446       {
00447          s.push_back(ch);
00448       }
00449       //basic_string<unsigned char> s;
00450       //is >> s;
00451       unsigned int length = s.length();
00452       unsigned char* p = new unsigned char[length];
00453       unsigned char* pOrig = p;
00454       //unsigned char* p = (unsigned char*)s.data();
00455       for ( unsigned int i = 0 ; i < length ; ++i )
00456       {
00457          p[i] = s.data()[i];
00458       }
00459       return unmarshal(0,&p,length);
00460       delete [] pOrig;
00461    }
00462 
00463 
00465    template< unsigned int NumT , unsigned int ThreshT >
00466    class ShareSet< Combinatoric<NumT,ThreshT> >
00467    {
00468       public :
00470          typedef Combinatoric<NumT,ThreshT>  ShareType;
00471 
00473          ShareSet() {}
00474 
00476          ShareSet( const ShareSet< ShareType >& aOther ) :
00477             m_shares( aOther.m_shares )
00478          {}
00479 
00481          void operator=( const ShareSet< ShareType >& aOther )
00482          {
00483             m_shares = aOther.m_shares;
00484          }
00485 
00494          const typename ShareType::ValueType& operator()( unsigned int i )
00495             const
00496          {
00497             return m_shares.share(i);
00498          }
00499 
00507          void setShare( unsigned int i,
00508                         const typename ShareType::ValueType& share )
00509          {
00510             m_shares.setShare(i,share);
00511          }
00512 
00514          void addShare( const ShareType& share )
00515          {
00516             m_shares += share;
00517          }
00518 
00524          void recover( CODEX_ASN1::SecureBigNumber& result ) const
00525          {
00526             return m_shares.recover( result );
00527          }
00528 
00538          bool shouldHave( unsigned int shareNum, unsigned int partNum ) const
00539          {
00540             typedef CombinatoricScenario<NumT,ThreshT-1>  CSType;
00541             CSType* cs = CSType::instance();
00542             if ( shareNum + 1 == ShareType::NumShares )
00543             {
00544                return true;
00545             }
00546             return ( ! cs->inScenario( partNum, shareNum ) );
00547          }
00548 
00549       private :
00550          ShareType  m_shares;
00551    };
00552 
00554    template< unsigned int NumT , unsigned int ThreshT >
00555    class ShareSplitting< Combinatoric<NumT,ThreshT> >
00556    {
00557       public :
00559          typedef Combinatoric<NumT,ThreshT>  ShareType;
00560 
00562          const static unsigned int           NumShares = ShareType::NumShares;
00563 
00573          static void split( const BIGNUM* secret,
00574                             ShareSet< ShareType >& shareSet,
00575                             const Range& range )
00576          {
00577             const BIGNUM * minVal = range.min();
00578             const BIGNUM * maxVal = range.max();
00579             BIGNUM * m = 0;
00580             BIGNUM * temp = 0;
00581             BIGNUM * total = 0;
00582             BIGNUM * remainder = 0;
00583             try
00584             {
00585                m = BN_new();
00586                if ( 0 == m )
00587                {
00588                   throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00589                                                                __LINE__ );
00590                }
00591                total = BN_new();
00592                if ( 0 == total )
00593                {
00594                   throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00595                                                                __LINE__ );
00596                }
00597                remainder = BN_new();
00598                if ( 0 == remainder )
00599                {
00600                   throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00601                                                                __LINE__ );
00602                } 
00603 
00604                if ( ! BN_sub( m, maxVal, minVal ) )
00605                {
00606                   throw CODEX_Exceptions::BignumSubException( __FILE__ ,
00607                                                               __LINE__ );
00608                }
00609                if ( ! BN_add( m, m, BN_value_one() ) )
00610                {
00611                   throw CODEX_Exceptions::BignumAddException( __FILE__ ,
00612                                                               __LINE__ );
00613                }
00614 
00615                for ( unsigned int i = 0 ; i < NumShares - 1 ; ++i )
00616                {
00617                   temp = BN_new();
00618                   if ( 0 == temp )
00619                   {
00620                      throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00621                                                                   __LINE__ );
00622                   }
00623                   if ( ! BN_rand_range( temp, m ) )
00624                   {
00625                      throw
00626                         CODEX_Exceptions::BignumRandRangeException( __FILE__ ,
00627                                                                     __LINE__ );
00628                   }
00629                   if ( ! BN_add( temp, temp, minVal ) )
00630                   {
00631                      throw CODEX_Exceptions::BignumAddException( __FILE__ ,
00632                                                                  __LINE__ );
00633                   }
00634 
00635                   if ( ! BN_add( total, total, temp ) )
00636                   {
00637                      throw CODEX_Exceptions::BignumAddException( __FILE__ ,
00638                                                                  __LINE__ );
00639                   }
00640                   shareSet.setShare(i,ShareType::ValueType(temp));
00641                   temp = 0;  // temp's memory is taken over above
00642                }
00643 
00644                if ( ! BN_sub( remainder, secret, total ) )
00645                {
00646                   throw CODEX_Exceptions::BignumSubException( __FILE__ ,
00647                                                               __LINE__ );
00648                }
00649                shareSet.setShare(NumShares-1,ShareType::ValueType(remainder));
00650                remainder = 0; // remainder's memory is taken over above
00651                BN_clear_free(total);
00652                BN_free(m);
00653             }
00654             catch ( ... )
00655             {
00656                if ( 0 != m ) BN_free(m);
00657                if ( 0 != temp ) BN_clear_free(temp);
00658                if ( 0 != total ) BN_clear_free(total);
00659                if ( 0 != remainder ) BN_clear_free(remainder);
00660                throw;
00661             }
00662          }
00663    };
00664 
00665 }
00666 
00667 #endif /* __CODEX_VSS_COMBINATORIC_H__*/

Generated on Wed Jun 2 16:32:54 2004 for COrnell Data EXchange (CODEX) by doxygen1.2.18