blob: c5548db975ff1c7ccd47e8fb2edf34723408f2a3 [file] [log] [blame]
Adam Langleye9ada862015-05-11 17:20:37 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
59 *
60 * Portions of the attached software ("Contribution") are developed by
61 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
62 *
63 * The Contribution is licensed pursuant to the Eric Young open source
64 * license provided above.
65 *
66 * The binary polynomial arithmetic software is originally written by
67 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
68 * Laboratories. */
69
David Benjamin7c0d06c2016-08-11 13:26:41 -040070/* Per C99, various stdint.h and inttypes.h macros (the latter used by bn.h) are
71 * unavailable in C++ unless some macros are defined. C++11 overruled this
72 * decision, but older Android NDKs still require it. */
73#if !defined(__STDC_CONSTANT_MACROS)
74#define __STDC_CONSTANT_MACROS
75#endif
Adam Langleye9ada862015-05-11 17:20:37 -070076#if !defined(__STDC_FORMAT_MACROS)
77#define __STDC_FORMAT_MACROS
78#endif
79
David Benjaminc895d6b2016-08-11 13:26:41 -040080#include <assert.h>
Adam Langleyf4e42722015-06-04 17:45:09 -070081#include <errno.h>
David Benjaminc895d6b2016-08-11 13:26:41 -040082#include <limits.h>
Adam Langleye9ada862015-05-11 17:20:37 -070083#include <stdio.h>
84#include <string.h>
85
Adam Langley4139edb2016-01-13 15:00:54 -080086#include <utility>
87
Adam Langleye9ada862015-05-11 17:20:37 -070088#include <openssl/bn.h>
David Benjaminf0c4a6c2016-08-11 13:26:41 -040089#include <openssl/bytestring.h>
Adam Langleye9ada862015-05-11 17:20:37 -070090#include <openssl/crypto.h>
91#include <openssl/err.h>
92#include <openssl/mem.h>
93
David Benjaminf0c4a6c2016-08-11 13:26:41 -040094#include "../internal.h"
95#include "../test/file_test.h"
96#include "../test/test_util.h"
Adam Langleye9ada862015-05-11 17:20:37 -070097
98
David Benjaminf0c4a6c2016-08-11 13:26:41 -040099static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
Adam Langley4139edb2016-01-13 15:00:54 -0800100 BIGNUM *raw = NULL;
101 int ret = BN_hex2bn(&raw, in);
102 out->reset(raw);
103 return ret;
104}
105
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400106static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *attribute) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400107 std::string hex;
108 if (!t->GetAttribute(&hex, attribute)) {
109 return nullptr;
110 }
111
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400112 bssl::UniquePtr<BIGNUM> ret;
David Benjaminc895d6b2016-08-11 13:26:41 -0400113 if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
114 t->PrintLine("Could not decode '%s'.", hex.c_str());
115 return nullptr;
116 }
117 return ret;
118}
119
120static bool GetInt(FileTest *t, int *out, const char *attribute) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400121 bssl::UniquePtr<BIGNUM> ret = GetBIGNUM(t, attribute);
David Benjaminc895d6b2016-08-11 13:26:41 -0400122 if (!ret) {
Adam Langleye9ada862015-05-11 17:20:37 -0700123 return false;
124 }
125
David Benjaminc895d6b2016-08-11 13:26:41 -0400126 BN_ULONG word = BN_get_word(ret.get());
127 if (word > INT_MAX) {
128 return false;
Adam Langleye9ada862015-05-11 17:20:37 -0700129 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400130
131 *out = static_cast<int>(word);
Adam Langleye9ada862015-05-11 17:20:37 -0700132 return true;
133}
134
David Benjaminc895d6b2016-08-11 13:26:41 -0400135static bool ExpectBIGNUMsEqual(FileTest *t, const char *operation,
136 const BIGNUM *expected, const BIGNUM *actual) {
137 if (BN_cmp(expected, actual) == 0) {
138 return true;
139 }
140
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400141 bssl::UniquePtr<char> expected_str(BN_bn2hex(expected));
142 bssl::UniquePtr<char> actual_str(BN_bn2hex(actual));
David Benjaminc895d6b2016-08-11 13:26:41 -0400143 if (!expected_str || !actual_str) {
Adam Langleye9ada862015-05-11 17:20:37 -0700144 return false;
145 }
146
David Benjaminc895d6b2016-08-11 13:26:41 -0400147 t->PrintLine("Got %s =", operation);
148 t->PrintLine("\t%s", actual_str.get());
149 t->PrintLine("wanted:");
150 t->PrintLine("\t%s", expected_str.get());
151 return false;
Adam Langleye9ada862015-05-11 17:20:37 -0700152}
153
David Benjaminc895d6b2016-08-11 13:26:41 -0400154static bool TestSum(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400155 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
156 bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
157 bssl::UniquePtr<BIGNUM> sum = GetBIGNUM(t, "Sum");
David Benjaminc895d6b2016-08-11 13:26:41 -0400158 if (!a || !b || !sum) {
Adam Langleye9ada862015-05-11 17:20:37 -0700159 return false;
160 }
161
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400162 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400163 if (!ret ||
164 !BN_add(ret.get(), a.get(), b.get()) ||
165 !ExpectBIGNUMsEqual(t, "A + B", sum.get(), ret.get()) ||
166 !BN_sub(ret.get(), sum.get(), a.get()) ||
167 !ExpectBIGNUMsEqual(t, "Sum - A", b.get(), ret.get()) ||
168 !BN_sub(ret.get(), sum.get(), b.get()) ||
169 !ExpectBIGNUMsEqual(t, "Sum - B", a.get(), ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700170 return false;
171 }
172
David Benjaminc895d6b2016-08-11 13:26:41 -0400173 // Test that the functions work when |r| and |a| point to the same |BIGNUM|,
174 // or when |r| and |b| point to the same |BIGNUM|. TODO: Test the case where
175 // all of |r|, |a|, and |b| point to the same |BIGNUM|.
176 if (!BN_copy(ret.get(), a.get()) ||
177 !BN_add(ret.get(), ret.get(), b.get()) ||
178 !ExpectBIGNUMsEqual(t, "A + B (r is a)", sum.get(), ret.get()) ||
179 !BN_copy(ret.get(), b.get()) ||
180 !BN_add(ret.get(), a.get(), ret.get()) ||
181 !ExpectBIGNUMsEqual(t, "A + B (r is b)", sum.get(), ret.get()) ||
182 !BN_copy(ret.get(), sum.get()) ||
183 !BN_sub(ret.get(), ret.get(), a.get()) ||
184 !ExpectBIGNUMsEqual(t, "Sum - A (r is a)", b.get(), ret.get()) ||
185 !BN_copy(ret.get(), a.get()) ||
186 !BN_sub(ret.get(), sum.get(), ret.get()) ||
187 !ExpectBIGNUMsEqual(t, "Sum - A (r is b)", b.get(), ret.get()) ||
188 !BN_copy(ret.get(), sum.get()) ||
189 !BN_sub(ret.get(), ret.get(), b.get()) ||
190 !ExpectBIGNUMsEqual(t, "Sum - B (r is a)", a.get(), ret.get()) ||
191 !BN_copy(ret.get(), b.get()) ||
192 !BN_sub(ret.get(), sum.get(), ret.get()) ||
193 !ExpectBIGNUMsEqual(t, "Sum - B (r is b)", a.get(), ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700194 return false;
195 }
196
David Benjaminc895d6b2016-08-11 13:26:41 -0400197 // Test |BN_uadd| and |BN_usub| with the prerequisites they are documented as
198 // having. Note that these functions are frequently used when the
199 // prerequisites don't hold. In those cases, they are supposed to work as if
200 // the prerequisite hold, but we don't test that yet. TODO: test that.
201 if (!BN_is_negative(a.get()) &&
202 !BN_is_negative(b.get()) && BN_cmp(a.get(), b.get()) >= 0) {
203 if (!BN_uadd(ret.get(), a.get(), b.get()) ||
204 !ExpectBIGNUMsEqual(t, "A +u B", sum.get(), ret.get()) ||
205 !BN_usub(ret.get(), sum.get(), a.get()) ||
206 !ExpectBIGNUMsEqual(t, "Sum -u A", b.get(), ret.get()) ||
207 !BN_usub(ret.get(), sum.get(), b.get()) ||
208 !ExpectBIGNUMsEqual(t, "Sum -u B", a.get(), ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700209 return false;
210 }
211
David Benjaminc895d6b2016-08-11 13:26:41 -0400212 // Test that the functions work when |r| and |a| point to the same |BIGNUM|,
213 // or when |r| and |b| point to the same |BIGNUM|. TODO: Test the case where
214 // all of |r|, |a|, and |b| point to the same |BIGNUM|.
215 if (!BN_copy(ret.get(), a.get()) ||
216 !BN_uadd(ret.get(), ret.get(), b.get()) ||
217 !ExpectBIGNUMsEqual(t, "A +u B (r is a)", sum.get(), ret.get()) ||
218 !BN_copy(ret.get(), b.get()) ||
219 !BN_uadd(ret.get(), a.get(), ret.get()) ||
220 !ExpectBIGNUMsEqual(t, "A +u B (r is b)", sum.get(), ret.get()) ||
221 !BN_copy(ret.get(), sum.get()) ||
222 !BN_usub(ret.get(), ret.get(), a.get()) ||
223 !ExpectBIGNUMsEqual(t, "Sum -u A (r is a)", b.get(), ret.get()) ||
224 !BN_copy(ret.get(), a.get()) ||
225 !BN_usub(ret.get(), sum.get(), ret.get()) ||
226 !ExpectBIGNUMsEqual(t, "Sum -u A (r is b)", b.get(), ret.get()) ||
227 !BN_copy(ret.get(), sum.get()) ||
228 !BN_usub(ret.get(), ret.get(), b.get()) ||
229 !ExpectBIGNUMsEqual(t, "Sum -u B (r is a)", a.get(), ret.get()) ||
230 !BN_copy(ret.get(), b.get()) ||
231 !BN_usub(ret.get(), sum.get(), ret.get()) ||
232 !ExpectBIGNUMsEqual(t, "Sum -u B (r is b)", a.get(), ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700233 return false;
234 }
235 }
236
David Benjaminc895d6b2016-08-11 13:26:41 -0400237 // Test with |BN_add_word| and |BN_sub_word| if |b| is small enough.
238 BN_ULONG b_word = BN_get_word(b.get());
239 if (!BN_is_negative(b.get()) && b_word != (BN_ULONG)-1) {
240 if (!BN_copy(ret.get(), a.get()) ||
241 !BN_add_word(ret.get(), b_word) ||
242 !ExpectBIGNUMsEqual(t, "A + B (word)", sum.get(), ret.get()) ||
243 !BN_copy(ret.get(), sum.get()) ||
244 !BN_sub_word(ret.get(), b_word) ||
245 !ExpectBIGNUMsEqual(t, "Sum - B (word)", a.get(), ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700246 return false;
247 }
248 }
Kenny Rootb8494592015-09-25 02:29:14 +0000249
Adam Langleye9ada862015-05-11 17:20:37 -0700250 return true;
251}
252
David Benjaminc895d6b2016-08-11 13:26:41 -0400253static bool TestLShift1(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400254 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
255 bssl::UniquePtr<BIGNUM> lshift1 = GetBIGNUM(t, "LShift1");
256 bssl::UniquePtr<BIGNUM> zero(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400257 if (!a || !lshift1 || !zero) {
Adam Langleye9ada862015-05-11 17:20:37 -0700258 return false;
259 }
260
Adam Langleye9ada862015-05-11 17:20:37 -0700261 BN_zero(zero.get());
262
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400263 bssl::UniquePtr<BIGNUM> ret(BN_new()), two(BN_new()), remainder(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400264 if (!ret || !two || !remainder ||
265 !BN_set_word(two.get(), 2) ||
266 !BN_add(ret.get(), a.get(), a.get()) ||
267 !ExpectBIGNUMsEqual(t, "A + A", lshift1.get(), ret.get()) ||
268 !BN_mul(ret.get(), a.get(), two.get(), ctx) ||
269 !ExpectBIGNUMsEqual(t, "A * 2", lshift1.get(), ret.get()) ||
270 !BN_div(ret.get(), remainder.get(), lshift1.get(), two.get(), ctx) ||
271 !ExpectBIGNUMsEqual(t, "LShift1 / 2", a.get(), ret.get()) ||
272 !ExpectBIGNUMsEqual(t, "LShift1 % 2", zero.get(), remainder.get()) ||
273 !BN_lshift1(ret.get(), a.get()) ||
274 !ExpectBIGNUMsEqual(t, "A << 1", lshift1.get(), ret.get()) ||
275 !BN_rshift1(ret.get(), lshift1.get()) ||
276 !ExpectBIGNUMsEqual(t, "LShift >> 1", a.get(), ret.get()) ||
277 !BN_rshift1(ret.get(), lshift1.get()) ||
278 !ExpectBIGNUMsEqual(t, "LShift >> 1", a.get(), ret.get())) {
279 return false;
280 }
281
282 // Set the LSB to 1 and test rshift1 again.
283 if (!BN_set_bit(lshift1.get(), 0) ||
284 !BN_div(ret.get(), nullptr /* rem */, lshift1.get(), two.get(), ctx) ||
285 !ExpectBIGNUMsEqual(t, "(LShift1 | 1) / 2", a.get(), ret.get()) ||
286 !BN_rshift1(ret.get(), lshift1.get()) ||
287 !ExpectBIGNUMsEqual(t, "(LShift | 1) >> 1", a.get(), ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700288 return false;
289 }
290
291 return true;
292}
293
David Benjaminc895d6b2016-08-11 13:26:41 -0400294static bool TestLShift(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400295 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
296 bssl::UniquePtr<BIGNUM> lshift = GetBIGNUM(t, "LShift");
David Benjaminc895d6b2016-08-11 13:26:41 -0400297 int n = 0;
298 if (!a || !lshift || !GetInt(t, &n, "N")) {
Adam Langleye9ada862015-05-11 17:20:37 -0700299 return false;
300 }
301
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400302 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400303 if (!ret ||
304 !BN_lshift(ret.get(), a.get(), n) ||
305 !ExpectBIGNUMsEqual(t, "A << N", lshift.get(), ret.get()) ||
306 !BN_rshift(ret.get(), lshift.get(), n) ||
307 !ExpectBIGNUMsEqual(t, "A >> N", a.get(), ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700308 return false;
309 }
310
311 return true;
312}
313
David Benjaminc895d6b2016-08-11 13:26:41 -0400314static bool TestRShift(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400315 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
316 bssl::UniquePtr<BIGNUM> rshift = GetBIGNUM(t, "RShift");
David Benjaminc895d6b2016-08-11 13:26:41 -0400317 int n = 0;
318 if (!a || !rshift || !GetInt(t, &n, "N")) {
Adam Langleye9ada862015-05-11 17:20:37 -0700319 return false;
320 }
321
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400322 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400323 if (!ret ||
324 !BN_rshift(ret.get(), a.get(), n) ||
325 !ExpectBIGNUMsEqual(t, "A >> N", rshift.get(), ret.get())) {
326 return false;
327 }
328
329 return true;
330}
331
332static bool TestSquare(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400333 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
334 bssl::UniquePtr<BIGNUM> square = GetBIGNUM(t, "Square");
335 bssl::UniquePtr<BIGNUM> zero(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400336 if (!a || !square || !zero) {
337 return false;
338 }
339
340 BN_zero(zero.get());
341
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400342 bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400343 if (!ret || !remainder ||
David Benjaminc895d6b2016-08-11 13:26:41 -0400344 !BN_sqr(ret.get(), a.get(), ctx) ||
345 !ExpectBIGNUMsEqual(t, "A^2", square.get(), ret.get()) ||
346 !BN_mul(ret.get(), a.get(), a.get(), ctx) ||
347 !ExpectBIGNUMsEqual(t, "A * A", square.get(), ret.get()) ||
348 !BN_div(ret.get(), remainder.get(), square.get(), a.get(), ctx) ||
349 !ExpectBIGNUMsEqual(t, "Square / A", a.get(), ret.get()) ||
350 !ExpectBIGNUMsEqual(t, "Square % A", zero.get(), remainder.get())) {
351 return false;
352 }
353
354 BN_set_negative(a.get(), 0);
355 if (!BN_sqrt(ret.get(), square.get(), ctx) ||
356 !ExpectBIGNUMsEqual(t, "sqrt(Square)", a.get(), ret.get())) {
357 return false;
358 }
359
360 // BN_sqrt should fail on non-squares and negative numbers.
361 if (!BN_is_zero(square.get())) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400362 bssl::UniquePtr<BIGNUM> tmp(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400363 if (!tmp || !BN_copy(tmp.get(), square.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700364 return false;
365 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400366 BN_set_negative(tmp.get(), 1);
367
368 if (BN_sqrt(ret.get(), tmp.get(), ctx)) {
369 t->PrintLine("BN_sqrt succeeded on a negative number");
370 return false;
371 }
372 ERR_clear_error();
373
374 BN_set_negative(tmp.get(), 0);
375 if (!BN_add(tmp.get(), tmp.get(), BN_value_one())) {
376 return false;
377 }
378 if (BN_sqrt(ret.get(), tmp.get(), ctx)) {
379 t->PrintLine("BN_sqrt succeeded on a non-square");
380 return false;
381 }
382 ERR_clear_error();
383 }
384
385 return true;
386}
387
388static bool TestProduct(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400389 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
390 bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
391 bssl::UniquePtr<BIGNUM> product = GetBIGNUM(t, "Product");
392 bssl::UniquePtr<BIGNUM> zero(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400393 if (!a || !b || !product || !zero) {
394 return false;
395 }
396
397 BN_zero(zero.get());
398
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400399 bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400400 if (!ret || !remainder ||
401 !BN_mul(ret.get(), a.get(), b.get(), ctx) ||
402 !ExpectBIGNUMsEqual(t, "A * B", product.get(), ret.get()) ||
403 !BN_div(ret.get(), remainder.get(), product.get(), a.get(), ctx) ||
404 !ExpectBIGNUMsEqual(t, "Product / A", b.get(), ret.get()) ||
405 !ExpectBIGNUMsEqual(t, "Product % A", zero.get(), remainder.get()) ||
406 !BN_div(ret.get(), remainder.get(), product.get(), b.get(), ctx) ||
407 !ExpectBIGNUMsEqual(t, "Product / B", a.get(), ret.get()) ||
408 !ExpectBIGNUMsEqual(t, "Product % B", zero.get(), remainder.get())) {
409 return false;
410 }
411
412 return true;
413}
414
415static bool TestQuotient(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400416 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
417 bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
418 bssl::UniquePtr<BIGNUM> quotient = GetBIGNUM(t, "Quotient");
419 bssl::UniquePtr<BIGNUM> remainder = GetBIGNUM(t, "Remainder");
David Benjaminc895d6b2016-08-11 13:26:41 -0400420 if (!a || !b || !quotient || !remainder) {
421 return false;
422 }
423
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400424 bssl::UniquePtr<BIGNUM> ret(BN_new()), ret2(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400425 if (!ret || !ret2 ||
426 !BN_div(ret.get(), ret2.get(), a.get(), b.get(), ctx) ||
427 !ExpectBIGNUMsEqual(t, "A / B", quotient.get(), ret.get()) ||
428 !ExpectBIGNUMsEqual(t, "A % B", remainder.get(), ret2.get()) ||
429 !BN_mul(ret.get(), quotient.get(), b.get(), ctx) ||
430 !BN_add(ret.get(), ret.get(), remainder.get()) ||
431 !ExpectBIGNUMsEqual(t, "Quotient * B + Remainder", a.get(), ret.get())) {
432 return false;
433 }
434
435 // Test with |BN_mod_word| and |BN_div_word| if the divisor is small enough.
436 BN_ULONG b_word = BN_get_word(b.get());
437 if (!BN_is_negative(b.get()) && b_word != (BN_ULONG)-1) {
438 BN_ULONG remainder_word = BN_get_word(remainder.get());
439 assert(remainder_word != (BN_ULONG)-1);
440 if (!BN_copy(ret.get(), a.get())) {
441 return false;
442 }
443 BN_ULONG ret_word = BN_div_word(ret.get(), b_word);
444 if (ret_word != remainder_word) {
445 t->PrintLine("Got A %% B (word) = " BN_HEX_FMT1 ", wanted " BN_HEX_FMT1
446 "\n",
447 ret_word, remainder_word);
448 return false;
449 }
450 if (!ExpectBIGNUMsEqual(t, "A / B (word)", quotient.get(), ret.get())) {
451 return false;
452 }
453
454 ret_word = BN_mod_word(a.get(), b_word);
455 if (ret_word != remainder_word) {
456 t->PrintLine("Got A %% B (word) = " BN_HEX_FMT1 ", wanted " BN_HEX_FMT1
457 "\n",
458 ret_word, remainder_word);
Adam Langleye9ada862015-05-11 17:20:37 -0700459 return false;
460 }
461 }
462
David Benjaminc895d6b2016-08-11 13:26:41 -0400463 // Test BN_nnmod.
464 if (!BN_is_negative(b.get())) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400465 bssl::UniquePtr<BIGNUM> nnmod(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400466 if (!nnmod ||
467 !BN_copy(nnmod.get(), remainder.get()) ||
468 (BN_is_negative(nnmod.get()) &&
469 !BN_add(nnmod.get(), nnmod.get(), b.get())) ||
470 !BN_nnmod(ret.get(), a.get(), b.get(), ctx) ||
471 !ExpectBIGNUMsEqual(t, "A % B (non-negative)", nnmod.get(),
472 ret.get())) {
Adam Langleye9ada862015-05-11 17:20:37 -0700473 return false;
474 }
Adam Langleye9ada862015-05-11 17:20:37 -0700475 }
476
477 return true;
478}
479
David Benjaminc895d6b2016-08-11 13:26:41 -0400480static bool TestModMul(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400481 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
482 bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
483 bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
484 bssl::UniquePtr<BIGNUM> mod_mul = GetBIGNUM(t, "ModMul");
David Benjaminc895d6b2016-08-11 13:26:41 -0400485 if (!a || !b || !m || !mod_mul) {
486 return false;
487 }
488
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400489 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400490 if (!ret ||
491 !BN_mod_mul(ret.get(), a.get(), b.get(), m.get(), ctx) ||
492 !ExpectBIGNUMsEqual(t, "A * B (mod M)", mod_mul.get(), ret.get())) {
493 return false;
494 }
495
496 if (BN_is_odd(m.get())) {
497 // Reduce |a| and |b| and test the Montgomery version.
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400498 bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
499 bssl::UniquePtr<BIGNUM> a_tmp(BN_new()), b_tmp(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400500 if (!mont || !a_tmp || !b_tmp ||
501 !BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
502 !BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
503 !BN_nnmod(b_tmp.get(), b.get(), m.get(), ctx) ||
504 !BN_to_montgomery(a_tmp.get(), a_tmp.get(), mont.get(), ctx) ||
505 !BN_to_montgomery(b_tmp.get(), b_tmp.get(), mont.get(), ctx) ||
506 !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), b_tmp.get(), mont.get(),
507 ctx) ||
508 !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
509 !ExpectBIGNUMsEqual(t, "A * B (mod M) (Montgomery)",
510 mod_mul.get(), ret.get())) {
511 return false;
512 }
513 }
514
515 return true;
516}
517
Robert Sloan4d1ac502017-02-06 08:36:14 -0800518static bool TestModSquare(FileTest *t, BN_CTX *ctx) {
519 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
520 bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
521 bssl::UniquePtr<BIGNUM> mod_square = GetBIGNUM(t, "ModSquare");
522 if (!a || !m || !mod_square) {
523 return false;
524 }
525
526 bssl::UniquePtr<BIGNUM> a_copy(BN_new());
527 bssl::UniquePtr<BIGNUM> ret(BN_new());
528 if (!ret || !a_copy ||
529 !BN_mod_mul(ret.get(), a.get(), a.get(), m.get(), ctx) ||
530 !ExpectBIGNUMsEqual(t, "A * A (mod M)", mod_square.get(), ret.get()) ||
531 // Repeat the operation with |a_copy|.
532 !BN_copy(a_copy.get(), a.get()) ||
533 !BN_mod_mul(ret.get(), a.get(), a_copy.get(), m.get(), ctx) ||
534 !ExpectBIGNUMsEqual(t, "A * A_copy (mod M)", mod_square.get(),
535 ret.get())) {
536 return false;
537 }
538
539 if (BN_is_odd(m.get())) {
540 // Reduce |a| and test the Montgomery version.
541 bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
542 bssl::UniquePtr<BIGNUM> a_tmp(BN_new());
543 if (!mont || !a_tmp ||
544 !BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
545 !BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
546 !BN_to_montgomery(a_tmp.get(), a_tmp.get(), mont.get(), ctx) ||
547 !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_tmp.get(), mont.get(),
548 ctx) ||
549 !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
550 !ExpectBIGNUMsEqual(t, "A * A (mod M) (Montgomery)",
551 mod_square.get(), ret.get()) ||
552 // Repeat the operation with |a_copy|.
553 !BN_copy(a_copy.get(), a_tmp.get()) ||
554 !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_copy.get(), mont.get(),
555 ctx) ||
556 !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
557 !ExpectBIGNUMsEqual(t, "A * A_copy (mod M) (Montgomery)",
558 mod_square.get(), ret.get())) {
559 return false;
560 }
561 }
562
563 return true;
564}
565
David Benjaminc895d6b2016-08-11 13:26:41 -0400566static bool TestModExp(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400567 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
568 bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
569 bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
570 bssl::UniquePtr<BIGNUM> mod_exp = GetBIGNUM(t, "ModExp");
David Benjaminc895d6b2016-08-11 13:26:41 -0400571 if (!a || !e || !m || !mod_exp) {
572 return false;
573 }
574
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400575 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400576 if (!ret ||
577 !BN_mod_exp(ret.get(), a.get(), e.get(), m.get(), ctx) ||
578 !ExpectBIGNUMsEqual(t, "A ^ E (mod M)", mod_exp.get(), ret.get())) {
579 return false;
580 }
581
582 if (BN_is_odd(m.get())) {
583 if (!BN_mod_exp_mont(ret.get(), a.get(), e.get(), m.get(), ctx, NULL) ||
584 !ExpectBIGNUMsEqual(t, "A ^ E (mod M) (Montgomery)", mod_exp.get(),
585 ret.get()) ||
586 !BN_mod_exp_mont_consttime(ret.get(), a.get(), e.get(), m.get(), ctx,
587 NULL) ||
588 !ExpectBIGNUMsEqual(t, "A ^ E (mod M) (constant-time)", mod_exp.get(),
589 ret.get())) {
590 return false;
591 }
592 }
593
594 return true;
595}
596
597static bool TestExp(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400598 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
599 bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
600 bssl::UniquePtr<BIGNUM> exp = GetBIGNUM(t, "Exp");
David Benjaminc895d6b2016-08-11 13:26:41 -0400601 if (!a || !e || !exp) {
602 return false;
603 }
604
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400605 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400606 if (!ret ||
607 !BN_exp(ret.get(), a.get(), e.get(), ctx) ||
608 !ExpectBIGNUMsEqual(t, "A ^ E", exp.get(), ret.get())) {
609 return false;
610 }
611
612 return true;
613}
614
615static bool TestModSqrt(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400616 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
617 bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
618 bssl::UniquePtr<BIGNUM> mod_sqrt = GetBIGNUM(t, "ModSqrt");
David Benjamin1b249672016-12-06 18:25:50 -0500619 bssl::UniquePtr<BIGNUM> mod_sqrt2(BN_new());
620 if (!a || !p || !mod_sqrt || !mod_sqrt2 ||
621 // There are two possible answers.
622 !BN_sub(mod_sqrt2.get(), p.get(), mod_sqrt.get())) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400623 return false;
624 }
625
David Benjamin1b249672016-12-06 18:25:50 -0500626 // -0 is 0, not P.
627 if (BN_is_zero(mod_sqrt.get())) {
628 BN_zero(mod_sqrt2.get());
629 }
630
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400631 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400632 if (!ret ||
David Benjamin1b249672016-12-06 18:25:50 -0500633 !BN_mod_sqrt(ret.get(), a.get(), p.get(), ctx)) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400634 return false;
635 }
636
David Benjamin1b249672016-12-06 18:25:50 -0500637 if (BN_cmp(ret.get(), mod_sqrt2.get()) != 0 &&
David Benjaminc895d6b2016-08-11 13:26:41 -0400638 !ExpectBIGNUMsEqual(t, "sqrt(A) (mod P)", mod_sqrt.get(), ret.get())) {
639 return false;
640 }
641
642 return true;
643}
644
David Benjamin1b249672016-12-06 18:25:50 -0500645static bool TestNotModSquare(FileTest *t, BN_CTX *ctx) {
646 bssl::UniquePtr<BIGNUM> not_mod_square = GetBIGNUM(t, "NotModSquare");
647 bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
648 bssl::UniquePtr<BIGNUM> ret(BN_new());
649 if (!not_mod_square || !p || !ret) {
650 return false;
651 }
652
653 if (BN_mod_sqrt(ret.get(), not_mod_square.get(), p.get(), ctx)) {
654 t->PrintLine("BN_mod_sqrt unexpectedly succeeded.");
655 return false;
656 }
657
658 uint32_t err = ERR_peek_error();
659 if (ERR_GET_LIB(err) == ERR_LIB_BN &&
660 ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
661 ERR_clear_error();
662 return true;
663 }
664
665 return false;
666}
667
David Benjaminc895d6b2016-08-11 13:26:41 -0400668static bool TestModInv(FileTest *t, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400669 bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
670 bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
671 bssl::UniquePtr<BIGNUM> mod_inv = GetBIGNUM(t, "ModInv");
David Benjaminc895d6b2016-08-11 13:26:41 -0400672 if (!a || !m || !mod_inv) {
673 return false;
674 }
675
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400676 bssl::UniquePtr<BIGNUM> ret(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -0400677 if (!ret ||
678 !BN_mod_inverse(ret.get(), a.get(), m.get(), ctx) ||
679 !ExpectBIGNUMsEqual(t, "inv(A) (mod M)", mod_inv.get(), ret.get())) {
680 return false;
681 }
682
David Benjaminc895d6b2016-08-11 13:26:41 -0400683 return true;
684}
685
686struct Test {
687 const char *name;
688 bool (*func)(FileTest *t, BN_CTX *ctx);
689};
690
691static const Test kTests[] = {
692 {"Sum", TestSum},
693 {"LShift1", TestLShift1},
694 {"LShift", TestLShift},
695 {"RShift", TestRShift},
696 {"Square", TestSquare},
697 {"Product", TestProduct},
698 {"Quotient", TestQuotient},
699 {"ModMul", TestModMul},
Robert Sloan4d1ac502017-02-06 08:36:14 -0800700 {"ModSquare", TestModSquare},
David Benjaminc895d6b2016-08-11 13:26:41 -0400701 {"ModExp", TestModExp},
702 {"Exp", TestExp},
703 {"ModSqrt", TestModSqrt},
David Benjamin1b249672016-12-06 18:25:50 -0500704 {"NotModSquare", TestNotModSquare},
David Benjaminc895d6b2016-08-11 13:26:41 -0400705 {"ModInv", TestModInv},
706};
707
708static bool RunTest(FileTest *t, void *arg) {
709 BN_CTX *ctx = reinterpret_cast<BN_CTX *>(arg);
710 for (const Test &test : kTests) {
711 if (t->GetType() != test.name) {
712 continue;
713 }
714 return test.func(t, ctx);
715 }
716 t->PrintLine("Unknown test type: %s", t->GetType().c_str());
717 return false;
718}
719
720static bool TestBN2BinPadded(BN_CTX *ctx) {
Adam Langleye9ada862015-05-11 17:20:37 -0700721 uint8_t zeros[256], out[256], reference[128];
722
Robert Sloan69939df2017-01-09 10:53:07 -0800723 OPENSSL_memset(zeros, 0, sizeof(zeros));
Adam Langleye9ada862015-05-11 17:20:37 -0700724
725 // Test edge case at 0.
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400726 bssl::UniquePtr<BIGNUM> n(BN_new());
Adam Langleye9ada862015-05-11 17:20:37 -0700727 if (!n || !BN_bn2bin_padded(NULL, 0, n.get())) {
728 fprintf(stderr,
729 "BN_bn2bin_padded failed to encode 0 in an empty buffer.\n");
730 return false;
731 }
Robert Sloan69939df2017-01-09 10:53:07 -0800732 OPENSSL_memset(out, -1, sizeof(out));
Adam Langleye9ada862015-05-11 17:20:37 -0700733 if (!BN_bn2bin_padded(out, sizeof(out), n.get())) {
734 fprintf(stderr,
735 "BN_bn2bin_padded failed to encode 0 in a non-empty buffer.\n");
736 return false;
737 }
Robert Sloan69939df2017-01-09 10:53:07 -0800738 if (OPENSSL_memcmp(zeros, out, sizeof(out))) {
Adam Langleye9ada862015-05-11 17:20:37 -0700739 fprintf(stderr, "BN_bn2bin_padded did not zero buffer.\n");
740 return false;
741 }
742
743 // Test a random numbers at various byte lengths.
744 for (size_t bytes = 128 - 7; bytes <= 128; bytes++) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400745 if (!BN_rand(n.get(), bytes * 8, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
Adam Langleye9ada862015-05-11 17:20:37 -0700746 ERR_print_errors_fp(stderr);
747 return false;
748 }
749 if (BN_num_bytes(n.get()) != bytes ||
750 BN_bn2bin(n.get(), reference) != bytes) {
751 fprintf(stderr, "Bad result from BN_rand; bytes.\n");
752 return false;
753 }
754 // Empty buffer should fail.
755 if (BN_bn2bin_padded(NULL, 0, n.get())) {
756 fprintf(stderr,
757 "BN_bn2bin_padded incorrectly succeeded on empty buffer.\n");
758 return false;
759 }
760 // One byte short should fail.
761 if (BN_bn2bin_padded(out, bytes - 1, n.get())) {
762 fprintf(stderr, "BN_bn2bin_padded incorrectly succeeded on short.\n");
763 return false;
764 }
765 // Exactly right size should encode.
766 if (!BN_bn2bin_padded(out, bytes, n.get()) ||
Robert Sloan69939df2017-01-09 10:53:07 -0800767 OPENSSL_memcmp(out, reference, bytes) != 0) {
Adam Langleye9ada862015-05-11 17:20:37 -0700768 fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
769 return false;
770 }
771 // Pad up one byte extra.
772 if (!BN_bn2bin_padded(out, bytes + 1, n.get()) ||
Robert Sloan69939df2017-01-09 10:53:07 -0800773 OPENSSL_memcmp(out + 1, reference, bytes) ||
774 OPENSSL_memcmp(out, zeros, 1)) {
Adam Langleye9ada862015-05-11 17:20:37 -0700775 fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
776 return false;
777 }
778 // Pad up to 256.
779 if (!BN_bn2bin_padded(out, sizeof(out), n.get()) ||
Robert Sloan69939df2017-01-09 10:53:07 -0800780 OPENSSL_memcmp(out + sizeof(out) - bytes, reference, bytes) ||
781 OPENSSL_memcmp(out, zeros, sizeof(out) - bytes)) {
Adam Langleye9ada862015-05-11 17:20:37 -0700782 fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
783 return false;
784 }
785 }
786
787 return true;
788}
789
Robert Sloan69939df2017-01-09 10:53:07 -0800790static bool TestLittleEndian() {
791 bssl::UniquePtr<BIGNUM> x(BN_new());
792 bssl::UniquePtr<BIGNUM> y(BN_new());
793 if (!x || !y) {
794 fprintf(stderr, "BN_new failed to malloc.\n");
795 return false;
796 }
797
798 // Test edge case at 0. Fill |out| with garbage to ensure |BN_bn2le_padded|
799 // wrote the result.
800 uint8_t out[256], zeros[256];
801 OPENSSL_memset(out, -1, sizeof(out));
802 OPENSSL_memset(zeros, 0, sizeof(zeros));
803 if (!BN_bn2le_padded(out, sizeof(out), x.get()) ||
804 OPENSSL_memcmp(zeros, out, sizeof(out))) {
805 fprintf(stderr, "BN_bn2le_padded failed to encode 0.\n");
806 return false;
807 }
808
809 if (!BN_le2bn(out, sizeof(out), y.get()) ||
810 BN_cmp(x.get(), y.get()) != 0) {
811 fprintf(stderr, "BN_le2bn failed to decode 0 correctly.\n");
812 return false;
813 }
814
815 // Test random numbers at various byte lengths.
816 for (size_t bytes = 128 - 7; bytes <= 128; bytes++) {
817 if (!BN_rand(x.get(), bytes * 8, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
818 ERR_print_errors_fp(stderr);
819 return false;
820 }
821
822 // Fill |out| with garbage to ensure |BN_bn2le_padded| wrote the result.
823 OPENSSL_memset(out, -1, sizeof(out));
824 if (!BN_bn2le_padded(out, sizeof(out), x.get())) {
825 fprintf(stderr, "BN_bn2le_padded failed to encode random value.\n");
826 return false;
827 }
828
829 // Compute the expected value by reversing the big-endian output.
830 uint8_t expected[sizeof(out)];
831 if (!BN_bn2bin_padded(expected, sizeof(expected), x.get())) {
832 return false;
833 }
834 for (size_t i = 0; i < sizeof(expected) / 2; i++) {
835 uint8_t tmp = expected[i];
836 expected[i] = expected[sizeof(expected) - 1 - i];
837 expected[sizeof(expected) - 1 - i] = tmp;
838 }
839
840 if (OPENSSL_memcmp(expected, out, sizeof(out))) {
841 fprintf(stderr, "BN_bn2le_padded failed to encode value correctly.\n");
842 hexdump(stderr, "Expected: ", expected, sizeof(expected));
843 hexdump(stderr, "Got: ", out, sizeof(out));
844 return false;
845 }
846
847 // Make sure the decoding produces the same BIGNUM.
848 if (!BN_le2bn(out, bytes, y.get()) ||
849 BN_cmp(x.get(), y.get()) != 0) {
850 bssl::UniquePtr<char> x_hex(BN_bn2hex(x.get())),
851 y_hex(BN_bn2hex(y.get()));
852 if (!x_hex || !y_hex) {
853 return false;
854 }
855 fprintf(stderr, "BN_le2bn failed to decode value correctly.\n");
856 fprintf(stderr, "Expected: %s\n", x_hex.get());
857 hexdump(stderr, "Encoding: ", out, bytes);
858 fprintf(stderr, "Got: %s\n", y_hex.get());
859 return false;
860 }
861 }
862
863 return true;
864}
865
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400866static int DecimalToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
Adam Langleye9ada862015-05-11 17:20:37 -0700867 BIGNUM *raw = NULL;
868 int ret = BN_dec2bn(&raw, in);
869 out->reset(raw);
870 return ret;
871}
872
David Benjaminc895d6b2016-08-11 13:26:41 -0400873static bool TestDec2BN(BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400874 bssl::UniquePtr<BIGNUM> bn;
Adam Langleye9ada862015-05-11 17:20:37 -0700875 int ret = DecimalToBIGNUM(&bn, "0");
876 if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
877 fprintf(stderr, "BN_dec2bn gave a bad result.\n");
878 return false;
879 }
880
881 ret = DecimalToBIGNUM(&bn, "256");
882 if (ret != 3 || !BN_is_word(bn.get(), 256) || BN_is_negative(bn.get())) {
883 fprintf(stderr, "BN_dec2bn gave a bad result.\n");
884 return false;
885 }
886
887 ret = DecimalToBIGNUM(&bn, "-42");
888 if (ret != 3 || !BN_abs_is_word(bn.get(), 42) || !BN_is_negative(bn.get())) {
889 fprintf(stderr, "BN_dec2bn gave a bad result.\n");
890 return false;
891 }
892
893 ret = DecimalToBIGNUM(&bn, "-0");
894 if (ret != 2 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
895 fprintf(stderr, "BN_dec2bn gave a bad result.\n");
896 return false;
897 }
898
899 ret = DecimalToBIGNUM(&bn, "42trailing garbage is ignored");
900 if (ret != 2 || !BN_abs_is_word(bn.get(), 42) || BN_is_negative(bn.get())) {
901 fprintf(stderr, "BN_dec2bn gave a bad result.\n");
902 return false;
903 }
904
905 return true;
906}
907
David Benjaminc895d6b2016-08-11 13:26:41 -0400908static bool TestHex2BN(BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400909 bssl::UniquePtr<BIGNUM> bn;
Adam Langleye9ada862015-05-11 17:20:37 -0700910 int ret = HexToBIGNUM(&bn, "0");
911 if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
912 fprintf(stderr, "BN_hex2bn gave a bad result.\n");
913 return false;
914 }
915
916 ret = HexToBIGNUM(&bn, "256");
917 if (ret != 3 || !BN_is_word(bn.get(), 0x256) || BN_is_negative(bn.get())) {
918 fprintf(stderr, "BN_hex2bn gave a bad result.\n");
919 return false;
920 }
921
922 ret = HexToBIGNUM(&bn, "-42");
923 if (ret != 3 || !BN_abs_is_word(bn.get(), 0x42) || !BN_is_negative(bn.get())) {
924 fprintf(stderr, "BN_hex2bn gave a bad result.\n");
925 return false;
926 }
927
928 ret = HexToBIGNUM(&bn, "-0");
929 if (ret != 2 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
930 fprintf(stderr, "BN_hex2bn gave a bad result.\n");
931 return false;
932 }
933
934 ret = HexToBIGNUM(&bn, "abctrailing garbage is ignored");
935 if (ret != 3 || !BN_is_word(bn.get(), 0xabc) || BN_is_negative(bn.get())) {
936 fprintf(stderr, "BN_hex2bn gave a bad result.\n");
937 return false;
938 }
939
940 return true;
941}
942
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400943static bssl::UniquePtr<BIGNUM> ASCIIToBIGNUM(const char *in) {
Adam Langleye9ada862015-05-11 17:20:37 -0700944 BIGNUM *raw = NULL;
945 if (!BN_asc2bn(&raw, in)) {
946 return nullptr;
947 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400948 return bssl::UniquePtr<BIGNUM>(raw);
Adam Langleye9ada862015-05-11 17:20:37 -0700949}
950
David Benjaminc895d6b2016-08-11 13:26:41 -0400951static bool TestASC2BN(BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400952 bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("0");
Adam Langleye9ada862015-05-11 17:20:37 -0700953 if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
954 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
955 return false;
956 }
957
958 bn = ASCIIToBIGNUM("256");
959 if (!bn || !BN_is_word(bn.get(), 256) || BN_is_negative(bn.get())) {
960 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
961 return false;
962 }
963
964 bn = ASCIIToBIGNUM("-42");
965 if (!bn || !BN_abs_is_word(bn.get(), 42) || !BN_is_negative(bn.get())) {
966 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
967 return false;
968 }
969
970 bn = ASCIIToBIGNUM("0x1234");
971 if (!bn || !BN_is_word(bn.get(), 0x1234) || BN_is_negative(bn.get())) {
972 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
973 return false;
974 }
975
976 bn = ASCIIToBIGNUM("0X1234");
977 if (!bn || !BN_is_word(bn.get(), 0x1234) || BN_is_negative(bn.get())) {
978 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
979 return false;
980 }
981
982 bn = ASCIIToBIGNUM("-0xabcd");
983 if (!bn || !BN_abs_is_word(bn.get(), 0xabcd) || !BN_is_negative(bn.get())) {
984 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
985 return false;
986 }
987
988 bn = ASCIIToBIGNUM("-0");
989 if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
990 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
991 return false;
992 }
993
994 bn = ASCIIToBIGNUM("123trailing garbage is ignored");
995 if (!bn || !BN_is_word(bn.get(), 123) || BN_is_negative(bn.get())) {
996 fprintf(stderr, "BN_asc2bn gave a bad result.\n");
997 return false;
998 }
999
1000 return true;
1001}
Adam Langleyf4e42722015-06-04 17:45:09 -07001002
Kenny Rootb8494592015-09-25 02:29:14 +00001003struct MPITest {
1004 const char *base10;
1005 const char *mpi;
1006 size_t mpi_len;
1007};
1008
1009static const MPITest kMPITests[] = {
1010 { "0", "\x00\x00\x00\x00", 4 },
1011 { "1", "\x00\x00\x00\x01\x01", 5 },
1012 { "-1", "\x00\x00\x00\x01\x81", 5 },
1013 { "128", "\x00\x00\x00\x02\x00\x80", 6 },
1014 { "256", "\x00\x00\x00\x02\x01\x00", 6 },
1015 { "-256", "\x00\x00\x00\x02\x81\x00", 6 },
1016};
1017
David Benjaminc895d6b2016-08-11 13:26:41 -04001018static bool TestMPI() {
Kenny Rootb8494592015-09-25 02:29:14 +00001019 uint8_t scratch[8];
1020
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001021 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMPITests); i++) {
Kenny Rootb8494592015-09-25 02:29:14 +00001022 const MPITest &test = kMPITests[i];
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001023 bssl::UniquePtr<BIGNUM> bn(ASCIIToBIGNUM(test.base10));
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001024 if (!bn) {
1025 return false;
1026 }
1027
Kenny Rootb8494592015-09-25 02:29:14 +00001028 const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
1029 if (mpi_len > sizeof(scratch)) {
1030 fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
1031 (unsigned)i);
1032 return false;
1033 }
1034
1035 const size_t mpi_len2 = BN_bn2mpi(bn.get(), scratch);
1036 if (mpi_len != mpi_len2) {
1037 fprintf(stderr, "MPI test #%u: length changes.\n", (unsigned)i);
1038 return false;
1039 }
1040
1041 if (mpi_len != test.mpi_len ||
Robert Sloan69939df2017-01-09 10:53:07 -08001042 OPENSSL_memcmp(test.mpi, scratch, mpi_len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001043 fprintf(stderr, "MPI test #%u failed:\n", (unsigned)i);
1044 hexdump(stderr, "Expected: ", test.mpi, test.mpi_len);
1045 hexdump(stderr, "Got: ", scratch, mpi_len);
1046 return false;
1047 }
1048
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001049 bssl::UniquePtr<BIGNUM> bn2(BN_mpi2bn(scratch, mpi_len, NULL));
Kenny Rootb8494592015-09-25 02:29:14 +00001050 if (bn2.get() == nullptr) {
1051 fprintf(stderr, "MPI test #%u: failed to parse\n", (unsigned)i);
1052 return false;
1053 }
1054
1055 if (BN_cmp(bn.get(), bn2.get()) != 0) {
1056 fprintf(stderr, "MPI test #%u: wrong result\n", (unsigned)i);
1057 return false;
1058 }
1059 }
1060
1061 return true;
1062}
1063
David Benjaminc895d6b2016-08-11 13:26:41 -04001064static bool TestRand() {
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001065 bssl::UniquePtr<BIGNUM> bn(BN_new());
Adam Langleyf4e42722015-06-04 17:45:09 -07001066 if (!bn) {
1067 return false;
1068 }
1069
1070 // Test BN_rand accounts for degenerate cases with |top| and |bottom|
1071 // parameters.
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001072 if (!BN_rand(bn.get(), 0, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
Adam Langleyf4e42722015-06-04 17:45:09 -07001073 !BN_is_zero(bn.get())) {
1074 fprintf(stderr, "BN_rand gave a bad result.\n");
1075 return false;
1076 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001077 if (!BN_rand(bn.get(), 0, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD) ||
Adam Langleyf4e42722015-06-04 17:45:09 -07001078 !BN_is_zero(bn.get())) {
1079 fprintf(stderr, "BN_rand gave a bad result.\n");
1080 return false;
1081 }
1082
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001083 if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
Adam Langleyf4e42722015-06-04 17:45:09 -07001084 !BN_is_word(bn.get(), 1)) {
1085 fprintf(stderr, "BN_rand gave a bad result.\n");
1086 return false;
1087 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001088 if (!BN_rand(bn.get(), 1, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
Adam Langleyf4e42722015-06-04 17:45:09 -07001089 !BN_is_word(bn.get(), 1)) {
1090 fprintf(stderr, "BN_rand gave a bad result.\n");
1091 return false;
1092 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001093 if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ODD) ||
Adam Langleyf4e42722015-06-04 17:45:09 -07001094 !BN_is_word(bn.get(), 1)) {
1095 fprintf(stderr, "BN_rand gave a bad result.\n");
1096 return false;
1097 }
1098
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001099 if (!BN_rand(bn.get(), 2, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
Adam Langleyf4e42722015-06-04 17:45:09 -07001100 !BN_is_word(bn.get(), 3)) {
1101 fprintf(stderr, "BN_rand gave a bad result.\n");
1102 return false;
1103 }
1104
1105 return true;
1106}
Kenny Rootb8494592015-09-25 02:29:14 +00001107
Robert Sloan572a4e22017-04-17 10:52:19 -07001108static bool TestRandRange() {
1109 bssl::UniquePtr<BIGNUM> bn(BN_new()), six(BN_new());
1110 if (!bn || !six ||
1111 !BN_set_word(six.get(), 6)) {
1112 return false;
1113 }
1114
1115 // Generate 1,000 random numbers and ensure they all stay in range. This check
1116 // may flakily pass when it should have failed but will not flakily fail.
1117 bool seen[6] = {false, false, false, false, false};
1118 for (unsigned i = 0; i < 1000; i++) {
1119 if (!BN_rand_range_ex(bn.get(), 1, six.get())) {
1120 return false;
1121 }
1122
1123 BN_ULONG word = BN_get_word(bn.get());
1124 if (BN_is_negative(bn.get()) ||
1125 word < 1 ||
1126 word >= 6) {
1127 fprintf(stderr,
1128 "BN_rand_range_ex generated invalid value: " BN_DEC_FMT1 "\n",
1129 word);
1130 return false;
1131 }
1132
1133 seen[word] = true;
1134 }
1135
1136 // Test that all numbers were accounted for. Note this test is probabilistic
1137 // and may flakily fail when it should have passed. As an upper-bound on the
1138 // failure probability, we'll never see any one number with probability
1139 // (4/5)^1000, so the probability of failure is at most 5*(4/5)^1000. This is
1140 // around 1 in 2^320.
1141 for (unsigned i = 1; i < 6; i++) {
1142 if (!seen[i]) {
1143 fprintf(stderr, "BN_rand_range failed to generate %u.\n", i);
1144 return false;
1145 }
1146 }
1147
1148 return true;
1149}
1150
Kenny Rootb8494592015-09-25 02:29:14 +00001151struct ASN1Test {
1152 const char *value_ascii;
1153 const char *der;
1154 size_t der_len;
1155};
1156
1157static const ASN1Test kASN1Tests[] = {
1158 {"0", "\x02\x01\x00", 3},
1159 {"1", "\x02\x01\x01", 3},
1160 {"127", "\x02\x01\x7f", 3},
1161 {"128", "\x02\x02\x00\x80", 4},
1162 {"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
1163 {"0x0102030405060708",
1164 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
1165 {"0xffffffffffffffff",
1166 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
1167};
1168
1169struct ASN1InvalidTest {
1170 const char *der;
1171 size_t der_len;
1172};
1173
1174static const ASN1InvalidTest kASN1InvalidTests[] = {
1175 // Bad tag.
1176 {"\x03\x01\x00", 3},
1177 // Empty contents.
1178 {"\x02\x00", 2},
1179};
1180
David Benjamin4969cc92016-04-22 15:02:23 -04001181// kASN1BuggyTests contains incorrect encodings and the corresponding, expected
1182// results of |BN_parse_asn1_unsigned_buggy| given that input.
Kenny Rootb8494592015-09-25 02:29:14 +00001183static const ASN1Test kASN1BuggyTests[] = {
1184 // Negative numbers.
1185 {"128", "\x02\x01\x80", 3},
1186 {"255", "\x02\x01\xff", 3},
1187 // Unnecessary leading zeros.
1188 {"1", "\x02\x02\x00\x01", 4},
1189};
1190
David Benjaminc895d6b2016-08-11 13:26:41 -04001191static bool TestASN1() {
Kenny Rootb8494592015-09-25 02:29:14 +00001192 for (const ASN1Test &test : kASN1Tests) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001193 bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM(test.value_ascii);
Kenny Rootb8494592015-09-25 02:29:14 +00001194 if (!bn) {
1195 return false;
1196 }
1197
1198 // Test that the input is correctly parsed.
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001199 bssl::UniquePtr<BIGNUM> bn2(BN_new());
Kenny Rootb8494592015-09-25 02:29:14 +00001200 if (!bn2) {
1201 return false;
1202 }
1203 CBS cbs;
1204 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
David Benjamin4969cc92016-04-22 15:02:23 -04001205 if (!BN_parse_asn1_unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001206 fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
1207 return false;
1208 }
1209 if (BN_cmp(bn.get(), bn2.get()) != 0) {
1210 fprintf(stderr, "Bad parse.\n");
1211 return false;
1212 }
1213
1214 // Test the value serializes correctly.
Steven Valdez909b19f2016-11-21 15:35:44 -05001215 bssl::ScopedCBB cbb;
Kenny Rootb8494592015-09-25 02:29:14 +00001216 uint8_t *der;
1217 size_t der_len;
Steven Valdez909b19f2016-11-21 15:35:44 -05001218 if (!CBB_init(cbb.get(), 0) ||
1219 !BN_marshal_asn1(cbb.get(), bn.get()) ||
1220 !CBB_finish(cbb.get(), &der, &der_len)) {
Kenny Rootb8494592015-09-25 02:29:14 +00001221 return false;
1222 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001223 bssl::UniquePtr<uint8_t> delete_der(der);
Kenny Rootb8494592015-09-25 02:29:14 +00001224 if (der_len != test.der_len ||
Robert Sloan69939df2017-01-09 10:53:07 -08001225 OPENSSL_memcmp(der, reinterpret_cast<const uint8_t *>(test.der),
1226 der_len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001227 fprintf(stderr, "Bad serialization.\n");
1228 return false;
1229 }
1230
David Benjamin4969cc92016-04-22 15:02:23 -04001231 // |BN_parse_asn1_unsigned_buggy| parses all valid input.
Kenny Rootb8494592015-09-25 02:29:14 +00001232 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
David Benjamin4969cc92016-04-22 15:02:23 -04001233 if (!BN_parse_asn1_unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001234 fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
1235 return false;
1236 }
1237 if (BN_cmp(bn.get(), bn2.get()) != 0) {
1238 fprintf(stderr, "Bad parse.\n");
1239 return false;
1240 }
1241 }
1242
1243 for (const ASN1InvalidTest &test : kASN1InvalidTests) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001244 bssl::UniquePtr<BIGNUM> bn(BN_new());
Kenny Rootb8494592015-09-25 02:29:14 +00001245 if (!bn) {
1246 return false;
1247 }
1248 CBS cbs;
1249 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
David Benjamin4969cc92016-04-22 15:02:23 -04001250 if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
Kenny Rootb8494592015-09-25 02:29:14 +00001251 fprintf(stderr, "Parsed invalid input.\n");
1252 return false;
1253 }
1254 ERR_clear_error();
1255
1256 // All tests in kASN1InvalidTests are also rejected by
David Benjamin4969cc92016-04-22 15:02:23 -04001257 // |BN_parse_asn1_unsigned_buggy|.
Kenny Rootb8494592015-09-25 02:29:14 +00001258 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
David Benjamin4969cc92016-04-22 15:02:23 -04001259 if (BN_parse_asn1_unsigned_buggy(&cbs, bn.get())) {
Kenny Rootb8494592015-09-25 02:29:14 +00001260 fprintf(stderr, "Parsed invalid input.\n");
1261 return false;
1262 }
1263 ERR_clear_error();
1264 }
1265
1266 for (const ASN1Test &test : kASN1BuggyTests) {
David Benjamin4969cc92016-04-22 15:02:23 -04001267 // These broken encodings are rejected by |BN_parse_asn1_unsigned|.
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001268 bssl::UniquePtr<BIGNUM> bn(BN_new());
Kenny Rootb8494592015-09-25 02:29:14 +00001269 if (!bn) {
1270 return false;
1271 }
1272
1273 CBS cbs;
1274 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
David Benjamin4969cc92016-04-22 15:02:23 -04001275 if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
Kenny Rootb8494592015-09-25 02:29:14 +00001276 fprintf(stderr, "Parsed invalid input.\n");
1277 return false;
1278 }
1279 ERR_clear_error();
1280
David Benjamin4969cc92016-04-22 15:02:23 -04001281 // However |BN_parse_asn1_unsigned_buggy| accepts them.
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001282 bssl::UniquePtr<BIGNUM> bn2 = ASCIIToBIGNUM(test.value_ascii);
Kenny Rootb8494592015-09-25 02:29:14 +00001283 if (!bn2) {
1284 return false;
1285 }
1286
1287 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
David Benjamin4969cc92016-04-22 15:02:23 -04001288 if (!BN_parse_asn1_unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001289 fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
1290 return false;
1291 }
1292
1293 if (BN_cmp(bn.get(), bn2.get()) != 0) {
1294 fprintf(stderr, "\"Bad\" parse.\n");
1295 return false;
1296 }
1297 }
1298
1299 // Serializing negative numbers is not supported.
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001300 bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("-1");
Kenny Rootb8494592015-09-25 02:29:14 +00001301 if (!bn) {
1302 return false;
1303 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001304 bssl::ScopedCBB cbb;
1305 if (!CBB_init(cbb.get(), 0) ||
1306 BN_marshal_asn1(cbb.get(), bn.get())) {
Kenny Rootb8494592015-09-25 02:29:14 +00001307 fprintf(stderr, "Serialized negative number.\n");
Kenny Rootb8494592015-09-25 02:29:14 +00001308 return false;
1309 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001310 ERR_clear_error();
Kenny Rootb8494592015-09-25 02:29:14 +00001311
1312 return true;
1313}
David Benjaminc895d6b2016-08-11 13:26:41 -04001314
1315static bool TestNegativeZero(BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001316 bssl::UniquePtr<BIGNUM> a(BN_new());
1317 bssl::UniquePtr<BIGNUM> b(BN_new());
1318 bssl::UniquePtr<BIGNUM> c(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -04001319 if (!a || !b || !c) {
1320 return false;
1321 }
1322
1323 // Test that BN_mul never gives negative zero.
1324 if (!BN_set_word(a.get(), 1)) {
1325 return false;
1326 }
1327 BN_set_negative(a.get(), 1);
1328 BN_zero(b.get());
1329 if (!BN_mul(c.get(), a.get(), b.get(), ctx)) {
1330 return false;
1331 }
1332 if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
1333 fprintf(stderr, "Multiplication test failed.\n");
1334 return false;
1335 }
1336
Robert Sloan69939df2017-01-09 10:53:07 -08001337 bssl::UniquePtr<BIGNUM> numerator(BN_new()), denominator(BN_new());
1338 if (!numerator || !denominator) {
1339 return false;
1340 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001341
Robert Sloan69939df2017-01-09 10:53:07 -08001342 // Test that BN_div never gives negative zero in the quotient.
1343 if (!BN_set_word(numerator.get(), 1) ||
1344 !BN_set_word(denominator.get(), 2)) {
1345 return false;
1346 }
1347 BN_set_negative(numerator.get(), 1);
1348 if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
1349 return false;
1350 }
1351 if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
1352 fprintf(stderr, "Incorrect quotient.\n");
1353 return false;
1354 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001355
Robert Sloan69939df2017-01-09 10:53:07 -08001356 // Test that BN_div never gives negative zero in the remainder.
1357 if (!BN_set_word(denominator.get(), 1)) {
1358 return false;
1359 }
1360 if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
1361 return false;
1362 }
1363 if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
1364 fprintf(stderr, "Incorrect remainder.\n");
1365 return false;
David Benjaminc895d6b2016-08-11 13:26:41 -04001366 }
1367
1368 // Test that BN_set_negative will not produce a negative zero.
1369 BN_zero(a.get());
1370 BN_set_negative(a.get(), 1);
1371 if (BN_is_negative(a.get())) {
1372 fprintf(stderr, "BN_set_negative produced a negative zero.\n");
1373 return false;
1374 }
1375
1376 // Test that forcibly creating a negative zero does not break |BN_bn2hex| or
1377 // |BN_bn2dec|.
1378 a->neg = 1;
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001379 bssl::UniquePtr<char> dec(BN_bn2dec(a.get()));
1380 bssl::UniquePtr<char> hex(BN_bn2hex(a.get()));
David Benjaminc895d6b2016-08-11 13:26:41 -04001381 if (!dec || !hex ||
1382 strcmp(dec.get(), "-0") != 0 ||
1383 strcmp(hex.get(), "-0") != 0) {
1384 fprintf(stderr, "BN_bn2dec or BN_bn2hex failed with negative zero.\n");
1385 return false;
1386 }
1387
Steven Valdez909b19f2016-11-21 15:35:44 -05001388 // Test that |BN_rshift| and |BN_rshift1| will not produce a negative zero.
1389 if (!BN_set_word(a.get(), 1)) {
1390 return false;
1391 }
1392
1393 BN_set_negative(a.get(), 1);
1394 if (!BN_rshift(b.get(), a.get(), 1) ||
1395 !BN_rshift1(c.get(), a.get())) {
1396 return false;
1397 }
1398
1399 if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
1400 fprintf(stderr, "BN_rshift(-1, 1) produced the wrong result.\n");
1401 return false;
1402 }
1403
1404 if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
1405 fprintf(stderr, "BN_rshift1(-1) produced the wrong result.\n");
1406 return false;
1407 }
1408
1409 // Test that |BN_div_word| will not produce a negative zero.
1410 if (BN_div_word(a.get(), 2) == (BN_ULONG)-1) {
1411 return false;
1412 }
1413
1414 if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
1415 fprintf(stderr, "BN_div_word(-1, 2) produced the wrong result.\n");
1416 return false;
1417 }
1418
David Benjaminc895d6b2016-08-11 13:26:41 -04001419 return true;
1420}
1421
1422static bool TestBadModulus(BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001423 bssl::UniquePtr<BIGNUM> a(BN_new());
1424 bssl::UniquePtr<BIGNUM> b(BN_new());
1425 bssl::UniquePtr<BIGNUM> zero(BN_new());
1426 bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
David Benjaminc895d6b2016-08-11 13:26:41 -04001427 if (!a || !b || !zero || !mont) {
1428 return false;
1429 }
1430
1431 BN_zero(zero.get());
1432
1433 if (BN_div(a.get(), b.get(), BN_value_one(), zero.get(), ctx)) {
1434 fprintf(stderr, "Division by zero unexpectedly succeeded.\n");
1435 return false;
1436 }
1437 ERR_clear_error();
1438
1439 if (BN_mod_mul(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx)) {
1440 fprintf(stderr, "BN_mod_mul with zero modulus unexpectedly succeeded.\n");
1441 return false;
1442 }
1443 ERR_clear_error();
1444
1445 if (BN_mod_exp(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx)) {
1446 fprintf(stderr, "BN_mod_exp with zero modulus unexpectedly succeeded.\n");
1447 return 0;
1448 }
1449 ERR_clear_error();
1450
1451 if (BN_mod_exp_mont(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx,
1452 NULL)) {
1453 fprintf(stderr,
1454 "BN_mod_exp_mont with zero modulus unexpectedly succeeded.\n");
1455 return 0;
1456 }
1457 ERR_clear_error();
1458
1459 if (BN_mod_exp_mont_consttime(a.get(), BN_value_one(), BN_value_one(),
1460 zero.get(), ctx, nullptr)) {
1461 fprintf(stderr,
1462 "BN_mod_exp_mont_consttime with zero modulus unexpectedly "
1463 "succeeded.\n");
1464 return 0;
1465 }
1466 ERR_clear_error();
1467
1468 if (BN_MONT_CTX_set(mont.get(), zero.get(), ctx)) {
1469 fprintf(stderr,
1470 "BN_MONT_CTX_set unexpectedly succeeded for zero modulus.\n");
1471 return false;
1472 }
1473 ERR_clear_error();
1474
1475 // Some operations also may not be used with an even modulus.
1476
1477 if (!BN_set_word(b.get(), 16)) {
1478 return false;
1479 }
1480
1481 if (BN_MONT_CTX_set(mont.get(), b.get(), ctx)) {
1482 fprintf(stderr,
1483 "BN_MONT_CTX_set unexpectedly succeeded for even modulus.\n");
1484 return false;
1485 }
1486 ERR_clear_error();
1487
1488 if (BN_mod_exp_mont(a.get(), BN_value_one(), BN_value_one(), b.get(), ctx,
1489 NULL)) {
1490 fprintf(stderr,
1491 "BN_mod_exp_mont with even modulus unexpectedly succeeded.\n");
1492 return 0;
1493 }
1494 ERR_clear_error();
1495
1496 if (BN_mod_exp_mont_consttime(a.get(), BN_value_one(), BN_value_one(),
1497 b.get(), ctx, nullptr)) {
1498 fprintf(stderr,
1499 "BN_mod_exp_mont_consttime with even modulus unexpectedly "
1500 "succeeded.\n");
1501 return 0;
1502 }
1503 ERR_clear_error();
1504
1505 return true;
1506}
1507
1508// TestExpModZero tests that 1**0 mod 1 == 0.
1509static bool TestExpModZero() {
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001510 bssl::UniquePtr<BIGNUM> zero(BN_new()), a(BN_new()), r(BN_new());
1511 if (!zero || !a || !r ||
1512 !BN_rand(a.get(), 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001513 return false;
1514 }
1515 BN_zero(zero.get());
1516
1517 if (!BN_mod_exp(r.get(), a.get(), zero.get(), BN_value_one(), nullptr) ||
1518 !BN_is_zero(r.get()) ||
1519 !BN_mod_exp_mont(r.get(), a.get(), zero.get(), BN_value_one(), nullptr,
1520 nullptr) ||
1521 !BN_is_zero(r.get()) ||
1522 !BN_mod_exp_mont_consttime(r.get(), a.get(), zero.get(), BN_value_one(),
1523 nullptr, nullptr) ||
1524 !BN_is_zero(r.get()) ||
1525 !BN_mod_exp_mont_word(r.get(), 42, zero.get(), BN_value_one(), nullptr,
1526 nullptr) ||
1527 !BN_is_zero(r.get())) {
1528 return false;
1529 }
1530
1531 return true;
1532}
1533
1534static bool TestSmallPrime(BN_CTX *ctx) {
1535 static const unsigned kBits = 10;
1536
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001537 bssl::UniquePtr<BIGNUM> r(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -04001538 if (!r || !BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
1539 NULL, NULL)) {
1540 return false;
1541 }
1542 if (BN_num_bits(r.get()) != kBits) {
1543 fprintf(stderr, "Expected %u bit prime, got %u bit number\n", kBits,
1544 BN_num_bits(r.get()));
1545 return false;
1546 }
1547
1548 return true;
1549}
1550
1551static bool TestCmpWord() {
1552 static const BN_ULONG kMaxWord = (BN_ULONG)-1;
1553
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001554 bssl::UniquePtr<BIGNUM> r(BN_new());
David Benjaminc895d6b2016-08-11 13:26:41 -04001555 if (!r ||
1556 !BN_set_word(r.get(), 0)) {
1557 return false;
1558 }
1559
1560 if (BN_cmp_word(r.get(), 0) != 0 ||
1561 BN_cmp_word(r.get(), 1) >= 0 ||
1562 BN_cmp_word(r.get(), kMaxWord) >= 0) {
1563 fprintf(stderr, "BN_cmp_word compared against 0 incorrectly.\n");
1564 return false;
1565 }
1566
1567 if (!BN_set_word(r.get(), 100)) {
1568 return false;
1569 }
1570
1571 if (BN_cmp_word(r.get(), 0) <= 0 ||
1572 BN_cmp_word(r.get(), 99) <= 0 ||
1573 BN_cmp_word(r.get(), 100) != 0 ||
1574 BN_cmp_word(r.get(), 101) >= 0 ||
1575 BN_cmp_word(r.get(), kMaxWord) >= 0) {
1576 fprintf(stderr, "BN_cmp_word compared against 100 incorrectly.\n");
1577 return false;
1578 }
1579
1580 BN_set_negative(r.get(), 1);
1581
1582 if (BN_cmp_word(r.get(), 0) >= 0 ||
1583 BN_cmp_word(r.get(), 100) >= 0 ||
1584 BN_cmp_word(r.get(), kMaxWord) >= 0) {
1585 fprintf(stderr, "BN_cmp_word compared against -100 incorrectly.\n");
1586 return false;
1587 }
1588
1589 if (!BN_set_word(r.get(), kMaxWord)) {
1590 return false;
1591 }
1592
1593 if (BN_cmp_word(r.get(), 0) <= 0 ||
1594 BN_cmp_word(r.get(), kMaxWord - 1) <= 0 ||
1595 BN_cmp_word(r.get(), kMaxWord) != 0) {
1596 fprintf(stderr, "BN_cmp_word compared against kMaxWord incorrectly.\n");
1597 return false;
1598 }
1599
1600 if (!BN_add(r.get(), r.get(), BN_value_one())) {
1601 return false;
1602 }
1603
1604 if (BN_cmp_word(r.get(), 0) <= 0 ||
1605 BN_cmp_word(r.get(), kMaxWord) <= 0) {
1606 fprintf(stderr, "BN_cmp_word compared against kMaxWord + 1 incorrectly.\n");
1607 return false;
1608 }
1609
1610 BN_set_negative(r.get(), 1);
1611
1612 if (BN_cmp_word(r.get(), 0) >= 0 ||
1613 BN_cmp_word(r.get(), kMaxWord) >= 0) {
1614 fprintf(stderr,
1615 "BN_cmp_word compared against -kMaxWord - 1 incorrectly.\n");
1616 return false;
1617 }
1618
1619 return true;
1620}
1621
David Benjaminf0c4a6c2016-08-11 13:26:41 -04001622static bool TestBN2Dec() {
1623 static const char *kBN2DecTests[] = {
1624 "0",
1625 "1",
1626 "-1",
1627 "100",
1628 "-100",
1629 "123456789012345678901234567890",
1630 "-123456789012345678901234567890",
1631 "123456789012345678901234567890123456789012345678901234567890",
1632 "-123456789012345678901234567890123456789012345678901234567890",
1633 };
1634
1635 for (const char *test : kBN2DecTests) {
1636 bssl::UniquePtr<BIGNUM> bn;
1637 int ret = DecimalToBIGNUM(&bn, test);
1638 if (ret == 0) {
1639 return false;
1640 }
1641
1642 bssl::UniquePtr<char> dec(BN_bn2dec(bn.get()));
1643 if (!dec) {
1644 fprintf(stderr, "BN_bn2dec failed on %s.\n", test);
1645 return false;
1646 }
1647
1648 if (strcmp(dec.get(), test) != 0) {
1649 fprintf(stderr, "BN_bn2dec gave %s, wanted %s.\n", dec.get(), test);
1650 return false;
1651 }
1652 }
1653
1654 return true;
1655}
1656
Robert Sloan69939df2017-01-09 10:53:07 -08001657static bool TestBNSetGetU64() {
David Benjamin7c0d06c2016-08-11 13:26:41 -04001658 static const struct {
1659 const char *hex;
1660 uint64_t value;
1661 } kU64Tests[] = {
1662 {"0", UINT64_C(0x0)},
1663 {"1", UINT64_C(0x1)},
1664 {"ffffffff", UINT64_C(0xffffffff)},
1665 {"100000000", UINT64_C(0x100000000)},
1666 {"ffffffffffffffff", UINT64_C(0xffffffffffffffff)},
1667 };
1668
1669 for (const auto& test : kU64Tests) {
1670 bssl::UniquePtr<BIGNUM> bn(BN_new()), expected;
1671 if (!bn ||
1672 !BN_set_u64(bn.get(), test.value) ||
1673 !HexToBIGNUM(&expected, test.hex) ||
1674 BN_cmp(bn.get(), expected.get()) != 0) {
1675 fprintf(stderr, "BN_set_u64 test failed for 0x%s.\n", test.hex);
1676 ERR_print_errors_fp(stderr);
1677 return false;
1678 }
Robert Sloan69939df2017-01-09 10:53:07 -08001679
1680 uint64_t tmp;
1681 if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
1682 fprintf(stderr, "BN_get_u64 test failed for 0x%s.\n", test.hex);
1683 return false;
1684 }
1685
1686 BN_set_negative(bn.get(), 1);
1687 if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
1688 fprintf(stderr, "BN_get_u64 test failed for -0x%s.\n", test.hex);
1689 return false;
1690 }
1691 }
1692
1693 // Test that BN_get_u64 fails on large numbers.
1694 bssl::UniquePtr<BIGNUM> bn(BN_new());
1695 if (!BN_lshift(bn.get(), BN_value_one(), 64)) {
1696 return false;
1697 }
1698
1699 uint64_t tmp;
1700 if (BN_get_u64(bn.get(), &tmp)) {
1701 fprintf(stderr, "BN_get_u64 of 2^64 unexpectedly succeeded.\n");
1702 return false;
1703 }
1704
1705 BN_set_negative(bn.get(), 1);
1706 if (BN_get_u64(bn.get(), &tmp)) {
1707 fprintf(stderr, "BN_get_u64 of -2^64 unexpectedly succeeded.\n");
1708 return false;
David Benjamin7c0d06c2016-08-11 13:26:41 -04001709 }
1710
1711 return true;
1712}
1713
Robert Sloan5d625782017-02-13 09:55:39 -08001714static bool TestBNPow2(BN_CTX *ctx) {
1715 bssl::UniquePtr<BIGNUM>
1716 power_of_two(BN_new()),
1717 random(BN_new()),
1718 expected(BN_new()),
1719 actual(BN_new());
1720
1721 if (!power_of_two.get() ||
1722 !random.get() ||
1723 !expected.get() ||
1724 !actual.get()) {
1725 return false;
1726 }
1727
1728 // Choose an exponent.
1729 for (size_t e = 3; e < 512; e += 11) {
1730 // Choose a bit length for our randoms.
1731 for (int len = 3; len < 512; len += 23) {
1732 // Set power_of_two = 2^e.
1733 if (!BN_lshift(power_of_two.get(), BN_value_one(), (int) e)) {
1734 fprintf(stderr, "Failed to shiftl.\n");
1735 return false;
1736 }
1737
1738 // Test BN_is_pow2 on power_of_two.
1739 if (!BN_is_pow2(power_of_two.get())) {
1740 fprintf(stderr, "BN_is_pow2 returned false for a power of two.\n");
1741 hexdump(stderr, "Arg: ", power_of_two->d,
1742 power_of_two->top * sizeof(BN_ULONG));
1743 return false;
1744 }
1745
1746 // Pick a large random value, ensuring it isn't a power of two.
1747 if (!BN_rand(random.get(), len, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) {
1748 fprintf(stderr, "Failed to generate random in TestBNPow2.\n");
1749 return false;
1750 }
1751
1752 // Test BN_is_pow2 on |r|.
1753 if (BN_is_pow2(random.get())) {
1754 fprintf(stderr, "BN_is_pow2 returned true for a non-power of two.\n");
1755 hexdump(stderr, "Arg: ", random->d, random->top * sizeof(BN_ULONG));
1756 return false;
1757 }
1758
1759 // Test BN_mod_pow2 on |r|.
1760 if (!BN_mod(expected.get(), random.get(), power_of_two.get(), ctx) ||
1761 !BN_mod_pow2(actual.get(), random.get(), e) ||
1762 BN_cmp(actual.get(), expected.get())) {
1763 fprintf(stderr, "BN_mod_pow2 returned the wrong value:\n");
1764 hexdump(stderr, "Expected: ", expected->d,
1765 expected->top * sizeof(BN_ULONG));
1766 hexdump(stderr, "Got: ", actual->d,
1767 actual->top * sizeof(BN_ULONG));
1768 return false;
1769 }
1770
1771 // Test BN_nnmod_pow2 on |r|.
1772 if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
1773 !BN_nnmod_pow2(actual.get(), random.get(), e) ||
1774 BN_cmp(actual.get(), expected.get())) {
1775 fprintf(stderr, "BN_nnmod_pow2 failed on positive input:\n");
1776 hexdump(stderr, "Expected: ", expected->d,
1777 expected->top * sizeof(BN_ULONG));
1778 hexdump(stderr, "Got: ", actual->d,
1779 actual->top * sizeof(BN_ULONG));
1780 return false;
1781 }
1782
1783 // Test BN_nnmod_pow2 on -|r|.
1784 BN_set_negative(random.get(), 1);
1785 if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
1786 !BN_nnmod_pow2(actual.get(), random.get(), e) ||
1787 BN_cmp(actual.get(), expected.get())) {
1788 fprintf(stderr, "BN_nnmod_pow2 failed on negative input:\n");
1789 hexdump(stderr, "Expected: ", expected->d,
1790 expected->top * sizeof(BN_ULONG));
1791 hexdump(stderr, "Got: ", actual->d,
1792 actual->top * sizeof(BN_ULONG));
1793 return false;
1794 }
1795 }
1796 }
1797
1798 return true;
1799}
1800
Robert Sloan2424d842017-05-01 07:46:28 -07001801static const int kPrimes[] = {
1802 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
1803 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79,
1804 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
1805 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
1806 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
1807 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
1808 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389,
1809 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457,
1810 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523,
1811 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
1812 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,
1813 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
1814 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823,
1815 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,
1816 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977,
1817 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
1818 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117,
1819 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
1820 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289,
1821 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
1822 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453,
1823 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531,
1824 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607,
1825 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
1826 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777,
1827 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
1828 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951,
1829 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029,
1830 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113,
1831 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,
1832 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293,
1833 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
1834 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447,
1835 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
1836 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659,
1837 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713,
1838 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797,
1839 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887,
1840 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971,
1841 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
1842 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187,
1843 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
1844 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359,
1845 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461,
1846 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539,
1847 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617,
1848 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701,
1849 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
1850 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889,
1851 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
1852 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073,
1853 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157,
1854 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253,
1855 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349,
1856 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451,
1857 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
1858 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643,
1859 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
1860 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817,
1861 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
1862 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009,
1863 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101,
1864 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209,
1865 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
1866 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417,
1867 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501,
1868 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581,
1869 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683,
1870 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783,
1871 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,
1872 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953,
1873 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
1874 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163,
1875 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263,
1876 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337,
1877 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427,
1878 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553,
1879 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659,
1880 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737,
1881 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
1882 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947,
1883 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013,
1884 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127,
1885 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229,
1886 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333,
1887 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477,
1888 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547,
1889 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
1890 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717,
1891 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829,
1892 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927,
1893 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053,
1894 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147,
1895 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237,
1896 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329,
1897 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
1898 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563,
1899 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663,
1900 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737,
1901 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831,
1902 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933,
1903 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029,
1904 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137,
1905 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
1906 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337,
1907 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421,
1908 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497,
1909 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623,
1910 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721,
1911 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811,
1912 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901,
1913 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
1914 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133,
1915 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223,
1916 10243, 10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313,
1917 10321, 10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429,
1918 10433, 10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529,
1919 10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639,
1920 10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733,
1921 10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
1922 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957,
1923 10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071,
1924 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171,
1925 11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279,
1926 11287, 11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393,
1927 11399, 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491,
1928 11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617,
1929 11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
1930 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831,
1931 11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933,
1932 11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037,
1933 12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119,
1934 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241,
1935 12251, 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343,
1936 12347, 12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437,
1937 12451, 12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
1938 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613,
1939 12619, 12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713,
1940 12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823,
1941 12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923,
1942 12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009,
1943 13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127,
1944 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229,
1945 13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
1946 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457,
1947 13463, 13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577,
1948 13591, 13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687,
1949 13691, 13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759,
1950 13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877,
1951 13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967,
1952 13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083,
1953 14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
1954 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347,
1955 14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447,
1956 14449, 14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551,
1957 14557, 14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653,
1958 14657, 14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747,
1959 14753, 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831,
1960 14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939,
1961 14947, 14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
1962 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161,
1963 15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269,
1964 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349,
1965 15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443,
1966 15451, 15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559,
1967 15569, 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649,
1968 15661, 15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749,
1969 15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
1970 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959,
1971 15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069,
1972 16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187,
1973 16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301,
1974 16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421,
1975 16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529,
1976 16547, 16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649,
1977 16651, 16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
1978 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883,
1979 16889, 16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981,
1980 16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077,
1981 17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191,
1982 17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321,
1983 17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401,
1984 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491,
1985 17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
1986 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729,
1987 17737, 17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839,
1988 17851, 17863, 17881, 17891, 17903, 17909, 17911, 17921, 17923, 17929, 17939,
1989 17957, 17959, 17971, 17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047,
1990 18049, 18059, 18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133,
1991 18143, 18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233,
1992 18251, 18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313, 18329,
1993 18341, 18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427, 18433, 18439,
1994 18443, 18451, 18457, 18461, 18481, 18493, 18503, 18517, 18521, 18523, 18539,
1995 18541, 18553, 18583, 18587, 18593, 18617, 18637, 18661, 18671, 18679, 18691,
1996 18701, 18713, 18719, 18731, 18743, 18749, 18757, 18773, 18787, 18793, 18797,
1997 18803, 18839, 18859, 18869, 18899, 18911, 18913, 18917, 18919, 18947, 18959,
1998 18973, 18979, 19001, 19009, 19013, 19031, 19037, 19051, 19069, 19073, 19079,
1999 19081, 19087, 19121, 19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211,
2000 19213, 19219, 19231, 19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309,
2001 19319, 19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423,
2002 19427, 19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, 19483,
2003 19489, 19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, 19577, 19583,
2004 19597, 19603, 19609, 19661, 19681, 19687, 19697, 19699, 19709, 19717, 19727,
2005 19739, 19751, 19753, 19759, 19763, 19777, 19793, 19801, 19813, 19819, 19841,
2006 19843, 19853, 19861, 19867, 19889, 19891, 19913, 19919, 19927, 19937, 19949,
2007 19961, 19963, 19973, 19979, 19991, 19993, 19997,
Robert Sloan9254e682017-04-24 09:42:06 -07002008};
2009
2010static bool TestPrimeChecking(BN_CTX *ctx) {
2011 bssl::UniquePtr<BIGNUM> p(BN_new());
2012 int is_probably_prime_1 = 0, is_probably_prime_2 = 0;
2013
2014 const int max_prime = kPrimes[OPENSSL_ARRAY_SIZE(kPrimes)-1];
2015 size_t next_prime_index = 0;
2016
2017 for (int i = 0; i <= max_prime; i++) {
2018 bool is_prime = false;
2019
2020 if (i == kPrimes[next_prime_index]) {
2021 is_prime = true;
2022 next_prime_index++;
2023 }
2024
2025 if (!BN_set_word(p.get(), i) ||
2026 !BN_primality_test(&is_probably_prime_1, p.get(), BN_prime_checks, ctx,
2027 false /* do_trial_division */,
2028 nullptr /* callback */) ||
2029 is_probably_prime_1 != (is_prime ? 1 : 0) ||
2030 !BN_primality_test(&is_probably_prime_2, p.get(), BN_prime_checks, ctx,
2031 true /* do_trial_division */,
2032 nullptr /* callback */) ||
2033 is_probably_prime_2 != (is_prime ? 1 : 0)) {
2034 fprintf(stderr,
2035 "TestPrimeChecking failed for %d (is_prime: %d vs %d without "
2036 "trial division vs %d with it)\n",
2037 i, static_cast<int>(is_prime), is_probably_prime_1,
2038 is_probably_prime_2);
2039 return false;
2040 }
2041 }
2042
2043 // Negative numbers are not prime.
2044 if (!BN_set_word(p.get(), 7)) {
2045 return false;
2046 }
2047 BN_set_negative(p.get(), 1);
2048 if (!BN_primality_test(&is_probably_prime_1, p.get(), BN_prime_checks, ctx,
2049 false /* do_trial_division */,
2050 nullptr /* callback */) ||
2051 is_probably_prime_1 != 0 ||
2052 !BN_primality_test(&is_probably_prime_2, p.get(), BN_prime_checks, ctx,
2053 true /* do_trial_division */,
2054 nullptr /* callback */) ||
2055 is_probably_prime_2 != 0) {
2056 fprintf(stderr,
2057 "TestPrimeChecking failed for -7 (is_prime: 0 vs %d without "
2058 "trial division vs %d with it)\n",
2059 is_probably_prime_1, is_probably_prime_2);
2060 return false;
2061 }
2062
2063 return true;
2064}
2065
David Benjaminc895d6b2016-08-11 13:26:41 -04002066int main(int argc, char *argv[]) {
2067 CRYPTO_library_init();
2068
2069 if (argc != 2) {
2070 fprintf(stderr, "%s TEST_FILE\n", argv[0]);
2071 return 1;
2072 }
2073
David Benjaminf0c4a6c2016-08-11 13:26:41 -04002074 bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
David Benjaminc895d6b2016-08-11 13:26:41 -04002075 if (!ctx) {
2076 return 1;
2077 }
2078
2079 if (!TestBN2BinPadded(ctx.get()) ||
2080 !TestDec2BN(ctx.get()) ||
2081 !TestHex2BN(ctx.get()) ||
2082 !TestASC2BN(ctx.get()) ||
Robert Sloan69939df2017-01-09 10:53:07 -08002083 !TestLittleEndian() ||
David Benjaminc895d6b2016-08-11 13:26:41 -04002084 !TestMPI() ||
2085 !TestRand() ||
Robert Sloan572a4e22017-04-17 10:52:19 -07002086 !TestRandRange() ||
David Benjaminc895d6b2016-08-11 13:26:41 -04002087 !TestASN1() ||
2088 !TestNegativeZero(ctx.get()) ||
2089 !TestBadModulus(ctx.get()) ||
2090 !TestExpModZero() ||
2091 !TestSmallPrime(ctx.get()) ||
David Benjaminf0c4a6c2016-08-11 13:26:41 -04002092 !TestCmpWord() ||
David Benjamin7c0d06c2016-08-11 13:26:41 -04002093 !TestBN2Dec() ||
Robert Sloan5d625782017-02-13 09:55:39 -08002094 !TestBNSetGetU64() ||
Robert Sloan9254e682017-04-24 09:42:06 -07002095 !TestBNPow2(ctx.get()) ||
2096 !TestPrimeChecking(ctx.get())) {
Robert Sloan572a4e22017-04-17 10:52:19 -07002097 ERR_print_errors_fp(stderr);
David Benjaminc895d6b2016-08-11 13:26:41 -04002098 return 1;
2099 }
2100
2101 return FileTestMain(RunTest, ctx.get(), argv[1]);
2102}