bn_intern.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (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 "internal/cryptlib.h"
  10. #include "bn_local.h"
  11. /*
  12. * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
  13. * This is an array r[] of values that are either zero or odd with an
  14. * absolute value less than 2^w satisfying
  15. * scalar = \sum_j r[j]*2^j
  16. * where at most one of any w+1 consecutive digits is non-zero
  17. * with the exception that the most significant digit may be only
  18. * w-1 zeros away from that next non-zero digit.
  19. */
  20. signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
  21. {
  22. int window_val;
  23. signed char *r = NULL;
  24. int sign = 1;
  25. int bit, next_bit, mask;
  26. size_t len = 0, j;
  27. if (BN_is_zero(scalar)) {
  28. r = OPENSSL_malloc(1);
  29. if (r == NULL)
  30. goto err;
  31. r[0] = 0;
  32. *ret_len = 1;
  33. return r;
  34. }
  35. if (w <= 0 || w > 7) { /* 'signed char' can represent integers with
  36. * absolute values less than 2^7 */
  37. ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR);
  38. goto err;
  39. }
  40. bit = 1 << w; /* at most 128 */
  41. next_bit = bit << 1; /* at most 256 */
  42. mask = next_bit - 1; /* at most 255 */
  43. if (BN_is_negative(scalar)) {
  44. sign = -1;
  45. }
  46. if (scalar->d == NULL || scalar->top == 0) {
  47. ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR);
  48. goto err;
  49. }
  50. len = BN_num_bits(scalar);
  51. r = OPENSSL_malloc(len + 1); /*
  52. * Modified wNAF may be one digit longer than binary representation
  53. * (*ret_len will be set to the actual length, i.e. at most
  54. * BN_num_bits(scalar) + 1)
  55. */
  56. if (r == NULL)
  57. goto err;
  58. window_val = scalar->d[0] & mask;
  59. j = 0;
  60. while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len,
  61. * window_val will not
  62. * increase */
  63. int digit = 0;
  64. /* 0 <= window_val <= 2^(w+1) */
  65. if (window_val & 1) {
  66. /* 0 < window_val < 2^(w+1) */
  67. if (window_val & bit) {
  68. digit = window_val - next_bit; /* -2^w < digit < 0 */
  69. #if 1 /* modified wNAF */
  70. if (j + w + 1 >= len) {
  71. /*
  72. * Special case for generating modified wNAFs:
  73. * no new bits will be added into window_val,
  74. * so using a positive digit here will decrease
  75. * the total length of the representation
  76. */
  77. digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
  78. }
  79. #endif
  80. } else {
  81. digit = window_val; /* 0 < digit < 2^w */
  82. }
  83. if (digit <= -bit || digit >= bit || !(digit & 1)) {
  84. ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR);
  85. goto err;
  86. }
  87. window_val -= digit;
  88. /*
  89. * now window_val is 0 or 2^(w+1) in standard wNAF generation;
  90. * for modified window NAFs, it may also be 2^w
  91. */
  92. if (window_val != 0 && window_val != next_bit
  93. && window_val != bit) {
  94. ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR);
  95. goto err;
  96. }
  97. }
  98. r[j++] = sign * digit;
  99. window_val >>= 1;
  100. window_val += bit * BN_is_bit_set(scalar, j + w);
  101. if (window_val > next_bit) {
  102. ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR);
  103. goto err;
  104. }
  105. }
  106. if (j > len + 1) {
  107. ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR);
  108. goto err;
  109. }
  110. *ret_len = j;
  111. return r;
  112. err:
  113. OPENSSL_free(r);
  114. return NULL;
  115. }
  116. int bn_get_top(const BIGNUM *a)
  117. {
  118. return a->top;
  119. }
  120. int bn_get_dmax(const BIGNUM *a)
  121. {
  122. return a->dmax;
  123. }
  124. void bn_set_all_zero(BIGNUM *a)
  125. {
  126. int i;
  127. for (i = a->top; i < a->dmax; i++)
  128. a->d[i] = 0;
  129. }
  130. int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size)
  131. {
  132. if (in->top > size)
  133. return 0;
  134. memset(out, 0, sizeof(*out) * size);
  135. if (in->d != NULL)
  136. memcpy(out, in->d, sizeof(*out) * in->top);
  137. return 1;
  138. }
  139. BN_ULONG *bn_get_words(const BIGNUM *a)
  140. {
  141. return a->d;
  142. }
  143. void bn_set_static_words(BIGNUM *a, const BN_ULONG *words, int size)
  144. {
  145. /*
  146. * |const| qualifier omission is compensated by BN_FLG_STATIC_DATA
  147. * flag, which effectively means "read-only data".
  148. */
  149. a->d = (BN_ULONG *)words;
  150. a->dmax = a->top = size;
  151. a->neg = 0;
  152. a->flags |= BN_FLG_STATIC_DATA;
  153. bn_correct_top(a);
  154. }
  155. int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words)
  156. {
  157. if (bn_wexpand(a, num_words) == NULL) {
  158. ERR_raise(ERR_LIB_BN, ERR_R_BN_LIB);
  159. return 0;
  160. }
  161. memcpy(a->d, words, sizeof(BN_ULONG) * num_words);
  162. a->top = num_words;
  163. bn_correct_top(a);
  164. return 1;
  165. }