Milán Major

netscape-revival

1 branch
Code

security/lib/crypto/cmpspprt.h

/* Copyright (C) RSA Data Security, Inc. created 1995.  This is an
   unpublished work protected as such under copyright law.  This work
   contains proprietary, confidential, and trade secret information of
   RSA Data Security, Inc.  Use, disclosure or reproduction without the
   express written authorization of RSA Data Security, Inc. is
   prohibited.
 */

/* This file contatins function prototypes for various support routines.
     Any source code that includes this header file should also include
     cmp.h first.
 */

#ifndef __cmpspprt_h_
#define __cmpspprt_h_

int CMP_GetOffsetOfMSB(CMPInt *theInt, int *offset);
int CMP_ShiftLeftByCMPWords(int shiftCount, CMPInt *base);
int CMP_ShiftRightByCMPWords(int shiftCount, CMPInt *base);
int CMP_ShiftLeftByBits(int leftShift, CMPInt *base);
int CMP_ShiftRightByBits(int rightShift, CMPInt *base);

/* targIndex is the target index for the most significant word. If the
     (targIndex)th word of base is non zero, we met the target. If it is
     zero, check the next word. Keep checking until a non zero word is
     found or there are no more words, whichever comes first. Then, set
     the length of base appropriately.
 */
int CMP_RecomputeLength(int targIndex, CMPInt *base);

/* Operate on two CMPInt's, placing the result into the second argument. */
int CMP_AddInPlace(CMPInt *increment, CMPInt *base);
int CMP_SubtractInPlace(CMPInt *decrement, CMPInt *base);

/* Computes coeffA, coeffB, and gcd such that
 *    (coeffA * u) mod v = gcd(u,v) and
 *    (coeffB * v) mod u = gcd(u,v)
 */
int CMP_ComputeExtendedGCD(CMPInt *u, CMPInt *v, CMPInt *coeffA,
			   CMPInt *coeffB, CMPInt *gcd);

/* Convert a CMPInt to and from Montgomery representation. */
int CMP_ConvertToMont(CMPInt *sourceCMPInt, CMPInt *modulus, CMPInt *montRep);
int CMP_ConvertFromMont(CMPInt *montRep, CMPInt *modulus, CMPWord n0Prime,
			CMPInt *reducedCMP);

int CMP_MontSquare(CMPInt *operand, CMPInt *modulus, CMPWord n0Prime,
		   CMPInt *montSquare);
int CMP_MontProduct(CMPInt *multiplicand, CMPInt *multiplier, CMPInt *modulus,
		    CMPWord n0Prime, CMPInt *montProduct);
/* Compute n0Prime */
int CMP_ComputeMontCoeff(CMPInt *n, CMPWord *n0Prime);

/* vectorB = (scaler * vectorA[indexA ... indexA+lengthA]) +
 *                     vectorB[indexB ... indexB+lengthA]
 */
void CMP_VectorMultiply(CMPWord scaler, CMPInt *vectorA, int indexA,
			int lengthA, CMPInt *vectorB, int indexB);

/* This is used by the Montgomery code.  You don't want to know what it does. */
void CMP_AddInTrace(CMPInt *vectorA, CMPInt *vectorB);

/* Macros for multiplying and squaring two CMPWords, then either keeping
     both the high and low CMPWord result, or simply keeping the low
     CMPWord result.
 */
#if CMP_DEC_ALPHA == 1
#include <c_asm.h>
#define CMP_MULT_LOW(a , b, lowProd) {\
  lowProd = asm ("mulq %a0, %a1, %v0", a, b);\
  }

#define CMP_MULT_HIGHLOW(a , b, lowProd, highProd) {\
  lowProd  = asm ("mulq %a0, %a1, %v0", a, b);\
  highProd = asm ("umulh %a0, %a1, %v0", a, b);\
  }

#define CMP_SQUARE_HIGHLOW(a, lowProd, highProd) {\
  lowProd  = asm ("mulq %a0, %a0, %v0", a);\
  highProd = asm ("umulh %a0, %a0, %v0", a);\
  }

#else   /* CMP_DEC_ALPHA */
#define CMP_MULT_LOW(a , b, lowProd) {\
  CMPWord mixProd;\
  CMPWord lowWordA, lowWordB, highWordA, highWordB;\
  lowWordA  = CMP_LOW_WORD (a);\
  lowWordB  = CMP_LOW_WORD (b);\
  highWordA = CMP_HIGH_WORD (a);\
  highWordB = CMP_HIGH_WORD (b);\
  lowProd   = lowWordA * lowWordB;\
  mixProd   = lowWordA * highWordB + highWordA * lowWordB;\
  mixProd <<= CMP_HALF_WORD_SIZE;\
  lowProd  += mixProd;\
  }

#ifdef __GNUC__
#define CMP_MULT_HIGHLOW(a , b, lowProd, highProd) {\
  unsigned long long foo;\
  foo = ((unsigned long long)a) * ((unsigned long long)b);\
  lowProd = foo;\
  highProd = foo >> 32;\
}
#else
#define CMP_MULT_HIGHLOW(a , b, lowProd, highProd) {\
  CMPWord a1b0, a0b1, mixProd;\
  CMPWord lowWordA, lowWordB, highWordA, highWordB;\
  lowWordA  = CMP_LOW_WORD (a);\
  lowWordB  = CMP_LOW_WORD (b);\
  highWordA = CMP_HIGH_WORD (a);\
  highWordB = CMP_HIGH_WORD (b);\
  lowProd   = lowWordA * lowWordB;\
  highProd  = highWordA * highWordB;\
  a0b1      = lowWordA * highWordB;\
  a1b0      = lowWordB * highWordA;\
  mixProd   = a0b1 + a1b0;\
  if (mixProd < a0b1) highProd += CMP_SQRT_RADIX ;\
  highProd += CMP_HIGH_WORD (mixProd);\
  mixProd <<= CMP_HALF_WORD_SIZE;\
  lowProd  += mixProd;\
  if (lowProd < mixProd) highProd++;\
  }
#endif

#define CMP_SQUARE_HIGHLOW(a, lowProd, highProd) {\
  CMPWord a0a1, mixProd;\
  CMPWord lowHalfA, highHalfA;\
  lowHalfA  = CMP_LOW_WORD (a);\
  highHalfA = CMP_HIGH_WORD (a);\
  lowProd   = lowHalfA * lowHalfA;\
  highProd  = highHalfA * highHalfA;\
  a0a1      = lowHalfA * highHalfA;\
  mixProd   = a0a1 << 1;\
  if (mixProd < a0a1) highProd += CMP_SQRT_RADIX ;\
  highProd += CMP_HIGH_WORD (mixProd);\
  mixProd <<= CMP_HALF_WORD_SIZE;\
  lowProd  += mixProd;\
  if (lowProd < mixProd) highProd++;\
}
#endif    /* CMP_DEC_ALPHA */

#endif    /* __cmpspprt_h_ */