XilinxProcessorIPLib/drivers/hdcp22_rx/src/xhdcp22_rx_crypt.c
static void XHdcp22Rx_Pkcs1MontMultFiosStub(u32 *U, u32 *A, u32 *B,
	u32 *N, const u32 *NPrime, int NDigits)
{
	/* Verify arguments */
	Xil_AssertVoid(U != NULL);
	Xil_AssertVoid(A != NULL);
	Xil_AssertVoid(B != NULL);
	Xil_AssertVoid(N != NULL);
	Xil_AssertVoid(NPrime != NULL);
	Xil_AssertVoid(NDigits == 16);

	int i, j;
	u32 S, C, C1, C2, M[2], X[2];
	u32 T[XHDCP22_RX_N_SIZE];

	memset(T, 0, 4*(NDigits+3));

	for(i=0; i<NDigits; i++)
	{
		// (C,S) = t[0] + a[0]*b[i], worst case 2 words
		spMultiply(X, A[0], B[i]);	// X[Upper,Lower] = a[0]*b[i]
		C = mpAdd(&S, T+0, X+0, 1);	// [C,S] = t[0] + X[Lower]
		mpAdd(&C, &C, X+1, 1);		// [~,C] = C + X[Upper], No carry

		// ADD(t[1],C)
		XHdcp22Rx_Pkcs1MontMultAdd(T, C, 1, NDigits+3);

		// m = S*n'[0] mod W, where W=2^32
		// Note: X[Upper,Lower] = S*n'[0], m=X[Lower]
		spMultiply(M, S, NPrime[0]);

		// (C,S) = S + m*n[0], worst case 2 words
		spMultiply(X, M[0], N[0]);	// X[Upper,Lower] = m*n[0]
		C = mpAdd(&S, &S, X+0, 1);	// [C,S] = S + X[Lower]
		mpAdd(&C, &C, X+1, 1);		// [~,C] = C + X[Upper]

		for(j=1; j<NDigits; j++)
		{
			// (C,S) = t[j] + a[j]*b[i] + C, worst case 2 words
			spMultiply(X, A[j], B[i]);	 	// X[Upper,Lower] = a[j]*b[i], double precision
			C1 = mpAdd(&S, T+j, &C, 1);		// (C1,S) = t[j] + C
			C2 = mpAdd(&S, &S, X+0, 1); 	// (C2,S) = S + X[Lower]
			mpAdd(&C, &C1, X+1, 1);			// (~,C)  = C1 + X[Upper], doesn't produce carry
			mpAdd(&C, &C, &C2, 1); 			// (~,C)  = C + C2, doesn't produce carry

			// ADD(t[j+1],C)
			XHdcp22Rx_Pkcs1MontMultAdd(T, C, j+1, NDigits+3);

			// (C,S) = S + m*n[j]
			spMultiply(X, M[0], N[j]);	// X[Upper,Lower] = m*n[j]
			C = mpAdd(&S, &S, X+0, 1);	// [C,S] = S + X[Lower]
			mpAdd(&C, &C, X+1, 1);		// [~,C] = C + X[Upper]

			// t[j-1] = S
			T[j-1] = S;
		}

		// (C,S) = t[s] + C
		C = mpAdd(&S, T+NDigits, &C, 1);
		// t[s-1] = S
		T[NDigits-1] = S;
		// t[s] = t[s+1] + C
		mpAdd(T+NDigits, T+NDigits+1, &C, 1);
		// t[s+1] = 0
		T[NDigits+1] = 0;
	}

	/* Step 3: if(u>=n) return u-n else return u */
	if(mpCompare(T, N, NDigits+3) >= 0)
	{
		mpSubtract(T, T, N, NDigits+3);
	}

	memcpy(U, T, 4*NDigits);
}
/****************************************************************************/
/**
* This function implements the Montgomery Modular Multiplication (MMM)
* Finely Integrated Operand Scanning (FIOS) algorithm. The FIOS method
* interleaves multiplication and reduction operations. Requires NDigits+3
* words of temporary storage.
*
* U = MontMult(A,B,N)
*
* Reference:
* Analyzing and Comparing Montgomery Multiplication Algorithms
* IEEE Micro, 16(3):26-33,June 1996
* By: Cetin Koc, Tolga Acar, and Burton Kaliski
*
* @param	U is the MMM result
* @param	A is the n-residue input, A' = A*R mod N
* @param	B is the n-residue input, B' = B*R mod N
* @param	N is the modulus
* @param	NPrime is a pre-computed constant, NPrime = (1-R*Rbar)/N
* @param	NDigits is the integer precision of the arguments (C,A,B,N,NPrime)
*
* @return	None.
*
* @note		None.
*****************************************************************************/
This function implements the Montgomery Modular Multiplication (MMM)
Finely Integrated Operand Scanning (FIOS) algorithm. The FIOS method
interleaves multiplication and reduction operations. Requires NDigits+3
words of temporary storage.



Analyzing and Comparing Montgomery Multiplication Algorithms
IEEE Micro, 16(3):26-33,June 1996
By: Cetin Koc, Tolga Acar, and Burton Kaliski
This function implements the Montgomery Modular Multiplication ( MMM ) Finely Integrated Operand Scanning ( FIOS ) algorithm . The FIOS method interleaves multiplication and reduction operations . Requires NDigits + 3 words of temporary storage . Analyzing and Comparing Montgomery Multiplication Algorithms IEEE Micro 16 ( 3 ) : 26 - 33 June 1996 By : Cetin Koc Tolga Acar and Burton Kaliski
static void XHdcp22Rx_Pkcs1MontMultFiosStub(u32 *U, u32 *A, u32 *B,
	u32 *N, const u32 *NPrime, int NDigits)
{
	Xil_AssertVoid(U != NULL);
	Xil_AssertVoid(A != NULL);
	Xil_AssertVoid(B != NULL);
	Xil_AssertVoid(N != NULL);
	Xil_AssertVoid(NPrime != NULL);
	Xil_AssertVoid(NDigits == 16);
	int i, j;
	u32 S, C, C1, C2, M[2], X[2];
	u32 T[XHDCP22_RX_N_SIZE];
	memset(T, 0, 4*(NDigits+3));
	for(i=0; i<NDigits; i++)
	{
		spMultiply(X, A[0], B[i]);	
		C = mpAdd(&S, T+0, X+0, 1);	
		mpAdd(&C, &C, X+1, 1);		
		XHdcp22Rx_Pkcs1MontMultAdd(T, C, 1, NDigits+3);
		spMultiply(M, S, NPrime[0]);
		spMultiply(X, M[0], N[0]);	
		C = mpAdd(&S, &S, X+0, 1);	
		mpAdd(&C, &C, X+1, 1);		
		for(j=1; j<NDigits; j++)
		{
			spMultiply(X, A[j], B[i]);	 	
			C1 = mpAdd(&S, T+j, &C, 1);		
			C2 = mpAdd(&S, &S, X+0, 1); 	
			mpAdd(&C, &C1, X+1, 1);			
			mpAdd(&C, &C, &C2, 1); 			
			XHdcp22Rx_Pkcs1MontMultAdd(T, C, j+1, NDigits+3);
			spMultiply(X, M[0], N[j]);	
			C = mpAdd(&S, &S, X+0, 1);	
			mpAdd(&C, &C, X+1, 1);		
			T[j-1] = S;
		}
		C = mpAdd(&S, T+NDigits, &C, 1);
		T[NDigits-1] = S;
		mpAdd(T+NDigits, T+NDigits+1, &C, 1);
		T[NDigits+1] = 0;
	}
	if(mpCompare(T, N, NDigits+3) >= 0)
	{
		mpSubtract(T, T, N, NDigits+3);
	}
	memcpy(U, T, 4*NDigits);
}
static void XHdcp22Rx_Pkcs1MontMultFiosStub ( u32 * U , u32 * A , u32 * B , u32 * N , const u32 * NPrime , int NDigits ) { Xil_AssertVoid ( U != NULL ) ; Xil_AssertVoid ( A != NULL ) ; Xil_AssertVoid ( B != NULL ) ; Xil_AssertVoid ( N != NULL ) ; Xil_AssertVoid ( NPrime != NULL ) ; Xil_AssertVoid ( NDigits == 16 ) ; int i , j ; u32 S , C , C1 , C2 , M [ 2 ] , X [ 2 ] ; u32 T [ XHDCP22_RX_N_SIZE ] ; memset ( T , 0 , 4 * ( NDigits + 3 ) ) ; for ( i = 0 ; i < NDigits ; i ++ ) { spMultiply ( X , A [ 0 ] , B [ i ] ) ; C = mpAdd ( & S , T + 0 , X + 0 , 1 ) ; mpAdd ( & C , & C , X + 1 , 1 ) ; XHdcp22Rx_Pkcs1MontMultAdd ( T , C , 1 , NDigits + 3 ) ; spMultiply ( M , S , NPrime [ 0 ] ) ; spMultiply ( X , M [ 0 ] , N [ 0 ] ) ; C = mpAdd ( & S , & S , X + 0 , 1 ) ; mpAdd ( & C , & C , X + 1 , 1 ) ; for ( j = 1 ; j < NDigits ; j ++ ) { spMultiply ( X , A [ j ] , B [ i ] ) ; C1 = mpAdd ( & S , T + j , & C , 1 ) ; C2 = mpAdd ( & S , & S , X + 0 , 1 ) ; mpAdd ( & C , & C1 , X + 1 , 1 ) ; mpAdd ( & C , & C , & C2 , 1 ) ; XHdcp22Rx_Pkcs1MontMultAdd ( T , C , j + 1 , NDigits + 3 ) ; spMultiply ( X , M [ 0 ] , N [ j ] ) ; C = mpAdd ( & S , & S , X + 0 , 1 ) ; mpAdd ( & C , & C , X + 1 , 1 ) ; T [ j - 1 ] = S ; } C = mpAdd ( & S , T + NDigits , & C , 1 ) ; T [ NDigits - 1 ] = S ; mpAdd ( T + NDigits , T + NDigits + 1 , & C , 1 ) ; T [ NDigits + 1 ] = 0 ; } if ( mpCompare ( T , N , NDigits + 3 ) >= 0 ) { mpSubtract ( T , T , N , NDigits + 3 ) ; } memcpy ( U , T , 4 * NDigits ) ; }
This function implements the Montgomery Modular Multiplication (MMM)
Finely Integrated Operand Scanning (FIOS) algorithm.
This function implements the Montgomery Modular Multiplication ( MMM ) Finely Integrated Operand Scanning ( FIOS ) algorithm .
/* Verify arguments */ // (C,S) = t[0] + a[0]*b[i], worst case 2 words // X[Upper,Lower] = a[0]*b[i] // [C,S] = t[0] + X[Lower] // [~,C] = C + X[Upper], No carry // ADD(t[1],C) // m = S*n'[0] mod W, where W=2^32 // Note: X[Upper,Lower] = S*n'[0], m=X[Lower] // (C,S) = S + m*n[0], worst case 2 words // X[Upper,Lower] = m*n[0] // [C,S] = S + X[Lower] // [~,C] = C + X[Upper] // (C,S) = t[j] + a[j]*b[i] + C, worst case 2 words // X[Upper,Lower] = a[j]*b[i], double precision // (C1,S) = t[j] + C // (C2,S) = S + X[Lower] // (~,C)  = C1 + X[Upper], doesn't produce carry // (~,C)  = C + C2, doesn't produce carry // ADD(t[j+1],C) // (C,S) = S + m*n[j] // X[Upper,Lower] = m*n[j] // [C,S] = S + X[Lower] // [~,C] = C + X[Upper] // t[j-1] = S // (C,S) = t[s] + C // t[s-1] = S // t[s] = t[s+1] + C // t[s+1] = 0 /* Step 3: if(u>=n) return u-n else return u */