VirtualBox

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

Last change on this file since 76553 was 76553, checked in by vboxsync, 5 years ago

scm --update-copyright-year

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

© 2023 Oracle
ContactPrivacy policyTerms of Use