ring-native 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/Gemfile +3 -0
  4. data/README.md +22 -0
  5. data/Rakefile +1 -0
  6. data/ext/ring/extconf.rb +29 -0
  7. data/lib/ring/native.rb +8 -0
  8. data/lib/ring/native/version.rb +5 -0
  9. data/ring-native.gemspec +25 -0
  10. data/vendor/ring/BUILDING.md +40 -0
  11. data/vendor/ring/Cargo.toml +43 -0
  12. data/vendor/ring/LICENSE +185 -0
  13. data/vendor/ring/Makefile +35 -0
  14. data/vendor/ring/PORTING.md +163 -0
  15. data/vendor/ring/README.md +113 -0
  16. data/vendor/ring/STYLE.md +197 -0
  17. data/vendor/ring/appveyor.yml +27 -0
  18. data/vendor/ring/build.rs +108 -0
  19. data/vendor/ring/crypto/aes/aes.c +1142 -0
  20. data/vendor/ring/crypto/aes/aes_test.Windows.vcxproj +25 -0
  21. data/vendor/ring/crypto/aes/aes_test.cc +93 -0
  22. data/vendor/ring/crypto/aes/asm/aes-586.pl +2368 -0
  23. data/vendor/ring/crypto/aes/asm/aes-armv4.pl +1249 -0
  24. data/vendor/ring/crypto/aes/asm/aes-x86_64.pl +2246 -0
  25. data/vendor/ring/crypto/aes/asm/aesni-x86.pl +1318 -0
  26. data/vendor/ring/crypto/aes/asm/aesni-x86_64.pl +2084 -0
  27. data/vendor/ring/crypto/aes/asm/aesv8-armx.pl +675 -0
  28. data/vendor/ring/crypto/aes/asm/bsaes-armv7.pl +1364 -0
  29. data/vendor/ring/crypto/aes/asm/bsaes-x86_64.pl +1565 -0
  30. data/vendor/ring/crypto/aes/asm/vpaes-x86.pl +841 -0
  31. data/vendor/ring/crypto/aes/asm/vpaes-x86_64.pl +1116 -0
  32. data/vendor/ring/crypto/aes/internal.h +87 -0
  33. data/vendor/ring/crypto/aes/mode_wrappers.c +61 -0
  34. data/vendor/ring/crypto/bn/add.c +394 -0
  35. data/vendor/ring/crypto/bn/asm/armv4-mont.pl +694 -0
  36. data/vendor/ring/crypto/bn/asm/armv8-mont.pl +1503 -0
  37. data/vendor/ring/crypto/bn/asm/bn-586.pl +774 -0
  38. data/vendor/ring/crypto/bn/asm/co-586.pl +287 -0
  39. data/vendor/ring/crypto/bn/asm/rsaz-avx2.pl +1882 -0
  40. data/vendor/ring/crypto/bn/asm/x86-mont.pl +592 -0
  41. data/vendor/ring/crypto/bn/asm/x86_64-gcc.c +599 -0
  42. data/vendor/ring/crypto/bn/asm/x86_64-mont.pl +1393 -0
  43. data/vendor/ring/crypto/bn/asm/x86_64-mont5.pl +3507 -0
  44. data/vendor/ring/crypto/bn/bn.c +352 -0
  45. data/vendor/ring/crypto/bn/bn_asn1.c +74 -0
  46. data/vendor/ring/crypto/bn/bn_test.Windows.vcxproj +25 -0
  47. data/vendor/ring/crypto/bn/bn_test.cc +1696 -0
  48. data/vendor/ring/crypto/bn/cmp.c +200 -0
  49. data/vendor/ring/crypto/bn/convert.c +433 -0
  50. data/vendor/ring/crypto/bn/ctx.c +311 -0
  51. data/vendor/ring/crypto/bn/div.c +594 -0
  52. data/vendor/ring/crypto/bn/exponentiation.c +1335 -0
  53. data/vendor/ring/crypto/bn/gcd.c +711 -0
  54. data/vendor/ring/crypto/bn/generic.c +1019 -0
  55. data/vendor/ring/crypto/bn/internal.h +316 -0
  56. data/vendor/ring/crypto/bn/montgomery.c +516 -0
  57. data/vendor/ring/crypto/bn/mul.c +888 -0
  58. data/vendor/ring/crypto/bn/prime.c +829 -0
  59. data/vendor/ring/crypto/bn/random.c +334 -0
  60. data/vendor/ring/crypto/bn/rsaz_exp.c +262 -0
  61. data/vendor/ring/crypto/bn/rsaz_exp.h +53 -0
  62. data/vendor/ring/crypto/bn/shift.c +276 -0
  63. data/vendor/ring/crypto/bytestring/bytestring_test.Windows.vcxproj +25 -0
  64. data/vendor/ring/crypto/bytestring/bytestring_test.cc +421 -0
  65. data/vendor/ring/crypto/bytestring/cbb.c +399 -0
  66. data/vendor/ring/crypto/bytestring/cbs.c +227 -0
  67. data/vendor/ring/crypto/bytestring/internal.h +46 -0
  68. data/vendor/ring/crypto/chacha/chacha_generic.c +140 -0
  69. data/vendor/ring/crypto/chacha/chacha_vec.c +323 -0
  70. data/vendor/ring/crypto/chacha/chacha_vec_arm.S +1447 -0
  71. data/vendor/ring/crypto/chacha/chacha_vec_arm_generate.go +153 -0
  72. data/vendor/ring/crypto/cipher/cipher_test.Windows.vcxproj +25 -0
  73. data/vendor/ring/crypto/cipher/e_aes.c +390 -0
  74. data/vendor/ring/crypto/cipher/e_chacha20poly1305.c +208 -0
  75. data/vendor/ring/crypto/cipher/internal.h +173 -0
  76. data/vendor/ring/crypto/cipher/test/aes_128_gcm_tests.txt +543 -0
  77. data/vendor/ring/crypto/cipher/test/aes_128_key_wrap_tests.txt +9 -0
  78. data/vendor/ring/crypto/cipher/test/aes_256_gcm_tests.txt +475 -0
  79. data/vendor/ring/crypto/cipher/test/aes_256_key_wrap_tests.txt +23 -0
  80. data/vendor/ring/crypto/cipher/test/chacha20_poly1305_old_tests.txt +422 -0
  81. data/vendor/ring/crypto/cipher/test/chacha20_poly1305_tests.txt +484 -0
  82. data/vendor/ring/crypto/cipher/test/cipher_test.txt +100 -0
  83. data/vendor/ring/crypto/constant_time_test.Windows.vcxproj +25 -0
  84. data/vendor/ring/crypto/constant_time_test.c +304 -0
  85. data/vendor/ring/crypto/cpu-arm-asm.S +32 -0
  86. data/vendor/ring/crypto/cpu-arm.c +199 -0
  87. data/vendor/ring/crypto/cpu-intel.c +261 -0
  88. data/vendor/ring/crypto/crypto.c +151 -0
  89. data/vendor/ring/crypto/curve25519/asm/x25519-arm.S +2118 -0
  90. data/vendor/ring/crypto/curve25519/curve25519.c +4888 -0
  91. data/vendor/ring/crypto/curve25519/x25519_test.cc +128 -0
  92. data/vendor/ring/crypto/digest/md32_common.h +181 -0
  93. data/vendor/ring/crypto/ec/asm/p256-x86_64-asm.pl +2725 -0
  94. data/vendor/ring/crypto/ec/ec.c +193 -0
  95. data/vendor/ring/crypto/ec/ec_curves.c +61 -0
  96. data/vendor/ring/crypto/ec/ec_key.c +228 -0
  97. data/vendor/ring/crypto/ec/ec_montgomery.c +114 -0
  98. data/vendor/ring/crypto/ec/example_mul.Windows.vcxproj +25 -0
  99. data/vendor/ring/crypto/ec/internal.h +243 -0
  100. data/vendor/ring/crypto/ec/oct.c +253 -0
  101. data/vendor/ring/crypto/ec/p256-64.c +1794 -0
  102. data/vendor/ring/crypto/ec/p256-x86_64-table.h +9548 -0
  103. data/vendor/ring/crypto/ec/p256-x86_64.c +509 -0
  104. data/vendor/ring/crypto/ec/simple.c +1007 -0
  105. data/vendor/ring/crypto/ec/util-64.c +183 -0
  106. data/vendor/ring/crypto/ec/wnaf.c +508 -0
  107. data/vendor/ring/crypto/ecdh/ecdh.c +155 -0
  108. data/vendor/ring/crypto/ecdsa/ecdsa.c +304 -0
  109. data/vendor/ring/crypto/ecdsa/ecdsa_asn1.c +193 -0
  110. data/vendor/ring/crypto/ecdsa/ecdsa_test.Windows.vcxproj +25 -0
  111. data/vendor/ring/crypto/ecdsa/ecdsa_test.cc +327 -0
  112. data/vendor/ring/crypto/header_removed.h +17 -0
  113. data/vendor/ring/crypto/internal.h +495 -0
  114. data/vendor/ring/crypto/libring.Windows.vcxproj +101 -0
  115. data/vendor/ring/crypto/mem.c +98 -0
  116. data/vendor/ring/crypto/modes/asm/aesni-gcm-x86_64.pl +1045 -0
  117. data/vendor/ring/crypto/modes/asm/ghash-armv4.pl +517 -0
  118. data/vendor/ring/crypto/modes/asm/ghash-x86.pl +1393 -0
  119. data/vendor/ring/crypto/modes/asm/ghash-x86_64.pl +1741 -0
  120. data/vendor/ring/crypto/modes/asm/ghashv8-armx.pl +422 -0
  121. data/vendor/ring/crypto/modes/ctr.c +226 -0
  122. data/vendor/ring/crypto/modes/gcm.c +1206 -0
  123. data/vendor/ring/crypto/modes/gcm_test.Windows.vcxproj +25 -0
  124. data/vendor/ring/crypto/modes/gcm_test.c +348 -0
  125. data/vendor/ring/crypto/modes/internal.h +299 -0
  126. data/vendor/ring/crypto/perlasm/arm-xlate.pl +170 -0
  127. data/vendor/ring/crypto/perlasm/readme +100 -0
  128. data/vendor/ring/crypto/perlasm/x86_64-xlate.pl +1164 -0
  129. data/vendor/ring/crypto/perlasm/x86asm.pl +292 -0
  130. data/vendor/ring/crypto/perlasm/x86gas.pl +263 -0
  131. data/vendor/ring/crypto/perlasm/x86masm.pl +200 -0
  132. data/vendor/ring/crypto/perlasm/x86nasm.pl +187 -0
  133. data/vendor/ring/crypto/poly1305/poly1305.c +331 -0
  134. data/vendor/ring/crypto/poly1305/poly1305_arm.c +301 -0
  135. data/vendor/ring/crypto/poly1305/poly1305_arm_asm.S +2015 -0
  136. data/vendor/ring/crypto/poly1305/poly1305_test.Windows.vcxproj +25 -0
  137. data/vendor/ring/crypto/poly1305/poly1305_test.cc +80 -0
  138. data/vendor/ring/crypto/poly1305/poly1305_test.txt +52 -0
  139. data/vendor/ring/crypto/poly1305/poly1305_vec.c +892 -0
  140. data/vendor/ring/crypto/rand/asm/rdrand-x86_64.pl +75 -0
  141. data/vendor/ring/crypto/rand/internal.h +32 -0
  142. data/vendor/ring/crypto/rand/rand.c +189 -0
  143. data/vendor/ring/crypto/rand/urandom.c +219 -0
  144. data/vendor/ring/crypto/rand/windows.c +56 -0
  145. data/vendor/ring/crypto/refcount_c11.c +66 -0
  146. data/vendor/ring/crypto/refcount_lock.c +53 -0
  147. data/vendor/ring/crypto/refcount_test.Windows.vcxproj +25 -0
  148. data/vendor/ring/crypto/refcount_test.c +58 -0
  149. data/vendor/ring/crypto/rsa/blinding.c +462 -0
  150. data/vendor/ring/crypto/rsa/internal.h +108 -0
  151. data/vendor/ring/crypto/rsa/padding.c +300 -0
  152. data/vendor/ring/crypto/rsa/rsa.c +450 -0
  153. data/vendor/ring/crypto/rsa/rsa_asn1.c +261 -0
  154. data/vendor/ring/crypto/rsa/rsa_impl.c +944 -0
  155. data/vendor/ring/crypto/rsa/rsa_test.Windows.vcxproj +25 -0
  156. data/vendor/ring/crypto/rsa/rsa_test.cc +437 -0
  157. data/vendor/ring/crypto/sha/asm/sha-armv8.pl +436 -0
  158. data/vendor/ring/crypto/sha/asm/sha-x86_64.pl +2390 -0
  159. data/vendor/ring/crypto/sha/asm/sha256-586.pl +1275 -0
  160. data/vendor/ring/crypto/sha/asm/sha256-armv4.pl +735 -0
  161. data/vendor/ring/crypto/sha/asm/sha256-armv8.pl +14 -0
  162. data/vendor/ring/crypto/sha/asm/sha256-x86_64.pl +14 -0
  163. data/vendor/ring/crypto/sha/asm/sha512-586.pl +911 -0
  164. data/vendor/ring/crypto/sha/asm/sha512-armv4.pl +666 -0
  165. data/vendor/ring/crypto/sha/asm/sha512-armv8.pl +14 -0
  166. data/vendor/ring/crypto/sha/asm/sha512-x86_64.pl +14 -0
  167. data/vendor/ring/crypto/sha/sha1.c +271 -0
  168. data/vendor/ring/crypto/sha/sha256.c +204 -0
  169. data/vendor/ring/crypto/sha/sha512.c +355 -0
  170. data/vendor/ring/crypto/test/file_test.cc +326 -0
  171. data/vendor/ring/crypto/test/file_test.h +181 -0
  172. data/vendor/ring/crypto/test/malloc.cc +150 -0
  173. data/vendor/ring/crypto/test/scoped_types.h +95 -0
  174. data/vendor/ring/crypto/test/test.Windows.vcxproj +35 -0
  175. data/vendor/ring/crypto/test/test_util.cc +46 -0
  176. data/vendor/ring/crypto/test/test_util.h +41 -0
  177. data/vendor/ring/crypto/thread_none.c +55 -0
  178. data/vendor/ring/crypto/thread_pthread.c +165 -0
  179. data/vendor/ring/crypto/thread_test.Windows.vcxproj +25 -0
  180. data/vendor/ring/crypto/thread_test.c +200 -0
  181. data/vendor/ring/crypto/thread_win.c +282 -0
  182. data/vendor/ring/examples/checkdigest.rs +103 -0
  183. data/vendor/ring/include/openssl/aes.h +121 -0
  184. data/vendor/ring/include/openssl/arm_arch.h +129 -0
  185. data/vendor/ring/include/openssl/base.h +156 -0
  186. data/vendor/ring/include/openssl/bn.h +794 -0
  187. data/vendor/ring/include/openssl/buffer.h +18 -0
  188. data/vendor/ring/include/openssl/bytestring.h +235 -0
  189. data/vendor/ring/include/openssl/chacha.h +37 -0
  190. data/vendor/ring/include/openssl/cmac.h +76 -0
  191. data/vendor/ring/include/openssl/cpu.h +184 -0
  192. data/vendor/ring/include/openssl/crypto.h +43 -0
  193. data/vendor/ring/include/openssl/curve25519.h +88 -0
  194. data/vendor/ring/include/openssl/ec.h +225 -0
  195. data/vendor/ring/include/openssl/ec_key.h +129 -0
  196. data/vendor/ring/include/openssl/ecdh.h +110 -0
  197. data/vendor/ring/include/openssl/ecdsa.h +156 -0
  198. data/vendor/ring/include/openssl/err.h +201 -0
  199. data/vendor/ring/include/openssl/mem.h +101 -0
  200. data/vendor/ring/include/openssl/obj_mac.h +71 -0
  201. data/vendor/ring/include/openssl/opensslfeatures.h +68 -0
  202. data/vendor/ring/include/openssl/opensslv.h +18 -0
  203. data/vendor/ring/include/openssl/ossl_typ.h +18 -0
  204. data/vendor/ring/include/openssl/poly1305.h +51 -0
  205. data/vendor/ring/include/openssl/rand.h +70 -0
  206. data/vendor/ring/include/openssl/rsa.h +399 -0
  207. data/vendor/ring/include/openssl/thread.h +133 -0
  208. data/vendor/ring/include/openssl/type_check.h +71 -0
  209. data/vendor/ring/mk/Common.props +63 -0
  210. data/vendor/ring/mk/Windows.props +42 -0
  211. data/vendor/ring/mk/WindowsTest.props +18 -0
  212. data/vendor/ring/mk/appveyor.bat +62 -0
  213. data/vendor/ring/mk/bottom_of_makefile.mk +54 -0
  214. data/vendor/ring/mk/ring.mk +266 -0
  215. data/vendor/ring/mk/top_of_makefile.mk +214 -0
  216. data/vendor/ring/mk/travis.sh +40 -0
  217. data/vendor/ring/mk/update-travis-yml.py +229 -0
  218. data/vendor/ring/ring.sln +153 -0
  219. data/vendor/ring/src/aead.rs +682 -0
  220. data/vendor/ring/src/agreement.rs +248 -0
  221. data/vendor/ring/src/c.rs +129 -0
  222. data/vendor/ring/src/constant_time.rs +37 -0
  223. data/vendor/ring/src/der.rs +96 -0
  224. data/vendor/ring/src/digest.rs +690 -0
  225. data/vendor/ring/src/digest_tests.txt +57 -0
  226. data/vendor/ring/src/ecc.rs +28 -0
  227. data/vendor/ring/src/ecc_build.rs +279 -0
  228. data/vendor/ring/src/ecc_curves.rs +117 -0
  229. data/vendor/ring/src/ed25519_tests.txt +2579 -0
  230. data/vendor/ring/src/exe_tests.rs +46 -0
  231. data/vendor/ring/src/ffi.rs +29 -0
  232. data/vendor/ring/src/file_test.rs +187 -0
  233. data/vendor/ring/src/hkdf.rs +153 -0
  234. data/vendor/ring/src/hkdf_tests.txt +59 -0
  235. data/vendor/ring/src/hmac.rs +414 -0
  236. data/vendor/ring/src/hmac_tests.txt +97 -0
  237. data/vendor/ring/src/input.rs +312 -0
  238. data/vendor/ring/src/lib.rs +41 -0
  239. data/vendor/ring/src/pbkdf2.rs +265 -0
  240. data/vendor/ring/src/pbkdf2_tests.txt +113 -0
  241. data/vendor/ring/src/polyfill.rs +57 -0
  242. data/vendor/ring/src/rand.rs +28 -0
  243. data/vendor/ring/src/signature.rs +314 -0
  244. data/vendor/ring/third-party/NIST/README.md +9 -0
  245. data/vendor/ring/third-party/NIST/SHAVS/SHA1LongMsg.rsp +263 -0
  246. data/vendor/ring/third-party/NIST/SHAVS/SHA1Monte.rsp +309 -0
  247. data/vendor/ring/third-party/NIST/SHAVS/SHA1ShortMsg.rsp +267 -0
  248. data/vendor/ring/third-party/NIST/SHAVS/SHA224LongMsg.rsp +263 -0
  249. data/vendor/ring/third-party/NIST/SHAVS/SHA224Monte.rsp +309 -0
  250. data/vendor/ring/third-party/NIST/SHAVS/SHA224ShortMsg.rsp +267 -0
  251. data/vendor/ring/third-party/NIST/SHAVS/SHA256LongMsg.rsp +263 -0
  252. data/vendor/ring/third-party/NIST/SHAVS/SHA256Monte.rsp +309 -0
  253. data/vendor/ring/third-party/NIST/SHAVS/SHA256ShortMsg.rsp +267 -0
  254. data/vendor/ring/third-party/NIST/SHAVS/SHA384LongMsg.rsp +519 -0
  255. data/vendor/ring/third-party/NIST/SHAVS/SHA384Monte.rsp +309 -0
  256. data/vendor/ring/third-party/NIST/SHAVS/SHA384ShortMsg.rsp +523 -0
  257. data/vendor/ring/third-party/NIST/SHAVS/SHA512LongMsg.rsp +519 -0
  258. data/vendor/ring/third-party/NIST/SHAVS/SHA512Monte.rsp +309 -0
  259. data/vendor/ring/third-party/NIST/SHAVS/SHA512ShortMsg.rsp +523 -0
  260. data/vendor/ring/third-party/NIST/sha256sums.txt +1 -0
  261. metadata +333 -0
@@ -0,0 +1,1696 @@
1
+ /* 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
+
70
+ /* For BIGNUM format macros. */
71
+ #if !defined(__STDC_FORMAT_MACROS)
72
+ #define __STDC_FORMAT_MACROS
73
+ #endif
74
+
75
+ #include <errno.h>
76
+ #include <stdio.h>
77
+ #include <string.h>
78
+
79
+ #include <utility>
80
+
81
+ #include <openssl/bn.h>
82
+ #include <openssl/bytestring.h>
83
+ #include <openssl/crypto.h>
84
+ #include <openssl/err.h>
85
+ #include <openssl/mem.h>
86
+
87
+ #include "../crypto/test/scoped_types.h"
88
+
89
+
90
+ // This program tests the BIGNUM implementation. It takes an optional -bc
91
+ // argument to write a transcript compatible with the UNIX bc utility.
92
+ //
93
+ // TODO(davidben): Rather than generate random inputs and depend on bc to check
94
+ // the results, most of these tests should use known answers.
95
+
96
+ static const int num0 = 100; // number of tests
97
+ static const int num1 = 50; // additional tests for some functions
98
+ static const int num2 = 5; // number of tests for slow functions
99
+
100
+ static bool test_add(FILE *fp);
101
+ static bool test_sub(FILE *fp);
102
+ static bool test_lshift1(FILE *fp);
103
+ static bool test_lshift(FILE *fp, BN_CTX *ctx, ScopedBIGNUM a);
104
+ static bool test_rshift1(FILE *fp);
105
+ static bool test_rshift(FILE *fp, BN_CTX *ctx);
106
+ static bool test_sqr(FILE *fp, BN_CTX *ctx);
107
+ static bool test_mul(FILE *fp);
108
+ static bool test_div(FILE *fp, BN_CTX *ctx);
109
+ static int rand_neg();
110
+
111
+ static bool test_div_word(FILE *fp);
112
+ static bool test_mont(FILE *fp, BN_CTX *ctx);
113
+ static bool test_mod(FILE *fp, BN_CTX *ctx);
114
+ static bool test_mod_mul(FILE *fp, BN_CTX *ctx);
115
+ static bool test_mod_exp(FILE *fp, BN_CTX *ctx);
116
+ static bool test_mod_exp_mont_consttime(FILE *fp, BN_CTX *ctx);
117
+ static bool test_exp(FILE *fp, BN_CTX *ctx);
118
+ static bool test_exp_mod_zero(void);
119
+ static bool test_small_prime(FILE *fp, BN_CTX *ctx);
120
+ static bool test_mod_exp_mont5(FILE *fp, BN_CTX *ctx);
121
+ static bool test_bn2bin_padded(BN_CTX *ctx);
122
+ static bool test_dec2bn(BN_CTX *ctx);
123
+ static bool test_hex2bn(BN_CTX *ctx);
124
+ static bool test_asc2bn(BN_CTX *ctx);
125
+ static bool test_rand();
126
+ static bool test_asn1();
127
+
128
+ static const uint8_t kSample[] =
129
+ "\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
130
+ "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
131
+
132
+ // A wrapper around puts that takes its arguments in the same order as our *_fp
133
+ // functions.
134
+ static void puts_fp(FILE *out, const char *m) {
135
+ if (out != nullptr) {
136
+ fputs(m, out);
137
+ }
138
+ }
139
+
140
+ static void flush_fp(FILE *out) {
141
+ if (out != nullptr) {
142
+ fflush(out);
143
+ }
144
+ }
145
+
146
+ static void message(FILE *out, const char *m) {
147
+ puts_fp(out, "print \"test ");
148
+ puts_fp(out, m);
149
+ puts_fp(out, "\\n\"\n");
150
+ }
151
+
152
+ int main(int argc, char *argv[]) {
153
+ CRYPTO_library_init();
154
+
155
+ ScopedFILE bc_file;
156
+ argc--;
157
+ argv++;
158
+ while (argc >= 1) {
159
+ if (strcmp(*argv, "-bc") == 0) {
160
+ if (argc < 2) {
161
+ fprintf(stderr, "Missing parameter to -bc\n");
162
+ return 1;
163
+ }
164
+ bc_file.reset(fopen(argv[1], "w+"));
165
+ if (!bc_file) {
166
+ fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno));
167
+ }
168
+ argc--;
169
+ argv++;
170
+ } else {
171
+ fprintf(stderr, "Unknown option: %s\n", argv[0]);
172
+ return 1;
173
+ }
174
+ argc--;
175
+ argv++;
176
+ }
177
+
178
+
179
+ ScopedBN_CTX ctx(BN_CTX_new());
180
+ if (!ctx) {
181
+ return 1;
182
+ }
183
+
184
+ puts_fp(bc_file.get(), "/* This script, when run through the UNIX bc utility, "
185
+ "should produce a sequence of zeros. */\n");
186
+ puts_fp(bc_file.get(), "/* tr a-f A-F < bn_test.out | sed s/BAsE/base/ | bc "
187
+ "| grep -v 0 */\n");
188
+ puts_fp(bc_file.get(), "obase=16\nibase=16\n");
189
+
190
+ message(bc_file.get(), "BN_add");
191
+ if (!test_add(bc_file.get())) {
192
+ return 1;
193
+ }
194
+ flush_fp(bc_file.get());
195
+
196
+ message(bc_file.get(), "BN_sub");
197
+ if (!test_sub(bc_file.get())) {
198
+ return 1;
199
+ }
200
+ flush_fp(bc_file.get());
201
+
202
+ message(bc_file.get(), "BN_lshift1");
203
+ if (!test_lshift1(bc_file.get())) {
204
+ return 1;
205
+ }
206
+ flush_fp(bc_file.get());
207
+
208
+ message(bc_file.get(), "BN_lshift (fixed)");
209
+ ScopedBIGNUM sample(BN_bin2bn(kSample, sizeof(kSample) - 1, NULL));
210
+ if (!sample) {
211
+ return 1;
212
+ }
213
+ if (!test_lshift(bc_file.get(), ctx.get(), std::move(sample))) {
214
+ return 1;
215
+ }
216
+ flush_fp(bc_file.get());
217
+
218
+ message(bc_file.get(), "BN_lshift");
219
+ if (!test_lshift(bc_file.get(), ctx.get(), nullptr)) {
220
+ return 1;
221
+ }
222
+ flush_fp(bc_file.get());
223
+
224
+ message(bc_file.get(), "BN_rshift1");
225
+ if (!test_rshift1(bc_file.get())) {
226
+ return 1;
227
+ }
228
+ flush_fp(bc_file.get());
229
+
230
+ message(bc_file.get(), "BN_rshift");
231
+ if (!test_rshift(bc_file.get(), ctx.get())) {
232
+ return 1;
233
+ }
234
+ flush_fp(bc_file.get());
235
+
236
+ message(bc_file.get(), "BN_sqr");
237
+ if (!test_sqr(bc_file.get(), ctx.get())) {
238
+ return 1;
239
+ }
240
+ flush_fp(bc_file.get());
241
+
242
+ message(bc_file.get(), "BN_mul");
243
+ if (!test_mul(bc_file.get())) {
244
+ return 1;
245
+ }
246
+ flush_fp(bc_file.get());
247
+
248
+ message(bc_file.get(), "BN_div");
249
+ if (!test_div(bc_file.get(), ctx.get())) {
250
+ return 1;
251
+ }
252
+ flush_fp(bc_file.get());
253
+
254
+ message(bc_file.get(), "BN_div_word");
255
+ if (!test_div_word(bc_file.get())) {
256
+ return 1;
257
+ }
258
+ flush_fp(bc_file.get());
259
+
260
+ message(bc_file.get(), "BN_mod");
261
+ if (!test_mod(bc_file.get(), ctx.get())) {
262
+ return 1;
263
+ }
264
+ flush_fp(bc_file.get());
265
+
266
+ message(bc_file.get(), "BN_mod_mul");
267
+ if (!test_mod_mul(bc_file.get(), ctx.get())) {
268
+ return 1;
269
+ }
270
+ flush_fp(bc_file.get());
271
+
272
+ message(bc_file.get(), "BN_mont");
273
+ if (!test_mont(bc_file.get(), ctx.get())) {
274
+ return 1;
275
+ }
276
+ flush_fp(bc_file.get());
277
+
278
+ message(bc_file.get(), "BN_mod_exp");
279
+ if (!test_mod_exp(bc_file.get(), ctx.get())) {
280
+ return 1;
281
+ }
282
+ flush_fp(bc_file.get());
283
+
284
+ message(bc_file.get(), "BN_mod_exp_mont_consttime");
285
+ if (!test_mod_exp_mont_consttime(bc_file.get(), ctx.get()) ||
286
+ !test_mod_exp_mont5(bc_file.get(), ctx.get())) {
287
+ return 1;
288
+ }
289
+ flush_fp(bc_file.get());
290
+
291
+ message(bc_file.get(), "BN_exp");
292
+ if (!test_exp(bc_file.get(), ctx.get()) ||
293
+ !test_exp_mod_zero()) {
294
+ return 1;
295
+ }
296
+ flush_fp(bc_file.get());
297
+
298
+ message(bc_file.get(), "Small prime generation");
299
+ if (!test_small_prime(bc_file.get(), ctx.get())) {
300
+ return 1;
301
+ }
302
+ flush_fp(bc_file.get());
303
+
304
+ if (!test_bn2bin_padded(ctx.get()) ||
305
+ !test_dec2bn(ctx.get()) ||
306
+ !test_hex2bn(ctx.get()) ||
307
+ !test_asc2bn(ctx.get()) ||
308
+ !test_rand() ||
309
+ !test_asn1()) {
310
+ return 1;
311
+ }
312
+
313
+ return 0;
314
+ }
315
+
316
+ static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
317
+ BIGNUM *raw = NULL;
318
+ int ret = BN_hex2bn(&raw, in);
319
+ out->reset(raw);
320
+ return ret;
321
+ }
322
+
323
+ static bool test_add(FILE *fp) {
324
+ ScopedBIGNUM a(BN_new());
325
+ ScopedBIGNUM b(BN_new());
326
+ ScopedBIGNUM c(BN_new());
327
+ if (!a || !b || !c || !BN_rand(a.get(), 512, 0, 0)) {
328
+ return false;
329
+ }
330
+
331
+ for (int i = 0; i < num0; i++) {
332
+ if (!BN_rand(b.get(), 450 + i, 0, 0)) {
333
+ return false;
334
+ }
335
+ a->neg = rand_neg();
336
+ b->neg = rand_neg();
337
+ if (!BN_add(c.get(), a.get(), b.get())) {
338
+ return false;
339
+ }
340
+ if (fp != NULL) {
341
+ BN_print_fp(fp, a.get());
342
+ puts_fp(fp, " + ");
343
+ BN_print_fp(fp, b.get());
344
+ puts_fp(fp, " - ");
345
+ BN_print_fp(fp, c.get());
346
+ puts_fp(fp, "\n");
347
+ }
348
+ a->neg = !a->neg;
349
+ b->neg = !b->neg;
350
+ if (!BN_add(c.get(), c.get(), b.get()) ||
351
+ !BN_add(c.get(), c.get(), a.get())) {
352
+ return false;
353
+ }
354
+ if (!BN_is_zero(c.get())) {
355
+ fprintf(stderr, "Add test failed!\n");
356
+ return false;
357
+ }
358
+ }
359
+ return true;
360
+ }
361
+
362
+ static bool test_sub(FILE *fp) {
363
+ ScopedBIGNUM a(BN_new());
364
+ ScopedBIGNUM b(BN_new());
365
+ ScopedBIGNUM c(BN_new());
366
+ if (!a || !b || !c) {
367
+ return false;
368
+ }
369
+
370
+ for (int i = 0; i < num0 + num1; i++) {
371
+ if (i < num1) {
372
+ if (!BN_rand(a.get(), 512, 0, 0) ||
373
+ !BN_copy(b.get(), a.get()) ||
374
+ !BN_set_bit(a.get(), i) ||
375
+ !BN_add_word(b.get(), i)) {
376
+ return false;
377
+ }
378
+ } else {
379
+ if (!BN_rand(b.get(), 400 + i - num1, 0, 0)) {
380
+ return false;
381
+ }
382
+ a->neg = rand_neg();
383
+ b->neg = rand_neg();
384
+ }
385
+ if (!BN_sub(c.get(), a.get(), b.get())) {
386
+ return false;
387
+ }
388
+ if (fp != NULL) {
389
+ BN_print_fp(fp, a.get());
390
+ puts_fp(fp, " - ");
391
+ BN_print_fp(fp, b.get());
392
+ puts_fp(fp, " - ");
393
+ BN_print_fp(fp, c.get());
394
+ puts_fp(fp, "\n");
395
+ }
396
+ if (!BN_add(c.get(), c.get(), b.get()) ||
397
+ !BN_sub(c.get(), c.get(), a.get())) {
398
+ return false;
399
+ }
400
+ if (!BN_is_zero(c.get())) {
401
+ fprintf(stderr, "Subtract test failed!\n");
402
+ return false;
403
+ }
404
+ }
405
+ return true;
406
+ }
407
+
408
+ static bool test_div(FILE *fp, BN_CTX *ctx) {
409
+ ScopedBIGNUM a(BN_new());
410
+ ScopedBIGNUM b(BN_new());
411
+ ScopedBIGNUM c(BN_new());
412
+ ScopedBIGNUM d(BN_new());
413
+ ScopedBIGNUM e(BN_new());
414
+ if (!a || !b || !c || !d || !e) {
415
+ return false;
416
+ }
417
+
418
+ if (!BN_one(a.get())) {
419
+ return false;
420
+ }
421
+ BN_zero(b.get());
422
+ if (BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
423
+ fprintf(stderr, "Division by zero succeeded!\n");
424
+ return false;
425
+ }
426
+ ERR_clear_error();
427
+
428
+ for (int i = 0; i < num0 + num1; i++) {
429
+ if (i < num1) {
430
+ if (!BN_rand(a.get(), 400, 0, 0) ||
431
+ !BN_copy(b.get(), a.get()) ||
432
+ !BN_lshift(a.get(), a.get(), i) ||
433
+ !BN_add_word(a.get(), i)) {
434
+ return false;
435
+ }
436
+ } else if (!BN_rand(b.get(), 50 + 3 * (i - num1), 0, 0)) {
437
+ return false;
438
+ }
439
+ a->neg = rand_neg();
440
+ b->neg = rand_neg();
441
+ if (!BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
442
+ return false;
443
+ }
444
+ if (fp != NULL) {
445
+ BN_print_fp(fp, a.get());
446
+ puts_fp(fp, " / ");
447
+ BN_print_fp(fp, b.get());
448
+ puts_fp(fp, " - ");
449
+ BN_print_fp(fp, d.get());
450
+ puts_fp(fp, "\n");
451
+
452
+ BN_print_fp(fp, a.get());
453
+ puts_fp(fp, " % ");
454
+ BN_print_fp(fp, b.get());
455
+ puts_fp(fp, " - ");
456
+ BN_print_fp(fp, c.get());
457
+ puts_fp(fp, "\n");
458
+ }
459
+ if (!BN_mul(e.get(), d.get(), b.get(), ctx) ||
460
+ !BN_add(d.get(), e.get(), c.get()) ||
461
+ !BN_sub(d.get(), d.get(), a.get())) {
462
+ return false;
463
+ }
464
+ if (!BN_is_zero(d.get())) {
465
+ fprintf(stderr, "Division test failed!\n");
466
+ return false;
467
+ }
468
+ }
469
+
470
+ // Test that BN_div never gives negative zero in the quotient.
471
+ if (!BN_set_word(a.get(), 1) ||
472
+ !BN_set_word(b.get(), 2)) {
473
+ return false;
474
+ }
475
+ BN_set_negative(a.get(), 1);
476
+ if (!BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
477
+ return false;
478
+ }
479
+ if (!BN_is_zero(d.get()) || BN_is_negative(d.get())) {
480
+ fprintf(stderr, "Division test failed!\n");
481
+ return false;
482
+ }
483
+
484
+ // Test that BN_div never gives negative zero in the remainder.
485
+ if (!BN_set_word(b.get(), 1)) {
486
+ return false;
487
+ }
488
+ if (!BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
489
+ return false;
490
+ }
491
+ if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
492
+ fprintf(stderr, "Division test failed!\n");
493
+ return false;
494
+ }
495
+
496
+ return true;
497
+ }
498
+
499
+ static bool test_lshift1(FILE *fp) {
500
+ ScopedBIGNUM a(BN_new());
501
+ ScopedBIGNUM b(BN_new());
502
+ ScopedBIGNUM c(BN_new());
503
+ if (!a || !b || !c || !BN_rand(a.get(), 200, 0, 0)) {
504
+ return false;
505
+ }
506
+ a->neg = rand_neg();
507
+ for (int i = 0; i < num0; i++) {
508
+ if (!BN_lshift1(b.get(), a.get())) {
509
+ return false;
510
+ }
511
+ if (fp != NULL) {
512
+ BN_print_fp(fp, a.get());
513
+ puts_fp(fp, " * 2");
514
+ puts_fp(fp, " - ");
515
+ BN_print_fp(fp, b.get());
516
+ puts_fp(fp, "\n");
517
+ }
518
+ if (!BN_add(c.get(), a.get(), a.get()) ||
519
+ !BN_sub(a.get(), b.get(), c.get())) {
520
+ return false;
521
+ }
522
+ if (!BN_is_zero(a.get())) {
523
+ fprintf(stderr, "Left shift one test failed!\n");
524
+ return false;
525
+ }
526
+
527
+ if (!BN_copy(a.get(), b.get())) {
528
+ return false;
529
+ }
530
+ }
531
+ return true;
532
+ }
533
+
534
+ static bool test_rshift(FILE *fp, BN_CTX *ctx) {
535
+ ScopedBIGNUM a(BN_new());
536
+ ScopedBIGNUM b(BN_new());
537
+ ScopedBIGNUM c(BN_new());
538
+ ScopedBIGNUM d(BN_new());
539
+ ScopedBIGNUM e(BN_new());
540
+ if (!a || !b || !c || !d || !e || !BN_one(c.get()) ||
541
+ !BN_rand(a.get(), 200, 0, 0)) {
542
+ return false;
543
+ }
544
+ a->neg = rand_neg();
545
+ for (int i = 0; i < num0; i++) {
546
+ if (!BN_rshift(b.get(), a.get(), i + 1) ||
547
+ !BN_add(c.get(), c.get(), c.get())) {
548
+ return false;
549
+ }
550
+ if (fp != NULL) {
551
+ BN_print_fp(fp, a.get());
552
+ puts_fp(fp, " / ");
553
+ BN_print_fp(fp, c.get());
554
+ puts_fp(fp, " - ");
555
+ BN_print_fp(fp, b.get());
556
+ puts_fp(fp, "\n");
557
+ }
558
+ if (!BN_div(d.get(), e.get(), a.get(), c.get(), ctx) ||
559
+ !BN_sub(d.get(), d.get(), b.get())) {
560
+ return false;
561
+ }
562
+ if (!BN_is_zero(d.get())) {
563
+ fprintf(stderr, "Right shift test failed!\n");
564
+ return false;
565
+ }
566
+ }
567
+ return true;
568
+ }
569
+
570
+ static bool test_rshift1(FILE *fp) {
571
+ ScopedBIGNUM a(BN_new());
572
+ ScopedBIGNUM b(BN_new());
573
+ ScopedBIGNUM c(BN_new());
574
+ if (!a || !b || !c || !BN_rand(a.get(), 200, 0, 0)) {
575
+ return false;
576
+ }
577
+ a->neg = rand_neg();
578
+
579
+ for (int i = 0; i < num0; i++) {
580
+ if (!BN_rshift1(b.get(), a.get())) {
581
+ return false;
582
+ }
583
+ if (fp != NULL) {
584
+ BN_print_fp(fp, a.get());
585
+ puts_fp(fp, " / 2");
586
+ puts_fp(fp, " - ");
587
+ BN_print_fp(fp, b.get());
588
+ puts_fp(fp, "\n");
589
+ }
590
+ if (!BN_sub(c.get(), a.get(), b.get()) ||
591
+ !BN_sub(c.get(), c.get(), b.get())) {
592
+ return false;
593
+ }
594
+ if (!BN_is_zero(c.get()) && !BN_abs_is_word(c.get(), 1)) {
595
+ fprintf(stderr, "Right shift one test failed!\n");
596
+ return false;
597
+ }
598
+ if (!BN_copy(a.get(), b.get())) {
599
+ return false;
600
+ }
601
+ }
602
+ return true;
603
+ }
604
+
605
+ static bool test_lshift(FILE *fp, BN_CTX *ctx, ScopedBIGNUM a) {
606
+ if (!a) {
607
+ a.reset(BN_new());
608
+ if (!a || !BN_rand(a.get(), 200, 0, 0)) {
609
+ return false;
610
+ }
611
+ a->neg = rand_neg();
612
+ }
613
+
614
+ ScopedBIGNUM b(BN_new());
615
+ ScopedBIGNUM c(BN_new());
616
+ ScopedBIGNUM d(BN_new());
617
+ if (!b || !c || !d || !BN_one(c.get())) {
618
+ return false;
619
+ }
620
+
621
+ for (int i = 0; i < num0; i++) {
622
+ if (!BN_lshift(b.get(), a.get(), i + 1) ||
623
+ !BN_add(c.get(), c.get(), c.get())) {
624
+ return false;
625
+ }
626
+ if (fp != NULL) {
627
+ BN_print_fp(fp, a.get());
628
+ puts_fp(fp, " * ");
629
+ BN_print_fp(fp, c.get());
630
+ puts_fp(fp, " - ");
631
+ BN_print_fp(fp, b.get());
632
+ puts_fp(fp, "\n");
633
+ }
634
+ if (!BN_mul(d.get(), a.get(), c.get(), ctx) ||
635
+ !BN_sub(d.get(), d.get(), b.get())) {
636
+ return false;
637
+ }
638
+ if (!BN_is_zero(d.get())) {
639
+ fprintf(stderr, "Left shift test failed!\n");
640
+ fprintf(stderr, "a=");
641
+ BN_print_fp(stderr, a.get());
642
+ fprintf(stderr, "\nb=");
643
+ BN_print_fp(stderr, b.get());
644
+ fprintf(stderr, "\nc=");
645
+ BN_print_fp(stderr, c.get());
646
+ fprintf(stderr, "\nd=");
647
+ BN_print_fp(stderr, d.get());
648
+ fprintf(stderr, "\n");
649
+ return false;
650
+ }
651
+ }
652
+ return true;
653
+ }
654
+
655
+ static bool test_mul(FILE *fp) {
656
+ ScopedBN_CTX ctx(BN_CTX_new());
657
+ ScopedBIGNUM a(BN_new());
658
+ ScopedBIGNUM b(BN_new());
659
+ ScopedBIGNUM c(BN_new());
660
+ ScopedBIGNUM d(BN_new());
661
+ ScopedBIGNUM e(BN_new());
662
+ if (!ctx || !a || !b || !c || !d || !e) {
663
+ return false;
664
+ }
665
+
666
+ for (int i = 0; i < num0 + num1; i++) {
667
+ if (i <= num1) {
668
+ if (!BN_rand(a.get(), 100, 0, 0) ||
669
+ !BN_rand(b.get(), 100, 0, 0)) {
670
+ return false;
671
+ }
672
+ } else if (!BN_rand(b.get(), i - num1, 0, 0)) {
673
+ return false;
674
+ }
675
+ a->neg = rand_neg();
676
+ b->neg = rand_neg();
677
+ if (!BN_mul(c.get(), a.get(), b.get(), ctx.get())) {
678
+ return false;
679
+ }
680
+ if (fp != NULL) {
681
+ BN_print_fp(fp, a.get());
682
+ puts_fp(fp, " * ");
683
+ BN_print_fp(fp, b.get());
684
+ puts_fp(fp, " - ");
685
+ BN_print_fp(fp, c.get());
686
+ puts_fp(fp, "\n");
687
+ }
688
+ if (!BN_div(d.get(), e.get(), c.get(), a.get(), ctx.get()) ||
689
+ !BN_sub(d.get(), d.get(), b.get())) {
690
+ return false;
691
+ }
692
+ if (!BN_is_zero(d.get()) || !BN_is_zero(e.get())) {
693
+ fprintf(stderr, "Multiplication test failed!\n");
694
+ return false;
695
+ }
696
+ }
697
+
698
+ // Test that BN_mul never gives negative zero.
699
+ if (!BN_set_word(a.get(), 1)) {
700
+ return false;
701
+ }
702
+ BN_set_negative(a.get(), 1);
703
+ BN_zero(b.get());
704
+ if (!BN_mul(c.get(), a.get(), b.get(), ctx.get())) {
705
+ return false;
706
+ }
707
+ if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
708
+ fprintf(stderr, "Multiplication test failed!\n");
709
+ return false;
710
+ }
711
+
712
+ return true;
713
+ }
714
+
715
+ static bool test_sqr(FILE *fp, BN_CTX *ctx) {
716
+ ScopedBIGNUM a(BN_new());
717
+ ScopedBIGNUM c(BN_new());
718
+ ScopedBIGNUM d(BN_new());
719
+ ScopedBIGNUM e(BN_new());
720
+ if (!a || !c || !d || !e) {
721
+ return false;
722
+ }
723
+
724
+ for (int i = 0; i < num0; i++) {
725
+ if (!BN_rand(a.get(), 40 + i * 10, 0, 0)) {
726
+ return false;
727
+ }
728
+ a->neg = rand_neg();
729
+ if (!BN_sqr(c.get(), a.get(), ctx)) {
730
+ return false;
731
+ }
732
+ if (fp != NULL) {
733
+ BN_print_fp(fp, a.get());
734
+ puts_fp(fp, " * ");
735
+ BN_print_fp(fp, a.get());
736
+ puts_fp(fp, " - ");
737
+ BN_print_fp(fp, c.get());
738
+ puts_fp(fp, "\n");
739
+ }
740
+ if (!BN_div(d.get(), e.get(), c.get(), a.get(), ctx) ||
741
+ !BN_sub(d.get(), d.get(), a.get())) {
742
+ return false;
743
+ }
744
+ if (!BN_is_zero(d.get()) || !BN_is_zero(e.get())) {
745
+ fprintf(stderr, "Square test failed!\n");
746
+ return false;
747
+ }
748
+ }
749
+
750
+ // Regression test for a BN_sqr overflow bug.
751
+ BIGNUM *a_raw = a.get();
752
+ if (!BN_hex2bn(
753
+ &a_raw,
754
+ "80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000") ||
755
+ !BN_sqr(c.get(), a.get(), ctx)) {
756
+ return false;
757
+ }
758
+ if (fp != NULL) {
759
+ BN_print_fp(fp, a.get());
760
+ puts_fp(fp, " * ");
761
+ BN_print_fp(fp, a.get());
762
+ puts_fp(fp, " - ");
763
+ BN_print_fp(fp, c.get());
764
+ puts_fp(fp, "\n");
765
+ }
766
+ if (!BN_mul(d.get(), a.get(), a.get(), ctx)) {
767
+ return false;
768
+ }
769
+ if (BN_cmp(c.get(), d.get())) {
770
+ fprintf(stderr,
771
+ "Square test failed: BN_sqr and BN_mul produce "
772
+ "different results!\n");
773
+ return false;
774
+ }
775
+
776
+ // Regression test for a BN_sqr overflow bug.
777
+ a_raw = a.get();
778
+ if (!BN_hex2bn(
779
+ &a_raw,
780
+ "80000000000000000000000080000001FFFFFFFE000000000000000000000000") ||
781
+ !BN_sqr(c.get(), a.get(), ctx)) {
782
+ return false;
783
+ }
784
+ if (fp != NULL) {
785
+ BN_print_fp(fp, a.get());
786
+ puts_fp(fp, " * ");
787
+ BN_print_fp(fp, a.get());
788
+ puts_fp(fp, " - ");
789
+ BN_print_fp(fp, c.get());
790
+ puts_fp(fp, "\n");
791
+ }
792
+ if (!BN_mul(d.get(), a.get(), a.get(), ctx)) {
793
+ return false;
794
+ }
795
+ if (BN_cmp(c.get(), d.get())) {
796
+ fprintf(stderr,
797
+ "Square test failed: BN_sqr and BN_mul produce "
798
+ "different results!\n");
799
+ return false;
800
+ }
801
+
802
+ return true;
803
+ }
804
+
805
+
806
+ static int rand_neg() {
807
+ static unsigned int neg = 0;
808
+ static const int sign[8] = {0, 0, 0, 1, 1, 0, 1, 1};
809
+
810
+ return sign[(neg++) % 8];
811
+ }
812
+
813
+ static void print_word(FILE *fp, BN_ULONG w) {
814
+ fprintf(fp, BN_HEX_FMT1, w);
815
+ }
816
+
817
+ static bool test_div_word(FILE *fp) {
818
+ ScopedBIGNUM a(BN_new());
819
+ ScopedBIGNUM b(BN_new());
820
+ if (!a || !b) {
821
+ return false;
822
+ }
823
+
824
+ for (int i = 0; i < num0; i++) {
825
+ do {
826
+ if (!BN_rand(a.get(), 512, -1, 0) ||
827
+ !BN_rand(b.get(), BN_BITS2, -1, 0)) {
828
+ return false;
829
+ }
830
+ } while (BN_is_zero(b.get()));
831
+
832
+ if (!BN_copy(b.get(), a.get())) {
833
+ return false;
834
+ }
835
+ BN_ULONG s = b->d[0];
836
+ BN_ULONG r = BN_div_word(b.get(), s);
837
+ if (r == (BN_ULONG)-1) {
838
+ return false;
839
+ }
840
+
841
+ if (fp != NULL) {
842
+ BN_print_fp(fp, a.get());
843
+ puts_fp(fp, " / ");
844
+ print_word(fp, s);
845
+ puts_fp(fp, " - ");
846
+ BN_print_fp(fp, b.get());
847
+ puts_fp(fp, "\n");
848
+
849
+ BN_print_fp(fp, a.get());
850
+ puts_fp(fp, " % ");
851
+ print_word(fp, s);
852
+ puts_fp(fp, " - ");
853
+ print_word(fp, r);
854
+ puts_fp(fp, "\n");
855
+ }
856
+ if (!BN_mul_word(b.get(), s) ||
857
+ !BN_add_word(b.get(), r) ||
858
+ !BN_sub(b.get(), a.get(), b.get())) {
859
+ return false;
860
+ }
861
+ if (!BN_is_zero(b.get())) {
862
+ fprintf(stderr, "Division (word) test failed!\n");
863
+ return false;
864
+ }
865
+ }
866
+ return true;
867
+ }
868
+
869
+ static bool test_mont(FILE *fp, BN_CTX *ctx) {
870
+ ScopedBIGNUM a(BN_new());
871
+ ScopedBIGNUM b(BN_new());
872
+ ScopedBIGNUM c(BN_new());
873
+ ScopedBIGNUM d(BN_new());
874
+ ScopedBIGNUM A(BN_new());
875
+ ScopedBIGNUM B(BN_new());
876
+ ScopedBIGNUM n(BN_new());
877
+ ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
878
+ if (!a || !b || !c || !d || !A || !B || !n || !mont) {
879
+ return false;
880
+ }
881
+
882
+ BN_zero(n.get());
883
+ if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
884
+ fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
885
+ return false;
886
+ }
887
+ ERR_clear_error();
888
+
889
+ if (!BN_set_word(n.get(), 16)) {
890
+ return false;
891
+ }
892
+ if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
893
+ fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
894
+ return false;
895
+ }
896
+ ERR_clear_error();
897
+
898
+ if (!BN_rand(a.get(), 100, 0, 0) ||
899
+ !BN_rand(b.get(), 100, 0, 0)) {
900
+ return false;
901
+ }
902
+
903
+ for (int i = 0; i < num2; i++) {
904
+ int bits = (200 * (i + 1)) / num2;
905
+
906
+ if (bits == 0) {
907
+ continue;
908
+ }
909
+ if (!BN_rand(n.get(), bits, 0, 1) ||
910
+ !BN_MONT_CTX_set(mont.get(), n.get(), ctx) ||
911
+ !BN_nnmod(a.get(), a.get(), n.get(), ctx) ||
912
+ !BN_nnmod(b.get(), b.get(), n.get(), ctx) ||
913
+ !BN_to_montgomery(A.get(), a.get(), mont.get(), ctx) ||
914
+ !BN_to_montgomery(B.get(), b.get(), mont.get(), ctx) ||
915
+ !BN_mod_mul_montgomery(c.get(), A.get(), B.get(), mont.get(), ctx) ||
916
+ !BN_from_montgomery(A.get(), c.get(), mont.get(), ctx)) {
917
+ return false;
918
+ }
919
+ if (fp != NULL) {
920
+ BN_print_fp(fp, a.get());
921
+ puts_fp(fp, " * ");
922
+ BN_print_fp(fp, b.get());
923
+ puts_fp(fp, " % ");
924
+ BN_print_fp(fp, &mont->N);
925
+ puts_fp(fp, " - ");
926
+ BN_print_fp(fp, A.get());
927
+ puts_fp(fp, "\n");
928
+ }
929
+ if (!BN_mod_mul(d.get(), a.get(), b.get(), n.get(), ctx) ||
930
+ !BN_sub(d.get(), d.get(), A.get())) {
931
+ return false;
932
+ }
933
+ if (!BN_is_zero(d.get())) {
934
+ fprintf(stderr, "Montgomery multiplication test failed!\n");
935
+ return false;
936
+ }
937
+ }
938
+
939
+ return true;
940
+ }
941
+
942
+ static bool test_mod(FILE *fp, BN_CTX *ctx) {
943
+ ScopedBIGNUM a(BN_new());
944
+ ScopedBIGNUM b(BN_new());
945
+ ScopedBIGNUM c(BN_new());
946
+ ScopedBIGNUM d(BN_new());
947
+ ScopedBIGNUM e(BN_new());
948
+ if (!a || !b || !c || !d || !e ||
949
+ !BN_rand(a.get(), 1024, 0, 0)) {
950
+ return false;
951
+ }
952
+
953
+ for (int i = 0; i < num0; i++) {
954
+ if (!BN_rand(b.get(), 450 + i * 10, 0, 0)) {
955
+ return false;
956
+ }
957
+ a->neg = rand_neg();
958
+ b->neg = rand_neg();
959
+ if (!BN_mod(c.get(), a.get(), b.get(), ctx)) {
960
+ return false;
961
+ }
962
+ if (fp != NULL) {
963
+ BN_print_fp(fp, a.get());
964
+ puts_fp(fp, " % ");
965
+ BN_print_fp(fp, b.get());
966
+ puts_fp(fp, " - ");
967
+ BN_print_fp(fp, c.get());
968
+ puts_fp(fp, "\n");
969
+ }
970
+ if (!BN_div(d.get(), e.get(), a.get(), b.get(), ctx) ||
971
+ !BN_sub(e.get(), e.get(), c.get())) {
972
+ return false;
973
+ }
974
+ if (!BN_is_zero(e.get())) {
975
+ fprintf(stderr, "Modulo test failed!\n");
976
+ return false;
977
+ }
978
+ }
979
+ return true;
980
+ }
981
+
982
+ static bool test_mod_mul(FILE *fp, BN_CTX *ctx) {
983
+ ScopedBIGNUM a(BN_new());
984
+ ScopedBIGNUM b(BN_new());
985
+ ScopedBIGNUM c(BN_new());
986
+ ScopedBIGNUM d(BN_new());
987
+ ScopedBIGNUM e(BN_new());
988
+ if (!a || !b || !c || !d || !e) {
989
+ return false;
990
+ }
991
+
992
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
993
+ return false;
994
+ }
995
+ BN_zero(c.get());
996
+ if (BN_mod_mul(e.get(), a.get(), b.get(), c.get(), ctx)) {
997
+ fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
998
+ return false;
999
+ }
1000
+ ERR_clear_error();
1001
+
1002
+ for (int j = 0; j < 3; j++) {
1003
+ if (!BN_rand(c.get(), 1024, 0, 0)) {
1004
+ return false;
1005
+ }
1006
+ for (int i = 0; i < num0; i++) {
1007
+ if (!BN_rand(a.get(), 475 + i * 10, 0, 0) ||
1008
+ !BN_rand(b.get(), 425 + i * 11, 0, 0)) {
1009
+ return false;
1010
+ }
1011
+ a->neg = rand_neg();
1012
+ b->neg = rand_neg();
1013
+ if (!BN_mod_mul(e.get(), a.get(), b.get(), c.get(), ctx)) {
1014
+ return false;
1015
+ }
1016
+ if (fp != NULL) {
1017
+ BN_print_fp(fp, a.get());
1018
+ puts_fp(fp, " * ");
1019
+ BN_print_fp(fp, b.get());
1020
+ puts_fp(fp, " % ");
1021
+ BN_print_fp(fp, c.get());
1022
+ if (a->neg != b->neg && !BN_is_zero(e.get())) {
1023
+ // If (a*b) % c is negative, c must be added
1024
+ // in order to obtain the normalized remainder
1025
+ // (new with OpenSSL 0.9.7, previous versions of
1026
+ // BN_mod_mul could generate negative results)
1027
+ puts_fp(fp, " + ");
1028
+ BN_print_fp(fp, c.get());
1029
+ }
1030
+ puts_fp(fp, " - ");
1031
+ BN_print_fp(fp, e.get());
1032
+ puts_fp(fp, "\n");
1033
+ }
1034
+ if (!BN_mul(d.get(), a.get(), b.get(), ctx) ||
1035
+ !BN_sub(d.get(), d.get(), e.get()) ||
1036
+ !BN_div(a.get(), b.get(), d.get(), c.get(), ctx)) {
1037
+ return false;
1038
+ }
1039
+ if (!BN_is_zero(b.get())) {
1040
+ fprintf(stderr, "Modulo multiply test failed!\n");
1041
+ return false;
1042
+ }
1043
+ }
1044
+ }
1045
+ return true;
1046
+ }
1047
+
1048
+ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) {
1049
+ ScopedBIGNUM a(BN_new());
1050
+ ScopedBIGNUM b(BN_new());
1051
+ ScopedBIGNUM c(BN_new());
1052
+ ScopedBIGNUM d(BN_new());
1053
+ ScopedBIGNUM e(BN_new());
1054
+ if (!a || !b || !c || !d || !e) {
1055
+ return false;
1056
+ }
1057
+
1058
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
1059
+ return false;
1060
+ }
1061
+ BN_zero(c.get());
1062
+ if (BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx)) {
1063
+ fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
1064
+ return 0;
1065
+ }
1066
+ ERR_clear_error();
1067
+
1068
+ if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
1069
+ return false;
1070
+ }
1071
+ for (int i = 0; i < num2; i++) {
1072
+ if (!BN_rand(a.get(), 20 + i * 5, 0, 0) ||
1073
+ !BN_rand(b.get(), 2 + i, 0, 0) ||
1074
+ !BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx)) {
1075
+ return false;
1076
+ }
1077
+
1078
+ if (fp != NULL) {
1079
+ BN_print_fp(fp, a.get());
1080
+ puts_fp(fp, " ^ ");
1081
+ BN_print_fp(fp, b.get());
1082
+ puts_fp(fp, " % ");
1083
+ BN_print_fp(fp, c.get());
1084
+ puts_fp(fp, " - ");
1085
+ BN_print_fp(fp, d.get());
1086
+ puts_fp(fp, "\n");
1087
+ }
1088
+ if (!BN_exp(e.get(), a.get(), b.get(), ctx) ||
1089
+ !BN_sub(e.get(), e.get(), d.get()) ||
1090
+ !BN_div(a.get(), b.get(), e.get(), c.get(), ctx)) {
1091
+ return false;
1092
+ }
1093
+ if (!BN_is_zero(b.get())) {
1094
+ fprintf(stderr, "Modulo exponentiation test failed!\n");
1095
+ return false;
1096
+ }
1097
+ }
1098
+
1099
+ // Regression test for carry propagation bug in sqr8x_reduction.
1100
+ if (!HexToBIGNUM(&a, "050505050505") ||
1101
+ !HexToBIGNUM(&b, "02") ||
1102
+ !HexToBIGNUM(
1103
+ &c,
1104
+ "4141414141414141414141274141414141414141414141414141414141414141"
1105
+ "4141414141414141414141414141414141414141414141414141414141414141"
1106
+ "4141414141414141414141800000000000000000000000000000000000000000"
1107
+ "0000000000000000000000000000000000000000000000000000000000000000"
1108
+ "0000000000000000000000000000000000000000000000000000000000000000"
1109
+ "0000000000000000000000000000000000000000000000000000000001") ||
1110
+ !BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx) ||
1111
+ !BN_mul(e.get(), a.get(), a.get(), ctx)) {
1112
+ return false;
1113
+ }
1114
+ if (BN_cmp(d.get(), e.get()) != 0) {
1115
+ fprintf(stderr, "BN_mod_exp and BN_mul produce different results!\n");
1116
+ return false;
1117
+ }
1118
+
1119
+ return true;
1120
+ }
1121
+
1122
+ static bool test_mod_exp_mont_consttime(FILE *fp, BN_CTX *ctx) {
1123
+ ScopedBIGNUM a(BN_new());
1124
+ ScopedBIGNUM b(BN_new());
1125
+ ScopedBIGNUM c(BN_new());
1126
+ ScopedBIGNUM d(BN_new());
1127
+ ScopedBIGNUM e(BN_new());
1128
+ if (!a || !b || !c || !d || !e) {
1129
+ return false;
1130
+ }
1131
+
1132
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
1133
+ return false;
1134
+ }
1135
+ BN_zero(c.get());
1136
+ if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
1137
+ nullptr)) {
1138
+ fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus succeeded!\n");
1139
+ return 0;
1140
+ }
1141
+ ERR_clear_error();
1142
+
1143
+ if (!BN_set_word(c.get(), 16)) {
1144
+ return false;
1145
+ }
1146
+ if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
1147
+ nullptr)) {
1148
+ fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus succeeded!\n");
1149
+ return 0;
1150
+ }
1151
+ ERR_clear_error();
1152
+
1153
+ if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
1154
+ return false;
1155
+ }
1156
+ for (int i = 0; i < num2; i++) {
1157
+ if (!BN_rand(a.get(), 20 + i * 5, 0, 0) ||
1158
+ !BN_rand(b.get(), 2 + i, 0, 0) ||
1159
+ !BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
1160
+ NULL)) {
1161
+ return false;
1162
+ }
1163
+
1164
+ if (fp != NULL) {
1165
+ BN_print_fp(fp, a.get());
1166
+ puts_fp(fp, " ^ ");
1167
+ BN_print_fp(fp, b.get());
1168
+ puts_fp(fp, " % ");
1169
+ BN_print_fp(fp, c.get());
1170
+ puts_fp(fp, " - ");
1171
+ BN_print_fp(fp, d.get());
1172
+ puts_fp(fp, "\n");
1173
+ }
1174
+ if (!BN_exp(e.get(), a.get(), b.get(), ctx) ||
1175
+ !BN_sub(e.get(), e.get(), d.get()) ||
1176
+ !BN_div(a.get(), b.get(), e.get(), c.get(), ctx)) {
1177
+ return false;
1178
+ }
1179
+ if (!BN_is_zero(b.get())) {
1180
+ fprintf(stderr, "Modulo exponentiation test failed!\n");
1181
+ return false;
1182
+ }
1183
+ }
1184
+ return true;
1185
+ }
1186
+
1187
+ // Test constant-time modular exponentiation with 1024-bit inputs,
1188
+ // which on x86_64 cause a different code branch to be taken.
1189
+ static bool test_mod_exp_mont5(FILE *fp, BN_CTX *ctx) {
1190
+ ScopedBIGNUM a(BN_new());
1191
+ ScopedBIGNUM p(BN_new());
1192
+ ScopedBIGNUM m(BN_new());
1193
+ ScopedBIGNUM d(BN_new());
1194
+ ScopedBIGNUM e(BN_new());
1195
+ if (!a || !p || !m || !d || !e ||
1196
+ !BN_rand(m.get(), 1024, 0, 1) || // must be odd for montgomery
1197
+ !BN_rand(a.get(), 1024, 0, 0)) {
1198
+ return false;
1199
+ }
1200
+ // Zero exponent.
1201
+ BN_zero(p.get());
1202
+ if (!BN_mod_exp_mont_consttime(d.get(), a.get(), p.get(), m.get(), ctx,
1203
+ NULL)) {
1204
+ return false;
1205
+ }
1206
+ if (!BN_is_one(d.get())) {
1207
+ fprintf(stderr, "Modular exponentiation test failed!\n");
1208
+ return false;
1209
+ }
1210
+ if (!BN_rand(p.get(), 1024, 0, 0)) {
1211
+ return false;
1212
+ }
1213
+ // Zero input.
1214
+ BN_zero(a.get());
1215
+ if (!BN_mod_exp_mont_consttime(d.get(), a.get(), p.get(), m.get(), ctx,
1216
+ NULL)) {
1217
+ return false;
1218
+ }
1219
+ if (!BN_is_zero(d.get())) {
1220
+ fprintf(stderr, "Modular exponentiation test failed!\n");
1221
+ return false;
1222
+ }
1223
+ // Craft an input whose Montgomery representation is 1, i.e., shorter than the
1224
+ // modulus m, in order to test the const time precomputation
1225
+ // scattering/gathering.
1226
+ ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
1227
+ if (!mont || !BN_one(a.get()) ||
1228
+ !BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
1229
+ !BN_from_montgomery(e.get(), a.get(), mont.get(), ctx) ||
1230
+ !BN_mod_exp_mont_consttime(d.get(), e.get(), p.get(), m.get(), ctx,
1231
+ NULL) ||
1232
+ !BN_mod_exp(a.get(), e.get(), p.get(), m.get(), ctx)) {
1233
+ return false;
1234
+ }
1235
+ if (BN_cmp(a.get(), d.get()) != 0) {
1236
+ fprintf(stderr, "Modular exponentiation test failed!\n");
1237
+ return false;
1238
+ }
1239
+ // Finally, some regular test vectors.
1240
+ if (!BN_rand(e.get(), 1024, 0, 0) ||
1241
+ !BN_mod_exp_mont_consttime(d.get(), e.get(), p.get(), m.get(), ctx,
1242
+ NULL) ||
1243
+ !BN_mod_exp(a.get(), e.get(), p.get(), m.get(), ctx)) {
1244
+ return false;
1245
+ }
1246
+ if (BN_cmp(a.get(), d.get()) != 0) {
1247
+ fprintf(stderr, "Modular exponentiation test failed!\n");
1248
+ return false;
1249
+ }
1250
+
1251
+ return true;
1252
+ }
1253
+
1254
+ static bool test_exp(FILE *fp, BN_CTX *ctx) {
1255
+ ScopedBIGNUM a(BN_new());
1256
+ ScopedBIGNUM b(BN_new());
1257
+ ScopedBIGNUM d(BN_new());
1258
+ ScopedBIGNUM e(BN_new());
1259
+ if (!a || !b || !d || !e) {
1260
+ return false;
1261
+ }
1262
+
1263
+ for (int i = 0; i < num2; i++) {
1264
+ if (!BN_rand(a.get(), 20 + i * 5, 0, 0) ||
1265
+ !BN_rand(b.get(), 2 + i, 0, 0) ||
1266
+ !BN_exp(d.get(), a.get(), b.get(), ctx)) {
1267
+ return false;
1268
+ }
1269
+
1270
+ if (fp != NULL) {
1271
+ BN_print_fp(fp, a.get());
1272
+ puts_fp(fp, " ^ ");
1273
+ BN_print_fp(fp, b.get());
1274
+ puts_fp(fp, " - ");
1275
+ BN_print_fp(fp, d.get());
1276
+ puts_fp(fp, "\n");
1277
+ }
1278
+ if (!BN_one(e.get())) {
1279
+ return false;
1280
+ }
1281
+ while (!BN_is_zero(b.get())) {
1282
+ if (!BN_mul(e.get(), e.get(), a.get(), ctx) ||
1283
+ !BN_sub(b.get(), b.get(), BN_value_one())) {
1284
+ return false;
1285
+ }
1286
+ }
1287
+ if (!BN_sub(e.get(), e.get(), d.get())) {
1288
+ return false;
1289
+ }
1290
+ if (!BN_is_zero(e.get())) {
1291
+ fprintf(stderr, "Exponentiation test failed!\n");
1292
+ return false;
1293
+ }
1294
+ }
1295
+ return true;
1296
+ }
1297
+
1298
+ // test_exp_mod_zero tests that 1**0 mod 1 == 0.
1299
+ static bool test_exp_mod_zero(void) {
1300
+ ScopedBIGNUM zero(BN_new());
1301
+ if (!zero) {
1302
+ return false;
1303
+ }
1304
+ BN_zero(zero.get());
1305
+
1306
+ ScopedBN_CTX ctx(BN_CTX_new());
1307
+ ScopedBIGNUM r(BN_new());
1308
+ if (!ctx || !r ||
1309
+ !BN_mod_exp(r.get(), BN_value_one(), zero.get(), BN_value_one(), ctx.get())) {
1310
+ return false;
1311
+ }
1312
+
1313
+ if (!BN_is_zero(r.get())) {
1314
+ fprintf(stderr, "1**0 mod 1 = ");
1315
+ BN_print_fp(stderr, r.get());
1316
+ fprintf(stderr, ", should be 0\n");
1317
+ return false;
1318
+ }
1319
+
1320
+ return true;
1321
+ }
1322
+
1323
+ static bool test_small_prime(FILE *fp, BN_CTX *ctx) {
1324
+ static const unsigned kBits = 10;
1325
+
1326
+ ScopedBIGNUM r(BN_new());
1327
+ if (!r || !BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
1328
+ NULL, NULL)) {
1329
+ return false;
1330
+ }
1331
+ if (BN_num_bits(r.get()) != kBits) {
1332
+ fprintf(fp, "Expected %u bit prime, got %u bit number\n", kBits,
1333
+ BN_num_bits(r.get()));
1334
+ return false;
1335
+ }
1336
+
1337
+ return true;
1338
+ }
1339
+
1340
+ static bool test_bn2bin_padded(BN_CTX *ctx) {
1341
+ uint8_t zeros[256], out[256], reference[128];
1342
+
1343
+ memset(zeros, 0, sizeof(zeros));
1344
+
1345
+ // Test edge case at 0.
1346
+ ScopedBIGNUM n(BN_new());
1347
+ if (!n || !BN_bn2bin_padded(NULL, 0, n.get())) {
1348
+ fprintf(stderr,
1349
+ "BN_bn2bin_padded failed to encode 0 in an empty buffer.\n");
1350
+ return false;
1351
+ }
1352
+ memset(out, -1, sizeof(out));
1353
+ if (!BN_bn2bin_padded(out, sizeof(out), n.get())) {
1354
+ fprintf(stderr,
1355
+ "BN_bn2bin_padded failed to encode 0 in a non-empty buffer.\n");
1356
+ return false;
1357
+ }
1358
+ if (memcmp(zeros, out, sizeof(out))) {
1359
+ fprintf(stderr, "BN_bn2bin_padded did not zero buffer.\n");
1360
+ return false;
1361
+ }
1362
+
1363
+ // Test a random numbers at various byte lengths.
1364
+ for (size_t bytes = 128 - 7; bytes <= 128; bytes++) {
1365
+ if (!BN_rand(n.get(), bytes * 8, 0 /* make sure top bit is 1 */,
1366
+ 0 /* don't modify bottom bit */)) {
1367
+ return false;
1368
+ }
1369
+ if (BN_num_bytes(n.get()) != bytes ||
1370
+ BN_bn2bin(n.get(), reference) != bytes) {
1371
+ fprintf(stderr, "Bad result from BN_rand; bytes.\n");
1372
+ return false;
1373
+ }
1374
+ // Empty buffer should fail.
1375
+ if (BN_bn2bin_padded(NULL, 0, n.get())) {
1376
+ fprintf(stderr,
1377
+ "BN_bn2bin_padded incorrectly succeeded on empty buffer.\n");
1378
+ return false;
1379
+ }
1380
+ // One byte short should fail.
1381
+ if (BN_bn2bin_padded(out, bytes - 1, n.get())) {
1382
+ fprintf(stderr, "BN_bn2bin_padded incorrectly succeeded on short.\n");
1383
+ return false;
1384
+ }
1385
+ // Exactly right size should encode.
1386
+ if (!BN_bn2bin_padded(out, bytes, n.get()) ||
1387
+ memcmp(out, reference, bytes) != 0) {
1388
+ fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
1389
+ return false;
1390
+ }
1391
+ // Pad up one byte extra.
1392
+ if (!BN_bn2bin_padded(out, bytes + 1, n.get()) ||
1393
+ memcmp(out + 1, reference, bytes) || memcmp(out, zeros, 1)) {
1394
+ fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
1395
+ return false;
1396
+ }
1397
+ // Pad up to 256.
1398
+ if (!BN_bn2bin_padded(out, sizeof(out), n.get()) ||
1399
+ memcmp(out + sizeof(out) - bytes, reference, bytes) ||
1400
+ memcmp(out, zeros, sizeof(out) - bytes)) {
1401
+ fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
1402
+ return false;
1403
+ }
1404
+ }
1405
+
1406
+ return true;
1407
+ }
1408
+
1409
+ static int DecimalToBIGNUM(ScopedBIGNUM *out, const char *in) {
1410
+ BIGNUM *raw = NULL;
1411
+ int ret = BN_dec2bn(&raw, in);
1412
+ out->reset(raw);
1413
+ return ret;
1414
+ }
1415
+
1416
+ static bool test_dec2bn(BN_CTX *ctx) {
1417
+ ScopedBIGNUM bn;
1418
+ int ret = DecimalToBIGNUM(&bn, "0");
1419
+ if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
1420
+ fprintf(stderr, "BN_dec2bn gave a bad result.\n");
1421
+ return false;
1422
+ }
1423
+
1424
+ ret = DecimalToBIGNUM(&bn, "256");
1425
+ if (ret != 3 || !BN_is_word(bn.get(), 256) || BN_is_negative(bn.get())) {
1426
+ fprintf(stderr, "BN_dec2bn gave a bad result.\n");
1427
+ return false;
1428
+ }
1429
+
1430
+ ret = DecimalToBIGNUM(&bn, "-42");
1431
+ if (ret != 3 || !BN_abs_is_word(bn.get(), 42) || !BN_is_negative(bn.get())) {
1432
+ fprintf(stderr, "BN_dec2bn gave a bad result.\n");
1433
+ return false;
1434
+ }
1435
+
1436
+ ret = DecimalToBIGNUM(&bn, "-0");
1437
+ if (ret != 2 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
1438
+ fprintf(stderr, "BN_dec2bn gave a bad result.\n");
1439
+ return false;
1440
+ }
1441
+
1442
+ ret = DecimalToBIGNUM(&bn, "42trailing garbage is ignored");
1443
+ if (ret != 2 || !BN_abs_is_word(bn.get(), 42) || BN_is_negative(bn.get())) {
1444
+ fprintf(stderr, "BN_dec2bn gave a bad result.\n");
1445
+ return false;
1446
+ }
1447
+
1448
+ return true;
1449
+ }
1450
+
1451
+ static bool test_hex2bn(BN_CTX *ctx) {
1452
+ ScopedBIGNUM bn;
1453
+ int ret = HexToBIGNUM(&bn, "0");
1454
+ if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
1455
+ fprintf(stderr, "BN_hex2bn gave a bad result.\n");
1456
+ return false;
1457
+ }
1458
+
1459
+ ret = HexToBIGNUM(&bn, "256");
1460
+ if (ret != 3 || !BN_is_word(bn.get(), 0x256) || BN_is_negative(bn.get())) {
1461
+ fprintf(stderr, "BN_hex2bn gave a bad result.\n");
1462
+ return false;
1463
+ }
1464
+
1465
+ ret = HexToBIGNUM(&bn, "-42");
1466
+ if (ret != 3 || !BN_abs_is_word(bn.get(), 0x42) || !BN_is_negative(bn.get())) {
1467
+ fprintf(stderr, "BN_hex2bn gave a bad result.\n");
1468
+ return false;
1469
+ }
1470
+
1471
+ ret = HexToBIGNUM(&bn, "-0");
1472
+ if (ret != 2 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
1473
+ fprintf(stderr, "BN_hex2bn gave a bad result.\n");
1474
+ return false;
1475
+ }
1476
+
1477
+ ret = HexToBIGNUM(&bn, "abctrailing garbage is ignored");
1478
+ if (ret != 3 || !BN_is_word(bn.get(), 0xabc) || BN_is_negative(bn.get())) {
1479
+ fprintf(stderr, "BN_hex2bn gave a bad result.\n");
1480
+ return false;
1481
+ }
1482
+
1483
+ return true;
1484
+ }
1485
+
1486
+ static ScopedBIGNUM ASCIIToBIGNUM(const char *in) {
1487
+ BIGNUM *raw = NULL;
1488
+ if (!BN_asc2bn(&raw, in)) {
1489
+ return nullptr;
1490
+ }
1491
+ return ScopedBIGNUM(raw);
1492
+ }
1493
+
1494
+ static bool test_asc2bn(BN_CTX *ctx) {
1495
+ ScopedBIGNUM bn = ASCIIToBIGNUM("0");
1496
+ if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
1497
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1498
+ return false;
1499
+ }
1500
+
1501
+ bn = ASCIIToBIGNUM("256");
1502
+ if (!bn || !BN_is_word(bn.get(), 256) || BN_is_negative(bn.get())) {
1503
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1504
+ return false;
1505
+ }
1506
+
1507
+ bn = ASCIIToBIGNUM("-42");
1508
+ if (!bn || !BN_abs_is_word(bn.get(), 42) || !BN_is_negative(bn.get())) {
1509
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1510
+ return false;
1511
+ }
1512
+
1513
+ bn = ASCIIToBIGNUM("0x1234");
1514
+ if (!bn || !BN_is_word(bn.get(), 0x1234) || BN_is_negative(bn.get())) {
1515
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1516
+ return false;
1517
+ }
1518
+
1519
+ bn = ASCIIToBIGNUM("0X1234");
1520
+ if (!bn || !BN_is_word(bn.get(), 0x1234) || BN_is_negative(bn.get())) {
1521
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1522
+ return false;
1523
+ }
1524
+
1525
+ bn = ASCIIToBIGNUM("-0xabcd");
1526
+ if (!bn || !BN_abs_is_word(bn.get(), 0xabcd) || !BN_is_negative(bn.get())) {
1527
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1528
+ return false;
1529
+ }
1530
+
1531
+ bn = ASCIIToBIGNUM("-0");
1532
+ if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
1533
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1534
+ return false;
1535
+ }
1536
+
1537
+ bn = ASCIIToBIGNUM("123trailing garbage is ignored");
1538
+ if (!bn || !BN_is_word(bn.get(), 123) || BN_is_negative(bn.get())) {
1539
+ fprintf(stderr, "BN_asc2bn gave a bad result.\n");
1540
+ return false;
1541
+ }
1542
+
1543
+ return true;
1544
+ }
1545
+
1546
+ static bool test_rand() {
1547
+ ScopedBIGNUM bn(BN_new());
1548
+ if (!bn) {
1549
+ return false;
1550
+ }
1551
+
1552
+ // Test BN_rand accounts for degenerate cases with |top| and |bottom|
1553
+ // parameters.
1554
+ if (!BN_rand(bn.get(), 0, 0 /* top */, 0 /* bottom */) ||
1555
+ !BN_is_zero(bn.get())) {
1556
+ fprintf(stderr, "BN_rand gave a bad result.\n");
1557
+ return false;
1558
+ }
1559
+ if (!BN_rand(bn.get(), 0, 1 /* top */, 1 /* bottom */) ||
1560
+ !BN_is_zero(bn.get())) {
1561
+ fprintf(stderr, "BN_rand gave a bad result.\n");
1562
+ return false;
1563
+ }
1564
+
1565
+ if (!BN_rand(bn.get(), 1, 0 /* top */, 0 /* bottom */) ||
1566
+ !BN_is_word(bn.get(), 1)) {
1567
+ fprintf(stderr, "BN_rand gave a bad result.\n");
1568
+ return false;
1569
+ }
1570
+ if (!BN_rand(bn.get(), 1, 1 /* top */, 0 /* bottom */) ||
1571
+ !BN_is_word(bn.get(), 1)) {
1572
+ fprintf(stderr, "BN_rand gave a bad result.\n");
1573
+ return false;
1574
+ }
1575
+ if (!BN_rand(bn.get(), 1, -1 /* top */, 1 /* bottom */) ||
1576
+ !BN_is_word(bn.get(), 1)) {
1577
+ fprintf(stderr, "BN_rand gave a bad result.\n");
1578
+ return false;
1579
+ }
1580
+
1581
+ if (!BN_rand(bn.get(), 2, 1 /* top */, 0 /* bottom */) ||
1582
+ !BN_is_word(bn.get(), 3)) {
1583
+ fprintf(stderr, "BN_rand gave a bad result.\n");
1584
+ return false;
1585
+ }
1586
+
1587
+ return true;
1588
+ }
1589
+
1590
+ struct ASN1Test {
1591
+ const char *value_ascii;
1592
+ const char *der;
1593
+ size_t der_len;
1594
+ };
1595
+
1596
+ static const ASN1Test kASN1Tests[] = {
1597
+ {"0", "\x02\x01\x00", 3},
1598
+ {"1", "\x02\x01\x01", 3},
1599
+ {"127", "\x02\x01\x7f", 3},
1600
+ {"128", "\x02\x02\x00\x80", 4},
1601
+ {"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
1602
+ {"0x0102030405060708",
1603
+ "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
1604
+ {"0xffffffffffffffff",
1605
+ "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
1606
+ };
1607
+
1608
+ struct ASN1InvalidTest {
1609
+ const char *der;
1610
+ size_t der_len;
1611
+ };
1612
+
1613
+ static const ASN1InvalidTest kASN1InvalidTests[] = {
1614
+ // Bad tag.
1615
+ {"\x03\x01\x00", 3},
1616
+ // Empty contents.
1617
+ {"\x02\x00", 2},
1618
+ // Negative number.
1619
+ {"\x02\x01\x80", 3},
1620
+ // Leading zeros.
1621
+ {"\x02\x02\x00\x01", 4},
1622
+ };
1623
+
1624
+ static bool test_asn1() {
1625
+ for (const ASN1Test &test : kASN1Tests) {
1626
+ ScopedBIGNUM bn = ASCIIToBIGNUM(test.value_ascii);
1627
+ if (!bn) {
1628
+ return false;
1629
+ }
1630
+
1631
+ // Test that the input is correctly parsed.
1632
+ ScopedBIGNUM bn2(BN_new());
1633
+ if (!bn2) {
1634
+ return false;
1635
+ }
1636
+ CBS cbs;
1637
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
1638
+ if (!BN_cbs2unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
1639
+ fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
1640
+ return false;
1641
+ }
1642
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
1643
+ fprintf(stderr, "Bad parse.\n");
1644
+ return false;
1645
+ }
1646
+
1647
+ // Test the value serializes correctly.
1648
+ CBB cbb;
1649
+ uint8_t *der;
1650
+ size_t der_len;
1651
+ CBB_zero(&cbb);
1652
+ if (!CBB_init(&cbb, 0) ||
1653
+ !BN_bn2cbb(&cbb, bn.get()) ||
1654
+ !CBB_finish(&cbb, &der, &der_len)) {
1655
+ CBB_cleanup(&cbb);
1656
+ return false;
1657
+ }
1658
+ ScopedOpenSSLBytes delete_der(der);
1659
+ if (der_len != test.der_len ||
1660
+ memcmp(der, reinterpret_cast<const uint8_t*>(test.der), der_len) != 0) {
1661
+ fprintf(stderr, "Bad serialization.\n");
1662
+ return false;
1663
+ }
1664
+ }
1665
+
1666
+ for (const ASN1InvalidTest &test : kASN1InvalidTests) {
1667
+ ScopedBIGNUM bn(BN_new());
1668
+ if (!bn) {
1669
+ return false;
1670
+ }
1671
+ CBS cbs;
1672
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
1673
+ if (BN_cbs2unsigned(&cbs, bn.get())) {
1674
+ fprintf(stderr, "Parsed invalid input.\n");
1675
+ return false;
1676
+ }
1677
+ ERR_clear_error();
1678
+ }
1679
+
1680
+ // Serializing negative numbers is not supported.
1681
+ ScopedBIGNUM bn = ASCIIToBIGNUM("-1");
1682
+ if (!bn) {
1683
+ return false;
1684
+ }
1685
+ CBB cbb;
1686
+ CBB_zero(&cbb);
1687
+ if (!CBB_init(&cbb, 0) ||
1688
+ BN_bn2cbb(&cbb, bn.get())) {
1689
+ fprintf(stderr, "Serialized negative number.\n");
1690
+ CBB_cleanup(&cbb);
1691
+ return false;
1692
+ }
1693
+ CBB_cleanup(&cbb);
1694
+
1695
+ return true;
1696
+ }