1/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. 2 * 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 COMPUTER, INC. AND THE 6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER, 7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL 8 * EXPOSE YOU TO LIABILITY. 9 *************************************************************************** 10 * 11 * giantPort_Generic.h - Generic giant definitions routines, used when 12 * no platform-specific version is available. 13 * 14 * Revision History 15 * ---------------- 16 * 06 Apr 1998 Doug Mitchell at Apple 17 * Created. 18 */ 19 20#ifndef _CK_NSGIANT_PORT_GENERIC_H_ 21#define _CK_NSGIANT_PORT_GENERIC_H_ 22 23#include "feeDebug.h" 24#include "platform.h" 25#include "giantIntegers.h" 26 27#ifdef __cplusplus 28extern "C" { 29#endif 30 31/* 32 * We'll be using the compiler's 64-bit long long for these routines. 33 * 34 * Mask for upper word. 35 */ 36#define GIANT_UPPER_DIGIT_MASK (~(unsigned long long(GIANT_DIGIT_MASK))) 37 38/* 39 * Multiple-precision arithmetic routines/macros. 40 */ 41 42/* 43 * Add two digits, return sum. Carry bit returned as an out parameter. 44 * This should work any size giantDigits up to unsigned int. 45 */ 46static inline giantDigit giantAddDigits( 47 giantDigit dig1, 48 giantDigit dig2, 49 giantDigit *carry) /* RETURNED, 0 or 1 */ 50{ 51 giantDigit sum = dig1 + dig2; 52 53 if((sum < dig1) || (sum < dig2)) { 54 *carry = 1; 55 } 56 else { 57 *carry = 0; 58 } 59 return sum & GIANT_DIGIT_MASK; 60} 61 62/* 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. 66 */ 67static inline void giantAddDouble( 68 giantDigit *accLow, /* IN/OUT */ 69 giantDigit *accHigh, /* IN/OUT */ 70 giantDigit val) 71{ 72 giantDigit sumLo = *accLow + val; 73 74 if((sumLo < *accLow) || (sumLo < val)) { 75 (*accHigh)++; 76 #if FEE_DEBUG 77 if(*accHigh == 0) { 78 CKRaise("giantAddDouble overflow"); 79 } 80 #endif /* FEE_DEBUG */ 81 } 82 *accLow = sumLo; 83} 84 85/* 86 * Subtract a - b, return difference. Borrow bit returned as an out parameter. 87 * This should work any size giantDigits up to unsigned int. 88 */ 89static inline giantDigit giantSubDigits( 90 giantDigit a, 91 giantDigit b, 92 giantDigit *borrow) /* RETURNED, 0 or 1 */ 93{ 94 giantDigit diff = a - b; 95 96 if(a < b) { 97 *borrow = 1; 98 } 99 else { 100 *borrow = 0; 101 } 102 return diff; 103} 104 105/* 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. 109 */ 110static inline void giantMulDigits( 111 giantDigit dig1, 112 giantDigit dig2, 113 giantDigit *lowProduct, /* RETURNED, low digit */ 114 giantDigit *hiProduct) /* RETURNED, high digit */ 115{ 116 unsigned long long dprod; 117 118 dprod = (unsigned long long)dig1 * (unsigned long long)dig2; 119 *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); 120 *lowProduct = (giantDigit)dprod; 121} 122 123/* 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. 127 */ 128static inline giantDigit VectorMultiply( 129 giantDigit plierDigit, 130 giantDigit *candVector, 131 unsigned candLength, 132 giantDigit *prodVector) 133{ 134 unsigned candDex; // index into multiplicandVector 135 giantDigit lastCarry = 0; 136 giantDigit prodLo; 137 giantDigit prodHi; 138 139 for(candDex=0; candDex<candLength; ++candDex) { 140 /* 141 * prod = *(candVector++) * plierDigit + *prodVector + lastCarry 142 */ 143 giantMulDigits(*(candVector++), 144 plierDigit, 145 &prodLo, 146 &prodHi); 147 giantAddDouble(&prodLo, &prodHi, *prodVector); 148 giantAddDouble(&prodLo, &prodHi, lastCarry); 149 150 /* 151 * *(destptr++) = prodHi; 152 * lastCarry = prodLo; 153 */ 154 *(prodVector++) = prodLo; 155 lastCarry = prodHi; 156 } 157 158 return lastCarry; 159} 160 161#ifdef __cplusplus 162extern "C" { 163#endif 164 165#endif /*_CK_NSGIANT_PORT_GENERIC_H_*/ 166