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

📄 bignum.c

📁 一个用纯C写的RSA_SHA1数字签名库
💻 C
📖 第 1 页 / 共 3 页
字号:
    *p  = ( z < 0 ) ? -z : z;    Y.s = ( z < 0 ) ? -1 : 1;    Y.n = 1;    Y.p = p;    return( mpi_cmp_mpi( X, &Y ) );}/* * Unsigned addition: X = |A| + |B|  (HAC 14.7) */int mpi_add_abs( mpi *X, mpi *A, mpi *B ){    int ret, i, j;    t_int *o, *p, c;    if( X == B )    {        mpi *T = A; A = X; B = T;    }    if( X != A )        MPI_CHK( mpi_copy( X, A ) );    for( j = B->n - 1; j >= 0; j-- )        if( B->p[j] != 0 )            break;    MPI_CHK( mpi_grow( X, j + 1 ) );    o = B->p; p = X->p; c = 0;    for( i = 0; i <= j; i++, o++, p++ )    {        *p +=  c; c  = ( *p <  c );        *p += *o; c += ( *p < *o );    }    while( c != 0 )    {        if( i >= X->n )        {            MPI_CHK( mpi_grow( X, i + 1 ) );            p = X->p + i;        }        *p += c; c = ( *p < c ); i++;    }cleanup:    return( ret );}/* * Helper for mpi substraction */static void mpi_sub_hlp( int n, t_int *s, t_int *d ){    int i;    t_int c, z;    for( i = c = 0; i < n; i++, s++, d++ )    {        z = ( *d <  c );     *d -=  c;        c = ( *d < *s ) + z; *d -= *s;    }    while( c != 0 )    {        z = ( *d < c ); *d -= c;        c = z; i++; d++;    }}/* * Unsigned substraction: X = |A| - |B|  (HAC 14.9) */int mpi_sub_abs( mpi *X, mpi *A, mpi *B ){    mpi TB;    int ret, n;    if( mpi_cmp_abs( A, B ) < 0 )        return( XYSSL_ERR_MPI_NEGATIVE_VALUE );    mpi_init( &TB, NULL );    if( X == B )    {        MPI_CHK( mpi_copy( &TB, B ) );        B = &TB;    }    if( X != A )        MPI_CHK( mpi_copy( X, A ) );    ret = 0;    for( n = B->n - 1; n >= 0; n-- )        if( B->p[n] != 0 )            break;    mpi_sub_hlp( n + 1, B->p, X->p );cleanup:    mpi_free( &TB, NULL );    return( ret );}/* * Signed addition: X = A + B */int mpi_add_mpi( mpi *X, mpi *A, mpi *B ){    int ret, s = A->s;    if( A->s * B->s < 0 )    {        if( mpi_cmp_abs( A, B ) >= 0 )        {            MPI_CHK( mpi_sub_abs( X, A, B ) );            X->s =  s;        }        else        {            MPI_CHK( mpi_sub_abs( X, B, A ) );            X->s = -s;        }    }    else    {        MPI_CHK( mpi_add_abs( X, A, B ) );        X->s = s;    }cleanup:    return( ret );}/* * Signed substraction: X = A - B */int mpi_sub_mpi( mpi *X, mpi *A, mpi *B ){    int ret, s = A->s;    if( A->s * B->s > 0 )    {        if( mpi_cmp_abs( A, B ) >= 0 )        {            MPI_CHK( mpi_sub_abs( X, A, B ) );            X->s =  s;        }        else        {            MPI_CHK( mpi_sub_abs( X, B, A ) );            X->s = -s;        }    }    else    {        MPI_CHK( mpi_add_abs( X, A, B ) );        X->s = s;    }cleanup:    return( ret );}/* * Signed addition: X = A + b */int mpi_add_int( mpi *X, mpi *A, int b ){    mpi _B;    t_int p[1];    p[0] = ( b < 0 ) ? -b : b;    _B.s = ( b < 0 ) ? -1 : 1;    _B.n = 1;    _B.p = p;    return( mpi_add_mpi( X, A, &_B ) );}/* * Signed substraction: X = A - b */int mpi_sub_int( mpi *X, mpi *A, int b ){    mpi _B;    t_int p[1];    p[0] = ( b < 0 ) ? -b : b;    _B.s = ( b < 0 ) ? -1 : 1;    _B.n = 1;    _B.p = p;    return( mpi_sub_mpi( X, A, &_B ) );}/* * Helper for mpi multiplication */ static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b ){    t_int c = 0, t = 0;#if defined(MULADDC_HUIT)    for( ; i >= 8; i -= 8 )    {        MULADDC_INIT        MULADDC_HUIT        MULADDC_STOP    }    for( ; i > 0; i-- )    {        MULADDC_INIT        MULADDC_CORE        MULADDC_STOP    }#else    for( ; i >= 16; i -= 16 )    {        MULADDC_INIT        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_STOP    }    for( ; i >= 8; i -= 8 )    {        MULADDC_INIT        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_CORE   MULADDC_CORE        MULADDC_STOP    }    for( ; i > 0; i-- )    {        MULADDC_INIT        MULADDC_CORE        MULADDC_STOP    }#endif    t++;    do {        *d += c; c = ( *d < c ); d++;    }    while( c != 0 );}/* * Baseline multiplication: X = A * B  (HAC 14.12) */int mpi_mul_mpi( mpi *X, mpi *A, mpi *B ){    int ret, i, j;    mpi TA, TB;    mpi_init( &TA, &TB, NULL );    if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }    if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }    for( i = A->n - 1; i >= 0; i-- )        if( A->p[i] != 0 )            break;    for( j = B->n - 1; j >= 0; j-- )        if( B->p[j] != 0 )            break;    MPI_CHK( mpi_grow( X, i + j + 2 ) );    MPI_CHK( mpi_lset( X, 0 ) );    for( i++; j >= 0; j-- )        mpi_mul_hlp( i, A->p, X->p + j, B->p[j] );    X->s = A->s * B->s;cleanup:    mpi_free( &TB, &TA, NULL );    return( ret );}/* * Baseline multiplication: X = A * b */int mpi_mul_int( mpi *X, mpi *A, t_int b ){    mpi _B;    t_int p[1];    _B.s = 1;    _B.n = 1;    _B.p = p;    p[0] = b;    return( mpi_mul_mpi( X, A, &_B ) );}/* * Division by mpi: A = Q * B + R  (HAC 14.20) */int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B ){    int ret, i, n, t, k;    mpi X, Y, Z, T1, T2;    if( mpi_cmp_int( B, 0 ) == 0 )        return( XYSSL_ERR_MPI_DIVISION_BY_ZERO );    mpi_init( &X, &Y, &Z, &T1, &T2, NULL );    if( mpi_cmp_abs( A, B ) < 0 )    {        if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );        if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );        return( 0 );    }    MPI_CHK( mpi_copy( &X, A ) );    MPI_CHK( mpi_copy( &Y, B ) );    X.s = Y.s = 1;    MPI_CHK( mpi_grow( &Z, A->n + 2 ) );    MPI_CHK( mpi_lset( &Z,  0 ) );    MPI_CHK( mpi_grow( &T1, 2 ) );    MPI_CHK( mpi_grow( &T2, 3 ) );    k = mpi_msb( &Y ) % biL;    if( k < (int) biL - 1 )    {        k = biL - 1 - k;        MPI_CHK( mpi_shift_l( &X, k ) );        MPI_CHK( mpi_shift_l( &Y, k ) );    }    else k = 0;    n = X.n - 1;    t = Y.n - 1;    mpi_shift_l( &Y, biL * (n - t) );    while( mpi_cmp_mpi( &X, &Y ) >= 0 )    {        Z.p[n - t]++;        mpi_sub_mpi( &X, &X, &Y );    }    mpi_shift_r( &Y, biL * (n - t) );    for( i = n; i > t ; i-- )    {        if( X.p[i] >= Y.p[t] )            Z.p[i - t - 1] = ~0;        else        {#if defined(XYSSL_HAVE_LONGLONG)            t_dbl r;            r  = (t_dbl) X.p[i] << biL;            r |= (t_dbl) X.p[i - 1];            r /= Y.p[t];            if( r > ((t_dbl) 1 << biL) - 1)                r = ((t_dbl) 1 << biL) - 1;            Z.p[i - t - 1] = (t_int) r;#else            /*             * __udiv_qrnnd_c, from gmp/longlong.h             */            t_int q0, q1, r0, r1;            t_int d0, d1, d, m;            d  = Y.p[t];            d0 = ( d << biH ) >> biH;            d1 = ( d >> biH );            q1 = X.p[i] / d1;            r1 = X.p[i] - d1 * q1;            r1 <<= biH;            r1 |= ( X.p[i - 1] >> biH );            m = q1 * d0;            if( r1 < m )            {                q1--, r1 += d;                while( r1 >= d && r1 < m )                    q1--, r1 += d;            }            r1 -= m;            q0 = r1 / d1;            r0 = r1 - d1 * q0;            r0 <<= biH;            r0 |= ( X.p[i - 1] << biH ) >> biH;            m = q0 * d0;            if( r0 < m )            {                q0--, r0 += d;                while( r0 >= d && r0 < m )                    q0--, r0 += d;            }            r0 -= m;            Z.p[i - t - 1] = ( q1 << biH ) | q0;#endif        }        Z.p[i - t - 1]++;        do        {            Z.p[i - t - 1]--;            MPI_CHK( mpi_lset( &T1, 0 ) );            T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];            T1.p[1] = Y.p[t];            MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );            MPI_CHK( mpi_lset( &T2, 0 ) );            T2.p[0] = (i < 2) ? 0 : X.p[i - 2];            T2.p[1] = (i < 1) ? 0 : X.p[i - 1];            T2.p[2] = X.p[i];        }        while( mpi_cmp_mpi( &T1, &T2 ) > 0 );        MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );        MPI_CHK( mpi_shift_l( &T1,  biL * (i - t - 1) ) );        MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );        if( mpi_cmp_int( &X, 0 ) < 0 )        {            MPI_CHK( mpi_copy( &T1, &Y ) );            MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );            MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );            Z.p[i - t - 1]--;        }    }    if( Q != NULL )    {        mpi_copy( Q, &Z );        Q->s = A->s * B->s;    }    if( R != NULL )    {        mpi_shift_r( &X, k );        mpi_copy( R, &X );        R->s = A->s;        if( mpi_cmp_int( R, 0 ) == 0 )            R->s = 1;    }cleanup:    mpi_free( &X, &Y, &Z, &T1, &T2, NULL );    return( ret );}/* * Division by int: A = Q * b + R * * Returns 0 if successful *         1 if memory allocation failed *         XYSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 */int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b ){    mpi _B;    t_int p[1];    p[0] = ( b < 0 ) ? -b : b;    _B.s = ( b < 0 ) ? -1 : 1;    _B.n = 1;    _B.p = p;    return( mpi_div_mpi( Q, R, A, &_B ) );}/* * Modulo: R = A mod B */int mpi_mod_mpi( mpi *R, mpi *A, mpi *B ){    int ret;    MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );    while( mpi_cmp_int( R, 0 ) < 0 )      MPI_CHK( mpi_add_mpi( R, R, B ) );    while( mpi_cmp_mpi( R, B ) >= 0 )      MPI_CHK( mpi_sub_mpi( R, R, B ) );cleanup:    return( ret );}/* * Modulo: r = A mod b */int mpi_mod_int( t_int *r, mpi *A, int b ){    int i;    t_int x, y, z;    if( b == 0 )        return( XYSSL_ERR_MPI_DIVISION_BY_ZERO );    if( b < 0 )        b = -b;    /*     * handle trivial cases     */    if( b == 1 )    {        *r = 0;        return( 0 );    }    if( b == 2 )    {        *r = A->p[0] & 1;        return( 0 );    }    /*     * general case     */    for( i = A->n - 1, y = 0; i >= 0; i-- )    {        x  = A->p[i];        y  = ( y << biH ) | ( x >> biH );        z  = y / b;        y -= z * b;        x <<= biH;        y  = ( y << biH ) | ( x >> biH );        z  = y / b;        y -= z * b;    }    *r = y;    return( 0 );}/* * Fast Montgomery initialization (thanks to Tom St Denis) */static void mpi_montg_init( t_int *mm, mpi *N ){    t_int x, m0 = N->p[0];    x  = m0;    x += ( ( m0 + 2 ) & 4 ) << 1;    x *= ( 2 - ( m0 * x ) );    if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );    if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );    if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );    *mm = ~x + 1;}/* * Montgomery multiplication: A = A * B * R^-1 mod N  (HAC 14.36) */static void mpi_montmul( mpi *A, mpi *B, mpi *N, t_int mm, mpi *T ){    int i, n, m;    t_int u0, u1, *d;    memset( T->p, 0, T->n * ciL );    d = T->p;    n = N->n;    m = ( B->n < n ) ? B->n : n;    for( i = 0; i < n; i++ )    {        /*         * T = (T + u0*B + u1*N) / 2^biL         */        u0 = A->p[i];        u1 = ( d[0] + u0 * B->p[0] ) * mm;        mpi_mul_hlp( m, B->p, d, u0 );        mpi_mul_hlp( n, N->p, d, u1 );        *d++ = u0; d[n + 1] = 0;    }    memcpy( A->p, d, (n + 1) * ciL );    if( mpi_cmp_abs( A, N ) >= 0 )        mpi_sub_hlp( n, N->p, A->p );    else        /* prevent timing attacks */        mpi_sub_hlp( n, A->p, T->p );}/* * Montgomery reduction: A = A * R^-1 mod N */static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T ){    t_int z = 1;    mpi U;    U.n = U.s = z;    U.p = &z;    mpi_montmul( A, &U, N, mm, T );}/* * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85) */int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR ){    int ret, i, j, wsize, wbits;    int bufsize, nblimbs, nbits;    t_int ei, mm, state;    mpi RR, T, W[64];

⌨️ 快捷键说明

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