TwlIPL_commit-99/build/tools/acsign/include/bn.h
2023-12-16 15:41:34 -05:00

1121 lines
34 KiB
C

/* $Id$ */
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#ifndef HEADER_COMMON_BN_H
#define HEADER_COMMON_BN_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef FLAT_INC
#include "r_types.h"
#else
#include "../include/r_types.h"
#endif
#if !defined(CCONV)
#define CCONV
#endif
#ifndef PRE_CCONV
#define PRE_CCONV
#endif
/* convert from the new to the old option names */
#if defined(OPT_BN_LLONG)
#define BN_LLONG /* comment to make sure Configure leaves this alone */
#endif
#if defined(OPT_BN_MUL_LATENCY)
#define BN_MUL_LATENCY
#endif
/* by default we have the following switched on - unless we have an option
* that switched them off for a specific platform
*/
#ifdef OPT_NO_COMBA
#define OPT_NO_BN_MUL_COMBA
#define OPT_NO_BN_SQR_COMBA
#endif
#ifdef OPT_NO_REC
#define OPT_NO_BN_RECURSION_MUL
#define OPT_NO_BN_RECURSION_SQR
#endif
#ifndef OPT_NO_BN_MUL_COMBA
#define BN_MUL_COMBA
#endif
#ifndef OPT_NO_BN_SQR_COMBA
#define BN_SQR_COMBA
#endif
#ifndef OPT_NO_BN_RECURSION_MUL
#define BN_RECURSION_MUL
#endif
#ifndef OPT_NO_BN_RECURSION_SQR
#define BN_RECURSION_SQR
#endif
#ifndef OPT_NO_BN_RECURSION_MONT
#undef BN_RECURSION_MONT /* DO NOT TURN THIS ON, IT IS BROKEN */
#endif
#if (!defined(OPT_NO_BN_MUL_COMBA) && !defined(OPT_NO_BN_SQR_COMBA))
#if OPT_MONT_REDUCE_COMBA /* TEMP UNTIL C IS IMPLEMENTED-DEF'd ON PLATFORMS W/ ASM */
#define BN_REDUCE_COMBA
#endif
#endif
#define RECP_MUL_MOD
#define MONT_MUL_MOD
#ifndef OPT_NO_BN_SURRENDER
#define BN_SURRENDER
#else
#undef BN_SURRENDER
#endif
#ifdef SMALL_CODE_SIZE
#undef BN_MUL_COMBA /* stop modification */
#undef BN_SQR_COMBA /* stop modification */
#undef BN_REDUCE_COMBA /* stop modification */
#undef BN_RECURSION_MUL /* stop modification */
#undef BN_RECURSION_SQR /* stop modification */
#undef BN_RECURSION_MONT /* stop modification */
#endif
/* This next option uses the C libraries (2 word)/(1 word) function.
* If it is not defined, I use my C version (which is slower).
* The reason for this flag is that when the particular C compiler
* library routine is used, and the library is linked with a different
* compiler, the library is missing. This mostly happens when the
* library is built with gcc and then linked using nornal cc. This would
* be a common occurance because gcc normally produces code that is
* 2 times faster than system compilers for the big number stuff.
* For machines with only one compiler (or shared libraries), this should
* be on. Again this in only really a problem on machines
* using "long long's", are 32bit, and are not using my assember code. */
#if defined(MSDOS) || defined(WINDOWS) || defined(linux)
#define BN_DIV2W
#endif
/* Only one for the following should be defined */
/* The prime number generation stuff may not work when
* EIGHT_BIT but I don't care since I've only used this mode
* for debuging the bignum libraries */
#undef SIXTY_FOUR_BIT_LONG
#undef SIXTY_FOUR_BIT
#undef SIXTY_BIT
#undef THIRTY_TWO_BIT
#undef THIRTY_BIT
#undef SIXTEEN_BIT
#undef EIGHT_BIT
#undef TEST_EIGHT_BIT
#if defined(OPT_64_BIT_LONG)
#define SIXTY_FOUR_BIT_LONG
#endif
#if defined(OPT_64_BIT)
#define SIXTY_FOUR_BIT
#endif
#if defined(OPT_60_BIT)
#define SIXTY_BIT
#endif
#if defined(OPT_32_BIT)
#define THIRTY_TWO_BIT
#endif
#if defined(OPT_32_BIT_INT)
#define THIRTY_TWO_BIT
#endif
#if defined(OPT_30_BIT)
#define THIRTY_BIT
#endif
#if defined(OPT_16_BIT)
#define SIXTEEN_BIT
#endif
#if defined(OPT_8_BIT)
#define EIGHT_BIT
#endif
#if defined(OPT_8_BIT_TEST)
#define TEST_EIGHT_BIT
#endif
/* This define is used for those few functions that 'break' when
* things are compiled for 8 bit words. Basically the size of an
* integer.
*/
#define BN_ILONG BN_ULONG
/* assuming long is 64bit - this is the DEC Alpha
* unsigned long long is only 64 bits, don't define
* BN_LLONG for the DEC Alpha */
#ifdef SIXTY_FOUR_BIT_LONG
#undef BN_LLONG
#define BN_ULLONG unsigned long long
#define BN_ULONG unsigned long
#define BN_LONG long
#define BN_BITS 128
#define BN_BYTES 8
#define BN_BITS2 64
#define BN_BITS4 32
#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
#define BN_MASK2 (0xffffffffffffffffL)
#define BN_MASK2l (0xffffffffL)
#define BN_MASK2lh (0xffffffffL)
#define BN_MASK2h (0xffffffff00000000L)
#define BN_MASK2h1 (0xffffffff80000000L)
#define BN_TBIT (0x8000000000000000L)
#define BN_DEC_CONV (10000000000000000000UL)
#define BN_DEC_FMT1 "%lu"
#define BN_DEC_FMT2 "%019lu"
#define BN_DEC_NUM 19
#define BN_HEX_FMT "%016lX"
#endif
/* This is where the long long data type is 64 bits, but long is 32.
* For machines where there are 64bit registers, this is the mode to use.
* IRIX, on R4000 and above should use this mode, along with the relevent
* assember code. Do NOT define BN_LLONG.
*/
#ifdef SIXTY_FOUR_BIT
#undef BN_LLONG /* Protect against config */
/* #define BN_ULLONG unsigned long long */
#ifdef WIN64
#define BN_ULONG unsigned _int64
#define BN_LONG _int64
#else
#define BN_ULONG unsigned long long
#define BN_LONG long long
#endif
#define BN_BITS 128
#define BN_BYTES 8
#define BN_BITS2 64
#define BN_BITS4 32
#define BN_MASK2 (0xffffffffffffffffLL)
#define BN_MASK2l (0xffffffffL)
#define BN_MASK2lh (0xffffffffL)
#define BN_MASK2h (0xffffffff00000000LL)
#define BN_MASK2h1 (0xffffffff80000000LL)
#define BN_TBIT (0x8000000000000000LL)
#define BN_DEC_CONV (10000000000000000000ULL)
#ifdef WIN64
#define BN_DEC_FMT1 "%I64u"
#define BN_DEC_FMT2 "%019I64u"
#define BN_DEC_NUM 19
#define BN_HEX_FMT "%016I64X"
#else
#define BN_DEC_FMT1 "%llu"
#define BN_DEC_FMT2 "%019llu"
#define BN_DEC_NUM 19
#define BN_HEX_FMT "%016llX"
#endif
#endif
#ifdef SIXTY_BIT
#undef SIXTY_FOUR_BIT
#undef BN_LLONG /* Protect against config */
/* #define BN_ULLONG unsigned long long */
#define BN_ULONG unsigned long long
#define BN_LONG long long
#define BN_BITS 120
#define BN_BITS2 60
#define BN_BITS4 30
#define BN_MASK2 (0x0fffffffffffffffLL)
#define BN_MASK2l ( 0x3fffffffL)
#define BN_MASK2lh ( 0x3fffffffL)
#define BN_MASK2h (0x0fffffffc0000000LL)
#define BN_MASK2h1 (0x0fffffffe0000000LL)
#define BN_TBIT (0x0800000000000000LL)
#define BN_DEC_CONV (100000000000000000LL)
#define BN_DEC_FMT1 "%9u"
#define BN_DEC_FMT2 "%017llu"
#define BN_DEC_NUM 17
#define BN_HEX_FMT "%016llX"
#endif
#ifdef THIRTY_TWO_BIT
#ifdef WIN32
#if defined(__BORLANDC__)
#define BN_ULLONG unsigned __int64
#else /* !__BORLANDC__ */
#if defined(__MINGW32__) || defined(__DJGPP__)
#define BN_ULLONG unsigned long long
#else
#define BN_ULLONG unsigned _int64
#endif /* __MINGW32__ || __DJGPP__ */
#endif /* __BORLANDC__ */
#else /* !WIN32 */
#define BN_ULLONG unsigned long long
#endif /* WIN32 */
#ifdef OPT_32_BIT_INT
#define BN_ULONG unsigned int
#define BN_LONG int
#else
#define BN_ULONG unsigned long
#define BN_LONG long
#endif
#define BN_BITS 64
#define BN_BYTES 4
#define BN_BITS2 32
#define BN_BITS4 16
/* This is needed because the Watcom compiler pre-processor
* under QNX tries to parses the 'LL' part even though it is
* never used.
*/
#ifdef BN_LLONG
#ifndef WIN32
#define BN_MASK (0xffffffffffffffffLL)
#else
#define BN_MASK (0xffffffffffffffffL)
#endif
#endif
#define BN_MASK2 (0xffffffffL)
#define BN_MASK2l (0xffff)
#define BN_MASK2lh (0xffff)
#define BN_MASK2h1 (0xffff8000L)
#define BN_MASK2h (0xffff0000L)
#define BN_TBIT (0x80000000L)
#define BN_DEC_CONV (1000000000L)
#define BN_DEC_FMT1 "%lu"
#define BN_DEC_FMT2 "%09lu"
#define BN_DEC_NUM 9
#define BN_HEX_FMT "%08lX"
#endif
#ifdef THIRTY_BIT
#ifdef WIN32
#if defined(__MINGW32__) || defined(__DJGPP__)
#define BN_ULLONG unsigned long long
#else /* ! (__MINGW32__ || __DJGPP__) */
#define BN_ULLONG unsigned _int64
#endif /* __MINGW32__ || __DJGPP__ */
#else /* !WIN32 */
#define BN_ULLONG unsigned long long
#endif /* WIN32 */
#define BN_ULONG unsigned long
#define BN_LONG long
#define BN_BITS 60
#define BN_BITS2 30
#define BN_BITS4 15
/* This is needed because the Watcom compiler pre-processor
* under QNX tries to parses the 'LL' part even though it is
* never used.
*/
#ifdef BN_LLONG
#ifndef WIN32
#define BN_MASK (0x0fffffffffffffffLL)
#else
#define BN_MASK (0x0fffffffffffffffL)
#endif
#endif
#define BN_MASK2 (0x3fffffffL)
#define BN_MASK2l (0x7fff)
#define BN_MASK2lh (0x7fff)
#define BN_MASK2h1 (0x3fffc000L)
#define BN_MASK2h (0x3fff8000L)
#define BN_TBIT (0x20000000L)
#define BN_DEC_CONV (1000000000L)
#define BN_DEC_FMT1 "%lu"
#define BN_DEC_FMT2 "%09lu"
#define BN_DEC_NUM 9
#define BN_HEX_FMT "%08lX"
#endif
#ifdef SIXTEEN_BIT
#ifndef BN_DIV2W
#define BN_DIV2W
#endif
#define BN_ULLONG unsigned long
#define BN_ULONG unsigned short
#define BN_LONG short
#define BN_BITS 32
#define BN_BYTES 2
#define BN_BITS2 16
#define BN_BITS4 8
#define BN_MASK (0xffffffff)
#define BN_MASK2 (0xffff)
#define BN_MASK2l (0xff)
#define BN_MASK2lh (0xff)
#define BN_MASK2h1 (0xff80)
#define BN_MASK2h (0xff00)
#define BN_TBIT (0x8000)
#define BN_DEC_CONV (10000)
#define BN_DEC_FMT1 "%u"
#define BN_DEC_FMT2 "%04u"
#define BN_DEC_NUM 4
#define BN_HEX_FMT "%04X"
#endif
#ifdef TEST_EIGHT_BIT
#define EIGHT_BIT /* comment to stop editing */
#endif
#ifdef EIGHT_BIT
#undef BN_ILONG
#define BN_ILONG unsigned int
#ifndef BN_DIV2W
#define BN_DIV2W
#endif
#ifdef TEST_EIGHT_BIT
#define BN_ULLONG unsigned int
#define BN_ULONG unsigned int
#define BN_LONG int
#else
#define BN_ULLONG unsigned short
#define BN_ULONG unsigned char
#define BN_LONG char
#endif
#define BN_BITS 16
#define BN_BYTES 1
#define BN_BITS2 8
#define BN_BITS4 4
#define BN_MASK (0xffff)
#define BN_MASK2 (0xff)
#define BN_MASK2lh (0xf)
#define BN_MASK2l (0xf)
#define BN_MASK2h1 (0xf8)
#define BN_MASK2h (0xf0)
#define BN_TBIT (0x80)
#define BN_DEC_CONV (100)
#define BN_DEC_FMT1 "%u"
#define BN_DEC_FMT2 "%02u"
#define BN_DEC_NUM 2
#define BN_HEX_FMT "%02X"
#endif
#ifdef BIGNUM
#undef BIGNUM
#endif
#define BN_FLG_MALLOCED 0x01
#define BN_FLG_STATIC_DATA 0x02
#define BN_FLG_FREE 0x8000 /* used for debuging */
#define BN_CTX_FLG_ABORT 0x4000 /* used for aborting RSA operations*/
#define BN_set_flags(b,n) ((b)->flags|=(n))
#define BN_get_flags(b,n) ((b)->flags&(n))
#define BN_CTX_set_flags(b,n) ((b)->flags|=(n))
#define BN_CTX_get_flags(b,n) ((b)->flags&(n))
#ifndef HEADER_COMMON_BN_H_TYPEDEF_DEF
#define HEADER_COMMON_BN_H_TYPEDEF_DEF
typedef struct bignum_st BIGNUM;
typedef struct bignum_ctx BN_CTX;
typedef struct bn_mont_ctx_st BN_MONT_CTX;
typedef struct bn_recp_ctx_st BN_RECP_CTX;
typedef struct bn_prime_ctx_st BN_PRIME_CTX;
typedef struct bn_blind_ctx_st BN_BLIND_CTX;
typedef struct bn_blind_meth_st BN_BLIND_METH;
#endif
typedef struct bn_mod_exp_meth_st BN_ME_METH;
typedef struct bn_mod_exp_ctx_st BN_ME_CTX;
/* The data array d must always have an extra 'valid' word in location
* bn->d[bn->max]. It must be ok for reading. This is needed if
* BN_MUL_LATENCY is defined.
*/
struct bignum_st
{
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int max; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};
/* Used for temp variables */
#define BN_CTX_NUM 12
struct bignum_ctx
{
int tos;
BIGNUM bn[BN_CTX_NUM+1];
int flags;
R_SURRENDER *surrender;
};
#if defined(WIN64) || defined(__ia64__) || defined(CPU_IA64)
#define BN_USHORT unsigned int
#else
#define BN_USHORT unsigned short
#endif
/* Used for prime number generation */
struct bn_prime_ctx_st
{
BN_USHORT *primes;
BN_USHORT *mods;
int num_primes;
int prime_checks;
R_SURRENDER *surrender;
R_RANDOM *random;
int flags;
};
struct bn_blind_ctx_st
{
int init;
BN_BLIND_METH *meth;
BIGNUM B;
BIGNUM Bi;
BIGNUM mod;
};
struct bn_blind_meth_st
{
void (*init) (BN_BLIND_CTX *);
void (*ctx_free)(BN_BLIND_CTX *);
int (*set) (BN_BLIND_CTX *,R_RANDOM *,BIGNUM *,BIGNUM *, BN_ME_CTX *,BN_CTX *);
int (*convert) (BN_BLIND_CTX *,BIGNUM *,BN_CTX *);
int (*invert) (BN_BLIND_CTX *,BIGNUM *,BN_CTX *);
int (*update) (BN_BLIND_CTX *,BN_CTX *);
int (*copy) (BN_BLIND_CTX *,BN_BLIND_CTX *);
};
/* Used for montgomery multiplication */
struct bn_mont_ctx_st
{
int use_word; /* 0 for word form, 1 for long form */
int ri; /* number of bits in R */
int riw; /* number of words in R */
BIGNUM RR; /* used to convert to montgomery form */
BIGNUM N; /* The modulus */
BIGNUM Ni; /* The inverse of N */
BN_ULONG n0; /* word form of inverse, normally only one of
* Ni or n0 is defined */
int flags;
};
/* Used by the recursive exponentiation implementations */
typedef struct bn_mod_exp_rec_meth_st
{
#ifndef NOPROTO
void (PRE_CCONV CCONV *mul)(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
void (PRE_CCONV CCONV *sqr)(BN_ULONG *r, BN_ULONG *a);
void (PRE_CCONV CCONV *low_mul)();
#else
void (PRE_CCONV CCONV *mul)();
void (PRE_CCONV CCONV *sqr)();
void (PRE_CCONV CCONV *low_mul)();
#endif
} BN_MOD_EXP_REC_METH;
/* If this flag is set, if there is a custom method for a modulus
* two times larger, use it. This is mostly mean for use on the
* itanium where a 512*512 routine is 10 times faster than the C
* code version, so we need to detect that we can turn of CRT
* for RSA if there is an native IA64 512*512 present.
*/
#define BN_ME_FLG_FAST_ASM 0x0001
struct bn_mod_exp_meth_st
{
int num; /* Word size we target */
char *name; /* Identify the method */
#ifndef NOPROTO
int (*useit)(const BN_ME_METH *meth);
/* If 'power' is null, reuse the old one */
int (*mod_exp)(BN_ME_CTX *mctx,BIGNUM *r,BIGNUM *a,BIGNUM *p,
BN_CTX *ctx);
/* Create the BN_ME_CTX */
int (*init_ctx)(const BN_ME_METH *meth,BN_ME_CTX **mctx);
/* Get rid of it */
int (*free_ctx)(BN_ME_CTX *mctx);
/* Assign the modulus */
int (*set)(BN_ME_CTX *mctx,BIGNUM *n,int cmd,int flags,BN_CTX *ctx);
#else
int (*useit)();
int (*mod_exp)();
int (*init_ctx)();
int (*free_ctx)();
int (*set)();
#endif
int argi;
char *argp; /* 'Extra stuff' */
};
#define BN_ME_METH_TABLE_MAX 32
/* Used in BN_library_init */
#define BN_INIT_LAST 0x00
#define BN_INIT_BN_ME_METH 0x01
#define BN_BNME_F_DEFAULT 0x01
/* Used only when loading, kept as bits internally, normally loaded as
* words */
#define BN_BNME_F_BITS 0x02
typedef struct bn_me_meth_info_st
{
#ifndef NOPROTO
const BN_ME_METH *(*meth)(void);
#else
const BN_ME_METH *(*meth)();
#endif
int min;
int max;
int flags;
} BN_ME_METH_INFO;
#define BN_ME_SET_MOD 0x01
#define BN_ME_SET_BASE 0x02
#define BN_ME_SET_EXP 0x03
#define BN_ME_SET_FLG_NO_LOOKUP 0x01 /* Passed to BN_ME_CTX_set() */
#define BN_FLG_CACHE 0x10 /* Cache values */
#define BN_ME_FLG_BASE 0x40 /* base has been cached */
#define BN_ME_FLG_EXP 0x80 /* power has been cached */
/* When one of these structures is setup, it is intended that the
* base or power, if not null, will be used for the current calculation.
* If the base and/or power are cached, they will only be used if the input
* value is null.
* For RSA, the power would normally be set.
* For DH, the base and power would be set. The initial value generated
* would be the public key, which is exchanged. The phase2 part would
* change the base but not the power.
* For DSA signing, a fixed base is used, but a random power.
* For DSA verification, there are two bases and two powers,
* a^p%m * b^q%m
* One way to implement this is to use a special function to
* generate a composite power value, and or a special base form.
* The other option is to have a special function to generate
* the 'base' array. The problem is that we are exponentiating with
* a 3 value power value, instead of the normal two. It should be possible
* to use the standard a^b%m function.
*/
struct bn_mod_exp_ctx_st
{
const BN_ME_METH *meth;
char *callback;
char *cb_arg;
int flags;
/* Evil hack for storage of data values, it should really be here
* other than the first value */
char *modulus; /* eg BN_MONT_CTX */
char *power; /* eg power representation */
char *base; /* eg base representation */
char *arg;
};
/* Used for reciprocal division/mod functions
* It cannot be shared between threads
*/
struct bn_recp_ctx_st
{
BIGNUM N; /* the divisor */
BIGNUM Nr; /* the reciprocal */
int num_bits;
int shift;
int flags;
};
typedef struct bn_rec_st
{
int depth;
int n;
#ifndef NOPROTO
void (PRE_CCONV CCONV *mul)(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
void (PRE_CCONV CCONV *sqr)(BN_ULONG *r, BN_ULONG *a);
void (PRE_CCONV CCONV *low_mul)();
#else
void (PRE_CCONV CCONV *mul)();
void (PRE_CCONV CCONV *sqr)();
void (PRE_CCONV CCONV *low_mul)();
#endif
} BN_REC;
#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
r,a,&((mont)->RR),(mont),ctx)
#define BN_prime_checks (5)
#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
#define BN_length(a) ((a)->top * BN_BYTES)
#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
#define BN_is_zero(a) (((a)->top == 0) || BN_is_word(a,0))
#define BN_is_one(a) (BN_is_word((a),1))
#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1))
#define BN_one(a) (BN_set_word((a),(BN_ULONG)1))
#define BN_zero(a) (BN_set_word((a),(BN_ULONG)0))
/*#define BN_ascii2bn(a) BN_hex2bn(a) */
/*#define BN_bn2ascii(a) BN_bn2hex(a) */
#define bn_expand(n,b) ((((((b+BN_BITS2-1))/BN_BITS2)) <= (n)->max)?\
(n):bn_expand2((n),(b)/BN_BITS2+1))
#define bn_wexpand(n,b) (((b) <= (n)->max)?(n):bn_expand2((n),(b)))
#ifdef SMALL_CODE_SIZE
void bn_zexpand(BIGNUM *a,int n);
void bn_fix_top(BIGNUM *a);
#else
#define bn_zexpand(a,n) \
if ((a)->top < n) \
{ \
int i; \
bn_wexpand((a),n); \
if ((a)->d!=NULL) \
{ \
for (i=(a)->top; i<n; i++) \
(a)->d[i]=0; \
} \
}
#define bn_fix_top(a) \
{ \
BN_ULONG *ftl; \
if ((a)->top > 0) \
{ \
for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
if (*(ftl--)) break; \
} \
}
#endif
#define BN_MONT_CTX_set(a,b,c) BN_MONT_CTX_set_word((a),(b),(c))
#ifndef NOPROTO
const BN_ME_METH *BN_ME_METH_word(void);
const BN_ME_METH *BN_ME_METH_full(void);
#if (defined(BN_MUL_COMBA) || defined(BN_SQR_COMBA))
/* word4 - used for 64bit multiprime*/
const BN_ME_METH *BN_ME_METH_word4(void);
const BN_ME_METH *BN_ME_METH_rec4_word8(void);
const BN_ME_METH *BN_ME_METH_rec4_word16(void);
const BN_ME_METH *BN_ME_METH_rec4_word32(void);
const BN_ME_METH *BN_ME_METH_rec4_word64(void);
const BN_ME_METH *BN_ME_METH_rec4_word128(void);
/* word6 - used for 64bit multiprime*/
const BN_ME_METH *BN_ME_METH_word6(void);
const BN_ME_METH *BN_ME_METH_rec6_word12(void);
const BN_ME_METH *BN_ME_METH_rec6_word24(void);
const BN_ME_METH *BN_ME_METH_rec6_word48(void);
const BN_ME_METH *BN_ME_METH_rec6_word96(void);
const BN_ME_METH *BN_ME_METH_word8(void);
const BN_ME_METH *BN_ME_METH_rec8_word16(void);
const BN_ME_METH *BN_ME_METH_rec8_word32(void);
const BN_ME_METH *BN_ME_METH_rec8_word64(void);
const BN_ME_METH *BN_ME_METH_rec8_word128(void);
const BN_ME_METH *BN_ME_METH_rec8_word256(void);
const BN_ME_METH *BN_ME_METH_word11(void);
const BN_ME_METH *BN_ME_METH_rec11_word22(void);
const BN_ME_METH *BN_ME_METH_rec11_word44(void);
const BN_ME_METH *BN_ME_METH_rec11_word88(void);
const BN_ME_METH *BN_ME_METH_word16(void);
const BN_ME_METH *BN_ME_METH_rec16_word32(void);
const BN_ME_METH *BN_ME_METH_rec16_word64(void);
const BN_ME_METH *BN_ME_METH_rec16_word128(void);
const BN_ME_METH *BN_ME_METH_rec16_word256(void);
#endif
#ifdef CPU_IA64
const BN_ME_METH *BN_ME_METH_ia64_384(void);
const BN_ME_METH *BN_ME_METH_ia64_512(void);
const BN_ME_METH *BN_ME_METH_ia64_1024(void);
#endif
#if (defined(CPU_SPARC_V8PLUS) || defined (CPU_SPARC_V9))
const BN_ME_METH *BN_ME_METH_usparc(void);
const BN_ME_METH *BN_ME_METH_usparc_352(void);
const BN_ME_METH *BN_ME_METH_usparc_512(void);
#endif
#if 1 || defined(CPU_X86)
const BN_ME_METH *BN_ME_METH_pentium4_29(void);
const BN_ME_METH *BN_ME_METH_pentium4_28(void);
#endif
/* NCipher Nfast hardware accelerator method prototype */
const BN_ME_METH *BN_ME_METH_nfast(void);
BIGNUM *BN_value_one(void);
const char * BN_options(void);
BN_CTX *BN_CTX_new(void);
void BN_CTX_init(BN_CTX *c);
void BN_CTX_free(BN_CTX *c);
#ifndef NO_BN_RAND
int BN_rand(BIGNUM *rnd, R_RANDOM *rand, int bits, int top,int bottom);
#endif
int BN_num_bits(BIGNUM *a);
int BN_num_bits_word(BN_ILONG);
BIGNUM *BN_new(void);
void BN_init(BIGNUM *);
void BN_clear_free(BIGNUM *a);
BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b);
BIGNUM *BN_bin2bn(unsigned char *s,int len,BIGNUM *ret);
int BN_bn2bin(BIGNUM *a, unsigned char *to);
BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret);
int BN_bn2mpi(BIGNUM *a, unsigned char *to);
int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b);
int BN_usub(BIGNUM *r, BIGNUM *a, BIGNUM *b);
int BN_uadd(BIGNUM *r, BIGNUM *a, BIGNUM *b);
int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx);
int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
int BN_mul_word(BIGNUM *a, BN_ULONG w);
int BN_add_word(BIGNUM *a, BN_ULONG w);
int BN_sub_word(BIGNUM *a, BN_ULONG w);
int BN_set_word(BIGNUM *a, BN_ULONG w);
BN_ULONG BN_get_word(BIGNUM *a);
int BN_cmp(BIGNUM *a, BIGNUM *b);
void BN_free(BIGNUM *a);
int BN_is_bit_set(BIGNUM *a, int n);
int BN_lshift(BIGNUM *r, BIGNUM *a, int n);
int BN_lshift1(BIGNUM *r, BIGNUM *a);
int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx);
int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx,
BN_MONT_CTX *m_ctx);
int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
BIGNUM *m,BN_CTX *ctx);
int BN_mask_bits(BIGNUM *a,int n);
int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m,
BN_CTX *ctx);
#if !defined(WIN16) && !defined(NO_FP_API)
int BN_print_fp(FILE *fp, BIGNUM *a);
#endif
#ifdef HEADER_COMMON_BIO_H
int BN_print(BIO *fp, BIGNUM *a);
#else
/* int BN_print(char *fp, BIGNUM *a); */
#endif
int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
int BN_rshift1(BIGNUM *r, BIGNUM *a);
void BN_clear(BIGNUM *a);
BIGNUM *bn_expand2(BIGNUM *b, int bits);
BIGNUM *BN_dup(BIGNUM *a);
int BN_ucmp(BIGNUM *a, BIGNUM *b);
int BN_set_bit(BIGNUM *a, int n);
int BN_clear_bit(BIGNUM *a, int n);
char * BN_bn2hex(BIGNUM *a);
char * BN_bn2dec(BIGNUM *a);
int BN_hex2bn(BIGNUM **a,char *str);
int BN_dec2bn(BIGNUM **a,char *str);
int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, BIGNUM *n,BN_CTX *ctx);
/* Return R, where it is R*(1<<BN_BITS2)% m == 1 */
BN_ULONG BN_mod_inverse_word(BN_ULONG m);
BIGNUM *BN_generate_prime(BN_PRIME_CTX *pctx,BIGNUM *ret,int bits);
int BN_is_prime(BN_PRIME_CTX *pctx,BIGNUM *p,int nchecks,BN_CTX *ctx);
void ERR_load_BN_strings(void );
BN_PRIME_CTX *BN_PRIME_CTX_new(void);
void BN_PRIME_CTX_init(BN_PRIME_CTX *pctx);
int BN_PRIME_CTX_setup(BN_PRIME_CTX *pctx, R_SURRENDER *surrender,
R_RANDOM *random, int num);
void BN_PRIME_CTX_free(BN_PRIME_CTX *pctx);
PRE_CCONV BN_ULONG CCONV bn_mul_add_words(BN_ULONG *rp,BN_ULONG *ap,
int num, BN_ULONG w);
PRE_CCONV BN_ULONG CCONV bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num,
BN_ULONG w);
PRE_CCONV void CCONV bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
BN_ULONG CCONV bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
PRE_CCONV BN_ULONG CCONV bn_add_words(BN_ULONG *rp, BN_ULONG *ap,
BN_ULONG *bp,int num);
PRE_CCONV BN_ULONG CCONV bn_sub_words(BN_ULONG *rp, BN_ULONG *ap,
BN_ULONG *bp,int num);
BN_MONT_CTX *BN_MONT_CTX_new(void );
void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
BN_CTX *ctx);
void BN_MONT_CTX_free(BN_MONT_CTX *mont);
/* int BN_MONT_CTX_set(BN_MONT_CTX *mont,BIGNUM *modulus,BN_CTX *ctx); */
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
int BN_MONT_CTX_set_full(BN_MONT_CTX *mont,BIGNUM *mod,BN_CTX *ctx);
void BN_set_params(int mul,int high,int low,int mont);
/* BN_get_params - which 0=mul, 1=high, 2=low, 3=mont */
int BN_get_params(int which);
void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
#if (defined(BN_MUL_COMBA) || defined(BN_SQR_COMBA))
PRE_CCONV void CCONV bn_mul_comba11(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
PRE_CCONV void CCONV bn_mul_comba6(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
#ifndef PLATFORM_HPUX_64
PRE_CCONV void CCONV bn_mul_comba16(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
#endif
PRE_CCONV void CCONV bn_sqr_comba11(BN_ULONG *r,BN_ULONG *a);
PRE_CCONV void CCONV bn_sqr_comba6(BN_ULONG *r,BN_ULONG *a);
#ifndef PLATFORM_HPUX_64
PRE_CCONV void CCONV bn_sqr_comba16(BN_ULONG *r,BN_ULONG *a);
#endif
#endif
PRE_CCONV void CCONV bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
PRE_CCONV void CCONV bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
PRE_CCONV void CCONV bn_sqr_comba8(BN_ULONG *r,BN_ULONG *a);
PRE_CCONV void CCONV bn_sqr_comba4(BN_ULONG *r,BN_ULONG *a);
int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
PRE_CCONV void r0_bn_mont_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *n,
int num,BN_ULONG n0);
PRE_CCONV void r0_bn_mont_comba6(BN_ULONG *r,BN_ULONG *a,BN_ULONG *n,
int num,BN_ULONG n0);
PRE_CCONV void r0_bn_mont_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *n,
int num,BN_ULONG n0);
PRE_CCONV void r0_bn_mont_comba11(BN_ULONG *r,BN_ULONG *a,BN_ULONG *n,
int num,BN_ULONG n0);
PRE_CCONV void r0_bn_mont_comba12(BN_ULONG *r,BN_ULONG *a,BN_ULONG *n,
int num,BN_ULONG n0);
PRE_CCONV void r0_bn_mont_comba16(BN_ULONG *r,BN_ULONG *a,BN_ULONG *n,
int num,BN_ULONG n0);
int bn_cmp_words(BN_ULONG *a,BN_ULONG *b,int n);
void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t);
void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
int tn, int n,BN_ULONG *t);
void bn_sqr_recursive(BN_ULONG *r,BN_ULONG *a, int n2, BN_ULONG *t);
void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
void BN_RECP_CTX_init(BN_RECP_CTX *recp);
BN_RECP_CTX *BN_RECP_CTX_new(void);
void BN_RECP_CTX_free(BN_RECP_CTX *recp);
int BN_RECP_CTX_set(BN_RECP_CTX *recp,BIGNUM *rdiv,BN_CTX *ctx);
int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
BN_RECP_CTX *recp,BN_CTX *ctx);
int BN_mod_exp_recp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx);
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
BN_RECP_CTX *recp, BN_CTX *ctx);
BN_ME_CTX *BN_ME_CTX_new(BN_ME_METH *meth,BN_ME_CTX **ret);
void BN_ME_CTX_free(BN_ME_CTX *ctx);
int BN_ME_CTX_set(BN_ME_CTX *mctx, BIGNUM *m, int cmd,int flags,BN_CTX *ctx);
char *BN_ME_CTX_name(BN_ME_CTX *ctx);
char *BN_ME_name(BN_ME_CTX *ctx);
int BN_ME_CTX_mod_exp( BN_ME_CTX *mctx, BIGNUM *ret, BIGNUM *a,
BIGNUM *p, BIGNUM *m, BN_CTX *ctx);
#if 0
int BN_ME_CTX_set_power(BN_ME_CTX *mctx,BIGNUM *p, int flags,BN_CTX *ctx);
int BN_ME_CTX_set_base( BN_ME_CTX *mctx, BIGNUM *b, int flags,BN_CTX *ctx);
#endif
int BN_gen_exp_bits(BIGNUM *p,unsigned char **strp,int flags,BN_CTX *ctx);
int BN_MONT_CTX_set_word(BN_MONT_CTX *mont,BIGNUM *mod,BN_CTX *ctx);
void bn_from_montgomery_words(BN_ULONG *ret,BN_ULONG *ap,BN_ULONG *np, int w,
BN_ULONG n0);
void bn_from_montgomery_full(BN_ULONG *ret,BN_ULONG *ap,BN_ULONG *np, int w,
BN_ULONG *nip,BN_ULONG *tmp);
void bn_mul_rec_words(BN_ULONG *rp,BN_ULONG *a,BN_ULONG *b,BN_ULONG *t,
BN_REC *rec);
void bn_sqr_rec_words(BN_ULONG *r,BN_ULONG *a,BN_ULONG *t,BN_REC *rec);
void bn_2s_comp(BN_ULONG *r,BN_ULONG *a, int n);
int BN_library_init(BN_ME_METH_INFO *);
int BN_default_init(void);
BN_ME_METH_INFO *BN_get_default_exp_table(void);
BN_ME_METH_INFO *BN_bnme_get_info(int index);
const BN_ME_METH * (*BN_bnme_get(int size,int flags))(void);
int BN_bnme_set(const BN_ME_METH *(*meth)(void), int min, int max, int flags);
void BN_bnme_clear(void);
int BN_bnme_delete(int index);
int BN_bnme_insert(const BN_ME_METH *(*meth)(void),int min,int max,int flagss,
int index);
void BN_BLIND_CTX_init(BN_BLIND_CTX *blind);
void BN_BLIND_CTX_free(BN_BLIND_CTX *blind);
int BN_BLIND_CTX_set(BN_BLIND_CTX *b_ctx, R_RANDOM *rand, BIGNUM *e,
BIGNUM *m,BN_ME_CTX *m_ctx, BN_CTX *ctx);
int BN_BLIND_CTX_convert(BN_BLIND_CTX *b, BIGNUM *a,BN_CTX *ctx);
int BN_BLIND_CTX_invert(BN_BLIND_CTX *b, BIGNUM *a, BN_CTX *ctx);
int BN_BLIND_CTX_update(BN_BLIND_CTX *b, BN_CTX *ctx);
int BN_BLIND_CTX_copy(BN_BLIND_CTX *b1, BN_BLIND_CTX *b2);
BN_BLIND_METH *BN_BLIND_METH_blinding();
#else
BIGNUM *BN_value_one();
const char * BN_options();
BN_CTX *BN_CTX_new();
void BN_CTX_init();
void BN_CTX_free();
#ifndef NO_BN_RAND
int BN_rand();
#endif
int BN_num_bits();
int BN_num_bits_word();
BIGNUM *BN_new();
void BN_init();
void BN_clear_free();
BIGNUM *BN_copy();
BIGNUM *BN_bin2bn();
int BN_bn2bin();
BIGNUM *BN_mpi2bn();
int BN_bn2mpi();
int BN_sub();
int BN_usub();
int BN_uadd();
int BN_add();
int BN_mod();
int BN_div();
int BN_mul();
int BN_sqr();
BN_ULONG BN_mod_word();
BN_ULONG BN_div_word();
int BN_add_word();
int BN_sub_word();
int BN_mul_word();
int BN_set_word();
unsigned long BN_get_word();
int BN_cmp();
void BN_free();
int BN_is_bit_set();
int BN_lshift();
int BN_lshift1();
int BN_exp();
int BN_mod_exp();
int BN_mod_exp_mont();
int BN_mod_exp_recp();
int BN_mod_exp_simple();
int BN_mask_bits();
int BN_mod_mul_reciprocal();
int BN_mod_mul();
#ifndef WIN16
int BN_print_fp();
#endif
int BN_print();
int BN_reciprocal();
int BN_rshift();
int BN_rshift1();
void BN_clear();
BIGNUM *bn_expand2();
BIGNUM *BN_dup();
int BN_ucmp();
int BN_set_bit();
int BN_clear_bit();
char * BN_bn2hex();
char * BN_bn2dec();
int BN_hex2bn();
int BN_dec2bn();
int BN_gcd();
BIGNUM *BN_mod_inverse();
BIGNUM *BN_generate_prime();
int BN_is_prime();
void ERR_load_BN_strings();
PRE_CCONV BN_ULONG CCONV bn_mul_add_words();
PRE_CCONV BN_ULONG CCONV bn_mul_words();
PRE_CCONV void CCONV bn_sqr_words();
BN_ULONG bn_div_words();
PRE_CCONV BN_ULONG CCONV bn_add_words();
PRE_CCONV BN_ULONG CCONV bn_sub_words();
int BN_mod_mul_montgomery();
int BN_from_montgomery();
BN_MONT_CTX *BN_MONT_CTX_new();
void BN_MONT_CTX_init();
void BN_MONT_CTX_free();
int BN_MONT_CTX_set();
void bn_mul_normal();
PRE_CCONV void bn_mul_comba8();
PRE_CCONV void bn_mul_comba4();
void bn_sqr_normal();
PRE_CCONV void bn_sqr_comba8();
PRE_CCONV void bn_sqr_comba4();
int bn_cmp_words();
void bn_mul_recursive();
void bn_mul_part_recursive();
void bn_sqr_recursive();
void bn_mul_low_normal();
void BN_RECP_CTX_init();
BN_RECP_CTX *BN_RECP_CTX_new();
void BN_RECP_CTX_free();
int BN_RECP_CTX_set();
int BN_mod_mul_reciprocal();
int BN_mod_exp_recp();
int BN_div_recp();
int BN_library_init();
int BN_library_init_small();
int BN_default_init();
BN_ME_METH_INFO *BN_get_default_exp_table();
BN_ME_METH_INFO *BN_bnme_get_info();
const BN_ME_METH * (*BN_bnme_get())();
int BN_bnme_set();
void BN_bnme_clear();
int BN_bnme_delete();
int BN_bnme_insert();
#endif
#ifdef CPU_TMS320
#define BN_ME_METH_DEFAULT BN_ME_METH_dspc
#else
#define BN_ME_METH_DEFAULT BN_ME_METH_word
#endif
/* BEGIN ERROR CODES */
/* Error codes for the BN functions. */
/* Function codes. */
#define BN_F_BN_BN2DEC 100
#define BN_F_BN_BN2HEX 101
#define BN_F_BN_CTX_NEW 102
#define BN_F_BN_DIV 103
#define BN_F_BN_DIV_RECP 104
#define BN_F_BN_EXPAND2 105
#define BN_F_BN_MOD_EXP2_MONT 106
#define BN_F_BN_MOD_EXP_MONT 107
#define BN_F_BN_MOD_INVERSE 108
#define BN_F_BN_MPI2BN 109
#define BN_F_BN_NEW 110
#define BN_F_BN_RAND 111
#define BN_F_BN_USUB 112
/* Reason codes. */
#define BN_R_ARG2_LT_ARG3 100
#define BN_R_BAD_RECIPROCAL 101
#define BN_R_CALLED_WITH_EVEN_MODULUS 102
#define BN_R_DIV_BY_ZERO 103
#define BN_R_ENCODING_ERROR 104
#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105
#define BN_R_INVALID_LENGTH 106
#define BN_R_NO_INVERSE 122
#ifdef __cplusplus
}
#endif
#endif /* HEADER_COMMON_BN_H */