VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTBigNum.cpp@ 76221

Last change on this file since 76221 was 75423, checked in by vboxsync, 6 years ago

tstRTBigNum: Test RTUInt32DivRem and RTUInt64DivRem too.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 85.6 KB
Line 
1/* $Id: tstRTBigNum.cpp 75423 2018-11-13 14:05:27Z vboxsync $ */
2/** @file
3 * IPRT - Testcase for the RTBigNum* functions.
4 */
5
6/*
7 * Copyright (C) 2006-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/bignum.h>
32#include <iprt/uint128.h>
33#include <iprt/uint64.h>
34#include <iprt/uint32.h>
35
36#include <iprt/string.h>
37#include <iprt/rand.h>
38#include <iprt/test.h>
39#include <iprt/thread.h>
40#include <iprt/time.h>
41
42#if 1
43# include <openssl/bn.h>
44#endif
45
46
47/*********************************************************************************************************************************
48* Global Variables *
49*********************************************************************************************************************************/
50static RTTEST g_hTest;
51
52
53static uint8_t const g_abLargePositive[] =
54{
55 0x67,0xcd,0xd6,0x60,0x4e,0xaa,0xe9,0x8e,0x06,0x99,0xde,0xb2,0xf5,0x1c,0xc3,0xfc,
56 0xf5,0x17,0x41,0xec,0x42,0x68,0xf0,0xab,0x0e,0xe6,0x79,0xa8,0x32,0x97,0x55,0x00,
57 0x49,0x21,0x2b,0x72,0x4b,0x34,0x33,0xe1,0xe2,0xfe,0xa2,0xb8,0x39,0x7a,0x2f,0x17,
58 0xae,0x1f,0xbb,0xdb,0x46,0xbc,0x59,0x8b,0x13,0x05,0x28,0x96,0xf6,0xfd,0xc1,0xa4
59};
60static RTBIGNUM g_LargePositive;
61static RTBIGNUM g_LargePositive2; /**< Smaller than g_LargePositive. */
62
63static uint8_t const g_abLargePositiveMinus1[] =
64{
65 0x67,0xcd,0xd6,0x60,0x4e,0xaa,0xe9,0x8e,0x06,0x99,0xde,0xb2,0xf5,0x1c,0xc3,0xfc,
66 0xf5,0x17,0x41,0xec,0x42,0x68,0xf0,0xab,0x0e,0xe6,0x79,0xa8,0x32,0x97,0x55,0x00,
67 0x49,0x21,0x2b,0x72,0x4b,0x34,0x33,0xe1,0xe2,0xfe,0xa2,0xb8,0x39,0x7a,0x2f,0x17,
68 0xae,0x1f,0xbb,0xdb,0x46,0xbc,0x59,0x8b,0x13,0x05,0x28,0x96,0xf6,0xfd,0xc1,0xa3
69};
70static RTBIGNUM g_LargePositiveMinus1; /**< g_LargePositive - 1 */
71
72
73static uint8_t const g_abLargeNegative[] =
74{
75 0xf2,0xde,0xbd,0xaf,0x43,0x9e,0x1e,0x88,0xdc,0x64,0x37,0xa9,0xdb,0xb7,0x26,0x31,
76 0x92,0x1d,0xf5,0x43,0x4c,0xb0,0x21,0x2b,0x07,0x4e,0xf5,0x94,0x9e,0xce,0x15,0x79,
77 0x13,0x0c,0x70,0x68,0x49,0x46,0xcf,0x72,0x2b,0xc5,0x8f,0xab,0x7c,0x88,0x2d,0x1e,
78 0x3b,0x43,0x5b,0xdb,0x47,0x45,0x7a,0x25,0x74,0x46,0x1d,0x87,0x24,0xaa,0xab,0x0d,
79 0x3e,0xdf,0xd1,0xd8,0x44,0x6f,0x01,0x84,0x01,0x36,0xe0,0x84,0x6e,0x6f,0x41,0xbb,
80 0xae,0x1a,0x31,0xef,0x42,0x23,0xfd,0xda,0xda,0x0f,0x7d,0x88,0x8f,0xf5,0x63,0x72,
81 0x36,0x9f,0xa9,0xa4,0x4f,0xa0,0xa6,0xb1,0x3b,0xbe,0x0d,0x9d,0x62,0x88,0x98,0x8b
82};
83static RTBIGNUM g_LargeNegative;
84static RTBIGNUM g_LargeNegative2; /**< A few digits less than g_LargeNegative, i.e. larger value. */
85
86static uint8_t const g_abLargeNegativePluss1[] =
87{
88 0xf2,0xde,0xbd,0xaf,0x43,0x9e,0x1e,0x88,0xdc,0x64,0x37,0xa9,0xdb,0xb7,0x26,0x31,
89 0x92,0x1d,0xf5,0x43,0x4c,0xb0,0x21,0x2b,0x07,0x4e,0xf5,0x94,0x9e,0xce,0x15,0x79,
90 0x13,0x0c,0x70,0x68,0x49,0x46,0xcf,0x72,0x2b,0xc5,0x8f,0xab,0x7c,0x88,0x2d,0x1e,
91 0x3b,0x43,0x5b,0xdb,0x47,0x45,0x7a,0x25,0x74,0x46,0x1d,0x87,0x24,0xaa,0xab,0x0d,
92 0x3e,0xdf,0xd1,0xd8,0x44,0x6f,0x01,0x84,0x01,0x36,0xe0,0x84,0x6e,0x6f,0x41,0xbb,
93 0xae,0x1a,0x31,0xef,0x42,0x23,0xfd,0xda,0xda,0x0f,0x7d,0x88,0x8f,0xf5,0x63,0x72,
94 0x36,0x9f,0xa9,0xa4,0x4f,0xa0,0xa6,0xb1,0x3b,0xbe,0x0d,0x9d,0x62,0x88,0x98,0x8c
95};
96static RTBIGNUM g_LargeNegativePluss1; /**< g_LargeNegative + 1 */
97
98
99static uint8_t const g_ab64BitPositive1[] = { 0x53, 0xe0, 0xdf, 0x11, 0x85, 0x93, 0x06, 0x21 };
100static uint64_t g_u64BitPositive1 = UINT64_C(0x53e0df1185930621);
101static RTBIGNUM g_64BitPositive1;
102
103
104static RTBIGNUM g_Zero;
105static RTBIGNUM g_One;
106static RTBIGNUM g_Two;
107static RTBIGNUM g_Three;
108static RTBIGNUM g_Four;
109static RTBIGNUM g_Five;
110static RTBIGNUM g_Ten;
111static RTBIGNUM g_FourtyTwo;
112
113static uint8_t const g_abMinus1[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
114//static int64_t g_iBitMinus1 = -1;
115static RTBIGNUM g_Minus1;
116
117
118/** @name The components of a real PKCS #7 signature (extracted from a build of
119 * this testcase).
120 * @{ */
121static uint8_t const g_abPubKeyExp[] = { 0x01, 0x00, 0x01 };
122static RTBIGNUM g_PubKeyExp;
123static uint8_t const g_abPubKeyMod[] =
124{
125 0x00, 0xea, 0x61, 0x4e, 0xa0, 0xb2, 0xae, 0x38, 0xbc, 0x43, 0x24, 0x5a, 0x28, 0xc7, 0xa0, 0x69,
126 0x82, 0x11, 0xd5, 0x78, 0xe8, 0x6b, 0x41, 0x54, 0x7b, 0x6c, 0x69, 0x13, 0xc8, 0x68, 0x75, 0x0f,
127 0xe4, 0x66, 0x54, 0xcd, 0xe3, 0x55, 0x33, 0x3b, 0x7f, 0x9f, 0x55, 0x75, 0x80, 0x6e, 0xd0, 0x8a,
128 0xff, 0xc1, 0xf4, 0xbf, 0xfd, 0x70, 0x9b, 0x73, 0x7e, 0xee, 0xf1, 0x80, 0x23, 0xd4, 0xbd, 0xba,
129 0xdc, 0xce, 0x09, 0x4a, 0xeb, 0xb0, 0xdd, 0x86, 0x4a, 0x0b, 0x8e, 0x3e, 0x9a, 0x8a, 0x58, 0xed,
130 0x98, 0x4f, 0x25, 0xe5, 0x0c, 0x18, 0xd8, 0x10, 0x95, 0xce, 0xe4, 0x19, 0x82, 0x38, 0xcd, 0x76,
131 0x6a, 0x38, 0xe5, 0x14, 0xe6, 0x95, 0x0d, 0x80, 0xc5, 0x09, 0x5e, 0x93, 0xf4, 0x6f, 0x82, 0x8e,
132 0x9c, 0x81, 0x09, 0xd6, 0xd4, 0xee, 0xd5, 0x1f, 0x94, 0x2d, 0x13, 0x18, 0x9a, 0xbc, 0x88, 0x5d,
133 0x9a, 0xe5, 0x66, 0x08, 0x99, 0x93, 0x1b, 0x8a, 0x69, 0x3f, 0x68, 0xb2, 0x97, 0x2a, 0x24, 0xf6,
134 0x65, 0x2a, 0x94, 0x33, 0x94, 0x14, 0x5c, 0x6f, 0xff, 0x95, 0xd0, 0x2b, 0xf0, 0x2b, 0xcb, 0x49,
135 0xcd, 0x03, 0x3a, 0x45, 0xd5, 0x22, 0x1c, 0xb3, 0xee, 0xd5, 0xaf, 0xb3, 0x5b, 0xcb, 0x1b, 0x35,
136 0x4e, 0xff, 0x21, 0x0a, 0x55, 0x1f, 0xa0, 0xf9, 0xdc, 0xad, 0x7a, 0x89, 0x0b, 0x6e, 0x3f, 0x75,
137 0xc0, 0x6c, 0x44, 0xff, 0x90, 0x63, 0x79, 0xcf, 0x70, 0x20, 0x60, 0x33, 0x3c, 0xb1, 0xfa, 0x6b,
138 0x6c, 0x55, 0x3c, 0xeb, 0x8d, 0x18, 0xe9, 0x0a, 0x81, 0xd5, 0x24, 0xc1, 0x88, 0x7c, 0xa6, 0x8e,
139 0xd3, 0x2c, 0x51, 0x1d, 0x6d, 0xdf, 0x51, 0xd5, 0x72, 0x54, 0x7a, 0x98, 0xc0, 0x36, 0x35, 0x21,
140 0x66, 0x3c, 0x2f, 0x01, 0xc0, 0x8e, 0xb0, 0x56, 0x60, 0x6e, 0x67, 0x4f, 0x5f, 0xac, 0x05, 0x60,
141 0x9b
142};
143static RTBIGNUM g_PubKeyMod;
144static uint8_t const g_abSignature[] =
145{
146 0x00, 0xae, 0xca, 0x93, 0x47, 0x0b, 0xfa, 0xd8, 0xb9, 0xbb, 0x5a, 0x5e, 0xf6, 0x75, 0x90, 0xed,
147 0x80, 0x37, 0x03, 0x6d, 0x23, 0x91, 0x30, 0x0c, 0x9d, 0xbf, 0x34, 0xc1, 0xf9, 0x43, 0xa7, 0xec,
148 0xc0, 0x83, 0xc0, 0x98, 0x3f, 0x8a, 0x65, 0x48, 0x7c, 0xa4, 0x9f, 0x14, 0x4d, 0x52, 0x90, 0x2d,
149 0x17, 0xd1, 0x3e, 0x05, 0xd6, 0x35, 0x1b, 0xdb, 0xe5, 0x1a, 0xa2, 0x54, 0x8c, 0x30, 0x6f, 0xfe,
150 0xa1, 0xd9, 0x98, 0x3f, 0xb5, 0x65, 0x14, 0x9c, 0x50, 0x55, 0xa1, 0xbf, 0xb5, 0x12, 0xc4, 0xf2,
151 0x72, 0x27, 0x14, 0x59, 0xb5, 0x23, 0x67, 0x11, 0x2a, 0xd8, 0xa8, 0x85, 0x4b, 0xc5, 0xb0, 0x2f,
152 0x73, 0x54, 0xcf, 0x33, 0xa0, 0x06, 0xf2, 0x8e, 0x4f, 0x4b, 0x18, 0x97, 0x08, 0x47, 0xce, 0x0c,
153 0x47, 0x97, 0x0d, 0xbd, 0x8b, 0xce, 0x61, 0x31, 0x21, 0x7e, 0xc4, 0x1d, 0x03, 0xf8, 0x06, 0xca,
154 0x9f, 0xd3, 0x5e, 0x4b, 0xfc, 0xf1, 0x99, 0x34, 0x78, 0x83, 0xfa, 0xab, 0x9c, 0x7c, 0x6b, 0x5c,
155 0x3d, 0x45, 0x39, 0x6d, 0x6a, 0x6c, 0xd5, 0x63, 0x3e, 0xbe, 0x09, 0x62, 0x64, 0x5f, 0x83, 0x3b,
156 0xb6, 0x5c, 0x7e, 0x8e, 0xeb, 0x1e, 0x6a, 0x34, 0xb9, 0xc7, 0x92, 0x92, 0x58, 0x64, 0x48, 0xfe,
157 0xf8, 0x35, 0x53, 0x07, 0x89, 0xb4, 0x29, 0x4d, 0x3d, 0x79, 0x43, 0x73, 0x0f, 0x16, 0x21, 0xab,
158 0xb7, 0x07, 0x2b, 0x5a, 0x8a, 0x0f, 0xd7, 0x2e, 0x95, 0xb4, 0x26, 0x66, 0x65, 0x72, 0xac, 0x7e,
159 0x46, 0x70, 0xe6, 0xad, 0x43, 0xa2, 0x73, 0x54, 0x6a, 0x41, 0xc8, 0x9c, 0x1e, 0x65, 0xed, 0x06,
160 0xd1, 0xc7, 0x99, 0x3e, 0x5f, 0x5a, 0xd3, 0xd0, 0x1a, 0x9b, 0x0e, 0x3e, 0x04, 0x66, 0xb6, 0xaa,
161 0xa6, 0x51, 0xb8, 0xc0, 0x13, 0x19, 0x34, 0x0e, 0x86, 0x02, 0xd5, 0xc8, 0x10, 0xaa, 0x1f, 0x97,
162 0x95
163};
164static RTBIGNUM g_Signature;
165static uint8_t const g_abSignatureDecrypted[] =
166{
167 0x00, 0x01, 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, 0xff, 0xff, 0xff, 0xff,
177 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
178 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
179 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
180 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
181 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x54, 0x60, 0xb0, 0x65,
182 0xf1, 0xbc, 0x40, 0x77, 0xfc, 0x9e, 0xfc, 0x2f, 0x94, 0x62, 0x62, 0x61, 0x43, 0xb9, 0x01, 0xb9
183};
184static RTBIGNUM g_SignatureDecrypted;
185/** @} */
186
187
188static void testInitOneLittleEndian(uint8_t const *pb, size_t cb, PRTBIGNUM pBigNum)
189{
190 uint8_t abLittleEndian[sizeof(g_abLargePositive) + sizeof(g_abLargeNegative)];
191 RTTESTI_CHECK_RETV(cb <= sizeof(abLittleEndian));
192
193 size_t cbLeft = cb;
194 uint8_t *pbDst = abLittleEndian + cb - 1;
195 uint8_t const *pbSrc = pb;
196 while (cbLeft-- > 0)
197 *pbDst-- = *pbSrc++;
198
199 RTBIGNUM Num;
200 RTTESTI_CHECK_RC_RETV(RTBigNumInit(&Num, RTBIGNUMINIT_F_ENDIAN_LITTLE | RTBIGNUMINIT_F_SIGNED,
201 abLittleEndian, cb), VINF_SUCCESS);
202 RTTESTI_CHECK(Num.fNegative == pBigNum->fNegative);
203 RTTESTI_CHECK(Num.cUsed == pBigNum->cUsed);
204 RTTESTI_CHECK(RTBigNumCompare(&Num, pBigNum) == 0);
205 RTTESTI_CHECK_RC(RTBigNumDestroy(&Num), VINF_SUCCESS);
206
207 RTTESTI_CHECK_RC_RETV(RTBigNumInit(&Num, RTBIGNUMINIT_F_ENDIAN_LITTLE | RTBIGNUMINIT_F_SIGNED | RTBIGNUMINIT_F_SENSITIVE,
208 abLittleEndian, cb), VINF_SUCCESS);
209 RTTESTI_CHECK(Num.fNegative == pBigNum->fNegative);
210 RTTESTI_CHECK(Num.cUsed == pBigNum->cUsed);
211 RTTESTI_CHECK(RTBigNumCompare(&Num, pBigNum) == 0);
212 RTTESTI_CHECK_RC(RTBigNumDestroy(&Num), VINF_SUCCESS);
213}
214
215static void testMoreInit(void)
216{
217 RTTESTI_CHECK(!g_LargePositive.fNegative);
218 RTTESTI_CHECK(!g_LargePositive.fSensitive);
219 RTTESTI_CHECK(!g_LargePositive2.fNegative);
220 RTTESTI_CHECK(!g_LargePositive2.fSensitive);
221 RTTESTI_CHECK(g_LargeNegative.fNegative);
222 RTTESTI_CHECK(!g_LargeNegative.fSensitive);
223 RTTESTI_CHECK(g_LargeNegative2.fNegative);
224 RTTESTI_CHECK(!g_LargeNegative2.fSensitive);
225
226 RTTESTI_CHECK(!g_Zero.fNegative);
227 RTTESTI_CHECK(!g_Zero.fSensitive);
228 RTTESTI_CHECK(g_Zero.cUsed == 0);
229
230 RTTESTI_CHECK(g_Minus1.fNegative);
231 RTTESTI_CHECK(!g_Minus1.fSensitive);
232 RTTESTI_CHECK(g_Minus1.cUsed == 1);
233 RTTESTI_CHECK(g_Minus1.pauElements[0] == 1);
234
235 RTTESTI_CHECK(g_One.cUsed == 1 && g_One.pauElements[0] == 1);
236 RTTESTI_CHECK(g_Two.cUsed == 1 && g_Two.pauElements[0] == 2);
237 RTTESTI_CHECK(g_Three.cUsed == 1 && g_Three.pauElements[0] == 3);
238 RTTESTI_CHECK(g_Four.cUsed == 1 && g_Four.pauElements[0] == 4);
239 RTTESTI_CHECK(g_Ten.cUsed == 1 && g_Ten.pauElements[0] == 10);
240 RTTESTI_CHECK(g_FourtyTwo.cUsed == 1 && g_FourtyTwo.pauElements[0] == 42);
241
242 /* Test big endian initialization w/ sensitive variation. */
243 testInitOneLittleEndian(g_abLargePositive, sizeof(g_abLargePositive), &g_LargePositive);
244 testInitOneLittleEndian(g_abLargePositive, sizeof(g_abLargePositive) - 11, &g_LargePositive2);
245
246 testInitOneLittleEndian(g_abLargeNegative, sizeof(g_abLargeNegative), &g_LargeNegative);
247 testInitOneLittleEndian(g_abLargeNegative, sizeof(g_abLargeNegative) - 9, &g_LargeNegative2);
248
249 RTTESTI_CHECK(g_Minus1.cUsed == 1);
250 testInitOneLittleEndian(g_abMinus1, sizeof(g_abMinus1), &g_Minus1);
251 testInitOneLittleEndian(g_abMinus1, 1, &g_Minus1);
252 testInitOneLittleEndian(g_abMinus1, 4, &g_Minus1);
253
254}
255
256
257static void testCompare(void)
258{
259 RTTestSub(g_hTest, "RTBigNumCompare*");
260 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargePositive) == 0);
261 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive2, &g_LargePositive) == -1);
262 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargePositive2) == 1);
263 RTTESTI_CHECK(RTBigNumCompare(&g_Zero, &g_LargePositive) == -1);
264 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_Zero) == 1);
265 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive2, &g_Zero) == 1);
266 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargePositiveMinus1) == 1);
267 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositiveMinus1, &g_LargePositive) == -1);
268
269 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegative) == 0);
270 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegative2) == -1);
271 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_LargeNegative) == 1);
272 RTTESTI_CHECK(RTBigNumCompare(&g_Zero, &g_LargeNegative) == 1);
273 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_Zero) == -1);
274 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_Zero) == -1);
275 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegativePluss1) == -1);
276 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegativePluss1, &g_LargeNegative) == 1);
277
278 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargePositive) == -1);
279 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargeNegative) == 1);
280 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_LargePositive) == -1);
281 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargeNegative2) == 1);
282 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_LargePositive2) == -1);
283 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive2, &g_LargeNegative2) == 1);
284
285 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, 0) == 0);
286 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, 1) == -1);
287 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, UINT32_MAX) == -1);
288 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, UINT64_MAX) == -1);
289 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargePositive, UINT64_MAX) == 1);
290 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargePositive2, 0x7213593) == 1);
291 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, 0) == -1);
292 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, 1) == -1);
293 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, UINT64_MAX) == -1);
294 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, 0x80034053) == -1);
295 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_64BitPositive1, g_u64BitPositive1) == 0);
296 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_64BitPositive1, g_u64BitPositive1 - 1) == 1);
297 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_64BitPositive1, g_u64BitPositive1 + 1) == -1);
298
299 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, 0) == 0);
300 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, 1) == -1);
301 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, -1) == 1);
302 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, INT32_MAX) == -1);
303 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_LargeNegative, INT32_MIN) == -1);
304 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_LargeNegative, INT64_MIN) == -1);
305 RTTESTI_CHECK(g_u64BitPositive1 < (uint64_t)INT64_MAX);
306 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, g_u64BitPositive1) == 0);
307 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, g_u64BitPositive1 - 1) == 1);
308 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, g_u64BitPositive1 + 1) == -1);
309 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, INT64_MIN) == 1);
310 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, INT64_MAX) == -1);
311 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Minus1, -1) == 0);
312 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Minus1, -2) == 1);
313 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Minus1, 0) == -1);
314}
315
316
317static void testSubtraction(void)
318{
319 RTTestSub(g_hTest, "RTBigNumSubtract");
320
321 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
322 {
323 RTBIGNUM Result;
324 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
325 RTBIGNUM Result2;
326 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
327
328 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
329 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
330
331 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
332 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
333
334 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Minus1, &g_Zero), VINF_SUCCESS);
335 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
336
337 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_64BitPositive1, &g_Minus1), VINF_SUCCESS);
338 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1 + 1) == 0);
339
340 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Minus1, &g_64BitPositive1), VINF_SUCCESS);
341 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, INT64_C(-1) - g_u64BitPositive1) == 0);
342
343 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
344 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
345 RTTESTI_CHECK(Result.cUsed == 1);
346
347 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargePositiveMinus1, &g_LargePositive), VINF_SUCCESS);
348 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
349 RTTESTI_CHECK(Result.cUsed == 1);
350
351 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegativePluss1) < 0);
352 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargeNegative, &g_LargeNegativePluss1), VINF_SUCCESS);
353 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
354 RTTESTI_CHECK(Result.cUsed == 1);
355
356 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargeNegativePluss1, &g_LargeNegative), VINF_SUCCESS);
357 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
358 RTTESTI_CHECK(Result.cUsed == 1);
359
360 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargeNegativePluss1, &g_LargeNegativePluss1), VINF_SUCCESS);
361 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
362 RTTESTI_CHECK(Result.cUsed == 0);
363
364 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
365 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
366 }
367}
368
369
370static void testAddition(void)
371{
372 RTTestSub(g_hTest, "RTBigNumAdd");
373
374 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
375 {
376 RTBIGNUM Result;
377 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
378 RTBIGNUM Result2;
379 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
380
381 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
382 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -2) == 0);
383
384 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
385 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
386
387 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Zero, &g_64BitPositive1), VINF_SUCCESS);
388 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1) == 0);
389
390 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Minus1, &g_64BitPositive1), VINF_SUCCESS);
391 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1 - 1) == 0);
392
393 RTTESTI_CHECK(g_u64BitPositive1 * 2 > g_u64BitPositive1);
394 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_64BitPositive1, &g_64BitPositive1), VINF_SUCCESS);
395 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1 * 2) == 0);
396
397
398 RTTESTI_CHECK_RC(RTBigNumAssign(&Result2, &g_LargePositive), VINF_SUCCESS);
399 RTTESTI_CHECK_RC(RTBigNumNegateThis(&Result2), VINF_SUCCESS);
400
401 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositive, &Result2), VINF_SUCCESS);
402 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, 0) == 0);
403
404 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &Result2, &g_LargePositive), VINF_SUCCESS);
405 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, 0) == 0);
406
407 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositiveMinus1, &Result2), VINF_SUCCESS);
408 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
409
410 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &Result2, &g_LargePositiveMinus1), VINF_SUCCESS);
411 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
412
413
414 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
415 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositive) > 0);
416 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargePositiveMinus1), VINF_SUCCESS);
417 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositive) == 0);
418 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargePositive), VINF_SUCCESS);
419 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositiveMinus1) == 0);
420
421 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositive, &g_LargeNegative), VINF_SUCCESS);
422 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargeNegative) > 0);
423 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositive) < 0);
424 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargePositive), VINF_SUCCESS);
425 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargeNegative) == 0);
426 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargeNegative), VINF_SUCCESS);
427 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositive) == 0);
428
429 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargeNegativePluss1, &g_LargeNegative), VINF_SUCCESS);
430 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargeNegative) < 0);
431 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargeNegative), VINF_SUCCESS);
432 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargeNegativePluss1) == 0);
433
434 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
435 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
436 }
437}
438
439static void testShift(void)
440{
441 RTTestSub(g_hTest, "RTBigNumShiftLeft, RTBigNumShiftRight");
442
443 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
444 {
445 RTBIGNUM Result;
446 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
447 RTBIGNUM Result2;
448 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
449
450 /* basic left tests */
451 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 1), VINF_SUCCESS);
452 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -2) == 0);
453
454 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 0), VINF_SUCCESS);
455 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
456
457 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 2), VINF_SUCCESS);
458 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -4) == 0);
459
460 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Minus1, 8), VINF_SUCCESS);
461 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -256) == 0);
462
463 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Zero, 511), VINF_SUCCESS);
464 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
465
466 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_FourtyTwo, 1), VINF_SUCCESS);
467 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 84) == 0);
468
469 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_FourtyTwo, 27+24), VINF_SUCCESS);
470 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, UINT64_C(0x150000000000000)) == 0);
471
472 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_FourtyTwo, 27), VINF_SUCCESS);
473 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result2, &Result, 24), VINF_SUCCESS);
474 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result2, UINT64_C(0x150000000000000)) == 0);
475
476 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_LargePositive, 2), VINF_SUCCESS);
477 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result2, &g_LargePositive, &g_Four), VINF_SUCCESS);
478 RTTESTI_CHECK(RTBigNumCompare(&Result2, &Result) == 0);
479
480 /* basic right tests. */
481 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_Minus1, 1), VINF_SUCCESS);
482 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
483
484 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_Minus1, 8), VINF_SUCCESS);
485 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
486
487 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_Zero, 511), VINF_SUCCESS);
488 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
489
490 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 0), VINF_SUCCESS);
491 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 42) == 0);
492
493 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 1), VINF_SUCCESS);
494 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 21) == 0);
495
496 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 2), VINF_SUCCESS);
497 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 10) == 0);
498
499 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 3), VINF_SUCCESS);
500 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 5) == 0);
501
502 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 4), VINF_SUCCESS);
503 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
504
505 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 5), VINF_SUCCESS);
506 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
507
508 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 6), VINF_SUCCESS);
509 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
510
511 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_FourtyTwo, 549), VINF_SUCCESS);
512 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
513
514 RTTESTI_CHECK_RC(RTBigNumDivideLong(&Result2, &Result, &g_LargePositive, &g_Four), VINF_SUCCESS);
515 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &g_LargePositive, 2), VINF_SUCCESS);
516 RTTESTI_CHECK(RTBigNumCompare(&Result2, &Result) == 0);
517
518 /* Some simple back and forth. */
519 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_One, 2), VINF_SUCCESS);
520 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 2), VINF_SUCCESS);
521 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_One) == 0);
522
523 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_Three, 63), VINF_SUCCESS);
524 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 63), VINF_SUCCESS);
525 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_Three) == 0);
526
527 for (uint32_t i = 0; i < 1024; i++)
528 {
529 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_LargePositive, i), VINF_SUCCESS);
530 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, i), VINF_SUCCESS);
531 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositive) == 0);
532 }
533
534 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &g_LargePositive, 2), VINF_SUCCESS);
535 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result2, &Result, 250), VINF_SUCCESS);
536 RTTESTI_CHECK_RC(RTBigNumShiftLeft(&Result, &Result2, 999), VINF_SUCCESS);
537 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 1), VINF_SUCCESS);
538 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &Result2, 250), VINF_SUCCESS);
539 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result2, &Result, 1), VINF_SUCCESS);
540 RTTESTI_CHECK_RC(RTBigNumShiftRight(&Result, &Result2, 999), VINF_SUCCESS);
541 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositive) == 0);
542
543
544 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
545 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
546 }
547}
548
549static bool testHexStringToNum(PRTBIGNUM pBigNum, const char *pszHex, uint32_t fFlags)
550{
551 uint8_t abBuf[_4K];
552 size_t cbHex = strlen(pszHex);
553 RTTESTI_CHECK_RET(!(cbHex & 1), false);
554 cbHex /= 2;
555 RTTESTI_CHECK_RET(cbHex < sizeof(abBuf), false);
556 RTTESTI_CHECK_RC_RET(RTStrConvertHexBytes(pszHex, abBuf, cbHex, 0), VINF_SUCCESS, false);
557 RTTESTI_CHECK_RC_RET(RTBigNumInit(pBigNum, RTBIGNUMINIT_F_ENDIAN_BIG | fFlags, abBuf, cbHex), VINF_SUCCESS, false);
558 return true;
559}
560
561static void testMultiplication(void)
562{
563 RTTestSub(g_hTest, "RTBigNumMultiply");
564
565 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
566 {
567 RTBIGNUM Result;
568 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
569 RTBIGNUM Result2;
570 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
571
572 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
573 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
574
575 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
576 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
577 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Minus1, &g_Zero), VINF_SUCCESS);
578 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
579
580 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Minus1, &g_64BitPositive1), VINF_SUCCESS);
581 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -(int64_t)g_u64BitPositive1) == 0);
582 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_64BitPositive1, &g_Minus1), VINF_SUCCESS);
583 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -(int64_t)g_u64BitPositive1) == 0);
584
585
586 static struct
587 {
588 const char *pszF1, *pszF2, *pszResult;
589 } s_aTests[] =
590 {
591 {
592 "29865DBFA717181B9DD4B515BD072DE10A5A314385F6DED735AC553FCD307D30C499",
593 "4DD65692F7365B90C55F63988E5B6C448653E7DB9DD941507586BD8CF71398287C",
594 "0CA02E8FFDB0EEA37264338A4AAA91C8974E162DDFCBCF804B434A11955671B89B3645AAB75423D60CA3459B0B4F3F28978DA768779FB54CF362FD61924637582F221C"
595 },
596 {
597 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
598 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
599 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000000000000000000001"
600 }
601 };
602 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
603 {
604 RTBIGNUM F1, F2, Expected;
605 if ( testHexStringToNum(&F1, s_aTests[i].pszF1, RTBIGNUMINIT_F_UNSIGNED | fFlags)
606 && testHexStringToNum(&F2, s_aTests[i].pszF2, RTBIGNUMINIT_F_UNSIGNED | fFlags)
607 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
608 {
609 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &F1, &F2), VINF_SUCCESS);
610 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
611 RTTESTI_CHECK_RC(RTBigNumDestroy(&F1), VINF_SUCCESS);
612 RTTESTI_CHECK_RC(RTBigNumDestroy(&F2), VINF_SUCCESS);
613 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
614 }
615 }
616 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
617 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
618 }
619}
620
621
622#if 0 /* Java program for generating testDivision test data. */
623import java.math.BigInteger;
624import java.lang.System;
625import java.lang.Integer;
626import java.util.Random;
627import java.security.SecureRandom;
628
629class bigintdivtestgen
630{
631
632public static String format(BigInteger BigNum)
633{
634 String str = BigNum.toString(16);
635 if ((str.length() & 1) != 0)
636 str = "0" + str;
637 return str;
638}
639
640public static void main(String args[])
641{
642 Random Rnd = new SecureRandom();
643
644 /* Can't go to far here because before we reach 11K both windows compilers
645 will have reached some kind of section limit. Probably string pool related. */
646 int cDivisorLarger = 0;
647 for (int i = 0; i < 9216; i++)
648 {
649 int cDividendBits = Rnd.nextInt(4095) + 1;
650 int cDivisorBits = i < 9 ? cDividendBits : Rnd.nextInt(4095) + 1;
651 if (cDivisorBits > cDividendBits)
652 {
653 cDivisorLarger++;
654 if (cDivisorLarger > i / 4)
655 cDivisorBits = Rnd.nextInt(cDividendBits);
656 }
657
658 BigInteger Dividend = new BigInteger(cDividendBits, Rnd);
659 BigInteger Divisor = new BigInteger(cDivisorBits, Rnd);
660 while (Divisor.compareTo(BigInteger.ZERO) == 0) {
661 cDivisorBits++;
662 Divisor = new BigInteger(cDivisorBits, Rnd);
663 }
664
665 BigInteger[] Result = Dividend.divideAndRemainder(Divisor);
666
667 System.out.println(" { /* i=" + Integer.toString(i)
668 + " cDividendBits=" + Integer.toString(cDividendBits)
669 + " cDivisorBits=" + Integer.toString(cDivisorBits) + " */");
670
671 System.out.println(" \"" + format(Dividend) + "\",");
672 System.out.println(" \"" + format(Divisor) + "\",");
673 System.out.println(" \"" + format(Result[0]) + "\",");
674 System.out.println(" \"" + format(Result[1]) + "\"");
675 System.out.println(" },");
676 }
677}
678}
679#endif
680
681static void testDivision(void)
682{
683 RTTestSub(g_hTest, "RTBigNumDivide");
684
685 //for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
686 uint32_t fFlags = 0;
687 {
688 RTBIGNUM Quotient;
689 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Quotient, fFlags), VINF_SUCCESS);
690 RTBIGNUM Remainder;
691 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Remainder, fFlags), VINF_SUCCESS);
692
693 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Minus1, &g_Minus1), VINF_SUCCESS);
694 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
695 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
696
697 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Zero, &g_Minus1), VINF_SUCCESS);
698 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 0) == 0);
699 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
700
701 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Minus1, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
702 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargeNegative, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
703 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargePositive, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
704
705 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Four, &g_Two), VINF_SUCCESS);
706 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 2) == 0);
707 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
708
709 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Three, &g_Two), VINF_SUCCESS);
710 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
711 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 1) == 0);
712
713 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Ten, &g_Two), VINF_SUCCESS);
714 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 5) == 0);
715 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
716
717
718 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
719 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
720 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 1) == 0);
721
722 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargeNegative, &g_LargeNegativePluss1), VINF_SUCCESS);
723 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
724 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, -1) == 0);
725
726 static struct
727 {
728 const char *pszDividend, *pszDivisor, *pszQuotient, *pszRemainder;
729 } const s_aTests[] =
730 {
731#if 1
732#include "tstRTBigNum-div-test-data.h"
733 { "ff", "10", /* = */ "0f", "0f" },
734 { /* cDividendBits=323 cDivisorBits=195 */
735 "064530fd21b30e179b5bd5efd1f4a7e8df173c13965bd75e1502891303060b417e62711ceb17a73e56",
736 "0784fac4a7c6b5165a99dc3228b6484cba9c7dfadde85cdde3",
737 "d578cc87ed22ac3630a4d1e5fc590ae6",
738 "06acef436982f9c4fc9b0a44d3df1e72cad3ef0cb51ba20664"
739 },
740 {
741 "ffffffffffffffffffffffffffffffffffffffffffffffff",
742 "fffffffffffffffffffffffffffffffffffffffffffffffe",
743 "01",
744 "01"
745 },
746 {
747 "922222222222222222222222222222222222222222222222",
748 "811111111111111111111111111111111111111111111111",
749 "01",
750 "111111111111111111111111111111111111111111111111"
751 },
752 {
753 "955555555555555555555555555555555555555555555555",
754 "211111111111111111111111111111111111111111111111",
755 "04",
756 "111111111111111111111111111111111111111111111111"
757 },
758#endif
759 /* This test triggers negative special cases in Knuth's division algorithm. */
760 {
761 "0137698320ec00bcaa13cd9c18df564bf6df45c5c4c73ad2012cb36cf897c5ff00db638256e19c9ba5a8fbe828ac6e8d470a5f3391d4350ca1390f79c4e4f944eb",
762 "67cdd6604eaae98e0699deb2f51cc3fcf51741ec4268f0ab0ee679a83297550049212b724b3433e1e2fea2b8397a2f17ae1fbbdb46bc598b13052896f6fdc1a4",
763 "02",
764 "67cdd6604eaae98e0699deb2f51cc3fcf51741ec4268f0ab0ee679a83297550049212b724b3433e1e2fea2b8397a2f17ae1fbbdb46bc598b13052896f6fdc1a3"
765 },
766 };
767 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
768 {
769 RTBIGNUM Dividend, Divisor, ExpectedQ, ExpectedR;
770 if ( testHexStringToNum(&Dividend, s_aTests[i].pszDividend, RTBIGNUMINIT_F_UNSIGNED | fFlags)
771 && testHexStringToNum(&Divisor, s_aTests[i].pszDivisor, RTBIGNUMINIT_F_UNSIGNED | fFlags)
772 && testHexStringToNum(&ExpectedQ, s_aTests[i].pszQuotient, RTBIGNUMINIT_F_UNSIGNED | fFlags)
773 && testHexStringToNum(&ExpectedR, s_aTests[i].pszRemainder, RTBIGNUMINIT_F_UNSIGNED | fFlags))
774 {
775 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &Dividend, &Divisor), VINF_SUCCESS);
776
777 if ( RTBigNumCompare(&Quotient, &ExpectedQ) != 0
778 || RTBigNumCompare(&Remainder, &ExpectedR) != 0)
779 {
780 RTTestIFailed("i=%#x both\n"
781 "ExpQ: %.*Rhxs\n"
782 "GotQ: %.*Rhxs\n"
783 "ExpR: %.*Rhxs\n"
784 "GotR: %.*Rhxs\n",
785 i,
786 ExpectedQ.cUsed * RTBIGNUM_ELEMENT_SIZE, ExpectedQ.pauElements,
787 Quotient.cUsed * RTBIGNUM_ELEMENT_SIZE, Quotient.pauElements,
788 ExpectedR.cUsed * RTBIGNUM_ELEMENT_SIZE, ExpectedR.pauElements,
789 Remainder.cUsed * RTBIGNUM_ELEMENT_SIZE, Remainder.pauElements);
790 RTTestIPrintf(RTTESTLVL_ALWAYS, "{ \"%s\", \"%s\", \"%s\", \"%s\" },\n",
791 s_aTests[i].pszDividend, s_aTests[i].pszDivisor,
792 s_aTests[i].pszQuotient, s_aTests[i].pszRemainder);
793 }
794
795 RTTESTI_CHECK_RC(RTBigNumDivideLong(&Quotient, &Remainder, &Dividend, &Divisor), VINF_SUCCESS);
796 RTTESTI_CHECK(RTBigNumCompare(&Quotient, &ExpectedQ) == 0);
797 RTTESTI_CHECK(RTBigNumCompare(&Remainder, &ExpectedR) == 0);
798
799 RTTESTI_CHECK_RC(RTBigNumModulo(&Remainder, &Dividend, &Divisor), VINF_SUCCESS);
800 RTTESTI_CHECK(RTBigNumCompare(&Remainder, &ExpectedR) == 0);
801
802
803 RTTESTI_CHECK_RC(RTBigNumDestroy(&ExpectedR), VINF_SUCCESS);
804 RTTESTI_CHECK_RC(RTBigNumDestroy(&ExpectedQ), VINF_SUCCESS);
805 RTTESTI_CHECK_RC(RTBigNumDestroy(&Divisor), VINF_SUCCESS);
806 RTTESTI_CHECK_RC(RTBigNumDestroy(&Dividend), VINF_SUCCESS);
807 }
808 }
809
810 RTTESTI_CHECK_RC(RTBigNumDestroy(&Quotient), VINF_SUCCESS);
811 RTTESTI_CHECK_RC(RTBigNumDestroy(&Remainder), VINF_SUCCESS);
812 }
813}
814
815
816static void testModulo(void)
817{
818 RTTestSub(g_hTest, "RTBigNumModulo");
819
820 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
821 {
822 RTBIGNUM Result;
823 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
824 RTBIGNUM Tmp;
825 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Tmp, fFlags), VINF_SUCCESS);
826
827 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
828 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
829
830 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
831 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
832
833 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Minus1, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
834 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargeNegative, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
835 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargePositive, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
836
837 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Four, &g_Two), VINF_SUCCESS);
838 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
839
840 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Three, &g_Two), VINF_SUCCESS);
841 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
842
843 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Ten, &g_Two), VINF_SUCCESS);
844 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
845
846 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
847 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
848
849 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargePositiveMinus1, &g_LargePositive), VINF_SUCCESS);
850 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositiveMinus1) == 0);
851
852 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositiveMinus1, &g_LargePositive), VINF_SUCCESS);
853 RTTESTI_CHECK_RC(RTBigNumAdd(&Tmp, &g_LargePositive, &Result), VINF_SUCCESS);
854 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &Tmp, &g_LargePositiveMinus1), VINF_SUCCESS);
855 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
856 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &Tmp, &g_LargePositive), VINF_SUCCESS);
857 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositiveMinus1) == 0);
858
859 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargeNegative, &g_LargeNegativePluss1), VINF_SUCCESS);
860 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
861
862 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
863 }
864}
865
866
867static void testExponentiation(void)
868{
869 RTTestSub(g_hTest, "RTBigNumExponentiate");
870
871 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
872 {
873 RTBIGNUM Result;
874 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
875 RTBIGNUM Result2;
876 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
877
878 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_One, &g_One), VINF_SUCCESS);
879 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
880
881 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_One), VINF_SUCCESS);
882 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
883
884 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_Two), VINF_SUCCESS);
885 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 4) == 0);
886
887 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_Ten), VINF_SUCCESS);
888 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1024) == 0);
889
890 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Five, &g_Five), VINF_SUCCESS);
891 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3125) == 0);
892
893 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Five, &g_Ten), VINF_SUCCESS);
894 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 9765625) == 0);
895
896 static struct
897 {
898 const char *pszBase, *pszExponent, *pszResult;
899 } s_aTests[] =
900 {
901 {
902 "180DB4284A119D6133AE4BB0C27C27D1", /*^*/ "3A", /* = */
903 "04546412B9E39476F10009F62608F614774C5AE475482434F138C3EA976583ECE09E58F1F03CE41F821A1D5DA59B69D031290B0AC7F7D5058E3AFA2CA3DAA7261D1620CA"
904 "D050576C0AFDF51ADBFCB9073B9D8324E816EA6BE4648DF68092F6617ED609045E6BE9D5410AE2CFF725832414E67656233F4DFA952461D321282426D50E2AF524D779EC"
905 "0744547E8A4F0768C2C49AF3A5A89D129430CA58456BE4534BC53C67523506C7A8B5770D88CF28B6B3EEBE73F3EA71BA2CE27C4C89BE0D699922B1A1EB20143CB0830A43"
906 "D864DDFFF026BA781614C2D55F3EDEA7257B93A0F40824E57D6EDFCFFB4611C316374D0D15698E6584851F1898DCAE75FC4D180908763DDB2FF93766EF144D091274AFE5"
907 "6980A1F4F574D577DAD833EA9486A4B499BFCA9C08225D7BDB2C632B4D9B53EF51C02ED419F22657D626064BCC2B083CD664E1A8D68F82F33233A833AC98AA0282B8B88D"
908 "A430CF2E581A1C7C4A1D646CA42760ED10C398F7C032A94D53964E6885B5C1CA884EC15081D4C010978627C85767FEC6F93364044EA86567F9610ABFB837808CC995FB5F"
909 "710B21CE198E0D4AD9F73C3BD56CB9965C85C790BF3F4B326B5245BFA81783126217BF80687C4A8AA3AE80969A4407191B4F90E71A0ABCCB5FEDD40477CE9D10FBAEF103"
910 "8457AB19BD793CECDFF8B29A96F12F590BFED544E08F834A44DEEF461281C40024EFE9388689AAC69BCBAB3D06434172D9319F30754756E1CF77B300679215BEBD27FC20"
911 "A2F1D2029BC767D4894A5F7B21BD784CD1DD4F41697839969CB6D2AA1E0AFA5D3D644A792586F681EB36475CAE59EB457E55D6AC2E286E196BFAC000C7389A96C514552D"
912 "5D9D3DD962F72DAE4A7575A9A67856646239560A39E50826BB2523598C8F8FF0EC8D09618378E9F362A8FBFE842B55CD1855A95D8A5E93B8B91D31EB8FBBF57113F06171"
913 "BB69B81C4240EC4C7D1AC67EA1CE4CEBEE71828917EC1CF500E1AD2F09535F5498CD6E613383810A840A265AED5DD20AE58FFF2D0DEB8EF99FA494B22714F520E8E8B684"
914 "5E8521966A7B1699236998A730FDF9F049CE2A4EA44D1EBC3B9754908848540D0DEE64A6D60E2BFBC3362B659C10543BDC20C1BAD3D68B173442C100C2C366CB885E8490"
915 "EDB977E49E9D51D4427B73B3B999AF4BA17685387182C3918D20808197A2E3FCDD0F66ECDEC05542C23A08B94C83BDF93606A49E9A0645B002CFCA1EAE1917BEED0D6542"
916 "9A0EF00E5FB5F70D61C8C4DF1F1E9DA58188A221"
917 },
918 {
919 "03", /*^*/ "164b", /* = */
920 "29ABEC229C2B15C41573F8608D4DCD2DADAACA94CA3C40B42FFAD32D6202E228E16F61E050FF97EC5D45F24A4EB057C2D1A5DA72DFC5944E6941DBEDDE70EF56702BEC35"
921 "A3150EFE84E87185E3CBAB1D73F434EB820E41298BDD4F3941230DFFD8DFF1D2E2F3C5D0CB5088505B9C78507A81AAD8073C28B8FA70771C3E04110344328C6B3F38E55A"
922 "32B009F4DDA1813232C3FF422DF4E4D12545C803C63D0BE67E2E773B2BAC41CC69D895787B217D7BE9CE80BD4B500AE630AA21B50A06E0A74953F8011E9F23863CA79885"
923 "35D5FF0214DBD9B25756BE3D43008A15C018348E6A7C3355F4BECF37595BD530E5AC1AD3B14182862E47AD002097465F6B78F435B0D6365E18490567F508CD3CAAAD340A"
924 "E76A218FE8B517F923FE9CCDE61CB35409590CDBC606D89BA33B32A3862DEE7AB99DFBE103D02D2BED6D418B949E6B3C51CAB8AB5BE93AA104FA10D3A02D4CAD6700CD0F"
925 "83922EAAB18705915198DE51C1C562984E2B7571F36A4D756C459B61E0A4B7DE268A74E807311273DD51C2863771AB72504044C870E2498F13BF1DE92C13D93008E304D2"
926 "879C5D8A646DB5BF7BC64D96BB9E2FBA2EA6BF55CD825ABD995762F661C327133BE01F9A9F298CA096B3CE61CBBD8047A003870B218AC505D72ED6C7BF3B37BE5877B6A1"
927 "606A713EE86509C99B2A3627FD74AE7E81FE7F69C34B40E01A6F8B18A328E0F9D18A7911E5645331540538AA76B6D5D591F14313D730CFE30728089A245EE91058748F0C"
928 "E3E6CE4DE51D23E233BFF9007E0065AEBAA3FB0D0FACE62A4757FE1C9C7075E2214071197D5074C92AF1E6D853F7DE782F32F1E40507CB981A1C10AC6B1C23AC46C07EF1"
929 "EDE857C444902B936771DF75E0EE6C2CB3F0F9DBB387BAD0658E98F42A7338DE45E2F1B012B530FFD66861F74137C041D7558408A4A23B83FBDDE494381D9F9FF0326D44"
930 "302F75DE68B91A54CFF6E3C2821D09F2664CA74783C29AF98E2F1D3D84CAC49EAE55BABE3D2CBE8833D50517109E19CB5C63D1DE26E308ACC213D1CBCCF7C3AAE05B06D9"
931 "909AB0A1AEFD02A193CFADC7F724D377E1F4E78DC21012BE26D910548CDF55B0AB9CB64756045FF48C3B858E954553267C4087EC5A9C860CFA56CF5CFBB442BDDA298230"
932 "D6C000A6A6010D87FB4C3859C3AFAF15C37BCE03EBC392E8149056C489508841110060A991F1EEAF1E7CCF0B279AB2B35F3DAC0FAB4F4A107794E67D305E6D61A27C8FEB"
933 "DEA00C3334C888B2092E740DD3EFF7A69F06CE12EF511126EB23D80902D1D54BF4AEE04DF9457D59E8859AA83D6229481E1B1BC7C3ED96F6F7C1CEEF7B904268FD00BE51"
934 "1EF69692D593F8A9F7CCC053C343306940A4054A55DBA94D95FF6D02B7A73E110C2DBE6CA29C01B5921420B5BC9C92DAA9D82003829C6AE772FF12135C2E138C6725DC47"
935 "7938F3062264575EBBB1CBB359E496DD7A38AE0E33D1B1D9C16BDD87E6DE44DFB832286AE01D00AA14B423DBF7ECCC34A0A06A249707B75C2BA931D7F4F513FDF0F6E516"
936 "345B8DA85FEFD218B390828AECADF0C47916FAF44CB29010B0BB2BBA8E120B6DAFB2CC90B9D1B8659C2AFB"
937 }
938 };
939 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
940 {
941 RTBIGNUM Base, Exponent, Expected;
942 if ( testHexStringToNum(&Base, s_aTests[i].pszBase, RTBIGNUMINIT_F_UNSIGNED | fFlags)
943 && testHexStringToNum(&Exponent, s_aTests[i].pszExponent, RTBIGNUMINIT_F_UNSIGNED | fFlags)
944 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
945 {
946 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &Base, &Exponent), VINF_SUCCESS);
947 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
948 RTTESTI_CHECK_RC(RTBigNumDestroy(&Base), VINF_SUCCESS);
949 RTTESTI_CHECK_RC(RTBigNumDestroy(&Exponent), VINF_SUCCESS);
950 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
951 }
952 }
953 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
954 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
955 }
956}
957
958
959static void testModExp(void)
960{
961 RTTestSub(g_hTest, "RTBigNumModExp");
962 RTBIGNUM Result;
963
964 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
965 {
966 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
967
968 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_One, &g_One, &g_One), VINF_SUCCESS);
969 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
970 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_One, &g_One), VINF_SUCCESS);
971 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
972 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_LargePositive, &g_One), VINF_SUCCESS);
973 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
974
975 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_One, &g_Zero, &g_Five), VINF_SUCCESS);
976 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
977 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_Five), VINF_SUCCESS);
978 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
979 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_One), VINF_SUCCESS);
980 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
981 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_LargePositive), VINF_SUCCESS);
982 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
983
984 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Zero, &g_Zero, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
985 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
986 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_LargePositive, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
987
988 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Two, &g_Four, &g_Five), VINF_SUCCESS);
989 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
990
991 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Two, &g_Four, &g_Three), VINF_SUCCESS);
992 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
993
994 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Three, &g_Three), VINF_SUCCESS);
995 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
996
997 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Three, &g_Five), VINF_SUCCESS);
998 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
999
1000 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Five, &g_Five), VINF_SUCCESS);
1001 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3) == 0);
1002
1003 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Five, &g_Four), VINF_SUCCESS);
1004 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3) == 0);
1005
1006#if 0
1007 static struct
1008 {
1009 const char *pszBase, *pszExponent, *pszModulus, *pszResult;
1010 } s_aTests[] =
1011 {
1012 {
1013 "180DB4284A119D6133AE4BB0C27C27D1", /*^*/ "3A", /*mod */ " ", /* = */
1014 },
1015 };
1016 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1017 {
1018 RTBIGNUM Base, Exponent, Expected, Modulus;
1019 if ( testHexStringToNum(&Base, s_aTests[i].pszBase, RTBIGNUMINIT_F_UNSIGNED | fFlags)
1020 && testHexStringToNum(&Exponent, s_aTests[i].pszExponent, RTBIGNUMINIT_F_UNSIGNED | fFlags)
1021 && testHexStringToNum(&Modulus, s_aTests[i].pszModulus, RTBIGNUMINIT_F_UNSIGNED | fFlags)
1022 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
1023 {
1024 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &Base, &Exponent, &Modulus), VINF_SUCCESS);
1025 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
1026 RTTESTI_CHECK_RC(RTBigNumDestroy(&Base), VINF_SUCCESS);
1027 RTTESTI_CHECK_RC(RTBigNumDestroy(&Exponent), VINF_SUCCESS);
1028 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
1029 RTTESTI_CHECK_RC(RTBigNumDestroy(&Modulus), VINF_SUCCESS);
1030 }
1031 }
1032#endif
1033
1034 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
1035 }
1036
1037 /* Decrypt a PKCS#7 signature. */
1038 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, 0), VINF_SUCCESS);
1039 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
1040 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_SignatureDecrypted) == 0);
1041}
1042
1043
1044static void testToBytes(void)
1045{
1046 RTTestSub(g_hTest, "RTBigNumToBytes*Endian");
1047 uint8_t abBuf[sizeof(g_abLargePositive) + sizeof(g_abLargeNegative)];
1048
1049 memset(abBuf, 0xcc, sizeof(abBuf));
1050 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 1), VINF_SUCCESS);
1051 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0xcc);
1052
1053 memset(abBuf, 0xcc, sizeof(abBuf));
1054 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 2), VINF_SUCCESS);
1055 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0xcc);
1056
1057 memset(abBuf, 0xcc, sizeof(abBuf));
1058 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 3), VINF_SUCCESS);
1059 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0 && abBuf[3] == 0xcc);
1060
1061 memset(abBuf, 0xcc, sizeof(abBuf));
1062 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 4), VINF_SUCCESS);
1063 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0 && abBuf[3] == 0 && abBuf[4] == 0xcc);
1064
1065
1066 memset(abBuf, 0xcc, sizeof(abBuf));
1067 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 1), VINF_SUCCESS);
1068 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xcc && abBuf[2] == 0xcc && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
1069
1070 memset(abBuf, 0xcc, sizeof(abBuf));
1071 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 2), VINF_SUCCESS);
1072 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xcc && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
1073
1074 memset(abBuf, 0xcc, sizeof(abBuf));
1075 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 3), VINF_SUCCESS);
1076 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xff && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
1077
1078 memset(abBuf, 0xcc, sizeof(abBuf));
1079 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 4), VINF_SUCCESS);
1080 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xff && abBuf[3] == 0xff && abBuf[4] == 0xcc);
1081
1082
1083 memset(abBuf, 0xcc, sizeof(abBuf));
1084 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_LargePositive, abBuf, sizeof(g_abLargePositive)), VINF_SUCCESS);
1085 RTTESTI_CHECK(memcmp(abBuf, g_abLargePositive, sizeof(g_abLargePositive)) == 0);
1086 RTTESTI_CHECK(abBuf[sizeof(g_abLargePositive)] == 0xcc);
1087
1088 memset(abBuf, 0xcc, sizeof(abBuf));
1089 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_LargePositive, abBuf, sizeof(g_abLargePositive) -1 ), VERR_BUFFER_OVERFLOW);
1090 RTTESTI_CHECK(memcmp(abBuf, &g_abLargePositive[1], sizeof(g_abLargePositive) - 1) == 0);
1091 RTTESTI_CHECK(abBuf[sizeof(g_abLargePositive) - 1] == 0xcc);
1092}
1093
1094
1095static void testBenchmarks(bool fOnlyModExp)
1096{
1097 RTTestSub(g_hTest, "Benchmarks");
1098
1099 /*
1100 * For the modexp benchmark we decrypt a real PKCS #7 signature.
1101 */
1102 RTBIGNUM Decrypted;
1103 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Decrypted, 0 /*fFlags*/), VINF_SUCCESS);
1104 RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
1105 RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
1106
1107 RTThreadYield();
1108 int rc = VINF_SUCCESS;
1109 uint32_t cRounds = 0;
1110 uint64_t uStartTS = RTTimeNanoTS();
1111 while (cRounds < 10240)
1112 {
1113 rc |= RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod);
1114 cRounds++;
1115 }
1116 uint64_t uElapsed = RTTimeNanoTS() - uStartTS;
1117 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
1118 RTTestIValue("RTBigNumModExp", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1119
1120 if (fOnlyModExp)
1121 return;
1122
1123#if 1
1124 /* Compare with OpenSSL BN. */
1125 BN_CTX *pObnCtx = BN_CTX_new();
1126 BIGNUM *pObnPubKeyExp = BN_bin2bn(g_abPubKeyExp, sizeof(g_abPubKeyExp), NULL);
1127 BIGNUM *pObnPubKeyMod = BN_bin2bn(g_abPubKeyMod, sizeof(g_abPubKeyMod), NULL);
1128 BIGNUM *pObnSignature = BN_bin2bn(g_abSignature, sizeof(g_abSignature), NULL);
1129 BIGNUM *pObnSignatureDecrypted = BN_bin2bn(g_abSignatureDecrypted, sizeof(g_abSignatureDecrypted), NULL);
1130 BIGNUM *pObnResult = BN_new();
1131 RTTESTI_CHECK_RETV(BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx) == 1);
1132 RTTESTI_CHECK_RETV(BN_ucmp(pObnResult, pObnSignatureDecrypted) == 0);
1133
1134 rc = 1;
1135 cRounds = 0;
1136 uStartTS = RTTimeNanoTS();
1137 while (cRounds < 4096)
1138 {
1139 rc &= BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
1140 cRounds++;
1141 }
1142 uElapsed = RTTimeNanoTS() - uStartTS;
1143 RTTESTI_CHECK_RC(rc, 1);
1144 RTTestIValue("BN_mod_exp", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1145
1146 rc = 1;
1147 cRounds = 0;
1148 uStartTS = RTTimeNanoTS();
1149 while (cRounds < 4096)
1150 {
1151 rc &= BN_mod_exp_simple(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
1152 cRounds++;
1153 }
1154 uElapsed = RTTimeNanoTS() - uStartTS;
1155 RTTESTI_CHECK_RC(rc, 1);
1156 RTTestIValue("BN_mod_exp_simple", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1157#endif
1158
1159 /*
1160 * Check out the speed of modulo.
1161 */
1162 RTBIGNUM Product;
1163 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Product, 0), VINF_SUCCESS);
1164 RTTESTI_CHECK_RC_RETV(RTBigNumMultiply(&Product, &g_Signature, &g_Signature), VINF_SUCCESS);
1165 RTTESTI_CHECK_RC_RETV(RTBigNumModulo(&Decrypted, &Product, &g_PubKeyMod), VINF_SUCCESS);
1166 RTThreadYield();
1167 rc = VINF_SUCCESS;
1168 cRounds = 0;
1169 uStartTS = RTTimeNanoTS();
1170 while (cRounds < 10240)
1171 {
1172 rc |= RTBigNumModulo(&Decrypted, &Product, &g_PubKeyMod);
1173 cRounds++;
1174 }
1175 uElapsed = RTTimeNanoTS() - uStartTS;
1176 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
1177 RTTestIValue("RTBigNumModulo", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1178
1179#if 1
1180 /* Compare with OpenSSL BN. */
1181 BIGNUM *pObnProduct = BN_new();
1182 RTTESTI_CHECK_RETV(BN_mul(pObnProduct, pObnSignature, pObnSignature, pObnCtx) == 1);
1183 RTTESTI_CHECK_RETV(BN_mod(pObnResult, pObnProduct, pObnPubKeyMod, pObnCtx) == 1);
1184 rc = 1;
1185 cRounds = 0;
1186 uStartTS = RTTimeNanoTS();
1187 while (cRounds < 10240)
1188 {
1189 rc &= BN_mod(pObnResult, pObnProduct, pObnPubKeyMod, pObnCtx);
1190 cRounds++;
1191 }
1192 uElapsed = RTTimeNanoTS() - uStartTS;
1193 RTTESTI_CHECK_RC(rc, 1);
1194 RTTestIValue("BN_mod", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1195#endif
1196
1197 /*
1198 * Check out the speed of multiplication.
1199 */
1200 RTThreadYield();
1201 rc = VINF_SUCCESS;
1202 cRounds = 0;
1203 uStartTS = RTTimeNanoTS();
1204 while (cRounds < 10240)
1205 {
1206 rc |= RTBigNumMultiply(&Product, &g_Signature, &g_Signature);
1207 cRounds++;
1208 }
1209 uElapsed = RTTimeNanoTS() - uStartTS;
1210 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
1211 RTTestIValue("RTBigNumMultiply", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1212
1213#if 1
1214 /* Compare with OpenSSL BN. */
1215 rc = 1;
1216 cRounds = 0;
1217 uStartTS = RTTimeNanoTS();
1218 while (cRounds < 10240)
1219 {
1220 rc &= BN_mul(pObnProduct, pObnSignature, pObnSignature, pObnCtx);
1221 cRounds++;
1222 }
1223 uElapsed = RTTimeNanoTS() - uStartTS;
1224 RTTESTI_CHECK_RC(rc, 1);
1225 RTTestIValue("BN_mul", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1226#endif
1227
1228}
1229
1230/*
1231 * UInt128 tests (RTBigInt uses UInt128 in some cases.
1232 */
1233
1234static void testUInt128Subtraction(void)
1235{
1236 RTTestSub(g_hTest, "RTUInt128Sub");
1237
1238 static struct
1239 {
1240 RTUINT128U uMinuend, uSubtrahend, uResult;
1241 } const s_aTests[] =
1242 {
1243 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
1244 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(~0, ~0) },
1245 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) },
1246 { RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
1247 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(~0, ~0) },
1248 { RTUINT128_INIT_C(2, 9), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 9) },
1249 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(1, ~0) },
1250 {
1251 RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
1252 RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
1253 RTUINT128_INIT_C(0xfffffffffffffffe, 0x0000000000000001),
1254 },
1255 {
1256 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
1257 RTUINT128_INIT_C(0x0000000000000000, 0x00000000000fffff),
1258 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffe00001),
1259 },
1260 {
1261 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1262 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1263 RTUINT128_INIT_C(0xfffff00000000000, 0x0000000000000000)
1264 },
1265 {
1266 RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85),
1267 RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
1268 RTUINT128_INIT_C(0x0000000000000000, 0x000000221af4e338),
1269 },
1270 {
1271 RTUINT128_INIT_C(0xfd4d22a441ffa48c, 0x170739b573a9498d),
1272 RTUINT128_INIT_C(0x43459cea40782b26, 0xc8c16bb29cb3b343),
1273 RTUINT128_INIT_C(0xba0785ba01877965, 0x4e45ce02d6f5964a),
1274 },
1275 };
1276 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1277 {
1278 RTUINT128U uResult;
1279 PRTUINT128U pResult = RTUInt128Sub(&uResult, &s_aTests[i].uMinuend, &s_aTests[i].uSubtrahend);
1280 if (pResult != &uResult)
1281 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
1282 else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
1283 RTTestIFailed("test #%i failed: remainder differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1284 i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
1285
1286 uResult = s_aTests[i].uMinuend;
1287 pResult = RTUInt128AssignSub(&uResult, &s_aTests[i].uSubtrahend);
1288 RTTESTI_CHECK(pResult == &uResult);
1289 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1290 }
1291}
1292
1293
1294static void testUInt128Addition(void)
1295{
1296 RTTestSub(g_hTest, "RTUInt128Add");
1297
1298 static struct
1299 {
1300 RTUINT128U uAugend, uAddend, uResult;
1301 } const s_aTests[] =
1302 {
1303 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
1304 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
1305 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2) },
1306 { RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 3) },
1307 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 3) },
1308 { RTUINT128_INIT_C(2, 9), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(4, 9) },
1309 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(2, 3) },
1310 {
1311 RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
1312 RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
1313 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1314 },
1315 {
1316 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
1317 RTUINT128_INIT_C(0x0000000000000000, 0x00000000000ffeff),
1318 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffffffeff),
1319 },
1320 {
1321 RTUINT128_INIT_C(0xefffffffffffffff, 0xfffffffffff00000),
1322 RTUINT128_INIT_C(0x0000000000000000, 0x00000000001fffff),
1323 RTUINT128_INIT_C(0xf000000000000000, 0x00000000000fffff),
1324 },
1325 {
1326 RTUINT128_INIT_C(0xeeeeeeeeeeeeeeee, 0xeeeeeeeeeee00000),
1327 RTUINT128_INIT_C(0x0111111111111111, 0x11111111112fffff),
1328 RTUINT128_INIT_C(0xf000000000000000, 0x00000000000fffff),
1329 },
1330 {
1331 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1332 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1333 RTUINT128_INIT_C(0x00000fffffffffff, 0xfffffffffffffffe)
1334 },
1335 {
1336 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1337 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1338 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffffffffe)
1339 },
1340 {
1341 RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85),
1342 RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
1343 RTUINT128_INIT_C(0x0000000000000000, 0x000000281edd19d2),
1344 },
1345 {
1346 RTUINT128_INIT_C(0xfd4d22a441ffa48c, 0x170739b573a9498d),
1347 RTUINT128_INIT_C(0x43459cea40782b26, 0xc8c16bb29cb3b343),
1348 RTUINT128_INIT_C(0x4092bf8e8277cfb2, 0xdfc8a568105cfcd0),
1349 },
1350 };
1351 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1352 {
1353 RTUINT128U uResult;
1354 PRTUINT128U pResult = RTUInt128Add(&uResult, &s_aTests[i].uAugend, &s_aTests[i].uAddend);
1355 if (pResult != &uResult)
1356 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
1357 else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
1358 RTTestIFailed("test #%i failed: result differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1359 i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
1360
1361 uResult = s_aTests[i].uAugend;
1362 pResult = RTUInt128AssignAdd(&uResult, &s_aTests[i].uAddend);
1363 RTTESTI_CHECK(pResult == &uResult);
1364 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1365
1366 if (s_aTests[i].uAddend.s.Hi == 0)
1367 {
1368 pResult = RTUInt128AddU64(&uResult, &s_aTests[i].uAugend, s_aTests[i].uAddend.s.Lo);
1369 RTTESTI_CHECK(pResult == &uResult);
1370 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1371
1372 uResult = s_aTests[i].uAugend;
1373 pResult = RTUInt128AssignAddU64(&uResult, s_aTests[i].uAddend.s.Lo);
1374 RTTESTI_CHECK(pResult == &uResult);
1375 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1376 }
1377
1378 if (s_aTests[i].uAugend.s.Hi == 0)
1379 {
1380 pResult = RTUInt128AddU64(&uResult, &s_aTests[i].uAddend, s_aTests[i].uAugend.s.Lo);
1381 RTTESTI_CHECK(pResult == &uResult);
1382 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1383
1384 uResult = s_aTests[i].uAddend;
1385 pResult = RTUInt128AssignAddU64(&uResult, s_aTests[i].uAugend.s.Lo);
1386 RTTESTI_CHECK(pResult == &uResult);
1387 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1388 }
1389 }
1390}
1391
1392static void testUInt128Multiplication(void)
1393{
1394 RTTestSub(g_hTest, "RTUInt128Mul");
1395
1396 static struct
1397 {
1398 RTUINT128U uFactor1, uFactor2, uResult;
1399 } const s_aTests[] =
1400 {
1401 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) },
1402 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
1403 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
1404 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 2) },
1405 { RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 0) },
1406 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(4, 2) },
1407 {
1408 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1409 RTUINT128_INIT_C(0, 2),
1410 RTUINT128_INIT_C(0x2222222222222222, 0x2222222222222222)
1411 },
1412 {
1413 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1414 RTUINT128_INIT_C(0, 0xf),
1415 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff)
1416 },
1417 {
1418 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1419 RTUINT128_INIT_C(0, 0x30000),
1420 RTUINT128_INIT_C(0x3333333333333333, 0x3333333333330000)
1421 },
1422 {
1423 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1424 RTUINT128_INIT_C(0, 0x30000000),
1425 RTUINT128_INIT_C(0x3333333333333333, 0x3333333330000000)
1426 },
1427 {
1428 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1429 RTUINT128_INIT_C(0, 0x3000000000000),
1430 RTUINT128_INIT_C(0x3333333333333333, 0x3333000000000000)
1431 },
1432 {
1433 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1434 RTUINT128_INIT_C(0x0000000000000003, 0x0000000000000000),
1435 RTUINT128_INIT_C(0x3333333333333333, 0x0000000000000000)
1436 },
1437 {
1438 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1439 RTUINT128_INIT_C(0x0000000300000000, 0x0000000000000000),
1440 RTUINT128_INIT_C(0x3333333300000000, 0x0000000000000000)
1441 },
1442 {
1443 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1444 RTUINT128_INIT_C(0x0003000000000000, 0x0000000000000000),
1445 RTUINT128_INIT_C(0x3333000000000000, 0x0000000000000000)
1446 },
1447 {
1448 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1449 RTUINT128_INIT_C(0x3000000000000000, 0x0000000000000000),
1450 RTUINT128_INIT_C(0x3000000000000000, 0x0000000000000000)
1451 },
1452 {
1453 RTUINT128_INIT_C(0x0000000000000000, 0x6816816816816817),
1454 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000a0280a),
1455 RTUINT128_INIT_C(0x0000000000411e58, 0x7627627627b1a8e6)
1456 },
1457 };
1458 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1459 {
1460 RTUINT128U uResult;
1461 PRTUINT128U pResult = RTUInt128Mul(&uResult, &s_aTests[i].uFactor1, &s_aTests[i].uFactor2);
1462 if (pResult != &uResult)
1463 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
1464 else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
1465 RTTestIFailed("test #%i failed: \nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1466 i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
1467
1468 if (s_aTests[i].uFactor2.s.Hi == 0)
1469 {
1470 pResult = RTUInt128MulByU64(&uResult, &s_aTests[i].uFactor1, s_aTests[i].uFactor2.s.Lo);
1471 RTTESTI_CHECK(pResult == &uResult);
1472 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1473 }
1474
1475 if (s_aTests[i].uFactor1.s.Hi == 0)
1476 {
1477 pResult = RTUInt128MulByU64(&uResult, &s_aTests[i].uFactor2, s_aTests[i].uFactor1.s.Lo);
1478 RTTESTI_CHECK(pResult == &uResult);
1479 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1480 }
1481
1482 uResult = s_aTests[i].uFactor1;
1483 pResult = RTUInt128AssignMul(&uResult, &s_aTests[i].uFactor2);
1484 RTTESTI_CHECK(pResult == &uResult);
1485 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1486 }
1487}
1488
1489
1490#if 0 /* Java program for generating testUInt128Division test data. */
1491import java.math.BigInteger;
1492import java.lang.System;
1493import java.lang.Integer;
1494import java.util.Random;
1495import java.security.SecureRandom;
1496
1497class uint128divtestgen
1498{
1499
1500public static String format(BigInteger BigNum)
1501{
1502 String str = BigNum.toString(16);
1503 while (str.length() < 32)
1504 str = "0" + str;
1505 return "RTUINT128_INIT_C(0x" + str.substring(0, 16) + ", 0x" + str.substring(16) + ")";
1506}
1507
1508public static void main(String args[])
1509{
1510 Random Rnd = new SecureRandom();
1511
1512 int cDivisorLarger = 0;
1513 for (int i = 0; i < 4096; i++)
1514 {
1515 int cDividendBits = Rnd.nextInt(127) + 1;
1516 int cDivisorBits = i < 9 ? cDividendBits : Rnd.nextInt(127) + 1;
1517 if (cDivisorBits > cDividendBits)
1518 {
1519 if (cDivisorLarger > i / 16)
1520 cDividendBits = 128 - Rnd.nextInt(16);
1521 else
1522 cDivisorLarger++;
1523 }
1524
1525 BigInteger Dividend = new BigInteger(cDividendBits, Rnd);
1526 BigInteger Divisor = new BigInteger(cDivisorBits, Rnd);
1527 while (Divisor.compareTo(BigInteger.ZERO) == 0) {
1528 cDivisorBits++;
1529 Divisor = new BigInteger(cDivisorBits, Rnd);
1530 }
1531
1532 BigInteger[] Result = Dividend.divideAndRemainder(Divisor);
1533
1534 System.out.println(" { /* i=" + Integer.toString(i) + "; " + Integer.toString(cDividendBits) + " / " + Integer.toString(cDivisorBits) + " */");
1535 System.out.println(" " + format(Dividend) + ", " + format(Divisor) + ",");
1536 System.out.println(" " + format(Result[0]) + ", " + format(Result[1]) + "");
1537 System.out.println(" },");
1538 }
1539}
1540}
1541#endif
1542
1543static void testUInt128Division(void)
1544{
1545 RTTestSub(g_hTest, "RTUInt128DivMod");
1546
1547 static struct
1548 {
1549 RTUINT128U uDividend, uDivisor, uQuotient, uRemainder;
1550 } const s_aTests[] =
1551 {
1552 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) }, /* #0 */
1553 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) }, /* #1 */
1554 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1) }, /* #2 */
1555 { RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) }, /* #3 */
1556 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(1, 0), RTUINT128_INIT_C(0, 1) }, /* #4 */
1557 { /* #5 */
1558 RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
1559 RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
1560 RTUINT128_INIT_C(0x0000000000000001, 0x0000000000000000),
1561 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000000000)
1562 },
1563 { /* #6 */
1564 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
1565 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1566 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000100000),
1567 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000000000)
1568 },
1569 { /* #7 */
1570 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1571 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1572 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000100000),
1573 RTUINT128_INIT_C(0x0000000000000000, 0x00000000000fffff)
1574 },
1575 { /* #8 */
1576 RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85), RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
1577 RTUINT128_INIT_C(0x0000000000000000, 0x000000000000000c), RTUINT128_INIT_C(0x0000000000000000, 0x000000010577b6e9)
1578 },
1579
1580#include "tstRTBigNum-uint128-div-test-data.h"
1581 };
1582 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1583 {
1584 RTUINT128U uResultQ, uResultR;
1585 PRTUINT128U pResultQ = RTUInt128DivRem(&uResultQ, &uResultR, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
1586 if (pResultQ != &uResultQ)
1587 RTTestIFailed("test #%i returns %p instead of %p", i, pResultQ, &uResultQ);
1588 else if ( RTUInt128IsNotEqual(&uResultQ, &s_aTests[i].uQuotient)
1589 && RTUInt128IsNotEqual(&uResultR, &s_aTests[i].uRemainder))
1590 {
1591 RTTestIFailed("test #%i failed on both counts", i);
1592 }
1593 else if (RTUInt128IsNotEqual(&uResultQ, &s_aTests[i].uQuotient))
1594 RTTestIFailed("test #%i failed: quotient differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1595 i, s_aTests[i].uQuotient.s.Hi, s_aTests[i].uQuotient.s.Lo, uResultQ.s.Hi, uResultQ.s.Lo );
1596 else if (RTUInt128IsNotEqual(&uResultR, &s_aTests[i].uRemainder))
1597 RTTestIFailed("test #%i failed: remainder differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1598 i, s_aTests[i].uRemainder.s.Hi, s_aTests[i].uRemainder.s.Lo, uResultR.s.Hi, uResultR.s.Lo );
1599
1600 pResultQ = RTUInt128Div(&uResultQ, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
1601 RTTESTI_CHECK(pResultQ == &uResultQ);
1602 RTTESTI_CHECK(RTUInt128IsEqual(&uResultQ, &s_aTests[i].uQuotient));
1603
1604 uResultQ = s_aTests[i].uDividend;
1605 pResultQ = RTUInt128AssignDiv(&uResultQ, &s_aTests[i].uDivisor);
1606 RTTESTI_CHECK(pResultQ == &uResultQ);
1607 RTTESTI_CHECK(RTUInt128IsEqual(&uResultQ, &s_aTests[i].uQuotient));
1608
1609
1610 PRTUINT128U pResultR = RTUInt128Mod(&uResultR, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
1611 RTTESTI_CHECK(pResultR == &uResultR);
1612 RTTESTI_CHECK(RTUInt128IsEqual(&uResultR, &s_aTests[i].uRemainder));
1613
1614 uResultR = s_aTests[i].uDividend;
1615 pResultR = RTUInt128AssignMod(&uResultR, &s_aTests[i].uDivisor);
1616 RTTESTI_CHECK(pResultR == &uResultR);
1617 RTTESTI_CHECK(RTUInt128IsEqual(&uResultR, &s_aTests[i].uRemainder));
1618 }
1619}
1620
1621
1622static void testUInt64Division(void)
1623{
1624 /*
1625 * Check the results against native code.
1626 */
1627 RTTestSub(g_hTest, "RTUInt64DivRem");
1628 for (uint32_t i = 0; i < _1M / 2; i++)
1629 {
1630 uint64_t const uDividend = RTRandU64Ex(0, UINT64_MAX);
1631 uint64_t const uDivisor = RTRandU64Ex(1, UINT64_MAX);
1632 uint64_t const uQuotient = uDividend / uDivisor;
1633 uint64_t const uRemainder = uDividend % uDivisor;
1634 RTUINT64U Dividend = { uDividend };
1635 RTUINT64U Divisor = { uDivisor };
1636 RTUINT64U Quotient = { UINT64_MAX };
1637 RTUINT64U Remainder = { UINT64_MAX };
1638 RTTESTI_CHECK(RTUInt64DivRem(&Quotient, &Remainder, &Dividend, &Divisor) == &Quotient);
1639 if (uQuotient != Quotient.u || uRemainder != Remainder.u)
1640 RTTestIFailed("%RU64 / %RU64 -> %RU64 rem %RU64, expected %RU64 rem %RU64",
1641 uDividend, uDivisor, Quotient.u, Remainder.u, uQuotient, uRemainder);
1642 }
1643}
1644
1645
1646static void testUInt32Division(void)
1647{
1648 /*
1649 * Check the results against native code.
1650 */
1651 RTTestSub(g_hTest, "RTUInt32DivRem");
1652 for (uint32_t i = 0; i < _1M / 2; i++)
1653 {
1654 uint32_t const uDividend = RTRandU32Ex(0, UINT32_MAX);
1655 uint32_t const uDivisor = RTRandU32Ex(1, UINT32_MAX);
1656 uint32_t const uQuotient = uDividend / uDivisor;
1657 uint32_t const uRemainder = uDividend % uDivisor;
1658 RTUINT32U Dividend = { uDividend };
1659 RTUINT32U Divisor = { uDivisor };
1660 RTUINT32U Quotient = { UINT32_MAX };
1661 RTUINT32U Remainder = { UINT32_MAX };
1662 RTTESTI_CHECK(RTUInt32DivRem(&Quotient, &Remainder, &Dividend, &Divisor) == &Quotient);
1663 if (uQuotient != Quotient.u || uRemainder != Remainder.u)
1664 RTTestIFailed("%u / %u -> %u rem %u, expected %u rem %u",
1665 uDividend, uDivisor, Quotient.u, Remainder.u, uQuotient, uRemainder);
1666 }
1667}
1668
1669
1670
1671int main(int argc, char **argv)
1672{
1673 RT_NOREF_PV(argv);
1674
1675 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTBigNum", &g_hTest);
1676 if (rcExit != RTEXITCODE_SUCCESS)
1677 return rcExit;
1678 RTTestBanner(g_hTest);
1679
1680 /* Init fixed integers. */
1681 RTTestSub(g_hTest, "RTBigNumInit");
1682 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositive, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1683 g_abLargePositive, sizeof(g_abLargePositive)), VINF_SUCCESS);
1684 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositive2, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1685 g_abLargePositive, sizeof(g_abLargePositive) - 11), VINF_SUCCESS);
1686 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositiveMinus1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1687 g_abLargePositiveMinus1, sizeof(g_abLargePositiveMinus1)), VINF_SUCCESS);
1688 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegative, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1689 g_abLargeNegative, sizeof(g_abLargeNegative)), VINF_SUCCESS);
1690 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegative2, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1691 g_abLargeNegative, sizeof(g_abLargeNegative) - 9), VINF_SUCCESS);
1692 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegativePluss1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1693 g_abLargeNegativePluss1, sizeof(g_abLargeNegativePluss1)), VINF_SUCCESS);
1694 RTTESTI_CHECK_RC(RTBigNumInit(&g_64BitPositive1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1695 g_ab64BitPositive1, sizeof(g_ab64BitPositive1)), VINF_SUCCESS);
1696
1697 RTTESTI_CHECK_RC(RTBigNumInitZero(&g_Zero, 0), VINF_SUCCESS);
1698 RTTESTI_CHECK_RC(RTBigNumInit(&g_One, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x01", 1), VINF_SUCCESS);
1699 RTTESTI_CHECK_RC(RTBigNumInit(&g_Two, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x02", 1), VINF_SUCCESS);
1700 RTTESTI_CHECK_RC(RTBigNumInit(&g_Three, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x03", 1), VINF_SUCCESS);
1701 RTTESTI_CHECK_RC(RTBigNumInit(&g_Four, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x04", 1), VINF_SUCCESS);
1702 RTTESTI_CHECK_RC(RTBigNumInit(&g_Five, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x05", 1), VINF_SUCCESS);
1703 RTTESTI_CHECK_RC(RTBigNumInit(&g_Ten, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x0a", 1), VINF_SUCCESS);
1704 RTTESTI_CHECK_RC(RTBigNumInit(&g_FourtyTwo, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x2a", 1), VINF_SUCCESS);
1705
1706 RTTESTI_CHECK_RC(RTBigNumInit(&g_Minus1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1707 g_abMinus1, sizeof(g_abMinus1)), VINF_SUCCESS);
1708
1709 RTTESTI_CHECK_RC(RTBigNumInit(&g_PubKeyExp, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1710 g_abPubKeyExp, sizeof(g_abPubKeyExp)), VINF_SUCCESS);
1711 RTTESTI_CHECK_RC(RTBigNumInit(&g_PubKeyMod, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1712 g_abPubKeyMod, sizeof(g_abPubKeyMod)), VINF_SUCCESS);
1713 RTTESTI_CHECK_RC(RTBigNumInit(&g_Signature, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1714 g_abSignature, sizeof(g_abSignature)), VINF_SUCCESS);
1715 RTTESTI_CHECK_RC(RTBigNumInit(&g_SignatureDecrypted, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1716 g_abSignatureDecrypted, sizeof(g_abSignatureDecrypted)), VINF_SUCCESS);
1717 testMoreInit();
1718
1719 if (RTTestIErrorCount() == 0)
1720 {
1721 if (argc != 2)
1722 {
1723 /* Test UInt128 first as it may be used by RTBigInt. */
1724 testUInt128Multiplication();
1725 testUInt128Division();
1726 testUInt128Subtraction();
1727 testUInt128Addition();
1728
1729 /* Test UInt32 and UInt64 division as it's used by the watcom support code (BIOS, ValKit, OS/2 GAs). */
1730 testUInt32Division();
1731 testUInt64Division();
1732
1733 /* Test the RTBigInt operations. */
1734 testCompare();
1735 testSubtraction();
1736 testAddition();
1737 testShift();
1738 testMultiplication();
1739 testDivision();
1740 testModulo();
1741 testExponentiation();
1742 testModExp();
1743 testToBytes();
1744 }
1745
1746 /* Benchmarks */
1747 testBenchmarks(argc == 2);
1748
1749 /* Cleanups. */
1750 RTTestSub(g_hTest, "RTBigNumDestroy");
1751 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargePositive), VINF_SUCCESS);
1752 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargePositive2), VINF_SUCCESS);
1753 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargeNegative), VINF_SUCCESS);
1754 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargeNegative2), VINF_SUCCESS);
1755 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_Zero), VINF_SUCCESS);
1756 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_64BitPositive1), VINF_SUCCESS);
1757 }
1758
1759 return RTTestSummaryAndDestroy(g_hTest);
1760}
1761
Note: See TracBrowser for help on using the repository browser.

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