VirtualBox

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

Last change on this file since 93654 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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