]>
git.saurik.com Git - apple/security.git/blob - OSX/include/security_cryptkit/giantPort_Generic.h
1 /* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
11 * giantPort_Generic.h - Generic giant definitions routines, used when
12 * no platform-specific version is available.
16 * 06 Apr 1998 at Apple
20 #ifndef _CK_NSGIANT_PORT_GENERIC_H_
21 #define _CK_NSGIANT_PORT_GENERIC_H_
25 #include "giantIntegers.h"
32 * We'll be using the compiler's 64-bit long long for these routines.
34 * Mask for upper word.
36 #define GIANT_UPPER_DIGIT_MASK (~(unsigned long long(GIANT_DIGIT_MASK)))
39 * Multiple-precision arithmetic routines/macros.
43 * Add two digits, return sum. Carry bit returned as an out parameter.
44 * This should work any size giantDigits up to unsigned int.
46 static inline giantDigit
giantAddDigits(
49 giantDigit
*carry
) /* RETURNED, 0 or 1 */
51 giantDigit sum
= dig1
+ dig2
;
53 if((sum
< dig1
) || (sum
< dig2
)) {
59 return sum
& GIANT_DIGIT_MASK
;
63 * Add a single digit value to a double digit accumulator in place.
64 * Carry out of the MSD of the accumulator is not handled.
65 * This should work any size giantDigits up to unsigned int.
67 static inline void giantAddDouble(
68 giantDigit
*accLow
, /* IN/OUT */
69 giantDigit
*accHigh
, /* IN/OUT */
72 giantDigit sumLo
= *accLow
+ val
;
74 if((sumLo
< *accLow
) || (sumLo
< val
)) {
78 CKRaise("giantAddDouble overflow");
80 #endif /* FEE_DEBUG */
86 * Subtract a - b, return difference. Borrow bit returned as an out parameter.
87 * This should work any size giantDigits up to unsigned int.
89 static inline giantDigit
giantSubDigits(
92 giantDigit
*borrow
) /* RETURNED, 0 or 1 */
94 giantDigit diff
= a
- b
;
106 * Multiply two digits, return two digits.
107 * This should work for 16 or 32 bit giantDigits, though it's kind of
108 * inefficient for 16 bits.
110 static inline void giantMulDigits(
113 giantDigit
*lowProduct
, /* RETURNED, low digit */
114 giantDigit
*hiProduct
) /* RETURNED, high digit */
116 unsigned long long dprod
;
118 dprod
= (unsigned long long)dig1
* (unsigned long long)dig2
;
119 *hiProduct
= (giantDigit
)(dprod
>> GIANT_BITS_PER_DIGIT
);
120 *lowProduct
= (giantDigit
)dprod
;
124 * Multiply a vector of giantDigits, candVector, by a single giantDigit,
125 * plierDigit, adding results into prodVector. Returns m.s. digit from
126 * final multiply; only candLength digits of *prodVector will be written.
128 static inline giantDigit
VectorMultiply(
129 giantDigit plierDigit
,
130 giantDigit
*candVector
,
132 giantDigit
*prodVector
)
134 unsigned candDex
; // index into multiplicandVector
135 giantDigit lastCarry
= 0;
139 for(candDex
=0; candDex
<candLength
; ++candDex
) {
141 * prod = *(candVector++) * plierDigit + *prodVector + lastCarry
143 giantMulDigits(*(candVector
++),
147 giantAddDouble(&prodLo
, &prodHi
, *prodVector
);
148 giantAddDouble(&prodLo
, &prodHi
, lastCarry
);
151 * *(destptr++) = prodHi;
152 * lastCarry = prodLo;
154 *(prodVector
++) = prodLo
;
165 #endif /*_CK_NSGIANT_PORT_GENERIC_H_*/