⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huge.cpp

📁 详细的AESRSASHA1实现原理
💻 CPP
字号:
// Huge.cpp: implementation of the CHuge class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Huge.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHuge::CHuge ( )
{
    m_iSize = MAX_HUGE_SIZE;
    Zero();
}

CHuge::~CHuge ( )
{
    
}

void CHuge::Zero ( )
{
    for ( int i = 0; i < m_iSize; i++ ) m_pValue[i] = 0;
    
    m_bSign  = 0;
    m_iSize  = 1;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
bool CHuge::CreateFromBytes ( BYTE pBytes[], int size )
{
    int  i, t;
    
    Zero( );
    t = size >> ELEM_BYTE_SIZE_LOG2;
    if ( size & ELEM_BYTE_SIZE_MASK ) t++;
    
    if ( t > MAX_HUGE_SIZE ) return false;
    if ( t == 0 ) return true;
    
    m_iSize = t;
    for ( i = 0; i < size; i++ )
    {
        int t0 = i >> ELEM_BYTE_SIZE_LOG2;
        int t1 = i &  ELEM_BYTE_SIZE_MASK;
        int t2 = t1 << 3;
        BYTE t3 = pBytes[i];
        m_pValue[t0] |= t3 << t2;
    }
    
    Tidy( );
    
    return true;
}

bool CHuge::TransToBytes ( BYTE pBytes[], int size )
{
    unsigned len, i, t0, t1, t2;
    
    if ( *this == 0 ) return true;
    
    len = (m_iSize-1) << ELEM_BYTE_SIZE_LOG2;
    for ( t0 = m_pValue[m_iSize-1]; t0; t0>>=8, len++ );
    if ( len > size ) return false;
    
    for ( i = 0; i < len; i++ )
    {
        t0 = i >> ELEM_BYTE_SIZE_LOG2;
        t1 = i & ELEM_BYTE_SIZE_MASK;
        t2 = (3-t1) << 3;

        pBytes[i] = (m_pValue[t0]<<t2) >> 24;
    }
    
    for ( i = len; i < size; i++ ) pBytes[i] = 0;
    
    return true;
}

//////////////////////////////////////////////////////////////////////
// Print
//////////////////////////////////////////////////////////////////////
void CHuge::Tidy ( )
{
    while ( (m_iSize > 0) && (m_pValue[m_iSize-1] == 0) ) --m_iSize;
    
    if ( m_iSize == 0 ) m_iSize = 1;
}

//////////////////////////////////////////////////////////////////////
// Get / Set
//////////////////////////////////////////////////////////////////////
bool CHuge::IsMinus ( )
{
    return m_bSign;
}

unsigned CHuge::GetBitLength ( )
{
    unsigned zeros = 0, t = 1<<ELEM_BIT_SIZE_MASK;
    
    while ( t && (m_pValue[m_iSize-1] & t) == 0 )
    {
        ++zeros;
        t >>= 1;
    }
    
    return (m_iSize<<ELEM_BIT_SIZE_LOG2)-zeros;
}

void CHuge::SetBit ( unsigned pos, bool flag )
{
    if ( flag )
        m_pValue[pos>>ELEM_BIT_SIZE_LOG2] |= ( 1 << (pos&ELEM_BIT_SIZE_MASK) );
    else
        m_pValue[pos>>ELEM_BIT_SIZE_LOG2] &= ~( 1 << (pos&ELEM_BIT_SIZE_MASK) );
}

bool CHuge::GetBit ( unsigned pos )
{
    if ( m_pValue[pos>>ELEM_BIT_SIZE_LOG2] & ( 1 << (pos&ELEM_BIT_SIZE_MASK) ) )
        return true;
    
    return false;
}

unsigned CHuge::CountLastZeros ( )
{
    int i, cnt, t;
    if( *this == 0 )  return 1;
    
    for ( i = 0; (i < m_iSize) && (m_pValue[i] == 0); i++ );
    cnt = i*ELEM_BIT_SIZE;
    
    t = m_pValue[i];
    while( (t&1) == 0 )
    {
        ++cnt;
        t >>= 1;
    }
    
    return cnt;
}

//////////////////////////////////////////////////////////////////////
// evaluate 
//////////////////////////////////////////////////////////////////////
void CHuge::operator = ( const int n )
{
    Zero();
    
    if( n>=0 )
    {
        m_pValue[0] = n;
    }
    else
    {
        m_pValue[0] = -n;
        m_bSign = 1;
    }
}

void CHuge::operator = ( const CHuge n )
{
    Zero();
    m_iSize = n.m_iSize;
    m_bSign = n.m_bSign;
    
    for ( int i = 0; i < m_iSize; i++ )
        m_pValue[i] = n.m_pValue[i];
}

//////////////////////////////////////////////////////////////////////
// Subscript
//////////////////////////////////////////////////////////////////////
unsigned& CHuge::operator [] ( const int index )
{
    return m_pValue[index];
}

unsigned CHuge::operator [] ( const int index )const
{
    return m_pValue[index];
}

//////////////////////////////////////////////////////////////////////
// Compare
//////////////////////////////////////////////////////////////////////
bool operator <	( CHuge& a, CHuge& b )
{
    return (Compare( a, b ) == -1);
}

bool operator >= ( CHuge& a, CHuge& b )
{ 
    return !(Compare( a, b ) == -1);
}

bool operator >	( CHuge& a, CHuge& b )
{  
    return (Compare( a, b ) == 1);
}

bool operator <= ( CHuge& a, CHuge& b )
{ 
    return !(Compare( a, b ) == 1);
}

bool operator == ( CHuge& a, CHuge& b )
{
    return (Compare( a, b ) == 0);
}

bool operator != ( CHuge& a, CHuge& b )
{
    return !(Compare( a, b ) == 0);
}

bool operator == ( CHuge& a, int n )
{
    if ( a.m_iSize != 1 )   return false;
    
    bool sign = 0;
    if ( n < 0 )
    {
        sign = 1; 
        n   = -n;
    }
    if ( sign != a.m_bSign )    return false;
    if ( a.m_pValue[0] != n )   return false;
    
    return true;
}

bool operator != ( CHuge& a, int n )
{
    if ( a.m_iSize != 1 )   return true;
    
    bool sign = 0;
    if ( n < 0 )
    {
        sign = 1; 
        n   = -n;
    }
    if ( sign != a.m_bSign )    return false;
    if ( a.m_pValue[0] == n )   return false;
    
    return true;
}

//////////////////////////////////////////////////////////////////////
// Algorithm
//////////////////////////////////////////////////////////////////////
CHuge operator << ( CHuge& n, unsigned shift )
{
    CHuge	    res;
    unsigned    t, lsh, rsh, left, right;
    int         i;
    
    t	= shift >> ELEM_BIT_SIZE_LOG2;
    lsh	= shift &  ELEM_BIT_SIZE_MASK;
    rsh = ELEM_BIT_SIZE - lsh;
    
    res.m_iSize = n.m_iSize+t;
    if ( res.m_iSize > MAX_HUGE_SIZE ) { res = 0; return res; } 
    
    if ( lsh == 0 )
    {
        for ( i = t; i < res.m_iSize; i++ )
            res[i]  = n[i-t];
    }
    else
    {
        right = 0;
        for ( i = t; i < res.m_iSize; i++ )
        {
            left	= n[i-t] << lsh;
            res[i]  = left | right;
            right	= n[i-t] >> rsh;
        }
        if ( right )
        {
            res[res.m_iSize]	= right;
            ++res.m_iSize;
        }
    }
    
    return res;
}

CHuge operator >> ( CHuge& n, unsigned shift )
{
    CHuge	    res;
    unsigned    t, lsh, rsh, left, right, mask;
    int         i;
    
    t	= shift >> ELEM_BIT_SIZE_LOG2;
    rsh	= shift &  ELEM_BIT_SIZE_MASK;
    lsh = ELEM_BIT_SIZE - rsh;
    
    res.m_iSize = n.m_iSize-t;
    
    if ( rsh == 0 )
    {
        for ( i = res.m_iSize-1; i >= 0; i-- )
            res[i]  = n[i+t];
    }
    else
    {
        left = 0;
        mask = (1<<rsh)-1;
        for ( i = res.m_iSize-1; i >= 0; i-- )
        {
            right   = n[i+t] >> rsh;
            res[i]  = left | right;
            left    = (n[i+t] & mask) << lsh;
        }
        
        res.Tidy( );
    }
    
    return res;
}

CHuge operator - ( CHuge& n )
{
    CHuge res;
    
    res = n;
    res.m_bSign = !n.m_bSign;
    
    return res;
}

CHuge operator + ( CHuge& a, CHuge& b )
{
    CHuge	res;
    
    if ( a.m_bSign == b.m_bSign )
    {
        res = AbsAdd( a, b );
        res.m_bSign = a.m_bSign;
    }
    else
    {
        int abscmp = AbsCompare( a, b );
        
        if ( abscmp == 1 )
        {
            res = AbsSub( a, b );
            res.m_bSign = a.m_bSign;
        }
        else if ( abscmp == -1 )
        {
            res = AbsSub( b, a );
            res.m_bSign = b.m_bSign;
        }
        else
        {
            res = 0;
        }
    }
    
    return res;
}

CHuge operator - ( CHuge& a, CHuge& b )
{
    return a+(-b);
}

CHuge operator * ( CHuge& a, CHuge& b )
{
    CHuge	            res;
    unsigned __int64    t;
    int		            i, j, pos;
    
    if ( a.m_iSize+b.m_iSize-1 > MAX_HUGE_SIZE ) return res;
    if ( (a == 0) || (b == 0) ) return res;
    
    for ( i = 0; i < a.m_iSize; i++ )
    {
        for ( j = 0; j < b.m_iSize; j++ )
        {
            t = (unsigned __int64)a[i]*(unsigned __int64)b[j];
            pos = i+j;
            
            do
            {
                t += res[pos];
                res[pos] = (unsigned)t;
                t >>= ELEM_BIT_SIZE;
                pos++;
            }
            while ( t );
        }
    }
    
    if ( res[pos] )
        res.m_iSize = pos+1;
    else
        res.m_iSize = pos;
    
    if ( a.m_bSign == b.m_bSign )
        res.m_bSign = 0;
    else
        res.m_bSign = 1;
    
    res.Tidy( );
    
    return res;  
}

CHuge operator / ( CHuge& a, CHuge& b )
{
    ASSERT( b != 0 );
    CHuge res, rem;
    
    Divide( a, b, res, rem );
    
    return res;
}

CHuge operator % ( CHuge& a, CHuge& b )
{
    CHuge res, rem;
    
    Divide( a, b, res, rem );
    
    return rem;
}


CHuge operator - ( CHuge& a, int n )
{
    CHuge res;
    
    res = n;
    res = a - res;
    
    return res;
}

//////////////////////////////////////////////////////////////////////
// Assistant
//////////////////////////////////////////////////////////////////////
int	AbsCompare ( CHuge& a, CHuge& b )
{
    if ( a.m_iSize > b.m_iSize )
        return 1;
    if ( a.m_iSize < b.m_iSize )
        return -1;
    
    int i = a.m_iSize-1;
    while ( (i >= 0) && (a[i] == b[i]) ) i--;
    
    if ( i<0 ) return 0;  
    if ( a[i] > b[i] ) return 1;
    
    return -1;
}

int Compare ( CHuge& a, CHuge& b )
{
    if ( a.m_bSign != b.m_bSign )
    {
        if ( a.m_bSign == 0 )
            return 1;
        else
            return -1;
    }
    else
    {
        int abscmp = AbsCompare( a, b );
        
        if ( abscmp>0 )
        {
            if ( a.m_bSign == 0 )
                return 1;
            else
                return -1;
        }
        else if ( abscmp < 0 )
        {
            if ( a.m_bSign == 1 )
                return 1;
            else
                return -1;
        }
        else
        {
            return 0;
        }
    }
}

CHuge AbsAdd ( CHuge& a, CHuge& b)
{
    CHuge res;
    
    res.m_iSize = (a.m_iSize > b.m_iSize) ? a.m_iSize:b.m_iSize;
    
    bool carry  = 0;
    for ( int i = 0; i < res.m_iSize; i++ )
    {
        res[i]  = a[i] + b[i] + carry;
        carry   = (res[i] < a[i]);
    }
    
    if ( carry )
    {
        res[res.m_iSize] = 1;
        res.m_iSize ++;
    }
    
    return res;
}

CHuge AbsSub ( CHuge& a, CHuge& b)
{
    CHuge res;
    
    res.m_iSize  = a.m_iSize;
    
    bool loan = 0;
    for ( int i = 0; i < res.m_iSize; i++ )
    {
        if ( a[i] > b[i] )
        {
            res[i] = a[i] - b[i] - loan;
            loan   = 0;
        }
        else if ( a[i] < b[i] )
        {
            res[i] = ELEM_MAX_VALUE - b[i] + a[i] - loan + 1;
            loan = 1;
        }
        else
        {
            if ( loan == 0 )
                res[i] = 0;
            else
                res[i] = ELEM_MAX_VALUE;
        }
    }
    
    res.Tidy();
    
    return res;
}

void Divide ( CHuge& a, CHuge& b, CHuge& res, CHuge& rem )
{
    CHuge   tb, t;
    int     pos, shift;
    
    if ( a.m_bSign == 1 ) rem = -a;  else rem = a;
    if ( b.m_bSign == 1 ) tb = -b;   else tb = b;
    
    if ( rem < tb )
    {
        res = 0;
        rem = a;
        return;
    }
    
    pos = rem.GetBitLength( ) - tb.GetBitLength( );
    t   = tb << pos;
    res.m_iSize  = (pos >> ELEM_BIT_SIZE_LOG2) + 1;
    
    while ( (pos >= 0) && (rem >= tb) )
    {
        if( rem >= t )
        {
            res.SetBit( pos );
            rem = rem - t;
            rem.Tidy();
        }
        shift = t.GetBitLength( ) - rem.GetBitLength( );
        if ( shift==0 ) shift = 1;
        t     = t >> shift;
        pos  -= shift;
    }
    
    if ( a.m_bSign == b.m_bSign )
        res.m_bSign = 0;
    else
        res.m_bSign = 1;
    
    rem.m_bSign = a.m_bSign;
    
    res.Tidy( );
}

//////////////////////////////////////////////////////////////////////
// Create Random Prime
//////////////////////////////////////////////////////////////////////
bool CreateRandomHuge ( CHuge& n, const unsigned bits )
{
    n.Zero( );
    
    if ( bits == 0 ) return true;
    if ( bits > (MAX_HUGE_SIZE << ELEM_BIT_SIZE_LOG2) ) return false;
    
    n.m_iSize  = bits >> ELEM_BIT_SIZE_LOG2;
    if ( bits &  ELEM_BIT_SIZE_MASK ) n.m_iSize++;
    
    for ( int i = n.m_iSize-1; i >= 0; i-- )
        n[i] = (rand()<<16) | (rand());
    
    int t = bits &  ELEM_BIT_SIZE_MASK;
    if ( t ) n[n.m_iSize-1] &= ( (1<<t)-1 );
    n[n.m_iSize-1] |= ( 1<<(t-1) );
    
    return true;
}

bool CreateRandomHugePrime ( CHuge& n, const unsigned bits )
{
    int len = bits >> ELEM_BIT_SIZE_LOG2;
    if ( bits&ELEM_BIT_SIZE_MASK ) len++;
    if ( len >= (MAX_HUGE_SIZE>>1) ) return false;

    do 
    {
        CreateRandomHuge( n, bits );
        n[0] |= 1;
    }
    while( !IsPrime( n ) );
    
    return true;
}

bool IsPrime ( CHuge& n )
{
    CHuge	    t;
    unsigned    i, shift;
    
    t = n - 1;
    shift = t.CountLastZeros( );
    t = t >> shift;
    
    for ( i = 0; i < MB_TEST_TIMES; i++ )
        if ( !Miller_Rabin( n, t, shift ) ) return false;
        
    return true;
}

bool Miller_Rabin( CHuge& n, CHuge& t, const unsigned pos )
{
    int		i;
    CHuge	a, q;
    
    q = n - 1;
    do
    {
        CreateRandomHuge( a, 2 + rand() % (n.m_iSize<<3) );
    }
    while ( (a >= n) || (a == 0) || (a == 1) );
    
    a = PowerMod( a, t, n );
    if ( a == 1 )   return true;
    
    for ( i=0; i<pos; i++ )
    {
        if ( a == q ) return true;
        a = (a*a) % n;
    }
    
    return false;
}

CHuge PowerMod( CHuge& base, CHuge& exp, CHuge& div )
{
    CHuge   rem, t0, t1;
    
    rem = 1;
    t0  = exp;
    t1	= base % div;
    
    while( t0 != 0 )
    {
        if( t0[0] & 1 )
            rem = (rem * t1) % div; // should promise the max_len is large enough, so that
                                    // make sure there is enough memory to store the product
        t1 = (t1 * t1) % div;
        t0 = t0 >> 1;
    }
    
    return rem;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -