Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ModExpFunctional.cc

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: ModExpFunctional.cc,v 1.3 2004/05/19 15:57:00 mmarsh Exp $
00008 //
00009 // $Log: ModExpFunctional.cc,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:23:08  mmarsh
00014 // General code cleanup.
00015 //
00016 //
00017 
00018 #include "ModExpFunctional.h"
00019 #include "CODEX_Exceptions/BignumExceptions.h"
00020 
00021 #include "timing.h"
00022 
00023 using namespace CODEX_VSS;
00024 
00025 ModExpFunctional::ModExpFunctional( const ArgType& base,
00026                                     const ArgType& modulus ) :
00027    ShareFunctional(),
00028    m_base( base ),
00029    m_modulus( modulus )
00030 {
00031 }
00032 
00033 ModExpFunctional::ModExpFunctional( const CtorArgs& args ) :
00034    ShareFunctional(),
00035    m_base( args.base() ),
00036    m_modulus( args.modulus() )
00037 {
00038 }
00039 
00040 ModExpFunctional::~ModExpFunctional()
00041 {
00042 }
00043 
00045 void
00046 ModExpFunctional::operator()( const CODEX_ASN1::SecureBigNumber& operand,
00047                               CODEX_ASN1::BigNumber& result ) const
00048 {
00049    if ( ! m_modulus.initialized() )
00050    {
00051       throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00052    }
00053    if ( ! m_base.initialized() )
00054    {
00055       throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00056    }
00057    if ( ! operand.initialized() )
00058    {
00059       throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00060    }
00061 #ifdef TIMING
00062    OneWayTimer.start();
00063 #endif
00064    // If the operand is negative, we will need to take special actions.
00065    const BIGNUM * op = operand.value();
00066    bool negativeExponent = false;
00067    BIGNUM * temp = 0;
00068    if ( operand.value()->neg )
00069    {
00070 //      temp = BN_dup(op);
00071 //      if ( 0 == temp )
00072 //      {
00073 //         throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00074 //      }
00075 //      temp->neg = 0;
00076 //      op = temp;
00077       ((BIGNUM*)op)->neg = 0;
00078       negativeExponent = true;
00079    }
00080    const BIGNUM * n = m_modulus.value();
00081    const BIGNUM * b = m_base.value();
00082    BIGNUM * r = 0;
00083    BN_CTX * ctx = 0;
00084    try
00085    {
00086       r = BN_new();
00087       if ( 0 == r )
00088       {
00089          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00090       }
00091       ctx = BN_CTX_new();
00092       if ( 0 == ctx )
00093       {
00094          throw CODEX_Exceptions::BignumContextException( __FILE__ ,
00095                                                          __LINE__ );
00096       }
00097       if ( ! BN_mod_exp( r, b, op, n, ctx ) )
00098       {
00099          throw CODEX_Exceptions::BignumModExpException( __FILE__ ,
00100                                                         __LINE__ );
00101       }
00102       if ( negativeExponent )
00103       {
00104          if ( ! BN_mod_inverse( r, r, n, ctx ) )
00105          {
00106             throw CODEX_Exceptions::BignumModInverseException( __FILE__ ,
00107                                                                __LINE__ );
00108          }
00109       }
00110       BN_CTX_free( ctx );
00111 //      if ( negativeExponent ) BN_free( temp );
00112       if ( negativeExponent ) ((BIGNUM*)op)->neg = 1;
00113    }
00114    catch ( ... )
00115    {
00116       if ( 0 != r ) BN_free(r);
00117       if ( 0 != ctx ) BN_CTX_free(ctx);
00118 //      if ( negativeExponent ) BN_free( temp );
00119       if ( negativeExponent ) ((BIGNUM*)op)->neg = 1;
00120 #ifdef TIMING
00121       OneWayTimer.cancel();
00122 #endif
00123       throw;
00124    }
00125    result = r;
00126 #ifdef TIMING
00127    OneWayTimer.stop();
00128 #endif
00129 }
00130 
00131 
00132 ModExpFunctionalArgs::ModExpFunctionalArgs() :
00133    CODEX_ASN1::Base( false )
00134 {
00135 }
00136 
00137 ModExpFunctionalArgs::ModExpFunctionalArgs(
00138    const CODEX_ASN1::BigNumber& base,
00139    const CODEX_ASN1::BigNumber& modulus ) :
00140    CODEX_ASN1::Base( true ),
00141    m_base( base ),
00142    m_modulus( modulus )
00143 {
00144 }
00145 
00146 ModExpFunctionalArgs::ModExpFunctionalArgs(
00147    const ModExpFunctionalArgs& aOther ) :
00148    CODEX_ASN1::Base( aOther.m_initialized ),
00149    m_base( aOther.m_base ),
00150    m_modulus( aOther.m_modulus )
00151 {
00152 }
00153 
00154 ModExpFunctionalArgs::~ModExpFunctionalArgs()
00155 {
00156 }
00157 
00158 void
00159 ModExpFunctionalArgs::operator=( const ModExpFunctionalArgs& aOther )
00160 {
00161    m_initialized = aOther.m_initialized;
00162    m_base = aOther.m_base;
00163    m_modulus = aOther.m_modulus;
00164 }
00165 
00166 int
00167 ModExpFunctionalArgs::marshal( unsigned char ** pp ) const
00168 {
00169    if ( ! m_base.initialized() ) return 0;
00170    if ( ! m_modulus.initialized() ) return 0;
00171    int r=0;
00172    int ret=0;
00173    unsigned char * p;
00174 
00175    ret += m_base.marshal(0);
00176    ret += m_modulus.marshal(0);
00177    M_ASN1_I2D_seq_total();
00178    m_base.marshal(&p);
00179    m_modulus.marshal(&p);
00180    M_ASN1_I2D_finish();
00181 }
00182 
00183 void*
00184 ModExpFunctionalArgs::unmarshal( void* bogus,
00185                                  unsigned char** pp,
00186                                  long length )
00187 {
00188    if ( m_initialized )
00189    {
00190       return 0;
00191    }
00192    if ( (0 == pp) || (0 == *pp) )
00193    {
00194       return 0;
00195    }
00196 
00197    ASN1_CTX c;
00198    c.pp = pp;
00199    c.q = *pp;
00200    c.error = ERR_R_NESTED_ASN1_ERROR;
00201    int i;
00202 
00203    M_ASN1_D2I_Init();
00204    M_ASN1_D2I_start_sequence();
00205    M_ASN1_D2I_get(i, m_base.unmarshal);
00206    M_ASN1_D2I_get(i, m_modulus.unmarshal);
00207    if ( !asn1_Finish(&c) )
00208    {
00209       return 0;
00210    }
00211    *pp=c.p;
00212    m_initialized = true;
00213    return this;
00214   err: // needed by ASN.1 macros
00215    return 0;
00216 }

Generated on Fri May 6 17:40:51 2005 for COrnell Data EXchange (CODEX) by  doxygen 1.4.1