VirtualBox

Changeset 52335 in vbox for trunk/src/VBox/Runtime/testcase


Ignore:
Timestamp:
Aug 11, 2014 12:30:20 PM (10 years ago)
Author:
vboxsync
Message:

RTBigNum: Added shift APIs, implemented a faster division algorithm, optimized multiplication on x86 & amd64.

Location:
trunk/src/VBox/Runtime/testcase
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/testcase/tstRTBigNum.cpp

    r52297 r52335  
    2929*******************************************************************************/
    3030#include <iprt/bignum.h>
     31#include <iprt/uint128.h>
    3132
    3233#include <iprt/test.h>
     
    110111static RTBIGNUM g_Minus1;
    111112
     113
     114/** @name The components of a real PKCS #7 signature (extracted from a build of
     115 *   this testcase).
     116 * @{ */
     117static uint8_t const g_abPubKeyExp[] = { 0x01, 0x00, 0x01 };
     118static RTBIGNUM      g_PubKeyExp;
     119static uint8_t const g_abPubKeyMod[] =
     120{
     121    0x00, 0xea, 0x61, 0x4e, 0xa0, 0xb2, 0xae, 0x38, 0xbc, 0x43, 0x24, 0x5a, 0x28, 0xc7, 0xa0, 0x69,
     122    0x82, 0x11, 0xd5, 0x78, 0xe8, 0x6b, 0x41, 0x54, 0x7b, 0x6c, 0x69, 0x13, 0xc8, 0x68, 0x75, 0x0f,
     123    0xe4, 0x66, 0x54, 0xcd, 0xe3, 0x55, 0x33, 0x3b, 0x7f, 0x9f, 0x55, 0x75, 0x80, 0x6e, 0xd0, 0x8a,
     124    0xff, 0xc1, 0xf4, 0xbf, 0xfd, 0x70, 0x9b, 0x73, 0x7e, 0xee, 0xf1, 0x80, 0x23, 0xd4, 0xbd, 0xba,
     125    0xdc, 0xce, 0x09, 0x4a, 0xeb, 0xb0, 0xdd, 0x86, 0x4a, 0x0b, 0x8e, 0x3e, 0x9a, 0x8a, 0x58, 0xed,
     126    0x98, 0x4f, 0x25, 0xe5, 0x0c, 0x18, 0xd8, 0x10, 0x95, 0xce, 0xe4, 0x19, 0x82, 0x38, 0xcd, 0x76,
     127    0x6a, 0x38, 0xe5, 0x14, 0xe6, 0x95, 0x0d, 0x80, 0xc5, 0x09, 0x5e, 0x93, 0xf4, 0x6f, 0x82, 0x8e,
     128    0x9c, 0x81, 0x09, 0xd6, 0xd4, 0xee, 0xd5, 0x1f, 0x94, 0x2d, 0x13, 0x18, 0x9a, 0xbc, 0x88, 0x5d,
     129    0x9a, 0xe5, 0x66, 0x08, 0x99, 0x93, 0x1b, 0x8a, 0x69, 0x3f, 0x68, 0xb2, 0x97, 0x2a, 0x24, 0xf6,
     130    0x65, 0x2a, 0x94, 0x33, 0x94, 0x14, 0x5c, 0x6f, 0xff, 0x95, 0xd0, 0x2b, 0xf0, 0x2b, 0xcb, 0x49,
     131    0xcd, 0x03, 0x3a, 0x45, 0xd5, 0x22, 0x1c, 0xb3, 0xee, 0xd5, 0xaf, 0xb3, 0x5b, 0xcb, 0x1b, 0x35,
     132    0x4e, 0xff, 0x21, 0x0a, 0x55, 0x1f, 0xa0, 0xf9, 0xdc, 0xad, 0x7a, 0x89, 0x0b, 0x6e, 0x3f, 0x75,
     133    0xc0, 0x6c, 0x44, 0xff, 0x90, 0x63, 0x79, 0xcf, 0x70, 0x20, 0x60, 0x33, 0x3c, 0xb1, 0xfa, 0x6b,
     134    0x6c, 0x55, 0x3c, 0xeb, 0x8d, 0x18, 0xe9, 0x0a, 0x81, 0xd5, 0x24, 0xc1, 0x88, 0x7c, 0xa6, 0x8e,
     135    0xd3, 0x2c, 0x51, 0x1d, 0x6d, 0xdf, 0x51, 0xd5, 0x72, 0x54, 0x7a, 0x98, 0xc0, 0x36, 0x35, 0x21,
     136    0x66, 0x3c, 0x2f, 0x01, 0xc0, 0x8e, 0xb0, 0x56, 0x60, 0x6e, 0x67, 0x4f, 0x5f, 0xac, 0x05, 0x60,
     137    0x9b
     138};
     139static RTBIGNUM g_PubKeyMod;
     140static uint8_t const g_abSignature[] =
     141{
     142    0x00, 0xae, 0xca, 0x93, 0x47, 0x0b, 0xfa, 0xd8, 0xb9, 0xbb, 0x5a, 0x5e, 0xf6, 0x75, 0x90, 0xed,
     143    0x80, 0x37, 0x03, 0x6d, 0x23, 0x91, 0x30, 0x0c, 0x9d, 0xbf, 0x34, 0xc1, 0xf9, 0x43, 0xa7, 0xec,
     144    0xc0, 0x83, 0xc0, 0x98, 0x3f, 0x8a, 0x65, 0x48, 0x7c, 0xa4, 0x9f, 0x14, 0x4d, 0x52, 0x90, 0x2d,
     145    0x17, 0xd1, 0x3e, 0x05, 0xd6, 0x35, 0x1b, 0xdb, 0xe5, 0x1a, 0xa2, 0x54, 0x8c, 0x30, 0x6f, 0xfe,
     146    0xa1, 0xd9, 0x98, 0x3f, 0xb5, 0x65, 0x14, 0x9c, 0x50, 0x55, 0xa1, 0xbf, 0xb5, 0x12, 0xc4, 0xf2,
     147    0x72, 0x27, 0x14, 0x59, 0xb5, 0x23, 0x67, 0x11, 0x2a, 0xd8, 0xa8, 0x85, 0x4b, 0xc5, 0xb0, 0x2f,
     148    0x73, 0x54, 0xcf, 0x33, 0xa0, 0x06, 0xf2, 0x8e, 0x4f, 0x4b, 0x18, 0x97, 0x08, 0x47, 0xce, 0x0c,
     149    0x47, 0x97, 0x0d, 0xbd, 0x8b, 0xce, 0x61, 0x31, 0x21, 0x7e, 0xc4, 0x1d, 0x03, 0xf8, 0x06, 0xca,
     150    0x9f, 0xd3, 0x5e, 0x4b, 0xfc, 0xf1, 0x99, 0x34, 0x78, 0x83, 0xfa, 0xab, 0x9c, 0x7c, 0x6b, 0x5c,
     151    0x3d, 0x45, 0x39, 0x6d, 0x6a, 0x6c, 0xd5, 0x63, 0x3e, 0xbe, 0x09, 0x62, 0x64, 0x5f, 0x83, 0x3b,
     152    0xb6, 0x5c, 0x7e, 0x8e, 0xeb, 0x1e, 0x6a, 0x34, 0xb9, 0xc7, 0x92, 0x92, 0x58, 0x64, 0x48, 0xfe,
     153    0xf8, 0x35, 0x53, 0x07, 0x89, 0xb4, 0x29, 0x4d, 0x3d, 0x79, 0x43, 0x73, 0x0f, 0x16, 0x21, 0xab,
     154    0xb7, 0x07, 0x2b, 0x5a, 0x8a, 0x0f, 0xd7, 0x2e, 0x95, 0xb4, 0x26, 0x66, 0x65, 0x72, 0xac, 0x7e,
     155    0x46, 0x70, 0xe6, 0xad, 0x43, 0xa2, 0x73, 0x54, 0x6a, 0x41, 0xc8, 0x9c, 0x1e, 0x65, 0xed, 0x06,
     156    0xd1, 0xc7, 0x99, 0x3e, 0x5f, 0x5a, 0xd3, 0xd0, 0x1a, 0x9b, 0x0e, 0x3e, 0x04, 0x66, 0xb6, 0xaa,
     157    0xa6, 0x51, 0xb8, 0xc0, 0x13, 0x19, 0x34, 0x0e, 0x86, 0x02, 0xd5, 0xc8, 0x10, 0xaa, 0x1f, 0x97,
     158    0x95
     159};
     160static RTBIGNUM g_Signature;
     161static uint8_t const g_abSignatureDecrypted[] =
     162{
     163    0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     164    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     165    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     166    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     167    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     168    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     169    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     170    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     171    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     172    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     173    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     174    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     175    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     176    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
     177    0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x54, 0x60, 0xb0, 0x65,
     178    0xf1, 0xbc, 0x40, 0x77, 0xfc, 0x9e, 0xfc, 0x2f, 0x94, 0x62, 0x62, 0x61, 0x43, 0xb9, 0x01, 0xb9
     179};
     180static RTBIGNUM g_SignatureDecrypted;
     181/** @} */
    112182
    113183
     
    363433}
    364434
     435static void testShift(void)
     436{
     437    RTTestSub(g_hTest, "RTBigNumShiftLeft, RTBigNumShiftRight");
     438
     439    for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
     440    {
     441        RTBIGNUM Result;
     442        RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
     443        RTBIGNUM Result2;
     444        RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
     445
     446        /* basic left tests */
     447        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 1), VINF_SUCCESS);
     448        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -2) == 0);
     449
     450        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 0), VINF_SUCCESS);
     451        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
     452
     453        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 2), VINF_SUCCESS);
     454        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -4) == 0);
     455
     456        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 8), VINF_SUCCESS);
     457        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -256) == 0);
     458
     459        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Zero, 511), VINF_SUCCESS);
     460        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
     461
     462        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_FourtyTwo, 1), VINF_SUCCESS);
     463        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 84) == 0);
     464
     465        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_FourtyTwo, 27+24), VINF_SUCCESS);
     466        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, UINT64_C(0x150000000000000)) == 0);
     467
     468        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_FourtyTwo, 27), VINF_SUCCESS);
     469        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result2, &Result, 24), VINF_SUCCESS);
     470        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result2, UINT64_C(0x150000000000000)) == 0);
     471
     472        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_LargePositive, 2), VINF_SUCCESS);
     473        RTTESTI_CHECK_RC(RTBigNumMultiply(&Result2, &g_LargePositive, &g_Four), VINF_SUCCESS);
     474        RTTESTI_CHECK(RTBigNumCompare(&Result2, &Result) == 0);
     475
     476        /* basic right tests. */
     477        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_Minus1, 1), VINF_SUCCESS);
     478        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
     479
     480        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_Minus1, 8), VINF_SUCCESS);
     481        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
     482
     483        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_Zero, 511), VINF_SUCCESS);
     484        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
     485
     486        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 0), VINF_SUCCESS);
     487        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 42) == 0);
     488
     489        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 1), VINF_SUCCESS);
     490        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 21) == 0);
     491
     492        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 2), VINF_SUCCESS);
     493        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 10) == 0);
     494
     495        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 3), VINF_SUCCESS);
     496        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 5) == 0);
     497
     498        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 4), VINF_SUCCESS);
     499        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
     500
     501        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 5), VINF_SUCCESS);
     502        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
     503
     504        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 6), VINF_SUCCESS);
     505        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
     506
     507        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 549), VINF_SUCCESS);
     508        RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
     509
     510        RTTESTI_CHECK_RC(RTBigNumDivideLong(&Result2, &Result, &g_LargePositive, &g_Four), VINF_SUCCESS);
     511        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_LargePositive, 2), VINF_SUCCESS);
     512        RTTESTI_CHECK(RTBigNumCompare(&Result2, &Result) == 0);
     513
     514        /* Some simple back and forth. */
     515        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_One, 2), VINF_SUCCESS);
     516        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 2), VINF_SUCCESS);
     517        RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_One) == 0);
     518
     519        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Three, 63), VINF_SUCCESS);
     520        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 63), VINF_SUCCESS);
     521        RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_Three) == 0);
     522
     523        for (uint32_t i = 0; i < 1024; i++)
     524        {
     525            RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_LargePositive, i), VINF_SUCCESS);
     526            RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, i), VINF_SUCCESS);
     527            RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositive) == 0);
     528        }
     529
     530        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_LargePositive, 2), VINF_SUCCESS);
     531        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result2, &Result, 250), VINF_SUCCESS);
     532        RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &Result2, 999), VINF_SUCCESS);
     533        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 1), VINF_SUCCESS);
     534        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &Result2, 250), VINF_SUCCESS);
     535        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 1), VINF_SUCCESS);
     536        RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &Result2, 999), VINF_SUCCESS);
     537        RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositive) == 0);
     538
     539
     540        RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
     541        RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
     542    }
     543}
     544
    365545static bool testHexStringToNum(PRTBIGNUM pBigNum, const char *pszHex, uint32_t fFlags)
    366546{
     
    436616
    437617
     618#if 0 /* Java program for generating testDivision test data. */
     619import java.math.BigInteger;
     620import java.lang.System;
     621import java.lang.Integer;
     622import java.util.Random;
     623import java.security.SecureRandom;
     624
     625class bigintdivtestgen
     626{
     627
     628public static String format(BigInteger BigNum)
     629{
     630    String str = BigNum.toString(16);
     631    if ((str.length() & 1) != 0)
     632        str = "0" + str;
     633    return str;
     634}
     635
     636public static void main(String args[])
     637{
     638    Random Rnd = new SecureRandom();
     639
     640    /* Can't go to far here because before we reach 11K both windows compilers
     641       will have reached some kind of section limit. Probably string pool related. */
     642    int cDivisorLarger = 0;
     643    for (int i = 0; i < 9216; i++)
     644    {
     645        int cDividendBits = Rnd.nextInt(4095) + 1;
     646        int cDivisorBits  = i < 9 ? cDividendBits : Rnd.nextInt(4095) + 1;
     647        if (cDivisorBits > cDividendBits)
     648        {
     649            cDivisorLarger++;
     650            if (cDivisorLarger > i / 4)
     651                cDivisorBits = Rnd.nextInt(cDividendBits);
     652        }
     653
     654        BigInteger Dividend = new BigInteger(cDividendBits, Rnd);
     655        BigInteger Divisor  = new BigInteger(cDivisorBits, Rnd);
     656        while (Divisor.compareTo(BigInteger.ZERO) == 0) {
     657            cDivisorBits++;
     658            Divisor = new BigInteger(cDivisorBits, Rnd);
     659        }
     660
     661        BigInteger[] Result = Dividend.divideAndRemainder(Divisor);
     662
     663        System.out.println("    { /* i=" + Integer.toString(i)
     664                           + " cDividendBits=" + Integer.toString(cDividendBits)
     665                           + " cDivisorBits=" + Integer.toString(cDivisorBits) + " */");
     666
     667        System.out.println("        \"" + format(Dividend)  + "\",");
     668        System.out.println("        \"" + format(Divisor)   + "\",");
     669        System.out.println("        \"" + format(Result[0]) + "\",");
     670        System.out.println("        \"" + format(Result[1]) + "\"");
     671        System.out.println("    },");
     672    }
     673}
     674}
     675#endif
     676
    438677static void testDivision(void)
    439678{
    440679    RTTestSub(g_hTest, "RTBigNumDivide");
    441680
    442     for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
     681    //for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
     682    uint32_t fFlags = 0;
    443683    {
    444684        RTBIGNUM Quotient;
     
    480720        RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, -1) == 0);
    481721
    482 
    483 #if 0
    484722        static struct
    485723        {
    486             const char *pszF1, *pszF2, *pszQuotient, *pszRemainder;
    487         } s_aTests[] =
    488         {
    489             {
    490                 "29865DBFA717181B9DD4B515BD072DE10A5A314385F6DED735AC553FCD307D30C499",
    491                 "4DD65692F7365B90C55F63988E5B6C448653E7DB9DD941507586BD8CF71398287C",
    492                 "0CA02E8FFDB0EEA37264338A4AAA91C8974E162DDFCBCF804B434A11955671B89B3645AAB75423D60CA3459B0B4F3F28978DA768779FB54CF362FD61924637582F221C"
     724            const char *pszDividend, *pszDivisor, *pszQuotient, *pszRemainder;
     725        } const s_aTests[] =
     726        {
     727#if 1
     728#include "tstRTBigNum-div-test-data.h"
     729            {   "ff", "10", /* = */ "0f", "0f" },
     730            { /* cDividendBits=323 cDivisorBits=195 */
     731                "064530fd21b30e179b5bd5efd1f4a7e8df173c13965bd75e1502891303060b417e62711ceb17a73e56",
     732                "0784fac4a7c6b5165a99dc3228b6484cba9c7dfadde85cdde3",
     733                "d578cc87ed22ac3630a4d1e5fc590ae6",
     734                "06acef436982f9c4fc9b0a44d3df1e72cad3ef0cb51ba20664"
    493735            },
    494736            {
    495                 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
    496                 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
    497                 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000000000000000000001"
    498             }
     737                "ffffffffffffffffffffffffffffffffffffffffffffffff",
     738                "fffffffffffffffffffffffffffffffffffffffffffffffe",
     739                "01",
     740                "01"
     741            },
     742            {
     743                "922222222222222222222222222222222222222222222222",
     744                "811111111111111111111111111111111111111111111111",
     745                "01",
     746                "111111111111111111111111111111111111111111111111"
     747            },
     748            {
     749                "955555555555555555555555555555555555555555555555",
     750                "211111111111111111111111111111111111111111111111",
     751                "04",
     752                "111111111111111111111111111111111111111111111111"
     753            },
     754#endif
     755            /* This test triggers negative special cases in Knuth's division algorithm. */
     756            {
     757                "0137698320ec00bcaa13cd9c18df564bf6df45c5c4c73ad2012cb36cf897c5ff00db638256e19c9ba5a8fbe828ac6e8d470a5f3391d4350ca1390f79c4e4f944eb",
     758                "67cdd6604eaae98e0699deb2f51cc3fcf51741ec4268f0ab0ee679a83297550049212b724b3433e1e2fea2b8397a2f17ae1fbbdb46bc598b13052896f6fdc1a4",
     759                "02",
     760                "67cdd6604eaae98e0699deb2f51cc3fcf51741ec4268f0ab0ee679a83297550049212b724b3433e1e2fea2b8397a2f17ae1fbbdb46bc598b13052896f6fdc1a3"
     761            },
    499762        };
    500763        for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
    501764        {
    502             RTBIGNUM F1, F2, Expected;
    503             if (   testHexStringToNum(&F1, s_aTests[i].pszF1, RTBIGNUMINIT_F_UNSIGNED | fFlags)
    504                 && testHexStringToNum(&F2, s_aTests[i].pszF2, RTBIGNUMINIT_F_UNSIGNED | fFlags)
    505                 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
     765            RTBIGNUM Dividend, Divisor, ExpectedQ, ExpectedR;
     766            if (   testHexStringToNum(&Dividend,  s_aTests[i].pszDividend, RTBIGNUMINIT_F_UNSIGNED | fFlags)
     767                && testHexStringToNum(&Divisor,   s_aTests[i].pszDivisor, RTBIGNUMINIT_F_UNSIGNED | fFlags)
     768                && testHexStringToNum(&ExpectedQ, s_aTests[i].pszQuotient, RTBIGNUMINIT_F_UNSIGNED | fFlags)
     769                && testHexStringToNum(&ExpectedR, s_aTests[i].pszRemainder, RTBIGNUMINIT_F_UNSIGNED | fFlags))
    506770            {
    507                 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &F1, &F2), VINF_SUCCESS);
    508                 RTTESTI_CHECK(RTBigNumCompare(&Quotient, &Expected) == 0);
    509                 RTTESTI_CHECK_RC(RTBigNumDestroy(&F1), VINF_SUCCESS);
    510                 RTTESTI_CHECK_RC(RTBigNumDestroy(&F2), VINF_SUCCESS);
    511                 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
     771                RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &Dividend, &Divisor), VINF_SUCCESS);
     772
     773                if (   RTBigNumCompare(&Quotient,  &ExpectedQ) != 0
     774                    || RTBigNumCompare(&Remainder, &ExpectedR) != 0)
     775                {
     776                    RTTestIFailed("i=%#x both\n"
     777                                  "ExpQ: %.*Rhxs\n"
     778                                  "GotQ: %.*Rhxs\n"
     779                                  "ExpR: %.*Rhxs\n"
     780                                  "GotR: %.*Rhxs\n",
     781                                  i,
     782                                  ExpectedQ.cUsed * RTBIGNUM_ELEMENT_SIZE, ExpectedQ.pauElements,
     783                                  Quotient.cUsed  * RTBIGNUM_ELEMENT_SIZE, Quotient.pauElements,
     784                                  ExpectedR.cUsed * RTBIGNUM_ELEMENT_SIZE, ExpectedR.pauElements,
     785                                  Remainder.cUsed * RTBIGNUM_ELEMENT_SIZE, Remainder.pauElements);
     786                    RTTestIPrintf(RTTESTLVL_ALWAYS,  "{ \"%s\", \"%s\", \"%s\", \"%s\" },\n",
     787                                  s_aTests[i].pszDividend, s_aTests[i].pszDivisor,
     788                                  s_aTests[i].pszQuotient, s_aTests[i].pszRemainder);
     789                }
     790
     791                RTTESTI_CHECK_RC(RTBigNumDivideLong(&Quotient, &Remainder, &Dividend, &Divisor), VINF_SUCCESS);
     792                RTTESTI_CHECK(RTBigNumCompare(&Quotient,  &ExpectedQ) == 0);
     793                RTTESTI_CHECK(RTBigNumCompare(&Remainder, &ExpectedR) == 0);
     794
     795                RTTESTI_CHECK_RC(RTBigNumModulo(&Remainder, &Dividend, &Divisor), VINF_SUCCESS);
     796                RTTESTI_CHECK(RTBigNumCompare(&Remainder, &ExpectedR) == 0);
     797
     798
     799                RTTESTI_CHECK_RC(RTBigNumDestroy(&ExpectedR), VINF_SUCCESS);
     800                RTTESTI_CHECK_RC(RTBigNumDestroy(&ExpectedQ), VINF_SUCCESS);
     801                RTTESTI_CHECK_RC(RTBigNumDestroy(&Divisor), VINF_SUCCESS);
     802                RTTESTI_CHECK_RC(RTBigNumDestroy(&Dividend), VINF_SUCCESS);
    512803            }
    513804        }
    514 #endif
     805
    515806        RTTESTI_CHECK_RC(RTBigNumDestroy(&Quotient), VINF_SUCCESS);
    516807        RTTESTI_CHECK_RC(RTBigNumDestroy(&Remainder), VINF_SUCCESS);
     
    665956{
    666957    RTTestSub(g_hTest, "RTBigNumModExp");
     958    RTBIGNUM Result;
    667959
    668960    for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
    669961    {
    670         RTBIGNUM Result;
    671962        RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
    672963
     
    7391030        RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
    7401031    }
     1032
     1033    /* Decrypt a PKCS#7 signature. */
     1034    RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, 0), VINF_SUCCESS);
     1035    RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
     1036    RTTESTI_CHECK(RTBigNumCompare(&Result, &g_SignatureDecrypted) == 0);
    7411037}
    7421038
     
    7901086    RTTESTI_CHECK(memcmp(abBuf, &g_abLargePositive[1], sizeof(g_abLargePositive) - 1) == 0);
    7911087    RTTESTI_CHECK(abBuf[sizeof(g_abLargePositive) - 1] == 0xcc);
    792 
    793 }
    794 
    795 
    796 static void testBenchmarks(void)
     1088}
     1089
     1090
     1091static void testBenchmarks(bool fOnlyModExp)
    7971092{
    7981093    RTTestSub(g_hTest, "Benchmarks");
    7991094
    800     /* For the modexp benchmark we decrypt a real PKCS #7 signature. */
    801     static uint8_t const s_abPubKeyExp[] = { 0x01, 0x00, 0x01 };
    802     RTBIGNUM PubKeyExp;
    803     RTTESTI_CHECK_RC_RETV(RTBigNumInit(&PubKeyExp, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
    804                                        s_abPubKeyExp, sizeof(s_abPubKeyExp)), VINF_SUCCESS);
    805 
    806     static uint8_t const s_abPubKeyMod[] =
    807     {
    808         0x00, 0xea, 0x61, 0x4e, 0xa0, 0xb2, 0xae, 0x38, 0xbc, 0x43, 0x24, 0x5a, 0x28, 0xc7, 0xa0, 0x69,
    809         0x82, 0x11, 0xd5, 0x78, 0xe8, 0x6b, 0x41, 0x54, 0x7b, 0x6c, 0x69, 0x13, 0xc8, 0x68, 0x75, 0x0f,
    810         0xe4, 0x66, 0x54, 0xcd, 0xe3, 0x55, 0x33, 0x3b, 0x7f, 0x9f, 0x55, 0x75, 0x80, 0x6e, 0xd0, 0x8a,
    811         0xff, 0xc1, 0xf4, 0xbf, 0xfd, 0x70, 0x9b, 0x73, 0x7e, 0xee, 0xf1, 0x80, 0x23, 0xd4, 0xbd, 0xba,
    812         0xdc, 0xce, 0x09, 0x4a, 0xeb, 0xb0, 0xdd, 0x86, 0x4a, 0x0b, 0x8e, 0x3e, 0x9a, 0x8a, 0x58, 0xed,
    813         0x98, 0x4f, 0x25, 0xe5, 0x0c, 0x18, 0xd8, 0x10, 0x95, 0xce, 0xe4, 0x19, 0x82, 0x38, 0xcd, 0x76,
    814         0x6a, 0x38, 0xe5, 0x14, 0xe6, 0x95, 0x0d, 0x80, 0xc5, 0x09, 0x5e, 0x93, 0xf4, 0x6f, 0x82, 0x8e,
    815         0x9c, 0x81, 0x09, 0xd6, 0xd4, 0xee, 0xd5, 0x1f, 0x94, 0x2d, 0x13, 0x18, 0x9a, 0xbc, 0x88, 0x5d,
    816         0x9a, 0xe5, 0x66, 0x08, 0x99, 0x93, 0x1b, 0x8a, 0x69, 0x3f, 0x68, 0xb2, 0x97, 0x2a, 0x24, 0xf6,
    817         0x65, 0x2a, 0x94, 0x33, 0x94, 0x14, 0x5c, 0x6f, 0xff, 0x95, 0xd0, 0x2b, 0xf0, 0x2b, 0xcb, 0x49,
    818         0xcd, 0x03, 0x3a, 0x45, 0xd5, 0x22, 0x1c, 0xb3, 0xee, 0xd5, 0xaf, 0xb3, 0x5b, 0xcb, 0x1b, 0x35,
    819         0x4e, 0xff, 0x21, 0x0a, 0x55, 0x1f, 0xa0, 0xf9, 0xdc, 0xad, 0x7a, 0x89, 0x0b, 0x6e, 0x3f, 0x75,
    820         0xc0, 0x6c, 0x44, 0xff, 0x90, 0x63, 0x79, 0xcf, 0x70, 0x20, 0x60, 0x33, 0x3c, 0xb1, 0xfa, 0x6b,
    821         0x6c, 0x55, 0x3c, 0xeb, 0x8d, 0x18, 0xe9, 0x0a, 0x81, 0xd5, 0x24, 0xc1, 0x88, 0x7c, 0xa6, 0x8e,
    822         0xd3, 0x2c, 0x51, 0x1d, 0x6d, 0xdf, 0x51, 0xd5, 0x72, 0x54, 0x7a, 0x98, 0xc0, 0x36, 0x35, 0x21,
    823         0x66, 0x3c, 0x2f, 0x01, 0xc0, 0x8e, 0xb0, 0x56, 0x60, 0x6e, 0x67, 0x4f, 0x5f, 0xac, 0x05, 0x60,
    824         0x9b
    825     };
    826     RTBIGNUM PubKeyMod;
    827     RTTESTI_CHECK_RC_RETV(RTBigNumInit(&PubKeyMod, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
    828                                        s_abPubKeyMod, sizeof(s_abPubKeyMod)), VINF_SUCCESS);
    829 
    830     static uint8_t const  s_abSignature[] =
    831     {
    832         0x00, 0xae, 0xca, 0x93, 0x47, 0x0b, 0xfa, 0xd8, 0xb9, 0xbb, 0x5a, 0x5e, 0xf6, 0x75, 0x90, 0xed,
    833         0x80, 0x37, 0x03, 0x6d, 0x23, 0x91, 0x30, 0x0c, 0x9d, 0xbf, 0x34, 0xc1, 0xf9, 0x43, 0xa7, 0xec,
    834         0xc0, 0x83, 0xc0, 0x98, 0x3f, 0x8a, 0x65, 0x48, 0x7c, 0xa4, 0x9f, 0x14, 0x4d, 0x52, 0x90, 0x2d,
    835         0x17, 0xd1, 0x3e, 0x05, 0xd6, 0x35, 0x1b, 0xdb, 0xe5, 0x1a, 0xa2, 0x54, 0x8c, 0x30, 0x6f, 0xfe,
    836         0xa1, 0xd9, 0x98, 0x3f, 0xb5, 0x65, 0x14, 0x9c, 0x50, 0x55, 0xa1, 0xbf, 0xb5, 0x12, 0xc4, 0xf2,
    837         0x72, 0x27, 0x14, 0x59, 0xb5, 0x23, 0x67, 0x11, 0x2a, 0xd8, 0xa8, 0x85, 0x4b, 0xc5, 0xb0, 0x2f,
    838         0x73, 0x54, 0xcf, 0x33, 0xa0, 0x06, 0xf2, 0x8e, 0x4f, 0x4b, 0x18, 0x97, 0x08, 0x47, 0xce, 0x0c,
    839         0x47, 0x97, 0x0d, 0xbd, 0x8b, 0xce, 0x61, 0x31, 0x21, 0x7e, 0xc4, 0x1d, 0x03, 0xf8, 0x06, 0xca,
    840         0x9f, 0xd3, 0x5e, 0x4b, 0xfc, 0xf1, 0x99, 0x34, 0x78, 0x83, 0xfa, 0xab, 0x9c, 0x7c, 0x6b, 0x5c,
    841         0x3d, 0x45, 0x39, 0x6d, 0x6a, 0x6c, 0xd5, 0x63, 0x3e, 0xbe, 0x09, 0x62, 0x64, 0x5f, 0x83, 0x3b,
    842         0xb6, 0x5c, 0x7e, 0x8e, 0xeb, 0x1e, 0x6a, 0x34, 0xb9, 0xc7, 0x92, 0x92, 0x58, 0x64, 0x48, 0xfe,
    843         0xf8, 0x35, 0x53, 0x07, 0x89, 0xb4, 0x29, 0x4d, 0x3d, 0x79, 0x43, 0x73, 0x0f, 0x16, 0x21, 0xab,
    844         0xb7, 0x07, 0x2b, 0x5a, 0x8a, 0x0f, 0xd7, 0x2e, 0x95, 0xb4, 0x26, 0x66, 0x65, 0x72, 0xac, 0x7e,
    845         0x46, 0x70, 0xe6, 0xad, 0x43, 0xa2, 0x73, 0x54, 0x6a, 0x41, 0xc8, 0x9c, 0x1e, 0x65, 0xed, 0x06,
    846         0xd1, 0xc7, 0x99, 0x3e, 0x5f, 0x5a, 0xd3, 0xd0, 0x1a, 0x9b, 0x0e, 0x3e, 0x04, 0x66, 0xb6, 0xaa,
    847         0xa6, 0x51, 0xb8, 0xc0, 0x13, 0x19, 0x34, 0x0e, 0x86, 0x02, 0xd5, 0xc8, 0x10, 0xaa, 0x1f, 0x97,
    848         0x95
    849     };
    850     RTBIGNUM Signature;
    851     RTTESTI_CHECK_RC_RETV(RTBigNumInit(&Signature, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
    852                                        s_abSignature, sizeof(s_abSignature)), VINF_SUCCESS);
    853 
     1095    /*
     1096     * For the modexp benchmark we decrypt a real PKCS #7 signature.
     1097     */
    8541098    RTBIGNUM Decrypted;
    8551099    RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Decrypted, 0 /*fFlags*/), VINF_SUCCESS);
    856     RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &Signature, &PubKeyExp, &PubKeyMod), VINF_SUCCESS);
    857     RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &Signature, &PubKeyExp, &PubKeyMod), VINF_SUCCESS);
     1100    RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
     1101    RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
    8581102
    8591103    RTThreadYield();
     
    8611105    uint32_t cRounds  = 0;
    8621106    uint64_t uStartTS = RTTimeNanoTS();
    863     while (cRounds < 256)
    864     {
    865         rc |= RTBigNumModExp(&Decrypted, &Signature, &PubKeyExp, &PubKeyMod);
     1107    while (cRounds < 10240)
     1108    {
     1109        rc |= RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod);
    8661110        cRounds++;
    8671111    }
     
    8701114    RTTestIValue("RTBigNumModExp", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
    8711115
     1116    if (fOnlyModExp)
     1117        return;
     1118
    8721119#if 1
    8731120    /* Compare with OpenSSL BN. */
    8741121    BN_CTX *pObnCtx = BN_CTX_new();
    875     BIGNUM *pObnPubKeyExp = BN_bin2bn(s_abPubKeyExp, sizeof(s_abPubKeyExp), NULL);
    876     BIGNUM *pObnPubKeyMod = BN_bin2bn(s_abPubKeyMod, sizeof(s_abPubKeyMod), NULL);
    877     BIGNUM *pObnSignature = BN_bin2bn(s_abSignature, sizeof(s_abSignature), NULL);
     1122    BIGNUM *pObnPubKeyExp = BN_bin2bn(g_abPubKeyExp, sizeof(g_abPubKeyExp), NULL);
     1123    BIGNUM *pObnPubKeyMod = BN_bin2bn(g_abPubKeyMod, sizeof(g_abPubKeyMod), NULL);
     1124    BIGNUM *pObnSignature = BN_bin2bn(g_abSignature, sizeof(g_abSignature), NULL);
     1125    BIGNUM *pObnSignatureDecrypted = BN_bin2bn(g_abSignatureDecrypted, sizeof(g_abSignatureDecrypted), NULL);
    8781126    BIGNUM *pObnResult = BN_new();
    8791127    RTTESTI_CHECK_RETV(BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx) == 1);
    880     BN_CTX_free(pObnCtx);
     1128    RTTESTI_CHECK_RETV(BN_ucmp(pObnResult, pObnSignatureDecrypted) == 0);
    8811129
    8821130    rc = 1;
     
    8851133    while (cRounds < 4096)
    8861134    {
    887         pObnCtx = BN_CTX_new();
    8881135        rc &= BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
    889         BN_CTX_free(pObnCtx);
    8901136        cRounds++;
    8911137    }
     
    8991145    while (cRounds < 4096)
    9001146    {
    901         pObnCtx = BN_CTX_new();
    9021147        rc &= BN_mod_exp_simple(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
    903         BN_CTX_free(pObnCtx);
    9041148        cRounds++;
    9051149    }
     
    9081152    RTTestIValue("BN_mod_exp_simple", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
    9091153#endif
     1154
     1155    /*
     1156     * Check out the speed of modulo.
     1157     */
     1158    RTBIGNUM Product;
     1159    RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Product, 0), VINF_SUCCESS);
     1160    RTTESTI_CHECK_RC_RETV(RTBigNumMultiply(&Product, &g_Signature, &g_Signature), VINF_SUCCESS);
     1161    RTTESTI_CHECK_RC_RETV(RTBigNumModulo(&Decrypted, &Product, &g_PubKeyMod), VINF_SUCCESS);
     1162    RTThreadYield();
     1163    rc       = VINF_SUCCESS;
     1164    cRounds  = 0;
     1165    uStartTS = RTTimeNanoTS();
     1166    while (cRounds < 10240)
     1167    {
     1168        rc |= RTBigNumModulo(&Decrypted, &Product, &g_PubKeyMod);
     1169        cRounds++;
     1170    }
     1171    uElapsed = RTTimeNanoTS() - uStartTS;
     1172    RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
     1173    RTTestIValue("RTBigNumModulo", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
     1174
     1175#if 1
     1176    /* Compare with OpenSSL BN. */
     1177    BIGNUM *pObnProduct = BN_new();
     1178    RTTESTI_CHECK_RETV(BN_mul(pObnProduct, pObnSignature, pObnSignature, pObnCtx) == 1);
     1179    RTTESTI_CHECK_RETV(BN_mod(pObnResult, pObnProduct, pObnPubKeyMod, pObnCtx) == 1);
     1180    rc = 1;
     1181    cRounds  = 0;
     1182    uStartTS = RTTimeNanoTS();
     1183    while (cRounds < 10240)
     1184    {
     1185        rc &= BN_mod(pObnResult, pObnProduct, pObnPubKeyMod, pObnCtx);
     1186        cRounds++;
     1187    }
     1188    uElapsed = RTTimeNanoTS() - uStartTS;
     1189    RTTESTI_CHECK_RC(rc, 1);
     1190    RTTestIValue("BN_mod", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
     1191#endif
     1192
     1193    /*
     1194     * Check out the speed of multiplication.
     1195     */
     1196    RTThreadYield();
     1197    rc       = VINF_SUCCESS;
     1198    cRounds  = 0;
     1199    uStartTS = RTTimeNanoTS();
     1200    while (cRounds < 10240)
     1201    {
     1202        rc |= RTBigNumMultiply(&Product, &g_Signature, &g_Signature);
     1203        cRounds++;
     1204    }
     1205    uElapsed = RTTimeNanoTS() - uStartTS;
     1206    RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
     1207    RTTestIValue("RTBigNumMultiply", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
     1208
     1209#if 1
     1210    /* Compare with OpenSSL BN. */
     1211    rc = 1;
     1212    cRounds  = 0;
     1213    uStartTS = RTTimeNanoTS();
     1214    while (cRounds < 10240)
     1215    {
     1216        rc &= BN_mul(pObnProduct, pObnSignature, pObnSignature, pObnCtx);
     1217        cRounds++;
     1218    }
     1219    uElapsed = RTTimeNanoTS() - uStartTS;
     1220    RTTESTI_CHECK_RC(rc, 1);
     1221    RTTestIValue("BN_mul", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
     1222#endif
     1223
     1224}
     1225
     1226/*
     1227 * UInt128 tests (RTBigInt uses UInt128 in some cases.
     1228 */
     1229
     1230static void testUInt128Subtraction(void)
     1231{
     1232    RTTestSub(g_hTest, "RTUInt128Sub");
     1233
     1234    static struct
     1235    {
     1236        RTUINT128U uMinuend, uSubtrahend, uResult;
     1237    } const s_aTests[] =
     1238    {
     1239        { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
     1240        { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(~0, ~0) },
     1241        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) },
     1242        { RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
     1243        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(~0, ~0) },
     1244        { RTUINT128_INIT_C(2, 9), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 9) },
     1245        { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(1, ~0) },
     1246        {
     1247            RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
     1248            RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
     1249            RTUINT128_INIT_C(0xfffffffffffffffe, 0x0000000000000001),
     1250        },
     1251        {
     1252            RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
     1253            RTUINT128_INIT_C(0x0000000000000000, 0x00000000000fffff),
     1254            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffe00001),
     1255        },
     1256        {
     1257            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
     1258            RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
     1259            RTUINT128_INIT_C(0xfffff00000000000, 0x0000000000000000)
     1260        },
     1261        {
     1262            RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85),
     1263            RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
     1264            RTUINT128_INIT_C(0x0000000000000000, 0x000000221af4e338),
     1265        },
     1266        {
     1267            RTUINT128_INIT_C(0xfd4d22a441ffa48c, 0x170739b573a9498d),
     1268            RTUINT128_INIT_C(0x43459cea40782b26, 0xc8c16bb29cb3b343),
     1269            RTUINT128_INIT_C(0xba0785ba01877965, 0x4e45ce02d6f5964a),
     1270        },
     1271    };
     1272    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
     1273    {
     1274        RTUINT128U uResult;
     1275        PRTUINT128U pResult = RTUInt128Sub(&uResult, &s_aTests[i].uMinuend, &s_aTests[i].uSubtrahend);
     1276        if (pResult != &uResult)
     1277            RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
     1278        else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
     1279            RTTestIFailed("test #%i failed: remainder differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
     1280                          i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
     1281
     1282        uResult = s_aTests[i].uMinuend;
     1283        pResult = RTUInt128AssignSub(&uResult, &s_aTests[i].uSubtrahend);
     1284        RTTESTI_CHECK(pResult == &uResult);
     1285        RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1286    }
     1287}
     1288
     1289
     1290static void testUInt128Addition(void)
     1291{
     1292    RTTestSub(g_hTest, "RTUInt128Add");
     1293
     1294    static struct
     1295    {
     1296        RTUINT128U uAugend, uAddend, uResult;
     1297    } const s_aTests[] =
     1298    {
     1299        { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
     1300        { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
     1301        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2) },
     1302        { RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 3) },
     1303        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 3) },
     1304        { RTUINT128_INIT_C(2, 9), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(4, 9) },
     1305        { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(2, 3) },
     1306        {
     1307            RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
     1308            RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
     1309            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
     1310        },
     1311        {
     1312            RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
     1313            RTUINT128_INIT_C(0x0000000000000000, 0x00000000000ffeff),
     1314            RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffffffeff),
     1315        },
     1316        {
     1317            RTUINT128_INIT_C(0xefffffffffffffff, 0xfffffffffff00000),
     1318            RTUINT128_INIT_C(0x0000000000000000, 0x00000000001fffff),
     1319            RTUINT128_INIT_C(0xf000000000000000, 0x00000000000fffff),
     1320        },
     1321        {
     1322            RTUINT128_INIT_C(0xeeeeeeeeeeeeeeee, 0xeeeeeeeeeee00000),
     1323            RTUINT128_INIT_C(0x0111111111111111, 0x11111111112fffff),
     1324            RTUINT128_INIT_C(0xf000000000000000, 0x00000000000fffff),
     1325        },
     1326        {
     1327            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
     1328            RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
     1329            RTUINT128_INIT_C(0x00000fffffffffff, 0xfffffffffffffffe)
     1330        },
     1331        {
     1332            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
     1333            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
     1334            RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffffffffe)
     1335        },
     1336        {
     1337            RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85),
     1338            RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
     1339            RTUINT128_INIT_C(0x0000000000000000, 0x000000281edd19d2),
     1340        },
     1341        {
     1342            RTUINT128_INIT_C(0xfd4d22a441ffa48c, 0x170739b573a9498d),
     1343            RTUINT128_INIT_C(0x43459cea40782b26, 0xc8c16bb29cb3b343),
     1344            RTUINT128_INIT_C(0x4092bf8e8277cfb2, 0xdfc8a568105cfcd0),
     1345        },
     1346    };
     1347    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
     1348    {
     1349        RTUINT128U uResult;
     1350        PRTUINT128U pResult = RTUInt128Add(&uResult, &s_aTests[i].uAugend, &s_aTests[i].uAddend);
     1351        if (pResult != &uResult)
     1352            RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
     1353        else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
     1354            RTTestIFailed("test #%i failed: result differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
     1355                          i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
     1356
     1357        uResult = s_aTests[i].uAugend;
     1358        pResult = RTUInt128AssignAdd(&uResult, &s_aTests[i].uAddend);
     1359        RTTESTI_CHECK(pResult == &uResult);
     1360        RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1361
     1362        if (s_aTests[i].uAddend.s.Hi == 0)
     1363        {
     1364            pResult = RTUInt128AddU64(&uResult, &s_aTests[i].uAugend, s_aTests[i].uAddend.s.Lo);
     1365            RTTESTI_CHECK(pResult == &uResult);
     1366            RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1367
     1368            uResult = s_aTests[i].uAugend;
     1369            pResult = RTUInt128AssignAddU64(&uResult, s_aTests[i].uAddend.s.Lo);
     1370            RTTESTI_CHECK(pResult == &uResult);
     1371            RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1372        }
     1373
     1374        if (s_aTests[i].uAugend.s.Hi == 0)
     1375        {
     1376            pResult = RTUInt128AddU64(&uResult, &s_aTests[i].uAddend, s_aTests[i].uAugend.s.Lo);
     1377            RTTESTI_CHECK(pResult == &uResult);
     1378            RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1379
     1380            uResult = s_aTests[i].uAddend;
     1381            pResult = RTUInt128AssignAddU64(&uResult, s_aTests[i].uAugend.s.Lo);
     1382            RTTESTI_CHECK(pResult == &uResult);
     1383            RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1384        }
     1385    }
     1386}
     1387
     1388static void testUInt128Multiplication(void)
     1389{
     1390    RTTestSub(g_hTest, "RTUInt128Mul");
     1391
     1392    static struct
     1393    {
     1394        RTUINT128U uFactor1, uFactor2, uResult;
     1395    } const s_aTests[] =
     1396    {
     1397        { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) },
     1398        { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
     1399        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
     1400        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 2) },
     1401        { RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 0) },
     1402        { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(4, 2) },
     1403        {
     1404            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1405            RTUINT128_INIT_C(0, 2),
     1406            RTUINT128_INIT_C(0x2222222222222222, 0x2222222222222222)
     1407        },
     1408        {
     1409            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1410            RTUINT128_INIT_C(0, 0xf),
     1411            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff)
     1412        },
     1413        {
     1414            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1415            RTUINT128_INIT_C(0,                             0x30000),
     1416            RTUINT128_INIT_C(0x3333333333333333, 0x3333333333330000)
     1417        },
     1418        {
     1419            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1420            RTUINT128_INIT_C(0,                          0x30000000),
     1421            RTUINT128_INIT_C(0x3333333333333333, 0x3333333330000000)
     1422        },
     1423        {
     1424            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1425            RTUINT128_INIT_C(0,                     0x3000000000000),
     1426            RTUINT128_INIT_C(0x3333333333333333, 0x3333000000000000)
     1427        },
     1428        {
     1429            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1430            RTUINT128_INIT_C(0x0000000000000003, 0x0000000000000000),
     1431            RTUINT128_INIT_C(0x3333333333333333, 0x0000000000000000)
     1432        },
     1433        {
     1434            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1435            RTUINT128_INIT_C(0x0000000300000000, 0x0000000000000000),
     1436            RTUINT128_INIT_C(0x3333333300000000, 0x0000000000000000)
     1437        },
     1438        {
     1439            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1440            RTUINT128_INIT_C(0x0003000000000000, 0x0000000000000000),
     1441            RTUINT128_INIT_C(0x3333000000000000, 0x0000000000000000)
     1442        },
     1443        {
     1444            RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
     1445            RTUINT128_INIT_C(0x3000000000000000, 0x0000000000000000),
     1446            RTUINT128_INIT_C(0x3000000000000000, 0x0000000000000000)
     1447        },
     1448    };
     1449    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
     1450    {
     1451        RTUINT128U uResult;
     1452        PRTUINT128U pResult = RTUInt128Mul(&uResult, &s_aTests[i].uFactor1, &s_aTests[i].uFactor2);
     1453        if (pResult != &uResult)
     1454            RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
     1455        else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
     1456            RTTestIFailed("test #%i failed: \nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
     1457                          i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
     1458
     1459        if (s_aTests[i].uFactor2.s.Hi == 0)
     1460        {
     1461            pResult = RTUInt128MulByU64(&uResult, &s_aTests[i].uFactor1, s_aTests[i].uFactor2.s.Lo);
     1462            RTTESTI_CHECK(pResult == &uResult);
     1463            RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1464        }
     1465
     1466        if (s_aTests[i].uFactor1.s.Hi == 0)
     1467        {
     1468            pResult = RTUInt128MulByU64(&uResult, &s_aTests[i].uFactor2, s_aTests[i].uFactor1.s.Lo);
     1469            RTTESTI_CHECK(pResult == &uResult);
     1470            RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1471        }
     1472
     1473        uResult = s_aTests[i].uFactor1;
     1474        pResult = RTUInt128AssignMul(&uResult, &s_aTests[i].uFactor2);
     1475        RTTESTI_CHECK(pResult == &uResult);
     1476        RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
     1477    }
     1478}
     1479
     1480
     1481#if 0 /* Java program for generating testUInt128Division test data. */
     1482import java.math.BigInteger;
     1483import java.lang.System;
     1484import java.lang.Integer;
     1485import java.util.Random;
     1486import java.security.SecureRandom;
     1487
     1488class uint128divtestgen
     1489{
     1490
     1491public static String format(BigInteger BigNum)
     1492{
     1493    String str = BigNum.toString(16);
     1494    while (str.length() < 32)
     1495        str = "0" + str;
     1496    return "RTUINT128_INIT_C(0x" + str.substring(0, 16) + ", 0x" + str.substring(16) + ")";
     1497}
     1498
     1499public static void main(String args[])
     1500{
     1501    Random Rnd = new SecureRandom();
     1502
     1503    int cDivisorLarger = 0;
     1504    for (int i = 0; i < 4096; i++)
     1505    {
     1506        int cDividendBits = Rnd.nextInt(127) + 1;
     1507        int cDivisorBits  = i < 9 ? cDividendBits : Rnd.nextInt(127) + 1;
     1508        if (cDivisorBits > cDividendBits)
     1509        {
     1510            if (cDivisorLarger > i / 16)
     1511                cDividendBits = 128 - Rnd.nextInt(16);
     1512            else
     1513                cDivisorLarger++;
     1514        }
     1515
     1516        BigInteger Dividend = new BigInteger(cDividendBits, Rnd);
     1517        BigInteger Divisor  = new BigInteger(cDivisorBits, Rnd);
     1518        while (Divisor.compareTo(BigInteger.ZERO) == 0) {
     1519            cDivisorBits++;
     1520            Divisor = new BigInteger(cDivisorBits, Rnd);
     1521        }
     1522
     1523        BigInteger[] Result = Dividend.divideAndRemainder(Divisor);
     1524
     1525        System.out.println("    { /* i=" + Integer.toString(i) + "; " + Integer.toString(cDividendBits) + " / " + Integer.toString(cDivisorBits) + " */");
     1526        System.out.println("        " + format(Dividend)  + ", " + format(Divisor)   + ",");
     1527        System.out.println("        " + format(Result[0]) + ", " + format(Result[1]) + "");
     1528        System.out.println("    },");
     1529    }
     1530}
     1531}
     1532#endif
     1533
     1534static void testUInt128Division(void)
     1535{
     1536    RTTestSub(g_hTest, "RTUInt128DivMod");
     1537
     1538    static struct
     1539    {
     1540        RTUINT128U uDividend, uDivisor, uQuotient, uRemainder;
     1541    } const s_aTests[] =
     1542    {
     1543        { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) }, /* #0 */
     1544        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) }, /* #1 */
     1545        { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1) }, /* #2 */
     1546        { RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) }, /* #3 */
     1547        { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(1, 0), RTUINT128_INIT_C(0, 1) }, /* #4 */
     1548        {   /* #5 */
     1549            RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
     1550            RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
     1551            RTUINT128_INIT_C(0x0000000000000001, 0x0000000000000000),
     1552            RTUINT128_INIT_C(0x0000000000000000, 0x0000000000000000)
     1553        },
     1554        {   /* #6 */
     1555            RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
     1556            RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
     1557            RTUINT128_INIT_C(0x0000000000000000, 0x0000000000100000),
     1558            RTUINT128_INIT_C(0x0000000000000000, 0x0000000000000000)
     1559        },
     1560        {   /* #7 */
     1561            RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
     1562            RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
     1563            RTUINT128_INIT_C(0x0000000000000000, 0x0000000000100000),
     1564            RTUINT128_INIT_C(0x0000000000000000, 0x00000000000fffff)
     1565        },
     1566        {   /* #8 */
     1567            RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85), RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
     1568            RTUINT128_INIT_C(0x0000000000000000, 0x000000000000000c), RTUINT128_INIT_C(0x0000000000000000, 0x000000010577b6e9)
     1569        },
     1570
     1571#include "tstRTBigNum-uint128-div-test-data.h"
     1572    };
     1573    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
     1574    {
     1575        RTUINT128U uResultQ, uResultR;
     1576        PRTUINT128U pResultQ = RTUInt128DivRem(&uResultQ, &uResultR, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
     1577        if (pResultQ != &uResultQ)
     1578            RTTestIFailed("test #%i returns %p instead of %p", i, pResultQ, &uResultQ);
     1579        else if (   RTUInt128IsNotEqual(&uResultQ, &s_aTests[i].uQuotient)
     1580                 && RTUInt128IsNotEqual(&uResultR, &s_aTests[i].uRemainder))
     1581        {
     1582            RTTestIFailed("test #%i failed on both counts", i);
     1583        }
     1584        else if (RTUInt128IsNotEqual(&uResultQ, &s_aTests[i].uQuotient))
     1585            RTTestIFailed("test #%i failed: quotient differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
     1586                          i, s_aTests[i].uQuotient.s.Hi, s_aTests[i].uQuotient.s.Lo, uResultQ.s.Hi, uResultQ.s.Lo );
     1587        else if (RTUInt128IsNotEqual(&uResultR, &s_aTests[i].uRemainder))
     1588            RTTestIFailed("test #%i failed: remainder differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
     1589                          i, s_aTests[i].uRemainder.s.Hi, s_aTests[i].uRemainder.s.Lo, uResultR.s.Hi, uResultR.s.Lo );
     1590
     1591        pResultQ = RTUInt128Div(&uResultQ, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
     1592        RTTESTI_CHECK(pResultQ == &uResultQ);
     1593        RTTESTI_CHECK(RTUInt128IsEqual(&uResultQ, &s_aTests[i].uQuotient));
     1594
     1595        uResultQ = s_aTests[i].uDividend;
     1596        pResultQ = RTUInt128AssignDiv(&uResultQ, &s_aTests[i].uDivisor);
     1597        RTTESTI_CHECK(pResultQ == &uResultQ);
     1598        RTTESTI_CHECK(RTUInt128IsEqual(&uResultQ, &s_aTests[i].uQuotient));
     1599
     1600
     1601        PRTUINT128U pResultR = RTUInt128Mod(&uResultR, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
     1602        RTTESTI_CHECK(pResultR == &uResultR);
     1603        RTTESTI_CHECK(RTUInt128IsEqual(&uResultR, &s_aTests[i].uRemainder));
     1604
     1605        uResultR = s_aTests[i].uDividend;
     1606        pResultR = RTUInt128AssignMod(&uResultR, &s_aTests[i].uDivisor);
     1607        RTTESTI_CHECK(pResultR == &uResultR);
     1608        RTTESTI_CHECK(RTUInt128IsEqual(&uResultR, &s_aTests[i].uRemainder));
     1609    }
    9101610}
    9111611
     
    9471647    RTTESTI_CHECK_RC(RTBigNumInit(&g_Minus1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
    9481648                                  g_abMinus1, sizeof(g_abMinus1)), VINF_SUCCESS);
     1649
     1650    RTTESTI_CHECK_RC(RTBigNumInit(&g_PubKeyExp, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
     1651                                  g_abPubKeyExp, sizeof(g_abPubKeyExp)), VINF_SUCCESS);
     1652    RTTESTI_CHECK_RC(RTBigNumInit(&g_PubKeyMod, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
     1653                                  g_abPubKeyMod, sizeof(g_abPubKeyMod)), VINF_SUCCESS);
     1654    RTTESTI_CHECK_RC(RTBigNumInit(&g_Signature, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
     1655                                  g_abSignature, sizeof(g_abSignature)), VINF_SUCCESS);
     1656    RTTESTI_CHECK_RC(RTBigNumInit(&g_SignatureDecrypted, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
     1657                                  g_abSignatureDecrypted, sizeof(g_abSignatureDecrypted)), VINF_SUCCESS);
    9491658    testMoreInit();
    9501659
     
    9531662        if (argc != 2)
    9541663        {
    955             /* Do testing. */
     1664            /* Test UInt128 first as it may be used by RTBigInt. */
     1665            testUInt128Multiplication();
     1666            testUInt128Division();
     1667            testUInt128Subtraction();
     1668            testUInt128Addition();
     1669
     1670            /* Test the RTBigInt operations. */
    9561671            testCompare();
    9571672            testSubtraction();
    9581673            testAddition();
     1674            testShift();
    9591675            testMultiplication();
    9601676            testDivision();
     
    9661682
    9671683        /* Benchmarks */
    968         testBenchmarks();
     1684        testBenchmarks(argc == 2);
    9691685
    9701686        /* Cleanups. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette