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

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

Committer:
wolfSSL
Date:
Tue May 02 08:44:47 2017 +0000
Revision:
7:481bce714567
wolfSSL3.10.2

Who changed what in which revision?

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