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

📄 bignum.h

📁 windows的加密api源码
💻 H
📖 第 1 页 / 共 4 页
字号:


/*
        Macro to return 3^i (exponentiation), for 0 <= i <= 15.
        Intended for use with constant argument, such as
        in array dimensions.  The POWER3 array should
        be used if the subscript is variable.
*/

#define POWER3CON(i) (   ((i) & 1 ?  3 : 1)  *  ((i) & 2 ?    9 : 1) \
                       * ((i) & 4 ? 81 : 1)  *  ((i) & 8 ? 6561 : 1) )

exportable_var DWORDC POWER3[16];   /* See mpglobals.c */
/*
        kara.c repeatedly replaces an operand by three
        half-length operands and a sign.  The sign has
        type kara_sign_t.  The operands are partitioned
        in half until their size at most VMUL_MAX_LNG_SINGLE,
        and sometimes further (see padinfo_initialization in kara.c)
        This may require up to KARA_MAX_HALVINGS halvings,
        giving 3^KARA_MAX_HALVINGS outputs each with size
        as large as VMUL_MAX_SINGLE words.  The signs
        array has length (3^KARA_MAX_HALVINGS - 1)/2.
*/
#if TARGET == TARGET_ALPHA
    typedef int kara_sign_t;
                        /* Try to avoid char data on Alpha */
#else
    typedef unsigned char kara_sign_t;
                        /* Values SIGN_PLUS, SIGN_MINUS.  See kara.c. */
#endif

typedef const kara_sign_t kara_sign_tc;
#define VMUL_MAX_LNG_SINGLE 12
#define KARA_MAX_HALVINGS (LG2_MP_LONGEST - 2)
#if KARA_MAX_HALVINGS > 15
    #error -- "Extend POWER3CON macro"
#endif
#define KARA_MAX_LNG_DIFS ((MP_LONGEST >> KARA_MAX_HALVINGS) * POWER3CON(KARA_MAX_HALVINGS))
#define KARA_MAX_LNG_SIGNS ((POWER3CON(KARA_MAX_HALVINGS) - 1)/2)
#define MEMORY_BANK_ALLOWANCE 1

typedef struct  {
                  digit_t     difs[KARA_MAX_LNG_DIFS + MEMORY_BANK_ALLOWANCE];
                  kara_sign_t signs[KARA_MAX_LNG_SIGNS];
                } kara_longest_t;   /* For MP_LONGEST or less */
                       /* On the Pentium P5 and P6,
                          the two arguments to vmulnn
                          should lie in different memory banks
                          (i.e., different addresses mod 32 bytes).
                          We make the .difs arrays one digit_t entry
                          larger than essential, in an attempt to reduce
                          data cache conflicts.  Look for the
                          MEMORY_BANK_ALLOWANCE symbol in the source code.
                        */


typedef struct  {
                  digit_t     difs[KARA_MAX_LNG_DIFS/3 + MEMORY_BANK_ALLOWANCE];
                  kara_sign_t signs[KARA_MAX_LNG_SIGNS/3];
                } kara_half_longest_t;  /* For MP_LONGEST/2 or less */

typedef const kara_half_longest_t kara_half_longest_tc;
typedef const kara_longest_t      kara_longest_tc;

typedef struct {      /* Constants relating to padding lengths. */
                  DWORD  length;
                                /* length = length3[0] * 2^nhalving */
                  DWORD  nhalving;
                  DWORD  length3[KARA_MAX_HALVINGS+1];
                                /* length3[0] is 1, 2, 3, or 4 */
                                /* length3[i] is length3[0] * 3^i */
               } padinfo_t;

typedef const padinfo_t padinfo_tc;
#define padinfo_NULL ((padinfo_t*)0)

/*
        The reciprocal_1_t type is used when div21
        or divide or divide_immediate would otherwise
        divide by the same number repeatedly.  See file divide.c.
*/

typedef struct {
                digit_t multiplier;
                int     shiftamt;
               } reciprocal_1_t;

typedef const reciprocal_1_t reciprocal_1_tc;

/*
        mp_modulus_t struct has modulus-dependent constants
        used for fast reduction (typically for a fixed modulus,
        which will be used several times, as in modular exponentiation).
        These constants are initialized by function create_modulus:

        modulus -- Modulus used for computations.  Must be nonzero.

        length  -- Length of the modulus, without leading zeros.
                   Operands to mod_add, mod_mul, mod_sub, ...
                   are assumed to have this length.

        padinfo -- Pointer to a padinfo_t struct.  For fast arithmetic,
                   operands are padded to a length
                   length_padded >= length (see find_padinfo in kara.c).
                   The value of length_padded is stored in padinfo->length.
                   The present implementation requires length_padded be either
                   a power of 2, or 3 times a power of 2.
                   For example, if length = 19, then length_padded = 24,
                   and the operands are treated as 24-word
                   operands for Karatsuba.

        half_padinfo -- Pointer to a padinfo_t struct for length
                   CEIL(length/2).  Used in modular_reduce to
                   use Karatsuba multiplication on half-length operands.
                   We denote half_length_padded = half_padinfo->length.

        reddir  -- Equal to FROM_LEFT if reductions of
                   products are done from the left (traditional
                   division), and to FROM_RIGHT if reductions of
                   products are done from the right (Montgomery reduction).

                   When using FROM_RIGHT, the modulus must be odd.
                   Arguments to mod_mul should be pre-scaled by
                   RADIX^scaling_power (mod modulus).
                   The product will be similarly scaled.

        scaling_power --  Equal to 2*half_length_padded when
                   reddir = FROM_RIGHT.  Undefined
                   if reddir = FROM_LEFT.

        one --     Constant 1 (length length), scaled if reddir = FROM_RIGHT.
                   When reddir = FROM_RIGHT, this is
                   RADIX^scaling_power (mod modulus).

        left_multiplier_first -- The first multiplier when reducing from the
                   left.  Length length.

-RADIX^(length + half_length_padded)/2^(left_reciprocal_1.shiftamt) mod modulus

        left_reciprocal_1 -- Reciprocal of the divisor starting at the
                   leftmost digit (i.e., modulus[length-1]);

        right_reciprocal_1 -- If modulus is odd, this holds
                   1/modulus (mod RADIX), for use in mod_shift.
                   Otherwise the field is zero.

        right_multiplier_second -- If reddir = FROM_RIGHT,
                   then this has 1/modulus mod RADIX^(half_length_padded).

        right_multiplier_first --   -1/RADIX^half_length_padded mod modulus.
                   Equal to

        left_multiplier_second -- Contains the half_length_padded*RADIX_BITS

            (modulus * right_multiplier_second - 1)/RADIX^half_length_padded.
                   most significant bits of (high power of 2)/modulus
                   (excluding the leading -1-).  More precisely, this has

        RADIX^(length + half_length_padded) - 1
 FLOOR( --------------------------------------- ) - RADIX^(half_length_padded)
        modulus * 2^(left_reciprocal_1.shiftamt)


                   See file divide.c for an explanation
                   about how this constant is used to get accurate
                   quotients when dividing from the left.

        left_multiplier_second_over2 -- Left_multiplier_second/2.
*/


typedef enum {FROM_LEFT, FROM_RIGHT} reddir_t;
typedef const reddir_t reddir_tc;

typedef struct {
                  digit_t   modulus[MP_LONGEST];
                  DWORD     length;      /* Length passed to create_modulus */
                  DWORD     scaling_power; /* 2*half_padinfo->length */
                  padinfo_tc *padinfo;   /* Pointer to struct containing
                                            padded length and related info */
                  padinfo_tc *half_padinfo;
                                         /* Padinfo info for CEIL(length/2) */
                  reddir_t  reddir;      /* FROM_LEFT or FROM_RIGHT */
                  reciprocal_1_t  left_reciprocal_1;
                  digit_t  right_reciprocal_1;
                                        /* 1/modulus[0] mod RADIX,
                                           if modulus is odd */

                  kara_half_longest_t modulus_kara2[2];
                                        /*
                                            Copy of modulus.

                                            Lower half_length_padded
                                            and upper
                                            length - half_length_padded
                                            words separately passed
                                            to to_kara.
                                         */
                  kara_half_longest_t left_multiplier_first_kara2[2];
                                /* Remainder when dividing
                                     -RADIX^(length + half_length_padded)
                                   / 2^(left_reciprocal_1.shiftamt)
                                   by modulus.

                                   Lower and upper halvves separately
                                   passed to to_kara.
                                */

                  kara_half_longest_t left_multiplier_second_kara;
                                /* half_length_padded*RADIX_BITS
                                   most significant bits of (left)
                                   reciprocal of modulus,
                                   excluding the leading -1-. */

                  digit_t  left_multiplier_second_over2[MP_LONGEST/2];
                                /* left_multiplier_second/2 */
                  kara_half_longest_t right_multiplier_first_kara2[2];
                                        /*  -1/RADIX^half_length_padded
                                            mod modulus.
                                        */
                  digit_t             right_multiplier_second[MP_LONGEST/2];
                  kara_half_longest_t right_multiplier_second_kara;
                              /* 1/modulus mod RADIX^(half_length_padded) */
                  digit_t  cofactor[MP_LONGEST];
                  DWORD    lng_cofactor;
                             /*
                                In factorization programs, this
                                holds the cofactor after dividing
                                modulus by any factors found.
                                Used by gcdex_jacobi.
                             */
                  digit_t  one[MP_LONGEST];
                } mp_modulus_t;


typedef const mp_modulus_t mp_modulus_tc;
/*
       The modular multiplication code and its
       relatives (e.g., modular_reduce, to_kara)
       need large amounts of temporary space
       during processing.  All big temporaries
       are gathered into a modmultemp_t struct.
       Users of these routines can allocate the
       storage themselves, and pass a pointer
       to the temporary storage (fastest), or can pass
       a null pointer (modmultemp_NULL).

*/
typedef struct {
                   // mmul fields are for mod_mul,
                   // mod_mul_kara, mod_mul_kara1

        digit_t             mmul_adifs[KARA_MAX_LNG_DIFS];
        kara_sign_t         mmul_asigns[KARA_MAX_LNG_SIGNS];
        digit_t             mmul_bdifs[KARA_MAX_LNG_DIFS
                                       + MEMORY_BANK_ALLOWANCE];
        kara_sign_t         mmul_bsigns[KARA_MAX_LNG_SIGNS];

                   // mr_ fields are for modular_reduce.
                   // The input to modular_reduce can be stored
                   // in mr_dividend -- this will save a mp_copy call.

        digit_t             mr_dividend[MAX(2*MP_LONGEST,
                                            2*KARA_MAX_LNG_DIFS+1)];

        digit_t             mr_prd1[2*MP_LONGEST];
        digit_t             mr_prd2[2*MP_LONGEST];
        digit_t             mr_mptemp[2*MP_LONGEST];

                   // htk_ fields are for half_times_kara
                   // and half_times_kara2

        digit_t             htk_abprd[2][2*KARA_MAX_LNG_DIFS/3];
        kara_half_longest_t htk_ak;
        } modmultemp_t;

typedef struct {
        void             *pInfo;
        void             *pFuncRNG;
        } RNGINFO;

/*
        When an error is detected, variable mp_errno is set
        to the error number and execution continues.
        If the library was compiled with #define PRINT_ERROR_MESSAGES,
        then a message is written to file mp_errfil.

        The application program should occasionally check mp_errno.

        Except for MP_ERRNO_NO_ERROR, the error numbers are
        in alphabetical order by name.  The routine issuing
        each error number is part of the name.
*/

typedef enum {
        MP_ERRNO_NO_ERROR = 0,
        MP_ERRNO_CREATE_MODULUS_LEADING_ZERO,
        MP_ERRNO_CREATE_MODULUS_MONTGOMERY_EVEN,
        MP_ERRNO_CREATE_MODULUS_TOO_LONG,
        MP_ERRNO_DIGIT_JACOBI_EVEN_DENOMINATOR,
        MP_ERRNO_DIGIT_MOD_DIVIDE_ODD_EVEN_MODULUS,
        MP_ERRNO_DIGIT_MOD_DIVIDE_ODD_NONTRIVIAL_GCD,
        MP_ERRNO_DIGIT_MOD_DIVIDE_ODD_ZERO_DENOMINATOR,
        MP_ERRNO_DIGIT_NEXT_PRIME_TOO_HIGH,
        MP_ERRNO_DIV21_INVALID_ARGUMENT,
        MP_ERRNO_DIVIDE_ESTIMATION_ERROR,
        MP_ERRNO_DIVIDE_INVALID_LENGTHS,
        MP_ERRNO_DIVIDE_LEADING_ZERO,
        MP_ERRNO_DSA_KEY_GENERATION_INVALID_SIZES,
        MP_ERRNO_DSA_PRECOMPUTE_BAD_G,
        MP_ERRNO_DSA_PRECOMPUTE_INVALID_KEY,
        MP_ERRNO_DSA_PRECOMPUTE_PQ_NONPRIME,
        MP_ERRNO_DSA_PRECOMPUTE_WRONG_SC,
        MP_ERRNO_DSA_SIGNATURE_VERIFICATION_NONTRIVIAL_GCD,
        MP_ERRNO_FIND_BIG_PRIME_BAD_CONGRUENCE_CLASS,
        MP_ERRNO_FIND_BIG_PRIME_CONG_MOD_TOO_LARGE,
        MP_ERRNO_FIND_BIG_PRIME_CONG_TO_TOO_LARGE,
        MP_ERRNO_GCDEX_JACOBI_EVEN_MODULUS,
        MP_ERRNO_KP_TOO_SHORT,
        MP_ERRNO_KPDIV_ZERO_DENOMINATOR,
        MP_ERRNO_MOD_ADD_CARRY_NONZERO,
        MP_ERRNO_MOD_SHIFT_LEFT_CARRY_NONZERO,
        MP_ERRNO_MOD_SHIFT_RIGHT_CARRY_NONZERO,
        MP_ERRNO_MOD_SHIFT_RIGHT_EVEN,
        MP_ERRNO_MOD_SUB_BORROW_NONZERO,
        MP_ERRNO_MODULAR_REDUCE_BOTTOM_BITS_DIFFERENT,
        MP_ERRNO_MODULAR_REDUCE_TOO_LONG,
        MP_ERRNO_MODULAR_REDUCE_UNEXPECTED_CARRY,
        MP_ERRNO_MP_DECIMAL_INPUT_NONDIGIT,
        MP_ERRNO_MP_DECIMAL_INPUT_OVERFLOW,
        MP_ERRNO_MP_GCD_INTERMEDIATE_EVEN,
        MP_ERRNO_MP_GCD_TOO_LONG,
        MP_ERRNO_MP_GCDEX_INTERNAL_ERROR,
        MP_ERRNO_MP_GCDEX_NONZERO_REMAINDER,
        MP_ERRNO_MP_GCDEX_ZERO_OPERAND,
        MP_ERRNO_MP_SHIFT_INVALID_SHIFT_COUNT,
        MP_ERRNO_MP_TRAILING_ZERO_COUNT_ZERO_ARG,
        MP_ERRNO_MULTIPLY_LOW_INVALID_LENGTH,
        MP_ERRNO_NO_MEMORY,      // From mp_alloc_temp

⌨️ 快捷键说明

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