зеркало из https://github.com/github/putty.git
Move BignumInt definitions into a header file.
This allows files other than sshbn.c to work with the primitives necessary to build multi-word arithmetic functions satisfying all of PuTTY's portability constraints.
This commit is contained in:
Родитель
d0c74a115a
Коммит
2c60070aad
85
sshbn.c
85
sshbn.c
|
@ -11,90 +11,7 @@
|
|||
|
||||
#include "misc.h"
|
||||
|
||||
/*
|
||||
* Usage notes:
|
||||
* * Do not call the DIVMOD_WORD macro with expressions such as array
|
||||
* subscripts, as some implementations object to this (see below).
|
||||
* * Note that none of the division methods below will cope if the
|
||||
* quotient won't fit into BIGNUM_INT_BITS. Callers should be careful
|
||||
* to avoid this case.
|
||||
* If this condition occurs, in the case of the x86 DIV instruction,
|
||||
* an overflow exception will occur, which (according to a correspondent)
|
||||
* will manifest on Windows as something like
|
||||
* 0xC0000095: Integer overflow
|
||||
* The C variant won't give the right answer, either.
|
||||
*/
|
||||
|
||||
#if defined __GNUC__ && defined __i386__
|
||||
typedef unsigned long BignumInt;
|
||||
typedef unsigned long long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFUL
|
||||
#define BIGNUM_TOP_BIT 0x80000000UL
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) \
|
||||
__asm__("div %2" : \
|
||||
"=d" (r), "=a" (q) : \
|
||||
"r" (w), "d" (hi), "a" (lo))
|
||||
#elif defined _MSC_VER && defined _M_IX86
|
||||
typedef unsigned __int32 BignumInt;
|
||||
typedef unsigned __int64 BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFUL
|
||||
#define BIGNUM_TOP_BIT 0x80000000UL
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
/* Note: MASM interprets array subscripts in the macro arguments as
|
||||
* assembler syntax, which gives the wrong answer. Don't supply them.
|
||||
* <http://msdn2.microsoft.com/en-us/library/bf1dw62z.aspx> */
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
__asm mov edx, hi \
|
||||
__asm mov eax, lo \
|
||||
__asm div w \
|
||||
__asm mov r, edx \
|
||||
__asm mov q, eax \
|
||||
} while(0)
|
||||
#elif defined _LP64
|
||||
/* 64-bit architectures can do 32x32->64 chunks at a time */
|
||||
typedef unsigned int BignumInt;
|
||||
typedef unsigned long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFU
|
||||
#define BIGNUM_TOP_BIT 0x80000000U
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
|
||||
q = n / w; \
|
||||
r = n % w; \
|
||||
} while (0)
|
||||
#elif defined _LLP64
|
||||
/* 64-bit architectures in which unsigned long is 32 bits, not 64 */
|
||||
typedef unsigned long BignumInt;
|
||||
typedef unsigned long long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFUL
|
||||
#define BIGNUM_TOP_BIT 0x80000000UL
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
|
||||
q = n / w; \
|
||||
r = n % w; \
|
||||
} while (0)
|
||||
#else
|
||||
/* Fallback for all other cases */
|
||||
typedef unsigned short BignumInt;
|
||||
typedef unsigned long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFU
|
||||
#define BIGNUM_TOP_BIT 0x8000U
|
||||
#define BIGNUM_INT_BITS 16
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
|
||||
q = n / w; \
|
||||
r = n % w; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8)
|
||||
#include "sshbn.h"
|
||||
|
||||
#define BIGNUM_INTERNAL
|
||||
typedef BignumInt *Bignum;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* sshbn.h: the assorted conditional definitions of BignumInt and
|
||||
* multiply/divide macros used throughout the bignum code to treat
|
||||
* numbers as arrays of the most conveniently sized word for the
|
||||
* target machine. Exported so that other code (e.g. poly1305) can use
|
||||
* it too.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Usage notes:
|
||||
* * Do not call the DIVMOD_WORD macro with expressions such as array
|
||||
* subscripts, as some implementations object to this (see below).
|
||||
* * Note that none of the division methods below will cope if the
|
||||
* quotient won't fit into BIGNUM_INT_BITS. Callers should be careful
|
||||
* to avoid this case.
|
||||
* If this condition occurs, in the case of the x86 DIV instruction,
|
||||
* an overflow exception will occur, which (according to a correspondent)
|
||||
* will manifest on Windows as something like
|
||||
* 0xC0000095: Integer overflow
|
||||
* The C variant won't give the right answer, either.
|
||||
*/
|
||||
|
||||
#if defined __GNUC__ && defined __i386__
|
||||
typedef unsigned long BignumInt;
|
||||
typedef unsigned long long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFUL
|
||||
#define BIGNUM_TOP_BIT 0x80000000UL
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) \
|
||||
__asm__("div %2" : \
|
||||
"=d" (r), "=a" (q) : \
|
||||
"r" (w), "d" (hi), "a" (lo))
|
||||
#elif defined _MSC_VER && defined _M_IX86
|
||||
typedef unsigned __int32 BignumInt;
|
||||
typedef unsigned __int64 BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFUL
|
||||
#define BIGNUM_TOP_BIT 0x80000000UL
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
/* Note: MASM interprets array subscripts in the macro arguments as
|
||||
* assembler syntax, which gives the wrong answer. Don't supply them.
|
||||
* <http://msdn2.microsoft.com/en-us/library/bf1dw62z.aspx> */
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
__asm mov edx, hi \
|
||||
__asm mov eax, lo \
|
||||
__asm div w \
|
||||
__asm mov r, edx \
|
||||
__asm mov q, eax \
|
||||
} while(0)
|
||||
#elif defined _LP64
|
||||
/* 64-bit architectures can do 32x32->64 chunks at a time */
|
||||
typedef unsigned int BignumInt;
|
||||
typedef unsigned long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFU
|
||||
#define BIGNUM_TOP_BIT 0x80000000U
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
|
||||
q = n / w; \
|
||||
r = n % w; \
|
||||
} while (0)
|
||||
#elif defined _LLP64
|
||||
/* 64-bit architectures in which unsigned long is 32 bits, not 64 */
|
||||
typedef unsigned long BignumInt;
|
||||
typedef unsigned long long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFFFFFUL
|
||||
#define BIGNUM_TOP_BIT 0x80000000UL
|
||||
#define BIGNUM_INT_BITS 32
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
|
||||
q = n / w; \
|
||||
r = n % w; \
|
||||
} while (0)
|
||||
#else
|
||||
/* Fallback for all other cases */
|
||||
typedef unsigned short BignumInt;
|
||||
typedef unsigned long BignumDblInt;
|
||||
#define BIGNUM_INT_MASK 0xFFFFU
|
||||
#define BIGNUM_TOP_BIT 0x8000U
|
||||
#define BIGNUM_INT_BITS 16
|
||||
#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
|
||||
#define DIVMOD_WORD(q, r, hi, lo, w) do { \
|
||||
BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
|
||||
q = n / w; \
|
||||
r = n % w; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8)
|
Загрузка…
Ссылка в новой задаче