iBoot/lib/pki/libGiants/giantPort_Generic.h

161 lines
3.9 KiB
C
Raw Permalink Normal View History

2023-07-08 13:03:17 -07:00
/* 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_*/