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

📄 bignum.c

📁 一个用纯C写的RSA_SHA1数字签名库
💻 C
📖 第 1 页 / 共 3 页
字号:
    if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )        return( XYSSL_ERR_MPI_BAD_INPUT_DATA );    /*     * Init temps and window size     */    mpi_montg_init( &mm, N );    mpi_init( &RR, &T, NULL );    memset( W, 0, sizeof( W ) );    i = mpi_msb( E );    wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :            ( i >  79 ) ? 4 : ( i >  23 ) ? 3 : 1;    j = N->n + 1;    MPI_CHK( mpi_grow( X, j ) );    MPI_CHK( mpi_grow( &W[1],  j ) );    MPI_CHK( mpi_grow( &T, j * 2 ) );    /*     * If 1st call, pre-compute R^2 mod N     */    if( _RR == NULL || _RR->p == NULL )    {        MPI_CHK( mpi_lset( &RR, 1 ) );        MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );        MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );        if( _RR != NULL )            memcpy( _RR, &RR, sizeof( mpi ) );    }    else        memcpy( &RR, _RR, sizeof( mpi ) );    /*     * W[1] = A * R^2 * R^-1 mod N = A * R mod N     */    if( mpi_cmp_mpi( A, N ) >= 0 )        mpi_mod_mpi( &W[1], A, N );    else   mpi_copy( &W[1], A );    mpi_montmul( &W[1], &RR, N, mm, &T );    /*     * X = R^2 * R^-1 mod N = R mod N     */    MPI_CHK( mpi_copy( X, &RR ) );    mpi_montred( X, N, mm, &T );    if( wsize > 1 )    {        /*         * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)         */        j =  1 << (wsize - 1);        MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );        MPI_CHK( mpi_copy( &W[j], &W[1]    ) );        for( i = 0; i < wsize - 1; i++ )            mpi_montmul( &W[j], &W[j], N, mm, &T );            /*         * W[i] = W[i - 1] * W[1]         */        for( i = j + 1; i < (1 << wsize); i++ )        {            MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );            MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );            mpi_montmul( &W[i], &W[1], N, mm, &T );        }    }    nblimbs = E->n;    bufsize = 0;    nbits   = 0;    wbits   = 0;    state   = 0;    while( 1 )    {        if( bufsize == 0 )        {            if( nblimbs-- == 0 )                break;            bufsize = sizeof( t_int ) << 3;        }        bufsize--;        ei = (E->p[nblimbs] >> bufsize) & 1;        /*         * skip leading 0s         */        if( ei == 0 && state == 0 )            continue;        if( ei == 0 && state == 1 )        {            /*             * out of window, square X             */            mpi_montmul( X, X, N, mm, &T );            continue;        }        /*         * add ei to current window         */        state = 2;        nbits++;        wbits |= (ei << (wsize - nbits));        if( nbits == wsize )        {            /*             * X = X^wsize R^-1 mod N             */            for( i = 0; i < wsize; i++ )                mpi_montmul( X, X, N, mm, &T );            /*             * X = X * W[wbits] R^-1 mod N             */            mpi_montmul( X, &W[wbits], N, mm, &T );            state--;            nbits = 0;            wbits = 0;        }    }    /*     * process the remaining bits     */    for( i = 0; i < nbits; i++ )    {        mpi_montmul( X, X, N, mm, &T );        wbits <<= 1;        if( (wbits & (1 << wsize)) != 0 )            mpi_montmul( X, &W[1], N, mm, &T );    }    /*     * X = A^E * R * R^-1 mod N = A^E mod N     */    mpi_montred( X, N, mm, &T );cleanup:    for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ )        mpi_free( &W[i], NULL );    if( _RR != NULL )         mpi_free( &W[1], &T, NULL );    else mpi_free( &W[1], &T, &RR, NULL );    return( ret );}#if defined(XYSSL_GENPRIME)/* * Greatest common divisor: G = gcd(A, B)  (HAC 14.54) */int mpi_gcd( mpi *G, mpi *A, mpi *B ){    int ret;    mpi TG, TA, TB;    mpi_init( &TG, &TA, &TB, NULL );    MPI_CHK( mpi_lset( &TG, 1 ) );    MPI_CHK( mpi_copy( &TA, A ) );    MPI_CHK( mpi_copy( &TB, B ) );    TA.s = TB.s = 1;    while( mpi_cmp_int( &TA, 0 ) != 0 )    {        while( ( TA.p[0] & 1 ) == 0 ) MPI_CHK( mpi_shift_r( &TA, 1 ) );        while( ( TB.p[0] & 1 ) == 0 ) MPI_CHK( mpi_shift_r( &TB, 1 ) );        if( mpi_cmp_mpi( &TA, &TB ) >= 0 )        {            MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );            MPI_CHK( mpi_shift_r( &TA, 1 ) );        }        else        {            MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );            MPI_CHK( mpi_shift_r( &TB, 1 ) );        }    }    MPI_CHK( mpi_mul_mpi( G, &TG, &TB ) );cleanup:    mpi_free( &TB, &TA, &TG, NULL );    return( ret );}/* * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64) */int mpi_inv_mod( mpi *X, mpi *A, mpi *N ){    int ret;    mpi G, TA, TU, U1, U2, TB, TV, V1, V2;    if( mpi_cmp_int( N, 0 ) <= 0 )        return( XYSSL_ERR_MPI_BAD_INPUT_DATA );    mpi_init( &TA, &TU, &U1, &U2, &G,              &TB, &TV, &V1, &V2, NULL );    MPI_CHK( mpi_gcd( &G, A, N ) );    if( mpi_cmp_int( &G, 1 ) != 0 )    {        ret = XYSSL_ERR_MPI_NOT_ACCEPTABLE;        goto cleanup;    }    MPI_CHK( mpi_mod_mpi( &TA, A, N ) );    MPI_CHK( mpi_copy( &TU, &TA ) );    MPI_CHK( mpi_copy( &TB, N ) );    MPI_CHK( mpi_copy( &TV, N ) );    MPI_CHK( mpi_lset( &U1, 1 ) );    MPI_CHK( mpi_lset( &U2, 0 ) );    MPI_CHK( mpi_lset( &V1, 0 ) );    MPI_CHK( mpi_lset( &V2, 1 ) );    do    {        while( ( TU.p[0] & 1 ) == 0 )        {            MPI_CHK( mpi_shift_r( &TU, 1 ) );            if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )            {                MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );                MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );            }            MPI_CHK( mpi_shift_r( &U1, 1 ) );            MPI_CHK( mpi_shift_r( &U2, 1 ) );        }        while( ( TV.p[0] & 1 ) == 0 )        {            MPI_CHK( mpi_shift_r( &TV, 1 ) );            if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )            {                MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );                MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );            }            MPI_CHK( mpi_shift_r( &V1, 1 ) );            MPI_CHK( mpi_shift_r( &V2, 1 ) );        }        if( mpi_cmp_mpi( &TU, &TV ) >= 0 )        {            MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );            MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );            MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );        }        else        {            MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );            MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );            MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );        }    }    while( mpi_cmp_int( &TU, 0 ) != 0 );    while( mpi_cmp_int( &V1, 0 ) < 0 )        MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );    while( mpi_cmp_mpi( &V1, N ) >= 0 )        MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );    MPI_CHK( mpi_copy( X, &V1 ) );cleanup:    mpi_free( &V2, &V1, &TV, &TB, &G,              &U2, &U1, &TU, &TA, NULL );    return( ret );}static const int small_prime[] ={        3,    5,    7,   11,   13,   17,   19,   23,       29,   31,   37,   41,   43,   47,   53,   59,       61,   67,   71,   73,   79,   83,   89,   97,      101,  103,  107,  109,  113,  127,  131,  137,      139,  149,  151,  157,  163,  167,  173,  179,      181,  191,  193,  197,  199,  211,  223,  227,      229,  233,  239,  241,  251,  257,  263,  269,      271,  277,  281,  283,  293,  307,  311,  313,      317,  331,  337,  347,  349,  353,  359,  367,      373,  379,  383,  389,  397,  401,  409,  419,      421,  431,  433,  439,  443,  449,  457,  461,      463,  467,  479,  487,  491,  499,  503,  509,      521,  523,  541,  547,  557,  563,  569,  571,      577,  587,  593,  599,  601,  607,  613,  617,      619,  631,  641,  643,  647,  653,  659,  661,      673,  677,  683,  691,  701,  709,  719,  727,      733,  739,  743,  751,  757,  761,  769,  773,      787,  797,  809,  811,  821,  823,  827,  829,      839,  853,  857,  859,  863,  877,  881,  883,      887,  907,  911,  919,  929,  937,  941,  947,      953,  967,  971,  977,  983,  991,  997, -103};/* * Miller-Rabin primality test  (HAC 4.24) */int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ){    int ret, i, j, n, s, xs;    mpi W, R, T, A, RR;    unsigned char *p;    if( mpi_cmp_int( X, 0 ) == 0 )        return( 0 );    mpi_init( &W, &R, &T, &A, &RR, NULL );    xs = X->s; X->s = 1;    /*     * test trivial factors first     */    if( ( X->p[0] & 1 ) == 0 )        return( XYSSL_ERR_MPI_NOT_ACCEPTABLE );    for( i = 0; small_prime[i] > 0; i++ )    {        t_int r;        if( mpi_cmp_int( X, small_prime[i] ) <= 0 )            return( 0 );        MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );        if( r == 0 )            return( XYSSL_ERR_MPI_NOT_ACCEPTABLE );    }    /*     * W = |X| - 1     * R = W >> lsb( W )     */    s = mpi_lsb( &W );    MPI_CHK( mpi_sub_int( &W, X, 1 ) );    MPI_CHK( mpi_copy( &R, &W ) );    MPI_CHK( mpi_shift_r( &R, s ) );    i = mpi_msb( X );    /*     * HAC, table 4.4     */    n = ( ( i >= 1300 ) ?  2 : ( i >=  850 ) ?  3 :          ( i >=  650 ) ?  4 : ( i >=  350 ) ?  8 :          ( i >=  250 ) ? 12 : ( i >=  150 ) ? 18 : 27 );    for( i = 0; i < n; i++ )    {        /*         * pick a random A, 1 < A < |X| - 1         */        MPI_CHK( mpi_grow( &A, X->n ) );        p = (unsigned char *) A.p;        for( j = 0; j < A.n * ciL; j++ )            *p++ = (unsigned char) f_rng( p_rng );        j = mpi_msb( &A ) - mpi_msb( &W );        MPI_CHK( mpi_shift_r( &A, j + 1 ) );        A.p[0] |= 3;        /*         * A = A^R mod |X|         */        MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );        if( mpi_cmp_mpi( &A, &W ) == 0 ||            mpi_cmp_int( &A,  1 ) == 0 )            continue;        j = 1;        while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )        {            /*             * A = A * A mod |X|             */            MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );            MPI_CHK( mpi_mod_mpi( &A, &T, X  ) );            if( mpi_cmp_int( &A, 1 ) == 0 )                break;            j++;        }        /*         * not prime if A != |X| - 1 or A == 1         */        if( mpi_cmp_mpi( &A, &W ) != 0 ||            mpi_cmp_int( &A,  1 ) == 0 )        {            ret = XYSSL_ERR_MPI_NOT_ACCEPTABLE;            break;        }    }cleanup:    X->s = xs;    mpi_free( &RR, &A, &T, &R, &W, NULL );    return( ret );}/* * Prime number generation */int mpi_gen_prime( mpi *X, int nbits, int dh_flag,                   int (*f_rng)(void *), void *p_rng ){    int ret, k, n;    unsigned char *p;    mpi Y;    if( nbits < 3 )        return( XYSSL_ERR_MPI_BAD_INPUT_DATA );    mpi_init( &Y, NULL );    n = BITS_TO_LIMBS( nbits );    MPI_CHK( mpi_grow( X, n ) );    MPI_CHK( mpi_lset( X, 0 ) );    p = (unsigned char *) X->p;    for( k = 0; k < X->n * ciL; k++ )        *p++ = (unsigned char) f_rng( p_rng );    k = mpi_msb( X );    if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );    if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );    X->p[0] |= 3;    if( dh_flag == 0 )    {        while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )        {            if( ret != XYSSL_ERR_MPI_NOT_ACCEPTABLE )                goto cleanup;            MPI_CHK( mpi_add_int( X, X, 2 ) );        }    }    else    {        MPI_CHK( mpi_sub_int( &Y, X, 1 ) );        MPI_CHK( mpi_shift_r( &Y, 1 ) );        while( 1 )        {            if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )            {                if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )                    break;                if( ret != XYSSL_ERR_MPI_NOT_ACCEPTABLE )                    goto cleanup;            }            if( ret != XYSSL_ERR_MPI_NOT_ACCEPTABLE )                goto cleanup;            MPI_CHK( mpi_add_int( &Y, X, 1 ) );            MPI_CHK( mpi_add_int(  X, X, 2 ) );            MPI_CHK( mpi_shift_r( &Y, 1 ) );        }    }cleanup:    mpi_free( &Y, NULL );    return( ret );}#endif#if defined(XYSSL_SELF_TEST)/* * Checkup routine */int mpi_self_test( int verbose ){    int ret;    mpi A, E, N, X, Y, U, V;    mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );    MPI_CHK( mpi_read_string( &A, 16,        "EFE021C2645FD1DC586E69184AF4A31E" \        "D5F53E93B5F123FA41680867BA110131" \        "944FE7952E2517337780CB0DB80E61AA" \        "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );    MPI_CHK( mpi_read_string( &E, 16,        "B2E7EFD37075B9F03FF989C7C5051C20" \        "34D2A323810251127E7BF8625A4F49A5" \        "F3E27F4DA8BD59C47D6DAABA4C8127BD" \        "5B5C25763222FEFCCFC38B832366C29E" ) );    MPI_CHK( mpi_read_string( &N, 16,        "0066A198186C18C10B2F5ED9B522752A" \        "9830B69916E535C8F047518A889A43A5" \        "94B6BED27A168D31D4A52F88925AA8F5" ) );    MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );    MPI_CHK( mpi_read_string( &U, 16,        "602AB7ECA597A3D6B56FF9829A5E8B85" \        "9E857EA95A03512E2BAE7391688D264A" \        "A5663B0341DB9CCFD2C4C5F421FEC814" \        "8001B72E848A38CAE1C65F78E56ABDEF" \        "E12D3C039B8A02D6BE593F0BBBDA56F1" \        "ECF677152EF804370C1A305CAF3B5BF1" \        "30879B56C61DE584A0F53A2447A51E" ) );    if( verbose != 0 )        printf( "  MPI test #1 (mul_mpi): " );    if( mpi_cmp_mpi( &X, &U ) != 0 )    {        if( verbose != 0 )            printf( "failed\n" );        return( 1 );    }    if( verbose != 0 )        printf( "passed\n" );    MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );    MPI_CHK( mpi_read_string( &U, 16,        "256567336059E52CAE22925474705F39A94" ) );    MPI_CHK( mpi_read_string( &V, 16,        "6613F26162223DF488E9CD48CC132C7A" \        "0AC93C701B001B092E4E5B9F73BCD27B" \        "9EE50D0657C77F374E903CDFA4C642" ) );    if( verbose != 0 )        printf( "  MPI test #2 (div_mpi): " );    if( mpi_cmp_mpi( &X, &U ) != 0 ||        mpi_cmp_mpi( &Y, &V ) != 0 )    {        if( verbose != 0 )            printf( "failed\n" );        return( 1 );    }    if( verbose != 0 )        printf( "passed\n" );    MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );    MPI_CHK( mpi_read_string( &U, 16,        "36E139AEA55215609D2816998ED020BB" \        "BD96C37890F65171D948E9BC7CBAA4D9" \        "325D24D6A3C12710F10A09FA08AB87" ) );    if( verbose != 0 )        printf( "  MPI test #3 (exp_mod): " );    if( mpi_cmp_mpi( &X, &U ) != 0 )    {        if( verbose != 0 )            printf( "failed\n" );        return( 1 );    }    if( verbose != 0 )        printf( "passed\n" );    MPI_CHK( mpi_inv_mod( &X, &A, &N ) );    MPI_CHK( mpi_read_string( &U, 16,        "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \        "C3DBA76456363A10869622EAC2DD84EC" \        "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );    if( verbose != 0 )        printf( "  MPI test #4 (inv_mod): " );    if( mpi_cmp_mpi( &X, &U ) != 0 )    {        if( verbose != 0 )            printf( "failed\n" );        return( 1 );    }    if( verbose != 0 )        printf( "passed\n" );cleanup:    if( ret != 0 && verbose != 0 )        printf( "Unexpected error, return code = %08X\n", ret );    mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );    if( verbose != 0 )        printf( "\n" );    return( ret );}#endif#endif

⌨️ 快捷键说明

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