XilinxProcessorIPLib/drivers/hdcp22_rx/src/xhdcp22_rx_crypt.c
int XHdcp22Rx_CalcMontNPrime(u8 *NPrime, const u8 *N, int NDigits)
{
	/* Verify arguments */
	Xil_AssertNonvoid(NPrime != NULL);
	Xil_AssertNonvoid(N != NULL);
	Xil_AssertNonvoid(NDigits == 16);

	u32 N_i[XHDCP22_RX_N_SIZE/4];
	u32 NPrime_i[XHDCP22_RX_N_SIZE/4];
	u32 R[XHDCP22_RX_N_SIZE/4];
	u32 RInv[XHDCP22_RX_N_SIZE/4];
	u32 T1[XHDCP22_RX_N_SIZE/2];
	u32 T2[XHDCP22_RX_N_SIZE/2];

	/* Clear variables */
	memset(N_i, 0, sizeof(N_i));
	memset(NPrime_i, 0, sizeof(NPrime_i));
	memset(R, 0, sizeof(R));
	memset(RInv, 0, sizeof(RInv));
	memset(T1, 0, sizeof(T1));
	memset(T2, 0, sizeof(T2));

	/* Convert from octet string */
	mpConvFromOctets(N_i, XHdcp22Rx_MpSizeof(N_i), N, 4*NDigits);

	/* Step 1: R = 2^(NDigits*32) */
	R[0] = 1;
	mpShiftLeft(R, R, 32*NDigits, XHdcp22Rx_MpSizeof(R));

	/* Step 2: Rinv = R^(-1)*mod(N) */
	T1[0] = 0;
	memcpy(T1, N_i, sizeof(N_i)); // Increase precision of N
	if(mpModInv(RInv, R, T1, XHdcp22Rx_MpSizeof(RInv)))
	{
		print("ERROR: Failed Rinv Calculation\r\n");
		return XST_FAILURE;
	}

	/* Step 3: NPrime = (R*Rinv-1)/N */
	mpMultiply(T1, R, RInv, 2*NDigits);
	memset(T2, 0, sizeof(T2));
	T2[0] = 1;
	mpSubtract(T1, T1, T2, XHdcp22Rx_MpSizeof(T1));
	mpDivide(NPrime_i, T2, T1, XHdcp22Rx_MpSizeof(NPrime_i), (u32 *)N_i, NDigits);

	/* Step 4: Sanity Check, R*Rinv - N*NPrime == 1 */
	mpMultiply(T1, R, RInv, 2*NDigits);
	mpMultiply(T2, (u32 *)N_i, NPrime_i, XHdcp22Rx_MpSizeof(NPrime_i));
	mpSubtract(T1, T1, T2, XHdcp22Rx_MpSizeof(T1));
	memset(T2, 0, sizeof(T2));
	T2[0] = 1;
	if(!mpEqual(T1, T2, XHdcp22Rx_MpSizeof(T1)))
	{
		print("ERROR: Failed NPrime Calculation\r\n");
		return XST_FAILURE;
	}

	/* Convert to octet string */
	mpConvToOctets(NPrime_i, NDigits, NPrime, 4*NDigits);

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function is used to calculate the Montgomery NPrime. NPrime is
* calculated from the following equation R*Rinv - N*NPrime == 1.
* For the HDCP2.2 receiver the modulus N has a fixed size
* of k = 512bits. Given k, the value R = 2^(k), and Rinv is the modular
* inverse of R.
*
* Reference:
* Analyzing and Comparing Montgomery Multiplication Algorithms
* IEEE Micro, 16(3):26-33,June 1996
* By: Cetin Koc, Tolga Acar, and Burton Kaliski
*
* @param	NPrime is the calculated value and 2*NDigits in Size.
* @param	N is modulus
* @param	NDigits is the integer precision of arguments (N, NPrime), which
* 			should always be 16 for the HDCP2.2 receiver.
*
* @return	XST_SUCCESS or FAILURE.
*
* @note		None.
******************************************************************************/
This function is used to calculate the Montgomery NPrime. NPrime is
calculated from the following equation R*Rinv - N*NPrime == 1.
For the HDCP2.2 receiver the modulus N has a fixed size
of k = 512bits. Given k, the value R = 2^(k), and Rinv is the modular
inverse of R.

Analyzing and Comparing Montgomery Multiplication Algorithms
IEEE Micro, 16(3):26-33,June 1996
By: Cetin Koc, Tolga Acar, and Burton Kaliski
This function is used to calculate the Montgomery NPrime . NPrime is calculated from the following equation R * Rinv - N * NPrime == 1 . For the HDCP2 . 2 receiver the modulus N has a fixed size of k = 512bits . Given k the value R = 2^ ( k ) and Rinv is the modular inverse of R . Analyzing and Comparing Montgomery Multiplication Algorithms IEEE Micro 16 ( 3 ) : 26 - 33 June 1996 By : Cetin Koc Tolga Acar and Burton Kaliski
int XHdcp22Rx_CalcMontNPrime(u8 *NPrime, const u8 *N, int NDigits)
{
	Xil_AssertNonvoid(NPrime != NULL);
	Xil_AssertNonvoid(N != NULL);
	Xil_AssertNonvoid(NDigits == 16);
	u32 N_i[XHDCP22_RX_N_SIZE/4];
	u32 NPrime_i[XHDCP22_RX_N_SIZE/4];
	u32 R[XHDCP22_RX_N_SIZE/4];
	u32 RInv[XHDCP22_RX_N_SIZE/4];
	u32 T1[XHDCP22_RX_N_SIZE/2];
	u32 T2[XHDCP22_RX_N_SIZE/2];
	memset(N_i, 0, sizeof(N_i));
	memset(NPrime_i, 0, sizeof(NPrime_i));
	memset(R, 0, sizeof(R));
	memset(RInv, 0, sizeof(RInv));
	memset(T1, 0, sizeof(T1));
	memset(T2, 0, sizeof(T2));
	mpConvFromOctets(N_i, XHdcp22Rx_MpSizeof(N_i), N, 4*NDigits);
	R[0] = 1;
	mpShiftLeft(R, R, 32*NDigits, XHdcp22Rx_MpSizeof(R));
	T1[0] = 0;
	memcpy(T1, N_i, sizeof(N_i)); 
	if(mpModInv(RInv, R, T1, XHdcp22Rx_MpSizeof(RInv)))
	{
		print("ERROR: Failed Rinv Calculation\r\n");
		return XST_FAILURE;
	}
	mpMultiply(T1, R, RInv, 2*NDigits);
	memset(T2, 0, sizeof(T2));
	T2[0] = 1;
	mpSubtract(T1, T1, T2, XHdcp22Rx_MpSizeof(T1));
	mpDivide(NPrime_i, T2, T1, XHdcp22Rx_MpSizeof(NPrime_i), (u32 *)N_i, NDigits);
	mpMultiply(T1, R, RInv, 2*NDigits);
	mpMultiply(T2, (u32 *)N_i, NPrime_i, XHdcp22Rx_MpSizeof(NPrime_i));
	mpSubtract(T1, T1, T2, XHdcp22Rx_MpSizeof(T1));
	memset(T2, 0, sizeof(T2));
	T2[0] = 1;
	if(!mpEqual(T1, T2, XHdcp22Rx_MpSizeof(T1)))
	{
		print("ERROR: Failed NPrime Calculation\r\n");
		return XST_FAILURE;
	}
	mpConvToOctets(NPrime_i, NDigits, NPrime, 4*NDigits);
	return XST_SUCCESS;
}
int XHdcp22Rx_CalcMontNPrime ( u8 * NPrime , const u8 * N , int NDigits ) { Xil_AssertNonvoid ( NPrime != NULL ) ; Xil_AssertNonvoid ( N != NULL ) ; Xil_AssertNonvoid ( NDigits == 16 ) ; u32 N_i [ XHDCP22_RX_N_SIZE / 4 ] ; u32 NPrime_i [ XHDCP22_RX_N_SIZE / 4 ] ; u32 R [ XHDCP22_RX_N_SIZE / 4 ] ; u32 RInv [ XHDCP22_RX_N_SIZE / 4 ] ; u32 T1 [ XHDCP22_RX_N_SIZE / 2 ] ; u32 T2 [ XHDCP22_RX_N_SIZE / 2 ] ; memset ( N_i , 0 , sizeof ( N_i ) ) ; memset ( NPrime_i , 0 , sizeof ( NPrime_i ) ) ; memset ( R , 0 , sizeof ( R ) ) ; memset ( RInv , 0 , sizeof ( RInv ) ) ; memset ( T1 , 0 , sizeof ( T1 ) ) ; memset ( T2 , 0 , sizeof ( T2 ) ) ; mpConvFromOctets ( N_i , XHdcp22Rx_MpSizeof ( N_i ) , N , 4 * NDigits ) ; R [ 0 ] = 1 ; mpShiftLeft ( R , R , 32 * NDigits , XHdcp22Rx_MpSizeof ( R ) ) ; T1 [ 0 ] = 0 ; memcpy ( T1 , N_i , sizeof ( N_i ) ) ; if ( mpModInv ( RInv , R , T1 , XHdcp22Rx_MpSizeof ( RInv ) ) ) { print ( " \r \n " ) ; return XST_FAILURE ; } mpMultiply ( T1 , R , RInv , 2 * NDigits ) ; memset ( T2 , 0 , sizeof ( T2 ) ) ; T2 [ 0 ] = 1 ; mpSubtract ( T1 , T1 , T2 , XHdcp22Rx_MpSizeof ( T1 ) ) ; mpDivide ( NPrime_i , T2 , T1 , XHdcp22Rx_MpSizeof ( NPrime_i ) , ( u32 * ) N_i , NDigits ) ; mpMultiply ( T1 , R , RInv , 2 * NDigits ) ; mpMultiply ( T2 , ( u32 * ) N_i , NPrime_i , XHdcp22Rx_MpSizeof ( NPrime_i ) ) ; mpSubtract ( T1 , T1 , T2 , XHdcp22Rx_MpSizeof ( T1 ) ) ; memset ( T2 , 0 , sizeof ( T2 ) ) ; T2 [ 0 ] = 1 ; if ( ! mpEqual ( T1 , T2 , XHdcp22Rx_MpSizeof ( T1 ) ) ) { print ( " \r \n " ) ; return XST_FAILURE ; } mpConvToOctets ( NPrime_i , NDigits , NPrime , 4 * NDigits ) ; return XST_SUCCESS ; }
This function is used to calculate the Montgomery NPrime.
This function is used to calculate the Montgomery NPrime .
/* Verify arguments */ /* Clear variables */ /* Convert from octet string */ /* Step 1: R = 2^(NDigits*32) */ /* Step 2: Rinv = R^(-1)*mod(N) */ // Increase precision of N /* Step 3: NPrime = (R*Rinv-1)/N */ /* Step 4: Sanity Check, R*Rinv - N*NPrime == 1 */ /* Convert to octet string */