VirtualBox

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

Last change on this file since 78338 was 77736, checked in by vboxsync, 6 years ago

tstRTBigNum: Some memory leak fixes (to reduce the noise and being able to concentrate on the real leaks)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 86.0 KB
Line 
1/* $Id: tstRTBigNum.cpp 77736 2019-03-16 22:13:39Z 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(&Tmp), VINF_SUCCESS);
864 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
865 }
866}
867
868
869static void testExponentiation(void)
870{
871 RTTestSub(g_hTest, "RTBigNumExponentiate");
872
873 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
874 {
875 RTBIGNUM Result;
876 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
877 RTBIGNUM Result2;
878 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
879
880 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_One, &g_One), VINF_SUCCESS);
881 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
882
883 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_One), VINF_SUCCESS);
884 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
885
886 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_Two), VINF_SUCCESS);
887 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 4) == 0);
888
889 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_Ten), VINF_SUCCESS);
890 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1024) == 0);
891
892 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Five, &g_Five), VINF_SUCCESS);
893 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3125) == 0);
894
895 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Five, &g_Ten), VINF_SUCCESS);
896 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 9765625) == 0);
897
898 static struct
899 {
900 const char *pszBase, *pszExponent, *pszResult;
901 } s_aTests[] =
902 {
903 {
904 "180DB4284A119D6133AE4BB0C27C27D1", /*^*/ "3A", /* = */
905 "04546412B9E39476F10009F62608F614774C5AE475482434F138C3EA976583ECE09E58F1F03CE41F821A1D5DA59B69D031290B0AC7F7D5058E3AFA2CA3DAA7261D1620CA"
906 "D050576C0AFDF51ADBFCB9073B9D8324E816EA6BE4648DF68092F6617ED609045E6BE9D5410AE2CFF725832414E67656233F4DFA952461D321282426D50E2AF524D779EC"
907 "0744547E8A4F0768C2C49AF3A5A89D129430CA58456BE4534BC53C67523506C7A8B5770D88CF28B6B3EEBE73F3EA71BA2CE27C4C89BE0D699922B1A1EB20143CB0830A43"
908 "D864DDFFF026BA781614C2D55F3EDEA7257B93A0F40824E57D6EDFCFFB4611C316374D0D15698E6584851F1898DCAE75FC4D180908763DDB2FF93766EF144D091274AFE5"
909 "6980A1F4F574D577DAD833EA9486A4B499BFCA9C08225D7BDB2C632B4D9B53EF51C02ED419F22657D626064BCC2B083CD664E1A8D68F82F33233A833AC98AA0282B8B88D"
910 "A430CF2E581A1C7C4A1D646CA42760ED10C398F7C032A94D53964E6885B5C1CA884EC15081D4C010978627C85767FEC6F93364044EA86567F9610ABFB837808CC995FB5F"
911 "710B21CE198E0D4AD9F73C3BD56CB9965C85C790BF3F4B326B5245BFA81783126217BF80687C4A8AA3AE80969A4407191B4F90E71A0ABCCB5FEDD40477CE9D10FBAEF103"
912 "8457AB19BD793CECDFF8B29A96F12F590BFED544E08F834A44DEEF461281C40024EFE9388689AAC69BCBAB3D06434172D9319F30754756E1CF77B300679215BEBD27FC20"
913 "A2F1D2029BC767D4894A5F7B21BD784CD1DD4F41697839969CB6D2AA1E0AFA5D3D644A792586F681EB36475CAE59EB457E55D6AC2E286E196BFAC000C7389A96C514552D"
914 "5D9D3DD962F72DAE4A7575A9A67856646239560A39E50826BB2523598C8F8FF0EC8D09618378E9F362A8FBFE842B55CD1855A95D8A5E93B8B91D31EB8FBBF57113F06171"
915 "BB69B81C4240EC4C7D1AC67EA1CE4CEBEE71828917EC1CF500E1AD2F09535F5498CD6E613383810A840A265AED5DD20AE58FFF2D0DEB8EF99FA494B22714F520E8E8B684"
916 "5E8521966A7B1699236998A730FDF9F049CE2A4EA44D1EBC3B9754908848540D0DEE64A6D60E2BFBC3362B659C10543BDC20C1BAD3D68B173442C100C2C366CB885E8490"
917 "EDB977E49E9D51D4427B73B3B999AF4BA17685387182C3918D20808197A2E3FCDD0F66ECDEC05542C23A08B94C83BDF93606A49E9A0645B002CFCA1EAE1917BEED0D6542"
918 "9A0EF00E5FB5F70D61C8C4DF1F1E9DA58188A221"
919 },
920 {
921 "03", /*^*/ "164b", /* = */
922 "29ABEC229C2B15C41573F8608D4DCD2DADAACA94CA3C40B42FFAD32D6202E228E16F61E050FF97EC5D45F24A4EB057C2D1A5DA72DFC5944E6941DBEDDE70EF56702BEC35"
923 "A3150EFE84E87185E3CBAB1D73F434EB820E41298BDD4F3941230DFFD8DFF1D2E2F3C5D0CB5088505B9C78507A81AAD8073C28B8FA70771C3E04110344328C6B3F38E55A"
924 "32B009F4DDA1813232C3FF422DF4E4D12545C803C63D0BE67E2E773B2BAC41CC69D895787B217D7BE9CE80BD4B500AE630AA21B50A06E0A74953F8011E9F23863CA79885"
925 "35D5FF0214DBD9B25756BE3D43008A15C018348E6A7C3355F4BECF37595BD530E5AC1AD3B14182862E47AD002097465F6B78F435B0D6365E18490567F508CD3CAAAD340A"
926 "E76A218FE8B517F923FE9CCDE61CB35409590CDBC606D89BA33B32A3862DEE7AB99DFBE103D02D2BED6D418B949E6B3C51CAB8AB5BE93AA104FA10D3A02D4CAD6700CD0F"
927 "83922EAAB18705915198DE51C1C562984E2B7571F36A4D756C459B61E0A4B7DE268A74E807311273DD51C2863771AB72504044C870E2498F13BF1DE92C13D93008E304D2"
928 "879C5D8A646DB5BF7BC64D96BB9E2FBA2EA6BF55CD825ABD995762F661C327133BE01F9A9F298CA096B3CE61CBBD8047A003870B218AC505D72ED6C7BF3B37BE5877B6A1"
929 "606A713EE86509C99B2A3627FD74AE7E81FE7F69C34B40E01A6F8B18A328E0F9D18A7911E5645331540538AA76B6D5D591F14313D730CFE30728089A245EE91058748F0C"
930 "E3E6CE4DE51D23E233BFF9007E0065AEBAA3FB0D0FACE62A4757FE1C9C7075E2214071197D5074C92AF1E6D853F7DE782F32F1E40507CB981A1C10AC6B1C23AC46C07EF1"
931 "EDE857C444902B936771DF75E0EE6C2CB3F0F9DBB387BAD0658E98F42A7338DE45E2F1B012B530FFD66861F74137C041D7558408A4A23B83FBDDE494381D9F9FF0326D44"
932 "302F75DE68B91A54CFF6E3C2821D09F2664CA74783C29AF98E2F1D3D84CAC49EAE55BABE3D2CBE8833D50517109E19CB5C63D1DE26E308ACC213D1CBCCF7C3AAE05B06D9"
933 "909AB0A1AEFD02A193CFADC7F724D377E1F4E78DC21012BE26D910548CDF55B0AB9CB64756045FF48C3B858E954553267C4087EC5A9C860CFA56CF5CFBB442BDDA298230"
934 "D6C000A6A6010D87FB4C3859C3AFAF15C37BCE03EBC392E8149056C489508841110060A991F1EEAF1E7CCF0B279AB2B35F3DAC0FAB4F4A107794E67D305E6D61A27C8FEB"
935 "DEA00C3334C888B2092E740DD3EFF7A69F06CE12EF511126EB23D80902D1D54BF4AEE04DF9457D59E8859AA83D6229481E1B1BC7C3ED96F6F7C1CEEF7B904268FD00BE51"
936 "1EF69692D593F8A9F7CCC053C343306940A4054A55DBA94D95FF6D02B7A73E110C2DBE6CA29C01B5921420B5BC9C92DAA9D82003829C6AE772FF12135C2E138C6725DC47"
937 "7938F3062264575EBBB1CBB359E496DD7A38AE0E33D1B1D9C16BDD87E6DE44DFB832286AE01D00AA14B423DBF7ECCC34A0A06A249707B75C2BA931D7F4F513FDF0F6E516"
938 "345B8DA85FEFD218B390828AECADF0C47916FAF44CB29010B0BB2BBA8E120B6DAFB2CC90B9D1B8659C2AFB"
939 }
940 };
941 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
942 {
943 RTBIGNUM Base, Exponent, Expected;
944 if ( testHexStringToNum(&Base, s_aTests[i].pszBase, RTBIGNUMINIT_F_UNSIGNED | fFlags)
945 && testHexStringToNum(&Exponent, s_aTests[i].pszExponent, RTBIGNUMINIT_F_UNSIGNED | fFlags)
946 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
947 {
948 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &Base, &Exponent), VINF_SUCCESS);
949 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
950 RTTESTI_CHECK_RC(RTBigNumDestroy(&Base), VINF_SUCCESS);
951 RTTESTI_CHECK_RC(RTBigNumDestroy(&Exponent), VINF_SUCCESS);
952 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
953 }
954 }
955 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
956 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
957 }
958}
959
960
961static void testModExp(void)
962{
963 RTTestSub(g_hTest, "RTBigNumModExp");
964 RTBIGNUM Result;
965
966 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
967 {
968 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
969
970 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_One, &g_One, &g_One), VINF_SUCCESS);
971 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
972 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_One, &g_One), VINF_SUCCESS);
973 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
974 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_LargePositive, &g_One), VINF_SUCCESS);
975 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
976
977 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_One, &g_Zero, &g_Five), VINF_SUCCESS);
978 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
979 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_Five), VINF_SUCCESS);
980 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
981 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_One), VINF_SUCCESS);
982 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
983 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_LargePositive), VINF_SUCCESS);
984 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
985
986 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Zero, &g_Zero, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
987 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
988 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_LargePositive, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
989
990 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Two, &g_Four, &g_Five), VINF_SUCCESS);
991 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
992
993 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Two, &g_Four, &g_Three), VINF_SUCCESS);
994 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
995
996 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Three, &g_Three), VINF_SUCCESS);
997 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
998
999 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Three, &g_Five), VINF_SUCCESS);
1000 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
1001
1002 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Five, &g_Five), VINF_SUCCESS);
1003 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3) == 0);
1004
1005 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Five, &g_Four), VINF_SUCCESS);
1006 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3) == 0);
1007
1008#if 0
1009 static struct
1010 {
1011 const char *pszBase, *pszExponent, *pszModulus, *pszResult;
1012 } s_aTests[] =
1013 {
1014 {
1015 "180DB4284A119D6133AE4BB0C27C27D1", /*^*/ "3A", /*mod */ " ", /* = */
1016 },
1017 };
1018 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1019 {
1020 RTBIGNUM Base, Exponent, Expected, Modulus;
1021 if ( testHexStringToNum(&Base, s_aTests[i].pszBase, RTBIGNUMINIT_F_UNSIGNED | fFlags)
1022 && testHexStringToNum(&Exponent, s_aTests[i].pszExponent, RTBIGNUMINIT_F_UNSIGNED | fFlags)
1023 && testHexStringToNum(&Modulus, s_aTests[i].pszModulus, RTBIGNUMINIT_F_UNSIGNED | fFlags)
1024 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
1025 {
1026 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &Base, &Exponent, &Modulus), VINF_SUCCESS);
1027 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
1028 RTTESTI_CHECK_RC(RTBigNumDestroy(&Base), VINF_SUCCESS);
1029 RTTESTI_CHECK_RC(RTBigNumDestroy(&Exponent), VINF_SUCCESS);
1030 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
1031 RTTESTI_CHECK_RC(RTBigNumDestroy(&Modulus), VINF_SUCCESS);
1032 }
1033 }
1034#endif
1035
1036 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
1037 }
1038
1039 /* Decrypt a PKCS#7 signature. */
1040 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, 0), VINF_SUCCESS);
1041 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
1042 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_SignatureDecrypted) == 0);
1043 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
1044}
1045
1046
1047static void testToBytes(void)
1048{
1049 RTTestSub(g_hTest, "RTBigNumToBytes*Endian");
1050 uint8_t abBuf[sizeof(g_abLargePositive) + sizeof(g_abLargeNegative)];
1051
1052 memset(abBuf, 0xcc, sizeof(abBuf));
1053 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 1), VINF_SUCCESS);
1054 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0xcc);
1055
1056 memset(abBuf, 0xcc, sizeof(abBuf));
1057 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 2), VINF_SUCCESS);
1058 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0xcc);
1059
1060 memset(abBuf, 0xcc, sizeof(abBuf));
1061 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 3), VINF_SUCCESS);
1062 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0 && abBuf[3] == 0xcc);
1063
1064 memset(abBuf, 0xcc, sizeof(abBuf));
1065 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 4), VINF_SUCCESS);
1066 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0 && abBuf[3] == 0 && abBuf[4] == 0xcc);
1067
1068
1069 memset(abBuf, 0xcc, sizeof(abBuf));
1070 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 1), VINF_SUCCESS);
1071 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xcc && abBuf[2] == 0xcc && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
1072
1073 memset(abBuf, 0xcc, sizeof(abBuf));
1074 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 2), VINF_SUCCESS);
1075 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xcc && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
1076
1077 memset(abBuf, 0xcc, sizeof(abBuf));
1078 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 3), VINF_SUCCESS);
1079 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xff && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
1080
1081 memset(abBuf, 0xcc, sizeof(abBuf));
1082 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 4), VINF_SUCCESS);
1083 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xff && abBuf[3] == 0xff && abBuf[4] == 0xcc);
1084
1085
1086 memset(abBuf, 0xcc, sizeof(abBuf));
1087 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_LargePositive, abBuf, sizeof(g_abLargePositive)), VINF_SUCCESS);
1088 RTTESTI_CHECK(memcmp(abBuf, g_abLargePositive, sizeof(g_abLargePositive)) == 0);
1089 RTTESTI_CHECK(abBuf[sizeof(g_abLargePositive)] == 0xcc);
1090
1091 memset(abBuf, 0xcc, sizeof(abBuf));
1092 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_LargePositive, abBuf, sizeof(g_abLargePositive) -1 ), VERR_BUFFER_OVERFLOW);
1093 RTTESTI_CHECK(memcmp(abBuf, &g_abLargePositive[1], sizeof(g_abLargePositive) - 1) == 0);
1094 RTTESTI_CHECK(abBuf[sizeof(g_abLargePositive) - 1] == 0xcc);
1095}
1096
1097
1098static void testBenchmarks(bool fOnlyModExp)
1099{
1100 RTTestSub(g_hTest, "Benchmarks");
1101
1102 /*
1103 * For the modexp benchmark we decrypt a real PKCS #7 signature.
1104 */
1105 RTBIGNUM Decrypted;
1106 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Decrypted, 0 /*fFlags*/), VINF_SUCCESS);
1107 RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
1108 RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod), VINF_SUCCESS);
1109
1110 RTThreadYield();
1111 int rc = VINF_SUCCESS;
1112 uint32_t cRounds = 0;
1113 uint64_t uStartTS = RTTimeNanoTS();
1114 while (cRounds < 10240)
1115 {
1116 rc |= RTBigNumModExp(&Decrypted, &g_Signature, &g_PubKeyExp, &g_PubKeyMod);
1117 cRounds++;
1118 }
1119 uint64_t uElapsed = RTTimeNanoTS() - uStartTS;
1120 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
1121 RTTestIValue("RTBigNumModExp", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1122
1123 if (fOnlyModExp)
1124 return;
1125
1126#if 1
1127 /* Compare with OpenSSL BN. */
1128 BN_CTX *pObnCtx = BN_CTX_new();
1129 BIGNUM *pObnPubKeyExp = BN_bin2bn(g_abPubKeyExp, sizeof(g_abPubKeyExp), NULL);
1130 BIGNUM *pObnPubKeyMod = BN_bin2bn(g_abPubKeyMod, sizeof(g_abPubKeyMod), NULL);
1131 BIGNUM *pObnSignature = BN_bin2bn(g_abSignature, sizeof(g_abSignature), NULL);
1132 BIGNUM *pObnSignatureDecrypted = BN_bin2bn(g_abSignatureDecrypted, sizeof(g_abSignatureDecrypted), NULL);
1133 BIGNUM *pObnResult = BN_new();
1134 RTTESTI_CHECK_RETV(BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx) == 1);
1135 RTTESTI_CHECK_RETV(BN_ucmp(pObnResult, pObnSignatureDecrypted) == 0);
1136
1137 rc = 1;
1138 cRounds = 0;
1139 uStartTS = RTTimeNanoTS();
1140 while (cRounds < 4096)
1141 {
1142 rc &= BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
1143 cRounds++;
1144 }
1145 uElapsed = RTTimeNanoTS() - uStartTS;
1146 RTTESTI_CHECK_RC(rc, 1);
1147 RTTestIValue("BN_mod_exp", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1148
1149 rc = 1;
1150 cRounds = 0;
1151 uStartTS = RTTimeNanoTS();
1152 while (cRounds < 4096)
1153 {
1154 rc &= BN_mod_exp_simple(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
1155 cRounds++;
1156 }
1157 uElapsed = RTTimeNanoTS() - uStartTS;
1158 RTTESTI_CHECK_RC(rc, 1);
1159 RTTestIValue("BN_mod_exp_simple", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1160#endif
1161
1162 /*
1163 * Check out the speed of modulo.
1164 */
1165 RTBIGNUM Product;
1166 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Product, 0), VINF_SUCCESS);
1167 RTTESTI_CHECK_RC_RETV(RTBigNumMultiply(&Product, &g_Signature, &g_Signature), VINF_SUCCESS);
1168 RTTESTI_CHECK_RC_RETV(RTBigNumModulo(&Decrypted, &Product, &g_PubKeyMod), VINF_SUCCESS);
1169 RTThreadYield();
1170 rc = VINF_SUCCESS;
1171 cRounds = 0;
1172 uStartTS = RTTimeNanoTS();
1173 while (cRounds < 10240)
1174 {
1175 rc |= RTBigNumModulo(&Decrypted, &Product, &g_PubKeyMod);
1176 cRounds++;
1177 }
1178 uElapsed = RTTimeNanoTS() - uStartTS;
1179 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
1180 RTTestIValue("RTBigNumModulo", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1181
1182 RTBigNumDestroy(&Decrypted);
1183
1184#if 1
1185 /* Compare with OpenSSL BN. */
1186 BIGNUM *pObnProduct = BN_new();
1187 RTTESTI_CHECK_RETV(BN_mul(pObnProduct, pObnSignature, pObnSignature, pObnCtx) == 1);
1188 RTTESTI_CHECK_RETV(BN_mod(pObnResult, pObnProduct, pObnPubKeyMod, pObnCtx) == 1);
1189 rc = 1;
1190 cRounds = 0;
1191 uStartTS = RTTimeNanoTS();
1192 while (cRounds < 10240)
1193 {
1194 rc &= BN_mod(pObnResult, pObnProduct, pObnPubKeyMod, pObnCtx);
1195 cRounds++;
1196 }
1197 uElapsed = RTTimeNanoTS() - uStartTS;
1198 RTTESTI_CHECK_RC(rc, 1);
1199 RTTestIValue("BN_mod", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1200#endif
1201
1202 /*
1203 * Check out the speed of multiplication.
1204 */
1205 RTThreadYield();
1206 rc = VINF_SUCCESS;
1207 cRounds = 0;
1208 uStartTS = RTTimeNanoTS();
1209 while (cRounds < 10240)
1210 {
1211 rc |= RTBigNumMultiply(&Product, &g_Signature, &g_Signature);
1212 cRounds++;
1213 }
1214 uElapsed = RTTimeNanoTS() - uStartTS;
1215 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
1216 RTTestIValue("RTBigNumMultiply", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1217
1218 RTBigNumDestroy(&Product);
1219
1220#if 1
1221 /* Compare with OpenSSL BN. */
1222 rc = 1;
1223 cRounds = 0;
1224 uStartTS = RTTimeNanoTS();
1225 while (cRounds < 10240)
1226 {
1227 rc &= BN_mul(pObnProduct, pObnSignature, pObnSignature, pObnCtx);
1228 cRounds++;
1229 }
1230 uElapsed = RTTimeNanoTS() - uStartTS;
1231 RTTESTI_CHECK_RC(rc, 1);
1232 RTTestIValue("BN_mul", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
1233
1234 BN_free(pObnPubKeyExp);
1235 BN_free(pObnPubKeyMod);
1236 BN_free(pObnSignature);
1237 BN_free(pObnSignatureDecrypted);
1238 BN_free(pObnResult);
1239 BN_free(pObnProduct);
1240 BN_CTX_free(pObnCtx);
1241#endif
1242
1243}
1244
1245/*
1246 * UInt128 tests (RTBigInt uses UInt128 in some cases.
1247 */
1248
1249static void testUInt128Subtraction(void)
1250{
1251 RTTestSub(g_hTest, "RTUInt128Sub");
1252
1253 static struct
1254 {
1255 RTUINT128U uMinuend, uSubtrahend, uResult;
1256 } const s_aTests[] =
1257 {
1258 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
1259 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(~0, ~0) },
1260 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) },
1261 { RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
1262 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(~0, ~0) },
1263 { RTUINT128_INIT_C(2, 9), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 9) },
1264 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(1, ~0) },
1265 {
1266 RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
1267 RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
1268 RTUINT128_INIT_C(0xfffffffffffffffe, 0x0000000000000001),
1269 },
1270 {
1271 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
1272 RTUINT128_INIT_C(0x0000000000000000, 0x00000000000fffff),
1273 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffe00001),
1274 },
1275 {
1276 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1277 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1278 RTUINT128_INIT_C(0xfffff00000000000, 0x0000000000000000)
1279 },
1280 {
1281 RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85),
1282 RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
1283 RTUINT128_INIT_C(0x0000000000000000, 0x000000221af4e338),
1284 },
1285 {
1286 RTUINT128_INIT_C(0xfd4d22a441ffa48c, 0x170739b573a9498d),
1287 RTUINT128_INIT_C(0x43459cea40782b26, 0xc8c16bb29cb3b343),
1288 RTUINT128_INIT_C(0xba0785ba01877965, 0x4e45ce02d6f5964a),
1289 },
1290 };
1291 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1292 {
1293 RTUINT128U uResult;
1294 PRTUINT128U pResult = RTUInt128Sub(&uResult, &s_aTests[i].uMinuend, &s_aTests[i].uSubtrahend);
1295 if (pResult != &uResult)
1296 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
1297 else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
1298 RTTestIFailed("test #%i failed: remainder differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1299 i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
1300
1301 uResult = s_aTests[i].uMinuend;
1302 pResult = RTUInt128AssignSub(&uResult, &s_aTests[i].uSubtrahend);
1303 RTTESTI_CHECK(pResult == &uResult);
1304 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1305 }
1306}
1307
1308
1309static void testUInt128Addition(void)
1310{
1311 RTTestSub(g_hTest, "RTUInt128Add");
1312
1313 static struct
1314 {
1315 RTUINT128U uAugend, uAddend, uResult;
1316 } const s_aTests[] =
1317 {
1318 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
1319 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
1320 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2) },
1321 { RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 3) },
1322 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 3) },
1323 { RTUINT128_INIT_C(2, 9), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(4, 9) },
1324 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(2, 3) },
1325 {
1326 RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
1327 RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
1328 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1329 },
1330 {
1331 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
1332 RTUINT128_INIT_C(0x0000000000000000, 0x00000000000ffeff),
1333 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffffffeff),
1334 },
1335 {
1336 RTUINT128_INIT_C(0xefffffffffffffff, 0xfffffffffff00000),
1337 RTUINT128_INIT_C(0x0000000000000000, 0x00000000001fffff),
1338 RTUINT128_INIT_C(0xf000000000000000, 0x00000000000fffff),
1339 },
1340 {
1341 RTUINT128_INIT_C(0xeeeeeeeeeeeeeeee, 0xeeeeeeeeeee00000),
1342 RTUINT128_INIT_C(0x0111111111111111, 0x11111111112fffff),
1343 RTUINT128_INIT_C(0xf000000000000000, 0x00000000000fffff),
1344 },
1345 {
1346 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1347 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1348 RTUINT128_INIT_C(0x00000fffffffffff, 0xfffffffffffffffe)
1349 },
1350 {
1351 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1352 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1353 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffffffffe)
1354 },
1355 {
1356 RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85),
1357 RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
1358 RTUINT128_INIT_C(0x0000000000000000, 0x000000281edd19d2),
1359 },
1360 {
1361 RTUINT128_INIT_C(0xfd4d22a441ffa48c, 0x170739b573a9498d),
1362 RTUINT128_INIT_C(0x43459cea40782b26, 0xc8c16bb29cb3b343),
1363 RTUINT128_INIT_C(0x4092bf8e8277cfb2, 0xdfc8a568105cfcd0),
1364 },
1365 };
1366 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1367 {
1368 RTUINT128U uResult;
1369 PRTUINT128U pResult = RTUInt128Add(&uResult, &s_aTests[i].uAugend, &s_aTests[i].uAddend);
1370 if (pResult != &uResult)
1371 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
1372 else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
1373 RTTestIFailed("test #%i failed: result differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1374 i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
1375
1376 uResult = s_aTests[i].uAugend;
1377 pResult = RTUInt128AssignAdd(&uResult, &s_aTests[i].uAddend);
1378 RTTESTI_CHECK(pResult == &uResult);
1379 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1380
1381 if (s_aTests[i].uAddend.s.Hi == 0)
1382 {
1383 pResult = RTUInt128AddU64(&uResult, &s_aTests[i].uAugend, s_aTests[i].uAddend.s.Lo);
1384 RTTESTI_CHECK(pResult == &uResult);
1385 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1386
1387 uResult = s_aTests[i].uAugend;
1388 pResult = RTUInt128AssignAddU64(&uResult, s_aTests[i].uAddend.s.Lo);
1389 RTTESTI_CHECK(pResult == &uResult);
1390 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1391 }
1392
1393 if (s_aTests[i].uAugend.s.Hi == 0)
1394 {
1395 pResult = RTUInt128AddU64(&uResult, &s_aTests[i].uAddend, s_aTests[i].uAugend.s.Lo);
1396 RTTESTI_CHECK(pResult == &uResult);
1397 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1398
1399 uResult = s_aTests[i].uAddend;
1400 pResult = RTUInt128AssignAddU64(&uResult, s_aTests[i].uAugend.s.Lo);
1401 RTTESTI_CHECK(pResult == &uResult);
1402 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1403 }
1404 }
1405}
1406
1407static void testUInt128Multiplication(void)
1408{
1409 RTTestSub(g_hTest, "RTUInt128Mul");
1410
1411 static struct
1412 {
1413 RTUINT128U uFactor1, uFactor2, uResult;
1414 } const s_aTests[] =
1415 {
1416 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) },
1417 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) },
1418 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1) },
1419 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 2) },
1420 { RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 0) },
1421 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(4, 2) },
1422 {
1423 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1424 RTUINT128_INIT_C(0, 2),
1425 RTUINT128_INIT_C(0x2222222222222222, 0x2222222222222222)
1426 },
1427 {
1428 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1429 RTUINT128_INIT_C(0, 0xf),
1430 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff)
1431 },
1432 {
1433 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1434 RTUINT128_INIT_C(0, 0x30000),
1435 RTUINT128_INIT_C(0x3333333333333333, 0x3333333333330000)
1436 },
1437 {
1438 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1439 RTUINT128_INIT_C(0, 0x30000000),
1440 RTUINT128_INIT_C(0x3333333333333333, 0x3333333330000000)
1441 },
1442 {
1443 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1444 RTUINT128_INIT_C(0, 0x3000000000000),
1445 RTUINT128_INIT_C(0x3333333333333333, 0x3333000000000000)
1446 },
1447 {
1448 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1449 RTUINT128_INIT_C(0x0000000000000003, 0x0000000000000000),
1450 RTUINT128_INIT_C(0x3333333333333333, 0x0000000000000000)
1451 },
1452 {
1453 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1454 RTUINT128_INIT_C(0x0000000300000000, 0x0000000000000000),
1455 RTUINT128_INIT_C(0x3333333300000000, 0x0000000000000000)
1456 },
1457 {
1458 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1459 RTUINT128_INIT_C(0x0003000000000000, 0x0000000000000000),
1460 RTUINT128_INIT_C(0x3333000000000000, 0x0000000000000000)
1461 },
1462 {
1463 RTUINT128_INIT_C(0x1111111111111111, 0x1111111111111111),
1464 RTUINT128_INIT_C(0x3000000000000000, 0x0000000000000000),
1465 RTUINT128_INIT_C(0x3000000000000000, 0x0000000000000000)
1466 },
1467 {
1468 RTUINT128_INIT_C(0x0000000000000000, 0x6816816816816817),
1469 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000a0280a),
1470 RTUINT128_INIT_C(0x0000000000411e58, 0x7627627627b1a8e6)
1471 },
1472 };
1473 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1474 {
1475 RTUINT128U uResult;
1476 PRTUINT128U pResult = RTUInt128Mul(&uResult, &s_aTests[i].uFactor1, &s_aTests[i].uFactor2);
1477 if (pResult != &uResult)
1478 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult);
1479 else if (RTUInt128IsNotEqual(&uResult, &s_aTests[i].uResult))
1480 RTTestIFailed("test #%i failed: \nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1481 i, s_aTests[i].uResult.s.Hi, s_aTests[i].uResult.s.Lo, uResult.s.Hi, uResult.s.Lo );
1482
1483 if (s_aTests[i].uFactor2.s.Hi == 0)
1484 {
1485 pResult = RTUInt128MulByU64(&uResult, &s_aTests[i].uFactor1, s_aTests[i].uFactor2.s.Lo);
1486 RTTESTI_CHECK(pResult == &uResult);
1487 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1488 }
1489
1490 if (s_aTests[i].uFactor1.s.Hi == 0)
1491 {
1492 pResult = RTUInt128MulByU64(&uResult, &s_aTests[i].uFactor2, s_aTests[i].uFactor1.s.Lo);
1493 RTTESTI_CHECK(pResult == &uResult);
1494 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1495 }
1496
1497 uResult = s_aTests[i].uFactor1;
1498 pResult = RTUInt128AssignMul(&uResult, &s_aTests[i].uFactor2);
1499 RTTESTI_CHECK(pResult == &uResult);
1500 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult));
1501 }
1502}
1503
1504
1505#if 0 /* Java program for generating testUInt128Division test data. */
1506import java.math.BigInteger;
1507import java.lang.System;
1508import java.lang.Integer;
1509import java.util.Random;
1510import java.security.SecureRandom;
1511
1512class uint128divtestgen
1513{
1514
1515public static String format(BigInteger BigNum)
1516{
1517 String str = BigNum.toString(16);
1518 while (str.length() < 32)
1519 str = "0" + str;
1520 return "RTUINT128_INIT_C(0x" + str.substring(0, 16) + ", 0x" + str.substring(16) + ")";
1521}
1522
1523public static void main(String args[])
1524{
1525 Random Rnd = new SecureRandom();
1526
1527 int cDivisorLarger = 0;
1528 for (int i = 0; i < 4096; i++)
1529 {
1530 int cDividendBits = Rnd.nextInt(127) + 1;
1531 int cDivisorBits = i < 9 ? cDividendBits : Rnd.nextInt(127) + 1;
1532 if (cDivisorBits > cDividendBits)
1533 {
1534 if (cDivisorLarger > i / 16)
1535 cDividendBits = 128 - Rnd.nextInt(16);
1536 else
1537 cDivisorLarger++;
1538 }
1539
1540 BigInteger Dividend = new BigInteger(cDividendBits, Rnd);
1541 BigInteger Divisor = new BigInteger(cDivisorBits, Rnd);
1542 while (Divisor.compareTo(BigInteger.ZERO) == 0) {
1543 cDivisorBits++;
1544 Divisor = new BigInteger(cDivisorBits, Rnd);
1545 }
1546
1547 BigInteger[] Result = Dividend.divideAndRemainder(Divisor);
1548
1549 System.out.println(" { /* i=" + Integer.toString(i) + "; " + Integer.toString(cDividendBits) + " / " + Integer.toString(cDivisorBits) + " */");
1550 System.out.println(" " + format(Dividend) + ", " + format(Divisor) + ",");
1551 System.out.println(" " + format(Result[0]) + ", " + format(Result[1]) + "");
1552 System.out.println(" },");
1553 }
1554}
1555}
1556#endif
1557
1558static void testUInt128Division(void)
1559{
1560 RTTestSub(g_hTest, "RTUInt128DivMod");
1561
1562 static struct
1563 {
1564 RTUINT128U uDividend, uDivisor, uQuotient, uRemainder;
1565 } const s_aTests[] =
1566 {
1567 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 0) }, /* #0 */
1568 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) }, /* #1 */
1569 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1) }, /* #2 */
1570 { RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 0) }, /* #3 */
1571 { RTUINT128_INIT_C(2, 1), RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(1, 0), RTUINT128_INIT_C(0, 1) }, /* #4 */
1572 { /* #5 */
1573 RTUINT128_INIT_C(0xffffffffffffffff, 0x0000000000000000),
1574 RTUINT128_INIT_C(0x0000000000000000, 0xffffffffffffffff),
1575 RTUINT128_INIT_C(0x0000000000000001, 0x0000000000000000),
1576 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000000000)
1577 },
1578 { /* #6 */
1579 RTUINT128_INIT_C(0xffffffffffffffff, 0xfffffffffff00000),
1580 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1581 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000100000),
1582 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000000000)
1583 },
1584 { /* #7 */
1585 RTUINT128_INIT_C(0xffffffffffffffff, 0xffffffffffffffff),
1586 RTUINT128_INIT_C(0x00000fffffffffff, 0xffffffffffffffff),
1587 RTUINT128_INIT_C(0x0000000000000000, 0x0000000000100000),
1588 RTUINT128_INIT_C(0x0000000000000000, 0x00000000000fffff)
1589 },
1590 { /* #8 */
1591 RTUINT128_INIT_C(0x0000000000000000, 0x000000251ce8fe85), RTUINT128_INIT_C(0x0000000000000000, 0x0000000301f41b4d),
1592 RTUINT128_INIT_C(0x0000000000000000, 0x000000000000000c), RTUINT128_INIT_C(0x0000000000000000, 0x000000010577b6e9)
1593 },
1594
1595#include "tstRTBigNum-uint128-div-test-data.h"
1596 };
1597 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
1598 {
1599 RTUINT128U uResultQ, uResultR;
1600 PRTUINT128U pResultQ = RTUInt128DivRem(&uResultQ, &uResultR, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
1601 if (pResultQ != &uResultQ)
1602 RTTestIFailed("test #%i returns %p instead of %p", i, pResultQ, &uResultQ);
1603 else if ( RTUInt128IsNotEqual(&uResultQ, &s_aTests[i].uQuotient)
1604 && RTUInt128IsNotEqual(&uResultR, &s_aTests[i].uRemainder))
1605 {
1606 RTTestIFailed("test #%i failed on both counts", i);
1607 }
1608 else if (RTUInt128IsNotEqual(&uResultQ, &s_aTests[i].uQuotient))
1609 RTTestIFailed("test #%i failed: quotient differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1610 i, s_aTests[i].uQuotient.s.Hi, s_aTests[i].uQuotient.s.Lo, uResultQ.s.Hi, uResultQ.s.Lo );
1611 else if (RTUInt128IsNotEqual(&uResultR, &s_aTests[i].uRemainder))
1612 RTTestIFailed("test #%i failed: remainder differs:\nExp: %016RX64`%016RX64\nGot: %016RX64`%016RX64",
1613 i, s_aTests[i].uRemainder.s.Hi, s_aTests[i].uRemainder.s.Lo, uResultR.s.Hi, uResultR.s.Lo );
1614
1615 pResultQ = RTUInt128Div(&uResultQ, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
1616 RTTESTI_CHECK(pResultQ == &uResultQ);
1617 RTTESTI_CHECK(RTUInt128IsEqual(&uResultQ, &s_aTests[i].uQuotient));
1618
1619 uResultQ = s_aTests[i].uDividend;
1620 pResultQ = RTUInt128AssignDiv(&uResultQ, &s_aTests[i].uDivisor);
1621 RTTESTI_CHECK(pResultQ == &uResultQ);
1622 RTTESTI_CHECK(RTUInt128IsEqual(&uResultQ, &s_aTests[i].uQuotient));
1623
1624
1625 PRTUINT128U pResultR = RTUInt128Mod(&uResultR, &s_aTests[i].uDividend, &s_aTests[i].uDivisor);
1626 RTTESTI_CHECK(pResultR == &uResultR);
1627 RTTESTI_CHECK(RTUInt128IsEqual(&uResultR, &s_aTests[i].uRemainder));
1628
1629 uResultR = s_aTests[i].uDividend;
1630 pResultR = RTUInt128AssignMod(&uResultR, &s_aTests[i].uDivisor);
1631 RTTESTI_CHECK(pResultR == &uResultR);
1632 RTTESTI_CHECK(RTUInt128IsEqual(&uResultR, &s_aTests[i].uRemainder));
1633 }
1634}
1635
1636
1637static void testUInt64Division(void)
1638{
1639 /*
1640 * Check the results against native code.
1641 */
1642 RTTestSub(g_hTest, "RTUInt64DivRem");
1643 for (uint32_t i = 0; i < _1M / 2; i++)
1644 {
1645 uint64_t const uDividend = RTRandU64Ex(0, UINT64_MAX);
1646 uint64_t const uDivisor = RTRandU64Ex(1, UINT64_MAX);
1647 uint64_t const uQuotient = uDividend / uDivisor;
1648 uint64_t const uRemainder = uDividend % uDivisor;
1649 RTUINT64U Dividend = { uDividend };
1650 RTUINT64U Divisor = { uDivisor };
1651 RTUINT64U Quotient = { UINT64_MAX };
1652 RTUINT64U Remainder = { UINT64_MAX };
1653 RTTESTI_CHECK(RTUInt64DivRem(&Quotient, &Remainder, &Dividend, &Divisor) == &Quotient);
1654 if (uQuotient != Quotient.u || uRemainder != Remainder.u)
1655 RTTestIFailed("%RU64 / %RU64 -> %RU64 rem %RU64, expected %RU64 rem %RU64",
1656 uDividend, uDivisor, Quotient.u, Remainder.u, uQuotient, uRemainder);
1657 }
1658}
1659
1660
1661static void testUInt32Division(void)
1662{
1663 /*
1664 * Check the results against native code.
1665 */
1666 RTTestSub(g_hTest, "RTUInt32DivRem");
1667 for (uint32_t i = 0; i < _1M / 2; i++)
1668 {
1669 uint32_t const uDividend = RTRandU32Ex(0, UINT32_MAX);
1670 uint32_t const uDivisor = RTRandU32Ex(1, UINT32_MAX);
1671 uint32_t const uQuotient = uDividend / uDivisor;
1672 uint32_t const uRemainder = uDividend % uDivisor;
1673 RTUINT32U Dividend = { uDividend };
1674 RTUINT32U Divisor = { uDivisor };
1675 RTUINT32U Quotient = { UINT32_MAX };
1676 RTUINT32U Remainder = { UINT32_MAX };
1677 RTTESTI_CHECK(RTUInt32DivRem(&Quotient, &Remainder, &Dividend, &Divisor) == &Quotient);
1678 if (uQuotient != Quotient.u || uRemainder != Remainder.u)
1679 RTTestIFailed("%u / %u -> %u rem %u, expected %u rem %u",
1680 uDividend, uDivisor, Quotient.u, Remainder.u, uQuotient, uRemainder);
1681 }
1682}
1683
1684
1685
1686int main(int argc, char **argv)
1687{
1688 RT_NOREF_PV(argv);
1689
1690 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTBigNum", &g_hTest);
1691 if (rcExit != RTEXITCODE_SUCCESS)
1692 return rcExit;
1693 RTTestBanner(g_hTest);
1694
1695 /* Init fixed integers. */
1696 RTTestSub(g_hTest, "RTBigNumInit");
1697 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositive, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1698 g_abLargePositive, sizeof(g_abLargePositive)), VINF_SUCCESS);
1699 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositive2, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1700 g_abLargePositive, sizeof(g_abLargePositive) - 11), VINF_SUCCESS);
1701 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositiveMinus1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1702 g_abLargePositiveMinus1, sizeof(g_abLargePositiveMinus1)), VINF_SUCCESS);
1703 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegative, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1704 g_abLargeNegative, sizeof(g_abLargeNegative)), VINF_SUCCESS);
1705 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegative2, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1706 g_abLargeNegative, sizeof(g_abLargeNegative) - 9), VINF_SUCCESS);
1707 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegativePluss1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1708 g_abLargeNegativePluss1, sizeof(g_abLargeNegativePluss1)), VINF_SUCCESS);
1709 RTTESTI_CHECK_RC(RTBigNumInit(&g_64BitPositive1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1710 g_ab64BitPositive1, sizeof(g_ab64BitPositive1)), VINF_SUCCESS);
1711
1712 RTTESTI_CHECK_RC(RTBigNumInitZero(&g_Zero, 0), VINF_SUCCESS);
1713 RTTESTI_CHECK_RC(RTBigNumInit(&g_One, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x01", 1), VINF_SUCCESS);
1714 RTTESTI_CHECK_RC(RTBigNumInit(&g_Two, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x02", 1), VINF_SUCCESS);
1715 RTTESTI_CHECK_RC(RTBigNumInit(&g_Three, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x03", 1), VINF_SUCCESS);
1716 RTTESTI_CHECK_RC(RTBigNumInit(&g_Four, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x04", 1), VINF_SUCCESS);
1717 RTTESTI_CHECK_RC(RTBigNumInit(&g_Five, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x05", 1), VINF_SUCCESS);
1718 RTTESTI_CHECK_RC(RTBigNumInit(&g_Ten, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x0a", 1), VINF_SUCCESS);
1719 RTTESTI_CHECK_RC(RTBigNumInit(&g_FourtyTwo, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x2a", 1), VINF_SUCCESS);
1720
1721 RTTESTI_CHECK_RC(RTBigNumInit(&g_Minus1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
1722 g_abMinus1, sizeof(g_abMinus1)), VINF_SUCCESS);
1723
1724 RTTESTI_CHECK_RC(RTBigNumInit(&g_PubKeyExp, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1725 g_abPubKeyExp, sizeof(g_abPubKeyExp)), VINF_SUCCESS);
1726 RTTESTI_CHECK_RC(RTBigNumInit(&g_PubKeyMod, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1727 g_abPubKeyMod, sizeof(g_abPubKeyMod)), VINF_SUCCESS);
1728 RTTESTI_CHECK_RC(RTBigNumInit(&g_Signature, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1729 g_abSignature, sizeof(g_abSignature)), VINF_SUCCESS);
1730 RTTESTI_CHECK_RC(RTBigNumInit(&g_SignatureDecrypted, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
1731 g_abSignatureDecrypted, sizeof(g_abSignatureDecrypted)), VINF_SUCCESS);
1732 testMoreInit();
1733
1734 if (RTTestIErrorCount() == 0)
1735 {
1736 if (argc != 2)
1737 {
1738 /* Test UInt128 first as it may be used by RTBigInt. */
1739 testUInt128Multiplication();
1740 testUInt128Division();
1741 testUInt128Subtraction();
1742 testUInt128Addition();
1743
1744 /* Test UInt32 and UInt64 division as it's used by the watcom support code (BIOS, ValKit, OS/2 GAs). */
1745 testUInt32Division();
1746 testUInt64Division();
1747
1748 /* Test the RTBigInt operations. */
1749 testCompare();
1750 testSubtraction();
1751 testAddition();
1752 testShift();
1753 testMultiplication();
1754 testDivision();
1755 testModulo();
1756 testExponentiation();
1757 testModExp();
1758 testToBytes();
1759 }
1760
1761 /* Benchmarks */
1762 testBenchmarks(argc == 2);
1763
1764 /* Cleanups. */
1765 RTTestSub(g_hTest, "RTBigNumDestroy");
1766 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargePositive), VINF_SUCCESS);
1767 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargePositive2), VINF_SUCCESS);
1768 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargeNegative), VINF_SUCCESS);
1769 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargeNegative2), VINF_SUCCESS);
1770 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_Zero), VINF_SUCCESS);
1771 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_64BitPositive1), VINF_SUCCESS);
1772 }
1773
1774 return RTTestSummaryAndDestroy(g_hTest);
1775}
1776
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