VirtualBox

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

Last change on this file since 53428 was 52335, checked in by vboxsync, 10 years ago

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

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