first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantDebug.c - debugging support
|
||||
*
|
||||
* Created Aug. 5 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#include <libGiants/giantDebug.h>
|
||||
#include <libGiants/giantTypes.h>
|
||||
|
||||
#if GIANTS_DEBUG
|
||||
|
||||
void GIRaise(const char *str)
|
||||
{
|
||||
printf("Fatal libGiants library error: %s\n", str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* GIANTS_DEBUG */
|
||||
|
||||
#if GI_STACK_DEBUG
|
||||
|
||||
void *gInitSp;
|
||||
void *giLowestSp;
|
||||
|
||||
void GI_SET_INIT_SP(void)
|
||||
{
|
||||
gInitSp = GI_GET_SP();
|
||||
giLowestSp = NULL;
|
||||
}
|
||||
|
||||
#ifdef __ppc__
|
||||
|
||||
|
||||
void *GI_GET_SP(void)
|
||||
{
|
||||
void *currsp;
|
||||
asm("mr %0,r1" : "=r"(currsp) : );
|
||||
return currsp;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef __i386__
|
||||
void *GI_GET_SP(void)
|
||||
{
|
||||
register void *sp __asm__("esp");
|
||||
return sp;
|
||||
}
|
||||
#else
|
||||
#ifdef __arm__
|
||||
void *GI_GET_SP(void)
|
||||
{
|
||||
register void *sp __asm__("r13");
|
||||
return sp;
|
||||
}
|
||||
#else
|
||||
#error Need a platform-dependent GI_GET_SP()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif /* GI_STACK_DEBUG */
|
||||
@@ -0,0 +1,101 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantDebug.h - debugging support.
|
||||
*
|
||||
* Created Aug. 5 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#ifndef _GIANT_DEBUG_H_
|
||||
#define _GIANT_DEBUG_H_
|
||||
|
||||
#include <libGiants/giantPlatform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef GIANTS_DEBUG
|
||||
/* Should be defined in giantPlatform.h */
|
||||
#error Please defgine GIANTS_DEBUG.
|
||||
#endif
|
||||
|
||||
#if GIANTS_DEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define dbgLog(str) printf(str)
|
||||
|
||||
#define GIASSERT(s) assert(s)
|
||||
|
||||
#else /* GIANTS_DEBUG */
|
||||
|
||||
#define dbgLog(str)
|
||||
|
||||
#define GIASSERT(s)
|
||||
|
||||
#endif /* GIANTS_DEBUG */
|
||||
|
||||
#undef NULL
|
||||
#define NULL ((void *)0)
|
||||
|
||||
#if GIANTS_DEBUG
|
||||
void GIRaise(const char *str) __attribute((noreturn));
|
||||
#else
|
||||
#define GIRaise(s)
|
||||
#endif
|
||||
|
||||
/* detect overflow og giant->n[] */
|
||||
#define CHECK_GIANT_OFLOW(g) GIASSERT((g)->sign <= (g)->capacity)
|
||||
|
||||
/* stack analysis support */
|
||||
#if GI_STACK_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern void *gInitSp;
|
||||
extern void *giLowestSp;
|
||||
|
||||
extern void GI_SET_INIT_SP(void);
|
||||
extern void *GI_GET_SP(void);
|
||||
|
||||
static inline void GI_CHECK_SP(const char *fcn)
|
||||
{
|
||||
void *currSp = GI_GET_SP();
|
||||
if((giLowestSp == NULL) || (currSp < giLowestSp)) {
|
||||
giLowestSp = currSp;
|
||||
printf("%s: new min sp %p; stack used %d\n", fcn,
|
||||
giLowestSp,
|
||||
gInitSp ? (gInitSp - giLowestSp) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* this does some fine-grain stack logging regardless of giLowestSp */
|
||||
#if GI_STACK_LOG
|
||||
static inline void GI_LOG_SP(const char *fcn)
|
||||
{
|
||||
void *currSp = GI_GET_SP();
|
||||
printf("%s: sp %p; stack used %d\n",
|
||||
fcn, currSp,
|
||||
gInitSp ? (gInitSp - currSp) : 0);
|
||||
}
|
||||
#else
|
||||
#define GI_LOG_SP(fcn)
|
||||
#endif /* GI_STACK_LOG */
|
||||
#else /* GI_STACK_DEBUG */
|
||||
|
||||
#define GI_SET_INIT_SP()
|
||||
#define GI_GET_SP()
|
||||
#define GI_CHECK_SP(fcn)
|
||||
#define GI_LOG_SP(fcn)
|
||||
|
||||
#endif /* GI_STACK_DEBUG */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GIANT_DEBUG_H_ */
|
||||
@@ -0,0 +1,191 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantExternal.c - convert between giant integer and external representation
|
||||
*
|
||||
* Created Aug. 5 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#include <libGiants/giantTypes.h>
|
||||
#include <libGiants/giantExternal.h>
|
||||
#include <libGiants/giantDebug.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Precalculate actual size in bytes needed to serialize a given giant.
|
||||
*/
|
||||
gi_uint16 serializeGiantBytes(const giant g)
|
||||
{
|
||||
gi_size numDigits, numZeros, digitByte;
|
||||
giantDigit digit;
|
||||
|
||||
gtrimSign(g);
|
||||
numDigits = g->sign;
|
||||
if(numDigits == 0) {
|
||||
return 0;
|
||||
}
|
||||
/* Count the number of leading 0 bytes in the m.s. digit. */
|
||||
numZeros = 0;
|
||||
digit = g->n[numDigits - 1];
|
||||
for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
|
||||
/* one loop per byte in the digit */
|
||||
gi_uint8 byte = (gi_uint8)digit;
|
||||
digit >>= 8;
|
||||
if (byte) {
|
||||
numZeros = 0;
|
||||
} else {
|
||||
numZeros++;
|
||||
}
|
||||
}
|
||||
return (numDigits * GIANT_BYTES_PER_DIGIT) - numZeros;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize, deserialize giants's n[] to/from byte stream.
|
||||
* First byte of byte stream is the m.s. byte of the resulting giant,
|
||||
* regardless of the size of giantDigit.
|
||||
*
|
||||
* No assumption is made about the alignment of cp.
|
||||
*
|
||||
* The numBytes argument indicates the space available on input;
|
||||
* on return it indicates the actual number of bytes written.
|
||||
*/
|
||||
GIReturn serializeGiant(
|
||||
const giant g,
|
||||
gi_uint8 *cp,
|
||||
gi_uint16 *numBytes) /* IN/OUT */
|
||||
{
|
||||
gi_size digitDex, numDigits, digitByte, totalBytes, bytesLeft;
|
||||
gi_uint8 *currCp;
|
||||
giantDigit digit;
|
||||
|
||||
GI_CHECK_SP("serializeGiant");
|
||||
if((g == NULL) || (cp == NULL) || (numBytes == NULL)) {
|
||||
return GR_IllegalArg;
|
||||
}
|
||||
totalBytes = serializeGiantBytes(g);
|
||||
if(totalBytes == 0) {
|
||||
*numBytes = 0;
|
||||
return GR_Success;
|
||||
}
|
||||
numDigits = g->sign;
|
||||
if(totalBytes > *numBytes) {
|
||||
dbgLog("serializeGiant: Insufficient space\n");
|
||||
return GR_Overflow;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit bytes starting at the far end of the outgoing byte
|
||||
* stream, which is the l.s. byte of giant data. In order to prevent
|
||||
* writing out leading zeros, we special case the m.s. digit.
|
||||
*/
|
||||
currCp = cp + totalBytes - 1;
|
||||
for(digitDex=0; digitDex<numDigits - 1; digitDex++) {
|
||||
/* one loop per giant digit */
|
||||
digit = g->n[digitDex];
|
||||
|
||||
for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
|
||||
/* one loop per byte in the digit */
|
||||
*currCp-- = (gi_uint8)digit;
|
||||
digit >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle the m.s. digit, by writing out only as many bytes as are left.
|
||||
Since we already wrote out numDigits - 1 digits above the answer is: */
|
||||
bytesLeft = totalBytes - (numDigits - 1) * GIANT_BYTES_PER_DIGIT;
|
||||
digit = g->n[digitDex];
|
||||
for(digitByte=0; digitByte<bytesLeft; digitByte++) {
|
||||
/* one loop per byte in the digit */
|
||||
*currCp-- = (gi_uint8)digit;
|
||||
digit >>= 8;
|
||||
}
|
||||
|
||||
*numBytes = totalBytes;
|
||||
return GR_Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a giant with specified data. Does not have to be
|
||||
* aligned to giantDigits (as the output of serializeGiant() always
|
||||
* is).
|
||||
*/
|
||||
GIReturn deserializeGiant(
|
||||
giant g,
|
||||
const gi_uint8 *cp,
|
||||
gi_uint16 numBytes)
|
||||
{
|
||||
gi_size numDigits;
|
||||
giantDigit digit;
|
||||
giantDigit tempDigit;
|
||||
gi_size digitDex;
|
||||
gi_size digitByte;
|
||||
gi_size dex;
|
||||
const gi_uint8 *currCp;
|
||||
|
||||
GI_CHECK_SP("deserializeGiant");
|
||||
if(g == NULL) {
|
||||
return GR_IllegalArg;
|
||||
}
|
||||
if(numBytes == 0) {
|
||||
g->sign = 0;
|
||||
return GR_Success;
|
||||
}
|
||||
if(cp == NULL) {
|
||||
return GR_IllegalArg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Trim off leading zeroes, sometimes placed there during DER
|
||||
* encoding to ensure the number does not appear negative. We
|
||||
* don't support negative numbers in this module...
|
||||
*/
|
||||
|
||||
while((*cp == 0) && (numBytes != 0)) {
|
||||
cp++;
|
||||
numBytes--;
|
||||
}
|
||||
if(numBytes == 0) {
|
||||
g->sign = 0;
|
||||
return GR_Success;
|
||||
}
|
||||
|
||||
numDigits = BYTES_TO_GIANT_DIGITS(numBytes);
|
||||
if(numDigits > g->capacity) {
|
||||
return GR_Overflow;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start at l.s. byte, at the far end of the byte stream.
|
||||
*/
|
||||
digitDex = 0; /* index into g->n[] */
|
||||
digit = 0; /* accumulator */
|
||||
digitByte = 0; /* byte index into digit */
|
||||
currCp = cp + numBytes - 1;
|
||||
|
||||
for(dex=0; dex<numBytes; dex++) {
|
||||
/* add in current byte */
|
||||
tempDigit = *currCp--;
|
||||
tempDigit <<= (8 * digitByte);
|
||||
digit |= tempDigit;
|
||||
digitByte++;
|
||||
|
||||
/* have a complete digit, or reached the last byte? */
|
||||
if((digitByte == GIANT_BYTES_PER_DIGIT) || /* full digit */
|
||||
(dex == (numBytes - 1))) { /* no more data */
|
||||
g->n[digitDex++] = digit;
|
||||
|
||||
/* reset for next digit */
|
||||
digit = 0;
|
||||
digitByte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Infer sign/size from non-zero n[] elements
|
||||
*/
|
||||
g->sign = numDigits;
|
||||
gtrimSign(g);
|
||||
return GR_Success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantExternal.h - convert between giant integer and external representation
|
||||
*
|
||||
* Created Aug. 5 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#ifndef _GIANT_EXTERNAL_H_
|
||||
#define _GIANT_EXTERNAL_H_
|
||||
|
||||
#include <libGiants/giantIntegers.h>
|
||||
#include <libGiants/giantTypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Max size in bytes needed to serialize a giant of given number of digits.
|
||||
*/
|
||||
#define MAX_SERIALIZED_GIANT_SIZE(digits) (GIANT_BYTES_PER_DIGIT * digits)
|
||||
|
||||
/*
|
||||
* Precalculate actual size in bytes needed to serialize a given giant.
|
||||
*/
|
||||
gi_uint16 serializeGiantBytes(const giant g);
|
||||
|
||||
/*
|
||||
* serialize, deserialize giants's n[] to/from byte stream.
|
||||
* First byte of byte stream is the m.s. byte of the resulting giant,
|
||||
* regardless of the size of giantDigit. The resulting byte stream
|
||||
* is suitable for use as the content of a DER-encoded integer.
|
||||
*
|
||||
* No assumption is made about the alignment of cp.
|
||||
*
|
||||
* The numBytes argument indicates the space available on input;
|
||||
* on return it indicates the actual number of bytes written.
|
||||
*/
|
||||
GIReturn serializeGiant(
|
||||
const giant g,
|
||||
gi_uint8 *cp,
|
||||
gi_uint16 *numBytes); /* IN/OUT */
|
||||
|
||||
/*
|
||||
* Initialize a giant with specified data, which may well have come from
|
||||
* serializeGiant.
|
||||
*/
|
||||
GIReturn deserializeGiant(
|
||||
giant g,
|
||||
const gi_uint8 *cp,
|
||||
gi_uint16 numBytes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GIANT_EXTERNAL_H_ */
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,286 @@
|
||||
/* Copyright (c) 1998-2007 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
|
||||
* TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
|
||||
* SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
|
||||
* ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
|
||||
* INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
|
||||
* EXPOSE YOU TO LIABILITY.
|
||||
***************************************************************************
|
||||
*
|
||||
* giantIntegers.h - large-integer arithmetic library.
|
||||
*/
|
||||
|
||||
#ifndef _GI_GIANTINTEGERS_H_
|
||||
#define _GI_GIANTINTEGERS_H_
|
||||
|
||||
#include <libGiants/giantTypes.h>
|
||||
#include <libGiants/giantDebug.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* platform-independent digit manipulation macros */
|
||||
|
||||
#define GIANT_BYTES_PER_DIGIT (sizeof(giantDigit))
|
||||
#define GIANT_BITS_PER_DIGIT (8 * GIANT_BYTES_PER_DIGIT)
|
||||
#define GIANT_DIGIT_MASK ((giantDigit)~0)
|
||||
#define BYTES_TO_GIANT_DIGITS(x) \
|
||||
((x + GIANT_BYTES_PER_DIGIT - 1) / GIANT_BYTES_PER_DIGIT)
|
||||
|
||||
|
||||
/*
|
||||
* Static giant support; giantstruct->n[] no longer dynamically allocated, but
|
||||
* hard-coded to the max needed for a particular implementation. This max size
|
||||
* is a function of the prime size (easy to determine) and the max size of
|
||||
* giant, in digits relative to the size of the prime, actually needed for the
|
||||
* math implemented in this library (which is going to be tricky to accurately
|
||||
* determine). We want to minimize the static size of a giant in order to
|
||||
* minimize RAM usage.
|
||||
*/
|
||||
|
||||
#ifndef GI_MAX_PRIME_SIZE_BITS
|
||||
#error Please #define GI_MAX_PRIME_SIZE_BITS.
|
||||
#endif
|
||||
|
||||
/* convert that to bytes and digits; these remain fixed */
|
||||
#define MAX_PRIME_SIZE_BYTES ((GI_MAX_PRIME_SIZE_BITS + 7) / 8)
|
||||
#define MAX_PRIME_SIZE_DIGITS BYTES_TO_GIANT_DIGITS(MAX_PRIME_SIZE_BYTES)
|
||||
|
||||
/*
|
||||
* The number of digits in a minimal giant, requiring only extra space for
|
||||
* an add.
|
||||
*/
|
||||
#define GIANT_LITTLE_DIGITS (MAX_PRIME_SIZE_DIGITS + 1)
|
||||
|
||||
/*
|
||||
* The number of digits in a max giant, used for mulg and its kin.
|
||||
*/
|
||||
#define GIANT_BIG_DIGITS (MAX_PRIME_SIZE_DIGITS * 2)
|
||||
|
||||
/*
|
||||
* The number of digits in a "triple giant", used sparingly in and
|
||||
* around make_recip and modg_via_recip only.
|
||||
* The max observed required size seems to be when doing a mulg on
|
||||
* two numbers, both of whose signs are s+1.
|
||||
*/
|
||||
#define GIANT_TRIPLE_DIGITS ((MAX_PRIME_SIZE_DIGITS * 2) + 2)
|
||||
|
||||
/* Basic giant type with giantDigit array allocated elsewhere */
|
||||
typedef struct {
|
||||
gi_uint16 sign; /* number of giantDigits */
|
||||
gi_uint16 capacity; /* largest possible number of giantDigits */
|
||||
giantDigit *n; /* n[0] is l.s. digit */
|
||||
} giantStruct;
|
||||
|
||||
typedef giantStruct *giant;
|
||||
|
||||
/*
|
||||
* Giant capable of being allocated on the stack, with capacity
|
||||
* no greater than GIANT_LITTLE_DIGITS, i.e., a "little giant" or
|
||||
* lGiant in the SFEE paper.
|
||||
*
|
||||
* Use base giantstruct g in any function call requiring a giant.
|
||||
*/
|
||||
typedef struct {
|
||||
giantStruct g;
|
||||
giantDigit _n_[GIANT_LITTLE_DIGITS];
|
||||
} lgiant;
|
||||
|
||||
/*
|
||||
* "Big giant" "subclass" of standard giant. Use base giantstruct g in
|
||||
* any function call requiring a giant.
|
||||
*/
|
||||
typedef struct {
|
||||
giantStruct g;
|
||||
giantDigit _n_[GIANT_BIG_DIGITS];
|
||||
} bigGiantStruct;
|
||||
|
||||
typedef bigGiantStruct bgiant; /* for heap allocation */
|
||||
|
||||
/*
|
||||
* "Triple giant" "subclass" of standard giant. Used sparingly in and
|
||||
* around make_recip only.
|
||||
|
||||
*/
|
||||
typedef struct {
|
||||
giantStruct g;
|
||||
giantDigit _n_[GIANT_TRIPLE_DIGITS];
|
||||
} tripleGiantStruct;
|
||||
|
||||
typedef tripleGiantStruct tgiant;
|
||||
|
||||
gi_uint16 bitlen(giant n); /* Returns the bit-length n;
|
||||
* e.g. n=7 returns 3. */
|
||||
giantDigit bitval(giant n, gi_uint16 pos);
|
||||
gi_uint16 giantNumBytes(giant n);
|
||||
void gtog(giant src, giant dest); /* Copies one giant to another */
|
||||
void int_to_giant(gi_uint32 n, giant g); /* Gives a giant an int value */
|
||||
GIReturn giant_to_int(giant g, gi_uint32 *i); /* Convent giant to int. */
|
||||
gi_uint16 numtrailzeros(giant g); /* # of trailing zero bits in g */
|
||||
int gcompg(giant a, giant b); /* Returns 1, 0, -1 as a>b, a=b, a<b */
|
||||
void normal_addg(giant a, giant b); /* b += a */
|
||||
#define addg(a, b) normal_addg(a, b)
|
||||
|
||||
void iaddg(giantDigit a, giant b); /* b += a */
|
||||
void imulg(giantDigit a, giant b); /* b *= a */
|
||||
void normal_subg(giant a, giant b); /* b -= a. */
|
||||
void gshiftleft(gi_uint16 bits, giant g); /* Shift g left by bits, introducing
|
||||
* zeros on the right. */
|
||||
void gshiftright(gi_uint16 bits, giant g); /* Shift g right by bits, losing bits
|
||||
* on the right. */
|
||||
// Right-shift z by s giantDigits
|
||||
void gshifltwordsright(gi_uint16 digits, giant g);
|
||||
// shift left by s giantDigits
|
||||
void gshiftwordsleft(gi_uint16 digits, giant g);
|
||||
|
||||
void extractbits(gi_uint16 n, giant src, giant dest);
|
||||
/* dest becomes lowermost n bits of
|
||||
* src. Equivalent to
|
||||
* dest = src % 2^n */
|
||||
|
||||
void grammarSquare(giant a); /* g *= g. */
|
||||
void grammarSquare_common(giant a, giant dest);
|
||||
/* dest := (a * a)
|
||||
* dest is typically a bgiant */
|
||||
|
||||
#define gsquare(g) grammarSquare(g)
|
||||
|
||||
void mulg(giant a, giant b); /* b *= a. */
|
||||
void mulg_common(giant a, giant b, giant dest);
|
||||
/* dest := a * b;
|
||||
* dest is typically a bgiant */
|
||||
void gtrimSign(giant g); /* Adjust sign for possible leading
|
||||
* (m.s.) zero digits */
|
||||
|
||||
void clearGiant(giant g); /* zero a giant's data */
|
||||
|
||||
/* converted from trivial functions */
|
||||
|
||||
#if GIANTS_DEBUG
|
||||
/*
|
||||
* counter, acccumulates calls to (giantDigit x giantDigit) multiply.
|
||||
*/
|
||||
extern unsigned numGiantDigitMuls;
|
||||
#define INCR_DIGIT_MULS numGiantDigitMuls++
|
||||
|
||||
/*
|
||||
* Accumulate calls to mulg_common()
|
||||
*/
|
||||
extern unsigned numMulgCommon;
|
||||
#define INCR_NUM_MULGS numMulgCommon++;
|
||||
|
||||
/*
|
||||
* Accumulate calls to grammarSquare_common()
|
||||
*/
|
||||
extern unsigned numGSquareCommon;
|
||||
#define INCR_NUM_GSQUARE numGSquareCommon++;
|
||||
|
||||
|
||||
#else /* GIANTS_DEBUG */
|
||||
|
||||
#define INCR_DIGIT_MULS
|
||||
#define INCR_NUM_MULGS
|
||||
#define INCR_NUM_GSQUARE
|
||||
|
||||
#endif /* GIANTS_DEBUG */
|
||||
|
||||
/*
|
||||
* Functions which can be explicit C functions, macros, or static inlines
|
||||
* depending on the configuration.
|
||||
*/
|
||||
#if !defined(GI_INLINE_SMALL_FUNCS) && !defined(GI_MACRO_SMALL_FUNCTIONS)
|
||||
#error Please define GI_INLINE_SMALL_FUNCS and GI_MACRO_SMALL_FUNCTIONS.
|
||||
#endif
|
||||
|
||||
#if GI_INLINE_SMALL_FUNCS && GI_MACRO_SMALL_FUNCTIONS
|
||||
#error GI_INLINE_SMALL_FUNCS and GI_MACRO_SMALL_FUNCTIONS are mutually exclusive.
|
||||
#endif
|
||||
|
||||
#if GI_INLINE_SMALL_FUNCS
|
||||
|
||||
/* common giant init */
|
||||
static GI_INLINE void initGiant(
|
||||
giant g,
|
||||
gi_uint16 capacity,
|
||||
giantDigit *digits)
|
||||
{
|
||||
g->sign = 0;
|
||||
g->capacity = capacity;
|
||||
g->n = digits;
|
||||
}
|
||||
|
||||
/* call this after declaring a local lgiant and before using it */
|
||||
static GI_INLINE void localGiantAlloc(lgiant *g)
|
||||
{
|
||||
initGiant(&g->g, GIANT_LITTLE_DIGITS, g->_n_);
|
||||
}
|
||||
|
||||
/* ditto, for a bgiant */
|
||||
static GI_INLINE void localBigGiantAlloc(bgiant *g)
|
||||
{
|
||||
initGiant(&g->g, GIANT_BIG_DIGITS, g->_n_);
|
||||
}
|
||||
|
||||
/* ditto, for a tgiant */
|
||||
static GI_INLINE void localTriGiantAlloc(tgiant *g)
|
||||
{
|
||||
initGiant(&g->g, GIANT_TRIPLE_DIGITS, g->_n_);
|
||||
}
|
||||
|
||||
/* Returns whether g is 1 */
|
||||
static GI_INLINE int isone(giant g)
|
||||
{
|
||||
return ((g->sign == 1) && (g->n[0] == 1));
|
||||
}
|
||||
|
||||
/* Returns whether g is zero */
|
||||
static GI_INLINE int isZero(giant g)
|
||||
{
|
||||
/* we're skipping the !trimmed check here... */
|
||||
return (g->sign == 0);
|
||||
}
|
||||
|
||||
#elif GI_MACRO_SMALL_FUNCTIONS
|
||||
|
||||
#define initGiant(gnt, cap, digs) \
|
||||
(gnt)->sign = 0; \
|
||||
(gnt)->capacity = cap; \
|
||||
(gnt)->n = digs;
|
||||
|
||||
#define localGiantAlloc(lg) initGiant(&((lg)->g), GIANT_LITTLE_DIGITS, (lg)->_n_)
|
||||
#define localBigGiantAlloc(bg) initGiant(&((bg)->g), GIANT_BIG_DIGITS, (bg)->_n_)
|
||||
#define localTriGiantAlloc(tg) initGiant(&((tg)->g), GIANT_TRIPLE_DIGITS, (tg)->_n_)
|
||||
|
||||
#define isone(g) (((g)->sign == 1) && ((g)->n[0] == 1))
|
||||
#define isZero(g) ((g)->sign == 0)
|
||||
|
||||
#else
|
||||
|
||||
/*** regular C functions ***/
|
||||
|
||||
/* call this after declaring a local lgiant and before using it */
|
||||
extern void localGiantAlloc(lgiant *g);
|
||||
|
||||
/* ditto, for a bgiant */
|
||||
extern void localBigGiantAlloc(bgiant *g);
|
||||
|
||||
/* ditto, for a tgiant */
|
||||
extern void localTriGiantAlloc(tgiant *g);
|
||||
|
||||
void initGiant(
|
||||
giant g,
|
||||
gi_uint16 capacity,
|
||||
giantDigit *digits);
|
||||
|
||||
int isone(giant g); /* Returns whether g is 1 */
|
||||
int isZero(giant g); /* Returns whether g is zero */
|
||||
|
||||
#endif /* INLINE / MACRO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GI_GIANTINTEGERS_H_ */
|
||||
@@ -0,0 +1,48 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantMemutils.c - trivial implementation of memcpy and bzero, for platforms
|
||||
* without libc versions of those functions.
|
||||
*
|
||||
* Created Aug. 8 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#include <libGiants/giantPlatform.h>
|
||||
|
||||
#ifndef GI_HAVE_MEMCPY
|
||||
#error Please define GI_HAVE_MEMCPY.
|
||||
#endif
|
||||
|
||||
#ifndef GI_HAVE_BZERO
|
||||
#error Please define GI_HAVE_BZERO.
|
||||
#endif
|
||||
|
||||
#if !GI_HAVE_MEMCPY
|
||||
|
||||
void *Memcpy(void *dst, const void *src, gi_uint16 len)
|
||||
{
|
||||
gi_size dex;
|
||||
unsigned char *dstp = (unsigned char *)dst;
|
||||
const unsigned char *srcp = (const unsigned char *)src;
|
||||
|
||||
for(dex=0; dex<len; dex++) {
|
||||
*dstp++ = *srcp++;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !GI_HAVE_BZERO
|
||||
|
||||
void Bzero(void *b, gi_uint16 len)
|
||||
{
|
||||
gi_size dex;
|
||||
unsigned char *dstp = (unsigned char *)b;
|
||||
|
||||
for(dex=0; dex<len; dex++) {
|
||||
*dstp++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,722 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantMod.c - modular arithmetic function declarations.
|
||||
*
|
||||
* Created Nov. 29 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#include <libGiants/giantMod.h>
|
||||
#include <libGiants/giantDebug.h>
|
||||
|
||||
|
||||
#ifndef GI_SMALL_CRT_ENABLE
|
||||
#error Please define GI_SMALL_CRT_ENABLE.
|
||||
#endif
|
||||
|
||||
#if GI_SMALL_CRT_ENABLE
|
||||
/*
|
||||
* Custom version of the tgiant for GI_SMALL_CRT_ENABLE use.
|
||||
* Normally a tgiant has 2n+2 digits. The corresponding "small tgiant"
|
||||
* has n+2 digits.
|
||||
*/
|
||||
#define GIANT_SMALL_TRIPLE_DIGITS (MAX_PRIME_SIZE_DIGITS + 2)
|
||||
|
||||
typedef struct {
|
||||
giantStruct g;
|
||||
giantDigit _n_[GIANT_SMALL_TRIPLE_DIGITS];
|
||||
} smallTGiantStruct;
|
||||
typedef smallTGiantStruct stgiant;
|
||||
|
||||
static GI_INLINE void localSmallTGiantAlloc(stgiant *g)
|
||||
{
|
||||
initGiant(&g->g, GIANT_SMALL_TRIPLE_DIGITS, g->_n_);
|
||||
}
|
||||
|
||||
static void rsquareSmall(
|
||||
giant x,
|
||||
giant n,
|
||||
giant recip);
|
||||
static void rmulgSmall(
|
||||
giant x,
|
||||
giant y,
|
||||
giant n,
|
||||
giant recip);
|
||||
static void modg_via_recipSmall(
|
||||
giant d,
|
||||
giant r,
|
||||
giant n);
|
||||
static void powermodgSmall(
|
||||
giant base,
|
||||
giant expo,
|
||||
giant n,
|
||||
giant recip,
|
||||
giant result);
|
||||
#endif
|
||||
|
||||
/* for lots of grungy low-level debugging */
|
||||
#define DEBUG_MODG 0
|
||||
#if DEBUG_MODG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <libGiantsUtils/printGiant.h>
|
||||
|
||||
static void dispGiant(
|
||||
const char *label,
|
||||
giant g)
|
||||
{
|
||||
printf("--- %s : ", label);
|
||||
printGiant(g);
|
||||
}
|
||||
|
||||
static void dispInt(
|
||||
const char *label,
|
||||
unsigned i)
|
||||
{
|
||||
printf("--- %s : %u\n", label, i);
|
||||
}
|
||||
|
||||
static void dispHeader(
|
||||
const char *label)
|
||||
{
|
||||
printf("--- %s ---\n", label);
|
||||
}
|
||||
static void dispDelim(void)
|
||||
{
|
||||
printf("-------------\n");
|
||||
}
|
||||
#else /* DEBUG_MODG */
|
||||
#define dispGiant(l, g)
|
||||
#define dispInt(l, i)
|
||||
#define dispDelim()
|
||||
#define dispHeader(l)
|
||||
#endif /* DEBUG_MODG */
|
||||
|
||||
#if GI_MODG_ENABLE
|
||||
|
||||
|
||||
/* returns 1 if g has exactly one bit set, else returns zero */
|
||||
static int isPowerOfTwo(
|
||||
giant g)
|
||||
{
|
||||
int foundBit = 0;
|
||||
gi_uint16 dex;
|
||||
giantDigit currDigit;
|
||||
giantDigit mask;
|
||||
|
||||
GI_CHECK_SP("isPowerOfTwo");
|
||||
if(isZero(g)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* see if m.s. digit has exactly one bit set */
|
||||
currDigit = g->n[g->sign - 1];
|
||||
/* mask shifts out to zero when done */
|
||||
for(mask=0x01; mask != 0; mask <<= 1) {
|
||||
if(currDigit & mask) {
|
||||
if(foundBit) {
|
||||
/* found second bit set: done */
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* first '1' bit seen */
|
||||
foundBit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
GIASSERT(foundBit != 0);
|
||||
|
||||
/* now we return true iff all the rest of the digits are zero */
|
||||
for(dex=0; dex<g->sign-1; dex++) {
|
||||
if(g->n[dex] != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the reciprocal of a demonimator.
|
||||
*/
|
||||
void make_recip(
|
||||
giant d,
|
||||
giant recip)
|
||||
/* r becomes the steady-state reciprocal
|
||||
2^(2b)/d, where b = bit-length of d-1. */
|
||||
{
|
||||
int b;
|
||||
|
||||
tgiant tmp1;
|
||||
bgiant tmp2;
|
||||
tgiant tmp3;
|
||||
|
||||
GI_CHECK_SP("make_recip (1)");
|
||||
if (isZero(d)) {
|
||||
GIASSERT(0);
|
||||
return;
|
||||
}
|
||||
if(isPowerOfTwo(d)) {
|
||||
gtog(d, recip);
|
||||
return;
|
||||
}
|
||||
|
||||
localTriGiantAlloc(&tmp1);
|
||||
localBigGiantAlloc(&tmp2);
|
||||
localTriGiantAlloc(&tmp3);
|
||||
//localGiantAlloc(&tmpRecip);
|
||||
|
||||
GI_CHECK_SP("make_recip (2)");
|
||||
|
||||
b = bitlen(d);
|
||||
int_to_giant(1, recip);
|
||||
if((b & (GIANT_BITS_PER_DIGIT - 1)) == 0) {
|
||||
/* digit-aligned */
|
||||
gshiftwordsleft(b >> GI_GIANT_LOG2_BITS_PER_DIGIT, recip);
|
||||
}
|
||||
else {
|
||||
gshiftleft(b, recip);
|
||||
}
|
||||
gtog(recip, &tmp2.g);
|
||||
|
||||
while(1) {
|
||||
grammarSquare_common(recip, &tmp1.g);
|
||||
gshiftright(b, &tmp1.g);
|
||||
mulg_common(d, &tmp1.g, &tmp3.g);
|
||||
gshiftright(b, &tmp3.g);
|
||||
addg(recip, recip);
|
||||
normal_subg(&tmp3.g, recip);
|
||||
if(gcompg(recip, &tmp2.g) <= 0) {
|
||||
break;
|
||||
}
|
||||
gtog(recip, &tmp2.g);
|
||||
}
|
||||
mulg_common(recip, d, &tmp1.g);
|
||||
int_to_giant(1, &tmp2.g);
|
||||
while(bitlen(&tmp1.g) > (2 * b)) {
|
||||
normal_subg(&tmp2.g, recip);
|
||||
normal_subg(d, &tmp1.g);
|
||||
}
|
||||
CHECK_GIANT_OFLOW(recip);
|
||||
}
|
||||
|
||||
#define MODG_CTR_LIMIT 3
|
||||
|
||||
/*
|
||||
* Optimized modg.
|
||||
* n := n % d, where r is the precalculated steady-state reciprocal of d.
|
||||
*/
|
||||
void modg_via_recip(
|
||||
giant d,
|
||||
giant r,
|
||||
giant n)
|
||||
{
|
||||
int s = bitlen(r)-1;
|
||||
bgiant tmp1;
|
||||
tgiant tmp2;
|
||||
|
||||
//dispGiant("d", d);
|
||||
//dispGiant("r", r);
|
||||
//dispGiant("n", n);
|
||||
|
||||
GI_CHECK_SP("modg_via_recip(1)");
|
||||
GIASSERT(!isZero(r));
|
||||
|
||||
if(s == 0) {
|
||||
int_to_giant(0, n);
|
||||
return;
|
||||
}
|
||||
if(gcompg(n, d) < 0) {
|
||||
/* this mod is a nop: done. */
|
||||
return;
|
||||
}
|
||||
localBigGiantAlloc(&tmp1);
|
||||
localTriGiantAlloc(&tmp2);
|
||||
|
||||
do {
|
||||
unsigned ct = 0;
|
||||
gtog(n, &tmp1.g);
|
||||
gshiftright(s-1, &tmp1.g);
|
||||
|
||||
mulg_common(r, &tmp1.g, &tmp2.g);
|
||||
gshiftright(s+1, &tmp2.g);
|
||||
mulg_common(d, &tmp2.g, &tmp1.g);
|
||||
normal_subg(&tmp1.g, n);
|
||||
|
||||
while(++ct <= MODG_CTR_LIMIT) {
|
||||
if(gcompg(n,d) >= 0) {
|
||||
normal_subg(d,n);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
/* Both n and div are written by this function, with new values:
|
||||
n := n mod d,
|
||||
div := floor(n/d).
|
||||
*/
|
||||
void divmodg_via_recip(
|
||||
giant d,
|
||||
giant r,
|
||||
giant n,
|
||||
giant dv)
|
||||
{
|
||||
int s = bitlen(r)-1;
|
||||
tgiant tmp1;
|
||||
tgiant tmp2;
|
||||
|
||||
GI_CHECK_SP("divmodg_via_recip(1)");
|
||||
GIASSERT(!isZero(r));
|
||||
|
||||
if(s == 0) {
|
||||
int_to_giant(0, n);
|
||||
gtog(n, dv);
|
||||
return;
|
||||
}
|
||||
int_to_giant(0, dv);
|
||||
if(gcompg(n, d) < 0) {
|
||||
/* this mod is a nop: done. */
|
||||
return;
|
||||
}
|
||||
localTriGiantAlloc(&tmp1);
|
||||
localTriGiantAlloc(&tmp2);
|
||||
GI_CHECK_SP("divmodg_via_recip(2)");
|
||||
|
||||
do {
|
||||
unsigned ct = 0;
|
||||
gtog(n, &tmp1.g);
|
||||
gshiftright(s-1, &tmp1.g);
|
||||
mulg_common(r, &tmp1.g, &tmp2.g);
|
||||
gshiftright(s+1, &tmp2.g);
|
||||
mulg_common(d, &tmp2.g, &tmp1.g);
|
||||
normal_subg(&tmp1.g, n);
|
||||
addg(&tmp2.g, dv);
|
||||
while(++ct <= 3) {
|
||||
if(gcompg(n,d) >= 0) {
|
||||
normal_subg(d,n);
|
||||
iaddg(1, dv);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
/* x := (x^2) mod n with known reciprocal of n */
|
||||
void rsquare(
|
||||
giant x,
|
||||
giant n,
|
||||
giant recip)
|
||||
{
|
||||
bgiant sq;
|
||||
|
||||
GI_CHECK_SP("rsquare(1)");
|
||||
localBigGiantAlloc(&sq);
|
||||
GI_CHECK_SP("rsquare(2)");
|
||||
grammarSquare_common(x, &sq.g);
|
||||
modg_via_recip(n, recip, &sq.g);
|
||||
gtog(&sq.g, x);
|
||||
}
|
||||
|
||||
/* y := (x * y) mod n with known reciprocal of n */
|
||||
void rmulg(
|
||||
giant x,
|
||||
giant y,
|
||||
giant n,
|
||||
giant recip)
|
||||
{
|
||||
bgiant prod;
|
||||
|
||||
GI_CHECK_SP("rmulg");
|
||||
localBigGiantAlloc(&prod);
|
||||
mulg_common(x, y, &prod.g);
|
||||
modg_via_recip(n, recip, &prod.g);
|
||||
gtog(&prod.g, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* result becomes base^expo (mod n).
|
||||
* Caller knows and gives us reciprocal of n as recip.
|
||||
* base and result can share the same giant.
|
||||
*/
|
||||
void powermodg(
|
||||
giant base,
|
||||
giant expo,
|
||||
giant n,
|
||||
giant recip,
|
||||
giant result)
|
||||
{
|
||||
int len, pos;
|
||||
lgiant bmod; /* saved base mod n */
|
||||
|
||||
GI_CHECK_SP("powermodg");
|
||||
GI_LOG_SP("top of powermodg");
|
||||
if(isZero(expo)) {
|
||||
int_to_giant(1, result);
|
||||
return;
|
||||
}
|
||||
|
||||
localGiantAlloc(&bmod);
|
||||
|
||||
if(base != result) {
|
||||
gtog(base, result);
|
||||
}
|
||||
if(gcompg(result, n) >= 0) {
|
||||
modg_via_recip(n, recip, result);
|
||||
}
|
||||
gtog(result, &bmod.g);
|
||||
|
||||
len = bitlen(expo);
|
||||
if(len == 1) {
|
||||
return;
|
||||
}
|
||||
for(pos = len-2; pos >= 0; pos--) {
|
||||
rsquare(result, n, recip); // New ring-square.
|
||||
if (bitval(expo, pos)) {
|
||||
rmulg(&bmod.g, result, n, recip);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void modg(
|
||||
giant d,
|
||||
giant n)
|
||||
/* n becomes n%d. n is arbitrary, but the denominator d must be positive! */
|
||||
{
|
||||
lgiant recip;
|
||||
|
||||
GI_CHECK_SP("modg");
|
||||
localGiantAlloc(&recip);
|
||||
make_recip(d, &recip.g);
|
||||
modg_via_recip(d, &recip.g, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* power/mod using Chinese Remainder Theorem.
|
||||
*
|
||||
* result becomes base^d (mod n).
|
||||
*
|
||||
* ...but we don't know or need d or n. What we have are
|
||||
*
|
||||
* p, q such that n = p*q
|
||||
* reciprocals of p, q
|
||||
* dp = d mod (p-1)
|
||||
* dq = d mod (q-1)
|
||||
* qinv = q^(1) mod p
|
||||
*/
|
||||
void powermodCRT(
|
||||
giant x, /* base (plaintext/ciphertext) */
|
||||
giant p, /* p*q = n */
|
||||
giant pRecip, /* reciprocal of p */
|
||||
giant q,
|
||||
giant qRecip, /* reciprocal of p */
|
||||
giant dp, /* d mod (p-1) */
|
||||
giant dq, /* d mod (q-1) */
|
||||
giant qinv,
|
||||
giant sq, /* scratch, provided and init'd by caller */
|
||||
giant result) /* OUTPUT */
|
||||
{
|
||||
bgiant sp;
|
||||
int m;
|
||||
|
||||
GI_CHECK_SP("powermodCRT");
|
||||
localBigGiantAlloc(&sp);
|
||||
GIASSERT(sq->capacity >= GIANT_LITTLE_DIGITS);
|
||||
|
||||
/*
|
||||
* sp := x^dp mod p;
|
||||
* sq := x^dq mod q;
|
||||
*/
|
||||
#if GI_SMALL_CRT_ENABLE
|
||||
powermodgSmall(x, dp, p, pRecip, &sp.g);
|
||||
powermodgSmall(x, dq, q, qRecip, sq);
|
||||
#else
|
||||
powermodg(x, dp, p, pRecip, &sp.g);
|
||||
powermodg(x, dq, q, qRecip, sq);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* m = gcompg(sp, sq);
|
||||
* if(m > = 0)
|
||||
* result = sp-sq;
|
||||
* else
|
||||
* result = sq-sp; // Note unsigned subtract always;
|
||||
*/
|
||||
m = gcompg(&sp.g, sq);
|
||||
if(m >= 0) {
|
||||
gtog(&sp.g, result);
|
||||
normal_subg(sq, result);
|
||||
}
|
||||
else {
|
||||
gtog(sq, result);
|
||||
normal_subg(&sp.g, result);
|
||||
}
|
||||
|
||||
/*
|
||||
* result = (qinv * result) mod p;
|
||||
* done with sp, use as scratch now...
|
||||
*/
|
||||
mulg_common(result, qinv, &sp.g);
|
||||
modg_via_recip(p, pRecip, &sp.g);
|
||||
gtog(&sp.g, result);
|
||||
|
||||
/*
|
||||
* if( ! isZero(result)) if(m < 0) result = p - result;
|
||||
*/
|
||||
if(!isZero(result)) {
|
||||
if(m < 0) {
|
||||
gtog(p, &sp.g);
|
||||
normal_subg(result, &sp.g);
|
||||
gtog(&sp.g, result);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* result *= q;
|
||||
* result += sq;
|
||||
*/
|
||||
mulg_common(result, q, &sp.g);
|
||||
addg(sq, &sp.g);
|
||||
gtog(&sp.g, result);
|
||||
}
|
||||
|
||||
#endif /* GI_MODG_ENABLE */
|
||||
|
||||
#if GI_INVERSE_MOD_ENABLE
|
||||
|
||||
/*
|
||||
* Given x, y coprime with x > 0, y > 1, this routine forces
|
||||
* x := x^(-1) mod modulus.
|
||||
*/
|
||||
void ginverseMod(
|
||||
giant modulus,
|
||||
giant recip, /* reciprocal of modulus */
|
||||
giant x) /* IN/OUT */
|
||||
{
|
||||
lgiant u, v, a, q, tmp;
|
||||
unsigned int k = 0;
|
||||
lgiant uRecip;
|
||||
|
||||
GI_CHECK_SP("ginverseMod");
|
||||
localGiantAlloc(&u);
|
||||
localGiantAlloc(&v);
|
||||
localGiantAlloc(&a);
|
||||
localGiantAlloc(&q);
|
||||
localGiantAlloc(&tmp);
|
||||
localGiantAlloc(&uRecip);
|
||||
|
||||
dispHeader("ginverseMod top");
|
||||
dispGiant("x", x);
|
||||
dispGiant("modulus", modulus);
|
||||
dispGiant("recip", recip);
|
||||
|
||||
/*
|
||||
* 1) (u, v, a, x, k) = (x mod modulus, modulus, 0, 1, 0);
|
||||
*/
|
||||
gtog(x, &u.g);
|
||||
modg_via_recip(modulus, recip, &u.g);
|
||||
gtog(modulus, &v.g);
|
||||
/* a is already zero */
|
||||
int_to_giant(1, x);
|
||||
|
||||
dispHeader("ginverseMod before loop");
|
||||
dispGiant("x", x);
|
||||
dispGiant("u", &u.g);
|
||||
dispGiant("v", &v.g);
|
||||
dispGiant("a", &a.g);
|
||||
dispInt("k", k);
|
||||
|
||||
/*
|
||||
* 2) while(u > 1) {
|
||||
* q = v div u;
|
||||
* (u, v, a, x, k) = (v mod u, u, x, (a + q*x) mod y, k + 1);
|
||||
* }
|
||||
*/
|
||||
while(!isZero(&u.g) && !isone(&u.g)) {
|
||||
/* (q,u) := (v div u, v mod u */
|
||||
make_recip(&u.g, &uRecip.g);
|
||||
gtog(&u.g, &tmp.g); /* for a const modulus in divmodg_via_recip() */
|
||||
gtog(&v.g, &u.g); /* divisor, then result of mod */
|
||||
divmodg_via_recip(&tmp.g, &uRecip.g, &u.g, &q.g);
|
||||
|
||||
/* v := old u */
|
||||
gtog(&tmp.g, &v.g);
|
||||
|
||||
/* intermediate: *old* x */
|
||||
gtog(x, &tmp.g);
|
||||
|
||||
/* calc new x := a + q*x mod y */
|
||||
rmulg(&q.g, x, modulus, recip);
|
||||
addg(&a.g, x);
|
||||
modg_via_recip(modulus, recip, x); /* just in case */
|
||||
|
||||
/* new a := old x */
|
||||
gtog(&tmp.g, &a.g);
|
||||
k++;
|
||||
|
||||
dispDelim();
|
||||
dispGiant("x", x);
|
||||
dispGiant("q", &q.g);
|
||||
dispGiant("u", &u.g);
|
||||
dispGiant("v", &v.g);
|
||||
dispGiant("a", &a.g);
|
||||
dispInt("k", k);
|
||||
}
|
||||
|
||||
/*
|
||||
* 3) if(k odd) x = y - x; // Unsigned (normal_subg) subtract.
|
||||
*/
|
||||
if(k & 1) {
|
||||
gtog(modulus, &u.g);
|
||||
normal_subg(x, &u.g);
|
||||
gtog(&u.g, x);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GI_INVERSE_MOD_ENABLE */
|
||||
|
||||
#if GI_SMALL_CRT_ENABLE
|
||||
|
||||
/*
|
||||
* Optional "small giant" routines used only by powermodCRT when
|
||||
* performing its initial powermodg operations with p and q as the
|
||||
* modulus; p and q are half the size of MAX_PRIME_SIZE_DIGITS, so
|
||||
* we implement the following functions with corresponding small
|
||||
* local giants.
|
||||
* On PPC, this saves 384 bytes of stack space, at the cost of
|
||||
* 1407 extra bytes of code.
|
||||
*/
|
||||
static void rsquareSmall(
|
||||
giant x,
|
||||
giant n,
|
||||
giant recip)
|
||||
{
|
||||
stgiant sq;
|
||||
|
||||
GI_CHECK_SP("rsquareSmall(1)");
|
||||
localSmallTGiantAlloc(&sq);
|
||||
GI_CHECK_SP("rsquareSmall(2)");
|
||||
grammarSquare_common(x, &sq.g);
|
||||
modg_via_recipSmall(n, recip, &sq.g);
|
||||
gtog(&sq.g, x);
|
||||
}
|
||||
|
||||
/* y := (x * y) mod n with known reciprocal of n */
|
||||
static void rmulgSmall(
|
||||
giant x,
|
||||
giant y,
|
||||
giant n,
|
||||
giant recip)
|
||||
{
|
||||
stgiant prod;
|
||||
|
||||
GI_CHECK_SP("rmulgSmall");
|
||||
localSmallTGiantAlloc(&prod);
|
||||
mulg_common(x, y, &prod.g);
|
||||
modg_via_recipSmall(n, recip, &prod.g);
|
||||
gtog(&prod.g, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* Optimized modg.
|
||||
* n := n % d, where r is the precalculated steady-state reciprocal of d.
|
||||
*/
|
||||
static void modg_via_recipSmall(
|
||||
giant d,
|
||||
giant r,
|
||||
giant n)
|
||||
{
|
||||
int s = bitlen(r)-1;
|
||||
stgiant tmp1;
|
||||
stgiant tmp2;
|
||||
|
||||
GI_CHECK_SP("modg_via_recipSmall(1)");
|
||||
GIASSERT(!isZero(r));
|
||||
|
||||
if(s == 0) {
|
||||
int_to_giant(0, n);
|
||||
return;
|
||||
}
|
||||
if(gcompg(n, d) < 0) {
|
||||
/* this mod is a nop: done. */
|
||||
return;
|
||||
}
|
||||
localSmallTGiantAlloc(&tmp1);
|
||||
localSmallTGiantAlloc(&tmp2);
|
||||
|
||||
do {
|
||||
unsigned ct = 0;
|
||||
gtog(n, &tmp1.g);
|
||||
gshiftright(s-1, &tmp1.g);
|
||||
|
||||
mulg_common(r, &tmp1.g, &tmp2.g);
|
||||
gshiftright(s+1, &tmp2.g);
|
||||
mulg_common(d, &tmp2.g, &tmp1.g);
|
||||
normal_subg(&tmp1.g, n);
|
||||
|
||||
while(++ct <= MODG_CTR_LIMIT) {
|
||||
if(gcompg(n,d) >= 0) {
|
||||
normal_subg(d,n);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* result becomes base^expo (mod n).
|
||||
* Caller knows and gives us reciprocal of n as recip.
|
||||
* base and result can share the same giant.
|
||||
*
|
||||
* This is only used by powermodCRT, which conveniently hands us
|
||||
* two initialized scratch giants, one bgiant and one stgiant
|
||||
* so neither we nor any of our callers have to allocate any
|
||||
* local giants.
|
||||
*/
|
||||
static void powermodgSmall(
|
||||
giant base,
|
||||
giant expo,
|
||||
giant n,
|
||||
giant recip,
|
||||
giant result)
|
||||
{
|
||||
int len, pos;
|
||||
lgiant bmod; /* saved base mod n */
|
||||
|
||||
GI_CHECK_SP("powermodgSmall");
|
||||
GI_LOG_SP("top of powermodgSmall");
|
||||
if(isZero(expo)) {
|
||||
int_to_giant(1, result);
|
||||
return;
|
||||
}
|
||||
|
||||
localGiantAlloc(&bmod);
|
||||
|
||||
if(base != result) {
|
||||
gtog(base, result);
|
||||
}
|
||||
if(gcompg(result, n) >= 0) {
|
||||
modg_via_recipSmall(n, recip, result);
|
||||
}
|
||||
gtog(result, &bmod.g);
|
||||
|
||||
len = bitlen(expo);
|
||||
if(len == 1) {
|
||||
return;
|
||||
}
|
||||
for(pos = len-2; pos >= 0; pos--) {
|
||||
rsquareSmall(result, n, recip); // New ring-square.
|
||||
if (bitval(expo, pos)) {
|
||||
rmulgSmall(&bmod.g, result, n, recip);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* GI_SMALL_CRT_ENABLE */
|
||||
@@ -0,0 +1,124 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantMod.h - modular arithmetic function declarations.
|
||||
*
|
||||
* Created Nov. 29 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#ifndef _GIANT_MOD_H_
|
||||
#define _GIANT_MOD_H_
|
||||
|
||||
#include <libGiants/giantIntegers.h>
|
||||
|
||||
/* this must be defined in giantPlatform.h */
|
||||
#ifndef GI_MODG_ENABLE
|
||||
#error Please define GI_MODG_ENABLE one way or the other.
|
||||
#endif
|
||||
|
||||
#if GI_MODG_ENABLE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate the reciprocal of a demonimator to be used in
|
||||
* modg_via_recip().
|
||||
*/
|
||||
void make_recip(giant d, giant recip);
|
||||
|
||||
/*
|
||||
* n := n % d, where r is the precalculated
|
||||
* steady-state reciprocal of d.
|
||||
*/
|
||||
void modg_via_recip(
|
||||
giant d,
|
||||
giant r,
|
||||
giant n);
|
||||
|
||||
/* Both n and div are written by this function, with new values:
|
||||
n := n mod d,
|
||||
div := floor(n/d).
|
||||
*/
|
||||
void divmodg_via_recip(
|
||||
giant d,
|
||||
giant r,
|
||||
giant n,
|
||||
giant dv);
|
||||
|
||||
/* x := (x^2) mod n with known reciprocal of n */
|
||||
void rsquare(
|
||||
giant x,
|
||||
giant n,
|
||||
giant recip);
|
||||
|
||||
/* y := (x * y) mod n with known reciprocal of n */
|
||||
void rmulg(
|
||||
giant x,
|
||||
giant y,
|
||||
giant n,
|
||||
giant recip);
|
||||
|
||||
/*
|
||||
* result becomes base^expo (mod n).
|
||||
* Caller knows and gives us reciprocal of n as recip.
|
||||
* base and result can share the same giant.
|
||||
*/
|
||||
void powermodg(
|
||||
giant base,
|
||||
giant expo,
|
||||
giant n,
|
||||
giant recip,
|
||||
giant result);
|
||||
|
||||
/* n becomes n%d. n is arbitrary, but the denominator d must be positive! */
|
||||
void modg(giant d,giant n);
|
||||
|
||||
/*
|
||||
* power/mod using Chinese Remainder Theorem.
|
||||
*
|
||||
* result becomes base^d (mod n).
|
||||
*
|
||||
* ...but we don't know or need d or n. What we have are
|
||||
*
|
||||
* p, q such that n = p*q
|
||||
* reciprocals of p, q
|
||||
* dp = d mod (p-1)
|
||||
* dq = d mod (q-1)
|
||||
* qinv = q^(1) mod p
|
||||
*
|
||||
* Plus one scratch giant, initialized by caller with the capacity at
|
||||
* least as big as an lgiant.
|
||||
*
|
||||
* The base and result arguments can be identical, i.e., an in/out
|
||||
* parameter.
|
||||
*/
|
||||
void powermodCRT(
|
||||
giant base, /* base (plaintext/ciphertext) */
|
||||
giant p, /* p*q = n */
|
||||
giant pRecip, /* reciprocal of p */
|
||||
giant q,
|
||||
giant qRecip, /* reciprocal of q */
|
||||
giant dp, /* d mod (p-1) */
|
||||
giant dq, /* d mod (q-1) */
|
||||
giant qinv,
|
||||
giant scratchLgiant,
|
||||
giant result); /* OUTPUT */
|
||||
|
||||
/*
|
||||
* Given x, y coprime with x > 0, y > 1, this routine forces
|
||||
* x := x^(-1) mod y.
|
||||
*/
|
||||
void ginverseMod(
|
||||
giant modulus,
|
||||
giant recip, /* reciprocal of modulus */
|
||||
giant x); /* IN/OUT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GI_MODG_ENABLE */
|
||||
|
||||
#endif /* _GIANT_MOD_H_ */
|
||||
@@ -0,0 +1,370 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantPlatform.h - platform specific type and routines, must be ported to
|
||||
* each platform on which this library runs.
|
||||
*/
|
||||
|
||||
#ifndef _GIANT_PLATFORM_H_
|
||||
#define _GIANT_PLATFORM_H_
|
||||
|
||||
/*
|
||||
* This is defined true only for development and testing.
|
||||
* For production code, leave it zero and define your platform
|
||||
* in this file.
|
||||
*/
|
||||
|
||||
#define GI_PLATFORM_EMULATE 1
|
||||
#if GI_PLATFORM_EMULATE
|
||||
#include <libGiants/giantPlatformEmulation.h>
|
||||
#else
|
||||
|
||||
/* be sure to #define NDEBUG for deployment builds */
|
||||
#define NDEBUG
|
||||
#ifdef NDEBUG
|
||||
#define GIANTS_DEBUG 0
|
||||
#else
|
||||
#define GIANTS_DEBUG 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Machine-dependent word-size related integer types.
|
||||
*
|
||||
* The following integer types must be defined in this module:
|
||||
*
|
||||
* gi_uint8 -- unsigned 8 bit (typically "unsigned char")
|
||||
* gi_uint16 -- unsigned 16 bit, platform/compiler dependent
|
||||
* gi_uint32 -- unsigned 32-bit integer, platform/compiler dependent
|
||||
* gi_size -- unsigned, at *least* 16 bits. Could be larger if that's
|
||||
* more efficient for the platform. For example on a 32-bit
|
||||
* processor this should be an unsigned 32 bit integer.
|
||||
* Generally used inside of functions as counters, indices,
|
||||
* etc. Function parameters which must be portable to
|
||||
* small processors are expressed as gi_uint16 or
|
||||
* gi_uint32.
|
||||
* giantDigit -- see below
|
||||
* giantDouble -- two giant digits, the result of a giantDigit multiply
|
||||
*
|
||||
* giantDigit is the largest native word size for which
|
||||
* a (giantDigit x giantDigit) hardware multiply (into a giantDouble,
|
||||
* somehow) is available. This is a crucial data type; the large integer
|
||||
* artithmetic package uses data types called 'giants' which are mainly
|
||||
* comprised of arrays of giantDigits. Most of the CPU cycles spent in this
|
||||
* library are involved in performing arithmetic on these arrays of
|
||||
* giantDigits.
|
||||
*
|
||||
* Our assumption is that the following all always fit into a gi_uint16:
|
||||
*
|
||||
* number of bits per giant digit
|
||||
* number of giant digits in the max base prime in this module
|
||||
* number of bits in the max base prime in this module
|
||||
*
|
||||
* Note we also assume the existence of a 16-bit integer type; arithmetic
|
||||
* involving this type doesn't have to be particularly fast but it has to be
|
||||
* usable as a function argument and in simple assignments. Thus 8-bit
|
||||
* platforms can run this code as long as there is a C type which compiles
|
||||
* to 16 bits.
|
||||
*
|
||||
* These preprocessor symbols also need to be defined for each platform:
|
||||
*
|
||||
* GI_GIANT_LOG2_BITS_PER_DIGIT
|
||||
* The log to base 2 of the size of giantDigit. There
|
||||
* is no straightforward way for the C preprocessor to figure this one
|
||||
* out so you have to specify it. For 16-bit giantDigits the value of
|
||||
* this symbol is 4; for 32-bit giantDigits the value is 5.
|
||||
*
|
||||
* GI_GIANT_PORT_INLINE
|
||||
* 1 : we don't have a platform-specific giant arithmetic module; use the
|
||||
* inlines in giantPort_Generic.h
|
||||
* 0 : we have a platform-specific giant arithmetic module
|
||||
*
|
||||
* GI_INLINE_SMALL_FUNCS
|
||||
* 1 : Use 'static inline' for a select set of small (1-3 line) functions.
|
||||
* Trade more code for faster runtime and less stack usage. The specific
|
||||
* effect of this flag wil be nighly dependent on your compiler; in some
|
||||
* cases you might even see smaller code size when this flag is true.
|
||||
* 0 : Disable this feature, use actual C functions.
|
||||
*
|
||||
* GI_MACRO_SMALL_FUNCTIONS
|
||||
*
|
||||
* Like GI_INLINE_SMALL_FUNCS, except causes small functions to be implemented
|
||||
* as macros. For platforms that don't support the 'inline' keyword. Mutually
|
||||
* exclusive with GI_INLINE_SMALL_FUNCS.
|
||||
* 1 : Use #defined macros for the functions in question.
|
||||
* 0 : Disable; use actual C functions.
|
||||
*
|
||||
*
|
||||
* GI_SMALL_CRT_ENABLE
|
||||
*
|
||||
* This flag involves a tradeoff between code size and stack usage in the
|
||||
* giantMod.c module. Setting this flag true increases code size and
|
||||
* decreases stack usage.
|
||||
*
|
||||
* On a G4, the tradeoff is that setting this flag saves 384 bytes of
|
||||
* stack space, at the cost of 1407 extra bytes of code.
|
||||
*
|
||||
* Note: this flag has no effect if GI_MODG_ENABLE is 0.
|
||||
*
|
||||
* 0 : disable the small-CRT functions to save code space.
|
||||
* 1 : enable to the small-CRT functions to save stack space.
|
||||
*
|
||||
* GI_HAVE_MEMCPY
|
||||
* 1 : This platform has memcpy() and we want to use it as the implementation
|
||||
* of Memcpy()
|
||||
* 0 : We've provided our own Memcpy()
|
||||
*
|
||||
* GI_HAVE_BZERO
|
||||
* 1 : This platform has bzero() and we want to use it as the implementation
|
||||
* of Bzero()
|
||||
* 0 : We've provided our own Bzero()
|
||||
*
|
||||
* GI_INLINE
|
||||
* Used where the 'inline' keyword would normally be used. #define to 'inline'
|
||||
* if your compiler provides this functionality, else #define it to nothing or
|
||||
* some other compiler-specific value.
|
||||
*
|
||||
* GI_MODG_ENABLE
|
||||
*
|
||||
* When nonzero, enables the modular arithmetic functions found in
|
||||
* giantMod.[ch]. Some applications such as SFEE do not need these functions.
|
||||
* Other applications, like RSA and BBS, do in fact need them.
|
||||
*
|
||||
* 1 : Enable compilation of giantMod.[ch]
|
||||
* 0 : Disable compilation of giantMod.[ch]
|
||||
*
|
||||
* GI_PRIME_TEST_ENABLE
|
||||
*
|
||||
* When nonzero, enables the logic in giantPrime.c used to determine
|
||||
* whether a given giant is prime. Used in RSA key generation.
|
||||
*
|
||||
* 1 : Enable compilation of giantPrime.[ch]
|
||||
* 0 : Disable compilation of giantPrime.[ch]
|
||||
*
|
||||
* GI_INVERSE_MOD_ENABLE
|
||||
*
|
||||
* When nonzero, enables the ginverseMod() function in giantMod.[ch]. Used
|
||||
* for RSA key generation and for BBS.
|
||||
*
|
||||
* 1 : Enable compilation of ginverseMod()
|
||||
* 0 : Disable compilation of ginverseMod()
|
||||
*
|
||||
*
|
||||
* Optimization flags
|
||||
* ------------------
|
||||
*
|
||||
* The following symbols have to be #defined to 0 or 1. See the comments below
|
||||
* for detailed descritpions of the effects of these flags.
|
||||
*
|
||||
* GI_GSQUARE_ENABLE
|
||||
* GI_OPTIMIZED_MULG
|
||||
* GI_ADDG_INLINE
|
||||
*/
|
||||
|
||||
/* These define a 16-bit word size emulated on Mac OS X */
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char gi_uint8;
|
||||
typedef uint16_t gi_uint16;
|
||||
typedef uint32_t gi_uint32;
|
||||
typedef uint16_t gi_size;
|
||||
typedef uint16_t giantDigit;
|
||||
typedef uint32_t giantDouble; /* two giant digits */
|
||||
|
||||
#define GI_GIANT_LOG2_BITS_PER_DIGIT 4
|
||||
|
||||
/*
|
||||
* Maximum size in bits of base integer in this package. For BBS, this is the
|
||||
* size of the public 'n' parameter. For asymmetric encryption, it's the
|
||||
* size of the base prime.
|
||||
*
|
||||
* Altering this has no effect on performance, only on memory usage.
|
||||
* Specifically it affects the amount of stack space used (since all
|
||||
* giantIntegers in this package are allocated on the stack).
|
||||
*/
|
||||
#define GI_MAX_PRIME_SIZE_BITS 4096
|
||||
|
||||
|
||||
/****
|
||||
**** Optimization flags
|
||||
****/
|
||||
|
||||
/*
|
||||
* Sample measurements of the effects of these flags were
|
||||
* taken on an 800 MHz G4, with a 16 bit giantDigit, running
|
||||
* the bbsProtocol test with 1024 bit 'n' and 10000 iterations.
|
||||
* Your mileage will certainly vary; the only way to know for
|
||||
* sure which is the best value for a particular optimizatiaon
|
||||
* flag is to measure a real-world case on your platform and then
|
||||
* make the size-vs.-speed tradeoff decision yourself.
|
||||
*
|
||||
* However, in the meantime, all of the functionality in this
|
||||
* library does work correctly for any value of all of these
|
||||
* flags.
|
||||
*/
|
||||
|
||||
/*
|
||||
* GI_GSQUARE_ENABLE
|
||||
*
|
||||
* Set nonzero to disable optimized grammarSquare().
|
||||
* Setting nonzero increases code size and increases performance.
|
||||
*
|
||||
* Setting this true has the following effects (on 800 MHz G4):
|
||||
*
|
||||
* -- adds 384 bytes of code
|
||||
* -- 7% speedup on private side
|
||||
* -- 7% speedup on public side
|
||||
*/
|
||||
#define GI_GSQUARE_ENABLE 1
|
||||
|
||||
/*
|
||||
* GI_OPTIMIZED_MULG
|
||||
*
|
||||
* Use old unoptimized, but smaller, mulg if this is zero.
|
||||
* Setting nonzero increases code size and increases performance.
|
||||
*
|
||||
* Setting this true has the following effects (on 800 MHz G4):
|
||||
*
|
||||
* -- adds 168 bytes of code
|
||||
* -- 20% speedup on private side
|
||||
* -- 18% speedup on public side
|
||||
*/
|
||||
|
||||
#define GI_OPTIMIZED_MULG 1
|
||||
|
||||
/*
|
||||
* GI_ADDG_INLINE
|
||||
*
|
||||
* There are two implementations of some core arithmetic routines.
|
||||
* Which one is faster depends highly on your implementation of the
|
||||
* routines declared in giantPortCommon.h and implemented in either
|
||||
* giantPort_Generic.h (as static inlines) or elsewhere (in C or
|
||||
* possibly assembly language). Performance also depends on your
|
||||
* platform's giantDouble performance. If giantDouble arithmetic
|
||||
* is fast then use GI_ADDG_INLINE. Otherwise try !GI_ADDG_INLINE,
|
||||
* measure the two, and pick the best one.
|
||||
*
|
||||
* Setting this false has the following effects (on 800 MHz G4):
|
||||
*
|
||||
* -- increases code size 192 bytes
|
||||
* -- elliptic operations (SFEE) slow down by 50-100%
|
||||
*/
|
||||
#define GI_ADDG_INLINE 1
|
||||
|
||||
/*
|
||||
* GI_GIANT_PORT_INLINE
|
||||
*
|
||||
* true : we don't have a platform-specific giant arithmetic module
|
||||
* false : we do
|
||||
*
|
||||
* If GI_ADDG_INLINE is true, setting this true saves a small amount
|
||||
* of code with no measurable performance impact.
|
||||
*
|
||||
* If GI_ADDG_INLINE is false, setting GI_GIANT_PORT_INLINE to
|
||||
* true has the following effects:
|
||||
*
|
||||
* -- adds 168 bytes of code
|
||||
* -- 2% speedup on private side
|
||||
* -- 1% speedup on public side
|
||||
*/
|
||||
#define GI_GIANT_PORT_INLINE 0
|
||||
|
||||
/*
|
||||
* GI_INLINE_SMALL_FUNCS
|
||||
*
|
||||
* When true, uses macros instead of a small number of small functions.
|
||||
* This is a tradeff of speed and less stack usage vs. code size.
|
||||
*/
|
||||
#define GI_INLINE_SMALL_FUNCS 1
|
||||
|
||||
/*
|
||||
* GI_MACRO_SMALL_FUNCTIONS
|
||||
*
|
||||
* Like GI_INLINE_SMALL_FUNCS, except causes small functions to be implemented
|
||||
* as macros. For platforms that don't support the 'inline' keyword.
|
||||
*/
|
||||
#define GI_MACRO_SMALL_FUNCTIONS 0
|
||||
|
||||
/*
|
||||
* GI_SMALL_CRT_ENABLE
|
||||
*
|
||||
* This flag involves a tradeoff between code size and stack usage in the
|
||||
* giantMod.c module. Setting this flag true increases code size and
|
||||
* decreases stack usage.
|
||||
*
|
||||
* On a G4, the tradeoff is that setting this flag saves 384 bytes of
|
||||
* stack space, at the cost of 1407 extra bytes of code.
|
||||
*
|
||||
* Note: this flag has no effect if GI_MODG_ENABLE is 0.
|
||||
*/
|
||||
#define GI_SMALL_CRT_ENABLE 1
|
||||
|
||||
|
||||
/****
|
||||
**** Library implementation flags
|
||||
****/
|
||||
|
||||
/* standard library functions available here */
|
||||
#define GI_HAVE_MEMCPY 1
|
||||
#define GI_HAVE_BZERO 1
|
||||
|
||||
/* enable/disable modular arithmetic */
|
||||
#define GI_MODG_ENABLE 1
|
||||
|
||||
/* enable/disable giantPrime.[ch] - requires GI_MODG_ENABLE! */
|
||||
#define GI_PRIME_TEST_ENABLE 1
|
||||
|
||||
/* enable/disable ginverseMod() */
|
||||
#define GI_INVERSE_MOD_ENABLE 1
|
||||
|
||||
#endif /* GI_PLATFORM_EMULATE */
|
||||
|
||||
#pragma mark --- Declarations of functions with platform-specific implementations ---
|
||||
|
||||
/*
|
||||
* You should not have to modify the rest of this file.
|
||||
*/
|
||||
|
||||
#if GI_HAVE_MEMCPY || GI_HAVE_BZERO
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This platform supports inline keywords.
|
||||
*/
|
||||
#define GI_INLINE inline
|
||||
|
||||
#if GI_HAVE_MEMCPY
|
||||
|
||||
#define Memcpy(d, s, l) memcpy(d, s, l)
|
||||
|
||||
#else /* !GI_HAVE_MEMCPY */
|
||||
|
||||
/*
|
||||
* memcpy() equivalent
|
||||
*/
|
||||
extern void *Memcpy(void *dst, const void *src, gi_uint16 len);
|
||||
|
||||
#endif /* GI_HAVE_MEMCPY */
|
||||
|
||||
#if GI_HAVE_BZERO
|
||||
|
||||
#define Bzero(b, l) bzero(b, l)
|
||||
|
||||
#else /* !GI_HAVE_BZERO */
|
||||
|
||||
/*
|
||||
* bzero() equivalent
|
||||
*/
|
||||
extern void Bzero(void *b, gi_uint16 len);
|
||||
|
||||
#endif /* GI_HAVE_BZERO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_GIANT_PLATFORM_H_*/
|
||||
@@ -0,0 +1,181 @@
|
||||
/* Copyright (c) 2004,2006-2007 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
|
||||
* TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
|
||||
* SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
|
||||
* ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
|
||||
* INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
|
||||
* EXPOSE YOU TO LIABILITY.
|
||||
***************************************************************************
|
||||
*
|
||||
* giantPlatformEmulation.h - #defines for platform emulation.
|
||||
*
|
||||
* This file is NOT used in production code.
|
||||
*/
|
||||
|
||||
#ifndef _GIANT_PLATFORM_EMULATION_H_
|
||||
#define _GIANT_PLATFORM_EMULATION_H_
|
||||
|
||||
#define NDEBUG
|
||||
#ifdef NDEBUG
|
||||
#define GIANTS_DEBUG 0
|
||||
#else
|
||||
#define GIANTS_DEBUG 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Emulation targets:
|
||||
*
|
||||
* #define _FEE_CUSTOM_XXX_CONFIG_ to 1 and fill in these blanks if
|
||||
* you want to generate a test configuration which is not strictly related
|
||||
* to the machine you're building for - e.g., build a 16-bit giant package on PPC.
|
||||
*/
|
||||
|
||||
/* this one for emulating 16-bit CPU on Mac OS X / PPC */
|
||||
#define _FEE_CUSTOM_16_CONFIG_ 1
|
||||
/* this one for emulating 8-bit CPU on Mac OS X / PPC */
|
||||
#define _FEE_CUSTOM_8_CONFIG_ 0
|
||||
|
||||
#if _FEE_CUSTOM_16_CONFIG_
|
||||
|
||||
/* 16-bit word size emulated on Mac OS X */
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char gi_uint8;
|
||||
typedef uint16_t gi_uint16;
|
||||
typedef uint32_t gi_uint32;
|
||||
typedef uint16_t gi_size;
|
||||
typedef uint16_t giantDigit;
|
||||
typedef uint32_t giantDouble; /* two giant digits */
|
||||
|
||||
#define GI_GIANT_LOG2_BITS_PER_DIGIT 4
|
||||
|
||||
#elif _FEE_CUSTOM_8_CONFIG_
|
||||
|
||||
/* 8-bit word size emulated on Mac OS X */
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char gi_uint8;
|
||||
typedef uint16_t gi_uint16;
|
||||
typedef uint32_t gi_uint32;
|
||||
typedef uint16_t gi_size;
|
||||
typedef uint8_t giantDigit;
|
||||
typedef uint16_t giantDouble; /* two giant digits */
|
||||
|
||||
#define GI_GIANT_LOG2_BITS_PER_DIGIT 3
|
||||
|
||||
#elif defined(__APPLE__) && defined(__ppc__)
|
||||
|
||||
/*
|
||||
* Mac OS X on 32-bit PPC
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char gi_uint8;
|
||||
typedef uint16_t gi_uint16;
|
||||
typedef uint32_t gi_uint32;
|
||||
typedef uint32_t gi_size;
|
||||
typedef uint32_t giantDigit;
|
||||
typedef uint64_t giantDouble; /* two giant digits */
|
||||
|
||||
#define GI_GIANT_LOG2_BITS_PER_DIGIT 5
|
||||
|
||||
#elif defined(__APPLE__) && defined(__i386__)
|
||||
|
||||
/*
|
||||
* Mac OS X on 32-bit Pentium
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char gi_uint8;
|
||||
typedef uint16_t gi_uint16;
|
||||
typedef uint32_t gi_uint32;
|
||||
typedef uint32_t gi_size;
|
||||
typedef uint32_t giantDigit;
|
||||
typedef uint64_t giantDouble; /* two giant digits */
|
||||
|
||||
#define GI_GIANT_LOG2_BITS_PER_DIGIT 5
|
||||
|
||||
#else
|
||||
/*
|
||||
* Other target goes here.
|
||||
*/
|
||||
#error Platform dependent work needed
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maximum size in bits of base integer in this package. For BBS, this is the
|
||||
* size of the public 'n' parameter.
|
||||
*/
|
||||
#define GI_MAX_PRIME_SIZE_BITS 4096
|
||||
|
||||
/****
|
||||
**** Optimization flags
|
||||
****/
|
||||
|
||||
/*
|
||||
* There are two implementations of some core arithmetic routines.
|
||||
* Which one is faster depends highly on your implementation of the
|
||||
* routines declared in giantPortCommon.h and implemented in either
|
||||
* giantPort_Generic.h (as static inlines) or elsewhere (in C or
|
||||
* possibly assembly language). Performance also depends on your
|
||||
* platform's giantDouble performance. If giantDouble arithmetic
|
||||
* is fast then use GI_ADDG_INLINE. Otherwise try !GI_ADDG_INLINE,
|
||||
* measure the two, and pick the best one.
|
||||
*/
|
||||
#define GI_ADDG_INLINE 1
|
||||
|
||||
/*
|
||||
* true : we don't have a platform-specific giant arithmetic module
|
||||
* false : we do
|
||||
*/
|
||||
#define GI_GIANT_PORT_INLINE 1
|
||||
|
||||
/*
|
||||
* GI_INLINE_SMALL_FUNCS
|
||||
*
|
||||
* When true, uses inlines instead of a small number of small functions.
|
||||
* This is a tradeff of speed and less stack usage vs. code size.
|
||||
*/
|
||||
#define GI_INLINE_SMALL_FUNCS 1
|
||||
|
||||
/*
|
||||
* GI_MACRO_SMALL_FUNCTIONS
|
||||
*
|
||||
* Like GI_INLINE_SMALL_FUNCS, except causes small functions to be implemented
|
||||
* as macros. For platforms that don't support the 'inline' keyword.
|
||||
*/
|
||||
#define GI_MACRO_SMALL_FUNCTIONS 0
|
||||
|
||||
/*
|
||||
* GI_SMALL_CRT_ENABLE
|
||||
*
|
||||
* This flag involves a tradeoff between code size and stack usage in the
|
||||
* giantMod.c module. Setting this flag true increases code size and
|
||||
* decreases stack usage.
|
||||
*
|
||||
* On a G4, the tradeoff is that setting this flag saves 384 bytes of
|
||||
* stack space, at the cost of 1407 extra bytes of code.
|
||||
*
|
||||
* Note: this flag has no effect if GI_MODG_ENABLE is 0.
|
||||
*/
|
||||
#define GI_SMALL_CRT_ENABLE 1
|
||||
|
||||
/****
|
||||
**** Library implementation flags
|
||||
****/
|
||||
|
||||
/* standard library functions available here */
|
||||
#define GI_HAVE_MEMCPY 1
|
||||
#define GI_HAVE_BZERO 1
|
||||
|
||||
/* enable/disable modular arithmetic */
|
||||
#define GI_MODG_ENABLE 1
|
||||
|
||||
/* enable/disable giantPrime.[ch] */
|
||||
#define GI_PRIME_TEST_ENABLE 1
|
||||
|
||||
/* enable/disable ginverseMod() */
|
||||
#define GI_INVERSE_MOD_ENABLE 1
|
||||
|
||||
#endif /* _GIANT_PLATFORM_EMULATION_H_ */
|
||||
@@ -0,0 +1,98 @@
|
||||
/* Copyright (c) 1998,2006-2007 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
|
||||
* TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
|
||||
* SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
|
||||
* ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
|
||||
* INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
|
||||
* EXPOSE YOU TO LIABILITY.
|
||||
***************************************************************************
|
||||
|
||||
giantPortCommon.h - common header used to specify and access
|
||||
platform-dependent giant digit routines.
|
||||
|
||||
Revision History
|
||||
----------------
|
||||
1 Sep 98 Doug Mitchell at Apple
|
||||
Created.
|
||||
|
||||
*******************************/
|
||||
|
||||
#ifndef _GIANT_PORT_COMMON_H_
|
||||
#define _GIANT_PORT_COMMON_H_
|
||||
|
||||
#include <libGiants/giantTypes.h>
|
||||
|
||||
/*
|
||||
* This is a platform-dependent symbol that must be defined elsewhere,
|
||||
* typically in giantPlatform.h.
|
||||
*/
|
||||
#ifndef GI_GIANT_PORT_INLINE
|
||||
#error Please define GI_GIANT_PORT_INLINE.
|
||||
#endif
|
||||
|
||||
#if GI_GIANT_PORT_INLINE
|
||||
|
||||
/*
|
||||
* Vanilla C version using static inlines, should work on any platform,
|
||||
* though may not be the fastest possible implementation.
|
||||
*/
|
||||
#include <libGiants/giantPort_Generic.h>
|
||||
|
||||
#else /* GI_GIANT_PORT_INLINE */
|
||||
|
||||
/*
|
||||
* A platform-dependent implementation of these functions is required.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Add two digits, return sum. Carry bit returned as an out parameter.
|
||||
*/
|
||||
extern giantDigit giantAddDigits(
|
||||
giantDigit dig1,
|
||||
giantDigit dig2,
|
||||
giantDigit *carry); /* RETURNED, 0 or 1 */
|
||||
|
||||
/*
|
||||
* Add a single digit value to a double digit accumulator in place.
|
||||
* Carry out of the MSD of the accumulator is not handled.
|
||||
*/
|
||||
extern void giantAddDouble(
|
||||
giantDigit *accLow, /* IN/OUT */
|
||||
giantDigit *accHigh, /* IN/OUT */
|
||||
giantDigit val);
|
||||
|
||||
/*
|
||||
* Subtract a - b, return difference. Borrow bit returned as an out parameter.
|
||||
*/
|
||||
extern giantDigit giantSubDigits(
|
||||
giantDigit a,
|
||||
giantDigit b,
|
||||
giantDigit *borrow); /* RETURNED, 0 or 1 */
|
||||
|
||||
/*
|
||||
* Multiply two digits, return two digits.
|
||||
*/
|
||||
extern void giantMulDigits(
|
||||
giantDigit dig1,
|
||||
giantDigit dig2,
|
||||
giantDigit *lowProduct, /* RETURNED, low digit */
|
||||
giantDigit *hiProduct); /* RETURNED, high digit */
|
||||
|
||||
#if 0
|
||||
/* this is not currently used or needed */
|
||||
/*
|
||||
* Multiply a vector of giantDigits, candVector, by a single giantDigit,
|
||||
* plierDigit, adding results into prodVector. Returns m.s. digit from
|
||||
* final multiply; only candLength digits of *prodVector will be written.
|
||||
*/
|
||||
extern giantDigit VectorMultiply(
|
||||
giantDigit plierDigit,
|
||||
giantDigit *candVector,
|
||||
gi_size candLength,
|
||||
giantDigit *prodVector);
|
||||
#endif
|
||||
|
||||
#endif /* GI_GIANT_PORT_INLINE */
|
||||
|
||||
#endif /* _GIANT_PORT_COMMON_H_ */
|
||||
@@ -0,0 +1,143 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantPort_C.h - Generic giant definitions routines, used when
|
||||
* no platform-specific version is available.
|
||||
*
|
||||
* This module works on any size giantDigit up to and including
|
||||
* the native unsigned int, as long as the platform does indeed
|
||||
* supply a (2 x giantDigit) unsigned integer, defined (in
|
||||
* giantPlatform.h) as a giantDouble.
|
||||
*
|
||||
* Created Aug. 8 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#include <libGiants/giantTypes.h>
|
||||
#include <libGiants/giantIntegers.h>
|
||||
#include <libGiants/giantPortCommon.h>
|
||||
#include <libGiants/giantDebug.h>
|
||||
|
||||
#ifndef GI_GIANT_PORT_INLINE
|
||||
#error Please define GI_GIANT_PORT_INLINE.
|
||||
#endif
|
||||
|
||||
#if !GI_GIANT_PORT_INLINE
|
||||
/*
|
||||
* Add two digits, return sum. Carry bit returned as an out parameter.
|
||||
*/
|
||||
giantDigit giantAddDigits(
|
||||
giantDigit dig1,
|
||||
giantDigit dig2,
|
||||
giantDigit *carry) /* RETURNED, 0 or 1 */
|
||||
{
|
||||
giantDigit sum = dig1 + dig2;
|
||||
|
||||
GI_CHECK_SP("giantAddDigits");
|
||||
if((sum < dig1) || (sum < dig2)) {
|
||||
*carry = 1;
|
||||
}
|
||||
else {
|
||||
*carry = 0;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a single digit value to a double digit accumulator in place.
|
||||
* Carry out of the MSD of the accumulator is not handled.
|
||||
*/
|
||||
void giantAddDouble(
|
||||
giantDigit *accLow, /* IN/OUT */
|
||||
giantDigit *accHigh, /* IN/OUT */
|
||||
giantDigit val)
|
||||
{
|
||||
giantDigit sumLo = *accLow + val;
|
||||
|
||||
GI_CHECK_SP("giantAddDouble");
|
||||
if((sumLo < *accLow) || (sumLo < val)) {
|
||||
(*accHigh)++;
|
||||
/* if it's zero we just overflowed */
|
||||
GIASSERT(*accHigh != 0);
|
||||
}
|
||||
*accLow = sumLo;
|
||||
}
|
||||
|
||||
/*
|
||||
* Subtract a - b, return difference. Borrow bit returned as an out parameter.
|
||||
*/
|
||||
giantDigit giantSubDigits(
|
||||
giantDigit a,
|
||||
giantDigit b,
|
||||
giantDigit *borrow) /* RETURNED, 0 or 1 */
|
||||
{
|
||||
giantDigit diff = a - b;
|
||||
|
||||
GI_CHECK_SP("giantSubDigits");
|
||||
if(a < b) {
|
||||
*borrow = 1;
|
||||
}
|
||||
else {
|
||||
*borrow = 0;
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiply two digits, return two digits.
|
||||
*/
|
||||
void giantMulDigits(
|
||||
giantDigit dig1,
|
||||
giantDigit dig2,
|
||||
giantDigit *lowProduct, /* RETURNED, low digit */
|
||||
giantDigit *hiProduct) /* RETURNED, high digit */
|
||||
{
|
||||
giantDouble dprod;
|
||||
|
||||
GI_CHECK_SP("giantMulDigits");
|
||||
dprod = (giantDouble)dig1 * (giantDouble)dig2;
|
||||
*hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT);
|
||||
*lowProduct = (giantDigit)dprod;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* this is currently unused. */
|
||||
/*
|
||||
* Multiply a vector of giantDigits, candVector, by a single giantDigit,
|
||||
* plierDigit, adding results into prodVector. Returns m.s. digit from
|
||||
* final multiply; only candLength digits of *prodVector will be written.
|
||||
*/
|
||||
giantDigit VectorMultiply(
|
||||
giantDigit plierDigit,
|
||||
giantDigit *candVector,
|
||||
gi_size candLength,
|
||||
giantDigit *prodVector)
|
||||
{
|
||||
gi_size candDex; // index into multiplicandVector
|
||||
giantDigit lastCarry = 0;
|
||||
giantDigit prodLo;
|
||||
giantDigit prodHi;
|
||||
|
||||
for(candDex=0; candDex<candLength; ++candDex) {
|
||||
/*
|
||||
* prod = *(candVector++) * plierDigit + *prodVector + lastCarry
|
||||
*/
|
||||
giantMulDigits(*(candVector++),
|
||||
plierDigit,
|
||||
&prodLo,
|
||||
&prodHi);
|
||||
giantAddDouble(&prodLo, &prodHi, *prodVector);
|
||||
giantAddDouble(&prodLo, &prodHi, lastCarry);
|
||||
|
||||
/*
|
||||
* *(destptr++) = prodHi;
|
||||
* lastCarry = prodLo;
|
||||
*/
|
||||
*(prodVector++) = prodLo;
|
||||
lastCarry = prodHi;
|
||||
}
|
||||
|
||||
return lastCarry;
|
||||
}
|
||||
#endif /* 0 - VectorMultiply disabled */
|
||||
|
||||
#endif /* !GI_GIANT_PORT_INLINE */
|
||||
@@ -0,0 +1,160 @@
|
||||
/* Copyright (c) 1998,2006-2007 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
|
||||
* TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
|
||||
* SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
|
||||
* ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
|
||||
* INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
|
||||
* EXPOSE YOU TO LIABILITY.
|
||||
***************************************************************************
|
||||
*
|
||||
* giantPort_Generic.h - Generic giant definitions routines, implemented
|
||||
* as static inlines, used when no platform-specific version is available.
|
||||
*
|
||||
* This module works on any size giantDigit up to and including
|
||||
* the native unsigned int, as long as the platform does indeed
|
||||
* supply a (2 x giantDigit) unsigned integer, defined (in
|
||||
* giantPlatform.h) as a giantDouble.
|
||||
*
|
||||
* The module giantPort_C.c is functionaly identical to this
|
||||
* except that its routines are actual C functions instead of
|
||||
* inlines.
|
||||
*
|
||||
* Revision History
|
||||
* ----------------
|
||||
* 06 Apr 1998 Doug Mitchell at Apple
|
||||
* Created.
|
||||
*/
|
||||
|
||||
#ifndef _GIANT_PORT_GENERIC_H_
|
||||
#define _GIANT_PORT_GENERIC_H_
|
||||
|
||||
#include <libGiants/giantTypes.h>
|
||||
#include <libGiants/giantIntegers.h>
|
||||
#include <libGiants/giantDebug.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add two digits, return sum. Carry bit returned as an out parameter.
|
||||
*/
|
||||
static GI_INLINE giantDigit giantAddDigits(
|
||||
giantDigit dig1,
|
||||
giantDigit dig2,
|
||||
giantDigit *carry) /* RETURNED, 0 or 1 */
|
||||
{
|
||||
giantDigit sum = dig1 + dig2;
|
||||
|
||||
if((sum < dig1) || (sum < dig2)) {
|
||||
*carry = 1;
|
||||
}
|
||||
else {
|
||||
*carry = 0;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a single digit value to a double digit accumulator in place.
|
||||
* Carry out of the MSD of the accumulator is not handled.
|
||||
*/
|
||||
static GI_INLINE void giantAddDouble(
|
||||
giantDigit *accLow, /* IN/OUT */
|
||||
giantDigit *accHigh, /* IN/OUT */
|
||||
giantDigit val)
|
||||
{
|
||||
giantDigit sumLo = *accLow + val;
|
||||
|
||||
if((sumLo < *accLow) || (sumLo < val)) {
|
||||
(*accHigh)++;
|
||||
/* if it's zero we just overflowed */
|
||||
GIASSERT(*accHigh != 0);
|
||||
}
|
||||
*accLow = sumLo;
|
||||
}
|
||||
|
||||
/*
|
||||
* Subtract a - b, return difference. Borrow bit returned as an out parameter.
|
||||
*/
|
||||
static GI_INLINE giantDigit giantSubDigits(
|
||||
giantDigit a,
|
||||
giantDigit b,
|
||||
giantDigit *borrow) /* RETURNED, 0 or 1 */
|
||||
{
|
||||
giantDigit diff = a - b;
|
||||
|
||||
if(a < b) {
|
||||
*borrow = 1;
|
||||
}
|
||||
else {
|
||||
*borrow = 0;
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiply two digits, return two digits.
|
||||
*/
|
||||
static GI_INLINE void giantMulDigits(
|
||||
giantDigit dig1,
|
||||
giantDigit dig2,
|
||||
giantDigit *lowProduct, /* RETURNED, low digit */
|
||||
giantDigit *hiProduct) /* RETURNED, high digit */
|
||||
{
|
||||
giantDouble dprod;
|
||||
|
||||
dprod = (giantDouble)dig1 * (giantDouble)dig2;
|
||||
*hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT);
|
||||
*lowProduct = (giantDigit)dprod;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* this is not currently used or needed */
|
||||
|
||||
/*
|
||||
* Multiply a vector of giantDigits, candVector, by a single giantDigit,
|
||||
* plierDigit, adding results into prodVector. Returns m.s. digit from
|
||||
* final multiply; only candLength digits of *prodVector will be written.
|
||||
*/
|
||||
static GI_INLINE giantDigit VectorMultiply(
|
||||
giantDigit plierDigit,
|
||||
giantDigit *candVector,
|
||||
gi_size candLength,
|
||||
giantDigit *prodVector)
|
||||
{
|
||||
gi_size candDex; // index into multiplicandVector
|
||||
giantDigit lastCarry = 0;
|
||||
giantDigit prodLo;
|
||||
giantDigit prodHi;
|
||||
|
||||
for(candDex=0; candDex<candLength; ++candDex) {
|
||||
/*
|
||||
* prod = *(candVector++) * plierDigit + *prodVector + lastCarry
|
||||
*/
|
||||
giantMulDigits(*(candVector++),
|
||||
plierDigit,
|
||||
&prodLo,
|
||||
&prodHi);
|
||||
giantAddDouble(&prodLo, &prodHi, *prodVector);
|
||||
giantAddDouble(&prodLo, &prodHi, lastCarry);
|
||||
|
||||
/*
|
||||
* *(destptr++) = prodHi;
|
||||
* lastCarry = prodLo;
|
||||
*/
|
||||
*(prodVector++) = prodLo;
|
||||
lastCarry = prodHi;
|
||||
}
|
||||
|
||||
return lastCarry;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_GIANT_PORT_GENERIC_H_*/
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* giantTypes.h - Standard typedefs
|
||||
*
|
||||
* Created Aug. 5 2005 by Doug Mitchell.
|
||||
*/
|
||||
|
||||
#ifndef _GIANT_TYPES_H_
|
||||
#define _GIANT_TYPES_H_
|
||||
|
||||
#include <libGiants/giantPlatform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Standard return codes.
|
||||
*/
|
||||
typedef enum {
|
||||
GR_Success = 0,
|
||||
GR_IllegalArg, /* illegal argument */
|
||||
GR_Unimplemented, /* unimplemented function */
|
||||
GR_Internal, /* internal library error */
|
||||
GR_Overflow, /* caller error, buffer/giant overflow */
|
||||
} GIReturn;
|
||||
|
||||
/*
|
||||
* We administer the namespace for other libraries' return codes here, so
|
||||
* all can share a common space.
|
||||
*/
|
||||
#define SFEE_RETURN_BASE 1000 /* libSFEE */
|
||||
#define RSA_RETURN_BASE 2000 /* libgRSA */
|
||||
#define LIBCERT_RETURN_BASE 3000 /* libCert */
|
||||
#define DH_RETURN_BASE 4000 /* libgDH */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GIANT_TYPES_H_ */
|
||||
Reference in new issue
Block a user