VirtualBox

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

Last change on this file since 52320 was 52297, checked in by vboxsync, 10 years ago

tstRTBigNum: compare with openssl. (Conclusion, we're very slow at modexp.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 51.1 KB
Line 
1/* $Id: tstRTBigNum.cpp 52297 2014-08-06 14:43:28Z vboxsync $ */
2/** @file
3 * IPRT - Testcase for the RTBigNum* functions.
4 */
5
6/*
7 * Copyright (C) 2006-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <iprt/bignum.h>
31
32#include <iprt/test.h>
33#include <iprt/thread.h>
34#include <iprt/time.h>
35#include <iprt/string.h>
36
37#if 1
38# include <openssl/bn.h>
39#endif
40
41
42/*******************************************************************************
43* Global Variables *
44*******************************************************************************/
45static RTTEST g_hTest;
46
47
48static uint8_t const g_abLargePositive[] =
49{
50 0x67,0xcd,0xd6,0x60,0x4e,0xaa,0xe9,0x8e,0x06,0x99,0xde,0xb2,0xf5,0x1c,0xc3,0xfc,
51 0xf5,0x17,0x41,0xec,0x42,0x68,0xf0,0xab,0x0e,0xe6,0x79,0xa8,0x32,0x97,0x55,0x00,
52 0x49,0x21,0x2b,0x72,0x4b,0x34,0x33,0xe1,0xe2,0xfe,0xa2,0xb8,0x39,0x7a,0x2f,0x17,
53 0xae,0x1f,0xbb,0xdb,0x46,0xbc,0x59,0x8b,0x13,0x05,0x28,0x96,0xf6,0xfd,0xc1,0xa4
54};
55static RTBIGNUM g_LargePositive;
56static RTBIGNUM g_LargePositive2; /**< Smaller than g_LargePositive. */
57
58static uint8_t const g_abLargePositiveMinus1[] =
59{
60 0x67,0xcd,0xd6,0x60,0x4e,0xaa,0xe9,0x8e,0x06,0x99,0xde,0xb2,0xf5,0x1c,0xc3,0xfc,
61 0xf5,0x17,0x41,0xec,0x42,0x68,0xf0,0xab,0x0e,0xe6,0x79,0xa8,0x32,0x97,0x55,0x00,
62 0x49,0x21,0x2b,0x72,0x4b,0x34,0x33,0xe1,0xe2,0xfe,0xa2,0xb8,0x39,0x7a,0x2f,0x17,
63 0xae,0x1f,0xbb,0xdb,0x46,0xbc,0x59,0x8b,0x13,0x05,0x28,0x96,0xf6,0xfd,0xc1,0xa3
64};
65static RTBIGNUM g_LargePositiveMinus1; /**< g_LargePositive - 1 */
66
67
68static uint8_t const g_abLargeNegative[] =
69{
70 0xf2,0xde,0xbd,0xaf,0x43,0x9e,0x1e,0x88,0xdc,0x64,0x37,0xa9,0xdb,0xb7,0x26,0x31,
71 0x92,0x1d,0xf5,0x43,0x4c,0xb0,0x21,0x2b,0x07,0x4e,0xf5,0x94,0x9e,0xce,0x15,0x79,
72 0x13,0x0c,0x70,0x68,0x49,0x46,0xcf,0x72,0x2b,0xc5,0x8f,0xab,0x7c,0x88,0x2d,0x1e,
73 0x3b,0x43,0x5b,0xdb,0x47,0x45,0x7a,0x25,0x74,0x46,0x1d,0x87,0x24,0xaa,0xab,0x0d,
74 0x3e,0xdf,0xd1,0xd8,0x44,0x6f,0x01,0x84,0x01,0x36,0xe0,0x84,0x6e,0x6f,0x41,0xbb,
75 0xae,0x1a,0x31,0xef,0x42,0x23,0xfd,0xda,0xda,0x0f,0x7d,0x88,0x8f,0xf5,0x63,0x72,
76 0x36,0x9f,0xa9,0xa4,0x4f,0xa0,0xa6,0xb1,0x3b,0xbe,0x0d,0x9d,0x62,0x88,0x98,0x8b
77};
78static RTBIGNUM g_LargeNegative;
79static RTBIGNUM g_LargeNegative2; /**< A few digits less than g_LargeNegative, i.e. larger value. */
80
81static uint8_t const g_abLargeNegativePluss1[] =
82{
83 0xf2,0xde,0xbd,0xaf,0x43,0x9e,0x1e,0x88,0xdc,0x64,0x37,0xa9,0xdb,0xb7,0x26,0x31,
84 0x92,0x1d,0xf5,0x43,0x4c,0xb0,0x21,0x2b,0x07,0x4e,0xf5,0x94,0x9e,0xce,0x15,0x79,
85 0x13,0x0c,0x70,0x68,0x49,0x46,0xcf,0x72,0x2b,0xc5,0x8f,0xab,0x7c,0x88,0x2d,0x1e,
86 0x3b,0x43,0x5b,0xdb,0x47,0x45,0x7a,0x25,0x74,0x46,0x1d,0x87,0x24,0xaa,0xab,0x0d,
87 0x3e,0xdf,0xd1,0xd8,0x44,0x6f,0x01,0x84,0x01,0x36,0xe0,0x84,0x6e,0x6f,0x41,0xbb,
88 0xae,0x1a,0x31,0xef,0x42,0x23,0xfd,0xda,0xda,0x0f,0x7d,0x88,0x8f,0xf5,0x63,0x72,
89 0x36,0x9f,0xa9,0xa4,0x4f,0xa0,0xa6,0xb1,0x3b,0xbe,0x0d,0x9d,0x62,0x88,0x98,0x8c
90};
91static RTBIGNUM g_LargeNegativePluss1; /**< g_LargeNegative + 1 */
92
93
94static uint8_t const g_ab64BitPositive1[] = { 0x53, 0xe0, 0xdf, 0x11, 0x85, 0x93, 0x06, 0x21 };
95static uint64_t g_u64BitPositive1 = UINT64_C(0x53e0df1185930621);
96static RTBIGNUM g_64BitPositive1;
97
98
99static RTBIGNUM g_Zero;
100static RTBIGNUM g_One;
101static RTBIGNUM g_Two;
102static RTBIGNUM g_Three;
103static RTBIGNUM g_Four;
104static RTBIGNUM g_Five;
105static RTBIGNUM g_Ten;
106static RTBIGNUM g_FourtyTwo;
107
108static uint8_t const g_abMinus1[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
109static int64_t g_iBitMinus1 = -1;
110static RTBIGNUM g_Minus1;
111
112
113
114static void testInitOneLittleEndian(uint8_t const *pb, size_t cb, PRTBIGNUM pBigNum)
115{
116 uint8_t abLittleEndian[sizeof(g_abLargePositive) + sizeof(g_abLargeNegative)];
117 RTTESTI_CHECK_RETV(cb <= sizeof(abLittleEndian));
118
119 size_t cbLeft = cb;
120 uint8_t *pbDst = abLittleEndian + cb - 1;
121 uint8_t const *pbSrc = pb;
122 while (cbLeft-- > 0)
123 *pbDst-- = *pbSrc++;
124
125 RTBIGNUM Num;
126 RTTESTI_CHECK_RC_RETV(RTBigNumInit(&Num, RTBIGNUMINIT_F_ENDIAN_LITTLE | RTBIGNUMINIT_F_SIGNED,
127 abLittleEndian, cb), VINF_SUCCESS);
128 RTTESTI_CHECK(Num.fNegative == pBigNum->fNegative);
129 RTTESTI_CHECK(Num.cUsed == pBigNum->cUsed);
130 RTTESTI_CHECK(RTBigNumCompare(&Num, pBigNum) == 0);
131 RTTESTI_CHECK_RC(RTBigNumDestroy(&Num), VINF_SUCCESS);
132
133 RTTESTI_CHECK_RC_RETV(RTBigNumInit(&Num, RTBIGNUMINIT_F_ENDIAN_LITTLE | RTBIGNUMINIT_F_SIGNED | RTBIGNUMINIT_F_SENSITIVE,
134 abLittleEndian, cb), VINF_SUCCESS);
135 RTTESTI_CHECK(Num.fNegative == pBigNum->fNegative);
136 RTTESTI_CHECK(Num.cUsed == pBigNum->cUsed);
137 RTTESTI_CHECK(RTBigNumCompare(&Num, pBigNum) == 0);
138 RTTESTI_CHECK_RC(RTBigNumDestroy(&Num), VINF_SUCCESS);
139}
140
141static void testMoreInit(void)
142{
143 RTTESTI_CHECK(!g_LargePositive.fNegative);
144 RTTESTI_CHECK(!g_LargePositive.fSensitive);
145 RTTESTI_CHECK(!g_LargePositive2.fNegative);
146 RTTESTI_CHECK(!g_LargePositive2.fSensitive);
147 RTTESTI_CHECK(g_LargeNegative.fNegative);
148 RTTESTI_CHECK(!g_LargeNegative.fSensitive);
149 RTTESTI_CHECK(g_LargeNegative2.fNegative);
150 RTTESTI_CHECK(!g_LargeNegative2.fSensitive);
151
152 RTTESTI_CHECK(!g_Zero.fNegative);
153 RTTESTI_CHECK(!g_Zero.fSensitive);
154 RTTESTI_CHECK(g_Zero.cUsed == 0);
155
156 RTTESTI_CHECK(g_Minus1.fNegative);
157 RTTESTI_CHECK(!g_Minus1.fSensitive);
158 RTTESTI_CHECK(g_Minus1.cUsed == 1);
159 RTTESTI_CHECK(g_Minus1.pauElements[0] == 1);
160
161 RTTESTI_CHECK(g_One.cUsed == 1 && g_One.pauElements[0] == 1);
162 RTTESTI_CHECK(g_Two.cUsed == 1 && g_Two.pauElements[0] == 2);
163 RTTESTI_CHECK(g_Three.cUsed == 1 && g_Three.pauElements[0] == 3);
164 RTTESTI_CHECK(g_Four.cUsed == 1 && g_Four.pauElements[0] == 4);
165 RTTESTI_CHECK(g_Ten.cUsed == 1 && g_Ten.pauElements[0] == 10);
166 RTTESTI_CHECK(g_FourtyTwo.cUsed == 1 && g_FourtyTwo.pauElements[0] == 42);
167
168 /* Test big endian initialization w/ sensitive variation. */
169 testInitOneLittleEndian(g_abLargePositive, sizeof(g_abLargePositive), &g_LargePositive);
170 testInitOneLittleEndian(g_abLargePositive, sizeof(g_abLargePositive) - 11, &g_LargePositive2);
171
172 testInitOneLittleEndian(g_abLargeNegative, sizeof(g_abLargeNegative), &g_LargeNegative);
173 testInitOneLittleEndian(g_abLargeNegative, sizeof(g_abLargeNegative) - 9, &g_LargeNegative2);
174
175 RTTESTI_CHECK(g_Minus1.cUsed == 1);
176 testInitOneLittleEndian(g_abMinus1, sizeof(g_abMinus1), &g_Minus1);
177 testInitOneLittleEndian(g_abMinus1, 1, &g_Minus1);
178 testInitOneLittleEndian(g_abMinus1, 4, &g_Minus1);
179
180}
181
182
183static void testCompare(void)
184{
185 RTTestSub(g_hTest, "RTBigNumCompare*");
186 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargePositive) == 0);
187 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive2, &g_LargePositive) == -1);
188 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargePositive2) == 1);
189 RTTESTI_CHECK(RTBigNumCompare(&g_Zero, &g_LargePositive) == -1);
190 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_Zero) == 1);
191 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive2, &g_Zero) == 1);
192 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargePositiveMinus1) == 1);
193 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositiveMinus1, &g_LargePositive) == -1);
194
195 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegative) == 0);
196 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegative2) == -1);
197 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_LargeNegative) == 1);
198 RTTESTI_CHECK(RTBigNumCompare(&g_Zero, &g_LargeNegative) == 1);
199 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_Zero) == -1);
200 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_Zero) == -1);
201 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegativePluss1) == -1);
202 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegativePluss1, &g_LargeNegative) == 1);
203
204 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargePositive) == -1);
205 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargeNegative) == 1);
206 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_LargePositive) == -1);
207 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive, &g_LargeNegative2) == 1);
208 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative2, &g_LargePositive2) == -1);
209 RTTESTI_CHECK(RTBigNumCompare(&g_LargePositive2, &g_LargeNegative2) == 1);
210
211 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, 0) == 0);
212 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, 1) == -1);
213 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, UINT32_MAX) == -1);
214 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_Zero, UINT64_MAX) == -1);
215 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargePositive, UINT64_MAX) == 1);
216 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargePositive2, 0x7213593) == 1);
217 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, 0) == -1);
218 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, 1) == -1);
219 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, UINT64_MAX) == -1);
220 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_LargeNegative, 0x80034053) == -1);
221 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_64BitPositive1, g_u64BitPositive1) == 0);
222 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_64BitPositive1, g_u64BitPositive1 - 1) == 1);
223 RTTESTI_CHECK(RTBigNumCompareWithU64(&g_64BitPositive1, g_u64BitPositive1 + 1) == -1);
224
225 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, 0) == 0);
226 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, 1) == -1);
227 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, -1) == 1);
228 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Zero, INT32_MAX) == -1);
229 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_LargeNegative, INT32_MIN) == -1);
230 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_LargeNegative, INT64_MIN) == -1);
231 RTTESTI_CHECK(g_u64BitPositive1 < (uint64_t)INT64_MAX);
232 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, g_u64BitPositive1) == 0);
233 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, g_u64BitPositive1 - 1) == 1);
234 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, g_u64BitPositive1 + 1) == -1);
235 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, INT64_MIN) == 1);
236 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_64BitPositive1, INT64_MAX) == -1);
237 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Minus1, -1) == 0);
238 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Minus1, -2) == 1);
239 RTTESTI_CHECK(RTBigNumCompareWithS64(&g_Minus1, 0) == -1);
240}
241
242
243static void testSubtraction(void)
244{
245 RTTestSub(g_hTest, "RTBigNumSubtract");
246
247 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
248 {
249 RTBIGNUM Result;
250 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
251 RTBIGNUM Result2;
252 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
253
254 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
255 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
256
257 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
258 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
259
260 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Minus1, &g_Zero), VINF_SUCCESS);
261 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
262
263 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_64BitPositive1, &g_Minus1), VINF_SUCCESS);
264 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1 + 1) == 0);
265
266 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_Minus1, &g_64BitPositive1), VINF_SUCCESS);
267 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, INT64_C(-1) - g_u64BitPositive1) == 0);
268
269 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
270 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
271 RTTESTI_CHECK(Result.cUsed == 1);
272
273 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargePositiveMinus1, &g_LargePositive), VINF_SUCCESS);
274 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
275 RTTESTI_CHECK(Result.cUsed == 1);
276
277 RTTESTI_CHECK(RTBigNumCompare(&g_LargeNegative, &g_LargeNegativePluss1) < 0);
278 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargeNegative, &g_LargeNegativePluss1), VINF_SUCCESS);
279 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
280 RTTESTI_CHECK(Result.cUsed == 1);
281
282 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargeNegativePluss1, &g_LargeNegative), VINF_SUCCESS);
283 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
284 RTTESTI_CHECK(Result.cUsed == 1);
285
286 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result, &g_LargeNegativePluss1, &g_LargeNegativePluss1), VINF_SUCCESS);
287 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
288 RTTESTI_CHECK(Result.cUsed == 0);
289
290 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
291 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
292 }
293}
294
295
296static void testAddition(void)
297{
298 RTTestSub(g_hTest, "RTBigNumAdd");
299
300 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
301 {
302 RTBIGNUM Result;
303 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
304 RTBIGNUM Result2;
305 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
306
307 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
308 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -2) == 0);
309
310 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
311 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
312
313 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Zero, &g_64BitPositive1), VINF_SUCCESS);
314 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1) == 0);
315
316 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_Minus1, &g_64BitPositive1), VINF_SUCCESS);
317 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1 - 1) == 0);
318
319 RTTESTI_CHECK(g_u64BitPositive1 * 2 > g_u64BitPositive1);
320 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_64BitPositive1, &g_64BitPositive1), VINF_SUCCESS);
321 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, g_u64BitPositive1 * 2) == 0);
322
323
324 RTTESTI_CHECK_RC(RTBigNumAssign(&Result2, &g_LargePositive), VINF_SUCCESS);
325 RTTESTI_CHECK_RC(RTBigNumNegateThis(&Result2), VINF_SUCCESS);
326
327 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositive, &Result2), VINF_SUCCESS);
328 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, 0) == 0);
329
330 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &Result2, &g_LargePositive), VINF_SUCCESS);
331 RTTESTI_CHECK(RTBigNumCompareWithU64(&Result, 0) == 0);
332
333 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositiveMinus1, &Result2), VINF_SUCCESS);
334 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
335
336 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &Result2, &g_LargePositiveMinus1), VINF_SUCCESS);
337 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
338
339
340 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
341 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositive) > 0);
342 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargePositiveMinus1), VINF_SUCCESS);
343 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositive) == 0);
344 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargePositive), VINF_SUCCESS);
345 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositiveMinus1) == 0);
346
347 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositive, &g_LargeNegative), VINF_SUCCESS);
348 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargeNegative) > 0);
349 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositive) < 0);
350 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargePositive), VINF_SUCCESS);
351 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargeNegative) == 0);
352 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargeNegative), VINF_SUCCESS);
353 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargePositive) == 0);
354
355 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargeNegativePluss1, &g_LargeNegative), VINF_SUCCESS);
356 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargeNegative) < 0);
357 RTTESTI_CHECK_RC(RTBigNumSubtract(&Result2, &Result, &g_LargeNegative), VINF_SUCCESS);
358 RTTESTI_CHECK(RTBigNumCompare(&Result2, &g_LargeNegativePluss1) == 0);
359
360 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
361 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
362 }
363}
364
365static bool testHexStringToNum(PRTBIGNUM pBigNum, const char *pszHex, uint32_t fFlags)
366{
367 uint8_t abBuf[_4K];
368 size_t cbHex = strlen(pszHex);
369 RTTESTI_CHECK_RET(!(cbHex & 1), false);
370 cbHex /= 2;
371 RTTESTI_CHECK_RET(cbHex < sizeof(abBuf), false);
372 RTTESTI_CHECK_RC_RET(RTStrConvertHexBytes(pszHex, abBuf, cbHex, 0), VINF_SUCCESS, false);
373 RTTESTI_CHECK_RC_RET(RTBigNumInit(pBigNum, RTBIGNUMINIT_F_ENDIAN_BIG | fFlags, abBuf, cbHex), VINF_SUCCESS, false);
374 return true;
375}
376
377static void testMultiplication(void)
378{
379 RTTestSub(g_hTest, "RTBigNumMultiply");
380
381 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
382 {
383 RTBIGNUM Result;
384 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
385 RTBIGNUM Result2;
386 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
387
388 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
389 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
390
391 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
392 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
393 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Minus1, &g_Zero), VINF_SUCCESS);
394 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
395
396 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_Minus1, &g_64BitPositive1), VINF_SUCCESS);
397 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -(int64_t)g_u64BitPositive1) == 0);
398 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &g_64BitPositive1, &g_Minus1), VINF_SUCCESS);
399 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -(int64_t)g_u64BitPositive1) == 0);
400
401
402 static struct
403 {
404 const char *pszF1, *pszF2, *pszResult;
405 } s_aTests[] =
406 {
407 {
408 "29865DBFA717181B9DD4B515BD072DE10A5A314385F6DED735AC553FCD307D30C499",
409 "4DD65692F7365B90C55F63988E5B6C448653E7DB9DD941507586BD8CF71398287C",
410 "0CA02E8FFDB0EEA37264338A4AAA91C8974E162DDFCBCF804B434A11955671B89B3645AAB75423D60CA3459B0B4F3F28978DA768779FB54CF362FD61924637582F221C"
411 },
412 {
413 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
414 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
415 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000000000000000000001"
416 }
417 };
418 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
419 {
420 RTBIGNUM F1, F2, Expected;
421 if ( testHexStringToNum(&F1, s_aTests[i].pszF1, RTBIGNUMINIT_F_UNSIGNED | fFlags)
422 && testHexStringToNum(&F2, s_aTests[i].pszF2, RTBIGNUMINIT_F_UNSIGNED | fFlags)
423 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
424 {
425 RTTESTI_CHECK_RC(RTBigNumMultiply(&Result, &F1, &F2), VINF_SUCCESS);
426 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
427 RTTESTI_CHECK_RC(RTBigNumDestroy(&F1), VINF_SUCCESS);
428 RTTESTI_CHECK_RC(RTBigNumDestroy(&F2), VINF_SUCCESS);
429 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
430 }
431 }
432 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
433 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
434 }
435}
436
437
438static void testDivision(void)
439{
440 RTTestSub(g_hTest, "RTBigNumDivide");
441
442 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
443 {
444 RTBIGNUM Quotient;
445 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Quotient, fFlags), VINF_SUCCESS);
446 RTBIGNUM Remainder;
447 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Remainder, fFlags), VINF_SUCCESS);
448
449 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Minus1, &g_Minus1), VINF_SUCCESS);
450 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
451 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
452
453 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Zero, &g_Minus1), VINF_SUCCESS);
454 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 0) == 0);
455 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
456
457 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Minus1, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
458 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargeNegative, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
459 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargePositive, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
460
461 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Four, &g_Two), VINF_SUCCESS);
462 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 2) == 0);
463 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
464
465 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Three, &g_Two), VINF_SUCCESS);
466 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
467 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 1) == 0);
468
469 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_Ten, &g_Two), VINF_SUCCESS);
470 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 5) == 0);
471 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 0) == 0);
472
473
474 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
475 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
476 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, 1) == 0);
477
478 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &g_LargeNegative, &g_LargeNegativePluss1), VINF_SUCCESS);
479 RTTESTI_CHECK(RTBigNumCompareWithS64(&Quotient, 1) == 0);
480 RTTESTI_CHECK(RTBigNumCompareWithS64(&Remainder, -1) == 0);
481
482
483#if 0
484 static struct
485 {
486 const char *pszF1, *pszF2, *pszQuotient, *pszRemainder;
487 } s_aTests[] =
488 {
489 {
490 "29865DBFA717181B9DD4B515BD072DE10A5A314385F6DED735AC553FCD307D30C499",
491 "4DD65692F7365B90C55F63988E5B6C448653E7DB9DD941507586BD8CF71398287C",
492 "0CA02E8FFDB0EEA37264338A4AAA91C8974E162DDFCBCF804B434A11955671B89B3645AAB75423D60CA3459B0B4F3F28978DA768779FB54CF362FD61924637582F221C"
493 },
494 {
495 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
496 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
497 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000000000000000000001"
498 }
499 };
500 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
501 {
502 RTBIGNUM F1, F2, Expected;
503 if ( testHexStringToNum(&F1, s_aTests[i].pszF1, RTBIGNUMINIT_F_UNSIGNED | fFlags)
504 && testHexStringToNum(&F2, s_aTests[i].pszF2, RTBIGNUMINIT_F_UNSIGNED | fFlags)
505 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
506 {
507 RTTESTI_CHECK_RC(RTBigNumDivide(&Quotient, &Remainder, &F1, &F2), VINF_SUCCESS);
508 RTTESTI_CHECK(RTBigNumCompare(&Quotient, &Expected) == 0);
509 RTTESTI_CHECK_RC(RTBigNumDestroy(&F1), VINF_SUCCESS);
510 RTTESTI_CHECK_RC(RTBigNumDestroy(&F2), VINF_SUCCESS);
511 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
512 }
513 }
514#endif
515 RTTESTI_CHECK_RC(RTBigNumDestroy(&Quotient), VINF_SUCCESS);
516 RTTESTI_CHECK_RC(RTBigNumDestroy(&Remainder), VINF_SUCCESS);
517 }
518}
519
520
521static void testModulo(void)
522{
523 RTTestSub(g_hTest, "RTBigNumModulo");
524
525 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
526 {
527 RTBIGNUM Result;
528 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
529 RTBIGNUM Tmp;
530 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Tmp, fFlags), VINF_SUCCESS);
531
532 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Minus1, &g_Minus1), VINF_SUCCESS);
533 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
534
535 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Zero, &g_Minus1), VINF_SUCCESS);
536 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
537
538 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Minus1, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
539 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargeNegative, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
540 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargePositive, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
541
542 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Four, &g_Two), VINF_SUCCESS);
543 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
544
545 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Three, &g_Two), VINF_SUCCESS);
546 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
547
548 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_Ten, &g_Two), VINF_SUCCESS);
549 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
550
551 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargePositive, &g_LargePositiveMinus1), VINF_SUCCESS);
552 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
553
554 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargePositiveMinus1, &g_LargePositive), VINF_SUCCESS);
555 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositiveMinus1) == 0);
556
557 RTTESTI_CHECK_RC(RTBigNumAdd(&Result, &g_LargePositiveMinus1, &g_LargePositive), VINF_SUCCESS);
558 RTTESTI_CHECK_RC(RTBigNumAdd(&Tmp, &g_LargePositive, &Result), VINF_SUCCESS);
559 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &Tmp, &g_LargePositiveMinus1), VINF_SUCCESS);
560 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
561 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &Tmp, &g_LargePositive), VINF_SUCCESS);
562 RTTESTI_CHECK(RTBigNumCompare(&Result, &g_LargePositiveMinus1) == 0);
563
564 RTTESTI_CHECK_RC(RTBigNumModulo(&Result, &g_LargeNegative, &g_LargeNegativePluss1), VINF_SUCCESS);
565 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, -1) == 0);
566
567 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
568 }
569}
570
571
572static void testExponentiation(void)
573{
574 RTTestSub(g_hTest, "RTBigNumExponentiate");
575
576 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
577 {
578 RTBIGNUM Result;
579 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
580 RTBIGNUM Result2;
581 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result2, fFlags), VINF_SUCCESS);
582
583 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_One, &g_One), VINF_SUCCESS);
584 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
585
586 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_One), VINF_SUCCESS);
587 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
588
589 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_Two), VINF_SUCCESS);
590 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 4) == 0);
591
592 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Two, &g_Ten), VINF_SUCCESS);
593 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1024) == 0);
594
595 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Five, &g_Five), VINF_SUCCESS);
596 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3125) == 0);
597
598 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &g_Five, &g_Ten), VINF_SUCCESS);
599 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 9765625) == 0);
600
601 static struct
602 {
603 const char *pszBase, *pszExponent, *pszResult;
604 } s_aTests[] =
605 {
606 {
607 "180DB4284A119D6133AE4BB0C27C27D1", /*^*/ "3A", /* = */
608 "04546412B9E39476F10009F62608F614774C5AE475482434F138C3EA976583ECE09E58F1F03CE41F821A1D5DA59B69D031290B0AC7F7D5058E3AFA2CA3DAA7261D1620CA"
609 "D050576C0AFDF51ADBFCB9073B9D8324E816EA6BE4648DF68092F6617ED609045E6BE9D5410AE2CFF725832414E67656233F4DFA952461D321282426D50E2AF524D779EC"
610 "0744547E8A4F0768C2C49AF3A5A89D129430CA58456BE4534BC53C67523506C7A8B5770D88CF28B6B3EEBE73F3EA71BA2CE27C4C89BE0D699922B1A1EB20143CB0830A43"
611 "D864DDFFF026BA781614C2D55F3EDEA7257B93A0F40824E57D6EDFCFFB4611C316374D0D15698E6584851F1898DCAE75FC4D180908763DDB2FF93766EF144D091274AFE5"
612 "6980A1F4F574D577DAD833EA9486A4B499BFCA9C08225D7BDB2C632B4D9B53EF51C02ED419F22657D626064BCC2B083CD664E1A8D68F82F33233A833AC98AA0282B8B88D"
613 "A430CF2E581A1C7C4A1D646CA42760ED10C398F7C032A94D53964E6885B5C1CA884EC15081D4C010978627C85767FEC6F93364044EA86567F9610ABFB837808CC995FB5F"
614 "710B21CE198E0D4AD9F73C3BD56CB9965C85C790BF3F4B326B5245BFA81783126217BF80687C4A8AA3AE80969A4407191B4F90E71A0ABCCB5FEDD40477CE9D10FBAEF103"
615 "8457AB19BD793CECDFF8B29A96F12F590BFED544E08F834A44DEEF461281C40024EFE9388689AAC69BCBAB3D06434172D9319F30754756E1CF77B300679215BEBD27FC20"
616 "A2F1D2029BC767D4894A5F7B21BD784CD1DD4F41697839969CB6D2AA1E0AFA5D3D644A792586F681EB36475CAE59EB457E55D6AC2E286E196BFAC000C7389A96C514552D"
617 "5D9D3DD962F72DAE4A7575A9A67856646239560A39E50826BB2523598C8F8FF0EC8D09618378E9F362A8FBFE842B55CD1855A95D8A5E93B8B91D31EB8FBBF57113F06171"
618 "BB69B81C4240EC4C7D1AC67EA1CE4CEBEE71828917EC1CF500E1AD2F09535F5498CD6E613383810A840A265AED5DD20AE58FFF2D0DEB8EF99FA494B22714F520E8E8B684"
619 "5E8521966A7B1699236998A730FDF9F049CE2A4EA44D1EBC3B9754908848540D0DEE64A6D60E2BFBC3362B659C10543BDC20C1BAD3D68B173442C100C2C366CB885E8490"
620 "EDB977E49E9D51D4427B73B3B999AF4BA17685387182C3918D20808197A2E3FCDD0F66ECDEC05542C23A08B94C83BDF93606A49E9A0645B002CFCA1EAE1917BEED0D6542"
621 "9A0EF00E5FB5F70D61C8C4DF1F1E9DA58188A221"
622 },
623 {
624 "03", /*^*/ "164b", /* = */
625 "29ABEC229C2B15C41573F8608D4DCD2DADAACA94CA3C40B42FFAD32D6202E228E16F61E050FF97EC5D45F24A4EB057C2D1A5DA72DFC5944E6941DBEDDE70EF56702BEC35"
626 "A3150EFE84E87185E3CBAB1D73F434EB820E41298BDD4F3941230DFFD8DFF1D2E2F3C5D0CB5088505B9C78507A81AAD8073C28B8FA70771C3E04110344328C6B3F38E55A"
627 "32B009F4DDA1813232C3FF422DF4E4D12545C803C63D0BE67E2E773B2BAC41CC69D895787B217D7BE9CE80BD4B500AE630AA21B50A06E0A74953F8011E9F23863CA79885"
628 "35D5FF0214DBD9B25756BE3D43008A15C018348E6A7C3355F4BECF37595BD530E5AC1AD3B14182862E47AD002097465F6B78F435B0D6365E18490567F508CD3CAAAD340A"
629 "E76A218FE8B517F923FE9CCDE61CB35409590CDBC606D89BA33B32A3862DEE7AB99DFBE103D02D2BED6D418B949E6B3C51CAB8AB5BE93AA104FA10D3A02D4CAD6700CD0F"
630 "83922EAAB18705915198DE51C1C562984E2B7571F36A4D756C459B61E0A4B7DE268A74E807311273DD51C2863771AB72504044C870E2498F13BF1DE92C13D93008E304D2"
631 "879C5D8A646DB5BF7BC64D96BB9E2FBA2EA6BF55CD825ABD995762F661C327133BE01F9A9F298CA096B3CE61CBBD8047A003870B218AC505D72ED6C7BF3B37BE5877B6A1"
632 "606A713EE86509C99B2A3627FD74AE7E81FE7F69C34B40E01A6F8B18A328E0F9D18A7911E5645331540538AA76B6D5D591F14313D730CFE30728089A245EE91058748F0C"
633 "E3E6CE4DE51D23E233BFF9007E0065AEBAA3FB0D0FACE62A4757FE1C9C7075E2214071197D5074C92AF1E6D853F7DE782F32F1E40507CB981A1C10AC6B1C23AC46C07EF1"
634 "EDE857C444902B936771DF75E0EE6C2CB3F0F9DBB387BAD0658E98F42A7338DE45E2F1B012B530FFD66861F74137C041D7558408A4A23B83FBDDE494381D9F9FF0326D44"
635 "302F75DE68B91A54CFF6E3C2821D09F2664CA74783C29AF98E2F1D3D84CAC49EAE55BABE3D2CBE8833D50517109E19CB5C63D1DE26E308ACC213D1CBCCF7C3AAE05B06D9"
636 "909AB0A1AEFD02A193CFADC7F724D377E1F4E78DC21012BE26D910548CDF55B0AB9CB64756045FF48C3B858E954553267C4087EC5A9C860CFA56CF5CFBB442BDDA298230"
637 "D6C000A6A6010D87FB4C3859C3AFAF15C37BCE03EBC392E8149056C489508841110060A991F1EEAF1E7CCF0B279AB2B35F3DAC0FAB4F4A107794E67D305E6D61A27C8FEB"
638 "DEA00C3334C888B2092E740DD3EFF7A69F06CE12EF511126EB23D80902D1D54BF4AEE04DF9457D59E8859AA83D6229481E1B1BC7C3ED96F6F7C1CEEF7B904268FD00BE51"
639 "1EF69692D593F8A9F7CCC053C343306940A4054A55DBA94D95FF6D02B7A73E110C2DBE6CA29C01B5921420B5BC9C92DAA9D82003829C6AE772FF12135C2E138C6725DC47"
640 "7938F3062264575EBBB1CBB359E496DD7A38AE0E33D1B1D9C16BDD87E6DE44DFB832286AE01D00AA14B423DBF7ECCC34A0A06A249707B75C2BA931D7F4F513FDF0F6E516"
641 "345B8DA85FEFD218B390828AECADF0C47916FAF44CB29010B0BB2BBA8E120B6DAFB2CC90B9D1B8659C2AFB"
642 }
643 };
644 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
645 {
646 RTBIGNUM Base, Exponent, Expected;
647 if ( testHexStringToNum(&Base, s_aTests[i].pszBase, RTBIGNUMINIT_F_UNSIGNED | fFlags)
648 && testHexStringToNum(&Exponent, s_aTests[i].pszExponent, RTBIGNUMINIT_F_UNSIGNED | fFlags)
649 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
650 {
651 RTTESTI_CHECK_RC(RTBigNumExponentiate(&Result, &Base, &Exponent), VINF_SUCCESS);
652 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
653 RTTESTI_CHECK_RC(RTBigNumDestroy(&Base), VINF_SUCCESS);
654 RTTESTI_CHECK_RC(RTBigNumDestroy(&Exponent), VINF_SUCCESS);
655 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
656 }
657 }
658 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
659 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result2), VINF_SUCCESS);
660 }
661}
662
663
664static void testModExp(void)
665{
666 RTTestSub(g_hTest, "RTBigNumModExp");
667
668 for (uint32_t fFlags = 0; fFlags <= RTBIGNUMINIT_F_SENSITIVE; fFlags += RTBIGNUMINIT_F_SENSITIVE)
669 {
670 RTBIGNUM Result;
671 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Result, fFlags), VINF_SUCCESS);
672
673 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_One, &g_One, &g_One), VINF_SUCCESS);
674 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
675 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_One, &g_One), VINF_SUCCESS);
676 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
677 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_LargePositive, &g_One), VINF_SUCCESS);
678 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
679
680 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_One, &g_Zero, &g_Five), VINF_SUCCESS);
681 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
682 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_Five), VINF_SUCCESS);
683 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
684 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_One), VINF_SUCCESS);
685 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
686 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_LargePositive), VINF_SUCCESS);
687 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 1);
688
689 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Zero, &g_Zero, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
690 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_Zero, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
691 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_LargePositive, &g_LargePositive, &g_Zero), VERR_BIGNUM_DIV_BY_ZERO);
692
693 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Two, &g_Four, &g_Five), VINF_SUCCESS);
694 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
695
696 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Two, &g_Four, &g_Three), VINF_SUCCESS);
697 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 1) == 0);
698
699 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Three, &g_Three), VINF_SUCCESS);
700 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 0) == 0);
701
702 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Three, &g_Five), VINF_SUCCESS);
703 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 2) == 0);
704
705 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Five, &g_Five), VINF_SUCCESS);
706 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3) == 0);
707
708 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &g_Three, &g_Five, &g_Four), VINF_SUCCESS);
709 RTTESTI_CHECK(RTBigNumCompareWithS64(&Result, 3) == 0);
710
711#if 0
712 static struct
713 {
714 const char *pszBase, *pszExponent, *pszModulus, *pszResult;
715 } s_aTests[] =
716 {
717 {
718 "180DB4284A119D6133AE4BB0C27C27D1", /*^*/ "3A", /*mod */ " ", /* = */
719 },
720 };
721 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
722 {
723 RTBIGNUM Base, Exponent, Expected, Modulus;
724 if ( testHexStringToNum(&Base, s_aTests[i].pszBase, RTBIGNUMINIT_F_UNSIGNED | fFlags)
725 && testHexStringToNum(&Exponent, s_aTests[i].pszExponent, RTBIGNUMINIT_F_UNSIGNED | fFlags)
726 && testHexStringToNum(&Modulus, s_aTests[i].pszModulus, RTBIGNUMINIT_F_UNSIGNED | fFlags)
727 && testHexStringToNum(&Expected, s_aTests[i].pszResult, RTBIGNUMINIT_F_UNSIGNED | fFlags))
728 {
729 RTTESTI_CHECK_RC(RTBigNumModExp(&Result, &Base, &Exponent, &Modulus), VINF_SUCCESS);
730 RTTESTI_CHECK(RTBigNumCompare(&Result, &Expected) == 0);
731 RTTESTI_CHECK_RC(RTBigNumDestroy(&Base), VINF_SUCCESS);
732 RTTESTI_CHECK_RC(RTBigNumDestroy(&Exponent), VINF_SUCCESS);
733 RTTESTI_CHECK_RC(RTBigNumDestroy(&Expected), VINF_SUCCESS);
734 RTTESTI_CHECK_RC(RTBigNumDestroy(&Modulus), VINF_SUCCESS);
735 }
736 }
737#endif
738
739 RTTESTI_CHECK_RC(RTBigNumDestroy(&Result), VINF_SUCCESS);
740 }
741}
742
743
744static void testToBytes(void)
745{
746 RTTestSub(g_hTest, "RTBigNumToBytes*Endian");
747 uint8_t abBuf[sizeof(g_abLargePositive) + sizeof(g_abLargeNegative)];
748
749 memset(abBuf, 0xcc, sizeof(abBuf));
750 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 1), VINF_SUCCESS);
751 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0xcc);
752
753 memset(abBuf, 0xcc, sizeof(abBuf));
754 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 2), VINF_SUCCESS);
755 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0xcc);
756
757 memset(abBuf, 0xcc, sizeof(abBuf));
758 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 3), VINF_SUCCESS);
759 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0 && abBuf[3] == 0xcc);
760
761 memset(abBuf, 0xcc, sizeof(abBuf));
762 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Zero, abBuf, 4), VINF_SUCCESS);
763 RTTESTI_CHECK(abBuf[0] == 0 && abBuf[1] == 0 && abBuf[2] == 0 && abBuf[3] == 0 && abBuf[4] == 0xcc);
764
765
766 memset(abBuf, 0xcc, sizeof(abBuf));
767 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 1), VINF_SUCCESS);
768 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xcc && abBuf[2] == 0xcc && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
769
770 memset(abBuf, 0xcc, sizeof(abBuf));
771 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 2), VINF_SUCCESS);
772 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xcc && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
773
774 memset(abBuf, 0xcc, sizeof(abBuf));
775 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 3), VINF_SUCCESS);
776 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xff && abBuf[3] == 0xcc && abBuf[4] == 0xcc);
777
778 memset(abBuf, 0xcc, sizeof(abBuf));
779 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_Minus1, abBuf, 4), VINF_SUCCESS);
780 RTTESTI_CHECK(abBuf[0] == 0xff && abBuf[1] == 0xff && abBuf[2] == 0xff && abBuf[3] == 0xff && abBuf[4] == 0xcc);
781
782
783 memset(abBuf, 0xcc, sizeof(abBuf));
784 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_LargePositive, abBuf, sizeof(g_abLargePositive)), VINF_SUCCESS);
785 RTTESTI_CHECK(memcmp(abBuf, g_abLargePositive, sizeof(g_abLargePositive)) == 0);
786 RTTESTI_CHECK(abBuf[sizeof(g_abLargePositive)] == 0xcc);
787
788 memset(abBuf, 0xcc, sizeof(abBuf));
789 RTTESTI_CHECK_RC(RTBigNumToBytesBigEndian(&g_LargePositive, abBuf, sizeof(g_abLargePositive) -1 ), VERR_BUFFER_OVERFLOW);
790 RTTESTI_CHECK(memcmp(abBuf, &g_abLargePositive[1], sizeof(g_abLargePositive) - 1) == 0);
791 RTTESTI_CHECK(abBuf[sizeof(g_abLargePositive) - 1] == 0xcc);
792
793}
794
795
796static void testBenchmarks(void)
797{
798 RTTestSub(g_hTest, "Benchmarks");
799
800 /* For the modexp benchmark we decrypt a real PKCS #7 signature. */
801 static uint8_t const s_abPubKeyExp[] = { 0x01, 0x00, 0x01 };
802 RTBIGNUM PubKeyExp;
803 RTTESTI_CHECK_RC_RETV(RTBigNumInit(&PubKeyExp, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
804 s_abPubKeyExp, sizeof(s_abPubKeyExp)), VINF_SUCCESS);
805
806 static uint8_t const s_abPubKeyMod[] =
807 {
808 0x00, 0xea, 0x61, 0x4e, 0xa0, 0xb2, 0xae, 0x38, 0xbc, 0x43, 0x24, 0x5a, 0x28, 0xc7, 0xa0, 0x69,
809 0x82, 0x11, 0xd5, 0x78, 0xe8, 0x6b, 0x41, 0x54, 0x7b, 0x6c, 0x69, 0x13, 0xc8, 0x68, 0x75, 0x0f,
810 0xe4, 0x66, 0x54, 0xcd, 0xe3, 0x55, 0x33, 0x3b, 0x7f, 0x9f, 0x55, 0x75, 0x80, 0x6e, 0xd0, 0x8a,
811 0xff, 0xc1, 0xf4, 0xbf, 0xfd, 0x70, 0x9b, 0x73, 0x7e, 0xee, 0xf1, 0x80, 0x23, 0xd4, 0xbd, 0xba,
812 0xdc, 0xce, 0x09, 0x4a, 0xeb, 0xb0, 0xdd, 0x86, 0x4a, 0x0b, 0x8e, 0x3e, 0x9a, 0x8a, 0x58, 0xed,
813 0x98, 0x4f, 0x25, 0xe5, 0x0c, 0x18, 0xd8, 0x10, 0x95, 0xce, 0xe4, 0x19, 0x82, 0x38, 0xcd, 0x76,
814 0x6a, 0x38, 0xe5, 0x14, 0xe6, 0x95, 0x0d, 0x80, 0xc5, 0x09, 0x5e, 0x93, 0xf4, 0x6f, 0x82, 0x8e,
815 0x9c, 0x81, 0x09, 0xd6, 0xd4, 0xee, 0xd5, 0x1f, 0x94, 0x2d, 0x13, 0x18, 0x9a, 0xbc, 0x88, 0x5d,
816 0x9a, 0xe5, 0x66, 0x08, 0x99, 0x93, 0x1b, 0x8a, 0x69, 0x3f, 0x68, 0xb2, 0x97, 0x2a, 0x24, 0xf6,
817 0x65, 0x2a, 0x94, 0x33, 0x94, 0x14, 0x5c, 0x6f, 0xff, 0x95, 0xd0, 0x2b, 0xf0, 0x2b, 0xcb, 0x49,
818 0xcd, 0x03, 0x3a, 0x45, 0xd5, 0x22, 0x1c, 0xb3, 0xee, 0xd5, 0xaf, 0xb3, 0x5b, 0xcb, 0x1b, 0x35,
819 0x4e, 0xff, 0x21, 0x0a, 0x55, 0x1f, 0xa0, 0xf9, 0xdc, 0xad, 0x7a, 0x89, 0x0b, 0x6e, 0x3f, 0x75,
820 0xc0, 0x6c, 0x44, 0xff, 0x90, 0x63, 0x79, 0xcf, 0x70, 0x20, 0x60, 0x33, 0x3c, 0xb1, 0xfa, 0x6b,
821 0x6c, 0x55, 0x3c, 0xeb, 0x8d, 0x18, 0xe9, 0x0a, 0x81, 0xd5, 0x24, 0xc1, 0x88, 0x7c, 0xa6, 0x8e,
822 0xd3, 0x2c, 0x51, 0x1d, 0x6d, 0xdf, 0x51, 0xd5, 0x72, 0x54, 0x7a, 0x98, 0xc0, 0x36, 0x35, 0x21,
823 0x66, 0x3c, 0x2f, 0x01, 0xc0, 0x8e, 0xb0, 0x56, 0x60, 0x6e, 0x67, 0x4f, 0x5f, 0xac, 0x05, 0x60,
824 0x9b
825 };
826 RTBIGNUM PubKeyMod;
827 RTTESTI_CHECK_RC_RETV(RTBigNumInit(&PubKeyMod, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
828 s_abPubKeyMod, sizeof(s_abPubKeyMod)), VINF_SUCCESS);
829
830 static uint8_t const s_abSignature[] =
831 {
832 0x00, 0xae, 0xca, 0x93, 0x47, 0x0b, 0xfa, 0xd8, 0xb9, 0xbb, 0x5a, 0x5e, 0xf6, 0x75, 0x90, 0xed,
833 0x80, 0x37, 0x03, 0x6d, 0x23, 0x91, 0x30, 0x0c, 0x9d, 0xbf, 0x34, 0xc1, 0xf9, 0x43, 0xa7, 0xec,
834 0xc0, 0x83, 0xc0, 0x98, 0x3f, 0x8a, 0x65, 0x48, 0x7c, 0xa4, 0x9f, 0x14, 0x4d, 0x52, 0x90, 0x2d,
835 0x17, 0xd1, 0x3e, 0x05, 0xd6, 0x35, 0x1b, 0xdb, 0xe5, 0x1a, 0xa2, 0x54, 0x8c, 0x30, 0x6f, 0xfe,
836 0xa1, 0xd9, 0x98, 0x3f, 0xb5, 0x65, 0x14, 0x9c, 0x50, 0x55, 0xa1, 0xbf, 0xb5, 0x12, 0xc4, 0xf2,
837 0x72, 0x27, 0x14, 0x59, 0xb5, 0x23, 0x67, 0x11, 0x2a, 0xd8, 0xa8, 0x85, 0x4b, 0xc5, 0xb0, 0x2f,
838 0x73, 0x54, 0xcf, 0x33, 0xa0, 0x06, 0xf2, 0x8e, 0x4f, 0x4b, 0x18, 0x97, 0x08, 0x47, 0xce, 0x0c,
839 0x47, 0x97, 0x0d, 0xbd, 0x8b, 0xce, 0x61, 0x31, 0x21, 0x7e, 0xc4, 0x1d, 0x03, 0xf8, 0x06, 0xca,
840 0x9f, 0xd3, 0x5e, 0x4b, 0xfc, 0xf1, 0x99, 0x34, 0x78, 0x83, 0xfa, 0xab, 0x9c, 0x7c, 0x6b, 0x5c,
841 0x3d, 0x45, 0x39, 0x6d, 0x6a, 0x6c, 0xd5, 0x63, 0x3e, 0xbe, 0x09, 0x62, 0x64, 0x5f, 0x83, 0x3b,
842 0xb6, 0x5c, 0x7e, 0x8e, 0xeb, 0x1e, 0x6a, 0x34, 0xb9, 0xc7, 0x92, 0x92, 0x58, 0x64, 0x48, 0xfe,
843 0xf8, 0x35, 0x53, 0x07, 0x89, 0xb4, 0x29, 0x4d, 0x3d, 0x79, 0x43, 0x73, 0x0f, 0x16, 0x21, 0xab,
844 0xb7, 0x07, 0x2b, 0x5a, 0x8a, 0x0f, 0xd7, 0x2e, 0x95, 0xb4, 0x26, 0x66, 0x65, 0x72, 0xac, 0x7e,
845 0x46, 0x70, 0xe6, 0xad, 0x43, 0xa2, 0x73, 0x54, 0x6a, 0x41, 0xc8, 0x9c, 0x1e, 0x65, 0xed, 0x06,
846 0xd1, 0xc7, 0x99, 0x3e, 0x5f, 0x5a, 0xd3, 0xd0, 0x1a, 0x9b, 0x0e, 0x3e, 0x04, 0x66, 0xb6, 0xaa,
847 0xa6, 0x51, 0xb8, 0xc0, 0x13, 0x19, 0x34, 0x0e, 0x86, 0x02, 0xd5, 0xc8, 0x10, 0xaa, 0x1f, 0x97,
848 0x95
849 };
850 RTBIGNUM Signature;
851 RTTESTI_CHECK_RC_RETV(RTBigNumInit(&Signature, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
852 s_abSignature, sizeof(s_abSignature)), VINF_SUCCESS);
853
854 RTBIGNUM Decrypted;
855 RTTESTI_CHECK_RC_RETV(RTBigNumInitZero(&Decrypted, 0 /*fFlags*/), VINF_SUCCESS);
856 RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &Signature, &PubKeyExp, &PubKeyMod), VINF_SUCCESS);
857 RTTESTI_CHECK_RC_RETV(RTBigNumModExp(&Decrypted, &Signature, &PubKeyExp, &PubKeyMod), VINF_SUCCESS);
858
859 RTThreadYield();
860 int rc = VINF_SUCCESS;
861 uint32_t cRounds = 0;
862 uint64_t uStartTS = RTTimeNanoTS();
863 while (cRounds < 256)
864 {
865 rc |= RTBigNumModExp(&Decrypted, &Signature, &PubKeyExp, &PubKeyMod);
866 cRounds++;
867 }
868 uint64_t uElapsed = RTTimeNanoTS() - uStartTS;
869 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
870 RTTestIValue("RTBigNumModExp", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
871
872#if 1
873 /* Compare with OpenSSL BN. */
874 BN_CTX *pObnCtx = BN_CTX_new();
875 BIGNUM *pObnPubKeyExp = BN_bin2bn(s_abPubKeyExp, sizeof(s_abPubKeyExp), NULL);
876 BIGNUM *pObnPubKeyMod = BN_bin2bn(s_abPubKeyMod, sizeof(s_abPubKeyMod), NULL);
877 BIGNUM *pObnSignature = BN_bin2bn(s_abSignature, sizeof(s_abSignature), NULL);
878 BIGNUM *pObnResult = BN_new();
879 RTTESTI_CHECK_RETV(BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx) == 1);
880 BN_CTX_free(pObnCtx);
881
882 rc = 1;
883 cRounds = 0;
884 uStartTS = RTTimeNanoTS();
885 while (cRounds < 4096)
886 {
887 pObnCtx = BN_CTX_new();
888 rc &= BN_mod_exp(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
889 BN_CTX_free(pObnCtx);
890 cRounds++;
891 }
892 uElapsed = RTTimeNanoTS() - uStartTS;
893 RTTESTI_CHECK_RC(rc, 1);
894 RTTestIValue("BN_mod_exp", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
895
896 rc = 1;
897 cRounds = 0;
898 uStartTS = RTTimeNanoTS();
899 while (cRounds < 4096)
900 {
901 pObnCtx = BN_CTX_new();
902 rc &= BN_mod_exp_simple(pObnResult, pObnSignature, pObnPubKeyExp, pObnPubKeyMod, pObnCtx);
903 BN_CTX_free(pObnCtx);
904 cRounds++;
905 }
906 uElapsed = RTTimeNanoTS() - uStartTS;
907 RTTESTI_CHECK_RC(rc, 1);
908 RTTestIValue("BN_mod_exp_simple", uElapsed / cRounds, RTTESTUNIT_NS_PER_CALL);
909#endif
910}
911
912
913
914int main(int argc, char **argv)
915{
916 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTBigNum", &g_hTest);
917 if (rcExit != RTEXITCODE_SUCCESS)
918 return rcExit;
919 RTTestBanner(g_hTest);
920
921 /* Init fixed integers. */
922 RTTestSub(g_hTest, "RTBigNumInit");
923 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositive, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
924 g_abLargePositive, sizeof(g_abLargePositive)), VINF_SUCCESS);
925 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositive2, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
926 g_abLargePositive, sizeof(g_abLargePositive) - 11), VINF_SUCCESS);
927 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargePositiveMinus1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
928 g_abLargePositiveMinus1, sizeof(g_abLargePositiveMinus1)), VINF_SUCCESS);
929 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegative, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
930 g_abLargeNegative, sizeof(g_abLargeNegative)), VINF_SUCCESS);
931 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegative2, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
932 g_abLargeNegative, sizeof(g_abLargeNegative) - 9), VINF_SUCCESS);
933 RTTESTI_CHECK_RC(RTBigNumInit(&g_LargeNegativePluss1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
934 g_abLargeNegativePluss1, sizeof(g_abLargeNegativePluss1)), VINF_SUCCESS);
935 RTTESTI_CHECK_RC(RTBigNumInit(&g_64BitPositive1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
936 g_ab64BitPositive1, sizeof(g_ab64BitPositive1)), VINF_SUCCESS);
937
938 RTTESTI_CHECK_RC(RTBigNumInitZero(&g_Zero, 0), VINF_SUCCESS);
939 RTTESTI_CHECK_RC(RTBigNumInit(&g_One, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x01", 1), VINF_SUCCESS);
940 RTTESTI_CHECK_RC(RTBigNumInit(&g_Two, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x02", 1), VINF_SUCCESS);
941 RTTESTI_CHECK_RC(RTBigNumInit(&g_Three, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x03", 1), VINF_SUCCESS);
942 RTTESTI_CHECK_RC(RTBigNumInit(&g_Four, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x04", 1), VINF_SUCCESS);
943 RTTESTI_CHECK_RC(RTBigNumInit(&g_Five, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x05", 1), VINF_SUCCESS);
944 RTTESTI_CHECK_RC(RTBigNumInit(&g_Ten, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x0a", 1), VINF_SUCCESS);
945 RTTESTI_CHECK_RC(RTBigNumInit(&g_FourtyTwo, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED, "\x2a", 1), VINF_SUCCESS);
946
947 RTTESTI_CHECK_RC(RTBigNumInit(&g_Minus1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_SIGNED,
948 g_abMinus1, sizeof(g_abMinus1)), VINF_SUCCESS);
949 testMoreInit();
950
951 if (RTTestIErrorCount() == 0)
952 {
953 if (argc != 2)
954 {
955 /* Do testing. */
956 testCompare();
957 testSubtraction();
958 testAddition();
959 testMultiplication();
960 testDivision();
961 testModulo();
962 testExponentiation();
963 testModExp();
964 testToBytes();
965 }
966
967 /* Benchmarks */
968 testBenchmarks();
969
970 /* Cleanups. */
971 RTTestSub(g_hTest, "RTBigNumDestroy");
972 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargePositive), VINF_SUCCESS);
973 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargePositive2), VINF_SUCCESS);
974 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargeNegative), VINF_SUCCESS);
975 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_LargeNegative2), VINF_SUCCESS);
976 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_Zero), VINF_SUCCESS);
977 RTTESTI_CHECK_RC(RTBigNumDestroy(&g_64BitPositive1), VINF_SUCCESS);
978 }
979
980 return RTTestSummaryAndDestroy(g_hTest);
981}
982
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