VirtualBox

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

Last change on this file since 103075 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

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