Home | History | Annotate | Download | only in bn
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 
     70 /* 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
     76 #if !defined(__STDC_FORMAT_MACROS)
     77 #define __STDC_FORMAT_MACROS
     78 #endif
     79 
     80 #include <assert.h>
     81 #include <errno.h>
     82 #include <limits.h>
     83 #include <stdio.h>
     84 #include <string.h>
     85 
     86 #include <utility>
     87 
     88 #include <openssl/bn.h>
     89 #include <openssl/bytestring.h>
     90 #include <openssl/crypto.h>
     91 #include <openssl/err.h>
     92 #include <openssl/mem.h>
     93 
     94 #include "../internal.h"
     95 #include "../test/file_test.h"
     96 #include "../test/test_util.h"
     97 
     98 
     99 static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
    100   BIGNUM *raw = NULL;
    101   int ret = BN_hex2bn(&raw, in);
    102   out->reset(raw);
    103   return ret;
    104 }
    105 
    106 static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *attribute) {
    107   std::string hex;
    108   if (!t->GetAttribute(&hex, attribute)) {
    109     return nullptr;
    110   }
    111 
    112   bssl::UniquePtr<BIGNUM> ret;
    113   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 
    120 static bool GetInt(FileTest *t, int *out, const char *attribute) {
    121   bssl::UniquePtr<BIGNUM> ret = GetBIGNUM(t, attribute);
    122   if (!ret) {
    123     return false;
    124   }
    125 
    126   BN_ULONG word = BN_get_word(ret.get());
    127   if (word > INT_MAX) {
    128     return false;
    129   }
    130 
    131   *out = static_cast<int>(word);
    132   return true;
    133 }
    134 
    135 static 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 
    141   bssl::UniquePtr<char> expected_str(BN_bn2hex(expected));
    142   bssl::UniquePtr<char> actual_str(BN_bn2hex(actual));
    143   if (!expected_str || !actual_str) {
    144     return false;
    145   }
    146 
    147   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;
    152 }
    153 
    154 static bool TestSum(FileTest *t, BN_CTX *ctx) {
    155   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    156   bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
    157   bssl::UniquePtr<BIGNUM> sum = GetBIGNUM(t, "Sum");
    158   if (!a || !b || !sum) {
    159     return false;
    160   }
    161 
    162   bssl::UniquePtr<BIGNUM> ret(BN_new());
    163   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())) {
    170     return false;
    171   }
    172 
    173   // 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())) {
    194     return false;
    195   }
    196 
    197   // 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())) {
    209       return false;
    210     }
    211 
    212     // 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())) {
    233       return false;
    234     }
    235   }
    236 
    237   // 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())) {
    246       return false;
    247     }
    248   }
    249 
    250   return true;
    251 }
    252 
    253 static bool TestLShift1(FileTest *t, BN_CTX *ctx) {
    254   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    255   bssl::UniquePtr<BIGNUM> lshift1 = GetBIGNUM(t, "LShift1");
    256   bssl::UniquePtr<BIGNUM> zero(BN_new());
    257   if (!a || !lshift1 || !zero) {
    258     return false;
    259   }
    260 
    261   BN_zero(zero.get());
    262 
    263   bssl::UniquePtr<BIGNUM> ret(BN_new()), two(BN_new()), remainder(BN_new());
    264   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())) {
    288     return false;
    289   }
    290 
    291   return true;
    292 }
    293 
    294 static bool TestLShift(FileTest *t, BN_CTX *ctx) {
    295   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    296   bssl::UniquePtr<BIGNUM> lshift = GetBIGNUM(t, "LShift");
    297   int n = 0;
    298   if (!a || !lshift || !GetInt(t, &n, "N")) {
    299     return false;
    300   }
    301 
    302   bssl::UniquePtr<BIGNUM> ret(BN_new());
    303   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())) {
    308     return false;
    309   }
    310 
    311   return true;
    312 }
    313 
    314 static bool TestRShift(FileTest *t, BN_CTX *ctx) {
    315   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    316   bssl::UniquePtr<BIGNUM> rshift = GetBIGNUM(t, "RShift");
    317   int n = 0;
    318   if (!a || !rshift || !GetInt(t, &n, "N")) {
    319     return false;
    320   }
    321 
    322   bssl::UniquePtr<BIGNUM> ret(BN_new());
    323   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 
    332 static bool TestSquare(FileTest *t, BN_CTX *ctx) {
    333   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    334   bssl::UniquePtr<BIGNUM> square = GetBIGNUM(t, "Square");
    335   bssl::UniquePtr<BIGNUM> zero(BN_new());
    336   if (!a || !square || !zero) {
    337     return false;
    338   }
    339 
    340   BN_zero(zero.get());
    341 
    342   bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
    343   if (!ret || !remainder ||
    344       !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())) {
    362     bssl::UniquePtr<BIGNUM> tmp(BN_new());
    363     if (!tmp || !BN_copy(tmp.get(), square.get())) {
    364       return false;
    365     }
    366     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 
    388 static bool TestProduct(FileTest *t, BN_CTX *ctx) {
    389   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());
    393   if (!a || !b || !product || !zero) {
    394     return false;
    395   }
    396 
    397   BN_zero(zero.get());
    398 
    399   bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
    400   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 
    415 static bool TestQuotient(FileTest *t, BN_CTX *ctx) {
    416   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");
    420   if (!a || !b || !quotient || !remainder) {
    421     return false;
    422   }
    423 
    424   bssl::UniquePtr<BIGNUM> ret(BN_new()), ret2(BN_new());
    425   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);
    459       return false;
    460     }
    461   }
    462 
    463   // Test BN_nnmod.
    464   if (!BN_is_negative(b.get())) {
    465     bssl::UniquePtr<BIGNUM> nnmod(BN_new());
    466     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())) {
    473       return false;
    474     }
    475   }
    476 
    477   return true;
    478 }
    479 
    480 static bool TestModMul(FileTest *t, BN_CTX *ctx) {
    481   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");
    485   if (!a || !b || !m || !mod_mul) {
    486     return false;
    487   }
    488 
    489   bssl::UniquePtr<BIGNUM> ret(BN_new());
    490   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.
    498     bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
    499     bssl::UniquePtr<BIGNUM> a_tmp(BN_new()), b_tmp(BN_new());
    500     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 
    518 static 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 
    566 static bool TestModExp(FileTest *t, BN_CTX *ctx) {
    567   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");
    571   if (!a || !e || !m || !mod_exp) {
    572     return false;
    573   }
    574 
    575   bssl::UniquePtr<BIGNUM> ret(BN_new());
    576   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 
    597 static bool TestExp(FileTest *t, BN_CTX *ctx) {
    598   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    599   bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
    600   bssl::UniquePtr<BIGNUM> exp = GetBIGNUM(t, "Exp");
    601   if (!a || !e || !exp) {
    602     return false;
    603   }
    604 
    605   bssl::UniquePtr<BIGNUM> ret(BN_new());
    606   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 
    615 static bool TestModSqrt(FileTest *t, BN_CTX *ctx) {
    616   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    617   bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
    618   bssl::UniquePtr<BIGNUM> mod_sqrt = GetBIGNUM(t, "ModSqrt");
    619   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())) {
    623     return false;
    624   }
    625 
    626   // -0 is 0, not P.
    627   if (BN_is_zero(mod_sqrt.get())) {
    628     BN_zero(mod_sqrt2.get());
    629   }
    630 
    631   bssl::UniquePtr<BIGNUM> ret(BN_new());
    632   if (!ret ||
    633       !BN_mod_sqrt(ret.get(), a.get(), p.get(), ctx)) {
    634     return false;
    635   }
    636 
    637   if (BN_cmp(ret.get(), mod_sqrt2.get()) != 0 &&
    638       !ExpectBIGNUMsEqual(t, "sqrt(A) (mod P)", mod_sqrt.get(), ret.get())) {
    639     return false;
    640   }
    641 
    642   return true;
    643 }
    644 
    645 static 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 
    668 static bool TestModInv(FileTest *t, BN_CTX *ctx) {
    669   bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
    670   bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
    671   bssl::UniquePtr<BIGNUM> mod_inv = GetBIGNUM(t, "ModInv");
    672   if (!a || !m || !mod_inv) {
    673     return false;
    674   }
    675 
    676   bssl::UniquePtr<BIGNUM> ret(BN_new());
    677   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 
    683   return true;
    684 }
    685 
    686 struct Test {
    687   const char *name;
    688   bool (*func)(FileTest *t, BN_CTX *ctx);
    689 };
    690 
    691 static 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},
    700     {"ModSquare", TestModSquare},
    701     {"ModExp", TestModExp},
    702     {"Exp", TestExp},
    703     {"ModSqrt", TestModSqrt},
    704     {"NotModSquare", TestNotModSquare},
    705     {"ModInv", TestModInv},
    706 };
    707 
    708 static 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 
    720 static bool TestBN2BinPadded(BN_CTX *ctx) {
    721   uint8_t zeros[256], out[256], reference[128];
    722 
    723   OPENSSL_memset(zeros, 0, sizeof(zeros));
    724 
    725   // Test edge case at 0.
    726   bssl::UniquePtr<BIGNUM> n(BN_new());
    727   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   }
    732   OPENSSL_memset(out, -1, sizeof(out));
    733   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   }
    738   if (OPENSSL_memcmp(zeros, out, sizeof(out))) {
    739     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++) {
    745     if (!BN_rand(n.get(), bytes * 8, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
    746       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()) ||
    767         OPENSSL_memcmp(out, reference, bytes) != 0) {
    768       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()) ||
    773         OPENSSL_memcmp(out + 1, reference, bytes) ||
    774         OPENSSL_memcmp(out, zeros, 1)) {
    775       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()) ||
    780         OPENSSL_memcmp(out + sizeof(out) - bytes, reference, bytes) ||
    781         OPENSSL_memcmp(out, zeros, sizeof(out) - bytes)) {
    782       fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
    783       return false;
    784     }
    785   }
    786 
    787   return true;
    788 }
    789 
    790 static 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 
    866 static int DecimalToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
    867   BIGNUM *raw = NULL;
    868   int ret = BN_dec2bn(&raw, in);
    869   out->reset(raw);
    870   return ret;
    871 }
    872 
    873 static bool TestDec2BN(BN_CTX *ctx) {
    874   bssl::UniquePtr<BIGNUM> bn;
    875   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 
    908 static bool TestHex2BN(BN_CTX *ctx) {
    909   bssl::UniquePtr<BIGNUM> bn;
    910   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 
    943 static bssl::UniquePtr<BIGNUM> ASCIIToBIGNUM(const char *in) {
    944   BIGNUM *raw = NULL;
    945   if (!BN_asc2bn(&raw, in)) {
    946     return nullptr;
    947   }
    948   return bssl::UniquePtr<BIGNUM>(raw);
    949 }
    950 
    951 static bool TestASC2BN(BN_CTX *ctx) {
    952   bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("0");
    953   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 }
   1002 
   1003 struct MPITest {
   1004   const char *base10;
   1005   const char *mpi;
   1006   size_t mpi_len;
   1007 };
   1008 
   1009 static 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 
   1018 static bool TestMPI() {
   1019   uint8_t scratch[8];
   1020 
   1021   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMPITests); i++) {
   1022     const MPITest &test = kMPITests[i];
   1023     bssl::UniquePtr<BIGNUM> bn(ASCIIToBIGNUM(test.base10));
   1024     if (!bn) {
   1025       return false;
   1026     }
   1027 
   1028     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 ||
   1042         OPENSSL_memcmp(test.mpi, scratch, mpi_len) != 0) {
   1043       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 
   1049     bssl::UniquePtr<BIGNUM> bn2(BN_mpi2bn(scratch, mpi_len, NULL));
   1050     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 
   1064 static bool TestRand() {
   1065   bssl::UniquePtr<BIGNUM> bn(BN_new());
   1066   if (!bn) {
   1067     return false;
   1068   }
   1069 
   1070   // Test BN_rand accounts for degenerate cases with |top| and |bottom|
   1071   // parameters.
   1072   if (!BN_rand(bn.get(), 0, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
   1073       !BN_is_zero(bn.get())) {
   1074     fprintf(stderr, "BN_rand gave a bad result.\n");
   1075     return false;
   1076   }
   1077   if (!BN_rand(bn.get(), 0, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD) ||
   1078       !BN_is_zero(bn.get())) {
   1079     fprintf(stderr, "BN_rand gave a bad result.\n");
   1080     return false;
   1081   }
   1082 
   1083   if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
   1084       !BN_is_word(bn.get(), 1)) {
   1085     fprintf(stderr, "BN_rand gave a bad result.\n");
   1086     return false;
   1087   }
   1088   if (!BN_rand(bn.get(), 1, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
   1089       !BN_is_word(bn.get(), 1)) {
   1090     fprintf(stderr, "BN_rand gave a bad result.\n");
   1091     return false;
   1092   }
   1093   if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ODD) ||
   1094       !BN_is_word(bn.get(), 1)) {
   1095     fprintf(stderr, "BN_rand gave a bad result.\n");
   1096     return false;
   1097   }
   1098 
   1099   if (!BN_rand(bn.get(), 2, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
   1100       !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 }
   1107 
   1108 struct ASN1Test {
   1109   const char *value_ascii;
   1110   const char *der;
   1111   size_t der_len;
   1112 };
   1113 
   1114 static const ASN1Test kASN1Tests[] = {
   1115     {"0", "\x02\x01\x00", 3},
   1116     {"1", "\x02\x01\x01", 3},
   1117     {"127", "\x02\x01\x7f", 3},
   1118     {"128", "\x02\x02\x00\x80", 4},
   1119     {"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
   1120     {"0x0102030405060708",
   1121      "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
   1122     {"0xffffffffffffffff",
   1123       "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
   1124 };
   1125 
   1126 struct ASN1InvalidTest {
   1127   const char *der;
   1128   size_t der_len;
   1129 };
   1130 
   1131 static const ASN1InvalidTest kASN1InvalidTests[] = {
   1132     // Bad tag.
   1133     {"\x03\x01\x00", 3},
   1134     // Empty contents.
   1135     {"\x02\x00", 2},
   1136 };
   1137 
   1138 // kASN1BuggyTests contains incorrect encodings and the corresponding, expected
   1139 // results of |BN_parse_asn1_unsigned_buggy| given that input.
   1140 static const ASN1Test kASN1BuggyTests[] = {
   1141     // Negative numbers.
   1142     {"128", "\x02\x01\x80", 3},
   1143     {"255", "\x02\x01\xff", 3},
   1144     // Unnecessary leading zeros.
   1145     {"1", "\x02\x02\x00\x01", 4},
   1146 };
   1147 
   1148 static bool TestASN1() {
   1149   for (const ASN1Test &test : kASN1Tests) {
   1150     bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM(test.value_ascii);
   1151     if (!bn) {
   1152       return false;
   1153     }
   1154 
   1155     // Test that the input is correctly parsed.
   1156     bssl::UniquePtr<BIGNUM> bn2(BN_new());
   1157     if (!bn2) {
   1158       return false;
   1159     }
   1160     CBS cbs;
   1161     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
   1162     if (!BN_parse_asn1_unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
   1163       fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
   1164       return false;
   1165     }
   1166     if (BN_cmp(bn.get(), bn2.get()) != 0) {
   1167       fprintf(stderr, "Bad parse.\n");
   1168       return false;
   1169     }
   1170 
   1171     // Test the value serializes correctly.
   1172     bssl::ScopedCBB cbb;
   1173     uint8_t *der;
   1174     size_t der_len;
   1175     if (!CBB_init(cbb.get(), 0) ||
   1176         !BN_marshal_asn1(cbb.get(), bn.get()) ||
   1177         !CBB_finish(cbb.get(), &der, &der_len)) {
   1178       return false;
   1179     }
   1180     bssl::UniquePtr<uint8_t> delete_der(der);
   1181     if (der_len != test.der_len ||
   1182         OPENSSL_memcmp(der, reinterpret_cast<const uint8_t *>(test.der),
   1183                        der_len) != 0) {
   1184       fprintf(stderr, "Bad serialization.\n");
   1185       return false;
   1186     }
   1187 
   1188     // |BN_parse_asn1_unsigned_buggy| parses all valid input.
   1189     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
   1190     if (!BN_parse_asn1_unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
   1191       fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
   1192       return false;
   1193     }
   1194     if (BN_cmp(bn.get(), bn2.get()) != 0) {
   1195       fprintf(stderr, "Bad parse.\n");
   1196       return false;
   1197     }
   1198   }
   1199 
   1200   for (const ASN1InvalidTest &test : kASN1InvalidTests) {
   1201     bssl::UniquePtr<BIGNUM> bn(BN_new());
   1202     if (!bn) {
   1203       return false;
   1204     }
   1205     CBS cbs;
   1206     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
   1207     if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
   1208       fprintf(stderr, "Parsed invalid input.\n");
   1209       return false;
   1210     }
   1211     ERR_clear_error();
   1212 
   1213     // All tests in kASN1InvalidTests are also rejected by
   1214     // |BN_parse_asn1_unsigned_buggy|.
   1215     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
   1216     if (BN_parse_asn1_unsigned_buggy(&cbs, bn.get())) {
   1217       fprintf(stderr, "Parsed invalid input.\n");
   1218       return false;
   1219     }
   1220     ERR_clear_error();
   1221   }
   1222 
   1223   for (const ASN1Test &test : kASN1BuggyTests) {
   1224     // These broken encodings are rejected by |BN_parse_asn1_unsigned|.
   1225     bssl::UniquePtr<BIGNUM> bn(BN_new());
   1226     if (!bn) {
   1227       return false;
   1228     }
   1229 
   1230     CBS cbs;
   1231     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
   1232     if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
   1233       fprintf(stderr, "Parsed invalid input.\n");
   1234       return false;
   1235     }
   1236     ERR_clear_error();
   1237 
   1238     // However |BN_parse_asn1_unsigned_buggy| accepts them.
   1239     bssl::UniquePtr<BIGNUM> bn2 = ASCIIToBIGNUM(test.value_ascii);
   1240     if (!bn2) {
   1241       return false;
   1242     }
   1243 
   1244     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
   1245     if (!BN_parse_asn1_unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
   1246       fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
   1247       return false;
   1248     }
   1249 
   1250     if (BN_cmp(bn.get(), bn2.get()) != 0) {
   1251       fprintf(stderr, "\"Bad\" parse.\n");
   1252       return false;
   1253     }
   1254   }
   1255 
   1256   // Serializing negative numbers is not supported.
   1257   bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("-1");
   1258   if (!bn) {
   1259     return false;
   1260   }
   1261   bssl::ScopedCBB cbb;
   1262   if (!CBB_init(cbb.get(), 0) ||
   1263       BN_marshal_asn1(cbb.get(), bn.get())) {
   1264     fprintf(stderr, "Serialized negative number.\n");
   1265     return false;
   1266   }
   1267   ERR_clear_error();
   1268 
   1269   return true;
   1270 }
   1271 
   1272 static bool TestNegativeZero(BN_CTX *ctx) {
   1273   bssl::UniquePtr<BIGNUM> a(BN_new());
   1274   bssl::UniquePtr<BIGNUM> b(BN_new());
   1275   bssl::UniquePtr<BIGNUM> c(BN_new());
   1276   if (!a || !b || !c) {
   1277     return false;
   1278   }
   1279 
   1280   // Test that BN_mul never gives negative zero.
   1281   if (!BN_set_word(a.get(), 1)) {
   1282     return false;
   1283   }
   1284   BN_set_negative(a.get(), 1);
   1285   BN_zero(b.get());
   1286   if (!BN_mul(c.get(), a.get(), b.get(), ctx)) {
   1287     return false;
   1288   }
   1289   if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
   1290     fprintf(stderr, "Multiplication test failed.\n");
   1291     return false;
   1292   }
   1293 
   1294   bssl::UniquePtr<BIGNUM> numerator(BN_new()), denominator(BN_new());
   1295   if (!numerator || !denominator) {
   1296     return false;
   1297   }
   1298 
   1299   // Test that BN_div never gives negative zero in the quotient.
   1300   if (!BN_set_word(numerator.get(), 1) ||
   1301       !BN_set_word(denominator.get(), 2)) {
   1302     return false;
   1303   }
   1304   BN_set_negative(numerator.get(), 1);
   1305   if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
   1306     return false;
   1307   }
   1308   if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
   1309     fprintf(stderr, "Incorrect quotient.\n");
   1310     return false;
   1311   }
   1312 
   1313   // Test that BN_div never gives negative zero in the remainder.
   1314   if (!BN_set_word(denominator.get(), 1)) {
   1315     return false;
   1316   }
   1317   if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
   1318     return false;
   1319   }
   1320   if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
   1321     fprintf(stderr, "Incorrect remainder.\n");
   1322     return false;
   1323   }
   1324 
   1325   // Test that BN_set_negative will not produce a negative zero.
   1326   BN_zero(a.get());
   1327   BN_set_negative(a.get(), 1);
   1328   if (BN_is_negative(a.get())) {
   1329     fprintf(stderr, "BN_set_negative produced a negative zero.\n");
   1330     return false;
   1331   }
   1332 
   1333   // Test that forcibly creating a negative zero does not break |BN_bn2hex| or
   1334   // |BN_bn2dec|.
   1335   a->neg = 1;
   1336   bssl::UniquePtr<char> dec(BN_bn2dec(a.get()));
   1337   bssl::UniquePtr<char> hex(BN_bn2hex(a.get()));
   1338   if (!dec || !hex ||
   1339       strcmp(dec.get(), "-0") != 0 ||
   1340       strcmp(hex.get(), "-0") != 0) {
   1341     fprintf(stderr, "BN_bn2dec or BN_bn2hex failed with negative zero.\n");
   1342     return false;
   1343   }
   1344 
   1345   // Test that |BN_rshift| and |BN_rshift1| will not produce a negative zero.
   1346   if (!BN_set_word(a.get(), 1)) {
   1347     return false;
   1348   }
   1349 
   1350   BN_set_negative(a.get(), 1);
   1351   if (!BN_rshift(b.get(), a.get(), 1) ||
   1352       !BN_rshift1(c.get(), a.get())) {
   1353     return false;
   1354   }
   1355 
   1356   if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
   1357     fprintf(stderr, "BN_rshift(-1, 1) produced the wrong result.\n");
   1358     return false;
   1359   }
   1360 
   1361   if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
   1362     fprintf(stderr, "BN_rshift1(-1) produced the wrong result.\n");
   1363     return false;
   1364   }
   1365 
   1366   // Test that |BN_div_word| will not produce a negative zero.
   1367   if (BN_div_word(a.get(), 2) == (BN_ULONG)-1) {
   1368     return false;
   1369   }
   1370 
   1371   if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
   1372     fprintf(stderr, "BN_div_word(-1, 2) produced the wrong result.\n");
   1373     return false;
   1374   }
   1375 
   1376   return true;
   1377 }
   1378 
   1379 static bool TestBadModulus(BN_CTX *ctx) {
   1380   bssl::UniquePtr<BIGNUM> a(BN_new());
   1381   bssl::UniquePtr<BIGNUM> b(BN_new());
   1382   bssl::UniquePtr<BIGNUM> zero(BN_new());
   1383   bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
   1384   if (!a || !b || !zero || !mont) {
   1385     return false;
   1386   }
   1387 
   1388   BN_zero(zero.get());
   1389 
   1390   if (BN_div(a.get(), b.get(), BN_value_one(), zero.get(), ctx)) {
   1391     fprintf(stderr, "Division by zero unexpectedly succeeded.\n");
   1392     return false;
   1393   }
   1394   ERR_clear_error();
   1395 
   1396   if (BN_mod_mul(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx)) {
   1397     fprintf(stderr, "BN_mod_mul with zero modulus unexpectedly succeeded.\n");
   1398     return false;
   1399   }
   1400   ERR_clear_error();
   1401 
   1402   if (BN_mod_exp(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx)) {
   1403     fprintf(stderr, "BN_mod_exp with zero modulus unexpectedly succeeded.\n");
   1404     return 0;
   1405   }
   1406   ERR_clear_error();
   1407 
   1408   if (BN_mod_exp_mont(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx,
   1409                       NULL)) {
   1410     fprintf(stderr,
   1411             "BN_mod_exp_mont with zero modulus unexpectedly succeeded.\n");
   1412     return 0;
   1413   }
   1414   ERR_clear_error();
   1415 
   1416   if (BN_mod_exp_mont_consttime(a.get(), BN_value_one(), BN_value_one(),
   1417                                 zero.get(), ctx, nullptr)) {
   1418     fprintf(stderr,
   1419             "BN_mod_exp_mont_consttime with zero modulus unexpectedly "
   1420             "succeeded.\n");
   1421     return 0;
   1422   }
   1423   ERR_clear_error();
   1424 
   1425   if (BN_MONT_CTX_set(mont.get(), zero.get(), ctx)) {
   1426     fprintf(stderr,
   1427             "BN_MONT_CTX_set unexpectedly succeeded for zero modulus.\n");
   1428     return false;
   1429   }
   1430   ERR_clear_error();
   1431 
   1432   // Some operations also may not be used with an even modulus.
   1433 
   1434   if (!BN_set_word(b.get(), 16)) {
   1435     return false;
   1436   }
   1437 
   1438   if (BN_MONT_CTX_set(mont.get(), b.get(), ctx)) {
   1439     fprintf(stderr,
   1440             "BN_MONT_CTX_set unexpectedly succeeded for even modulus.\n");
   1441     return false;
   1442   }
   1443   ERR_clear_error();
   1444 
   1445   if (BN_mod_exp_mont(a.get(), BN_value_one(), BN_value_one(), b.get(), ctx,
   1446                       NULL)) {
   1447     fprintf(stderr,
   1448             "BN_mod_exp_mont with even modulus unexpectedly succeeded.\n");
   1449     return 0;
   1450   }
   1451   ERR_clear_error();
   1452 
   1453   if (BN_mod_exp_mont_consttime(a.get(), BN_value_one(), BN_value_one(),
   1454                                 b.get(), ctx, nullptr)) {
   1455     fprintf(stderr,
   1456             "BN_mod_exp_mont_consttime with even modulus unexpectedly "
   1457             "succeeded.\n");
   1458     return 0;
   1459   }
   1460   ERR_clear_error();
   1461 
   1462   return true;
   1463 }
   1464 
   1465 // TestExpModZero tests that 1**0 mod 1 == 0.
   1466 static bool TestExpModZero() {
   1467   bssl::UniquePtr<BIGNUM> zero(BN_new()), a(BN_new()), r(BN_new());
   1468   if (!zero || !a || !r ||
   1469       !BN_rand(a.get(), 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
   1470     return false;
   1471   }
   1472   BN_zero(zero.get());
   1473 
   1474   if (!BN_mod_exp(r.get(), a.get(), zero.get(), BN_value_one(), nullptr) ||
   1475       !BN_is_zero(r.get()) ||
   1476       !BN_mod_exp_mont(r.get(), a.get(), zero.get(), BN_value_one(), nullptr,
   1477                        nullptr) ||
   1478       !BN_is_zero(r.get()) ||
   1479       !BN_mod_exp_mont_consttime(r.get(), a.get(), zero.get(), BN_value_one(),
   1480                                  nullptr, nullptr) ||
   1481       !BN_is_zero(r.get()) ||
   1482       !BN_mod_exp_mont_word(r.get(), 42, zero.get(), BN_value_one(), nullptr,
   1483                             nullptr) ||
   1484       !BN_is_zero(r.get())) {
   1485     return false;
   1486   }
   1487 
   1488   return true;
   1489 }
   1490 
   1491 static bool TestSmallPrime(BN_CTX *ctx) {
   1492   static const unsigned kBits = 10;
   1493 
   1494   bssl::UniquePtr<BIGNUM> r(BN_new());
   1495   if (!r || !BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
   1496                                   NULL, NULL)) {
   1497     return false;
   1498   }
   1499   if (BN_num_bits(r.get()) != kBits) {
   1500     fprintf(stderr, "Expected %u bit prime, got %u bit number\n", kBits,
   1501             BN_num_bits(r.get()));
   1502     return false;
   1503   }
   1504 
   1505   return true;
   1506 }
   1507 
   1508 static bool TestCmpWord() {
   1509   static const BN_ULONG kMaxWord = (BN_ULONG)-1;
   1510 
   1511   bssl::UniquePtr<BIGNUM> r(BN_new());
   1512   if (!r ||
   1513       !BN_set_word(r.get(), 0)) {
   1514     return false;
   1515   }
   1516 
   1517   if (BN_cmp_word(r.get(), 0) != 0 ||
   1518       BN_cmp_word(r.get(), 1) >= 0 ||
   1519       BN_cmp_word(r.get(), kMaxWord) >= 0) {
   1520     fprintf(stderr, "BN_cmp_word compared against 0 incorrectly.\n");
   1521     return false;
   1522   }
   1523 
   1524   if (!BN_set_word(r.get(), 100)) {
   1525     return false;
   1526   }
   1527 
   1528   if (BN_cmp_word(r.get(), 0) <= 0 ||
   1529       BN_cmp_word(r.get(), 99) <= 0 ||
   1530       BN_cmp_word(r.get(), 100) != 0 ||
   1531       BN_cmp_word(r.get(), 101) >= 0 ||
   1532       BN_cmp_word(r.get(), kMaxWord) >= 0) {
   1533     fprintf(stderr, "BN_cmp_word compared against 100 incorrectly.\n");
   1534     return false;
   1535   }
   1536 
   1537   BN_set_negative(r.get(), 1);
   1538 
   1539   if (BN_cmp_word(r.get(), 0) >= 0 ||
   1540       BN_cmp_word(r.get(), 100) >= 0 ||
   1541       BN_cmp_word(r.get(), kMaxWord) >= 0) {
   1542     fprintf(stderr, "BN_cmp_word compared against -100 incorrectly.\n");
   1543     return false;
   1544   }
   1545 
   1546   if (!BN_set_word(r.get(), kMaxWord)) {
   1547     return false;
   1548   }
   1549 
   1550   if (BN_cmp_word(r.get(), 0) <= 0 ||
   1551       BN_cmp_word(r.get(), kMaxWord - 1) <= 0 ||
   1552       BN_cmp_word(r.get(), kMaxWord) != 0) {
   1553     fprintf(stderr, "BN_cmp_word compared against kMaxWord incorrectly.\n");
   1554     return false;
   1555   }
   1556 
   1557   if (!BN_add(r.get(), r.get(), BN_value_one())) {
   1558     return false;
   1559   }
   1560 
   1561   if (BN_cmp_word(r.get(), 0) <= 0 ||
   1562       BN_cmp_word(r.get(), kMaxWord) <= 0) {
   1563     fprintf(stderr, "BN_cmp_word compared against kMaxWord + 1 incorrectly.\n");
   1564     return false;
   1565   }
   1566 
   1567   BN_set_negative(r.get(), 1);
   1568 
   1569   if (BN_cmp_word(r.get(), 0) >= 0 ||
   1570       BN_cmp_word(r.get(), kMaxWord) >= 0) {
   1571     fprintf(stderr,
   1572             "BN_cmp_word compared against -kMaxWord - 1 incorrectly.\n");
   1573     return false;
   1574   }
   1575 
   1576   return true;
   1577 }
   1578 
   1579 static bool TestBN2Dec() {
   1580   static const char *kBN2DecTests[] = {
   1581       "0",
   1582       "1",
   1583       "-1",
   1584       "100",
   1585       "-100",
   1586       "123456789012345678901234567890",
   1587       "-123456789012345678901234567890",
   1588       "123456789012345678901234567890123456789012345678901234567890",
   1589       "-123456789012345678901234567890123456789012345678901234567890",
   1590   };
   1591 
   1592   for (const char *test : kBN2DecTests) {
   1593     bssl::UniquePtr<BIGNUM> bn;
   1594     int ret = DecimalToBIGNUM(&bn, test);
   1595     if (ret == 0) {
   1596       return false;
   1597     }
   1598 
   1599     bssl::UniquePtr<char> dec(BN_bn2dec(bn.get()));
   1600     if (!dec) {
   1601       fprintf(stderr, "BN_bn2dec failed on %s.\n", test);
   1602       return false;
   1603     }
   1604 
   1605     if (strcmp(dec.get(), test) != 0) {
   1606       fprintf(stderr, "BN_bn2dec gave %s, wanted %s.\n", dec.get(), test);
   1607       return false;
   1608     }
   1609   }
   1610 
   1611   return true;
   1612 }
   1613 
   1614 static bool TestBNSetGetU64() {
   1615   static const struct {
   1616     const char *hex;
   1617     uint64_t value;
   1618   } kU64Tests[] = {
   1619       {"0", UINT64_C(0x0)},
   1620       {"1", UINT64_C(0x1)},
   1621       {"ffffffff", UINT64_C(0xffffffff)},
   1622       {"100000000", UINT64_C(0x100000000)},
   1623       {"ffffffffffffffff", UINT64_C(0xffffffffffffffff)},
   1624   };
   1625 
   1626   for (const auto& test : kU64Tests) {
   1627     bssl::UniquePtr<BIGNUM> bn(BN_new()), expected;
   1628     if (!bn ||
   1629         !BN_set_u64(bn.get(), test.value) ||
   1630         !HexToBIGNUM(&expected, test.hex) ||
   1631         BN_cmp(bn.get(), expected.get()) != 0) {
   1632       fprintf(stderr, "BN_set_u64 test failed for 0x%s.\n", test.hex);
   1633       ERR_print_errors_fp(stderr);
   1634       return false;
   1635     }
   1636 
   1637     uint64_t tmp;
   1638     if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
   1639       fprintf(stderr, "BN_get_u64 test failed for 0x%s.\n", test.hex);
   1640       return false;
   1641     }
   1642 
   1643     BN_set_negative(bn.get(), 1);
   1644     if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
   1645       fprintf(stderr, "BN_get_u64 test failed for -0x%s.\n", test.hex);
   1646       return false;
   1647     }
   1648   }
   1649 
   1650   // Test that BN_get_u64 fails on large numbers.
   1651   bssl::UniquePtr<BIGNUM> bn(BN_new());
   1652   if (!BN_lshift(bn.get(), BN_value_one(), 64)) {
   1653     return false;
   1654   }
   1655 
   1656   uint64_t tmp;
   1657   if (BN_get_u64(bn.get(), &tmp)) {
   1658     fprintf(stderr, "BN_get_u64 of 2^64 unexpectedly succeeded.\n");
   1659     return false;
   1660   }
   1661 
   1662   BN_set_negative(bn.get(), 1);
   1663   if (BN_get_u64(bn.get(), &tmp)) {
   1664     fprintf(stderr, "BN_get_u64 of -2^64 unexpectedly succeeded.\n");
   1665     return false;
   1666   }
   1667 
   1668   return true;
   1669 }
   1670 
   1671 static bool TestBNPow2(BN_CTX *ctx) {
   1672   bssl::UniquePtr<BIGNUM>
   1673       power_of_two(BN_new()),
   1674       random(BN_new()),
   1675       expected(BN_new()),
   1676       actual(BN_new());
   1677 
   1678   if (!power_of_two.get() ||
   1679       !random.get() ||
   1680       !expected.get() ||
   1681       !actual.get()) {
   1682     return false;
   1683   }
   1684 
   1685   // Choose an exponent.
   1686   for (size_t e = 3; e < 512; e += 11) {
   1687     // Choose a bit length for our randoms.
   1688     for (int len = 3; len < 512; len += 23) {
   1689       // Set power_of_two = 2^e.
   1690       if (!BN_lshift(power_of_two.get(), BN_value_one(), (int) e)) {
   1691         fprintf(stderr, "Failed to shiftl.\n");
   1692         return false;
   1693       }
   1694 
   1695       // Test BN_is_pow2 on power_of_two.
   1696       if (!BN_is_pow2(power_of_two.get())) {
   1697         fprintf(stderr, "BN_is_pow2 returned false for a power of two.\n");
   1698         hexdump(stderr, "Arg: ", power_of_two->d,
   1699                 power_of_two->top * sizeof(BN_ULONG));
   1700         return false;
   1701       }
   1702 
   1703       // Pick a large random value, ensuring it isn't a power of two.
   1704       if (!BN_rand(random.get(), len, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) {
   1705         fprintf(stderr, "Failed to generate random in TestBNPow2.\n");
   1706         return false;
   1707       }
   1708 
   1709       // Test BN_is_pow2 on |r|.
   1710       if (BN_is_pow2(random.get())) {
   1711         fprintf(stderr, "BN_is_pow2 returned true for a non-power of two.\n");
   1712         hexdump(stderr, "Arg: ", random->d, random->top * sizeof(BN_ULONG));
   1713         return false;
   1714       }
   1715 
   1716       // Test BN_mod_pow2 on |r|.
   1717       if (!BN_mod(expected.get(), random.get(), power_of_two.get(), ctx) ||
   1718           !BN_mod_pow2(actual.get(), random.get(), e) ||
   1719           BN_cmp(actual.get(), expected.get())) {
   1720         fprintf(stderr, "BN_mod_pow2 returned the wrong value:\n");
   1721         hexdump(stderr, "Expected: ", expected->d,
   1722                 expected->top * sizeof(BN_ULONG));
   1723         hexdump(stderr, "Got:      ", actual->d,
   1724                 actual->top * sizeof(BN_ULONG));
   1725         return false;
   1726       }
   1727 
   1728       // Test BN_nnmod_pow2 on |r|.
   1729       if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
   1730           !BN_nnmod_pow2(actual.get(), random.get(), e) ||
   1731           BN_cmp(actual.get(), expected.get())) {
   1732         fprintf(stderr, "BN_nnmod_pow2 failed on positive input:\n");
   1733         hexdump(stderr, "Expected: ", expected->d,
   1734                 expected->top * sizeof(BN_ULONG));
   1735         hexdump(stderr, "Got:      ", actual->d,
   1736                 actual->top * sizeof(BN_ULONG));
   1737         return false;
   1738       }
   1739 
   1740       // Test BN_nnmod_pow2 on -|r|.
   1741       BN_set_negative(random.get(), 1);
   1742       if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
   1743           !BN_nnmod_pow2(actual.get(), random.get(), e) ||
   1744           BN_cmp(actual.get(), expected.get())) {
   1745         fprintf(stderr, "BN_nnmod_pow2 failed on negative input:\n");
   1746         hexdump(stderr, "Expected: ", expected->d,
   1747                 expected->top * sizeof(BN_ULONG));
   1748         hexdump(stderr, "Got:      ", actual->d,
   1749                 actual->top * sizeof(BN_ULONG));
   1750         return false;
   1751       }
   1752     }
   1753   }
   1754 
   1755   return true;
   1756 }
   1757 
   1758 int main(int argc, char *argv[]) {
   1759   CRYPTO_library_init();
   1760 
   1761   if (argc != 2) {
   1762     fprintf(stderr, "%s TEST_FILE\n", argv[0]);
   1763     return 1;
   1764   }
   1765 
   1766   bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
   1767   if (!ctx) {
   1768     return 1;
   1769   }
   1770 
   1771   if (!TestBN2BinPadded(ctx.get()) ||
   1772       !TestDec2BN(ctx.get()) ||
   1773       !TestHex2BN(ctx.get()) ||
   1774       !TestASC2BN(ctx.get()) ||
   1775       !TestLittleEndian() ||
   1776       !TestMPI() ||
   1777       !TestRand() ||
   1778       !TestASN1() ||
   1779       !TestNegativeZero(ctx.get()) ||
   1780       !TestBadModulus(ctx.get()) ||
   1781       !TestExpModZero() ||
   1782       !TestSmallPrime(ctx.get()) ||
   1783       !TestCmpWord() ||
   1784       !TestBN2Dec() ||
   1785       !TestBNSetGetU64() ||
   1786       !TestBNPow2(ctx.get())) {
   1787     return 1;
   1788   }
   1789 
   1790   return FileTestMain(RunTest, ctx.get(), argv[1]);
   1791 }
   1792