Changeset 52290 in vbox for trunk/src/VBox/Runtime/common/math
- Timestamp:
- Aug 6, 2014 10:14:47 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 95402
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/math/bignum.cpp
r52050 r52290 29 29 * Header Files * 30 30 *******************************************************************************/ 31 /*#ifdef IN_RING3 32 # define RTMEM_WRAP_TO_EF_APIS 33 #endif*/ 31 34 #include "internal/iprt.h" 32 35 #include <iprt/bignum.h> … … 40 43 41 44 45 /******************************************************************************* 46 * Defined Constants And Macros * 47 *******************************************************************************/ 48 /** Allocation alignment in elements. */ 49 #ifndef RTMEM_WRAP_TO_EF_APIS 50 # define RTBIGNUM_ALIGNMENT 4U 51 #else 52 # define RTBIGNUM_ALIGNMENT 1U 53 #endif 54 42 55 /** The max size (in bytes) of an elements array. */ 43 56 #define RTBIGNUM_MAX_SIZE _4M 57 58 59 /** Assert the validity of a big number structure pointer in strict builds. */ 60 #ifdef RT_STRICT 61 # define RTBIGNUM_ASSERT_VALID(a_pBigNum) \ 62 do { \ 63 AssertPtr(a_pBigNum); \ 64 Assert(!(a_pBigNum)->fCurScrambled); \ 65 Assert( (a_pBigNum)->cUsed == (a_pBigNum)->cAllocated \ 66 || ASMMemIsAllU32(&(a_pBigNum)->pauElements[(a_pBigNum)->cUsed], \ 67 ((a_pBigNum)->cAllocated - (a_pBigNum)->cUsed) * RTBIGNUM_ELEMENT_SIZE, 0) == NULL); \ 68 } while (0) 69 #else 70 # define RTBIGNUM_ASSERT_VALID(a_pBigNum) do {} while (0) 71 #endif 72 73 74 /** Enable assembly optimizations. */ 75 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 76 # define IPRT_BIGINT_WITH_ASM 77 #endif 78 79 80 /** @def RTBIGNUM_ZERO_ALIGN 81 * For calculating the rtBigNumEnsureExtraZeroElements argument from cUsed. 82 * This has to do with 64-bit assembly instruction operating as RTBIGNUMELEMENT 83 * was 64-bit on some hosts. 84 */ 85 #if defined(IPRT_BIGINT_WITH_ASM) && ARCH_BITS == 64 && RTBIGNUM_ELEMENT_SIZE == 4 && defined(RT_LITTLE_ENDIAN) 86 # define RTBIGNUM_ZERO_ALIGN(a_cUsed) RT_ALIGN_32(a_cUsed, 2) 87 #elif defined(IPRT_BIGINT_WITH_ASM) 88 # define RTBIGNUM_ZERO_ALIGN(a_cUsed) (a_cUsed) 89 #else 90 # define RTBIGNUM_ZERO_ALIGN(a_cUsed) (a_cUsed) 91 #endif 92 93 94 /******************************************************************************* 95 * Internal Functions * 96 *******************************************************************************/ 97 #ifdef IPRT_BIGINT_WITH_ASM 98 /* bignum-amd64-x86.asm: */ 99 DECLASM(void) rtBigNumMagnitudeSubAssemblyWorker(RTBIGNUMELEMENT *pauResult, RTBIGNUMELEMENT const *pauMinuend, 100 RTBIGNUMELEMENT const *pauSubtrahend, uint32_t cUsed); 101 DECLASM(void) rtBigNumMagnitudeSubThisAssemblyWorker(RTBIGNUMELEMENT *pauMinuendResult, RTBIGNUMELEMENT const *pauSubtrahend, 102 uint32_t cUsed); 103 DECLASM(RTBIGNUMELEMENT) rtBigNumMagnitudeShiftLeftOneAssemblyWorker(RTBIGNUMELEMENT *pauElements, uint32_t cUsed, 104 RTBIGNUMELEMENT uCarry); 105 #endif 44 106 45 107 … … 110 172 * @param pBigNum The big number. 111 173 * @param cNewUsed The new cUsed value. 112 */ 113 static int rtBigNumGrow(PRTBIGNUM pBigNum, uint32_t cNewUsed) 114 { 174 * @param cMinElements The minimum number of elements. 175 */ 176 static int rtBigNumGrow(PRTBIGNUM pBigNum, uint32_t cNewUsed, uint32_t cMinElements) 177 { 178 Assert(cMinElements >= cNewUsed); 115 179 uint32_t const cbOld = pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE; 116 uint32_t const cNew = RT_ALIGN_32(c NewUsed, 4);180 uint32_t const cNew = RT_ALIGN_32(cMinElements, RTBIGNUM_ALIGNMENT); 117 181 uint32_t const cbNew = cNew * RTBIGNUM_ELEMENT_SIZE; 118 182 Assert(cbNew > cbOld); … … 140 204 * Changes the cUsed member, growing the pauElements array if necessary. 141 205 * 142 * No assumptions about the value of any added elements should be made. This 143 * method is mainly for resizing result values where the caller will repopulate 144 * the element values short after this call. 206 * Any elements added to the array will be initialized to zero. 145 207 * 146 208 * @returns IPRT status code. … … 152 214 if (pBigNum->cAllocated >= cNewUsed) 153 215 { 216 if (pBigNum->cUsed > cNewUsed) 217 RT_BZERO(&pBigNum->pauElements[cNewUsed], (pBigNum->cUsed - cNewUsed) * RTBIGNUM_ELEMENT_SIZE); 218 #ifdef RT_STRICT 219 else if (pBigNum->cUsed != cNewUsed) 220 Assert(ASMMemIsAllU32(&pBigNum->pauElements[pBigNum->cUsed], 221 (cNewUsed - pBigNum->cUsed) * RTBIGNUM_ELEMENT_SIZE, 0) == NULL); 222 #endif 154 223 pBigNum->cUsed = cNewUsed; 155 224 return VINF_SUCCESS; 156 225 } 157 return rtBigNumGrow(pBigNum, cNewUsed); 158 } 226 return rtBigNumGrow(pBigNum, cNewUsed, cNewUsed); 227 } 228 229 230 /** 231 * Extended version of rtBigNumSetUsed that also allow specifying the number of 232 * zero elements required. 233 * 234 * @returns IPRT status code. 235 * @param pBigNum The big number. 236 * @param cNewUsed The new cUsed value. 237 * @param cMinElements The minimum number of elements allocated. The 238 * difference between @a cNewUsed and @a cMinElements 239 * is initialized to zero because all free elements are 240 * zero. 241 */ 242 DECLINLINE(int) rtBigNumSetUsedEx(PRTBIGNUM pBigNum, uint32_t cNewUsed, uint32_t cMinElements) 243 { 244 if (pBigNum->cAllocated >= cMinElements) 245 { 246 if (pBigNum->cUsed > cNewUsed) 247 RT_BZERO(&pBigNum->pauElements[cNewUsed], (pBigNum->cUsed - cNewUsed) * RTBIGNUM_ELEMENT_SIZE); 248 #ifdef RT_STRICT 249 else if (pBigNum->cUsed != cNewUsed) 250 Assert(ASMMemIsAllU32(&pBigNum->pauElements[pBigNum->cUsed], 251 (cNewUsed - pBigNum->cUsed) * RTBIGNUM_ELEMENT_SIZE, 0) == NULL); 252 #endif 253 pBigNum->cUsed = cNewUsed; 254 return VINF_SUCCESS; 255 } 256 return rtBigNumGrow(pBigNum, cNewUsed, cMinElements); 257 } 258 259 260 /** 261 * For ensuring zero padding of pauElements for sub/add with carry assembly 262 * operations. 263 * 264 * @returns IPRT status code. 265 * @param pBigNum The big number. 266 * @param cElements The number of elements that must be in the elements 267 * array array, where those after pBigNum->cUsed must 268 * be zero. 269 */ 270 DECLINLINE(int) rtBigNumEnsureExtraZeroElements(PRTBIGNUM pBigNum, uint32_t cElements) 271 { 272 if (pBigNum->cAllocated >= cElements) 273 { 274 Assert( pBigNum->cAllocated == pBigNum->cUsed 275 || ASMMemIsAllU32(&pBigNum->pauElements[pBigNum->cUsed], 276 (pBigNum->cAllocated - pBigNum->cUsed) * RTBIGNUM_ELEMENT_SIZE, 0) == NULL); 277 return VINF_SUCCESS; 278 } 279 return rtBigNumGrow(pBigNum, pBigNum->cUsed, cElements); 280 } 281 159 282 160 283 /** … … 321 444 if (pBigNum->cUsed) 322 445 { 323 pBigNum->cAllocated = RT_ALIGN_32(pBigNum->cUsed, 4);446 pBigNum->cAllocated = RT_ALIGN_32(pBigNum->cUsed, RTBIGNUM_ALIGNMENT); 324 447 if (pBigNum->fSensitive) 325 448 pBigNum->pauElements = (RTBIGNUMELEMENT *)RTMemSaferAllocZ(pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE); … … 415 538 pBigNum->pauElements[i] = 0U - pBigNum->pauElements[i] - 1U; 416 539 } 540 541 /* 542 * Clear unused elements. 543 */ 544 if (pBigNum->cUsed != pBigNum->cAllocated) 545 { 546 RTBIGNUMELEMENT *puUnused = &pBigNum->pauElements[pBigNum->cUsed]; 547 AssertCompile(RTBIGNUM_ALIGNMENT <= 4); 548 switch (pBigNum->cAllocated - pBigNum->cUsed) 549 { 550 default: AssertFailed(); 551 case 3: *puUnused++ = 0; 552 case 2: *puUnused++ = 0; 553 case 1: *puUnused++ = 0; 554 } 555 } 556 RTBIGNUM_ASSERT_VALID(pBigNum); 417 557 } 418 558 … … 455 595 { 456 596 /* Duplicate the element array. */ 457 pBigNum->cAllocated = RT_ALIGN_32(pBigNum->cUsed, 4);597 pBigNum->cAllocated = RT_ALIGN_32(pBigNum->cUsed, RTBIGNUM_ALIGNMENT); 458 598 if (pBigNum->fSensitive) 459 599 pBigNum->pauElements = (RTBIGNUMELEMENT *)RTMemSaferAllocZ(pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE); … … 461 601 pBigNum->pauElements = (RTBIGNUMELEMENT *)RTMemAlloc(pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE); 462 602 if (RT_LIKELY(pBigNum->pauElements)) 603 { 463 604 memcpy(pBigNum->pauElements, pSrc->pauElements, pBigNum->cUsed * RTBIGNUM_ELEMENT_SIZE); 605 if (pBigNum->cUsed != pBigNum->cAllocated) 606 RT_BZERO(&pBigNum->pauElements[pBigNum->cUsed], (pBigNum->cAllocated - pBigNum->cUsed) * RTBIGNUM_ELEMENT_SIZE); 607 } 464 608 else 465 609 { … … 477 621 if (RT_SUCCESS(rc)) 478 622 { 623 RTBIGNUM_ASSERT_VALID(pSrc); 479 624 rc = rtBigNumCloneInternal(pBigNum, pSrc); 480 625 if (RT_SUCCESS(rc)) … … 512 657 if (RT_SUCCESS(rc)) 513 658 { 659 RTBIGNUM_ASSERT_VALID(pDst); 514 660 rc = rtBigNumUnscramble((PRTBIGNUM)pSrc); 515 661 if (RT_SUCCESS(rc)) 516 662 { 663 RTBIGNUM_ASSERT_VALID(pSrc); 517 664 if ( pDst->fSensitive == pSrc->fSensitive 518 665 || pDst->fSensitive) … … 520 667 if (pDst->cAllocated >= pSrc->cUsed) 521 668 { 669 if (pDst->cUsed > pSrc->cUsed) 670 RT_BZERO(&pDst->pauElements[pSrc->cUsed], (pDst->cUsed - pSrc->cUsed) * RTBIGNUM_ELEMENT_SIZE); 522 671 pDst->cUsed = pSrc->cUsed; 523 672 pDst->fNegative = pSrc->fNegative; … … 526 675 else 527 676 { 528 rc = rtBigNumGrow(pDst, pSrc->cUsed );677 rc = rtBigNumGrow(pDst, pSrc->cUsed, pSrc->cUsed); 529 678 if (RT_SUCCESS(rc)) 530 679 { … … 610 759 if (RT_SUCCESS(rc)) 611 760 { 761 RTBIGNUM_ASSERT_VALID(pBigNum); 612 762 rc = VINF_SUCCESS; 613 763 if (pBigNum->cUsed != 0) … … 681 831 if (RT_SUCCESS(rc)) 682 832 { 833 RTBIGNUM_ASSERT_VALID(pLeft); 683 834 rc = rtBigNumUnscramble(pRight); 684 835 if (RT_SUCCESS(rc)) 685 836 { 837 RTBIGNUM_ASSERT_VALID(pRight); 686 838 if (pLeft->fNegative == pRight->fNegative) 687 839 { … … 720 872 if (RT_SUCCESS(rc)) 721 873 { 874 RTBIGNUM_ASSERT_VALID(pLeft); 722 875 if (!pLeft->fNegative) 723 876 { … … 767 920 if (RT_SUCCESS(rc)) 768 921 { 922 RTBIGNUM_ASSERT_VALID(pLeft); 769 923 if (pLeft->fNegative == (iRight < 0)) 770 924 { … … 843 997 844 998 /** 999 * Copies the magnitude of on number (@a pSrc) to another (@a pBigNum). 1000 * 1001 * The variables must be unscrambled. The sign flag is not considered nor 1002 * touched. 1003 * 1004 * @returns IPRT status code. 1005 * @param pDst The destination number. 1006 * @param pSrc The source number. 1007 */ 1008 DECLINLINE(int) rtBigNumMagnitudeCopy(PRTBIGNUM pDst, PCRTBIGNUM pSrc) 1009 { 1010 int rc = rtBigNumSetUsed(pDst, pSrc->cUsed); 1011 if (RT_SUCCESS(rc)) 1012 memcpy(pDst->pauElements, pSrc->pauElements, pSrc->cUsed * RTBIGNUM_ELEMENT_SIZE); 1013 return rc; 1014 } 1015 1016 1017 /** 845 1018 * Does addition with carry. 846 1019 * … … 953 1126 Assert(pMinuend->cUsed >= pSubtrahend->cUsed); 954 1127 955 int rc = rtBigNumSetUsed(pResult, pMinuend->cUsed);956 if ( RT_SUCCESS(rc))1128 int rc; 1129 if (pSubtrahend->cUsed) 957 1130 { 958 1131 /* 959 * The primitive way, as usual. 1132 * Resize the result. In the assembly case, ensure that all three arrays 1133 * has the same number of used entries, possibly with an extra zero 1134 * element on 64-bit systems. 960 1135 */ 961 RTBIGNUMELEMENT fBorrow = 0; 962 for (uint32_t i = 0; i < pMinuend->cUsed; i++) 963 pResult->pauElements[i] = rtBigNumElementSubWithBorrow(pMinuend->pauElements[i], 964 rtBigNumGetElement(pSubtrahend, i), 965 &fBorrow); 966 Assert(fBorrow == 0); 967 968 /* 969 * Trim the result. 970 */ 971 rtBigNumStripTrailingZeros(pResult); 972 } 1136 rc = rtBigNumSetUsedEx(pResult, pMinuend->cUsed, RTBIGNUM_ZERO_ALIGN(pMinuend->cUsed)); 1137 #ifdef IPRT_BIGINT_WITH_ASM 1138 if (RT_SUCCESS(rc)) 1139 rc = rtBigNumEnsureExtraZeroElements((PRTBIGNUM)pMinuend, RTBIGNUM_ZERO_ALIGN(pMinuend->cUsed)); 1140 if (RT_SUCCESS(rc)) 1141 rc = rtBigNumEnsureExtraZeroElements((PRTBIGNUM)pSubtrahend, RTBIGNUM_ZERO_ALIGN(pMinuend->cUsed)); 1142 #endif 1143 if (RT_SUCCESS(rc)) 1144 { 1145 #ifdef IPRT_BIGINT_WITH_ASM 1146 /* 1147 * Call assembly to do the work. 1148 */ 1149 rtBigNumMagnitudeSubAssemblyWorker(pResult->pauElements, pMinuend->pauElements, 1150 pSubtrahend->pauElements, pMinuend->cUsed); 1151 # ifdef RT_STRICT 1152 RTBIGNUMELEMENT fBorrow = 0; 1153 for (uint32_t i = 0; i < pMinuend->cUsed; i++) 1154 { 1155 RTBIGNUMELEMENT uCorrect = rtBigNumElementSubWithBorrow(pMinuend->pauElements[i], rtBigNumGetElement(pSubtrahend, i), &fBorrow); 1156 AssertMsg(pResult->pauElements[i] == uCorrect, ("[%u]=%#x, expected %#x\n", i, pResult->pauElements[i], uCorrect)); 1157 } 1158 # endif 1159 #else 1160 /* 1161 * The primitive C way. 1162 */ 1163 RTBIGNUMELEMENT fBorrow = 0; 1164 for (uint32_t i = 0; i < pMinuend->cUsed; i++) 1165 pResult->pauElements[i] = rtBigNumElementSubWithBorrow(pMinuend->pauElements[i], 1166 rtBigNumGetElement(pSubtrahend, i), 1167 &fBorrow); 1168 Assert(fBorrow == 0); 1169 #endif 1170 1171 /* 1172 * Trim the result. 1173 */ 1174 rtBigNumStripTrailingZeros(pResult); 1175 } 1176 } 1177 /* 1178 * Special case: Subtrahend is zero. 1179 */ 1180 else 1181 rc = rtBigNumMagnitudeCopy(pResult, pMinuend); 973 1182 974 1183 return rc; … … 984 1193 * @a pSubtrahend. 985 1194 * 1195 * @returns IPRT status code (memory alloc error). 986 1196 * @param pMinuendResult What to subtract from and return as result. 987 1197 * @param pSubtrahend What to subtract. 988 1198 */ 989 static voidrtBigNumMagnitudeSubThis(PRTBIGNUM pMinuendResult, PCRTBIGNUM pSubtrahend)1199 static int rtBigNumMagnitudeSubThis(PRTBIGNUM pMinuendResult, PCRTBIGNUM pSubtrahend) 990 1200 { 991 1201 Assert(!pMinuendResult->fCurScrambled); Assert(!pSubtrahend->fCurScrambled); … … 993 1203 Assert(pMinuendResult->cUsed >= pSubtrahend->cUsed); 994 1204 1205 #ifdef IPRT_BIGINT_WITH_ASM 1206 /* 1207 * Use the assembly worker. Requires same sized element arrays, so zero extend them. 1208 */ 1209 int rc = rtBigNumEnsureExtraZeroElements(pMinuendResult, RTBIGNUM_ZERO_ALIGN(pMinuendResult->cUsed)); 1210 if (RT_SUCCESS(rc)) 1211 rc = rtBigNumEnsureExtraZeroElements((PRTBIGNUM)pSubtrahend, RTBIGNUM_ZERO_ALIGN(pMinuendResult->cUsed)); 1212 if (RT_FAILURE(rc)) 1213 return rc; 1214 rtBigNumMagnitudeSubThisAssemblyWorker(pMinuendResult->pauElements, pSubtrahend->pauElements, pMinuendResult->cUsed); 1215 #else 995 1216 /* 996 1217 * The primitive way, as usual. … … 1002 1223 &fBorrow); 1003 1224 Assert(fBorrow == 0); 1225 #endif 1004 1226 1005 1227 /* … … 1007 1229 */ 1008 1230 rtBigNumStripTrailingZeros(pMinuendResult); 1231 1232 return VINF_SUCCESS; 1009 1233 } 1010 1234 … … 1018 1242 if (RT_SUCCESS(rc)) 1019 1243 { 1244 RTBIGNUM_ASSERT_VALID(pResult); 1020 1245 rc = rtBigNumUnscramble((PRTBIGNUM)pAugend); 1021 1246 if (RT_SUCCESS(rc)) 1022 1247 { 1248 RTBIGNUM_ASSERT_VALID(pAugend); 1023 1249 rc = rtBigNumUnscramble((PRTBIGNUM)pAddend); 1024 1250 if (RT_SUCCESS(rc)) 1025 1251 { 1252 RTBIGNUM_ASSERT_VALID(pAddend); 1253 1026 1254 /* 1027 1255 * Same sign: Add magnitude, keep sign. … … 1071 1299 if (RT_SUCCESS(rc)) 1072 1300 { 1301 RTBIGNUM_ASSERT_VALID(pResult); 1073 1302 if (pMinuend != pSubtrahend) 1074 1303 { … … 1076 1305 if (RT_SUCCESS(rc)) 1077 1306 { 1307 RTBIGNUM_ASSERT_VALID(pMinuend); 1078 1308 rc = rtBigNumUnscramble((PRTBIGNUM)pSubtrahend); 1079 1309 if (RT_SUCCESS(rc)) 1080 1310 { 1311 RTBIGNUM_ASSERT_VALID(pSubtrahend); 1312 1081 1313 /* 1082 1314 * Different sign: Add magnitude, keep sign of first. … … 1117 1349 /* zero. */ 1118 1350 pResult->fNegative = 0; 1119 pResult->cUsed = 0;1351 rtBigNumSetUsed(pResult, 0); 1120 1352 } 1121 1353 rtBigNumScramble(pResult); … … 1161 1393 { 1162 1394 pResult->fNegative = 0; 1163 pResult->cUsed = 0;1395 rtBigNumSetUsed(pResult, 0); 1164 1396 return VINF_SUCCESS; 1165 1397 } … … 1220 1452 if (RT_SUCCESS(rc)) 1221 1453 { 1454 RTBIGNUM_ASSERT_VALID(pResult); 1222 1455 rc = rtBigNumUnscramble((PRTBIGNUM)pMultiplicand); 1223 1456 if (RT_SUCCESS(rc)) 1224 1457 { 1458 RTBIGNUM_ASSERT_VALID(pMultiplicand); 1225 1459 rc = rtBigNumUnscramble((PRTBIGNUM)pMultiplier); 1226 1460 if (RT_SUCCESS(rc)) 1227 1461 { 1462 RTBIGNUM_ASSERT_VALID(pMultiplier); 1463 1228 1464 /* 1229 1465 * The sign values follow XOR rules: … … 1247 1483 1248 1484 /** 1249 * Copies the magnitude of on number (@a pSrc) to another (@a pBigNum).1250 *1251 * The variables must be unscrambled. The sign flag is not considered nor1252 * touched.1253 *1254 * @returns IPRT status code.1255 * @param pDst The destination number.1256 * @param pSrc The source number.1257 */1258 DECLINLINE(int) rtBigNumMagnitudeCopy(PRTBIGNUM pDst, PCRTBIGNUM pSrc)1259 {1260 int rc = rtBigNumSetUsed(pDst, pSrc->cUsed);1261 if (RT_SUCCESS(rc))1262 memcpy(pDst->pauElements, pSrc->pauElements, pSrc->cUsed * RTBIGNUM_ELEMENT_SIZE);1263 return rc;1264 }1265 1266 1267 /**1268 1485 * Clears a bit in the magnitude of @a pBigNum. 1269 1486 * … … 1278 1495 if (iElement < pBigNum->cUsed) 1279 1496 { 1497 iBit &= RTBIGNUM_ELEMENT_BITS - 1; 1280 1498 pBigNum->pauElements[iElement] &= ~RTBIGNUM_ELEMENT_BIT(iBit); 1281 1499 if (iElement + 1 == pBigNum->cUsed && !pBigNum->pauElements[iElement]) … … 1300 1518 if (RT_SUCCESS(rc)) 1301 1519 { 1520 iBit &= RTBIGNUM_ELEMENT_BITS - 1; 1302 1521 pBigNum->pauElements[iElement] |= RTBIGNUM_ELEMENT_BIT(iBit); 1303 1522 return VINF_SUCCESS; … … 1339 1558 uint32_t iElement = iBit / RTBIGNUM_ELEMENT_BITS; 1340 1559 if (iElement < pBigNum->cUsed) 1560 { 1561 iBit &= RTBIGNUM_ELEMENT_BITS - 1; 1341 1562 return (pBigNum->pauElements[iElement] >> iBit) & 1; 1563 } 1342 1564 return 0; 1343 1565 } … … 1359 1581 /* Do the shifting. */ 1360 1582 uint32_t cUsed = pBigNum->cUsed; 1583 #ifdef IPRT_BIGINT_WITH_ASM 1584 uCarry = rtBigNumMagnitudeShiftLeftOneAssemblyWorker(pBigNum->pauElements, cUsed, uCarry); 1585 #else 1361 1586 for (uint32_t i = 0; i < cUsed; i++) 1362 1587 { … … 1365 1590 uCarry = uTmp >> (RTBIGNUM_ELEMENT_BITS - 1); 1366 1591 } 1592 #endif 1367 1593 1368 1594 /* If we still carry a bit, we need to increase the size. */ … … 1399 1625 * special case and the initial state of the general case. 1400 1626 */ 1401 pQuotient->cUsed = 0;1402 pRemainder->cUsed = 0;1627 rtBigNumSetUsed(pQuotient, 0); 1628 rtBigNumSetUsed(pRemainder, 0); 1403 1629 1404 1630 /* … … 1447 1673 { 1448 1674 if (iDiff != 0) 1449 rtBigNumMagnitudeSubThis(pRemainder, pDivisor); 1675 { 1676 rc = rtBigNumMagnitudeSubThis(pRemainder, pDivisor); 1677 AssertRCBreak(rc); 1678 } 1450 1679 else 1451 pRemainder->cUsed = 0;1680 rtBigNumSetUsed(pRemainder, 0); 1452 1681 rc = rtBigNumMagnitudeSetBit(pQuotient, iBit); 1453 1682 AssertRCBreak(rc); … … 1471 1700 if (RT_SUCCESS(rc)) 1472 1701 { 1702 RTBIGNUM_ASSERT_VALID(pQuotient); 1473 1703 rc = rtBigNumUnscramble(pRemainder); 1474 1704 if (RT_SUCCESS(rc)) 1475 1705 { 1706 RTBIGNUM_ASSERT_VALID(pRemainder); 1476 1707 rc = rtBigNumUnscramble((PRTBIGNUM)pDividend); 1477 1708 if (RT_SUCCESS(rc)) 1478 1709 { 1710 RTBIGNUM_ASSERT_VALID(pDividend); 1479 1711 rc = rtBigNumUnscramble((PRTBIGNUM)pDivisor); 1480 1712 if (RT_SUCCESS(rc)) 1481 1713 { 1714 RTBIGNUM_ASSERT_VALID(pDivisor); 1715 1482 1716 /* 1483 1717 * The sign value of the remainder is the same as the dividend. … … 1531 1765 * special case and the initial state of the general case. 1532 1766 */ 1533 pRemainder->cUsed = 0;1767 rtBigNumSetUsed(pRemainder, 0); 1534 1768 1535 1769 /* … … 1573 1807 { 1574 1808 if (iDiff != 0) 1575 rtBigNumMagnitudeSubThis(pRemainder, pDivisor); 1809 { 1810 rc = rtBigNumMagnitudeSubThis(pRemainder, pDivisor); 1811 AssertRCBreak(rc); 1812 } 1576 1813 else 1577 pRemainder->cUsed = 0; 1578 AssertRCBreak(rc); 1814 rtBigNumSetUsed(pRemainder, 0); 1579 1815 } 1580 1816 } … … 1588 1824 RTDECL(int) RTBigNumModulo(PRTBIGNUM pRemainder, PCRTBIGNUM pDividend, PCRTBIGNUM pDivisor) 1589 1825 { 1590 1826 Assert(pRemainder != pDividend); Assert(pRemainder != pDivisor); 1591 1827 AssertReturn(pRemainder->fSensitive >= (pDividend->fSensitive | pDivisor->fSensitive), VERR_BIGNUM_SENSITIVE_INPUT); 1592 1828 … … 1594 1830 if (RT_SUCCESS(rc)) 1595 1831 { 1832 RTBIGNUM_ASSERT_VALID(pRemainder); 1596 1833 rc = rtBigNumUnscramble((PRTBIGNUM)pDividend); 1597 1834 if (RT_SUCCESS(rc)) 1598 1835 { 1836 RTBIGNUM_ASSERT_VALID(pDividend); 1599 1837 rc = rtBigNumUnscramble((PRTBIGNUM)pDivisor); 1600 1838 if (RT_SUCCESS(rc)) 1601 1839 { 1840 RTBIGNUM_ASSERT_VALID(pDivisor); 1841 1602 1842 /* 1603 1843 * The sign value of the remainder is the same as the dividend. … … 1718 1958 if (RT_SUCCESS(rc)) 1719 1959 { 1960 RTBIGNUM_ASSERT_VALID(pResult); 1720 1961 rc = rtBigNumUnscramble((PRTBIGNUM)pBase); 1721 1962 if (RT_SUCCESS(rc)) 1722 1963 { 1964 RTBIGNUM_ASSERT_VALID(pBase); 1723 1965 rc = rtBigNumUnscramble((PRTBIGNUM)pExponent); 1724 1966 if (RT_SUCCESS(rc)) 1725 1967 { 1968 RTBIGNUM_ASSERT_VALID(pExponent); 1726 1969 if (!pExponent->fNegative) 1727 1970 { … … 1771 2014 if (pModulus->cUsed == 1 && pModulus->pauElements[0] == 1) 1772 2015 { 1773 pResult->cUsed = 0;2016 rtBigNumSetUsed(pResult, 0); 1774 2017 return VINF_SUCCESS; 1775 2018 } … … 1867 2110 if (RT_SUCCESS(rc)) 1868 2111 { 2112 RTBIGNUM_ASSERT_VALID(pResult); 1869 2113 rc = rtBigNumUnscramble((PRTBIGNUM)pBase); 1870 2114 if (RT_SUCCESS(rc)) 1871 2115 { 2116 RTBIGNUM_ASSERT_VALID(pBase); 1872 2117 rc = rtBigNumUnscramble((PRTBIGNUM)pExponent); 1873 2118 if (RT_SUCCESS(rc)) 1874 2119 { 2120 RTBIGNUM_ASSERT_VALID(pExponent); 1875 2121 rc = rtBigNumUnscramble((PRTBIGNUM)pModulus); 1876 2122 if (RT_SUCCESS(rc)) 1877 2123 { 2124 RTBIGNUM_ASSERT_VALID(pModulus); 1878 2125 if (!pExponent->fNegative) 1879 2126 {
Note:
See TracChangeset
for help on using the changeset viewer.