bn_intern.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* ====================================================================
  2. * Copyright (c) 1998-2014 The OpenSSL Project. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * openssl-core@openssl.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This product includes cryptographic software written by Eric Young
  50. * (eay@cryptsoft.com). This product includes software written by Tim
  51. * Hudson (tjh@cryptsoft.com).
  52. *
  53. */
  54. #include "internal/cryptlib.h"
  55. #include "bn_lcl.h"
  56. /*
  57. * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
  58. * This is an array r[] of values that are either zero or odd with an
  59. * absolute value less than 2^w satisfying
  60. * scalar = \sum_j r[j]*2^j
  61. * where at most one of any w+1 consecutive digits is non-zero
  62. * with the exception that the most significant digit may be only
  63. * w-1 zeros away from that next non-zero digit.
  64. */
  65. signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
  66. {
  67. int window_val;
  68. signed char *r = NULL;
  69. int sign = 1;
  70. int bit, next_bit, mask;
  71. size_t len = 0, j;
  72. if (BN_is_zero(scalar)) {
  73. r = OPENSSL_malloc(1);
  74. if (!r) {
  75. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
  76. goto err;
  77. }
  78. r[0] = 0;
  79. *ret_len = 1;
  80. return r;
  81. }
  82. if (w <= 0 || w > 7) { /* 'signed char' can represent integers with
  83. * absolute values less than 2^7 */
  84. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
  85. goto err;
  86. }
  87. bit = 1 << w; /* at most 128 */
  88. next_bit = bit << 1; /* at most 256 */
  89. mask = next_bit - 1; /* at most 255 */
  90. if (BN_is_negative(scalar)) {
  91. sign = -1;
  92. }
  93. if (scalar->d == NULL || scalar->top == 0) {
  94. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
  95. goto err;
  96. }
  97. len = BN_num_bits(scalar);
  98. r = OPENSSL_malloc(len + 1); /*
  99. * Modified wNAF may be one digit longer than binary representation
  100. * (*ret_len will be set to the actual length, i.e. at most
  101. * BN_num_bits(scalar) + 1)
  102. */
  103. if (r == NULL) {
  104. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
  105. goto err;
  106. }
  107. window_val = scalar->d[0] & mask;
  108. j = 0;
  109. while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len,
  110. * window_val will not
  111. * increase */
  112. int digit = 0;
  113. /* 0 <= window_val <= 2^(w+1) */
  114. if (window_val & 1) {
  115. /* 0 < window_val < 2^(w+1) */
  116. if (window_val & bit) {
  117. digit = window_val - next_bit; /* -2^w < digit < 0 */
  118. #if 1 /* modified wNAF */
  119. if (j + w + 1 >= len) {
  120. /*
  121. * Special case for generating modified wNAFs:
  122. * no new bits will be added into window_val,
  123. * so using a positive digit here will decrease
  124. * the total length of the representation
  125. */
  126. digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
  127. }
  128. #endif
  129. } else {
  130. digit = window_val; /* 0 < digit < 2^w */
  131. }
  132. if (digit <= -bit || digit >= bit || !(digit & 1)) {
  133. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
  134. goto err;
  135. }
  136. window_val -= digit;
  137. /*
  138. * now window_val is 0 or 2^(w+1) in standard wNAF generation;
  139. * for modified window NAFs, it may also be 2^w
  140. */
  141. if (window_val != 0 && window_val != next_bit
  142. && window_val != bit) {
  143. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
  144. goto err;
  145. }
  146. }
  147. r[j++] = sign * digit;
  148. window_val >>= 1;
  149. window_val += bit * BN_is_bit_set(scalar, j + w);
  150. if (window_val > next_bit) {
  151. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
  152. goto err;
  153. }
  154. }
  155. if (j > len + 1) {
  156. BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
  157. goto err;
  158. }
  159. *ret_len = j;
  160. return r;
  161. err:
  162. OPENSSL_free(r);
  163. return NULL;
  164. }
  165. int bn_get_top(const BIGNUM *a)
  166. {
  167. return a->top;
  168. }
  169. void bn_set_top(BIGNUM *a, int top)
  170. {
  171. a->top = top;
  172. }
  173. int bn_get_dmax(const BIGNUM *a)
  174. {
  175. return a->dmax;
  176. }
  177. void bn_set_all_zero(BIGNUM *a)
  178. {
  179. int i;
  180. for (i = a->top; i < a->dmax; i++)
  181. a->d[i] = 0;
  182. }
  183. int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size)
  184. {
  185. if (in->top > size)
  186. return 0;
  187. memset(out, 0, sizeof(*out) * size);
  188. memcpy(out, in->d, sizeof(*out) * in->top);
  189. return 1;
  190. }
  191. BN_ULONG *bn_get_words(const BIGNUM *a)
  192. {
  193. return a->d;
  194. }
  195. void bn_set_static_words(BIGNUM *a, BN_ULONG *words, int size)
  196. {
  197. a->d = words;
  198. a->dmax = a->top = size;
  199. a->neg = 0;
  200. a->flags |= BN_FLG_STATIC_DATA;
  201. bn_correct_top(a);
  202. }
  203. int bn_set_words(BIGNUM *a, BN_ULONG *words, int num_words)
  204. {
  205. if (bn_wexpand(a, num_words) == NULL) {
  206. BNerr(BN_F_BN_SET_WORDS, ERR_R_MALLOC_FAILURE);
  207. return 0;
  208. }
  209. memcpy(a->d, words, sizeof(BN_ULONG) * num_words);
  210. a->top = num_words;
  211. bn_correct_top(a);
  212. return 1;
  213. }
  214. size_t bn_sizeof_BIGNUM(void)
  215. {
  216. return sizeof(BIGNUM);
  217. }
  218. BIGNUM *bn_array_el(BIGNUM *base, int el)
  219. {
  220. return &base[el];
  221. }