VirtualBox

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

Last change on this file since 67979 was 65009, checked in by vboxsync, 8 years ago

tstRTBigNum: Another number.

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