11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 51cb0ef41Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 61cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at 71cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html 81cb0ef41Sopenharmony_ci */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci/* Copyright 2011 Google Inc. 111cb0ef41Sopenharmony_ci * 121cb0ef41Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 131cb0ef41Sopenharmony_ci * 141cb0ef41Sopenharmony_ci * you may not use this file except in compliance with the License. 151cb0ef41Sopenharmony_ci * You may obtain a copy of the License at 161cb0ef41Sopenharmony_ci * 171cb0ef41Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 181cb0ef41Sopenharmony_ci * 191cb0ef41Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 201cb0ef41Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 211cb0ef41Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 221cb0ef41Sopenharmony_ci * See the License for the specific language governing permissions and 231cb0ef41Sopenharmony_ci * limitations under the License. 241cb0ef41Sopenharmony_ci */ 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci/* 271cb0ef41Sopenharmony_ci * ECDSA low level APIs are deprecated for public use, but still ok for 281cb0ef41Sopenharmony_ci * internal use. 291cb0ef41Sopenharmony_ci */ 301cb0ef41Sopenharmony_ci#include "internal/deprecated.h" 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#include <openssl/opensslconf.h> 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci/* 351cb0ef41Sopenharmony_ci * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. 361cb0ef41Sopenharmony_ci */ 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci#include <stddef.h> 391cb0ef41Sopenharmony_ci#include "ec_local.h" 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci/* 421cb0ef41Sopenharmony_ci * Convert an array of points into affine coordinates. (If the point at 431cb0ef41Sopenharmony_ci * infinity is found (Z = 0), it remains unchanged.) This function is 441cb0ef41Sopenharmony_ci * essentially an equivalent to EC_POINTs_make_affine(), but works with the 451cb0ef41Sopenharmony_ci * internal representation of points as used by ecp_nistp###.c rather than 461cb0ef41Sopenharmony_ci * with (BIGNUM-based) EC_POINT data structures. point_array is the 471cb0ef41Sopenharmony_ci * input/output buffer ('num' points in projective form, i.e. three 481cb0ef41Sopenharmony_ci * coordinates each), based on an internal representation of field elements 491cb0ef41Sopenharmony_ci * of size 'felem_size'. tmp_felems needs to point to a temporary array of 501cb0ef41Sopenharmony_ci * 'num'+1 field elements for storage of intermediate values. 511cb0ef41Sopenharmony_ci */ 521cb0ef41Sopenharmony_civoid 531cb0ef41Sopenharmony_ciossl_ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, 541cb0ef41Sopenharmony_ci size_t felem_size, 551cb0ef41Sopenharmony_ci void *tmp_felems, 561cb0ef41Sopenharmony_ci void (*felem_one) (void *out), 571cb0ef41Sopenharmony_ci int (*felem_is_zero) (const void 581cb0ef41Sopenharmony_ci *in), 591cb0ef41Sopenharmony_ci void (*felem_assign) (void *out, 601cb0ef41Sopenharmony_ci const void 611cb0ef41Sopenharmony_ci *in), 621cb0ef41Sopenharmony_ci void (*felem_square) (void *out, 631cb0ef41Sopenharmony_ci const void 641cb0ef41Sopenharmony_ci *in), 651cb0ef41Sopenharmony_ci void (*felem_mul) (void *out, 661cb0ef41Sopenharmony_ci const void 671cb0ef41Sopenharmony_ci *in1, 681cb0ef41Sopenharmony_ci const void 691cb0ef41Sopenharmony_ci *in2), 701cb0ef41Sopenharmony_ci void (*felem_inv) (void *out, 711cb0ef41Sopenharmony_ci const void 721cb0ef41Sopenharmony_ci *in), 731cb0ef41Sopenharmony_ci void (*felem_contract) (void 741cb0ef41Sopenharmony_ci *out, 751cb0ef41Sopenharmony_ci const 761cb0ef41Sopenharmony_ci void 771cb0ef41Sopenharmony_ci *in)) 781cb0ef41Sopenharmony_ci{ 791cb0ef41Sopenharmony_ci int i = 0; 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) 821cb0ef41Sopenharmony_ci#define X(I) (&((char *)point_array)[3*(I) * felem_size]) 831cb0ef41Sopenharmony_ci#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) 841cb0ef41Sopenharmony_ci#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci if (!felem_is_zero(Z(0))) 871cb0ef41Sopenharmony_ci felem_assign(tmp_felem(0), Z(0)); 881cb0ef41Sopenharmony_ci else 891cb0ef41Sopenharmony_ci felem_one(tmp_felem(0)); 901cb0ef41Sopenharmony_ci for (i = 1; i < (int)num; i++) { 911cb0ef41Sopenharmony_ci if (!felem_is_zero(Z(i))) 921cb0ef41Sopenharmony_ci felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i)); 931cb0ef41Sopenharmony_ci else 941cb0ef41Sopenharmony_ci felem_assign(tmp_felem(i), tmp_felem(i - 1)); 951cb0ef41Sopenharmony_ci } 961cb0ef41Sopenharmony_ci /* 971cb0ef41Sopenharmony_ci * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any 981cb0ef41Sopenharmony_ci * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1 991cb0ef41Sopenharmony_ci */ 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci felem_inv(tmp_felem(num - 1), tmp_felem(num - 1)); 1021cb0ef41Sopenharmony_ci for (i = num - 1; i >= 0; i--) { 1031cb0ef41Sopenharmony_ci if (i > 0) 1041cb0ef41Sopenharmony_ci /* 1051cb0ef41Sopenharmony_ci * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i) 1061cb0ef41Sopenharmony_ci * is the inverse of the product of Z(0) .. Z(i) 1071cb0ef41Sopenharmony_ci */ 1081cb0ef41Sopenharmony_ci /* 1/Z(i) */ 1091cb0ef41Sopenharmony_ci felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i)); 1101cb0ef41Sopenharmony_ci else 1111cb0ef41Sopenharmony_ci felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */ 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci if (!felem_is_zero(Z(i))) { 1141cb0ef41Sopenharmony_ci if (i > 0) 1151cb0ef41Sopenharmony_ci /* 1161cb0ef41Sopenharmony_ci * For next iteration, replace tmp_felem(i-1) by its inverse 1171cb0ef41Sopenharmony_ci */ 1181cb0ef41Sopenharmony_ci felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i)); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci /* 1211cb0ef41Sopenharmony_ci * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) 1221cb0ef41Sopenharmony_ci */ 1231cb0ef41Sopenharmony_ci felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */ 1241cb0ef41Sopenharmony_ci felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */ 1251cb0ef41Sopenharmony_ci felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */ 1261cb0ef41Sopenharmony_ci felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */ 1271cb0ef41Sopenharmony_ci felem_contract(X(i), X(i)); 1281cb0ef41Sopenharmony_ci felem_contract(Y(i), Y(i)); 1291cb0ef41Sopenharmony_ci felem_one(Z(i)); 1301cb0ef41Sopenharmony_ci } else { 1311cb0ef41Sopenharmony_ci if (i > 0) 1321cb0ef41Sopenharmony_ci /* 1331cb0ef41Sopenharmony_ci * For next iteration, replace tmp_felem(i-1) by its inverse 1341cb0ef41Sopenharmony_ci */ 1351cb0ef41Sopenharmony_ci felem_assign(tmp_felem(i - 1), tmp_felem(i)); 1361cb0ef41Sopenharmony_ci } 1371cb0ef41Sopenharmony_ci } 1381cb0ef41Sopenharmony_ci} 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci/*- 1411cb0ef41Sopenharmony_ci * This function looks at 5+1 scalar bits (5 current, 1 adjacent less 1421cb0ef41Sopenharmony_ci * significant bit), and recodes them into a signed digit for use in fast point 1431cb0ef41Sopenharmony_ci * multiplication: the use of signed rather than unsigned digits means that 1441cb0ef41Sopenharmony_ci * fewer points need to be precomputed, given that point inversion is easy 1451cb0ef41Sopenharmony_ci * (a precomputed point dP makes -dP available as well). 1461cb0ef41Sopenharmony_ci * 1471cb0ef41Sopenharmony_ci * BACKGROUND: 1481cb0ef41Sopenharmony_ci * 1491cb0ef41Sopenharmony_ci * Signed digits for multiplication were introduced by Booth ("A signed binary 1501cb0ef41Sopenharmony_ci * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, 1511cb0ef41Sopenharmony_ci * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. 1521cb0ef41Sopenharmony_ci * Booth's original encoding did not generally improve the density of nonzero 1531cb0ef41Sopenharmony_ci * digits over the binary representation, and was merely meant to simplify the 1541cb0ef41Sopenharmony_ci * handling of signed factors given in two's complement; but it has since been 1551cb0ef41Sopenharmony_ci * shown to be the basis of various signed-digit representations that do have 1561cb0ef41Sopenharmony_ci * further advantages, including the wNAF, using the following general approach: 1571cb0ef41Sopenharmony_ci * 1581cb0ef41Sopenharmony_ci * (1) Given a binary representation 1591cb0ef41Sopenharmony_ci * 1601cb0ef41Sopenharmony_ci * b_k ... b_2 b_1 b_0, 1611cb0ef41Sopenharmony_ci * 1621cb0ef41Sopenharmony_ci * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 1631cb0ef41Sopenharmony_ci * by using bit-wise subtraction as follows: 1641cb0ef41Sopenharmony_ci * 1651cb0ef41Sopenharmony_ci * b_k b_(k-1) ... b_2 b_1 b_0 1661cb0ef41Sopenharmony_ci * - b_k ... b_3 b_2 b_1 b_0 1671cb0ef41Sopenharmony_ci * ----------------------------------------- 1681cb0ef41Sopenharmony_ci * s_(k+1) s_k ... s_3 s_2 s_1 s_0 1691cb0ef41Sopenharmony_ci * 1701cb0ef41Sopenharmony_ci * A left-shift followed by subtraction of the original value yields a new 1711cb0ef41Sopenharmony_ci * representation of the same value, using signed bits s_i = b_(i-1) - b_i. 1721cb0ef41Sopenharmony_ci * This representation from Booth's paper has since appeared in the 1731cb0ef41Sopenharmony_ci * literature under a variety of different names including "reversed binary 1741cb0ef41Sopenharmony_ci * form", "alternating greedy expansion", "mutual opposite form", and 1751cb0ef41Sopenharmony_ci * "sign-alternating {+-1}-representation". 1761cb0ef41Sopenharmony_ci * 1771cb0ef41Sopenharmony_ci * An interesting property is that among the nonzero bits, values 1 and -1 1781cb0ef41Sopenharmony_ci * strictly alternate. 1791cb0ef41Sopenharmony_ci * 1801cb0ef41Sopenharmony_ci * (2) Various window schemes can be applied to the Booth representation of 1811cb0ef41Sopenharmony_ci * integers: for example, right-to-left sliding windows yield the wNAF 1821cb0ef41Sopenharmony_ci * (a signed-digit encoding independently discovered by various researchers 1831cb0ef41Sopenharmony_ci * in the 1990s), and left-to-right sliding windows yield a left-to-right 1841cb0ef41Sopenharmony_ci * equivalent of the wNAF (independently discovered by various researchers 1851cb0ef41Sopenharmony_ci * around 2004). 1861cb0ef41Sopenharmony_ci * 1871cb0ef41Sopenharmony_ci * To prevent leaking information through side channels in point multiplication, 1881cb0ef41Sopenharmony_ci * we need to recode the given integer into a regular pattern: sliding windows 1891cb0ef41Sopenharmony_ci * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few 1901cb0ef41Sopenharmony_ci * decades older: we'll be using the so-called "modified Booth encoding" due to 1911cb0ef41Sopenharmony_ci * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 1921cb0ef41Sopenharmony_ci * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five 1931cb0ef41Sopenharmony_ci * signed bits into a signed digit: 1941cb0ef41Sopenharmony_ci * 1951cb0ef41Sopenharmony_ci * s_(5j + 4) s_(5j + 3) s_(5j + 2) s_(5j + 1) s_(5j) 1961cb0ef41Sopenharmony_ci * 1971cb0ef41Sopenharmony_ci * The sign-alternating property implies that the resulting digit values are 1981cb0ef41Sopenharmony_ci * integers from -16 to 16. 1991cb0ef41Sopenharmony_ci * 2001cb0ef41Sopenharmony_ci * Of course, we don't actually need to compute the signed digits s_i as an 2011cb0ef41Sopenharmony_ci * intermediate step (that's just a nice way to see how this scheme relates 2021cb0ef41Sopenharmony_ci * to the wNAF): a direct computation obtains the recoded digit from the 2031cb0ef41Sopenharmony_ci * six bits b_(5j + 4) ... b_(5j - 1). 2041cb0ef41Sopenharmony_ci * 2051cb0ef41Sopenharmony_ci * This function takes those six bits as an integer (0 .. 63), writing the 2061cb0ef41Sopenharmony_ci * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute 2071cb0ef41Sopenharmony_ci * value, in the range 0 .. 16). Note that this integer essentially provides 2081cb0ef41Sopenharmony_ci * the input bits "shifted to the left" by one position: for example, the input 2091cb0ef41Sopenharmony_ci * to compute the least significant recoded digit, given that there's no bit 2101cb0ef41Sopenharmony_ci * b_-1, has to be b_4 b_3 b_2 b_1 b_0 0. 2111cb0ef41Sopenharmony_ci * 2121cb0ef41Sopenharmony_ci */ 2131cb0ef41Sopenharmony_civoid ossl_ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, 2141cb0ef41Sopenharmony_ci unsigned char *digit, unsigned char in) 2151cb0ef41Sopenharmony_ci{ 2161cb0ef41Sopenharmony_ci unsigned char s, d; 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as 2191cb0ef41Sopenharmony_ci * 6-bit value */ 2201cb0ef41Sopenharmony_ci d = (1 << 6) - in - 1; 2211cb0ef41Sopenharmony_ci d = (d & s) | (in & ~s); 2221cb0ef41Sopenharmony_ci d = (d >> 1) + (d & 1); 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci *sign = s & 1; 2251cb0ef41Sopenharmony_ci *digit = d; 2261cb0ef41Sopenharmony_ci} 227