exptest.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "../e_os.h"
  13. #include <openssl/bio.h>
  14. #include <openssl/bn.h>
  15. #include <openssl/rand.h>
  16. #include <openssl/err.h>
  17. #define NUM_BITS (BN_BITS2 * 4)
  18. static const char rnd_seed[] =
  19. "string to make the random number generator think it has entropy";
  20. /*
  21. * Test that r == 0 in test_exp_mod_zero(). Returns one on success,
  22. * returns zero and prints debug output otherwise.
  23. */
  24. static int a_is_zero_mod_one(const char *method, const BIGNUM *r,
  25. const BIGNUM *a) {
  26. if (!BN_is_zero(r)) {
  27. fprintf(stderr, "%s failed:\n", method);
  28. fprintf(stderr, "a ** 0 mod 1 = r (should be 0)\n");
  29. fprintf(stderr, "a = ");
  30. BN_print_fp(stderr, a);
  31. fprintf(stderr, "\nr = ");
  32. BN_print_fp(stderr, r);
  33. fprintf(stderr, "\n");
  34. return 0;
  35. }
  36. return 1;
  37. }
  38. /*
  39. * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success.
  40. */
  41. static int test_exp_mod_zero()
  42. {
  43. BIGNUM *a = NULL, *p = NULL, *m = NULL;
  44. BIGNUM *r = NULL;
  45. BN_ULONG one_word = 1;
  46. BN_CTX *ctx = BN_CTX_new();
  47. int ret = 1, failed = 0;
  48. m = BN_new();
  49. if (!m)
  50. goto err;
  51. BN_one(m);
  52. a = BN_new();
  53. if (!a)
  54. goto err;
  55. BN_one(a);
  56. p = BN_new();
  57. if (!p)
  58. goto err;
  59. BN_zero(p);
  60. r = BN_new();
  61. if (!r)
  62. goto err;
  63. if (!BN_rand(a, 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
  64. goto err;
  65. if (!BN_mod_exp(r, a, p, m, ctx))
  66. goto err;
  67. if (!a_is_zero_mod_one("BN_mod_exp", r, a))
  68. failed = 1;
  69. if (!BN_mod_exp_recp(r, a, p, m, ctx))
  70. goto err;
  71. if (!a_is_zero_mod_one("BN_mod_exp_recp", r, a))
  72. failed = 1;
  73. if (!BN_mod_exp_simple(r, a, p, m, ctx))
  74. goto err;
  75. if (!a_is_zero_mod_one("BN_mod_exp_simple", r, a))
  76. failed = 1;
  77. if (!BN_mod_exp_mont(r, a, p, m, ctx, NULL))
  78. goto err;
  79. if (!a_is_zero_mod_one("BN_mod_exp_mont", r, a))
  80. failed = 1;
  81. if (!BN_mod_exp_mont_consttime(r, a, p, m, ctx, NULL)) {
  82. goto err;
  83. }
  84. if (!a_is_zero_mod_one("BN_mod_exp_mont_consttime", r, a))
  85. failed = 1;
  86. /*
  87. * A different codepath exists for single word multiplication
  88. * in non-constant-time only.
  89. */
  90. if (!BN_mod_exp_mont_word(r, one_word, p, m, ctx, NULL))
  91. goto err;
  92. if (!BN_is_zero(r)) {
  93. fprintf(stderr, "BN_mod_exp_mont_word failed:\n");
  94. fprintf(stderr, "1 ** 0 mod 1 = r (should be 0)\n");
  95. fprintf(stderr, "r = ");
  96. BN_print_fp(stderr, r);
  97. fprintf(stderr, "\n");
  98. return 0;
  99. }
  100. ret = failed;
  101. err:
  102. BN_free(r);
  103. BN_free(a);
  104. BN_free(p);
  105. BN_free(m);
  106. BN_CTX_free(ctx);
  107. return ret;
  108. }
  109. int main(int argc, char *argv[])
  110. {
  111. BN_CTX *ctx;
  112. BIO *out = NULL;
  113. int i, ret;
  114. unsigned char c;
  115. BIGNUM *r_mont, *r_mont_const, *r_recp, *r_simple, *a, *b, *m;
  116. RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we
  117. * don't even check its return
  118. * value (which we should) */
  119. ctx = BN_CTX_new();
  120. if (ctx == NULL)
  121. EXIT(1);
  122. r_mont = BN_new();
  123. r_mont_const = BN_new();
  124. r_recp = BN_new();
  125. r_simple = BN_new();
  126. a = BN_new();
  127. b = BN_new();
  128. m = BN_new();
  129. if ((r_mont == NULL) || (r_recp == NULL) || (a == NULL) || (b == NULL))
  130. goto err;
  131. out = BIO_new(BIO_s_file());
  132. if (out == NULL)
  133. EXIT(1);
  134. BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
  135. for (i = 0; i < 200; i++) {
  136. RAND_bytes(&c, 1);
  137. c = (c % BN_BITS) - BN_BITS2;
  138. BN_rand(a, NUM_BITS + c, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY);
  139. RAND_bytes(&c, 1);
  140. c = (c % BN_BITS) - BN_BITS2;
  141. BN_rand(b, NUM_BITS + c, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY);
  142. RAND_bytes(&c, 1);
  143. c = (c % BN_BITS) - BN_BITS2;
  144. BN_rand(m, NUM_BITS + c, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD);
  145. BN_mod(a, a, m, ctx);
  146. BN_mod(b, b, m, ctx);
  147. ret = BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL);
  148. if (ret <= 0) {
  149. printf("BN_mod_exp_mont() problems\n");
  150. ERR_print_errors(out);
  151. EXIT(1);
  152. }
  153. ret = BN_mod_exp_recp(r_recp, a, b, m, ctx);
  154. if (ret <= 0) {
  155. printf("BN_mod_exp_recp() problems\n");
  156. ERR_print_errors(out);
  157. EXIT(1);
  158. }
  159. ret = BN_mod_exp_simple(r_simple, a, b, m, ctx);
  160. if (ret <= 0) {
  161. printf("BN_mod_exp_simple() problems\n");
  162. ERR_print_errors(out);
  163. EXIT(1);
  164. }
  165. ret = BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL);
  166. if (ret <= 0) {
  167. printf("BN_mod_exp_mont_consttime() problems\n");
  168. ERR_print_errors(out);
  169. EXIT(1);
  170. }
  171. if (BN_cmp(r_simple, r_mont) == 0
  172. && BN_cmp(r_simple, r_recp) == 0
  173. && BN_cmp(r_simple, r_mont_const) == 0) {
  174. printf(".");
  175. fflush(stdout);
  176. } else {
  177. if (BN_cmp(r_simple, r_mont) != 0)
  178. printf("\nsimple and mont results differ\n");
  179. if (BN_cmp(r_simple, r_mont_const) != 0)
  180. printf("\nsimple and mont const time results differ\n");
  181. if (BN_cmp(r_simple, r_recp) != 0)
  182. printf("\nsimple and recp results differ\n");
  183. printf("a (%3d) = ", BN_num_bits(a));
  184. BN_print(out, a);
  185. printf("\nb (%3d) = ", BN_num_bits(b));
  186. BN_print(out, b);
  187. printf("\nm (%3d) = ", BN_num_bits(m));
  188. BN_print(out, m);
  189. printf("\nsimple =");
  190. BN_print(out, r_simple);
  191. printf("\nrecp =");
  192. BN_print(out, r_recp);
  193. printf("\nmont =");
  194. BN_print(out, r_mont);
  195. printf("\nmont_ct =");
  196. BN_print(out, r_mont_const);
  197. printf("\n");
  198. EXIT(1);
  199. }
  200. }
  201. BN_free(r_mont);
  202. BN_free(r_mont_const);
  203. BN_free(r_recp);
  204. BN_free(r_simple);
  205. BN_free(a);
  206. BN_free(b);
  207. BN_free(m);
  208. BN_CTX_free(ctx);
  209. if (test_exp_mod_zero() != 0)
  210. goto err;
  211. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  212. if (CRYPTO_mem_leaks(out) <= 0)
  213. goto err;
  214. #endif
  215. BIO_free(out);
  216. printf("\n");
  217. printf("done\n");
  218. EXIT(0);
  219. err:
  220. ERR_print_errors(out);
  221. EXIT(1);
  222. }