wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 13:f67a6c6013ca 1 /* fe_operations.c
wolfSSL 13:f67a6c6013ca 2 *
wolfSSL 13:f67a6c6013ca 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 13:f67a6c6013ca 4 *
wolfSSL 13:f67a6c6013ca 5 * This file is part of wolfSSL.
wolfSSL 13:f67a6c6013ca 6 *
wolfSSL 13:f67a6c6013ca 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 13:f67a6c6013ca 8 * it under the terms of the GNU General Public License as published by
wolfSSL 13:f67a6c6013ca 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 13:f67a6c6013ca 10 * (at your option) any later version.
wolfSSL 13:f67a6c6013ca 11 *
wolfSSL 13:f67a6c6013ca 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 13:f67a6c6013ca 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 13:f67a6c6013ca 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 13:f67a6c6013ca 15 * GNU General Public License for more details.
wolfSSL 13:f67a6c6013ca 16 *
wolfSSL 13:f67a6c6013ca 17 * You should have received a copy of the GNU General Public License
wolfSSL 13:f67a6c6013ca 18 * along with this program; if not, write to the Free Software
wolfSSL 13:f67a6c6013ca 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 13:f67a6c6013ca 20 */
wolfSSL 13:f67a6c6013ca 21
wolfSSL 13:f67a6c6013ca 22
wolfSSL 13:f67a6c6013ca 23 /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */
wolfSSL 13:f67a6c6013ca 24
wolfSSL 13:f67a6c6013ca 25 #ifdef HAVE_CONFIG_H
wolfSSL 13:f67a6c6013ca 26 #include <config.h>
wolfSSL 13:f67a6c6013ca 27 #endif
wolfSSL 13:f67a6c6013ca 28
wolfSSL 13:f67a6c6013ca 29 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 13:f67a6c6013ca 30
wolfSSL 13:f67a6c6013ca 31 #if defined(HAVE_CURVE25519) || defined(HAVE_ED25519)
wolfSSL 13:f67a6c6013ca 32 #if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL) /* run when not defined to use small memory math */
wolfSSL 13:f67a6c6013ca 33
wolfSSL 13:f67a6c6013ca 34 #include <wolfssl/wolfcrypt/fe_operations.h>
wolfSSL 13:f67a6c6013ca 35 #include <stdint.h>
wolfSSL 13:f67a6c6013ca 36
wolfSSL 13:f67a6c6013ca 37 #ifdef NO_INLINE
wolfSSL 13:f67a6c6013ca 38 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 13:f67a6c6013ca 39 #else
wolfSSL 13:f67a6c6013ca 40 #define WOLFSSL_MISC_INCLUDED
wolfSSL 13:f67a6c6013ca 41 #include <wolfcrypt/src/misc.c>
wolfSSL 13:f67a6c6013ca 42 #endif
wolfSSL 13:f67a6c6013ca 43
wolfSSL 13:f67a6c6013ca 44 #ifdef CURVED25519_128BIT
wolfSSL 13:f67a6c6013ca 45 #include "fe_x25519_128.i"
wolfSSL 13:f67a6c6013ca 46 #else
wolfSSL 13:f67a6c6013ca 47
wolfSSL 13:f67a6c6013ca 48 #if defined(HAVE_CURVE25519) || \
wolfSSL 13:f67a6c6013ca 49 (defined(HAVE_ED25519) && !defined(ED25519_SMALL))
wolfSSL 13:f67a6c6013ca 50 /*
wolfSSL 13:f67a6c6013ca 51 fe means field element.
wolfSSL 13:f67a6c6013ca 52 Here the field is \Z/(2^255-19).
wolfSSL 13:f67a6c6013ca 53 An element t, entries t[0]...t[9], represents the integer
wolfSSL 13:f67a6c6013ca 54 t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
wolfSSL 13:f67a6c6013ca 55 Bounds on each t[i] vary depending on context.
wolfSSL 13:f67a6c6013ca 56 */
wolfSSL 13:f67a6c6013ca 57
wolfSSL 13:f67a6c6013ca 58 uint64_t load_3(const unsigned char *in)
wolfSSL 13:f67a6c6013ca 59 {
wolfSSL 13:f67a6c6013ca 60 uint64_t result;
wolfSSL 13:f67a6c6013ca 61 result = (uint64_t) in[0];
wolfSSL 13:f67a6c6013ca 62 result |= ((uint64_t) in[1]) << 8;
wolfSSL 13:f67a6c6013ca 63 result |= ((uint64_t) in[2]) << 16;
wolfSSL 13:f67a6c6013ca 64 return result;
wolfSSL 13:f67a6c6013ca 65 }
wolfSSL 13:f67a6c6013ca 66
wolfSSL 13:f67a6c6013ca 67
wolfSSL 13:f67a6c6013ca 68 uint64_t load_4(const unsigned char *in)
wolfSSL 13:f67a6c6013ca 69 {
wolfSSL 13:f67a6c6013ca 70 uint64_t result;
wolfSSL 13:f67a6c6013ca 71 result = (uint64_t) in[0];
wolfSSL 13:f67a6c6013ca 72 result |= ((uint64_t) in[1]) << 8;
wolfSSL 13:f67a6c6013ca 73 result |= ((uint64_t) in[2]) << 16;
wolfSSL 13:f67a6c6013ca 74 result |= ((uint64_t) in[3]) << 24;
wolfSSL 13:f67a6c6013ca 75 return result;
wolfSSL 13:f67a6c6013ca 76 }
wolfSSL 13:f67a6c6013ca 77 #endif
wolfSSL 13:f67a6c6013ca 78
wolfSSL 13:f67a6c6013ca 79 /*
wolfSSL 13:f67a6c6013ca 80 h = 1
wolfSSL 13:f67a6c6013ca 81 */
wolfSSL 13:f67a6c6013ca 82
wolfSSL 13:f67a6c6013ca 83 void fe_1(fe h)
wolfSSL 13:f67a6c6013ca 84 {
wolfSSL 13:f67a6c6013ca 85 h[0] = 1;
wolfSSL 13:f67a6c6013ca 86 h[1] = 0;
wolfSSL 13:f67a6c6013ca 87 h[2] = 0;
wolfSSL 13:f67a6c6013ca 88 h[3] = 0;
wolfSSL 13:f67a6c6013ca 89 h[4] = 0;
wolfSSL 13:f67a6c6013ca 90 h[5] = 0;
wolfSSL 13:f67a6c6013ca 91 h[6] = 0;
wolfSSL 13:f67a6c6013ca 92 h[7] = 0;
wolfSSL 13:f67a6c6013ca 93 h[8] = 0;
wolfSSL 13:f67a6c6013ca 94 h[9] = 0;
wolfSSL 13:f67a6c6013ca 95 }
wolfSSL 13:f67a6c6013ca 96
wolfSSL 13:f67a6c6013ca 97
wolfSSL 13:f67a6c6013ca 98 /*
wolfSSL 13:f67a6c6013ca 99 h = 0
wolfSSL 13:f67a6c6013ca 100 */
wolfSSL 13:f67a6c6013ca 101
wolfSSL 13:f67a6c6013ca 102 void fe_0(fe h)
wolfSSL 13:f67a6c6013ca 103 {
wolfSSL 13:f67a6c6013ca 104 h[0] = 0;
wolfSSL 13:f67a6c6013ca 105 h[1] = 0;
wolfSSL 13:f67a6c6013ca 106 h[2] = 0;
wolfSSL 13:f67a6c6013ca 107 h[3] = 0;
wolfSSL 13:f67a6c6013ca 108 h[4] = 0;
wolfSSL 13:f67a6c6013ca 109 h[5] = 0;
wolfSSL 13:f67a6c6013ca 110 h[6] = 0;
wolfSSL 13:f67a6c6013ca 111 h[7] = 0;
wolfSSL 13:f67a6c6013ca 112 h[8] = 0;
wolfSSL 13:f67a6c6013ca 113 h[9] = 0;
wolfSSL 13:f67a6c6013ca 114 }
wolfSSL 13:f67a6c6013ca 115
wolfSSL 13:f67a6c6013ca 116 #if defined(HAVE_CURVE25519) && !defined(CURVE25519_SMALL) && \
wolfSSL 13:f67a6c6013ca 117 !defined(FREESCALE_LTC_ECC)
wolfSSL 13:f67a6c6013ca 118 int curve25519(byte* q, byte* n, byte* p)
wolfSSL 13:f67a6c6013ca 119 {
wolfSSL 13:f67a6c6013ca 120 #if 0
wolfSSL 13:f67a6c6013ca 121 unsigned char e[32];
wolfSSL 13:f67a6c6013ca 122 #endif
wolfSSL 13:f67a6c6013ca 123 fe x1;
wolfSSL 13:f67a6c6013ca 124 fe x2;
wolfSSL 13:f67a6c6013ca 125 fe z2;
wolfSSL 13:f67a6c6013ca 126 fe x3;
wolfSSL 13:f67a6c6013ca 127 fe z3;
wolfSSL 13:f67a6c6013ca 128 fe tmp0;
wolfSSL 13:f67a6c6013ca 129 fe tmp1;
wolfSSL 13:f67a6c6013ca 130 int pos;
wolfSSL 13:f67a6c6013ca 131 unsigned int swap;
wolfSSL 13:f67a6c6013ca 132 unsigned int b;
wolfSSL 13:f67a6c6013ca 133
wolfSSL 13:f67a6c6013ca 134 /* Clamp already done during key generation and import */
wolfSSL 13:f67a6c6013ca 135 #if 0
wolfSSL 13:f67a6c6013ca 136 {
wolfSSL 13:f67a6c6013ca 137 unsigned int i;
wolfSSL 13:f67a6c6013ca 138 for (i = 0;i < 32;++i) e[i] = n[i];
wolfSSL 13:f67a6c6013ca 139 e[0] &= 248;
wolfSSL 13:f67a6c6013ca 140 e[31] &= 127;
wolfSSL 13:f67a6c6013ca 141 e[31] |= 64;
wolfSSL 13:f67a6c6013ca 142 }
wolfSSL 13:f67a6c6013ca 143 #endif
wolfSSL 13:f67a6c6013ca 144
wolfSSL 13:f67a6c6013ca 145 fe_frombytes(x1,p);
wolfSSL 13:f67a6c6013ca 146 fe_1(x2);
wolfSSL 13:f67a6c6013ca 147 fe_0(z2);
wolfSSL 13:f67a6c6013ca 148 fe_copy(x3,x1);
wolfSSL 13:f67a6c6013ca 149 fe_1(z3);
wolfSSL 13:f67a6c6013ca 150
wolfSSL 13:f67a6c6013ca 151 swap = 0;
wolfSSL 13:f67a6c6013ca 152 for (pos = 254;pos >= 0;--pos) {
wolfSSL 13:f67a6c6013ca 153 #if 0
wolfSSL 13:f67a6c6013ca 154 b = e[pos / 8] >> (pos & 7);
wolfSSL 13:f67a6c6013ca 155 #else
wolfSSL 13:f67a6c6013ca 156 b = n[pos / 8] >> (pos & 7);
wolfSSL 13:f67a6c6013ca 157 #endif
wolfSSL 13:f67a6c6013ca 158 b &= 1;
wolfSSL 13:f67a6c6013ca 159 swap ^= b;
wolfSSL 13:f67a6c6013ca 160 fe_cswap(x2,x3,swap);
wolfSSL 13:f67a6c6013ca 161 fe_cswap(z2,z3,swap);
wolfSSL 13:f67a6c6013ca 162 swap = b;
wolfSSL 13:f67a6c6013ca 163
wolfSSL 13:f67a6c6013ca 164 /* montgomery */
wolfSSL 13:f67a6c6013ca 165 fe_sub(tmp0,x3,z3);
wolfSSL 13:f67a6c6013ca 166 fe_sub(tmp1,x2,z2);
wolfSSL 13:f67a6c6013ca 167 fe_add(x2,x2,z2);
wolfSSL 13:f67a6c6013ca 168 fe_add(z2,x3,z3);
wolfSSL 13:f67a6c6013ca 169 fe_mul(z3,tmp0,x2);
wolfSSL 13:f67a6c6013ca 170 fe_mul(z2,z2,tmp1);
wolfSSL 13:f67a6c6013ca 171 fe_sq(tmp0,tmp1);
wolfSSL 13:f67a6c6013ca 172 fe_sq(tmp1,x2);
wolfSSL 13:f67a6c6013ca 173 fe_add(x3,z3,z2);
wolfSSL 13:f67a6c6013ca 174 fe_sub(z2,z3,z2);
wolfSSL 13:f67a6c6013ca 175 fe_mul(x2,tmp1,tmp0);
wolfSSL 13:f67a6c6013ca 176 fe_sub(tmp1,tmp1,tmp0);
wolfSSL 13:f67a6c6013ca 177 fe_sq(z2,z2);
wolfSSL 13:f67a6c6013ca 178 fe_mul121666(z3,tmp1);
wolfSSL 13:f67a6c6013ca 179 fe_sq(x3,x3);
wolfSSL 13:f67a6c6013ca 180 fe_add(tmp0,tmp0,z3);
wolfSSL 13:f67a6c6013ca 181 fe_mul(z3,x1,z2);
wolfSSL 13:f67a6c6013ca 182 fe_mul(z2,tmp1,tmp0);
wolfSSL 13:f67a6c6013ca 183 }
wolfSSL 13:f67a6c6013ca 184 fe_cswap(x2,x3,swap);
wolfSSL 13:f67a6c6013ca 185 fe_cswap(z2,z3,swap);
wolfSSL 13:f67a6c6013ca 186
wolfSSL 13:f67a6c6013ca 187 fe_invert(z2,z2);
wolfSSL 13:f67a6c6013ca 188 fe_mul(x2,x2,z2);
wolfSSL 13:f67a6c6013ca 189 fe_tobytes(q,x2);
wolfSSL 13:f67a6c6013ca 190
wolfSSL 13:f67a6c6013ca 191 return 0;
wolfSSL 13:f67a6c6013ca 192 }
wolfSSL 13:f67a6c6013ca 193 #endif /* HAVE_CURVE25519 && !CURVE25519_SMALL && !FREESCALE_LTC_ECC */
wolfSSL 13:f67a6c6013ca 194
wolfSSL 13:f67a6c6013ca 195
wolfSSL 13:f67a6c6013ca 196 /*
wolfSSL 13:f67a6c6013ca 197 h = f * f
wolfSSL 13:f67a6c6013ca 198 Can overlap h with f.
wolfSSL 13:f67a6c6013ca 199
wolfSSL 13:f67a6c6013ca 200 Preconditions:
wolfSSL 13:f67a6c6013ca 201 |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
wolfSSL 13:f67a6c6013ca 202
wolfSSL 13:f67a6c6013ca 203 Postconditions:
wolfSSL 13:f67a6c6013ca 204 |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
wolfSSL 13:f67a6c6013ca 205 */
wolfSSL 13:f67a6c6013ca 206
wolfSSL 13:f67a6c6013ca 207 /*
wolfSSL 13:f67a6c6013ca 208 See fe_mul.c for discussion of implementation strategy.
wolfSSL 13:f67a6c6013ca 209 */
wolfSSL 13:f67a6c6013ca 210
wolfSSL 13:f67a6c6013ca 211 void fe_sq(fe h,const fe f)
wolfSSL 13:f67a6c6013ca 212 {
wolfSSL 13:f67a6c6013ca 213 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 214 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 215 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 216 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 217 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 218 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 219 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 220 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 221 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 222 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 223 int32_t f0_2 = 2 * f0;
wolfSSL 13:f67a6c6013ca 224 int32_t f1_2 = 2 * f1;
wolfSSL 13:f67a6c6013ca 225 int32_t f2_2 = 2 * f2;
wolfSSL 13:f67a6c6013ca 226 int32_t f3_2 = 2 * f3;
wolfSSL 13:f67a6c6013ca 227 int32_t f4_2 = 2 * f4;
wolfSSL 13:f67a6c6013ca 228 int32_t f5_2 = 2 * f5;
wolfSSL 13:f67a6c6013ca 229 int32_t f6_2 = 2 * f6;
wolfSSL 13:f67a6c6013ca 230 int32_t f7_2 = 2 * f7;
wolfSSL 13:f67a6c6013ca 231 int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 232 int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 233 int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 234 int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 235 int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 236 int64_t f0f0 = f0 * (int64_t) f0;
wolfSSL 13:f67a6c6013ca 237 int64_t f0f1_2 = f0_2 * (int64_t) f1;
wolfSSL 13:f67a6c6013ca 238 int64_t f0f2_2 = f0_2 * (int64_t) f2;
wolfSSL 13:f67a6c6013ca 239 int64_t f0f3_2 = f0_2 * (int64_t) f3;
wolfSSL 13:f67a6c6013ca 240 int64_t f0f4_2 = f0_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 241 int64_t f0f5_2 = f0_2 * (int64_t) f5;
wolfSSL 13:f67a6c6013ca 242 int64_t f0f6_2 = f0_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 243 int64_t f0f7_2 = f0_2 * (int64_t) f7;
wolfSSL 13:f67a6c6013ca 244 int64_t f0f8_2 = f0_2 * (int64_t) f8;
wolfSSL 13:f67a6c6013ca 245 int64_t f0f9_2 = f0_2 * (int64_t) f9;
wolfSSL 13:f67a6c6013ca 246 int64_t f1f1_2 = f1_2 * (int64_t) f1;
wolfSSL 13:f67a6c6013ca 247 int64_t f1f2_2 = f1_2 * (int64_t) f2;
wolfSSL 13:f67a6c6013ca 248 int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
wolfSSL 13:f67a6c6013ca 249 int64_t f1f4_2 = f1_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 250 int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
wolfSSL 13:f67a6c6013ca 251 int64_t f1f6_2 = f1_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 252 int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
wolfSSL 13:f67a6c6013ca 253 int64_t f1f8_2 = f1_2 * (int64_t) f8;
wolfSSL 13:f67a6c6013ca 254 int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 255 int64_t f2f2 = f2 * (int64_t) f2;
wolfSSL 13:f67a6c6013ca 256 int64_t f2f3_2 = f2_2 * (int64_t) f3;
wolfSSL 13:f67a6c6013ca 257 int64_t f2f4_2 = f2_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 258 int64_t f2f5_2 = f2_2 * (int64_t) f5;
wolfSSL 13:f67a6c6013ca 259 int64_t f2f6_2 = f2_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 260 int64_t f2f7_2 = f2_2 * (int64_t) f7;
wolfSSL 13:f67a6c6013ca 261 int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 262 int64_t f2f9_38 = f2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 263 int64_t f3f3_2 = f3_2 * (int64_t) f3;
wolfSSL 13:f67a6c6013ca 264 int64_t f3f4_2 = f3_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 265 int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
wolfSSL 13:f67a6c6013ca 266 int64_t f3f6_2 = f3_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 267 int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 268 int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 269 int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 270 int64_t f4f4 = f4 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 271 int64_t f4f5_2 = f4_2 * (int64_t) f5;
wolfSSL 13:f67a6c6013ca 272 int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
wolfSSL 13:f67a6c6013ca 273 int64_t f4f7_38 = f4 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 274 int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 275 int64_t f4f9_38 = f4 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 276 int64_t f5f5_38 = f5 * (int64_t) f5_38;
wolfSSL 13:f67a6c6013ca 277 int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
wolfSSL 13:f67a6c6013ca 278 int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 279 int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 280 int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 281 int64_t f6f6_19 = f6 * (int64_t) f6_19;
wolfSSL 13:f67a6c6013ca 282 int64_t f6f7_38 = f6 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 283 int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 284 int64_t f6f9_38 = f6 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 285 int64_t f7f7_38 = f7 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 286 int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 287 int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 288 int64_t f8f8_19 = f8 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 289 int64_t f8f9_38 = f8 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 290 int64_t f9f9_38 = f9 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 291 int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
wolfSSL 13:f67a6c6013ca 292 int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
wolfSSL 13:f67a6c6013ca 293 int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
wolfSSL 13:f67a6c6013ca 294 int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
wolfSSL 13:f67a6c6013ca 295 int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
wolfSSL 13:f67a6c6013ca 296 int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
wolfSSL 13:f67a6c6013ca 297 int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
wolfSSL 13:f67a6c6013ca 298 int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
wolfSSL 13:f67a6c6013ca 299 int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
wolfSSL 13:f67a6c6013ca 300 int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
wolfSSL 13:f67a6c6013ca 301 int64_t carry0;
wolfSSL 13:f67a6c6013ca 302 int64_t carry1;
wolfSSL 13:f67a6c6013ca 303 int64_t carry2;
wolfSSL 13:f67a6c6013ca 304 int64_t carry3;
wolfSSL 13:f67a6c6013ca 305 int64_t carry4;
wolfSSL 13:f67a6c6013ca 306 int64_t carry5;
wolfSSL 13:f67a6c6013ca 307 int64_t carry6;
wolfSSL 13:f67a6c6013ca 308 int64_t carry7;
wolfSSL 13:f67a6c6013ca 309 int64_t carry8;
wolfSSL 13:f67a6c6013ca 310 int64_t carry9;
wolfSSL 13:f67a6c6013ca 311
wolfSSL 13:f67a6c6013ca 312 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 313 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 314
wolfSSL 13:f67a6c6013ca 315 carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
wolfSSL 13:f67a6c6013ca 316 carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
wolfSSL 13:f67a6c6013ca 317
wolfSSL 13:f67a6c6013ca 318 carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
wolfSSL 13:f67a6c6013ca 319 carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
wolfSSL 13:f67a6c6013ca 320
wolfSSL 13:f67a6c6013ca 321 carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
wolfSSL 13:f67a6c6013ca 322 carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
wolfSSL 13:f67a6c6013ca 323
wolfSSL 13:f67a6c6013ca 324 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 325 carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
wolfSSL 13:f67a6c6013ca 326
wolfSSL 13:f67a6c6013ca 327 carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
wolfSSL 13:f67a6c6013ca 328
wolfSSL 13:f67a6c6013ca 329 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 330
wolfSSL 13:f67a6c6013ca 331 h[0] = (int32_t)h0;
wolfSSL 13:f67a6c6013ca 332 h[1] = (int32_t)h1;
wolfSSL 13:f67a6c6013ca 333 h[2] = (int32_t)h2;
wolfSSL 13:f67a6c6013ca 334 h[3] = (int32_t)h3;
wolfSSL 13:f67a6c6013ca 335 h[4] = (int32_t)h4;
wolfSSL 13:f67a6c6013ca 336 h[5] = (int32_t)h5;
wolfSSL 13:f67a6c6013ca 337 h[6] = (int32_t)h6;
wolfSSL 13:f67a6c6013ca 338 h[7] = (int32_t)h7;
wolfSSL 13:f67a6c6013ca 339 h[8] = (int32_t)h8;
wolfSSL 13:f67a6c6013ca 340 h[9] = (int32_t)h9;
wolfSSL 13:f67a6c6013ca 341 }
wolfSSL 13:f67a6c6013ca 342
wolfSSL 13:f67a6c6013ca 343
wolfSSL 13:f67a6c6013ca 344 /*
wolfSSL 13:f67a6c6013ca 345 h = f + g
wolfSSL 13:f67a6c6013ca 346 Can overlap h with f or g.
wolfSSL 13:f67a6c6013ca 347
wolfSSL 13:f67a6c6013ca 348 Preconditions:
wolfSSL 13:f67a6c6013ca 349 |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
wolfSSL 13:f67a6c6013ca 350 |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
wolfSSL 13:f67a6c6013ca 351
wolfSSL 13:f67a6c6013ca 352 Postconditions:
wolfSSL 13:f67a6c6013ca 353 |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
wolfSSL 13:f67a6c6013ca 354 */
wolfSSL 13:f67a6c6013ca 355
wolfSSL 13:f67a6c6013ca 356 void fe_add(fe h,const fe f,const fe g)
wolfSSL 13:f67a6c6013ca 357 {
wolfSSL 13:f67a6c6013ca 358 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 359 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 360 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 361 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 362 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 363 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 364 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 365 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 366 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 367 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 368 int32_t g0 = g[0];
wolfSSL 13:f67a6c6013ca 369 int32_t g1 = g[1];
wolfSSL 13:f67a6c6013ca 370 int32_t g2 = g[2];
wolfSSL 13:f67a6c6013ca 371 int32_t g3 = g[3];
wolfSSL 13:f67a6c6013ca 372 int32_t g4 = g[4];
wolfSSL 13:f67a6c6013ca 373 int32_t g5 = g[5];
wolfSSL 13:f67a6c6013ca 374 int32_t g6 = g[6];
wolfSSL 13:f67a6c6013ca 375 int32_t g7 = g[7];
wolfSSL 13:f67a6c6013ca 376 int32_t g8 = g[8];
wolfSSL 13:f67a6c6013ca 377 int32_t g9 = g[9];
wolfSSL 13:f67a6c6013ca 378 int32_t h0 = f0 + g0;
wolfSSL 13:f67a6c6013ca 379 int32_t h1 = f1 + g1;
wolfSSL 13:f67a6c6013ca 380 int32_t h2 = f2 + g2;
wolfSSL 13:f67a6c6013ca 381 int32_t h3 = f3 + g3;
wolfSSL 13:f67a6c6013ca 382 int32_t h4 = f4 + g4;
wolfSSL 13:f67a6c6013ca 383 int32_t h5 = f5 + g5;
wolfSSL 13:f67a6c6013ca 384 int32_t h6 = f6 + g6;
wolfSSL 13:f67a6c6013ca 385 int32_t h7 = f7 + g7;
wolfSSL 13:f67a6c6013ca 386 int32_t h8 = f8 + g8;
wolfSSL 13:f67a6c6013ca 387 int32_t h9 = f9 + g9;
wolfSSL 13:f67a6c6013ca 388 h[0] = h0;
wolfSSL 13:f67a6c6013ca 389 h[1] = h1;
wolfSSL 13:f67a6c6013ca 390 h[2] = h2;
wolfSSL 13:f67a6c6013ca 391 h[3] = h3;
wolfSSL 13:f67a6c6013ca 392 h[4] = h4;
wolfSSL 13:f67a6c6013ca 393 h[5] = h5;
wolfSSL 13:f67a6c6013ca 394 h[6] = h6;
wolfSSL 13:f67a6c6013ca 395 h[7] = h7;
wolfSSL 13:f67a6c6013ca 396 h[8] = h8;
wolfSSL 13:f67a6c6013ca 397 h[9] = h9;
wolfSSL 13:f67a6c6013ca 398 }
wolfSSL 13:f67a6c6013ca 399
wolfSSL 13:f67a6c6013ca 400
wolfSSL 13:f67a6c6013ca 401 /*
wolfSSL 13:f67a6c6013ca 402 Preconditions:
wolfSSL 13:f67a6c6013ca 403 |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
wolfSSL 13:f67a6c6013ca 404
wolfSSL 13:f67a6c6013ca 405 Write p=2^255-19; q=floor(h/p).
wolfSSL 13:f67a6c6013ca 406 Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
wolfSSL 13:f67a6c6013ca 407
wolfSSL 13:f67a6c6013ca 408 Proof:
wolfSSL 13:f67a6c6013ca 409 Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
wolfSSL 13:f67a6c6013ca 410 Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
wolfSSL 13:f67a6c6013ca 411
wolfSSL 13:f67a6c6013ca 412 Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
wolfSSL 13:f67a6c6013ca 413 Then 0<y<1.
wolfSSL 13:f67a6c6013ca 414
wolfSSL 13:f67a6c6013ca 415 Write r=h-pq.
wolfSSL 13:f67a6c6013ca 416 Have 0<=r<=p-1=2^255-20.
wolfSSL 13:f67a6c6013ca 417 Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
wolfSSL 13:f67a6c6013ca 418
wolfSSL 13:f67a6c6013ca 419 Write x=r+19(2^-255)r+y.
wolfSSL 13:f67a6c6013ca 420 Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
wolfSSL 13:f67a6c6013ca 421
wolfSSL 13:f67a6c6013ca 422 Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
wolfSSL 13:f67a6c6013ca 423 so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
wolfSSL 13:f67a6c6013ca 424 */
wolfSSL 13:f67a6c6013ca 425
wolfSSL 13:f67a6c6013ca 426 void fe_tobytes(unsigned char *s,const fe h)
wolfSSL 13:f67a6c6013ca 427 {
wolfSSL 13:f67a6c6013ca 428 int32_t h0 = h[0];
wolfSSL 13:f67a6c6013ca 429 int32_t h1 = h[1];
wolfSSL 13:f67a6c6013ca 430 int32_t h2 = h[2];
wolfSSL 13:f67a6c6013ca 431 int32_t h3 = h[3];
wolfSSL 13:f67a6c6013ca 432 int32_t h4 = h[4];
wolfSSL 13:f67a6c6013ca 433 int32_t h5 = h[5];
wolfSSL 13:f67a6c6013ca 434 int32_t h6 = h[6];
wolfSSL 13:f67a6c6013ca 435 int32_t h7 = h[7];
wolfSSL 13:f67a6c6013ca 436 int32_t h8 = h[8];
wolfSSL 13:f67a6c6013ca 437 int32_t h9 = h[9];
wolfSSL 13:f67a6c6013ca 438 int32_t q;
wolfSSL 13:f67a6c6013ca 439 int32_t carry0;
wolfSSL 13:f67a6c6013ca 440 int32_t carry1;
wolfSSL 13:f67a6c6013ca 441 int32_t carry2;
wolfSSL 13:f67a6c6013ca 442 int32_t carry3;
wolfSSL 13:f67a6c6013ca 443 int32_t carry4;
wolfSSL 13:f67a6c6013ca 444 int32_t carry5;
wolfSSL 13:f67a6c6013ca 445 int32_t carry6;
wolfSSL 13:f67a6c6013ca 446 int32_t carry7;
wolfSSL 13:f67a6c6013ca 447 int32_t carry8;
wolfSSL 13:f67a6c6013ca 448 int32_t carry9;
wolfSSL 13:f67a6c6013ca 449
wolfSSL 13:f67a6c6013ca 450 q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
wolfSSL 13:f67a6c6013ca 451 q = (h0 + q) >> 26;
wolfSSL 13:f67a6c6013ca 452 q = (h1 + q) >> 25;
wolfSSL 13:f67a6c6013ca 453 q = (h2 + q) >> 26;
wolfSSL 13:f67a6c6013ca 454 q = (h3 + q) >> 25;
wolfSSL 13:f67a6c6013ca 455 q = (h4 + q) >> 26;
wolfSSL 13:f67a6c6013ca 456 q = (h5 + q) >> 25;
wolfSSL 13:f67a6c6013ca 457 q = (h6 + q) >> 26;
wolfSSL 13:f67a6c6013ca 458 q = (h7 + q) >> 25;
wolfSSL 13:f67a6c6013ca 459 q = (h8 + q) >> 26;
wolfSSL 13:f67a6c6013ca 460 q = (h9 + q) >> 25;
wolfSSL 13:f67a6c6013ca 461
wolfSSL 13:f67a6c6013ca 462 /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
wolfSSL 13:f67a6c6013ca 463 h0 += 19 * q;
wolfSSL 13:f67a6c6013ca 464 /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
wolfSSL 13:f67a6c6013ca 465
wolfSSL 13:f67a6c6013ca 466 carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 467 carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
wolfSSL 13:f67a6c6013ca 468 carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
wolfSSL 13:f67a6c6013ca 469 carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
wolfSSL 13:f67a6c6013ca 470 carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 471 carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
wolfSSL 13:f67a6c6013ca 472 carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
wolfSSL 13:f67a6c6013ca 473 carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
wolfSSL 13:f67a6c6013ca 474 carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
wolfSSL 13:f67a6c6013ca 475 carry9 = h9 >> 25; h9 -= carry9 << 25;
wolfSSL 13:f67a6c6013ca 476 /* h10 = carry9 */
wolfSSL 13:f67a6c6013ca 477
wolfSSL 13:f67a6c6013ca 478 /*
wolfSSL 13:f67a6c6013ca 479 Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
wolfSSL 13:f67a6c6013ca 480 Have h0+...+2^230 h9 between 0 and 2^255-1;
wolfSSL 13:f67a6c6013ca 481 evidently 2^255 h10-2^255 q = 0.
wolfSSL 13:f67a6c6013ca 482 Goal: Output h0+...+2^230 h9.
wolfSSL 13:f67a6c6013ca 483 */
wolfSSL 13:f67a6c6013ca 484
wolfSSL 13:f67a6c6013ca 485 s[0] = h0 >> 0;
wolfSSL 13:f67a6c6013ca 486 s[1] = h0 >> 8;
wolfSSL 13:f67a6c6013ca 487 s[2] = h0 >> 16;
wolfSSL 13:f67a6c6013ca 488 s[3] = (h0 >> 24) | (h1 << 2);
wolfSSL 13:f67a6c6013ca 489 s[4] = h1 >> 6;
wolfSSL 13:f67a6c6013ca 490 s[5] = h1 >> 14;
wolfSSL 13:f67a6c6013ca 491 s[6] = (h1 >> 22) | (h2 << 3);
wolfSSL 13:f67a6c6013ca 492 s[7] = h2 >> 5;
wolfSSL 13:f67a6c6013ca 493 s[8] = h2 >> 13;
wolfSSL 13:f67a6c6013ca 494 s[9] = (h2 >> 21) | (h3 << 5);
wolfSSL 13:f67a6c6013ca 495 s[10] = h3 >> 3;
wolfSSL 13:f67a6c6013ca 496 s[11] = h3 >> 11;
wolfSSL 13:f67a6c6013ca 497 s[12] = (h3 >> 19) | (h4 << 6);
wolfSSL 13:f67a6c6013ca 498 s[13] = h4 >> 2;
wolfSSL 13:f67a6c6013ca 499 s[14] = h4 >> 10;
wolfSSL 13:f67a6c6013ca 500 s[15] = h4 >> 18;
wolfSSL 13:f67a6c6013ca 501 s[16] = h5 >> 0;
wolfSSL 13:f67a6c6013ca 502 s[17] = h5 >> 8;
wolfSSL 13:f67a6c6013ca 503 s[18] = h5 >> 16;
wolfSSL 13:f67a6c6013ca 504 s[19] = (h5 >> 24) | (h6 << 1);
wolfSSL 13:f67a6c6013ca 505 s[20] = h6 >> 7;
wolfSSL 13:f67a6c6013ca 506 s[21] = h6 >> 15;
wolfSSL 13:f67a6c6013ca 507 s[22] = (h6 >> 23) | (h7 << 3);
wolfSSL 13:f67a6c6013ca 508 s[23] = h7 >> 5;
wolfSSL 13:f67a6c6013ca 509 s[24] = h7 >> 13;
wolfSSL 13:f67a6c6013ca 510 s[25] = (h7 >> 21) | (h8 << 4);
wolfSSL 13:f67a6c6013ca 511 s[26] = h8 >> 4;
wolfSSL 13:f67a6c6013ca 512 s[27] = h8 >> 12;
wolfSSL 13:f67a6c6013ca 513 s[28] = (h8 >> 20) | (h9 << 6);
wolfSSL 13:f67a6c6013ca 514 s[29] = h9 >> 2;
wolfSSL 13:f67a6c6013ca 515 s[30] = h9 >> 10;
wolfSSL 13:f67a6c6013ca 516 s[31] = h9 >> 18;
wolfSSL 13:f67a6c6013ca 517 }
wolfSSL 13:f67a6c6013ca 518
wolfSSL 13:f67a6c6013ca 519
wolfSSL 13:f67a6c6013ca 520 /*
wolfSSL 13:f67a6c6013ca 521 h = f - g
wolfSSL 13:f67a6c6013ca 522 Can overlap h with f or g.
wolfSSL 13:f67a6c6013ca 523
wolfSSL 13:f67a6c6013ca 524 Preconditions:
wolfSSL 13:f67a6c6013ca 525 |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
wolfSSL 13:f67a6c6013ca 526 |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
wolfSSL 13:f67a6c6013ca 527
wolfSSL 13:f67a6c6013ca 528 Postconditions:
wolfSSL 13:f67a6c6013ca 529 |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
wolfSSL 13:f67a6c6013ca 530 */
wolfSSL 13:f67a6c6013ca 531
wolfSSL 13:f67a6c6013ca 532 void fe_sub(fe h,const fe f,const fe g)
wolfSSL 13:f67a6c6013ca 533 {
wolfSSL 13:f67a6c6013ca 534 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 535 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 536 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 537 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 538 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 539 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 540 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 541 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 542 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 543 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 544 int32_t g0 = g[0];
wolfSSL 13:f67a6c6013ca 545 int32_t g1 = g[1];
wolfSSL 13:f67a6c6013ca 546 int32_t g2 = g[2];
wolfSSL 13:f67a6c6013ca 547 int32_t g3 = g[3];
wolfSSL 13:f67a6c6013ca 548 int32_t g4 = g[4];
wolfSSL 13:f67a6c6013ca 549 int32_t g5 = g[5];
wolfSSL 13:f67a6c6013ca 550 int32_t g6 = g[6];
wolfSSL 13:f67a6c6013ca 551 int32_t g7 = g[7];
wolfSSL 13:f67a6c6013ca 552 int32_t g8 = g[8];
wolfSSL 13:f67a6c6013ca 553 int32_t g9 = g[9];
wolfSSL 13:f67a6c6013ca 554 int32_t h0 = f0 - g0;
wolfSSL 13:f67a6c6013ca 555 int32_t h1 = f1 - g1;
wolfSSL 13:f67a6c6013ca 556 int32_t h2 = f2 - g2;
wolfSSL 13:f67a6c6013ca 557 int32_t h3 = f3 - g3;
wolfSSL 13:f67a6c6013ca 558 int32_t h4 = f4 - g4;
wolfSSL 13:f67a6c6013ca 559 int32_t h5 = f5 - g5;
wolfSSL 13:f67a6c6013ca 560 int32_t h6 = f6 - g6;
wolfSSL 13:f67a6c6013ca 561 int32_t h7 = f7 - g7;
wolfSSL 13:f67a6c6013ca 562 int32_t h8 = f8 - g8;
wolfSSL 13:f67a6c6013ca 563 int32_t h9 = f9 - g9;
wolfSSL 13:f67a6c6013ca 564 h[0] = h0;
wolfSSL 13:f67a6c6013ca 565 h[1] = h1;
wolfSSL 13:f67a6c6013ca 566 h[2] = h2;
wolfSSL 13:f67a6c6013ca 567 h[3] = h3;
wolfSSL 13:f67a6c6013ca 568 h[4] = h4;
wolfSSL 13:f67a6c6013ca 569 h[5] = h5;
wolfSSL 13:f67a6c6013ca 570 h[6] = h6;
wolfSSL 13:f67a6c6013ca 571 h[7] = h7;
wolfSSL 13:f67a6c6013ca 572 h[8] = h8;
wolfSSL 13:f67a6c6013ca 573 h[9] = h9;
wolfSSL 13:f67a6c6013ca 574 }
wolfSSL 13:f67a6c6013ca 575
wolfSSL 13:f67a6c6013ca 576
wolfSSL 13:f67a6c6013ca 577 #if defined(HAVE_CURVE25519) || \
wolfSSL 13:f67a6c6013ca 578 (defined(HAVE_ED25519) && !defined(ED25519_SMALL))
wolfSSL 13:f67a6c6013ca 579 /*
wolfSSL 13:f67a6c6013ca 580 Ignores top bit of h.
wolfSSL 13:f67a6c6013ca 581 */
wolfSSL 13:f67a6c6013ca 582
wolfSSL 13:f67a6c6013ca 583 void fe_frombytes(fe h,const unsigned char *s)
wolfSSL 13:f67a6c6013ca 584 {
wolfSSL 13:f67a6c6013ca 585 int64_t h0 = load_4(s);
wolfSSL 13:f67a6c6013ca 586 int64_t h1 = load_3(s + 4) << 6;
wolfSSL 13:f67a6c6013ca 587 int64_t h2 = load_3(s + 7) << 5;
wolfSSL 13:f67a6c6013ca 588 int64_t h3 = load_3(s + 10) << 3;
wolfSSL 13:f67a6c6013ca 589 int64_t h4 = load_3(s + 13) << 2;
wolfSSL 13:f67a6c6013ca 590 int64_t h5 = load_4(s + 16);
wolfSSL 13:f67a6c6013ca 591 int64_t h6 = load_3(s + 20) << 7;
wolfSSL 13:f67a6c6013ca 592 int64_t h7 = load_3(s + 23) << 5;
wolfSSL 13:f67a6c6013ca 593 int64_t h8 = load_3(s + 26) << 4;
wolfSSL 13:f67a6c6013ca 594 int64_t h9 = (load_3(s + 29) & 8388607) << 2;
wolfSSL 13:f67a6c6013ca 595 int64_t carry0;
wolfSSL 13:f67a6c6013ca 596 int64_t carry1;
wolfSSL 13:f67a6c6013ca 597 int64_t carry2;
wolfSSL 13:f67a6c6013ca 598 int64_t carry3;
wolfSSL 13:f67a6c6013ca 599 int64_t carry4;
wolfSSL 13:f67a6c6013ca 600 int64_t carry5;
wolfSSL 13:f67a6c6013ca 601 int64_t carry6;
wolfSSL 13:f67a6c6013ca 602 int64_t carry7;
wolfSSL 13:f67a6c6013ca 603 int64_t carry8;
wolfSSL 13:f67a6c6013ca 604 int64_t carry9;
wolfSSL 13:f67a6c6013ca 605
wolfSSL 13:f67a6c6013ca 606 carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
wolfSSL 13:f67a6c6013ca 607 carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
wolfSSL 13:f67a6c6013ca 608 carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
wolfSSL 13:f67a6c6013ca 609 carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
wolfSSL 13:f67a6c6013ca 610 carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
wolfSSL 13:f67a6c6013ca 611
wolfSSL 13:f67a6c6013ca 612 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 613 carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
wolfSSL 13:f67a6c6013ca 614 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 615 carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
wolfSSL 13:f67a6c6013ca 616 carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
wolfSSL 13:f67a6c6013ca 617
wolfSSL 13:f67a6c6013ca 618 h[0] = (int32_t)h0;
wolfSSL 13:f67a6c6013ca 619 h[1] = (int32_t)h1;
wolfSSL 13:f67a6c6013ca 620 h[2] = (int32_t)h2;
wolfSSL 13:f67a6c6013ca 621 h[3] = (int32_t)h3;
wolfSSL 13:f67a6c6013ca 622 h[4] = (int32_t)h4;
wolfSSL 13:f67a6c6013ca 623 h[5] = (int32_t)h5;
wolfSSL 13:f67a6c6013ca 624 h[6] = (int32_t)h6;
wolfSSL 13:f67a6c6013ca 625 h[7] = (int32_t)h7;
wolfSSL 13:f67a6c6013ca 626 h[8] = (int32_t)h8;
wolfSSL 13:f67a6c6013ca 627 h[9] = (int32_t)h9;
wolfSSL 13:f67a6c6013ca 628 }
wolfSSL 13:f67a6c6013ca 629 #endif
wolfSSL 13:f67a6c6013ca 630
wolfSSL 13:f67a6c6013ca 631
wolfSSL 13:f67a6c6013ca 632 void fe_invert(fe out,const fe z)
wolfSSL 13:f67a6c6013ca 633 {
wolfSSL 13:f67a6c6013ca 634 fe t0;
wolfSSL 13:f67a6c6013ca 635 fe t1;
wolfSSL 13:f67a6c6013ca 636 fe t2;
wolfSSL 13:f67a6c6013ca 637 fe t3;
wolfSSL 13:f67a6c6013ca 638 int i;
wolfSSL 13:f67a6c6013ca 639
wolfSSL 13:f67a6c6013ca 640 /* pow225521 */
wolfSSL 13:f67a6c6013ca 641 fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0);
wolfSSL 13:f67a6c6013ca 642 fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 643 fe_mul(t1,z,t1);
wolfSSL 13:f67a6c6013ca 644 fe_mul(t0,t0,t1);
wolfSSL 13:f67a6c6013ca 645 fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 646 fe_mul(t1,t1,t2);
wolfSSL 13:f67a6c6013ca 647 fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 648 fe_mul(t1,t2,t1);
wolfSSL 13:f67a6c6013ca 649 fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 650 fe_mul(t2,t2,t1);
wolfSSL 13:f67a6c6013ca 651 fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3);
wolfSSL 13:f67a6c6013ca 652 fe_mul(t2,t3,t2);
wolfSSL 13:f67a6c6013ca 653 fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 654 fe_mul(t1,t2,t1);
wolfSSL 13:f67a6c6013ca 655 fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 656 fe_mul(t2,t2,t1);
wolfSSL 13:f67a6c6013ca 657 fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3);
wolfSSL 13:f67a6c6013ca 658 fe_mul(t2,t3,t2);
wolfSSL 13:f67a6c6013ca 659 fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 660 fe_mul(t1,t2,t1);
wolfSSL 13:f67a6c6013ca 661 fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 662 fe_mul(out,t1,t0);
wolfSSL 13:f67a6c6013ca 663
wolfSSL 13:f67a6c6013ca 664 return;
wolfSSL 13:f67a6c6013ca 665 }
wolfSSL 13:f67a6c6013ca 666
wolfSSL 13:f67a6c6013ca 667
wolfSSL 13:f67a6c6013ca 668 /*
wolfSSL 13:f67a6c6013ca 669 h = f
wolfSSL 13:f67a6c6013ca 670 */
wolfSSL 13:f67a6c6013ca 671
wolfSSL 13:f67a6c6013ca 672 void fe_copy(fe h,const fe f)
wolfSSL 13:f67a6c6013ca 673 {
wolfSSL 13:f67a6c6013ca 674 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 675 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 676 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 677 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 678 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 679 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 680 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 681 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 682 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 683 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 684 h[0] = f0;
wolfSSL 13:f67a6c6013ca 685 h[1] = f1;
wolfSSL 13:f67a6c6013ca 686 h[2] = f2;
wolfSSL 13:f67a6c6013ca 687 h[3] = f3;
wolfSSL 13:f67a6c6013ca 688 h[4] = f4;
wolfSSL 13:f67a6c6013ca 689 h[5] = f5;
wolfSSL 13:f67a6c6013ca 690 h[6] = f6;
wolfSSL 13:f67a6c6013ca 691 h[7] = f7;
wolfSSL 13:f67a6c6013ca 692 h[8] = f8;
wolfSSL 13:f67a6c6013ca 693 h[9] = f9;
wolfSSL 13:f67a6c6013ca 694 }
wolfSSL 13:f67a6c6013ca 695
wolfSSL 13:f67a6c6013ca 696
wolfSSL 13:f67a6c6013ca 697 /*
wolfSSL 13:f67a6c6013ca 698 h = f * g
wolfSSL 13:f67a6c6013ca 699 Can overlap h with f or g.
wolfSSL 13:f67a6c6013ca 700
wolfSSL 13:f67a6c6013ca 701 Preconditions:
wolfSSL 13:f67a6c6013ca 702 |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
wolfSSL 13:f67a6c6013ca 703 |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
wolfSSL 13:f67a6c6013ca 704
wolfSSL 13:f67a6c6013ca 705 Postconditions:
wolfSSL 13:f67a6c6013ca 706 |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
wolfSSL 13:f67a6c6013ca 707 */
wolfSSL 13:f67a6c6013ca 708
wolfSSL 13:f67a6c6013ca 709 /*
wolfSSL 13:f67a6c6013ca 710 Notes on implementation strategy:
wolfSSL 13:f67a6c6013ca 711
wolfSSL 13:f67a6c6013ca 712 Using schoolbook multiplication.
wolfSSL 13:f67a6c6013ca 713 Karatsuba would save a little in some cost models.
wolfSSL 13:f67a6c6013ca 714
wolfSSL 13:f67a6c6013ca 715 Most multiplications by 2 and 19 are 32-bit precomputations;
wolfSSL 13:f67a6c6013ca 716 cheaper than 64-bit postcomputations.
wolfSSL 13:f67a6c6013ca 717
wolfSSL 13:f67a6c6013ca 718 There is one remaining multiplication by 19 in the carry chain;
wolfSSL 13:f67a6c6013ca 719 one *19 precomputation can be merged into this,
wolfSSL 13:f67a6c6013ca 720 but the resulting data flow is considerably less clean.
wolfSSL 13:f67a6c6013ca 721
wolfSSL 13:f67a6c6013ca 722 There are 12 carries below.
wolfSSL 13:f67a6c6013ca 723 10 of them are 2-way parallelizable and vectorizable.
wolfSSL 13:f67a6c6013ca 724 Can get away with 11 carries, but then data flow is much deeper.
wolfSSL 13:f67a6c6013ca 725
wolfSSL 13:f67a6c6013ca 726 With tighter constraints on inputs can squeeze carries into int32.
wolfSSL 13:f67a6c6013ca 727 */
wolfSSL 13:f67a6c6013ca 728
wolfSSL 13:f67a6c6013ca 729 void fe_mul(fe h,const fe f,const fe g)
wolfSSL 13:f67a6c6013ca 730 {
wolfSSL 13:f67a6c6013ca 731 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 732 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 733 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 734 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 735 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 736 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 737 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 738 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 739 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 740 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 741 int32_t g0 = g[0];
wolfSSL 13:f67a6c6013ca 742 int32_t g1 = g[1];
wolfSSL 13:f67a6c6013ca 743 int32_t g2 = g[2];
wolfSSL 13:f67a6c6013ca 744 int32_t g3 = g[3];
wolfSSL 13:f67a6c6013ca 745 int32_t g4 = g[4];
wolfSSL 13:f67a6c6013ca 746 int32_t g5 = g[5];
wolfSSL 13:f67a6c6013ca 747 int32_t g6 = g[6];
wolfSSL 13:f67a6c6013ca 748 int32_t g7 = g[7];
wolfSSL 13:f67a6c6013ca 749 int32_t g8 = g[8];
wolfSSL 13:f67a6c6013ca 750 int32_t g9 = g[9];
wolfSSL 13:f67a6c6013ca 751 int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
wolfSSL 13:f67a6c6013ca 752 int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
wolfSSL 13:f67a6c6013ca 753 int32_t g3_19 = 19 * g3;
wolfSSL 13:f67a6c6013ca 754 int32_t g4_19 = 19 * g4;
wolfSSL 13:f67a6c6013ca 755 int32_t g5_19 = 19 * g5;
wolfSSL 13:f67a6c6013ca 756 int32_t g6_19 = 19 * g6;
wolfSSL 13:f67a6c6013ca 757 int32_t g7_19 = 19 * g7;
wolfSSL 13:f67a6c6013ca 758 int32_t g8_19 = 19 * g8;
wolfSSL 13:f67a6c6013ca 759 int32_t g9_19 = 19 * g9;
wolfSSL 13:f67a6c6013ca 760 int32_t f1_2 = 2 * f1;
wolfSSL 13:f67a6c6013ca 761 int32_t f3_2 = 2 * f3;
wolfSSL 13:f67a6c6013ca 762 int32_t f5_2 = 2 * f5;
wolfSSL 13:f67a6c6013ca 763 int32_t f7_2 = 2 * f7;
wolfSSL 13:f67a6c6013ca 764 int32_t f9_2 = 2 * f9;
wolfSSL 13:f67a6c6013ca 765 int64_t f0g0 = f0 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 766 int64_t f0g1 = f0 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 767 int64_t f0g2 = f0 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 768 int64_t f0g3 = f0 * (int64_t) g3;
wolfSSL 13:f67a6c6013ca 769 int64_t f0g4 = f0 * (int64_t) g4;
wolfSSL 13:f67a6c6013ca 770 int64_t f0g5 = f0 * (int64_t) g5;
wolfSSL 13:f67a6c6013ca 771 int64_t f0g6 = f0 * (int64_t) g6;
wolfSSL 13:f67a6c6013ca 772 int64_t f0g7 = f0 * (int64_t) g7;
wolfSSL 13:f67a6c6013ca 773 int64_t f0g8 = f0 * (int64_t) g8;
wolfSSL 13:f67a6c6013ca 774 int64_t f0g9 = f0 * (int64_t) g9;
wolfSSL 13:f67a6c6013ca 775 int64_t f1g0 = f1 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 776 int64_t f1g1_2 = f1_2 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 777 int64_t f1g2 = f1 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 778 int64_t f1g3_2 = f1_2 * (int64_t) g3;
wolfSSL 13:f67a6c6013ca 779 int64_t f1g4 = f1 * (int64_t) g4;
wolfSSL 13:f67a6c6013ca 780 int64_t f1g5_2 = f1_2 * (int64_t) g5;
wolfSSL 13:f67a6c6013ca 781 int64_t f1g6 = f1 * (int64_t) g6;
wolfSSL 13:f67a6c6013ca 782 int64_t f1g7_2 = f1_2 * (int64_t) g7;
wolfSSL 13:f67a6c6013ca 783 int64_t f1g8 = f1 * (int64_t) g8;
wolfSSL 13:f67a6c6013ca 784 int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 785 int64_t f2g0 = f2 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 786 int64_t f2g1 = f2 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 787 int64_t f2g2 = f2 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 788 int64_t f2g3 = f2 * (int64_t) g3;
wolfSSL 13:f67a6c6013ca 789 int64_t f2g4 = f2 * (int64_t) g4;
wolfSSL 13:f67a6c6013ca 790 int64_t f2g5 = f2 * (int64_t) g5;
wolfSSL 13:f67a6c6013ca 791 int64_t f2g6 = f2 * (int64_t) g6;
wolfSSL 13:f67a6c6013ca 792 int64_t f2g7 = f2 * (int64_t) g7;
wolfSSL 13:f67a6c6013ca 793 int64_t f2g8_19 = f2 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 794 int64_t f2g9_19 = f2 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 795 int64_t f3g0 = f3 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 796 int64_t f3g1_2 = f3_2 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 797 int64_t f3g2 = f3 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 798 int64_t f3g3_2 = f3_2 * (int64_t) g3;
wolfSSL 13:f67a6c6013ca 799 int64_t f3g4 = f3 * (int64_t) g4;
wolfSSL 13:f67a6c6013ca 800 int64_t f3g5_2 = f3_2 * (int64_t) g5;
wolfSSL 13:f67a6c6013ca 801 int64_t f3g6 = f3 * (int64_t) g6;
wolfSSL 13:f67a6c6013ca 802 int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
wolfSSL 13:f67a6c6013ca 803 int64_t f3g8_19 = f3 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 804 int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 805 int64_t f4g0 = f4 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 806 int64_t f4g1 = f4 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 807 int64_t f4g2 = f4 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 808 int64_t f4g3 = f4 * (int64_t) g3;
wolfSSL 13:f67a6c6013ca 809 int64_t f4g4 = f4 * (int64_t) g4;
wolfSSL 13:f67a6c6013ca 810 int64_t f4g5 = f4 * (int64_t) g5;
wolfSSL 13:f67a6c6013ca 811 int64_t f4g6_19 = f4 * (int64_t) g6_19;
wolfSSL 13:f67a6c6013ca 812 int64_t f4g7_19 = f4 * (int64_t) g7_19;
wolfSSL 13:f67a6c6013ca 813 int64_t f4g8_19 = f4 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 814 int64_t f4g9_19 = f4 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 815 int64_t f5g0 = f5 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 816 int64_t f5g1_2 = f5_2 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 817 int64_t f5g2 = f5 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 818 int64_t f5g3_2 = f5_2 * (int64_t) g3;
wolfSSL 13:f67a6c6013ca 819 int64_t f5g4 = f5 * (int64_t) g4;
wolfSSL 13:f67a6c6013ca 820 int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
wolfSSL 13:f67a6c6013ca 821 int64_t f5g6_19 = f5 * (int64_t) g6_19;
wolfSSL 13:f67a6c6013ca 822 int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
wolfSSL 13:f67a6c6013ca 823 int64_t f5g8_19 = f5 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 824 int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 825 int64_t f6g0 = f6 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 826 int64_t f6g1 = f6 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 827 int64_t f6g2 = f6 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 828 int64_t f6g3 = f6 * (int64_t) g3;
wolfSSL 13:f67a6c6013ca 829 int64_t f6g4_19 = f6 * (int64_t) g4_19;
wolfSSL 13:f67a6c6013ca 830 int64_t f6g5_19 = f6 * (int64_t) g5_19;
wolfSSL 13:f67a6c6013ca 831 int64_t f6g6_19 = f6 * (int64_t) g6_19;
wolfSSL 13:f67a6c6013ca 832 int64_t f6g7_19 = f6 * (int64_t) g7_19;
wolfSSL 13:f67a6c6013ca 833 int64_t f6g8_19 = f6 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 834 int64_t f6g9_19 = f6 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 835 int64_t f7g0 = f7 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 836 int64_t f7g1_2 = f7_2 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 837 int64_t f7g2 = f7 * (int64_t) g2;
wolfSSL 13:f67a6c6013ca 838 int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
wolfSSL 13:f67a6c6013ca 839 int64_t f7g4_19 = f7 * (int64_t) g4_19;
wolfSSL 13:f67a6c6013ca 840 int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
wolfSSL 13:f67a6c6013ca 841 int64_t f7g6_19 = f7 * (int64_t) g6_19;
wolfSSL 13:f67a6c6013ca 842 int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
wolfSSL 13:f67a6c6013ca 843 int64_t f7g8_19 = f7 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 844 int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 845 int64_t f8g0 = f8 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 846 int64_t f8g1 = f8 * (int64_t) g1;
wolfSSL 13:f67a6c6013ca 847 int64_t f8g2_19 = f8 * (int64_t) g2_19;
wolfSSL 13:f67a6c6013ca 848 int64_t f8g3_19 = f8 * (int64_t) g3_19;
wolfSSL 13:f67a6c6013ca 849 int64_t f8g4_19 = f8 * (int64_t) g4_19;
wolfSSL 13:f67a6c6013ca 850 int64_t f8g5_19 = f8 * (int64_t) g5_19;
wolfSSL 13:f67a6c6013ca 851 int64_t f8g6_19 = f8 * (int64_t) g6_19;
wolfSSL 13:f67a6c6013ca 852 int64_t f8g7_19 = f8 * (int64_t) g7_19;
wolfSSL 13:f67a6c6013ca 853 int64_t f8g8_19 = f8 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 854 int64_t f8g9_19 = f8 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 855 int64_t f9g0 = f9 * (int64_t) g0;
wolfSSL 13:f67a6c6013ca 856 int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
wolfSSL 13:f67a6c6013ca 857 int64_t f9g2_19 = f9 * (int64_t) g2_19;
wolfSSL 13:f67a6c6013ca 858 int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
wolfSSL 13:f67a6c6013ca 859 int64_t f9g4_19 = f9 * (int64_t) g4_19;
wolfSSL 13:f67a6c6013ca 860 int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
wolfSSL 13:f67a6c6013ca 861 int64_t f9g6_19 = f9 * (int64_t) g6_19;
wolfSSL 13:f67a6c6013ca 862 int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
wolfSSL 13:f67a6c6013ca 863 int64_t f9g8_19 = f9 * (int64_t) g8_19;
wolfSSL 13:f67a6c6013ca 864 int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
wolfSSL 13:f67a6c6013ca 865 int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
wolfSSL 13:f67a6c6013ca 866 int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
wolfSSL 13:f67a6c6013ca 867 int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
wolfSSL 13:f67a6c6013ca 868 int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
wolfSSL 13:f67a6c6013ca 869 int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
wolfSSL 13:f67a6c6013ca 870 int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
wolfSSL 13:f67a6c6013ca 871 int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38;
wolfSSL 13:f67a6c6013ca 872 int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19;
wolfSSL 13:f67a6c6013ca 873 int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38;
wolfSSL 13:f67a6c6013ca 874 int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ;
wolfSSL 13:f67a6c6013ca 875 int64_t carry0;
wolfSSL 13:f67a6c6013ca 876 int64_t carry1;
wolfSSL 13:f67a6c6013ca 877 int64_t carry2;
wolfSSL 13:f67a6c6013ca 878 int64_t carry3;
wolfSSL 13:f67a6c6013ca 879 int64_t carry4;
wolfSSL 13:f67a6c6013ca 880 int64_t carry5;
wolfSSL 13:f67a6c6013ca 881 int64_t carry6;
wolfSSL 13:f67a6c6013ca 882 int64_t carry7;
wolfSSL 13:f67a6c6013ca 883 int64_t carry8;
wolfSSL 13:f67a6c6013ca 884 int64_t carry9;
wolfSSL 13:f67a6c6013ca 885
wolfSSL 13:f67a6c6013ca 886 /*
wolfSSL 13:f67a6c6013ca 887 |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
wolfSSL 13:f67a6c6013ca 888 i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
wolfSSL 13:f67a6c6013ca 889 |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
wolfSSL 13:f67a6c6013ca 890 i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
wolfSSL 13:f67a6c6013ca 891 */
wolfSSL 13:f67a6c6013ca 892
wolfSSL 13:f67a6c6013ca 893 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 894 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 895 /* |h0| <= 2^25 */
wolfSSL 13:f67a6c6013ca 896 /* |h4| <= 2^25 */
wolfSSL 13:f67a6c6013ca 897 /* |h1| <= 1.71*2^59 */
wolfSSL 13:f67a6c6013ca 898 /* |h5| <= 1.71*2^59 */
wolfSSL 13:f67a6c6013ca 899
wolfSSL 13:f67a6c6013ca 900 carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
wolfSSL 13:f67a6c6013ca 901 carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
wolfSSL 13:f67a6c6013ca 902 /* |h1| <= 2^24; from now on fits into int32 */
wolfSSL 13:f67a6c6013ca 903 /* |h5| <= 2^24; from now on fits into int32 */
wolfSSL 13:f67a6c6013ca 904 /* |h2| <= 1.41*2^60 */
wolfSSL 13:f67a6c6013ca 905 /* |h6| <= 1.41*2^60 */
wolfSSL 13:f67a6c6013ca 906
wolfSSL 13:f67a6c6013ca 907 carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
wolfSSL 13:f67a6c6013ca 908 carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
wolfSSL 13:f67a6c6013ca 909 /* |h2| <= 2^25; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 910 /* |h6| <= 2^25; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 911 /* |h3| <= 1.71*2^59 */
wolfSSL 13:f67a6c6013ca 912 /* |h7| <= 1.71*2^59 */
wolfSSL 13:f67a6c6013ca 913
wolfSSL 13:f67a6c6013ca 914 carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
wolfSSL 13:f67a6c6013ca 915 carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
wolfSSL 13:f67a6c6013ca 916 /* |h3| <= 2^24; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 917 /* |h7| <= 2^24; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 918 /* |h4| <= 1.72*2^34 */
wolfSSL 13:f67a6c6013ca 919 /* |h8| <= 1.41*2^60 */
wolfSSL 13:f67a6c6013ca 920
wolfSSL 13:f67a6c6013ca 921 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 922 carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
wolfSSL 13:f67a6c6013ca 923 /* |h4| <= 2^25; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 924 /* |h8| <= 2^25; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 925 /* |h5| <= 1.01*2^24 */
wolfSSL 13:f67a6c6013ca 926 /* |h9| <= 1.71*2^59 */
wolfSSL 13:f67a6c6013ca 927
wolfSSL 13:f67a6c6013ca 928 carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
wolfSSL 13:f67a6c6013ca 929 /* |h9| <= 2^24; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 930 /* |h0| <= 1.1*2^39 */
wolfSSL 13:f67a6c6013ca 931
wolfSSL 13:f67a6c6013ca 932 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 933 /* |h0| <= 2^25; from now on fits into int32 unchanged */
wolfSSL 13:f67a6c6013ca 934 /* |h1| <= 1.01*2^24 */
wolfSSL 13:f67a6c6013ca 935
wolfSSL 13:f67a6c6013ca 936 h[0] = (int32_t)h0;
wolfSSL 13:f67a6c6013ca 937 h[1] = (int32_t)h1;
wolfSSL 13:f67a6c6013ca 938 h[2] = (int32_t)h2;
wolfSSL 13:f67a6c6013ca 939 h[3] = (int32_t)h3;
wolfSSL 13:f67a6c6013ca 940 h[4] = (int32_t)h4;
wolfSSL 13:f67a6c6013ca 941 h[5] = (int32_t)h5;
wolfSSL 13:f67a6c6013ca 942 h[6] = (int32_t)h6;
wolfSSL 13:f67a6c6013ca 943 h[7] = (int32_t)h7;
wolfSSL 13:f67a6c6013ca 944 h[8] = (int32_t)h8;
wolfSSL 13:f67a6c6013ca 945 h[9] = (int32_t)h9;
wolfSSL 13:f67a6c6013ca 946 }
wolfSSL 13:f67a6c6013ca 947
wolfSSL 13:f67a6c6013ca 948
wolfSSL 13:f67a6c6013ca 949 /*
wolfSSL 13:f67a6c6013ca 950 Replace (f,g) with (g,f) if b == 1;
wolfSSL 13:f67a6c6013ca 951 replace (f,g) with (f,g) if b == 0.
wolfSSL 13:f67a6c6013ca 952
wolfSSL 13:f67a6c6013ca 953 Preconditions: b in {0,1}.
wolfSSL 13:f67a6c6013ca 954 */
wolfSSL 13:f67a6c6013ca 955
wolfSSL 13:f67a6c6013ca 956 void fe_cswap(fe f, fe g, int b)
wolfSSL 13:f67a6c6013ca 957 {
wolfSSL 13:f67a6c6013ca 958 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 959 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 960 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 961 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 962 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 963 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 964 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 965 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 966 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 967 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 968 int32_t g0 = g[0];
wolfSSL 13:f67a6c6013ca 969 int32_t g1 = g[1];
wolfSSL 13:f67a6c6013ca 970 int32_t g2 = g[2];
wolfSSL 13:f67a6c6013ca 971 int32_t g3 = g[3];
wolfSSL 13:f67a6c6013ca 972 int32_t g4 = g[4];
wolfSSL 13:f67a6c6013ca 973 int32_t g5 = g[5];
wolfSSL 13:f67a6c6013ca 974 int32_t g6 = g[6];
wolfSSL 13:f67a6c6013ca 975 int32_t g7 = g[7];
wolfSSL 13:f67a6c6013ca 976 int32_t g8 = g[8];
wolfSSL 13:f67a6c6013ca 977 int32_t g9 = g[9];
wolfSSL 13:f67a6c6013ca 978 int32_t x0 = f0 ^ g0;
wolfSSL 13:f67a6c6013ca 979 int32_t x1 = f1 ^ g1;
wolfSSL 13:f67a6c6013ca 980 int32_t x2 = f2 ^ g2;
wolfSSL 13:f67a6c6013ca 981 int32_t x3 = f3 ^ g3;
wolfSSL 13:f67a6c6013ca 982 int32_t x4 = f4 ^ g4;
wolfSSL 13:f67a6c6013ca 983 int32_t x5 = f5 ^ g5;
wolfSSL 13:f67a6c6013ca 984 int32_t x6 = f6 ^ g6;
wolfSSL 13:f67a6c6013ca 985 int32_t x7 = f7 ^ g7;
wolfSSL 13:f67a6c6013ca 986 int32_t x8 = f8 ^ g8;
wolfSSL 13:f67a6c6013ca 987 int32_t x9 = f9 ^ g9;
wolfSSL 13:f67a6c6013ca 988 b = -b;
wolfSSL 13:f67a6c6013ca 989 x0 &= b;
wolfSSL 13:f67a6c6013ca 990 x1 &= b;
wolfSSL 13:f67a6c6013ca 991 x2 &= b;
wolfSSL 13:f67a6c6013ca 992 x3 &= b;
wolfSSL 13:f67a6c6013ca 993 x4 &= b;
wolfSSL 13:f67a6c6013ca 994 x5 &= b;
wolfSSL 13:f67a6c6013ca 995 x6 &= b;
wolfSSL 13:f67a6c6013ca 996 x7 &= b;
wolfSSL 13:f67a6c6013ca 997 x8 &= b;
wolfSSL 13:f67a6c6013ca 998 x9 &= b;
wolfSSL 13:f67a6c6013ca 999 f[0] = f0 ^ x0;
wolfSSL 13:f67a6c6013ca 1000 f[1] = f1 ^ x1;
wolfSSL 13:f67a6c6013ca 1001 f[2] = f2 ^ x2;
wolfSSL 13:f67a6c6013ca 1002 f[3] = f3 ^ x3;
wolfSSL 13:f67a6c6013ca 1003 f[4] = f4 ^ x4;
wolfSSL 13:f67a6c6013ca 1004 f[5] = f5 ^ x5;
wolfSSL 13:f67a6c6013ca 1005 f[6] = f6 ^ x6;
wolfSSL 13:f67a6c6013ca 1006 f[7] = f7 ^ x7;
wolfSSL 13:f67a6c6013ca 1007 f[8] = f8 ^ x8;
wolfSSL 13:f67a6c6013ca 1008 f[9] = f9 ^ x9;
wolfSSL 13:f67a6c6013ca 1009 g[0] = g0 ^ x0;
wolfSSL 13:f67a6c6013ca 1010 g[1] = g1 ^ x1;
wolfSSL 13:f67a6c6013ca 1011 g[2] = g2 ^ x2;
wolfSSL 13:f67a6c6013ca 1012 g[3] = g3 ^ x3;
wolfSSL 13:f67a6c6013ca 1013 g[4] = g4 ^ x4;
wolfSSL 13:f67a6c6013ca 1014 g[5] = g5 ^ x5;
wolfSSL 13:f67a6c6013ca 1015 g[6] = g6 ^ x6;
wolfSSL 13:f67a6c6013ca 1016 g[7] = g7 ^ x7;
wolfSSL 13:f67a6c6013ca 1017 g[8] = g8 ^ x8;
wolfSSL 13:f67a6c6013ca 1018 g[9] = g9 ^ x9;
wolfSSL 13:f67a6c6013ca 1019 }
wolfSSL 13:f67a6c6013ca 1020
wolfSSL 13:f67a6c6013ca 1021
wolfSSL 13:f67a6c6013ca 1022 /*
wolfSSL 13:f67a6c6013ca 1023 h = f * 121666
wolfSSL 13:f67a6c6013ca 1024 Can overlap h with f.
wolfSSL 13:f67a6c6013ca 1025
wolfSSL 13:f67a6c6013ca 1026 Preconditions:
wolfSSL 13:f67a6c6013ca 1027 |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
wolfSSL 13:f67a6c6013ca 1028
wolfSSL 13:f67a6c6013ca 1029 Postconditions:
wolfSSL 13:f67a6c6013ca 1030 |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
wolfSSL 13:f67a6c6013ca 1031 */
wolfSSL 13:f67a6c6013ca 1032
wolfSSL 13:f67a6c6013ca 1033 void fe_mul121666(fe h,fe f)
wolfSSL 13:f67a6c6013ca 1034 {
wolfSSL 13:f67a6c6013ca 1035 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 1036 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 1037 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 1038 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 1039 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 1040 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 1041 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 1042 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 1043 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 1044 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 1045 int64_t h0 = f0 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1046 int64_t h1 = f1 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1047 int64_t h2 = f2 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1048 int64_t h3 = f3 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1049 int64_t h4 = f4 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1050 int64_t h5 = f5 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1051 int64_t h6 = f6 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1052 int64_t h7 = f7 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1053 int64_t h8 = f8 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1054 int64_t h9 = f9 * (int64_t) 121666;
wolfSSL 13:f67a6c6013ca 1055 int64_t carry0;
wolfSSL 13:f67a6c6013ca 1056 int64_t carry1;
wolfSSL 13:f67a6c6013ca 1057 int64_t carry2;
wolfSSL 13:f67a6c6013ca 1058 int64_t carry3;
wolfSSL 13:f67a6c6013ca 1059 int64_t carry4;
wolfSSL 13:f67a6c6013ca 1060 int64_t carry5;
wolfSSL 13:f67a6c6013ca 1061 int64_t carry6;
wolfSSL 13:f67a6c6013ca 1062 int64_t carry7;
wolfSSL 13:f67a6c6013ca 1063 int64_t carry8;
wolfSSL 13:f67a6c6013ca 1064 int64_t carry9;
wolfSSL 13:f67a6c6013ca 1065
wolfSSL 13:f67a6c6013ca 1066 carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
wolfSSL 13:f67a6c6013ca 1067 carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
wolfSSL 13:f67a6c6013ca 1068 carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
wolfSSL 13:f67a6c6013ca 1069 carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
wolfSSL 13:f67a6c6013ca 1070 carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
wolfSSL 13:f67a6c6013ca 1071
wolfSSL 13:f67a6c6013ca 1072 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 1073 carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
wolfSSL 13:f67a6c6013ca 1074 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 1075 carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
wolfSSL 13:f67a6c6013ca 1076 carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
wolfSSL 13:f67a6c6013ca 1077
wolfSSL 13:f67a6c6013ca 1078 h[0] = (int32_t)h0;
wolfSSL 13:f67a6c6013ca 1079 h[1] = (int32_t)h1;
wolfSSL 13:f67a6c6013ca 1080 h[2] = (int32_t)h2;
wolfSSL 13:f67a6c6013ca 1081 h[3] = (int32_t)h3;
wolfSSL 13:f67a6c6013ca 1082 h[4] = (int32_t)h4;
wolfSSL 13:f67a6c6013ca 1083 h[5] = (int32_t)h5;
wolfSSL 13:f67a6c6013ca 1084 h[6] = (int32_t)h6;
wolfSSL 13:f67a6c6013ca 1085 h[7] = (int32_t)h7;
wolfSSL 13:f67a6c6013ca 1086 h[8] = (int32_t)h8;
wolfSSL 13:f67a6c6013ca 1087 h[9] = (int32_t)h9;
wolfSSL 13:f67a6c6013ca 1088 }
wolfSSL 13:f67a6c6013ca 1089
wolfSSL 13:f67a6c6013ca 1090
wolfSSL 13:f67a6c6013ca 1091 /*
wolfSSL 13:f67a6c6013ca 1092 h = 2 * f * f
wolfSSL 13:f67a6c6013ca 1093 Can overlap h with f.
wolfSSL 13:f67a6c6013ca 1094
wolfSSL 13:f67a6c6013ca 1095 Preconditions:
wolfSSL 13:f67a6c6013ca 1096 |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
wolfSSL 13:f67a6c6013ca 1097
wolfSSL 13:f67a6c6013ca 1098 Postconditions:
wolfSSL 13:f67a6c6013ca 1099 |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
wolfSSL 13:f67a6c6013ca 1100 */
wolfSSL 13:f67a6c6013ca 1101
wolfSSL 13:f67a6c6013ca 1102 /*
wolfSSL 13:f67a6c6013ca 1103 See fe_mul.c for discussion of implementation strategy.
wolfSSL 13:f67a6c6013ca 1104 */
wolfSSL 13:f67a6c6013ca 1105
wolfSSL 13:f67a6c6013ca 1106 void fe_sq2(fe h,const fe f)
wolfSSL 13:f67a6c6013ca 1107 {
wolfSSL 13:f67a6c6013ca 1108 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 1109 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 1110 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 1111 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 1112 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 1113 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 1114 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 1115 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 1116 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 1117 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 1118 int32_t f0_2 = 2 * f0;
wolfSSL 13:f67a6c6013ca 1119 int32_t f1_2 = 2 * f1;
wolfSSL 13:f67a6c6013ca 1120 int32_t f2_2 = 2 * f2;
wolfSSL 13:f67a6c6013ca 1121 int32_t f3_2 = 2 * f3;
wolfSSL 13:f67a6c6013ca 1122 int32_t f4_2 = 2 * f4;
wolfSSL 13:f67a6c6013ca 1123 int32_t f5_2 = 2 * f5;
wolfSSL 13:f67a6c6013ca 1124 int32_t f6_2 = 2 * f6;
wolfSSL 13:f67a6c6013ca 1125 int32_t f7_2 = 2 * f7;
wolfSSL 13:f67a6c6013ca 1126 int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 1127 int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 1128 int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 1129 int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 1130 int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
wolfSSL 13:f67a6c6013ca 1131 int64_t f0f0 = f0 * (int64_t) f0;
wolfSSL 13:f67a6c6013ca 1132 int64_t f0f1_2 = f0_2 * (int64_t) f1;
wolfSSL 13:f67a6c6013ca 1133 int64_t f0f2_2 = f0_2 * (int64_t) f2;
wolfSSL 13:f67a6c6013ca 1134 int64_t f0f3_2 = f0_2 * (int64_t) f3;
wolfSSL 13:f67a6c6013ca 1135 int64_t f0f4_2 = f0_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 1136 int64_t f0f5_2 = f0_2 * (int64_t) f5;
wolfSSL 13:f67a6c6013ca 1137 int64_t f0f6_2 = f0_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 1138 int64_t f0f7_2 = f0_2 * (int64_t) f7;
wolfSSL 13:f67a6c6013ca 1139 int64_t f0f8_2 = f0_2 * (int64_t) f8;
wolfSSL 13:f67a6c6013ca 1140 int64_t f0f9_2 = f0_2 * (int64_t) f9;
wolfSSL 13:f67a6c6013ca 1141 int64_t f1f1_2 = f1_2 * (int64_t) f1;
wolfSSL 13:f67a6c6013ca 1142 int64_t f1f2_2 = f1_2 * (int64_t) f2;
wolfSSL 13:f67a6c6013ca 1143 int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
wolfSSL 13:f67a6c6013ca 1144 int64_t f1f4_2 = f1_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 1145 int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
wolfSSL 13:f67a6c6013ca 1146 int64_t f1f6_2 = f1_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 1147 int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
wolfSSL 13:f67a6c6013ca 1148 int64_t f1f8_2 = f1_2 * (int64_t) f8;
wolfSSL 13:f67a6c6013ca 1149 int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1150 int64_t f2f2 = f2 * (int64_t) f2;
wolfSSL 13:f67a6c6013ca 1151 int64_t f2f3_2 = f2_2 * (int64_t) f3;
wolfSSL 13:f67a6c6013ca 1152 int64_t f2f4_2 = f2_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 1153 int64_t f2f5_2 = f2_2 * (int64_t) f5;
wolfSSL 13:f67a6c6013ca 1154 int64_t f2f6_2 = f2_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 1155 int64_t f2f7_2 = f2_2 * (int64_t) f7;
wolfSSL 13:f67a6c6013ca 1156 int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 1157 int64_t f2f9_38 = f2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1158 int64_t f3f3_2 = f3_2 * (int64_t) f3;
wolfSSL 13:f67a6c6013ca 1159 int64_t f3f4_2 = f3_2 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 1160 int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
wolfSSL 13:f67a6c6013ca 1161 int64_t f3f6_2 = f3_2 * (int64_t) f6;
wolfSSL 13:f67a6c6013ca 1162 int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 1163 int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 1164 int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1165 int64_t f4f4 = f4 * (int64_t) f4;
wolfSSL 13:f67a6c6013ca 1166 int64_t f4f5_2 = f4_2 * (int64_t) f5;
wolfSSL 13:f67a6c6013ca 1167 int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
wolfSSL 13:f67a6c6013ca 1168 int64_t f4f7_38 = f4 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 1169 int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 1170 int64_t f4f9_38 = f4 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1171 int64_t f5f5_38 = f5 * (int64_t) f5_38;
wolfSSL 13:f67a6c6013ca 1172 int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
wolfSSL 13:f67a6c6013ca 1173 int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 1174 int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 1175 int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1176 int64_t f6f6_19 = f6 * (int64_t) f6_19;
wolfSSL 13:f67a6c6013ca 1177 int64_t f6f7_38 = f6 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 1178 int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 1179 int64_t f6f9_38 = f6 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1180 int64_t f7f7_38 = f7 * (int64_t) f7_38;
wolfSSL 13:f67a6c6013ca 1181 int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 1182 int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1183 int64_t f8f8_19 = f8 * (int64_t) f8_19;
wolfSSL 13:f67a6c6013ca 1184 int64_t f8f9_38 = f8 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1185 int64_t f9f9_38 = f9 * (int64_t) f9_38;
wolfSSL 13:f67a6c6013ca 1186 int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
wolfSSL 13:f67a6c6013ca 1187 int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
wolfSSL 13:f67a6c6013ca 1188 int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
wolfSSL 13:f67a6c6013ca 1189 int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
wolfSSL 13:f67a6c6013ca 1190 int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
wolfSSL 13:f67a6c6013ca 1191 int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
wolfSSL 13:f67a6c6013ca 1192 int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
wolfSSL 13:f67a6c6013ca 1193 int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
wolfSSL 13:f67a6c6013ca 1194 int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
wolfSSL 13:f67a6c6013ca 1195 int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
wolfSSL 13:f67a6c6013ca 1196 int64_t carry0;
wolfSSL 13:f67a6c6013ca 1197 int64_t carry1;
wolfSSL 13:f67a6c6013ca 1198 int64_t carry2;
wolfSSL 13:f67a6c6013ca 1199 int64_t carry3;
wolfSSL 13:f67a6c6013ca 1200 int64_t carry4;
wolfSSL 13:f67a6c6013ca 1201 int64_t carry5;
wolfSSL 13:f67a6c6013ca 1202 int64_t carry6;
wolfSSL 13:f67a6c6013ca 1203 int64_t carry7;
wolfSSL 13:f67a6c6013ca 1204 int64_t carry8;
wolfSSL 13:f67a6c6013ca 1205 int64_t carry9;
wolfSSL 13:f67a6c6013ca 1206
wolfSSL 13:f67a6c6013ca 1207 h0 += h0;
wolfSSL 13:f67a6c6013ca 1208 h1 += h1;
wolfSSL 13:f67a6c6013ca 1209 h2 += h2;
wolfSSL 13:f67a6c6013ca 1210 h3 += h3;
wolfSSL 13:f67a6c6013ca 1211 h4 += h4;
wolfSSL 13:f67a6c6013ca 1212 h5 += h5;
wolfSSL 13:f67a6c6013ca 1213 h6 += h6;
wolfSSL 13:f67a6c6013ca 1214 h7 += h7;
wolfSSL 13:f67a6c6013ca 1215 h8 += h8;
wolfSSL 13:f67a6c6013ca 1216 h9 += h9;
wolfSSL 13:f67a6c6013ca 1217
wolfSSL 13:f67a6c6013ca 1218 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 1219 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 1220
wolfSSL 13:f67a6c6013ca 1221 carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
wolfSSL 13:f67a6c6013ca 1222 carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
wolfSSL 13:f67a6c6013ca 1223
wolfSSL 13:f67a6c6013ca 1224 carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
wolfSSL 13:f67a6c6013ca 1225 carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
wolfSSL 13:f67a6c6013ca 1226
wolfSSL 13:f67a6c6013ca 1227 carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
wolfSSL 13:f67a6c6013ca 1228 carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
wolfSSL 13:f67a6c6013ca 1229
wolfSSL 13:f67a6c6013ca 1230 carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
wolfSSL 13:f67a6c6013ca 1231 carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
wolfSSL 13:f67a6c6013ca 1232
wolfSSL 13:f67a6c6013ca 1233 carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
wolfSSL 13:f67a6c6013ca 1234
wolfSSL 13:f67a6c6013ca 1235 carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
wolfSSL 13:f67a6c6013ca 1236
wolfSSL 13:f67a6c6013ca 1237 h[0] = (int32_t)h0;
wolfSSL 13:f67a6c6013ca 1238 h[1] = (int32_t)h1;
wolfSSL 13:f67a6c6013ca 1239 h[2] = (int32_t)h2;
wolfSSL 13:f67a6c6013ca 1240 h[3] = (int32_t)h3;
wolfSSL 13:f67a6c6013ca 1241 h[4] = (int32_t)h4;
wolfSSL 13:f67a6c6013ca 1242 h[5] = (int32_t)h5;
wolfSSL 13:f67a6c6013ca 1243 h[6] = (int32_t)h6;
wolfSSL 13:f67a6c6013ca 1244 h[7] = (int32_t)h7;
wolfSSL 13:f67a6c6013ca 1245 h[8] = (int32_t)h8;
wolfSSL 13:f67a6c6013ca 1246 h[9] = (int32_t)h9;
wolfSSL 13:f67a6c6013ca 1247 }
wolfSSL 13:f67a6c6013ca 1248
wolfSSL 13:f67a6c6013ca 1249
wolfSSL 13:f67a6c6013ca 1250 void fe_pow22523(fe out,const fe z)
wolfSSL 13:f67a6c6013ca 1251 {
wolfSSL 13:f67a6c6013ca 1252 fe t0;
wolfSSL 13:f67a6c6013ca 1253 fe t1;
wolfSSL 13:f67a6c6013ca 1254 fe t2;
wolfSSL 13:f67a6c6013ca 1255 int i;
wolfSSL 13:f67a6c6013ca 1256
wolfSSL 13:f67a6c6013ca 1257 fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0);
wolfSSL 13:f67a6c6013ca 1258 fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 1259 fe_mul(t1,z,t1);
wolfSSL 13:f67a6c6013ca 1260 fe_mul(t0,t0,t1);
wolfSSL 13:f67a6c6013ca 1261 fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0);
wolfSSL 13:f67a6c6013ca 1262 fe_mul(t0,t1,t0);
wolfSSL 13:f67a6c6013ca 1263 fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 1264 fe_mul(t0,t1,t0);
wolfSSL 13:f67a6c6013ca 1265 fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 1266 fe_mul(t1,t1,t0);
wolfSSL 13:f67a6c6013ca 1267 fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 1268 fe_mul(t1,t2,t1);
wolfSSL 13:f67a6c6013ca 1269 fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 1270 fe_mul(t0,t1,t0);
wolfSSL 13:f67a6c6013ca 1271 fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 1272 fe_mul(t1,t1,t0);
wolfSSL 13:f67a6c6013ca 1273 fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2);
wolfSSL 13:f67a6c6013ca 1274 fe_mul(t1,t2,t1);
wolfSSL 13:f67a6c6013ca 1275 fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1);
wolfSSL 13:f67a6c6013ca 1276 fe_mul(t0,t1,t0);
wolfSSL 13:f67a6c6013ca 1277 fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0);
wolfSSL 13:f67a6c6013ca 1278 fe_mul(out,t0,z);
wolfSSL 13:f67a6c6013ca 1279
wolfSSL 13:f67a6c6013ca 1280 return;
wolfSSL 13:f67a6c6013ca 1281 }
wolfSSL 13:f67a6c6013ca 1282
wolfSSL 13:f67a6c6013ca 1283
wolfSSL 13:f67a6c6013ca 1284 /*
wolfSSL 13:f67a6c6013ca 1285 h = -f
wolfSSL 13:f67a6c6013ca 1286
wolfSSL 13:f67a6c6013ca 1287 Preconditions:
wolfSSL 13:f67a6c6013ca 1288 |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
wolfSSL 13:f67a6c6013ca 1289
wolfSSL 13:f67a6c6013ca 1290 Postconditions:
wolfSSL 13:f67a6c6013ca 1291 |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
wolfSSL 13:f67a6c6013ca 1292 */
wolfSSL 13:f67a6c6013ca 1293
wolfSSL 13:f67a6c6013ca 1294 void fe_neg(fe h,const fe f)
wolfSSL 13:f67a6c6013ca 1295 {
wolfSSL 13:f67a6c6013ca 1296 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 1297 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 1298 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 1299 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 1300 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 1301 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 1302 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 1303 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 1304 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 1305 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 1306 int32_t h0 = -f0;
wolfSSL 13:f67a6c6013ca 1307 int32_t h1 = -f1;
wolfSSL 13:f67a6c6013ca 1308 int32_t h2 = -f2;
wolfSSL 13:f67a6c6013ca 1309 int32_t h3 = -f3;
wolfSSL 13:f67a6c6013ca 1310 int32_t h4 = -f4;
wolfSSL 13:f67a6c6013ca 1311 int32_t h5 = -f5;
wolfSSL 13:f67a6c6013ca 1312 int32_t h6 = -f6;
wolfSSL 13:f67a6c6013ca 1313 int32_t h7 = -f7;
wolfSSL 13:f67a6c6013ca 1314 int32_t h8 = -f8;
wolfSSL 13:f67a6c6013ca 1315 int32_t h9 = -f9;
wolfSSL 13:f67a6c6013ca 1316 h[0] = h0;
wolfSSL 13:f67a6c6013ca 1317 h[1] = h1;
wolfSSL 13:f67a6c6013ca 1318 h[2] = h2;
wolfSSL 13:f67a6c6013ca 1319 h[3] = h3;
wolfSSL 13:f67a6c6013ca 1320 h[4] = h4;
wolfSSL 13:f67a6c6013ca 1321 h[5] = h5;
wolfSSL 13:f67a6c6013ca 1322 h[6] = h6;
wolfSSL 13:f67a6c6013ca 1323 h[7] = h7;
wolfSSL 13:f67a6c6013ca 1324 h[8] = h8;
wolfSSL 13:f67a6c6013ca 1325 h[9] = h9;
wolfSSL 13:f67a6c6013ca 1326 }
wolfSSL 13:f67a6c6013ca 1327
wolfSSL 13:f67a6c6013ca 1328
wolfSSL 13:f67a6c6013ca 1329 /*
wolfSSL 13:f67a6c6013ca 1330 Preconditions:
wolfSSL 13:f67a6c6013ca 1331 |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
wolfSSL 13:f67a6c6013ca 1332 */
wolfSSL 13:f67a6c6013ca 1333
wolfSSL 13:f67a6c6013ca 1334 static const unsigned char zero[32] = {0};
wolfSSL 13:f67a6c6013ca 1335
wolfSSL 13:f67a6c6013ca 1336 int fe_isnonzero(const fe f)
wolfSSL 13:f67a6c6013ca 1337 {
wolfSSL 13:f67a6c6013ca 1338 unsigned char s[32];
wolfSSL 13:f67a6c6013ca 1339 fe_tobytes(s,f);
wolfSSL 13:f67a6c6013ca 1340 return ConstantCompare(s,zero,32);
wolfSSL 13:f67a6c6013ca 1341 }
wolfSSL 13:f67a6c6013ca 1342
wolfSSL 13:f67a6c6013ca 1343
wolfSSL 13:f67a6c6013ca 1344 /*
wolfSSL 13:f67a6c6013ca 1345 return 1 if f is in {1,3,5,...,q-2}
wolfSSL 13:f67a6c6013ca 1346 return 0 if f is in {0,2,4,...,q-1}
wolfSSL 13:f67a6c6013ca 1347
wolfSSL 13:f67a6c6013ca 1348 Preconditions:
wolfSSL 13:f67a6c6013ca 1349 |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
wolfSSL 13:f67a6c6013ca 1350 */
wolfSSL 13:f67a6c6013ca 1351
wolfSSL 13:f67a6c6013ca 1352 int fe_isnegative(const fe f)
wolfSSL 13:f67a6c6013ca 1353 {
wolfSSL 13:f67a6c6013ca 1354 unsigned char s[32];
wolfSSL 13:f67a6c6013ca 1355 fe_tobytes(s,f);
wolfSSL 13:f67a6c6013ca 1356 return s[0] & 1;
wolfSSL 13:f67a6c6013ca 1357 }
wolfSSL 13:f67a6c6013ca 1358
wolfSSL 13:f67a6c6013ca 1359
wolfSSL 13:f67a6c6013ca 1360 /*
wolfSSL 13:f67a6c6013ca 1361 Replace (f,g) with (g,g) if b == 1;
wolfSSL 13:f67a6c6013ca 1362 replace (f,g) with (f,g) if b == 0.
wolfSSL 13:f67a6c6013ca 1363
wolfSSL 13:f67a6c6013ca 1364 Preconditions: b in {0,1}.
wolfSSL 13:f67a6c6013ca 1365 */
wolfSSL 13:f67a6c6013ca 1366
wolfSSL 13:f67a6c6013ca 1367 void fe_cmov(fe f, const fe g, int b)
wolfSSL 13:f67a6c6013ca 1368 {
wolfSSL 13:f67a6c6013ca 1369 int32_t f0 = f[0];
wolfSSL 13:f67a6c6013ca 1370 int32_t f1 = f[1];
wolfSSL 13:f67a6c6013ca 1371 int32_t f2 = f[2];
wolfSSL 13:f67a6c6013ca 1372 int32_t f3 = f[3];
wolfSSL 13:f67a6c6013ca 1373 int32_t f4 = f[4];
wolfSSL 13:f67a6c6013ca 1374 int32_t f5 = f[5];
wolfSSL 13:f67a6c6013ca 1375 int32_t f6 = f[6];
wolfSSL 13:f67a6c6013ca 1376 int32_t f7 = f[7];
wolfSSL 13:f67a6c6013ca 1377 int32_t f8 = f[8];
wolfSSL 13:f67a6c6013ca 1378 int32_t f9 = f[9];
wolfSSL 13:f67a6c6013ca 1379 int32_t g0 = g[0];
wolfSSL 13:f67a6c6013ca 1380 int32_t g1 = g[1];
wolfSSL 13:f67a6c6013ca 1381 int32_t g2 = g[2];
wolfSSL 13:f67a6c6013ca 1382 int32_t g3 = g[3];
wolfSSL 13:f67a6c6013ca 1383 int32_t g4 = g[4];
wolfSSL 13:f67a6c6013ca 1384 int32_t g5 = g[5];
wolfSSL 13:f67a6c6013ca 1385 int32_t g6 = g[6];
wolfSSL 13:f67a6c6013ca 1386 int32_t g7 = g[7];
wolfSSL 13:f67a6c6013ca 1387 int32_t g8 = g[8];
wolfSSL 13:f67a6c6013ca 1388 int32_t g9 = g[9];
wolfSSL 13:f67a6c6013ca 1389 int32_t x0 = f0 ^ g0;
wolfSSL 13:f67a6c6013ca 1390 int32_t x1 = f1 ^ g1;
wolfSSL 13:f67a6c6013ca 1391 int32_t x2 = f2 ^ g2;
wolfSSL 13:f67a6c6013ca 1392 int32_t x3 = f3 ^ g3;
wolfSSL 13:f67a6c6013ca 1393 int32_t x4 = f4 ^ g4;
wolfSSL 13:f67a6c6013ca 1394 int32_t x5 = f5 ^ g5;
wolfSSL 13:f67a6c6013ca 1395 int32_t x6 = f6 ^ g6;
wolfSSL 13:f67a6c6013ca 1396 int32_t x7 = f7 ^ g7;
wolfSSL 13:f67a6c6013ca 1397 int32_t x8 = f8 ^ g8;
wolfSSL 13:f67a6c6013ca 1398 int32_t x9 = f9 ^ g9;
wolfSSL 13:f67a6c6013ca 1399 b = -b;
wolfSSL 13:f67a6c6013ca 1400 x0 &= b;
wolfSSL 13:f67a6c6013ca 1401 x1 &= b;
wolfSSL 13:f67a6c6013ca 1402 x2 &= b;
wolfSSL 13:f67a6c6013ca 1403 x3 &= b;
wolfSSL 13:f67a6c6013ca 1404 x4 &= b;
wolfSSL 13:f67a6c6013ca 1405 x5 &= b;
wolfSSL 13:f67a6c6013ca 1406 x6 &= b;
wolfSSL 13:f67a6c6013ca 1407 x7 &= b;
wolfSSL 13:f67a6c6013ca 1408 x8 &= b;
wolfSSL 13:f67a6c6013ca 1409 x9 &= b;
wolfSSL 13:f67a6c6013ca 1410 f[0] = f0 ^ x0;
wolfSSL 13:f67a6c6013ca 1411 f[1] = f1 ^ x1;
wolfSSL 13:f67a6c6013ca 1412 f[2] = f2 ^ x2;
wolfSSL 13:f67a6c6013ca 1413 f[3] = f3 ^ x3;
wolfSSL 13:f67a6c6013ca 1414 f[4] = f4 ^ x4;
wolfSSL 13:f67a6c6013ca 1415 f[5] = f5 ^ x5;
wolfSSL 13:f67a6c6013ca 1416 f[6] = f6 ^ x6;
wolfSSL 13:f67a6c6013ca 1417 f[7] = f7 ^ x7;
wolfSSL 13:f67a6c6013ca 1418 f[8] = f8 ^ x8;
wolfSSL 13:f67a6c6013ca 1419 f[9] = f9 ^ x9;
wolfSSL 13:f67a6c6013ca 1420 }
wolfSSL 13:f67a6c6013ca 1421 #endif
wolfSSL 13:f67a6c6013ca 1422
wolfSSL 13:f67a6c6013ca 1423 #endif /* !CURVE25519_SMALL || !ED25519_SMALL */
wolfSSL 13:f67a6c6013ca 1424 #endif /* HAVE_CURVE25519 || HAVE_ED25519 */
wolfSSL 13:f67a6c6013ca 1425