2 * Copyright (c) 2006-2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 * @brief Big number library
24 ////////////////////////////////////////////////////////////////////////////
25 // Include Header Files
26 ////////////////////////////////////////////////////////////////////////////
27 #include "cc_bignum.h"
28 #include "cc_fast_math.h"
29 ////////////////////////////////////////////////////////////////////////////
31 ////////////////////////////////////////////////////////////////////////////
32 cc_u32 DWD_Zero[2] = {0, 0};
33 cc_u32 DWD_One[2] = {1, 0};
35 SDRM_BIG_NUM _BN_Zero = {0, 0, 2, DWD_Zero};
36 SDRM_BIG_NUM _BN_One = {0, 1, 2, DWD_One};
38 SDRM_BIG_NUM *BN_Zero = &_BN_Zero;
39 SDRM_BIG_NUM *BN_One = &_BN_One;
41 ////////////////////////////////////////////////////////////////////////////
42 // Local Functon Protypes
43 ////////////////////////////////////////////////////////////////////////////
44 int SDRM_DWD_Classical_REDC(cc_u32 *pdDest, cc_u32 DstLen, cc_u32 *pdModulus, cc_u32 ModLen);
46 #ifdef _OP64_NOTSUPPORTED
48 #define SDRM_HL(A) (cc_u32)(((A) >> 16) & 0xffffu)
49 #define SDRM_LL(A) (cc_u32)((A) & 0xffffu)
50 #define SDRM_LH(A) (cc_u32)(((A) & 0xffffu) << 16)
55 * @brief Double-width UINT32 Multiplication
57 * \n Dest [out]destination, 2-cc_u32-size array
58 * \n Src1 [in]first element
59 * \n Src2 [in]second element
63 void SDRM_DIGIT_Mul(cc_u32 *Dest, cc_u32 Src1, cc_u32 Src2)
65 cc_u32 Da, Db, R1, R0;
67 R1 = SDRM_HL(Src1) * SDRM_HL(Src2);
68 R0 = SDRM_LL(Src1) * SDRM_LL(Src2);
70 Da = SDRM_HL(Src1) * SDRM_LL(Src2);
71 Db = SDRM_LL(Src1) * SDRM_HL(Src2);
73 if ((Db += Da) < Da) {
74 R1 += ((cc_u32)1) << 16;
76 if ((R0 += SDRM_LH(Db)) < SDRM_LH(Db)) {
81 Dest[1] = R1 + SDRM_HL(Db);
88 * @brief Doublue-width DWROD Division
90 * \n Src1 [in]upper-digit of dividend
91 * \n Src2 [in]lower-digit of dividend
94 cc_u32 SDRM_DIGIT_Div(cc_u32 Src1, cc_u32 Src2, cc_u32 Div)
96 cc_u32 Dq, Dr, Dx, Dy, Dt;
98 // Estimate high half of quotient
99 Dq = Src1 / (SDRM_HL(Div) + 1);
101 // Subtract the product of estimate and divisor from the dividend
102 Dr = Src1 - (SDRM_HL(Div) * Dq);
104 Dy = SDRM_LH(Dr) + SDRM_HL(Src2);
105 if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
111 while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
113 if((Dr -= Div) > NOT(Div))
121 // Estimate low half of quotient
122 Dq = Dr / (SDRM_HL(Div) + 1);
124 // Subtract the product of estimate and divisor from the dividend
125 Dr -= SDRM_HL(Div) * Dq;
127 Dy = SDRM_LH(Dr) + SDRM_LL(Src2);
128 if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy) {
133 while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
135 if ((Dr -= Div) > NOT(Div))
147 * @brief Doublue-width DWROD Modular
149 * \n Src1 [in]upper-digit of dividend
150 * \n Src2 [in]lower-digit of dividend
153 cc_u32 SDRM_DIGIT_Mod(cc_u32 Src1, cc_u32 Src2, cc_u32 Div)
155 cc_u32 Dq, Dr, Dx, Dy;
157 // Estimate high half of quotient
158 Dq = Src1 / (SDRM_HL(Div) + 1);
160 // Subtract the from dividend the product of estimate and divisor
161 Dr = Src1 - (SDRM_HL(Div) * Dq);
163 Dy = SDRM_LH(Dr) + SDRM_HL(Src2);
164 if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
170 while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
172 if ((Dr -= Div) > NOT(Div))
178 // Estimate low half of quotient
179 Dq = Dr / (SDRM_HL(Div) + 1);
181 // Subtract the from dividend the product of estimate and divisor
182 Dr -= SDRM_HL(Div) * Dq;
184 Dy = SDRM_LH(Dr) + SDRM_LL(Src2);
185 if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
191 while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
193 if ((Dr -= Div) > NOT(Div) )
202 #endif //_OP64_NOTSUPPORTED
206 * @brief cc_u32 Array Comparison
208 * @param pdSrc1 [in]first element
209 * @param dSrcLen1 [in]legnth of pdSrc1
210 * @param pdSrc2 [in]second element
211 * @param dSrcLen2 [in]legnth of pdSrc2
213 * @return 1 if pdSrc1 is larger than pdSrc2
215 * \n -1 if pdSrc2 is larger than pdSrc1
217 static int SDRM_DWD_Cmp(cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
221 //When the length is different
222 if (dSrcLen1 >= dSrcLen2)
224 for (i = dSrcLen1 - 1; i != dSrcLen2 - 1; i--)
234 for (i = dSrcLen2 - 1; i != dSrcLen1 - 1; i--)
243 //Compare common digits
244 for (; i != (cc_u32)-1; i--)
246 if (pdSrc1[i] == pdSrc2[i])
252 if (pdSrc1[i] > pdSrc2[i])
268 * @brief Shift left the digit array
270 * @param pdDest [out]destination
271 * @param pdSrc [in]source
272 * @param dSrcLen [in]legnth of pdSrc
273 * @param dNumOfShift [in]shift amount
277 static cc_u32 SDRM_DWD_SHL(cc_u32 *pdDest, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dNumOfShift)
279 cc_u32 i = dSrcLen - 1;
288 dRet = pdSrc[i] >> (SDRM_BitsInDWORD - dNumOfShift);
292 pdDest[i] = (pdSrc[i] << dNumOfShift) ^ (pdSrc[i - 1] >> (SDRM_BitsInDWORD - dNumOfShift));
295 pdDest[i] = pdSrc[i] << dNumOfShift;
302 * @brief Shift right the digit array
304 * @param pdDest [out]destination
305 * @param pdSrc [in]source
306 * @param dSrcLen [in]legnth of pdSrc
307 * @param dNumOfShift [in]shift amount
311 static cc_u32 SDRM_DWD_SHR(cc_u32 *pdDest, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dNumOfShift)
316 dRet = pdSrc[i] << (SDRM_BitsInDWORD - dNumOfShift);
318 for (; i < dSrcLen - 1; i++)
320 pdDest[i] = (pdSrc[i] >> dNumOfShift) ^ (pdSrc[i + 1] << (SDRM_BitsInDWORD - dNumOfShift));
323 pdDest[i] = pdSrc[i] >> dNumOfShift;
330 * @brief Add two digit array
332 * @param pdDest [out]destination
333 * @param pdSrc1 [in]first element
334 * @param dSrcLen1 [in]legnth of pdSrc1
335 * @param pdSrc2 [in]second element
336 * @param dSrcLen2 [in]legnth of pdSrc2
340 static cc_u32 SDRM_DWD_Add(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
343 cc_u32 dCarry = 0, dTemp;
346 for (i = 0; i < dSrcLen2; i++)
348 if ((pdSrc2[i] == ((cc_u32)-1)) && (dCarry))
350 pdDest[i] = pdSrc1[i];
354 dTemp = pdSrc2[i] + dCarry;
355 pdDest[i] = pdSrc1[i] + dTemp;
356 dCarry = (pdDest[i] < dTemp ) ? 1 : 0;
363 memcpy(pdDest + i, pdSrc1 + i, (dSrcLen1 - i) * SDRM_SIZE_OF_DWORD);
373 for (i = dSrcLen2; i < dSrcLen1; i++)
387 * @brief subtract digit array
389 * @param pdDest [out]destination
390 * @param pdSrc1 [in]first element
391 * @param dSrcLen1 [in]legnth of pdSrc1
392 * @param pdSrc2 [in]second element
393 * @param dSrcLen2 [in]legnth of pdSrc2
397 static cc_u32 SDRM_DWD_Sub(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
400 cc_u32 dCarry = 0, dTemp;
402 //subtract low digits
403 for (i = 0; i < dSrcLen2; i++)
405 if (pdSrc2[i] + dCarry == 0)
407 pdDest[i] = pdSrc1[i];
411 dTemp = pdSrc2[i] + dCarry;
412 pdDest[i] = pdSrc1[i] - dTemp;
413 dCarry = ((pdDest[i]) > ~(dTemp)) ? 1 : 0;
420 memcpy(pdDest + i, pdSrc1 + i, (dSrcLen1 - i) * SDRM_SIZE_OF_DWORD);
430 for (i = dSrcLen2 ; i < dSrcLen1; i++)
443 * @fn SDRM_DWD_MulAdd
444 * @brief Add multiple
446 * @param pdDest [out]destination
447 * @param dDstLen [in]legnth of pbDest
448 * @param pdSrc [in]source
449 * @param dSrcLen [in]legnth of pdSrc
450 * @param dMultiplier [in]multiplier
454 static cc_u32 SDRM_DWD_MulAdd(cc_u32 *pdDest, cc_u32 dDstLen, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dMultiplier)
460 //Multiplication part
461 for (i = 0; i < dSrcLen; i++)
464 * Time code optimization. To be continue!
466 pdDigit2 =((cc_u64)pdSrc[i] * dMultiplier) + pdDest[i] + dTemp;
467 pdDest[i] = (cc_u32)pdDigit2;
468 dTemp = pdDigit2 >> 32;
470 /*SDRM_DIGIT_Mul(pdDigit, dMultiplier, pdSrc[i]);
471 if ((dTemp += pdDigit[0]) < pdDigit[0])
476 if ((pdDest[i] += dTemp) < dTemp)
481 dTemp = pdDigit[1];*/
490 if ((pdDest[i] += dTemp) >= dTemp)
495 for (i++; i < dDstLen; i++)
497 if ((++pdDest[i]) != 0)
507 * @fn SDRM_DWD_MulSub
508 * @brief Multiply and Subtract Digit Array
510 * @param pdDest [out]destination
511 * @param dDstLen [in]legnth of pbDest
512 * @param pdSrc [in]source
513 * @param dSrcLen [in]legnth of pdSrc
514 * @param dMultiplier [in]multiplier
518 static cc_u32 SDRM_DWD_MulSub(cc_u32 *pdDest, cc_u32 dDstLen, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dMultiplier)
521 cc_u32 pdDigit[2], dTemp = 0;
523 //Multiplication part
524 for (i = 0; i < dSrcLen; i++)
526 SDRM_DIGIT_Mul(pdDigit, dMultiplier, pdSrc[i]);
529 if (dTemp < pdDigit[0])
534 if (pdDest[i] < dTemp)
549 if (pdDest[i] >= dTemp)
560 for (i++; i < dDstLen; i++)
562 if ((pdDest[i]--) != 0)
573 * @brief Multiply tow Digit array
575 * @param pdDest [out]destination
576 * @param pdSrc1 [in]first element
577 * @param dSrcLen1 [in]legnth of pdSrc1
578 * @param pdSrc2 [in]second element
579 * @param dSrcLen2 [in]legnth of pdSrc2
583 static void SDRM_DWD_Mul(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
589 memset(pdDest, 0, (dSrcLen1 + dSrcLen2) * SDRM_SIZE_OF_DWORD);
591 for (j = 0; j < dSrcLen2; j++)
594 for (i = 0; i < dSrcLen1; i++)
597 pdDigit2 =((cc_u64)pdSrc1[i] * pdSrc2[j]) + pdDest[i + j] + dTemp;
598 pdDest[i + j] = (cc_u32)pdDigit2;
599 dTemp = pdDigit2 >> 32;
602 /*SDRM_DIGIT_Mul(pdDigit, pdSrc1[i], pdSrc2[j]);
603 if ((dTemp += pdDigit[0]) < pdDigit[0])
608 if ((pdDest[i + j] += dTemp) < dTemp)
613 dTemp = pdDigit[1];*/
615 pdDest[i + j] = dTemp;
621 * @brief Multiply tow Digit array
623 * @param pdDest [out]quotient
624 * @param pdRem [out]remainder
625 * @param pdSrc1 [in]divisor
626 * @param dSrcLen1 [in]legnth of pdSrc1
627 * @param pdSrc2 [in]dividend
628 * @param dSrcLen2 [in]legnth of pdSrc2
630 * @return 0 if reaminder is zero
633 static cc_u32 SDRM_DWD_Div(cc_u32 *pdDest, cc_u32 *pdRem,
634 cc_u32 *pdSrc1, cc_u32 dSrcLen1,
635 cc_u32 *pdSrc2, cc_u32 dSrcLen2)
637 cc_u32 i, q, c, dNum_of_Shift = 0;
638 cc_u32 *C = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * 2 * (MAX2(dSrcLen1, dSrcLen2) + 2));
642 return (cc_u32)CRYPTO_MEMORY_ALLOC_FAIL;
645 SDRM_DWD_Copy(C, pdSrc1, dSrcLen1);
650 for (i = dSrcLen2 * SDRM_BitsInDWORD-1; !SDRM_CheckBitUINT32(pdSrc2, i); i--, dNum_of_Shift++);
654 SDRM_DWD_SHL(C, C, c, dNum_of_Shift);
655 SDRM_DWD_SHL(pdSrc2, pdSrc2, dSrcLen2, dNum_of_Shift);
658 for (i = c-dSrcLen2 - 1; i != (cc_u32)-1; i--)
660 if (C[dSrcLen2 + i]==pdSrc2[dSrcLen2 - 1] )
666 q = SDRM_DIGIT_Div(C[dSrcLen2 + i], C[dSrcLen2 + i - 1], pdSrc2[dSrcLen2 - 1]);
669 if (SDRM_DWD_MulSub(C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2, q) )
672 if (!SDRM_DWD_Add(C + i, C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2))
675 SDRM_DWD_Add(C + i, C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2);
681 //Recover lowest '0's
684 SDRM_DWD_SHR(pdSrc2, pdSrc2, dSrcLen2, dNum_of_Shift);
685 SDRM_DWD_SHR(C, C, dSrcLen2, dNum_of_Shift);
690 SDRM_DWD_Copy(pdRem, C, dSrcLen2);
693 for (i = 0; i < c; i++)
708 * @fn SDRM_DWD_Classical_REDC
709 * @brief Classical Modular Reduction Algorithm
711 * @param pdDest [out]destination
712 * @param DstLen [in]length of pdDest
713 * @param pdModulus [in]modulus
714 * @param ModLen [in]legnth of pdModulus
716 * @return CRYPTO_SUCCESS if no error is occured
718 int SDRM_DWD_Classical_REDC(cc_u32 *pdDest, cc_u32 DstLen, cc_u32 *pdModulus, cc_u32 ModLen)
721 cc_u32 MSB=0, TTTT=0, FLAG=0, D_Quotient, MSD_Modulus;
725 return CRYPTO_SUCCESS;
728 if (pdDest[DstLen - 1] >= pdModulus[ModLen - 1])
731 TTTT = pdDest[DstLen];
732 pdDest[DstLen++] = 0;
735 for (i = SDRM_BitsInDWORD - 1; i != (cc_u32)-1; i--)
737 if (pdModulus[ModLen - 1] & ((cc_u32)1 << i))
747 SDRM_DWD_SHL(pdModulus, pdModulus, ModLen, MSB);
748 SDRM_DWD_SHL(pdDest, pdDest, DstLen, MSB);
751 // Step 2 : main part
752 MSD_Modulus = pdModulus[ModLen - 1];
753 for (i = DstLen - ModLen - 1; i != (cc_u32)-1; i--)
755 // Step 2-1 : Estimate D_Quotient
756 if (pdDest[ModLen + i] == MSD_Modulus)
758 D_Quotient = (cc_u32)-1;
762 D_Quotient = SDRM_DIGIT_Div(pdDest[ModLen + i], pdDest[ModLen + i - 1], MSD_Modulus);
765 // Step 2-2 : Make pdDest <- pdDest-D_Quotient*pdModulus
766 if (SDRM_DWD_MulSub(pdDest + i, ModLen + 1, pdModulus, ModLen, D_Quotient) )
768 if (SDRM_DWD_Add(pdDest + i, pdDest + i, ModLen + 1, pdModulus, ModLen) == 0)
770 SDRM_DWD_Add(pdDest + i, pdDest + i, ModLen + 1, pdModulus, ModLen);
775 // Step 4 : inverse part of Step 2
778 SDRM_DWD_SHR(pdModulus, pdModulus, ModLen, MSB);
779 SDRM_DWD_SHR(pdDest, pdDest, ModLen, MSB);
782 // Step 4.5 : inverse part of Step 1.5
786 pdDest[DstLen] = TTTT;
789 return CRYPTO_SUCCESS;
794 * @brief get gcd of two digits
796 * @param s1 [in]first element
797 * @param s2 [in]second element
801 cc_u32 SDRM_DIGIT_Gcd(cc_u32 s1, cc_u32 s2)
824 * @brief Show out a Big Number
826 * @param level [in]log level
828 * @param bn [in]big number to show out
832 void SDRM_PrintBN(const char* s, SDRM_BIG_NUM* bn)
836 printf("%15s %d :", s, (int)(bn->Length));
839 printf("%15s-%d :", s, (int)(bn->Length));
841 for (i = 0; i < bn->Length ; i++)
843 printf("%08x ", (int)(bn->pData[bn->Length - i -1]));
853 * @brief Convert Big Number to Octet String
855 * @param BN_Src [in]source integer
856 * @param dDstLen [in]Byte-length of pbDst
857 * @param pbDst [out]output octet string
859 * @return CRYPTO_SUCCESS if no error is occured
860 * \n CRYPTO_MEMORY_ALLOC_FAIL if arrary is too small
862 int SDRM_BN2OS(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
866 if ((BN_Src == NULL) || (pbDst == NULL))
868 return CRYPTO_NULL_POINTER;
871 SDRM_BN_OPTIMIZE_LENGTH(BN_Src);
879 if ((SDRM_SIZE_OF_DWORD * BN_Src->Length) <= dDstLen)
881 memset(pbDst, 0, dDstLen);
883 for (i = 0; (dDstLen != 0) && (i < BN_Src->Length); i++)
885 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i] ) & 0xff);
886 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>> 8) & 0xff);
887 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>16) & 0xff);
888 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>24) & 0xff);
893 i = (SDRM_SIZE_OF_DWORD * BN_Src->Length) - dDstLen;
894 if (i >= SDRM_SIZE_OF_DWORD)
896 return CRYPTO_BUFFER_TOO_SMALL;
898 else if ( BN_Src->pData[BN_Src->Length - 1] >> (8 * (SDRM_SIZE_OF_DWORD - i)))
900 return CRYPTO_BUFFER_TOO_SMALL;
905 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i] ) & 0xff);
911 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>> 8) & 0xFF);
917 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>16) & 0xFF);
923 pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>24) & 0xFF);
931 return CRYPTO_SUCCESS;
936 * @brief Convert Octet String to Big Number
938 * @param pbSrc [in]source octet string
939 * @param dSrcLen [in]Byte-length of pbSrc
940 * @param BN_Dst [out]output big number
942 * @return CRYPTO_SUCCESS if no error is occured
943 * \n CRYPTO_MEMORY_ALLOC_FAIL if arrary is too small
945 int SDRM_OS2BN(cc_u8 *pbSrc, cc_u32 dSrcLen, SDRM_BIG_NUM *BN_Dst)
950 if ((pbSrc == NULL) || (BN_Dst == NULL))
952 return CRYPTO_INVALID_ARGUMENT;
957 for (i = 0; i < dSrcLen; i++)
959 ret = SDRM_BN_SHL(BN_Dst, BN_Dst, 8);
961 if (ret != CRYPTO_SUCCESS)
966 BN_Dst->pData[0] ^= pbSrc[i];
967 if (BN_Dst->Length == 0) {
972 return CRYPTO_SUCCESS;
977 * @brief Converts a nonnonegative integer to an octet string of a specified length
979 * @param BN_Src [in]nonnegative integer to be converted
980 * @param dDstLen [in]intended length of the resulting octet string
981 * @param pbDst [out]corresponding octet string of length dDstLen
983 * @return CRYPTO_SUCCESS if no error is occured
985 int SDRM_I2OSP(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
989 SDRM_BN_OPTIMIZE_LENGTH(BN_Src);
992 for (dDstLen--; (int)dDstLen >= 0; dDstLen--)
994 pbDst[count++] = SDRM_CheckByteUINT32(BN_Src->pData, dDstLen);
997 return CRYPTO_SUCCESS;
1002 * @brief Clear the SDRM_BIG_NUM structure
1004 * @param BN_Src [in]source
1006 * @return CRYPTO_SUCCESS
1008 int SDRM_BN_Clr(SDRM_BIG_NUM* BN_Src)
1013 memset(BN_Src->pData, 0, BN_Src->Size * SDRM_SIZE_OF_DWORD);
1015 return CRYPTO_SUCCESS;
1020 * @brief copy SDRM_BIG_NUM
1022 * @param BN_Dest [out]destination
1023 * @param BN_Src [in]source
1025 * @return CRYPTO_SUCCESS
1027 int SDRM_BN_Copy(SDRM_BIG_NUM* BN_Dest, SDRM_BIG_NUM* BN_Src)
1029 if (BN_Src->Length > BN_Dest->Size)
1031 return CRYPTO_BUFFER_TOO_SMALL;
1034 BN_Dest->sign = BN_Src->sign;
1035 BN_Dest->Length = BN_Src->Length;
1037 memcpy(BN_Dest->pData, BN_Src->pData, BN_Src->Length * SDRM_SIZE_OF_DWORD);
1039 return CRYPTO_SUCCESS;
1044 * @brief allocate big number from buffer
1046 * @param pbSrc [in]start pointer of buffer
1047 * @param dSize [in]buffer size of big number
1049 * @return pointer of SDRM_BIG_NUM structure
1051 SDRM_BIG_NUM *SDRM_BN_Alloc(cc_u8* pbSrc, cc_u32 dSize)
1053 SDRM_BIG_NUM *BN_Dest = (SDRM_BIG_NUM*)(void*)pbSrc;
1060 memset(BN_Dest, 0, sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD);
1061 BN_Dest->pData = (cc_u32*)(void*)(pbSrc + sizeof(SDRM_BIG_NUM));
1062 BN_Dest->Size = dSize;
1063 BN_Dest->Length = 0;
1070 * @brief Allocate a new big number object
1072 * @param dSize [in]buffer size of big number
1074 * @return pointer of SDRM_BIG_NUM structure
1075 * \n NULL if memory allocation is failed
1077 SDRM_BIG_NUM *SDRM_BN_Init(cc_u32 dSize)
1079 cc_u32 AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1080 cc_u8 *pbBuf = (cc_u8*)malloc(AllocSize);
1081 SDRM_BIG_NUM *BN_Src = (SDRM_BIG_NUM*)(void*)pbBuf;
1087 memset(BN_Src, 0, AllocSize);
1088 BN_Src->pData = (cc_u32*)(void*)(pbBuf + sizeof(SDRM_BIG_NUM));
1089 BN_Src->Size = dSize;
1096 * @brief Compare two Big Number
1098 * @param BN_Src1 [in]first element
1099 * @param BN_Src2 [in]second element
1101 * @return 1 if BN_Src1 is larger than pdSrc2
1103 * \n -1 if BN_Src2 is larger than pdSrc1
1105 int SDRM_BN_Cmp(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1107 if (BN_Src1->Length >= BN_Src2->Length)
1109 return SDRM_DWD_Cmp(BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
1113 return -SDRM_DWD_Cmp(BN_Src2->pData, BN_Src2->Length, BN_Src1->pData, BN_Src1->Length);
1118 * @fn SDRM_BN_Cmp_sign
1119 * @brief Compare two Big Number considering sign
1121 * @param BN_Src1 [in]first element
1122 * @param BN_Src2 [in]second element
1124 * @return 1 if BN_Src1 is larger than pdSrc2
1126 * \n -1 if BN_Src2 is larger than pdSrc1
1128 int SDRM_BN_Cmp_sign(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1130 if (BN_Src1->sign > BN_Src2->sign)
1134 else if (BN_Src1->sign < BN_Src2->sign)
1139 if ( BN_Src1->Length >= BN_Src2->Length )
1141 return SDRM_DWD_Cmp(BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
1145 return -SDRM_DWD_Cmp(BN_Src2->pData, BN_Src2->Length, BN_Src1->pData, BN_Src1->Length);
1151 * @brief Generate simple random number
1153 * @param BN_Dst [out]destination
1154 * @param BitLen [in]bit-length of generated random number
1156 * @return CRYPTO_SUCCESS if no error is occured
1158 int SDRM_BN_Rand(SDRM_BIG_NUM *BN_Dst, cc_u32 BitLen)
1162 SDRM_BN_Clr(BN_Dst);
1164 for (i = 0; i < (BitLen / SDRM_BitsInDWORD); i++)
1166 BN_Dst->pData[i] = rand() ^ (rand() << 11);
1169 j = BitLen % SDRM_BitsInDWORD;
1172 BN_Dst->pData[i] = rand() ^ (rand() << 11);
1173 BN_Dst->pData[i] &= (((cc_u32)1) << j) - 1;
1177 BN_Dst->Length = ((BitLen - 1) / SDRM_BitsInDWORD) + 1;
1179 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1181 return CRYPTO_SUCCESS;
1186 * @brief Big Number Shift Left
1188 * @param BN_Dst [out]destination
1189 * @param BN_Src [in]source
1190 * @param NumOfShift [in]shift amount
1192 * @return CRYPTO_SUCCESS if no error occured
1194 int SDRM_BN_SHL(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
1198 if (!BN_Src->Length)
1200 SDRM_BN_Copy(BN_Dst, BN_Zero);
1201 return CRYPTO_SUCCESS;
1204 BN_Dst->sign = BN_Src->sign;
1206 t = NumOfShift % SDRM_BitsInDWORD;
1209 BN_Dst->Length = BN_Src->Length;
1210 t = SDRM_DWD_SHL(BN_Dst->pData, BN_Src->pData, BN_Src->Length, t);
1213 BN_Dst->pData[BN_Dst->Length++] = t;
1218 SDRM_BN_Copy(BN_Dst, BN_Src);
1221 t = NumOfShift / SDRM_BitsInDWORD;
1224 BN_Dst->Length += t;
1226 memmove((BN_Dst->pData) + t, BN_Dst->pData, (BN_Dst->Length - t) * SDRM_SIZE_OF_DWORD);
1228 memset(BN_Dst->pData, 0, t * SDRM_SIZE_OF_DWORD);
1231 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1233 return CRYPTO_SUCCESS;
1238 * @brief Big Number Shift Right
1240 * @param BN_Dst [out]destination
1241 * @param BN_Src [in]source
1242 * @param NumOfShift [in]shift amount
1244 * @return CRYPTO_SUCCESS if no error occured
1246 int SDRM_BN_SHR(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
1250 if (!BN_Src->Length)
1252 SDRM_BN_Copy(BN_Dst, BN_Src);
1253 return CRYPTO_SUCCESS;
1256 t = NumOfShift / SDRM_BitsInDWORD;
1259 if (t >= BN_Src->Length)
1261 SDRM_BN_Copy(BN_Dst, BN_Zero);
1262 return CRYPTO_SUCCESS;
1265 memcpy(BN_Dst->pData, (BN_Src->pData) + t, (BN_Src->Length - t) * SDRM_SIZE_OF_DWORD);
1267 BN_Dst->Length = BN_Src->Length - t;
1268 BN_Dst->sign = BN_Src->sign;
1269 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1273 SDRM_BN_Copy(BN_Dst, BN_Src);
1276 t = NumOfShift % SDRM_BitsInDWORD;
1279 SDRM_DWD_SHR(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, t);
1282 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1284 return CRYPTO_SUCCESS;
1289 * @brief Big Number Addition
1291 * @param BN_Dst [out]destination
1292 * @param BN_Src1 [in]first element
1293 * @param BN_Src2 [in]second element
1295 * @return CRYPTO_SUCCESS if no error occured
1296 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1298 int SDRM_BN_Add(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1300 cc_u32 carry, dSize, dAllocSize;
1301 SDRM_BIG_NUM *temp, *temp_Src1, *temp_Src2;
1304 dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
1305 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1307 pbBuf = (cc_u8*)malloc(dAllocSize * 2);
1311 return CRYPTO_MEMORY_ALLOC_FAIL;
1314 temp_Src1 = SDRM_BN_Alloc(pbBuf, dSize);
1315 temp_Src2 = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
1317 if (!BN_Src1->Length)
1319 SDRM_BN_Copy(BN_Dst, BN_Src2);
1322 return CRYPTO_SUCCESS;
1325 if (!BN_Src2->Length) {
1326 SDRM_BN_Copy(BN_Dst, BN_Src1);
1329 return CRYPTO_SUCCESS;
1332 SDRM_BN_Copy(temp_Src1, BN_Src1);
1333 SDRM_BN_Copy(temp_Src2, BN_Src2);
1335 if (temp_Src1->sign ^ temp_Src2->sign)
1337 if (temp_Src1->sign)
1340 temp_Src1 = temp_Src2;
1344 if (SDRM_BN_Cmp(temp_Src1, temp_Src2) < 0)
1346 SDRM_DWD_Sub(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
1348 BN_Dst->Length = temp_Src2->Length;
1352 SDRM_DWD_Sub(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
1354 BN_Dst->Length = temp_Src1->Length;
1359 return CRYPTO_SUCCESS;
1362 if (temp_Src1->sign)
1371 if (temp_Src1->Length > temp_Src2->Length)
1373 BN_Dst->Length = temp_Src1->Length;
1374 carry = SDRM_DWD_Add(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
1377 BN_Dst->pData[BN_Dst->Length++] = carry;
1382 BN_Dst->Length = temp_Src2->Length;
1383 carry = SDRM_DWD_Add(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
1386 BN_Dst->pData[BN_Dst->Length++] = carry;
1390 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1394 return CRYPTO_SUCCESS;
1399 * @brief Big Number Subtraction
1401 * @param BN_Dst [out]destination
1402 * @param BN_Src1 [in]first element
1403 * @param BN_Src2 [in]second element
1405 * @return CRYPTO_SUCCESS if no error occured
1406 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1408 int SDRM_BN_Sub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1410 int i, add = 0, dSize, dAllocSize;
1411 SDRM_BIG_NUM *temp, *temp_Src1, *temp_Src2;
1414 dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
1415 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1416 pbBuf = (cc_u8*)malloc(dAllocSize * 2);
1420 return CRYPTO_MEMORY_ALLOC_FAIL;
1423 temp_Src1 = SDRM_BN_Alloc(pbBuf, dSize);
1424 temp_Src2 = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
1426 SDRM_BN_Copy(temp_Src1, BN_Src1);
1427 SDRM_BN_Copy(temp_Src2, BN_Src2);
1429 if (BN_Src1 == BN_Src2)
1431 SDRM_BN_Clr(BN_Dst);
1434 return CRYPTO_SUCCESS;
1438 if (temp_Src1->sign)
1440 if (temp_Src2->sign)
1443 temp_Src1 = temp_Src2;
1449 temp_Src2->sign = 1;
1454 if (temp_Src2->sign)
1457 temp_Src2->sign = 0;
1463 i = (temp_Src1->Length | temp_Src2->Length) +1;
1466 SDRM_BN_Add(BN_Dst, temp_Src1, temp_Src2);
1470 SDRM_BN_Add(BN_Dst, temp_Src2, temp_Src1);
1475 return CRYPTO_SUCCESS;
1478 if (SDRM_BN_Cmp(temp_Src1, temp_Src2) < 0)
1480 SDRM_DWD_Sub(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
1482 BN_Dst->Length = temp_Src2->Length;
1486 SDRM_DWD_Sub(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
1488 BN_Dst->Length = temp_Src1->Length;
1490 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1494 return CRYPTO_SUCCESS;
1499 * @brief Big Number Multiplication
1501 * @param BN_Dst [out]destination
1502 * @param BN_Multiplicand [in]first element
1503 * @param BN_Multiplier [in]second element
1505 * @return CRYPTO_SUCCESS if no error occured
1506 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1508 int SDRM_BN_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Multiplicand, SDRM_BIG_NUM *BN_Multiplier)
1512 if ((BN_Multiplicand->Length == 0) || (BN_Multiplier->Length == 0))
1514 SDRM_BN_Clr(BN_Dst);
1515 return CRYPTO_SUCCESS;
1518 Dst = SDRM_BN_Init(BN_Dst->Size * 2);
1521 return CRYPTO_MEMORY_ALLOC_FAIL;
1524 Dst->Length = BN_Multiplicand->Length + BN_Multiplier->Length;
1526 if (BN_Multiplicand->sign != BN_Multiplier->sign)
1535 if (BN_Multiplicand->Length > BN_Multiplier->Length)
1537 SDRM_DWD_Mul(Dst->pData, BN_Multiplicand->pData, BN_Multiplicand->Length, BN_Multiplier->pData, BN_Multiplier->Length);
1541 SDRM_DWD_Mul(Dst->pData, BN_Multiplier->pData, BN_Multiplier->Length, BN_Multiplicand->pData, BN_Multiplicand->Length);
1544 SDRM_BN_OPTIMIZE_LENGTH(Dst);
1546 SDRM_BN_Copy(BN_Dst, Dst);
1549 return CRYPTO_SUCCESS;
1554 * @brief Big Number Division
1556 * @param BN_Quotient [out]quotient
1557 * @param BN_Remainder [out]remainder
1558 * @param BN_Dividend [in]dividend
1559 * @param BN_Divisor [in]divisor
1561 * @return CRYPTO_SUCCESS if no error occured
1562 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1564 int SDRM_BN_Div(SDRM_BIG_NUM *BN_Quotient, SDRM_BIG_NUM *BN_Remainder, SDRM_BIG_NUM *BN_Dividend, SDRM_BIG_NUM *BN_Divisor)
1566 cc_u32 tmp, dSize, dAllocSize;
1567 SDRM_BIG_NUM *temp_Dividend, *temp_Divisor;
1571 if (BN_Quotient != NULL)
1573 dSize = MAX2(BN_Quotient->Size, BN_Dividend->Size);
1577 dSize = BN_Dividend->Size;
1580 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1581 pbBuf = (cc_u8*)malloc(dAllocSize * 3 + 2 * SDRM_SIZE_OF_DWORD);
1584 return CRYPTO_MEMORY_ALLOC_FAIL;
1587 temp_Dividend = SDRM_BN_Alloc(pbBuf, dSize);
1588 temp_Divisor = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
1589 bnTmp = (cc_u32*)(void*)(pbBuf + dSize + dAllocSize);
1591 SDRM_BN_Copy(temp_Dividend, BN_Dividend);
1592 SDRM_BN_Copy(temp_Divisor, BN_Divisor);
1594 if (SDRM_BN_Cmp(temp_Dividend, temp_Divisor) < 0)
1596 if (BN_Remainder != NULL)
1598 SDRM_BN_Copy(BN_Remainder, temp_Dividend);
1600 //return CRYPTO_SUCCESS; modify by Chalyi Aleksandr: it is not correct
1603 if (BN_Quotient != NULL)
1605 SDRM_BN_Clr(BN_Quotient);
1609 return CRYPTO_SUCCESS;
1612 if (BN_Quotient == NULL)
1614 BN_Remainder->Length = temp_Divisor->Length;
1615 tmp = SDRM_DWD_Div(bnTmp, BN_Remainder->pData, temp_Dividend->pData, temp_Dividend->Length, temp_Divisor->pData, temp_Divisor->Length);
1616 SDRM_BN_OPTIMIZE_LENGTH(BN_Remainder);
1617 BN_Remainder->sign = BN_Dividend->sign;
1619 else if (BN_Remainder == NULL)
1621 BN_Quotient->Length = temp_Dividend->Length - temp_Divisor->Length + 1;
1622 tmp = SDRM_DWD_Div(BN_Quotient->pData, bnTmp, temp_Dividend->pData, temp_Dividend->Length, temp_Divisor->pData, temp_Divisor->Length);
1623 SDRM_BN_OPTIMIZE_LENGTH(BN_Quotient);
1624 BN_Quotient->sign= (BN_Dividend->sign^BN_Divisor->sign);
1628 BN_Quotient->Length = temp_Dividend->Length - temp_Divisor->Length + 1;
1629 BN_Remainder->Length = temp_Divisor->Length;
1630 BN_Quotient->sign= (BN_Dividend->sign^BN_Divisor->sign);
1631 BN_Remainder->sign = BN_Dividend->sign;
1633 tmp = SDRM_DWD_Div(BN_Quotient->pData, BN_Remainder->pData, BN_Dividend->pData, BN_Dividend->Length, BN_Divisor->pData, BN_Divisor->Length);
1635 SDRM_BN_OPTIMIZE_LENGTH(BN_Quotient);
1636 SDRM_BN_OPTIMIZE_LENGTH(BN_Remainder);
1641 if (!(tmp == 0 || tmp == 1))
1643 return CRYPTO_ERROR;
1646 return CRYPTO_SUCCESS;
1650 * @fn SDRM_BN_ModAdd
1651 * @brief Big Number Modular Addition
1653 * @param BN_Dst [out]destination
1654 * @param BN_Src1 [in]first element of addition
1655 * @param BN_Src2 [in]second element of addition
1656 * @param BN_Modulus [in]modular m
1658 * @return CRYPTO_SUCCESS if no error occured
1659 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1661 int SDRM_BN_ModAdd(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
1663 SDRM_BIG_NUM *BN_Src1_temp, *BN_Src2_temp;
1665 cc_u32 tmp = 0, dSize, AllocSize;
1667 dSize = MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size);
1668 AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1670 pbBuf = (cc_u8*)malloc(AllocSize * 2);
1674 return CRYPTO_MEMORY_ALLOC_FAIL;
1677 BN_Src1_temp = SDRM_BN_Alloc(pbBuf, dSize);
1678 BN_Src2_temp = SDRM_BN_Alloc(pbBuf + AllocSize, dSize);
1680 SDRM_BN_Copy(BN_Src1_temp, BN_Src1);
1681 SDRM_BN_Copy(BN_Src2_temp, BN_Src2);
1683 if ((SDRM_BN_Cmp(BN_Src1, BN_Modulus)>=0))
1685 SDRM_BN_ModRed(BN_Src1_temp, BN_Src1, BN_Modulus);
1688 if ((SDRM_BN_Cmp(BN_Src2, BN_Modulus)>=0))
1690 SDRM_BN_ModRed(BN_Src2_temp, BN_Src2, BN_Modulus);
1693 if (BN_Src1_temp->Length >= BN_Src2_temp->Length)
1695 BN_Dst->Length = BN_Src1_temp->Length;
1696 BN_Dst->sign = BN_Src1_temp->sign;
1697 tmp = SDRM_DWD_Add(BN_Dst->pData, BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
1701 BN_Dst->Length = BN_Src2_temp->Length;
1702 BN_Dst->sign = BN_Src2_temp->sign;
1703 tmp = SDRM_DWD_Add(BN_Dst->pData, BN_Src2_temp->pData, BN_Src2_temp->Length,
1704 BN_Src1_temp->pData, BN_Src1_temp->Length);
1709 BN_Dst->pData[BN_Dst->Length++] = tmp;
1712 SDRM_BN_ModRed(BN_Dst, BN_Dst, BN_Modulus);
1714 if (SDRM_DWD_Cmp(BN_Dst->pData, BN_Dst->Length, BN_Modulus->pData, BN_Modulus->Length) >= 0)
1716 SDRM_DWD_Sub(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, BN_Modulus->pData, BN_Modulus->Length);
1719 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1722 return CRYPTO_SUCCESS;
1726 * @fn SDRM_BN_ModSub
1727 * @brief Big Number Modular Subtraction
1729 * @param BN_Dst [out]destination
1730 * @param BN_Src1 [in]first element of subtraction
1731 * @param BN_Src2 [in]second element of subtraction
1732 * @param BN_Modulus [in]modular m
1734 * @return CRYPTO_SUCCESS if no error occured
1735 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1737 int SDRM_BN_ModSub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
1739 cc_u32 tmp = 0, dSize, AllocSize;
1740 SDRM_BIG_NUM *BN_Src1_temp, *BN_Src2_temp;
1743 dSize = MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size);
1744 AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1746 pbBuf = (cc_u8*)malloc(AllocSize * 2);
1750 return CRYPTO_MEMORY_ALLOC_FAIL;
1753 BN_Src1_temp = SDRM_BN_Alloc(pbBuf, dSize);
1754 BN_Src2_temp = SDRM_BN_Alloc(pbBuf + AllocSize, dSize);
1756 SDRM_BN_Copy(BN_Src1_temp, BN_Src1);
1757 SDRM_BN_Copy(BN_Src2_temp, BN_Src2);
1759 if ((SDRM_BN_Cmp(BN_Src1, BN_Modulus) >= 0))
1761 SDRM_BN_ModRed(BN_Src1_temp, BN_Src1, BN_Modulus);
1764 if ((SDRM_BN_Cmp(BN_Src2, BN_Modulus) >= 0))
1766 SDRM_BN_ModRed(BN_Src2_temp, BN_Src2, BN_Modulus);
1769 if (SDRM_DWD_Cmp(BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length) >= 0)
1771 BN_Dst->Length = BN_Src1_temp->Length;
1772 BN_Dst->sign = BN_Src1_temp->sign;
1774 tmp = SDRM_DWD_Sub(BN_Dst->pData, BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
1778 BN_Dst->Length = BN_Modulus->Length;
1779 BN_Dst->sign = BN_Modulus->sign;
1780 SDRM_DWD_Add(BN_Dst->pData, BN_Modulus->pData, BN_Modulus->Length, BN_Src1_temp->pData, BN_Src1_temp->Length);
1781 SDRM_DWD_Sub(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
1784 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1789 return CRYPTO_ERROR;
1792 return CRYPTO_SUCCESS;
1796 * @fn SDRM_BN_ModRed
1797 * @brief Big Number Modular Reduction
1799 * @param BN_Dst [out]destination
1800 * @param BN_Src [in]source
1801 * @param BN_Modulus [in]modular m
1803 * @return CRYPTO_SUCCESS if no error occured
1804 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1806 int SDRM_BN_ModRed(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
1809 cc_u32 *Value = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * 2 * (sizeof(SDRM_BIG_NUM) + MAX2(BN_Src->Size, BN_Modulus->Size) + 2));
1813 return CRYPTO_MEMORY_ALLOC_FAIL;
1816 if (SDRM_BN_Cmp(BN_Src, BN_Modulus) < 0)
1818 SDRM_BN_Copy(BN_Dst, BN_Src);
1820 return CRYPTO_SUCCESS;
1823 memcpy(Value, BN_Src->pData, BN_Src->Length * SDRM_SIZE_OF_DWORD);
1825 ret = SDRM_DWD_Classical_REDC(Value, BN_Src->Length, BN_Modulus->pData, BN_Modulus->Length);
1827 if (ret != CRYPTO_SUCCESS)
1833 memcpy(BN_Dst->pData, Value, BN_Modulus->Length * SDRM_SIZE_OF_DWORD);
1835 BN_Dst->Length = BN_Modulus->Length;
1836 BN_Dst->sign = BN_Modulus->sign;
1837 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1841 return CRYPTO_SUCCESS;
1845 * @fn SDRM_BN_ModMul
1846 * @brief Big Number Modular Multiplication
1848 * @param BN_Dst [out]destination
1849 * @param BN_Src1 [in]first element of multiplication
1850 * @param BN_Src2 [in]second element of multipliation
1851 * @param BN_Modulus [in]modular m
1853 * @return CRYPTO_SUCCESS if no error occured
1854 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1856 int SDRM_BN_ModMul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
1860 cc_u32 *Value = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * (MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size) + 2));
1864 return CRYPTO_MEMORY_ALLOC_FAIL;
1867 memset(Value, 0x00, SDRM_SIZE_OF_DWORD * (MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size) + 2));
1869 SDRM_DWD_Mul(Value, BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
1871 ret = SDRM_DWD_Classical_REDC(Value, BN_Src1->Length + BN_Src2->Length, BN_Modulus->pData, BN_Modulus->Length);
1872 if (ret != CRYPTO_SUCCESS)
1879 Dest.sign = (BN_Src1->sign == BN_Src2->sign)? 0 : 1;
1880 Dest.Length = BN_Modulus->Length;
1883 SDRM_BN_OPTIMIZE_LENGTH(&Dest);
1885 SDRM_BN_Copy(BN_Dst, &Dest);
1889 return CRYPTO_SUCCESS;
1893 * @fn SDRM_BN_ModInv
1894 * @brief Big Number Modular Inverse
1896 * @param BN_Dest [out]destination
1897 * @param BN_Src [in]soure
1898 * @param BN_Modulus [in]modular m
1900 * @return CRYPTO_SUCCESS if no error occured
1901 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
1902 * \n CRYPTO_NEGATIVE_INPUT if source is negative value
1903 * \n CRYPTO_INVERSE_NOT_EXIST if inverse is not exists
1905 int SDRM_BN_ModInv(SDRM_BIG_NUM *BN_Dest, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
1907 SDRM_BIG_NUM *BN_G0, *BN_G1, *BN_V0, *BN_V1, *BN_Y, *BN_Temp1, *BN_Temp2;
1908 cc_u8 *pbBuf = NULL;
1909 cc_u32 dSize, dAllocSize;
1911 dSize = MAX2(BN_Src->Size, BN_Modulus->Size);
1912 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1914 pbBuf = (cc_u8*)malloc(dAllocSize * 7);
1918 return CRYPTO_MEMORY_ALLOC_FAIL;
1921 BN_G0 = SDRM_BN_Alloc(pbBuf, dSize);
1922 BN_G1 = SDRM_BN_Alloc((cc_u8*)BN_G0 + dAllocSize, dSize);
1923 BN_V0 = SDRM_BN_Alloc((cc_u8*)BN_G1 + dAllocSize, dSize);
1924 BN_V1 = SDRM_BN_Alloc((cc_u8*)BN_V0 + dAllocSize, dSize);
1925 BN_Y = SDRM_BN_Alloc((cc_u8*)BN_V1 + dAllocSize, dSize);
1926 BN_Temp1 = SDRM_BN_Alloc((cc_u8*)BN_Y + dAllocSize, dSize);
1927 BN_Temp2 = SDRM_BN_Alloc((cc_u8*)BN_Temp1 + dAllocSize, dSize);
1932 return CRYPTO_NEGATIVE_INPUT;
1935 //Extended Euclid Algorithm
1936 SDRM_BN_Copy(BN_G0, BN_Modulus);
1937 SDRM_BN_ModRed(BN_G1, BN_Src, BN_Modulus);
1939 SDRM_BN_Copy(BN_V0, BN_Zero);
1940 SDRM_BN_Copy(BN_V1, BN_One);
1943 SDRM_BN_Clr(BN_Dest);
1945 while(SDRM_BN_Cmp(BN_G1, BN_Zero))
1947 if (!SDRM_BN_Cmp(BN_G1, BN_One))
1949 SDRM_BN_Copy(BN_Dest, BN_V1);
1950 SDRM_BN_OPTIMIZE_LENGTH(BN_Dest);
1953 return CRYPTO_SUCCESS;
1957 SDRM_BN_Clr(BN_Temp1);
1958 SDRM_DWD_Div(BN_Y->pData, BN_Temp1->pData, BN_G0->pData, BN_G0->Length, BN_G1->pData, BN_G1->Length);
1960 BN_Y->Length = BN_G0->Length;
1961 SDRM_BN_OPTIMIZE_LENGTH(BN_Y);
1963 BN_Temp1->Length = BN_G1->Length;
1964 SDRM_BN_Copy(BN_G0, BN_Temp1);
1965 SDRM_BN_OPTIMIZE_LENGTH(BN_G0);
1967 SDRM_BN_Clr(BN_Temp1);
1968 SDRM_DWD_Mul(BN_Temp1->pData, BN_Y->pData, BN_Y->Length, BN_V1->pData, BN_V1->Length);
1969 BN_Temp1->Length = BN_Y->Length + BN_V1->Length;
1970 SDRM_BN_OPTIMIZE_LENGTH(BN_Temp1);
1972 SDRM_BN_Clr(BN_Temp2);
1973 if (SDRM_BN_Cmp(BN_V0, BN_Temp1) >= 0)
1975 SDRM_BN_Add(BN_Temp2, BN_V0, BN_Temp1);
1979 SDRM_BN_Add(BN_Temp2, BN_Temp1, BN_V0);
1982 SDRM_BN_Copy(BN_V0, BN_Temp2);
1984 if (!SDRM_BN_Cmp(BN_G0, BN_Zero))
1989 if (!SDRM_BN_Cmp(BN_G0, BN_One))
1991 SDRM_BN_Sub(BN_Dest, BN_Modulus, BN_V0);
1992 SDRM_BN_OPTIMIZE_LENGTH(BN_Dest);
1995 return CRYPTO_SUCCESS;
1999 SDRM_BN_Clr(BN_Temp1);
2000 SDRM_DWD_Div(BN_Y->pData, BN_Temp1->pData, BN_G1->pData, BN_G1->Length, BN_G0->pData, BN_G0->Length);
2002 BN_Y->Length = BN_G1->Length;
2003 SDRM_BN_OPTIMIZE_LENGTH(BN_Y);
2005 BN_Temp1->Length = BN_G0->Length;
2006 SDRM_BN_Copy(BN_G1, BN_Temp1);
2007 SDRM_BN_OPTIMIZE_LENGTH(BN_G1);
2009 SDRM_BN_Clr(BN_Temp1);
2010 SDRM_DWD_Mul(BN_Temp1->pData, BN_Y->pData, BN_Y->Length, BN_V0->pData, BN_V0->Length);
2011 BN_Temp1->Length = BN_Y->Length + BN_V0->Length;
2012 SDRM_BN_OPTIMIZE_LENGTH(BN_Temp1);
2014 SDRM_BN_Clr(BN_Temp2);
2015 if (SDRM_BN_Cmp(BN_V1, BN_Temp1) >= 0)
2017 SDRM_BN_Add(BN_Temp2, BN_V1, BN_Temp1);
2021 SDRM_BN_Add(BN_Temp2, BN_Temp1, BN_V1);
2024 SDRM_BN_Copy(BN_V1, BN_Temp2);
2027 SDRM_BN_Copy(BN_Dest, BN_Zero);
2030 return CRYPTO_INVERSE_NOT_EXIST;
2034 * @fn SDRM_MONT_Rzn2zn
2035 * @brief Convert Montgomery number to noraml number
2037 * @param BN_Dst [out]destination, normal number
2038 * @param BN_Src1 [in]source, montgomery number
2039 * @param Mont [in]montgomery parameters
2041 * @return CRYPTO_SUCCESS if no error occured
2043 int SDRM_MONT_Rzn2zn(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_MONT *Mont)
2045 cc_u32 Src1_Len, Mod_Len, ri, i;
2047 SDRM_BIG_NUM *Src1 = NULL;
2049 if (!BN_Src1->Length)
2053 return CRYPTO_SUCCESS;
2056 Src1_Len = ri = Mont->ri / SDRM_BitsInDWORD;
2057 Mod_Len = Mont->Mod->Length + 1;
2059 Src1 = SDRM_BN_Init(BN_Src1->Size + Mod_Len);
2060 if(Src1 == NULL)//fixed prevent cid=89093 by guoxing.xu
2062 return CRYPTO_ERROR;
2064 SDRM_BN_Copy(Src1, BN_Src1);
2066 if (!Src1_Len || !Mod_Len)
2069 BN_Dst->pData[0] = 0;
2072 return CRYPTO_SUCCESS;
2075 Src1->sign = BN_Src1->sign ^ Mont->Mod->sign;
2077 memset(Src1->pData + Src1->Length, 0, (Mod_Len + BN_Src1->Length - Src1->Length) * SDRM_SIZE_OF_DWORD);
2079 Src1->Length = Mod_Len + BN_Src1->Length;
2081 for (i = 0; i < Mod_Len; i++)
2083 if ((carry = SDRM_DWD_MulAdd(Src1->pData + i, Src1->Length - i, Mont->Mod->pData, Mod_Len, (cc_u32)Src1->pData[i] * Mont->N0)))
2085 Src1->pData[Src1->Length++] = carry; //Added by Park Ji soon, 05-03-2006
2086 } // (cc_u32)A.pData[i]*modulus_p <== u=a[i]*m' mod b
2087 // A=A+ (A.pData[i]*modulus_p* modulus[i])*b^i;
2089 SDRM_BN_OPTIMIZE_LENGTH(Src1);
2091 SDRM_BN_SHR(BN_Dst, Src1, (Mod_Len) * 32);
2092 //BN_Dst->Length = Src1->Length - ri;
2093 BN_Dst->Length = Src1->Length - ri- 1;//Added by yhhwang
2095 //if (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
2096 while (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
2098 SDRM_BN_Sub(BN_Dst, BN_Dst, Mont->Mod);
2103 return CRYPTO_SUCCESS;
2108 * @brief Montgomery Multiplication
2110 * @param BN_Dst [out]destination, montgomery number
2111 * @param BN_Src1 [in]first element, montgomery number
2112 * @param BN_Src2 [in]second element, montgomery number
2113 * @param Mont [in]montgomery parameters
2115 * @return CRYPTO_SUCCESS if no error occured
2117 int SDRM_MONT_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_MONT *Mont)
2121 /* Begin - Add to test input range by Yong Ho Hwang (20120809) */
2123 if (SDRM_BN_Cmp(BN_Src1, Mont->Mod) >= 0)
2125 ret = SDRM_BN_ModRed(BN_Src1, BN_Src1, Mont->Mod);
2126 if (ret != CRYPTO_SUCCESS)
2130 } else if ( BN_Src1->sign == 1)
2132 printf("Minus Value\n");
2133 ret = SDRM_BN_Add(BN_Src1, BN_Src1, Mont->Mod);
2134 if (BN_Src1->sign == 1)
2136 printf("Value Fail.\n");
2137 return CRYPTO_ERROR;
2141 if (SDRM_BN_Cmp(BN_Src2, Mont->Mod) >= 0)
2143 ret = SDRM_BN_ModRed(BN_Src2, BN_Src2, Mont->Mod);
2144 if (ret != CRYPTO_SUCCESS)
2148 } else if ( BN_Src2->sign == 1)
2150 printf("Minus Value\n");
2151 ret = SDRM_BN_Add(BN_Src2, BN_Src2, Mont->Mod);
2152 if (BN_Src2->sign == 1)
2154 printf("Value Fail.\n");
2155 return CRYPTO_ERROR;
2159 /* End - Add to test input range by Yong Ho Hwang (20120809) */
2161 ret = SDRM_BN_Mul(BN_Dst, BN_Src1, BN_Src2);
2162 if (ret != CRYPTO_SUCCESS)
2167 ret = SDRM_MONT_Rzn2zn(BN_Dst, BN_Dst, Mont);
2169 /* Begin - Add to test input range by Yong Ho Hwang (20120809) */
2171 if (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
2173 printf("Output is bigger than Mod\n");
2174 } else if ( BN_Dst->sign == 1)
2176 printf("Minus Value\n");
2179 /* End - Add to test input range by Yong Ho Hwang (20120809) */
2186 * @brief Set Montgomery parameters
2188 * @param Mont [out]montgomery parameter
2189 * @param BN_Modulus [in]modular m
2191 * @return CRYPTO_SUCCESS if no error occured
2192 * \n BN_NOT_ENOUGHT_BUFFER if malloc is failed
2193 * \n CRYPTO_INVERSE_NOT_EXIST if inverse is not exists
2195 int SDRM_MONT_Set(SDRM_BIG_MONT *Mont, SDRM_BIG_NUM *BN_Modulus)
2197 SDRM_BIG_NUM *Ri, *R;
2198 SDRM_BIG_NUM *temp, *Rsquare;
2200 cc_u32 buf[2], dSize, dAllocSize, r2Size;
2202 if ((Mont == NULL) || (BN_Modulus == NULL))
2204 return CRYPTO_INVALID_ARGUMENT;
2207 if (Mont->R == NULL)
2209 Mont->R = SDRM_BN_Init(BN_Modulus->Size);
2211 if (Mont->R == NULL)//fix prevent 89095 by guoxing.xu
2213 return CRYPTO_MEMORY_ALLOC_FAIL;
2215 if (Mont->Mod == NULL)
2217 Mont->Mod = SDRM_BN_Init(BN_Modulus->Size);
2219 if (Mont->Mod == NULL)//fix prevent 89-95 by guoxing.xu
2221 SDRM_BN_FREE(Mont->R);
2222 return CRYPTO_MEMORY_ALLOC_FAIL;
2224 if (SDRM_BN_Cmp(Mont->Mod, BN_Modulus) == 0)
2226 return CRYPTO_SUCCESS;
2229 dSize = BN_Modulus->Size + 1;
2230 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2231 if (!(pbBuf = (cc_u8*)malloc(dAllocSize * 3)))
2233 return CRYPTO_MEMORY_ALLOC_FAIL;
2236 Ri = SDRM_BN_Alloc( pbBuf, dSize);
2237 R = SDRM_BN_Alloc((cc_u8*)Ri + dAllocSize, dSize);
2238 temp = SDRM_BN_Alloc((cc_u8*)R + dAllocSize, dSize);
2240 //++ 2012.08.20 - modified by yhhwang to apply R=2^(160+32)
2242 SDRM_BN_Copy(Mont->Mod, BN_Modulus);
2244 Mont->ri = (SDRM_BN_num_bits(BN_Modulus) + (SDRM_BitsInDWORD - 1)) / SDRM_BitsInDWORD * SDRM_BitsInDWORD;
2246 SDRM_BN_SHL(R, BN_One, SDRM_BitsInDWORD);
2248 buf[0] = BN_Modulus->pData[0];
2250 temp->pData[0] = buf[0];
2252 temp->sign = BN_Modulus->sign;
2254 SDRM_BN_ModInv(Ri, R, temp);
2259 return CRYPTO_INVERSE_NOT_EXIST;
2262 SDRM_BN_SHL(Ri, Ri, SDRM_BitsInDWORD);
2263 SDRM_BN_Sub(Ri, Ri, BN_One);
2264 SDRM_BN_Div(Ri, NULL, Ri, temp);
2265 SDRM_BN_Copy(Mont->Inv_Mod, Ri);
2266 Mont->N0 = Ri->pData[0];
2268 SDRM_BN_SHL(Mont->R, BN_One, 2 * (32 + Mont->ri));
2269 SDRM_BN_ModRed(Mont->R, Mont->R, Mont->Mod);
2273 SDRM_BN_Copy(Mont->Mod, BN_Modulus);
2274 Mont->Mod->pData[Mont->Mod->Length] = 0;
2276 Mont->ri = (SDRM_BN_num_bits(BN_Modulus) + (SDRM_BitsInDWORD - 1)) / SDRM_BitsInDWORD * SDRM_BitsInDWORD;
2278 SDRM_BN_SHL(R, BN_One, SDRM_BitsInDWORD);
2280 // Compute -m^-1 mod b
2281 buf[0] = BN_Modulus->pData[0];
2283 temp->pData[0] = buf[0];
2285 temp->sign = BN_Modulus->sign;
2287 SDRM_BN_ModInv(Ri, temp, R);
2289 SDRM_BN_Add(Ri, Ri, R);
2290 Mont->N0 = Ri->pData[0];
2292 r2Size = 2 * (SDRM_BitsInDWORD + Mont->ri);
2293 Rsquare = SDRM_BN_Init(r2Size / SDRM_BitsInDWORD + 1);
2294 if (Rsquare == NULL)
2297 return CRYPTO_MEMORY_ALLOC_FAIL;
2300 // Compute R and R^2 mod M
2301 SDRM_BN_SHL(Rsquare, BN_One, r2Size);
2302 SDRM_BN_ModRed(Mont->R, Rsquare, BN_Modulus);
2303 //-- 2012.08.20 - modified by yhhwang
2308 return CRYPTO_SUCCESS;
2312 * @fn SDRM_MONT_Init
2313 * @brief Allocate new momory for Montgomery parameter
2315 * @param dSize [in]size of buffer of big number
2317 * @return Pointer to created structure
2318 * \n NULL if malloc failed
2320 SDRM_BIG_MONT *SDRM_MONT_Init(cc_u32 dSize)
2322 SDRM_BIG_MONT *Mont;
2323 cc_u32 AllocSiz = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2325 Mont = (SDRM_BIG_MONT *)malloc(sizeof(SDRM_BIG_MONT) + AllocSiz * 3);
2332 Mont->R = SDRM_BN_Alloc((cc_u8*)Mont + sizeof(SDRM_BIG_MONT), dSize);
2333 Mont->Mod = SDRM_BN_Alloc((cc_u8*)Mont->R + AllocSiz, dSize);
2334 Mont->Inv_Mod = SDRM_BN_Alloc((cc_u8*)Mont->Mod + AllocSiz, dSize);
2340 * @fn SDRM_MONT_Free
2341 * @brief Free allocated memory for montgomery paramter
2343 * @param Mont [in]montgomery parameters
2347 void SDRM_MONT_Free(SDRM_BIG_MONT *Mont)
2354 int SDRM_BN_num_bits_index(SDRM_BIG_NUM *BN_Src, cc_u32 bitIndex)
2359 if (BN_Src->Length == 0)
2364 int div = bitIndex / (sizeof(cc_u32) * 8);
2365 int rem = bitIndex % (sizeof(cc_u32) * 8);
2367 l = BN_Src->pData[div];
2368 j = SDRM_UINT32_num_bits_index(&l, rem);
2372 int SDRM_UINT32_num_bits_index(cc_u32 *pdSrc, cc_u32 bitIndex)
2392 return temp & 0x00000001;
2398 * @fn SDRM_BN_num_bits
2399 * @brief Calc bit-length of Big Number
2401 * @param BN_Src [in]source
2403 * @return bit-length
2405 int SDRM_BN_num_bits(SDRM_BIG_NUM *BN_Src)
2410 if (BN_Src->Length == 0)
2415 l = BN_Src->pData[BN_Src->Length - 1];
2416 i = (BN_Src->Length-1) * SDRM_BitsInDWORD;
2418 j = SDRM_UINT32_num_bits(&l);
2424 * @fn SDRM_UINT32_num_bits
2425 * @brief Calc bit-length of cc_u32
2427 * @param pdSrc [in]source
2429 * @return bit-length
2431 int SDRM_UINT32_num_bits(cc_u32 *pdSrc)
2453 * @fn SDRM_INT_num_bits
2454 * @brief Calc bit-length of integer
2456 * @param Src [in]source
2458 * @return bit-length
2460 int SDRM_INT_num_bits(int Src)
2479 * @fn SDRM_BN_ModExp
2480 * @brief Big Number Modular Exponentiation
2482 * @param BN_Dst [out]destination
2483 * @param BN_Base [in]base
2484 * @param BN_Exponent [in]exponent
2485 * @param BN_Modulus [in]modular m
2487 * @return CRYPTO_SUCCESS if no error occured
2488 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
2489 * \n CRYPTO_ERROR if evaluation is failed
2491 int SDRM_BN_ModExp(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
2493 SDRM_BIG_NUM *c_, *a_, *BN_Temp;
2494 SDRM_BIG_MONT *Mont;
2497 cc_u32 dSize, dAllocSize;
2499 dSize = MAX3(BN_Base->Size, BN_Exponent->Size, BN_Modulus->Size);
2500 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2502 pbBuf = (cc_u8*)malloc(dAllocSize * 3);
2505 return CRYPTO_MEMORY_ALLOC_FAIL;
2508 c_ = SDRM_BN_Alloc(pbBuf, dSize);
2509 a_ = SDRM_BN_Alloc((cc_u8*)c_ + dAllocSize, dSize);
2510 BN_Temp = SDRM_BN_Alloc((cc_u8*)a_ + dAllocSize, dSize);
2512 if (SDRM_BN_Cmp(BN_Base, BN_Modulus) >= 0)
2514 SDRM_BN_ModRed(BN_Temp, BN_Base, BN_Modulus);
2521 if (SDRM_BN_Cmp(BN_Temp, BN_Zero) == 0)
2523 SDRM_BN_Copy(BN_Dst, BN_Zero);
2526 return CRYPTO_SUCCESS;
2529 Mont = SDRM_MONT_Init(dSize);
2530 SDRM_MONT_Set(Mont, BN_Modulus);
2532 SDRM_MONT_Zn2rzn(a_, BN_Temp, Mont);
2533 SDRM_MONT_Zn2rzn(c_, BN_One, Mont);
2535 m = SDRM_BN_num_bits(BN_Exponent);
2537 for (i = m - 1; i >= 0; i--)
2539 SDRM_MONT_Mul(c_, c_, c_, Mont);
2541 if (SDRM_CheckBitUINT32(BN_Exponent->pData, i) == 1)
2543 SDRM_MONT_Mul(c_, c_, a_, Mont);
2547 SDRM_MONT_Rzn2zn(BN_Dst, c_, Mont);
2549 SDRM_MONT_Free(Mont);
2553 return CRYPTO_SUCCESS;
2557 * @fn SDRM_BN_ModExp2
2558 * @brief Big Number Modular Exponentiation2 - Karen's method
2560 * @param BN_Dst [out]destination
2561 * @param BN_Base [in]base
2562 * @param BN_Exponent [in]exponent
2563 * @param BN_Modulus [in]modular m
2565 * @return CRYPTO_SUCCESS if no error occured
2566 * \n CRYPTO_MEMORY_ALLOC_FAIL if malloc is failed
2567 * \n CRYPTO_ERROR if evaluation is failed
2569 int SDRM_BN_ModExp2(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
2572 SDRM_BIG_NUM *BN_Temp;
2574 if ((BN_Dst != BN_Base) && (BN_Dst != BN_Exponent) && (BN_Dst != BN_Modulus))
2576 SDRM_BN_Clr(BN_Dst);
2579 if (SDRM_BN_Cmp(BN_Base, BN_Modulus) >= 0)
2581 BN_Temp = SDRM_BN_Init(MAX3(BN_Base->Size, BN_Exponent->Size, BN_Modulus->Size));
2582 if (BN_Temp == NULL)
2584 return CRYPTO_MEMORY_ALLOC_FAIL;
2587 if (BN_Temp == BN_Base)
2590 return CRYPTO_ERROR;
2593 SDRM_BN_ModRed(BN_Temp, BN_Base, BN_Modulus);
2600 if (SDRM_BN_Cmp(BN_Temp, BN_Zero) == 0)
2602 SDRM_BN_Clr(BN_Dst);
2604 if (BN_Temp != BN_Base)
2609 return CRYPTO_SUCCESS;
2612 retVal = SDRM_ll_ExpMod(BN_Temp->pData, BN_Temp->Length * 4, BN_Exponent->pData, BN_Exponent->Length * 4, BN_Modulus->pData, BN_Modulus->Length * 4, BN_Dst->pData);
2613 if (retVal != CRYPTO_SUCCESS)
2615 if (BN_Temp != BN_Base)
2623 BN_Dst->Length = BN_Dst->Size;
2625 while(BN_Dst->pData[BN_Dst->Length - 1] == 0)
2630 if (BN_Temp != BN_Base)
2635 return CRYPTO_SUCCESS;
2639 * @fn SDRM_BN_CheckRelativelyPrime
2640 * @brief get gcd of two big number
2642 * @param BN_Src1 [in]first element
2643 * @param BN_Src2 [in]second element
2645 * @return CRYPTO_ISPRIME if two elements are relatively prime
2646 * \n CRYPTO_MEMORY_ALLOC_FAIL if memory allocation is failed
2647 * \n CRYPTO_ERROR otherwise
2649 int SDRM_BN_CheckRelativelyPrime(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
2651 SDRM_BIG_NUM *Temp, *S1, *S2;
2653 cc_u32 dSize, dAllocSize;
2655 dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
2656 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2658 if (!(pbBuf = (cc_u8*)malloc(dAllocSize * 3)))
2660 return CRYPTO_MEMORY_ALLOC_FAIL;
2663 S1 = SDRM_BN_Alloc(pbBuf, dSize);
2664 S2 = SDRM_BN_Alloc((cc_u8*)S1 + dAllocSize, dSize);
2665 Temp = SDRM_BN_Alloc((cc_u8*)S2 + dAllocSize, dSize);
2667 if (SDRM_BN_Cmp(BN_Src1, BN_Src2) >= 0)
2669 SDRM_BN_Copy(S1, BN_Src1);
2670 SDRM_BN_Copy(S2, BN_Src2);
2674 SDRM_BN_Copy(S1, BN_Src2);
2675 SDRM_BN_Copy(S2, BN_Src1);
2678 SDRM_BN_OPTIMIZE_LENGTH(S1);
2679 SDRM_BN_OPTIMIZE_LENGTH(S2);
2683 SDRM_BN_ModRed(Temp, S1, S2);
2684 SDRM_BN_Copy(S1, S2);
2685 SDRM_BN_Copy(S2, Temp);
2688 if (SDRM_BN_Cmp(S1, BN_One) == 0)
2692 return CRYPTO_ISPRIME;
2697 return CRYPTO_ERROR;
2700 //small primes for pre-testing
2701 static cc_u32 miniPrimes[] = {
2702 0xC8E15F2A, 0x16FA4227, 0x87B81DA9, 0xDA38C071, 0xFDB17C23, 0xFE5E796B,
2703 0xC7E4CBF5, 0x7EB0F0B1, 0xB72EFC93, 0xF46CEE57, 0x80B2C2BB, 0x34A77199,
2704 0x447D1BD5, 0xEA4C7C31, 0xF046D45B, 0xFF55A7BF, 0x9B287041, 0x85663BEF,
2709 * @fn SDRM_BN_MILLER_RABIN
2710 * @brief MILLER_RABIN Test
2712 * @param n [in]value to test
2713 * @param t [in]security parameter
2715 * @return CRYPTO_ISPRIME if n is (probably) prime
2716 * \n CRYPTO_INVALID_ARGUMENT if n is composite
2718 int SDRM_BN_MILLER_RABIN(SDRM_BIG_NUM* n, cc_u32 t)
2720 SDRM_BIG_NUM *r, *a, *y, *n1;
2721 cc_u32 i, j, tmp, srcLen, s = 1;
2723 cc_u32 dSize, dAllocSize;
2726 dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2730 return CRYPTO_INVALID_ARGUMENT;
2733 if ((n->pData[0] & 0x01) == 0)
2735 return CRYPTO_INVALID_ARGUMENT;
2738 for (i = 0; miniPrimes[i] != 0; i++)
2741 for (j = n->Length - 1; j != (cc_u32)-1; j--)
2743 tmp = SDRM_DIGIT_Mod(tmp, n->pData[j], miniPrimes[i]);
2746 if(SDRM_DIGIT_Gcd(miniPrimes[i], tmp) != 1)
2748 return CRYPTO_INVALID_ARGUMENT;
2752 while(SDRM_CheckBitUINT32(n->pData, s) == 0) {
2756 pbBuf = (cc_u8*)malloc(dAllocSize * 4);
2759 return CRYPTO_MEMORY_ALLOC_FAIL;
2762 r = SDRM_BN_Alloc( pbBuf, dSize);
2763 a = SDRM_BN_Alloc((cc_u8*)r + dAllocSize, dSize);
2764 y = SDRM_BN_Alloc((cc_u8*)a + dAllocSize, dSize);
2765 n1 = SDRM_BN_Alloc((cc_u8*)y + dAllocSize, dSize);
2767 SDRM_BN_Sub(n1, n, BN_One);
2768 SDRM_BN_SHR(r, n1, s);
2770 srcLen = SDRM_BN_num_bits(n);
2772 for (i = 1; i <= t; i++)
2774 SDRM_BN_Rand(a, srcLen);
2775 a->pData[n->Length - 1] %= n->pData[n->Length - 1];
2777 SDRM_BN_ModExp(y, a, r, n);
2778 if ((SDRM_BN_Cmp(y, BN_One) == 0) || (SDRM_BN_Cmp(y, n1) == 0))
2783 for (j = 1; (j < s) && SDRM_BN_Cmp(y, n1) != 0; j++)
2785 SDRM_BN_ModMul(y, y, y, n);
2787 if (SDRM_BN_Cmp(y, BN_One) == 0)
2790 return CRYPTO_INVALID_ARGUMENT;
2794 if (SDRM_BN_Cmp(y, n1) != 0)
2798 return CRYPTO_INVALID_ARGUMENT;
2804 return CRYPTO_ISPRIME;
2808 * @fn int SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst)
2809 * @brief Convert Hex String to Big Number
2811 * @param pbSrc [in]source hex string
2812 * @param BN_Dst [out]output big number
2814 * @return CRYPTO_SUCCESS if no error is occured
2815 * \n CRYPTO_MEMORY_ALLOC_FAIL if arrary is too small
2817 int SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst)
2820 cc_u8 * bufferHex = NULL;
2822 n = (cc_u32)strlen((const char*)pbSrc);
2826 BN_Dst = SDRM_BN_Init((n / SDRM_SIZE_BLOCK) * SDRM_SIZE_OF_DWORD * 8);
2829 return CRYPTO_MEMORY_ALLOC_FAIL;
2838 BN_Dst->Length = n / SDRM_SIZE_BLOCK;
2840 if( n % SDRM_SIZE_BLOCK != 0 ) {
2843 #if 0 //fix prevent problem by guoxing.xu 20140826. move to before
2846 BN_Dst = SDRM_BN_Init(BN_Dst->Length * SDRM_SIZE_OF_DWORD * 8);
2849 for(i = 0; i < BN_Dst->Length ; i++)
2851 BN_Dst->pData[i] = 0;
2854 //full string: bufferHex mod Length = 0
2855 bufferHex = (cc_u8 *)malloc( sizeof(cc_u8) * (BN_Dst->Length * SDRM_SIZE_BLOCK));
2858 for(i = 0; i < BN_Dst->Length * SDRM_SIZE_BLOCK; i++)
2864 for(i = (BN_Dst->Length * SDRM_SIZE_BLOCK) - 1; (int)k >= 0; i--, k--)
2866 bufferHex[i] = pbSrc[k];
2869 for(i = 0; i < BN_Dst->Length; i++)
2871 for(j = (BN_Dst->Length * SDRM_SIZE_BLOCK) - (i * SDRM_SIZE_BLOCK) - SDRM_SIZE_BLOCK; j < (BN_Dst->Length * SDRM_SIZE_BLOCK) - (i * SDRM_SIZE_BLOCK) ; j++)
2873 switch(bufferHex[j])
2876 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2877 BN_Dst->pData[i] |= 0x0;
2880 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2881 BN_Dst->pData[i] |= 0x1;
2884 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2885 BN_Dst->pData[i] |= 0x2;
2888 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2889 BN_Dst->pData[i] |= 0x3;
2892 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2893 BN_Dst->pData[i] |= 0x4;
2896 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2897 BN_Dst->pData[i] |= 0x5;
2900 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2901 BN_Dst->pData[i] |= 0x6;
2904 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2905 BN_Dst->pData[i] |= 0x7;
2908 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2909 BN_Dst->pData[i] |= 0x8;
2912 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2913 BN_Dst->pData[i] |= 0x9;
2916 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2917 BN_Dst->pData[i] |= 0xa;
2920 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2921 BN_Dst->pData[i] |= 0xa;
2924 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2925 BN_Dst->pData[i] |= 0xb;
2928 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2929 BN_Dst->pData[i] |= 0xb;
2932 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2933 BN_Dst->pData[i] |= 0xc;
2936 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2937 BN_Dst->pData[i] |= 0xc;
2940 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2941 BN_Dst->pData[i] |= 0xd;
2944 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2945 BN_Dst->pData[i] |= 0xd;
2948 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2949 BN_Dst->pData[i] |= 0xe;
2952 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2953 BN_Dst->pData[i] |= 0xe;
2956 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2957 BN_Dst->pData[i] |= 0xf;
2960 BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2961 BN_Dst->pData[i] |= 0xf;
2966 return CRYPTO_INVALID_ARGUMENT;
2975 return CRYPTO_SUCCESS;
2979 * @fn cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
2980 * @brief Convert Big Number to binary String
2982 * @param pbSrc [in]source big number
2983 * @param BN_Dst [out]output numberBits of uot string
2985 * @return (cc_u8 *) binary string
2987 cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src)
2990 cc_u32 mask = 0x80000000;
2992 cc_u8 *tempC, *tempR;
2993 (*numberBits) = sizeof(cc_u8) * BN_Src->Length * SDRM_SIZE_OF_DWORD * 8 + 1;
2994 tempC = (cc_u8*)malloc(*numberBits);
2995 tempR = (cc_u8*)malloc(*numberBits);
2996 tempC[(*numberBits) - 1] = '\0';
2997 for(i = BN_Src->Length - 1; (int)i >= 0 ; i--)
2999 temp = BN_Src->pData[i];
3000 for(j = 0; j < (SDRM_SIZE_OF_DWORD * 8); j++)
3002 if((temp & mask) > 0) {
3003 tempC[(((BN_Src->Length - 1) - i) * (SDRM_SIZE_OF_DWORD * 8)) + j] = '1';
3006 tempC[(((BN_Src->Length - 1) - i) * (SDRM_SIZE_OF_DWORD * 8)) + j] = '0';
3013 //next block for normalize length string (eg 0111 = 111)
3015 for(i = 0; i < (*numberBits); i++)
3017 if(tempC[i] == '0' && check == 0) {
3024 tempR[k] = tempC[i];
3029 (*numberBits) = k - 1;
3037 * @fn int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t);
3038 * @brief Set word to Big Number
3040 * @param pbSrc [in]source word
3041 * @param BN_Dst [out]output Big Nubmer
3043 * @return CRYPTO_SUCCESS if no error is occuredg
3045 int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t)
3051 BN_Dst->pData[0] = t;
3057 BN_Dst->pData[0] = t * (-1);
3060 return CRYPTO_SUCCESS;
3064 * @fn int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src);
3065 * @brief check big number is zero
3067 * @param pbSrc [in]source big number
3069 * @return 0 - false, 1 - true
3071 int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src)
3073 return ((BN_Src)->Length == 0)?1:0;
3077 * @fn cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
3078 * @brief Convert Big Number to four String
3080 * @param pbSrc [in]source big number
3081 * @param BN_Dst [out]output numberBits of four string
3083 * @return (cc_u8 *) four string
3085 cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src)
3087 SDRM_BIG_NUM *d, *tempREM, *num;
3089 cc_u32 sLength = (2 * SDRM_SIZE_OF_DWORD) * BN_Src->Length;
3090 cc_u8 * strDestTemp = (cc_u8*)malloc(sLength * 10);
3095 if(strDestTemp == NULL)
3100 d = SDRM_BN_Init(BN_Src->Size);
3101 if( d == NULL)// fix prevent cid =89093 by guoxing.xu
3106 tempREM = SDRM_BN_Init(BN_Src->Size);
3107 num = SDRM_BN_Init(BN_Src->Size);
3108 if( num == NULL)//fix prevent cid = 89093 by guoxing.xu
3115 SDRM_BN_Copy(num, BN_Src);
3116 SDRM_BN_SetWord(d, 4);
3118 while (!SDRM_BN_isZero(num))
3120 SDRM_BN_Div(num, tempREM, num, d);
3121 //itoa(tempREM->pData[0], (char *)tempChar, 10);
3122 //sprintf((char*)tempChar, "%d", tempREM->pData[0]);
3123 snprintf((char*)tempChar, sizeof(tempChar), "%d", tempREM->pData[0]);// fix prevnet 60199 by guoxing.xu
3124 strDestTemp[(*numberBits)] = tempChar[0];
3128 if((*numberBits) != 0)
3130 strDest = (cc_u8*)malloc((*numberBits) + 1);
3131 for(i = 0; i < (*numberBits); i++) {
3132 strDest[i] = strDestTemp[((*numberBits) - 1) - i];
3134 strDest[(*numberBits)] = '\0';
3139 strDest = (cc_u8*)malloc((*numberBits) + 1);
3141 strDest[(*numberBits)] = '\0';
3146 SDRM_BN_FREE(tempREM);
3153 * @fn SDRM_BN_MassInit
3154 * @brief Allocate a series of big number object
3156 * @param dBufSize [in]buffer size of each big number
3157 * @param count [in]number BigNumbers
3159 * @return double pointer of SDRM_BIG_NUM structure
3160 * \n NULL if memory allocation is failed
3162 SDRM_BIG_NUM **SDRM_BN_MassInit(cc_u32 dBufSize, cc_u32 count)
3165 cc_u32 bnsiz = sizeof(SDRM_BIG_NUM) + dBufSize * SDRM_SIZE_OF_DWORD;
3169 SDRM_BIG_NUM** BN_Buf = (SDRM_BIG_NUM**)malloc((sizeof(SDRM_BIG_NUM*) + bnsiz) * count);
3176 memset(BN_Buf, 0x00, (sizeof(SDRM_BIG_NUM*) + bnsiz) * count);
3178 ptr = (cc_u8*)BN_Buf + sizeof(SDRM_BIG_NUM*) * count;
3179 for(i = 0; i < count; i++)
3181 //add by guoxing.xu to avoid warning. 2/15/2014
3183 BN_Buf[i] = (SDRM_BIG_NUM*)tmp;
3184 //BN_Buf[i] = (SDRM_BIG_NUM*)ptr;
3185 BN_Buf[i]->Size = dBufSize;
3186 tmp = (ptr + sizeof(SDRM_BIG_NUM));
3187 BN_Buf[i]->pData = (cc_u32*)tmp;
3188 //BN_Buf[i]->pData = (cc_u32*)(ptr + sizeof(SDRM_BIG_NUM));
3196 * @fn SDRM_BN_IntInit
3197 * @brief Allocate a big number object and assign an integer value
3199 * @param dSize [in]buffer size of each big number
3200 * @param data [in]integer value
3202 * @return double pointer of SDRM_BIG_NUM structure
3203 * \n NULL if memory allocation is failed
3205 SDRM_BIG_NUM *SDRM_BN_IntInit(cc_u32 dSize, cc_u32 data)
3207 SDRM_BIG_NUM* BN_Buf = SDRM_BN_Init(dSize);
3213 BN_Buf->pData[0] = data;
3219 /***************************** End of File *****************************/