1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* Copyright 2011 Google Inc. 11e1051a39Sopenharmony_ci * 12e1051a39Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 13e1051a39Sopenharmony_ci * 14e1051a39Sopenharmony_ci * you may not use this file except in compliance with the License. 15e1051a39Sopenharmony_ci * You may obtain a copy of the License at 16e1051a39Sopenharmony_ci * 17e1051a39Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 18e1051a39Sopenharmony_ci * 19e1051a39Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 20e1051a39Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 21e1051a39Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22e1051a39Sopenharmony_ci * See the License for the specific language governing permissions and 23e1051a39Sopenharmony_ci * limitations under the License. 24e1051a39Sopenharmony_ci */ 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci/* 27e1051a39Sopenharmony_ci * ECDSA low level APIs are deprecated for public use, but still ok for 28e1051a39Sopenharmony_ci * internal use. 29e1051a39Sopenharmony_ci */ 30e1051a39Sopenharmony_ci#include "internal/deprecated.h" 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci#include <openssl/opensslconf.h> 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ci/* 35e1051a39Sopenharmony_ci * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. 36e1051a39Sopenharmony_ci */ 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci#include <stddef.h> 39e1051a39Sopenharmony_ci#include "ec_local.h" 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci/* 42e1051a39Sopenharmony_ci * Convert an array of points into affine coordinates. (If the point at 43e1051a39Sopenharmony_ci * infinity is found (Z = 0), it remains unchanged.) This function is 44e1051a39Sopenharmony_ci * essentially an equivalent to EC_POINTs_make_affine(), but works with the 45e1051a39Sopenharmony_ci * internal representation of points as used by ecp_nistp###.c rather than 46e1051a39Sopenharmony_ci * with (BIGNUM-based) EC_POINT data structures. point_array is the 47e1051a39Sopenharmony_ci * input/output buffer ('num' points in projective form, i.e. three 48e1051a39Sopenharmony_ci * coordinates each), based on an internal representation of field elements 49e1051a39Sopenharmony_ci * of size 'felem_size'. tmp_felems needs to point to a temporary array of 50e1051a39Sopenharmony_ci * 'num'+1 field elements for storage of intermediate values. 51e1051a39Sopenharmony_ci */ 52e1051a39Sopenharmony_civoid 53e1051a39Sopenharmony_ciossl_ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, 54e1051a39Sopenharmony_ci size_t felem_size, 55e1051a39Sopenharmony_ci void *tmp_felems, 56e1051a39Sopenharmony_ci void (*felem_one) (void *out), 57e1051a39Sopenharmony_ci int (*felem_is_zero) (const void 58e1051a39Sopenharmony_ci *in), 59e1051a39Sopenharmony_ci void (*felem_assign) (void *out, 60e1051a39Sopenharmony_ci const void 61e1051a39Sopenharmony_ci *in), 62e1051a39Sopenharmony_ci void (*felem_square) (void *out, 63e1051a39Sopenharmony_ci const void 64e1051a39Sopenharmony_ci *in), 65e1051a39Sopenharmony_ci void (*felem_mul) (void *out, 66e1051a39Sopenharmony_ci const void 67e1051a39Sopenharmony_ci *in1, 68e1051a39Sopenharmony_ci const void 69e1051a39Sopenharmony_ci *in2), 70e1051a39Sopenharmony_ci void (*felem_inv) (void *out, 71e1051a39Sopenharmony_ci const void 72e1051a39Sopenharmony_ci *in), 73e1051a39Sopenharmony_ci void (*felem_contract) (void 74e1051a39Sopenharmony_ci *out, 75e1051a39Sopenharmony_ci const 76e1051a39Sopenharmony_ci void 77e1051a39Sopenharmony_ci *in)) 78e1051a39Sopenharmony_ci{ 79e1051a39Sopenharmony_ci int i = 0; 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ci#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) 82e1051a39Sopenharmony_ci#define X(I) (&((char *)point_array)[3*(I) * felem_size]) 83e1051a39Sopenharmony_ci#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) 84e1051a39Sopenharmony_ci#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci if (!felem_is_zero(Z(0))) 87e1051a39Sopenharmony_ci felem_assign(tmp_felem(0), Z(0)); 88e1051a39Sopenharmony_ci else 89e1051a39Sopenharmony_ci felem_one(tmp_felem(0)); 90e1051a39Sopenharmony_ci for (i = 1; i < (int)num; i++) { 91e1051a39Sopenharmony_ci if (!felem_is_zero(Z(i))) 92e1051a39Sopenharmony_ci felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i)); 93e1051a39Sopenharmony_ci else 94e1051a39Sopenharmony_ci felem_assign(tmp_felem(i), tmp_felem(i - 1)); 95e1051a39Sopenharmony_ci } 96e1051a39Sopenharmony_ci /* 97e1051a39Sopenharmony_ci * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any 98e1051a39Sopenharmony_ci * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1 99e1051a39Sopenharmony_ci */ 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci felem_inv(tmp_felem(num - 1), tmp_felem(num - 1)); 102e1051a39Sopenharmony_ci for (i = num - 1; i >= 0; i--) { 103e1051a39Sopenharmony_ci if (i > 0) 104e1051a39Sopenharmony_ci /* 105e1051a39Sopenharmony_ci * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i) 106e1051a39Sopenharmony_ci * is the inverse of the product of Z(0) .. Z(i) 107e1051a39Sopenharmony_ci */ 108e1051a39Sopenharmony_ci /* 1/Z(i) */ 109e1051a39Sopenharmony_ci felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i)); 110e1051a39Sopenharmony_ci else 111e1051a39Sopenharmony_ci felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */ 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci if (!felem_is_zero(Z(i))) { 114e1051a39Sopenharmony_ci if (i > 0) 115e1051a39Sopenharmony_ci /* 116e1051a39Sopenharmony_ci * For next iteration, replace tmp_felem(i-1) by its inverse 117e1051a39Sopenharmony_ci */ 118e1051a39Sopenharmony_ci felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i)); 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci /* 121e1051a39Sopenharmony_ci * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) 122e1051a39Sopenharmony_ci */ 123e1051a39Sopenharmony_ci felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */ 124e1051a39Sopenharmony_ci felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */ 125e1051a39Sopenharmony_ci felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */ 126e1051a39Sopenharmony_ci felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */ 127e1051a39Sopenharmony_ci felem_contract(X(i), X(i)); 128e1051a39Sopenharmony_ci felem_contract(Y(i), Y(i)); 129e1051a39Sopenharmony_ci felem_one(Z(i)); 130e1051a39Sopenharmony_ci } else { 131e1051a39Sopenharmony_ci if (i > 0) 132e1051a39Sopenharmony_ci /* 133e1051a39Sopenharmony_ci * For next iteration, replace tmp_felem(i-1) by its inverse 134e1051a39Sopenharmony_ci */ 135e1051a39Sopenharmony_ci felem_assign(tmp_felem(i - 1), tmp_felem(i)); 136e1051a39Sopenharmony_ci } 137e1051a39Sopenharmony_ci } 138e1051a39Sopenharmony_ci} 139e1051a39Sopenharmony_ci 140e1051a39Sopenharmony_ci/*- 141e1051a39Sopenharmony_ci * This function looks at 5+1 scalar bits (5 current, 1 adjacent less 142e1051a39Sopenharmony_ci * significant bit), and recodes them into a signed digit for use in fast point 143e1051a39Sopenharmony_ci * multiplication: the use of signed rather than unsigned digits means that 144e1051a39Sopenharmony_ci * fewer points need to be precomputed, given that point inversion is easy 145e1051a39Sopenharmony_ci * (a precomputed point dP makes -dP available as well). 146e1051a39Sopenharmony_ci * 147e1051a39Sopenharmony_ci * BACKGROUND: 148e1051a39Sopenharmony_ci * 149e1051a39Sopenharmony_ci * Signed digits for multiplication were introduced by Booth ("A signed binary 150e1051a39Sopenharmony_ci * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, 151e1051a39Sopenharmony_ci * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. 152e1051a39Sopenharmony_ci * Booth's original encoding did not generally improve the density of nonzero 153e1051a39Sopenharmony_ci * digits over the binary representation, and was merely meant to simplify the 154e1051a39Sopenharmony_ci * handling of signed factors given in two's complement; but it has since been 155e1051a39Sopenharmony_ci * shown to be the basis of various signed-digit representations that do have 156e1051a39Sopenharmony_ci * further advantages, including the wNAF, using the following general approach: 157e1051a39Sopenharmony_ci * 158e1051a39Sopenharmony_ci * (1) Given a binary representation 159e1051a39Sopenharmony_ci * 160e1051a39Sopenharmony_ci * b_k ... b_2 b_1 b_0, 161e1051a39Sopenharmony_ci * 162e1051a39Sopenharmony_ci * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 163e1051a39Sopenharmony_ci * by using bit-wise subtraction as follows: 164e1051a39Sopenharmony_ci * 165e1051a39Sopenharmony_ci * b_k b_(k-1) ... b_2 b_1 b_0 166e1051a39Sopenharmony_ci * - b_k ... b_3 b_2 b_1 b_0 167e1051a39Sopenharmony_ci * ----------------------------------------- 168e1051a39Sopenharmony_ci * s_(k+1) s_k ... s_3 s_2 s_1 s_0 169e1051a39Sopenharmony_ci * 170e1051a39Sopenharmony_ci * A left-shift followed by subtraction of the original value yields a new 171e1051a39Sopenharmony_ci * representation of the same value, using signed bits s_i = b_(i-1) - b_i. 172e1051a39Sopenharmony_ci * This representation from Booth's paper has since appeared in the 173e1051a39Sopenharmony_ci * literature under a variety of different names including "reversed binary 174e1051a39Sopenharmony_ci * form", "alternating greedy expansion", "mutual opposite form", and 175e1051a39Sopenharmony_ci * "sign-alternating {+-1}-representation". 176e1051a39Sopenharmony_ci * 177e1051a39Sopenharmony_ci * An interesting property is that among the nonzero bits, values 1 and -1 178e1051a39Sopenharmony_ci * strictly alternate. 179e1051a39Sopenharmony_ci * 180e1051a39Sopenharmony_ci * (2) Various window schemes can be applied to the Booth representation of 181e1051a39Sopenharmony_ci * integers: for example, right-to-left sliding windows yield the wNAF 182e1051a39Sopenharmony_ci * (a signed-digit encoding independently discovered by various researchers 183e1051a39Sopenharmony_ci * in the 1990s), and left-to-right sliding windows yield a left-to-right 184e1051a39Sopenharmony_ci * equivalent of the wNAF (independently discovered by various researchers 185e1051a39Sopenharmony_ci * around 2004). 186e1051a39Sopenharmony_ci * 187e1051a39Sopenharmony_ci * To prevent leaking information through side channels in point multiplication, 188e1051a39Sopenharmony_ci * we need to recode the given integer into a regular pattern: sliding windows 189e1051a39Sopenharmony_ci * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few 190e1051a39Sopenharmony_ci * decades older: we'll be using the so-called "modified Booth encoding" due to 191e1051a39Sopenharmony_ci * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 192e1051a39Sopenharmony_ci * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five 193e1051a39Sopenharmony_ci * signed bits into a signed digit: 194e1051a39Sopenharmony_ci * 195e1051a39Sopenharmony_ci * s_(5j + 4) s_(5j + 3) s_(5j + 2) s_(5j + 1) s_(5j) 196e1051a39Sopenharmony_ci * 197e1051a39Sopenharmony_ci * The sign-alternating property implies that the resulting digit values are 198e1051a39Sopenharmony_ci * integers from -16 to 16. 199e1051a39Sopenharmony_ci * 200e1051a39Sopenharmony_ci * Of course, we don't actually need to compute the signed digits s_i as an 201e1051a39Sopenharmony_ci * intermediate step (that's just a nice way to see how this scheme relates 202e1051a39Sopenharmony_ci * to the wNAF): a direct computation obtains the recoded digit from the 203e1051a39Sopenharmony_ci * six bits b_(5j + 4) ... b_(5j - 1). 204e1051a39Sopenharmony_ci * 205e1051a39Sopenharmony_ci * This function takes those six bits as an integer (0 .. 63), writing the 206e1051a39Sopenharmony_ci * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute 207e1051a39Sopenharmony_ci * value, in the range 0 .. 16). Note that this integer essentially provides 208e1051a39Sopenharmony_ci * the input bits "shifted to the left" by one position: for example, the input 209e1051a39Sopenharmony_ci * to compute the least significant recoded digit, given that there's no bit 210e1051a39Sopenharmony_ci * b_-1, has to be b_4 b_3 b_2 b_1 b_0 0. 211e1051a39Sopenharmony_ci * 212e1051a39Sopenharmony_ci */ 213e1051a39Sopenharmony_civoid ossl_ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, 214e1051a39Sopenharmony_ci unsigned char *digit, unsigned char in) 215e1051a39Sopenharmony_ci{ 216e1051a39Sopenharmony_ci unsigned char s, d; 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as 219e1051a39Sopenharmony_ci * 6-bit value */ 220e1051a39Sopenharmony_ci d = (1 << 6) - in - 1; 221e1051a39Sopenharmony_ci d = (d & s) | (in & ~s); 222e1051a39Sopenharmony_ci d = (d >> 1) + (d & 1); 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci *sign = s & 1; 225e1051a39Sopenharmony_ci *digit = d; 226e1051a39Sopenharmony_ci} 227