• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2015, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #ifndef OPENSSL_HEADER_EC_ECP_NISTZ_H
16 #define OPENSSL_HEADER_EC_ECP_NISTZ_H
17 
18 #include <GFp/base.h>
19 
20 #include "../../limbs/limbs.h"
21 
22 #if defined(__GNUC__)
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wconversion"
25 #pragma GCC diagnostic ignored "-Wsign-conversion"
26 #endif
27 
28 // This function looks at `w + 1` scalar bits (`w` current, 1 adjacent less
29 // significant bit), and recodes them into a signed digit for use in fast point
30 // multiplication: the use of signed rather than unsigned digits means that
31 // fewer points need to be precomputed, given that point inversion is easy (a
32 // precomputed point dP makes -dP available as well).
33 //
34 // BACKGROUND:
35 //
36 // Signed digits for multiplication were introduced by Booth ("A signed binary
37 // multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
38 // pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
39 // Booth's original encoding did not generally improve the density of nonzero
40 // digits over the binary representation, and was merely meant to simplify the
41 // handling of signed factors given in two's complement; but it has since been
42 // shown to be the basis of various signed-digit representations that do have
43 // further advantages, including the wNAF, using the following general
44 // approach:
45 //
46 // (1) Given a binary representation
47 //
48 //       b_k  ...  b_2  b_1  b_0,
49 //
50 //     of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
51 //     by using bit-wise subtraction as follows:
52 //
53 //        b_k     b_(k-1)  ...  b_2  b_1  b_0
54 //      -         b_k      ...  b_3  b_2  b_1  b_0
55 //       -----------------------------------------
56 //        s_(k+1) s_k      ...  s_3  s_2  s_1  s_0
57 //
58 //     A left-shift followed by subtraction of the original value yields a new
59 //     representation of the same value, using signed bits s_i = b_(i-1) - b_i.
60 //     This representation from Booth's paper has since appeared in the
61 //     literature under a variety of different names including "reversed binary
62 //     form", "alternating greedy expansion", "mutual opposite form", and
63 //     "sign-alternating {+-1}-representation".
64 //
65 //     An interesting property is that among the nonzero bits, values 1 and -1
66 //     strictly alternate.
67 //
68 // (2) Various window schemes can be applied to the Booth representation of
69 //     integers: for example, right-to-left sliding windows yield the wNAF
70 //     (a signed-digit encoding independently discovered by various researchers
71 //     in the 1990s), and left-to-right sliding windows yield a left-to-right
72 //     equivalent of the wNAF (independently discovered by various researchers
73 //     around 2004).
74 //
75 // To prevent leaking information through side channels in point multiplication,
76 // we need to recode the given integer into a regular pattern: sliding windows
77 // as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
78 // decades older: we'll be using the so-called "modified Booth encoding" due to
79 // MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
80 // (1961), pp. 67-91), in a radix-2**w setting.  That is, we always combine `w`
81 // signed bits into a signed digit, e.g. (for `w == 5`):
82 //
83 //       s_(5j + 4) s_(5j + 3) s_(5j + 2) s_(5j + 1) s_(5j)
84 //
85 // The sign-alternating property implies that the resulting digit values are
86 // integers from `-2**(w-1)` to `2**(w-1)`, e.g. -16 to 16 for `w == 5`.
87 //
88 // Of course, we don't actually need to compute the signed digits s_i as an
89 // intermediate step (that's just a nice way to see how this scheme relates
90 // to the wNAF): a direct computation obtains the recoded digit from the
91 // six bits b_(5j + 4) ... b_(5j - 1).
92 //
93 // This function takes those `w` bits as an integer (e.g. 0 .. 63), writing the
94 // recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
95 // value, in the range 0 .. 2**(w-1).  Note that this integer essentially provides
96 // the input bits "shifted to the left" by one position: for example, the input
97 // to compute the least significant recoded digit, given that there's no bit
98 // b_-1, has to be b_4 b_3 b_2 b_1 b_0 0.
99 //
100 // DOUBLING CASE:
101 //
102 // Point addition formulas for short Weierstrass curves are often incomplete.
103 // Edge cases such as P + P or P + ∞ must be handled separately. This
104 // complicates constant-time requirements. P + ∞ cannot be avoided (any window
105 // may be zero) and is handled with constant-time selects. P + P (where P is not
106 // ∞) usually is not. Instead, windowing strategies are chosen to avoid this
107 // case. Whether this happens depends on the group order.
108 //
109 // Let w be the window width (in this function, w = 5). The non-trivial doubling
110 // case in single-point scalar multiplication may occur if and only if the
111 // 2^(w-1) bit of the group order is zero.
112 //
113 // Note the above only holds if the scalar is fully reduced and the group order
114 // is a prime that is much larger than 2^w. It also only holds when windows
115 // are applied from most significant to least significant, doubling between each
116 // window. It does not apply to more complex table strategies such as
117 // |EC_GFp_nistz256_method|.
118 //
119 // PROOF:
120 //
121 // Let n be the group order. Let l be the number of bits needed to represent n.
122 // Assume there exists some 0 <= k < n such that signed w-bit windowed
123 // multiplication hits the doubling case.
124 //
125 // Windowed multiplication consists of iterating over groups of s_i (defined
126 // above based on k's binary representation) from most to least significant. At
127 // iteration i (for i = ..., 3w, 2w, w, 0, starting from the most significant
128 // window), we:
129 //
130 //  1. Double the accumulator A, w times. Let A_i be the value of A at this
131 //     point.
132 //
133 //  2. Set A to T_i + A_i, where T_i is a precomputed multiple of P
134 //     corresponding to the window s_(i+w-1) ... s_i.
135 //
136 // Let j be the index such that A_j = T_j ≠ ∞. Looking at A_i and T_i as
137 // multiples of P, define a_i and t_i to be scalar coefficients of A_i and T_i.
138 // Thus a_j = t_j ≠ 0 (mod n). Note a_i and t_i may not be reduced mod n. t_i is
139 // the value of the w signed bits s_(i+w-1) ... s_i. a_i is computed as a_i =
140 // 2^w * (a_(i+w) + t_(i+w)).
141 //
142 // t_i is bounded by -2^(w-1) <= t_i <= 2^(w-1). Additionally, we may write it
143 // in terms of unsigned bits b_i. t_i consists of signed bits s_(i+w-1) ... s_i.
144 // This is computed as:
145 //
146 //         b_(i+w-2) b_(i+w-3)  ...  b_i      b_(i-1)
147 //      -  b_(i+w-1) b_(i+w-2)  ...  b_(i+1)  b_i
148 //       --------------------------------------------
149 //   t_i = s_(i+w-1) s_(i+w-2)  ...  s_(i+1)  s_i
150 //
151 // Observe that b_(i+w-2) through b_i occur in both terms. Let x be the integer
152 // represented by that bit string, i.e. 2^(w-2)*b_(i+w-2) + ... + b_i.
153 //
154 //   t_i = (2*x + b_(i-1)) - (2^(w-1)*b_(i+w-1) + x)
155 //       = x - 2^(w-1)*b_(i+w-1) + b_(i-1)
156 //
157 // Or, using C notation for bit operations:
158 //
159 //   t_i = (k>>i) & ((1<<(w-1)) - 1) - (k>>i) & (1<<(w-1)) + (k>>(i-1)) & 1
160 //
161 // Note b_(i-1) is added in left-shifted by one (or doubled) from its place.
162 // This is compensated by t_(i-w)'s subtraction term. Thus, a_i may be computed
163 // by adding b_l b_(l-1) ... b_(i+1) b_i and an extra copy of b_(i-1). In C
164 // notation, this is:
165 //
166 //   a_i = (k>>(i+w)) << w + ((k>>(i+w-1)) & 1) << w
167 //
168 // Observe that, while t_i may be positive or negative, a_i is bounded by
169 // 0 <= a_i < n + 2^w. Additionally, a_i can only be zero if b_(i+w-1) and up
170 // are all zero. (Note this implies a non-trivial P + (-P) is unreachable for
171 // all groups. That would imply the subsequent a_i is zero, which means all
172 // terms thus far were zero.)
173 //
174 // Returning to our doubling position, we have a_j = t_j (mod n). We now
175 // determine the value of a_j - t_j, which must be divisible by n. Our bounds on
176 // a_j and t_j imply a_j - t_j is 0 or n. If it is 0, a_j = t_j. However, 2^w
177 // divides a_j and -2^(w-1) <= t_j <= 2^(w-1), so this can only happen if
178 // a_j = t_j = 0, which is a trivial doubling. Therefore, a_j - t_j = n.
179 //
180 // Now we determine j. Suppose j > 0. w divides j, so j >= w. Then,
181 //
182 //   n = a_j - t_j = (k>>(j+w)) << w + ((k>>(j+w-1)) & 1) << w - t_j
183 //                <= k/2^j + 2^w - t_j
184 //                 < n/2^w + 2^w + 2^(w-1)
185 //
186 // n is much larger than 2^w, so this is impossible. Thus, j = 0: only the final
187 // addition may hit the doubling case.
188 //
189 // Finally, we consider bit patterns for n and k. Divide k into k_H + k_M + k_L
190 // such that k_H is the contribution from b_(l-1) .. b_w, k_M is the
191 // contribution from b_(w-1), and k_L is the contribution from b_(w-2) ... b_0.
192 // That is:
193 //
194 // - 2^w divides k_H
195 // - k_M is 0 or 2^(w-1)
196 // - 0 <= k_L < 2^(w-1)
197 //
198 // Divide n into n_H + n_M + n_L similarly. We thus have:
199 //
200 //   t_0 = (k>>0) & ((1<<(w-1)) - 1) - (k>>0) & (1<<(w-1)) + (k>>(0-1)) & 1
201 //       = k & ((1<<(w-1)) - 1) - k & (1<<(w-1))
202 //       = k_L - k_M
203 //
204 //   a_0 = (k>>(0+w)) << w + ((k>>(0+w-1)) & 1) << w
205 //       = (k>>w) << w + ((k>>(w-1)) & 1) << w
206 //       = k_H + 2*k_M
207 //
208 //                 n = a_0 - t_0
209 //   n_H + n_M + n_L = (k_H + 2*k_M) - (k_L - k_M)
210 //                   = k_H + 3*k_M - k_L
211 //
212 // k_H - k_L < k and k < n, so k_H - k_L ≠ n. Therefore k_M is not 0 and must be
213 // 2^(w-1). Now we consider k_H and n_H. We know k_H <= n_H. Suppose k_H = n_H.
214 // Then,
215 //
216 //   n_M + n_L = 3*(2^(w-1)) - k_L
217 //             > 3*(2^(w-1)) - 2^(w-1)
218 //             = 2^w
219 //
220 // Contradiction (n_M + n_L is the bottom w bits of n). Thus k_H < n_H. Suppose
221 // k_H < n_H - 2*2^w. Then,
222 //
223 //   n_H + n_M + n_L = k_H + 3*(2^(w-1)) - k_L
224 //                   < n_H - 2*2^w + 3*(2^(w-1)) - k_L
225 //         n_M + n_L < -2^(w-1) - k_L
226 //
227 // Contradiction. Thus, k_H = n_H - 2^w. (Note 2^w divides n_H and k_H.) Thus,
228 //
229 //   n_H + n_M + n_L = k_H + 3*(2^(w-1)) - k_L
230 //                   = n_H - 2^w + 3*(2^(w-1)) - k_L
231 //         n_M + n_L = 2^(w-1) - k_L
232 //                  <= 2^(w-1)
233 //
234 // Equality would mean 2^(w-1) divides n, which is impossible if n is prime.
235 // Thus n_M + n_L < 2^(w-1), so n_M is zero, proving our condition.
236 //
237 // This proof constructs k, so, to show the converse, let k_H = n_H - 2^w,
238 // k_M = 2^(w-1), k_L = 2^(w-1) - n_L. This will result in a non-trivial point
239 // doubling in the final addition and is the only such scalar.
240 //
241 // COMMON CURVES:
242 //
243 // The group orders for common curves end in the following bit patterns:
244 //
245 //   P-521: ...00001001; w = 4 is okay
246 //   P-384: ...01110011; w = 2, 5, 6, 7 are okay
247 //   P-256: ...01010001; w = 5, 7 are okay
248 //   P-224: ...00111101; w = 3, 4, 5, 6 are okay
booth_recode(crypto_word * is_negative,crypto_word * digit,crypto_word in,crypto_word w)249 static inline void booth_recode(crypto_word *is_negative, crypto_word *digit,
250                                 crypto_word in, crypto_word w) {
251   debug_assert_nonsecret(w >= 2);
252   debug_assert_nonsecret(w <= 7);
253 
254   // Set all bits of `s` to MSB(in), similar to |constant_time_msb_s|,
255   // but 'in' seen as (`w+1`)-bit value.
256   crypto_word s = ~((in >> w) - 1);
257   crypto_word d;
258   d = ((crypto_word)1u << (w + 1)) - in - 1;
259   d = (d & s) | (in & ~s);
260   d = (d >> 1) + (d & 1);
261 
262   *is_negative = constant_time_is_nonzero_w(s & 1);
263   *digit = d;
264 }
265 
266 #if defined(__GNUC__)
267 #pragma GCC diagnostic pop
268 #endif
269 
270 void gfp_little_endian_bytes_from_scalar(uint8_t str[], size_t str_len,
271                                          const Limb scalar[],
272                                          size_t num_limbs);
273 
274 #endif // OPENSSL_HEADER_EC_ECP_NISTZ_H
275