Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ge_low_mem.c
00001 /* ge_low_mem.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 /* Based from Daniel Beer's public domain work. */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 #include <config.h> 00027 #endif 00028 00029 #include <wolfssl/wolfcrypt/settings.h> 00030 00031 #if defined(CURVED25519_SMALL) /* use slower code that takes less memory */ 00032 #if defined(HAVE_ED25519) 00033 00034 #include <wolfssl/wolfcrypt/ge_operations.h> 00035 #include <wolfssl/wolfcrypt/error-crypt.h> 00036 #ifdef NO_INLINE 00037 #include <wolfssl/wolfcrypt/misc.h> 00038 #else 00039 #include <wolfcrypt/src/misc.c> 00040 #endif 00041 00042 void ed25519_smult(ge_p3 *r, const ge_p3 *a, const byte *e); 00043 void ed25519_add(ge_p3 *r, const ge_p3 *a, const ge_p3 *b); 00044 void ed25519_double(ge_p3 *r, const ge_p3 *a); 00045 00046 00047 static const byte ed25519_order[F25519_SIZE] = { 00048 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 00049 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 00050 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00051 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 00052 }; 00053 00054 /*Arithmetic modulo the group order m = 2^252 + 00055 27742317777372353535851937790883648493 = 00056 7237005577332262213973186563042994240857116359379907606001950938285454250989 */ 00057 00058 static const word32 m[32] = { 00059 0xED,0xD3,0xF5,0x5C,0x1A,0x63,0x12,0x58,0xD6,0x9C,0xF7,0xA2,0xDE,0xF9, 00060 0xDE,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 00061 0x00,0x00,0x00,0x10 00062 }; 00063 00064 static const word32 mu[33] = { 00065 0x1B,0x13,0x2C,0x0A,0xA3,0xE5,0x9C,0xED,0xA7,0x29,0x63,0x08,0x5D,0x21, 00066 0x06,0x21,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 00067 0xFF,0xFF,0xFF,0xFF,0x0F 00068 }; 00069 00070 00071 int ge_compress_key(byte* out, const byte* xIn, const byte* yIn, 00072 word32 keySz) 00073 { 00074 byte tmp[F25519_SIZE]; 00075 byte parity; 00076 byte pt[32]; 00077 int i; 00078 00079 fe_copy(tmp, xIn); 00080 parity = (tmp[0] & 1) << 7; 00081 00082 fe_copy(pt, yIn); 00083 pt[31] |= parity; 00084 00085 for(i = 0; i < 32; i++) { 00086 out[32-i-1] = pt[i]; 00087 } 00088 (void)keySz; 00089 return 0; 00090 } 00091 00092 00093 static word32 lt(word32 a,word32 b) /* 16-bit inputs */ 00094 { 00095 unsigned int x = a; 00096 x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */ 00097 x >>= 31; /* 0: no; 1: yes */ 00098 return x; 00099 } 00100 00101 00102 /* Reduce coefficients of r before calling reduce_add_sub */ 00103 static void reduce_add_sub(word32 *r) 00104 { 00105 word32 pb = 0; 00106 word32 b; 00107 word32 mask; 00108 int i; 00109 unsigned char t[32]; 00110 00111 for(i=0;i<32;i++) 00112 { 00113 pb += m[i]; 00114 b = lt(r[i],pb); 00115 t[i] = r[i]-pb+(b<<8); 00116 pb = b; 00117 } 00118 mask = b - 1; 00119 for(i=0;i<32;i++) 00120 r[i] ^= mask & (r[i] ^ t[i]); 00121 } 00122 00123 00124 /* Reduce coefficients of x before calling barrett_reduce */ 00125 static void barrett_reduce(word32* r, word32 x[64]) 00126 { 00127 /* See HAC, Alg. 14.42 */ 00128 int i,j; 00129 word32 q2[66]; 00130 word32 *q3 = q2 + 33; 00131 word32 r1[33]; 00132 word32 r2[33]; 00133 word32 carry; 00134 word32 pb = 0; 00135 word32 b; 00136 00137 for (i = 0;i < 66;++i) q2[i] = 0; 00138 for (i = 0;i < 33;++i) r2[i] = 0; 00139 00140 for(i=0;i<33;i++) 00141 for(j=0;j<33;j++) 00142 if(i+j >= 31) q2[i+j] += mu[i]*x[j+31]; 00143 carry = q2[31] >> 8; 00144 q2[32] += carry; 00145 carry = q2[32] >> 8; 00146 q2[33] += carry; 00147 00148 for(i=0;i<33;i++)r1[i] = x[i]; 00149 for(i=0;i<32;i++) 00150 for(j=0;j<33;j++) 00151 if(i+j < 33) r2[i+j] += m[i]*q3[j]; 00152 00153 for(i=0;i<32;i++) 00154 { 00155 carry = r2[i] >> 8; 00156 r2[i+1] += carry; 00157 r2[i] &= 0xff; 00158 } 00159 00160 for(i=0;i<32;i++) 00161 { 00162 pb += r2[i]; 00163 b = lt(r1[i],pb); 00164 r[i] = r1[i]-pb+(b<<8); 00165 pb = b; 00166 } 00167 00168 /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 00169 * r is an unsigned type. 00170 * If so: Handle it here! 00171 */ 00172 00173 reduce_add_sub(r); 00174 reduce_add_sub(r); 00175 } 00176 00177 00178 void sc_reduce(unsigned char x[64]) 00179 { 00180 int i; 00181 word32 t[64]; 00182 word32 r[32]; 00183 for(i=0;i<64;i++) t[i] = x[i]; 00184 barrett_reduce(r, t); 00185 for(i=0;i<32;i++) x[i] = (r[i] & 0xFF); 00186 } 00187 00188 00189 void sc_muladd(byte* out, const byte* a, const byte* b, const byte* c) 00190 { 00191 00192 byte s[32]; 00193 byte e[64]; 00194 00195 XMEMSET(e, 0, sizeof(e)); 00196 XMEMCPY(e, b, 32); 00197 00198 /* Obtain e */ 00199 sc_reduce(e); 00200 00201 /* Compute s = ze + k */ 00202 fprime_mul(s, a, e, ed25519_order); 00203 fprime_add(s, c, ed25519_order); 00204 00205 XMEMCPY(out, s, 32); 00206 } 00207 00208 00209 /* Base point is (numbers wrapped): 00210 * 00211 * x = 151122213495354007725011514095885315114 00212 * 54012693041857206046113283949847762202 00213 * y = 463168356949264781694283940034751631413 00214 * 07993866256225615783033603165251855960 00215 * 00216 * y is derived by transforming the original Montgomery base (u=9). x 00217 * is the corresponding positive coordinate for the new curve equation. 00218 * t is x*y. 00219 */ 00220 const ge_p3 ed25519_base = { 00221 { 00222 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 00223 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 00224 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 00225 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21 00226 }, 00227 { 00228 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 00229 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 00230 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 00231 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 00232 }, 00233 {1, 0}, 00234 { 00235 0xa3, 0xdd, 0xb7, 0xa5, 0xb3, 0x8a, 0xde, 0x6d, 00236 0xf5, 0x52, 0x51, 0x77, 0x80, 0x9f, 0xf0, 0x20, 00237 0x7d, 0xe3, 0xab, 0x64, 0x8e, 0x4e, 0xea, 0x66, 00238 0x65, 0x76, 0x8b, 0xd7, 0x0f, 0x5f, 0x87, 0x67 00239 }, 00240 00241 }; 00242 00243 00244 const ge_p3 ed25519_neutral = { 00245 {0}, 00246 {1, 0}, 00247 {1, 0}, 00248 {0}, 00249 00250 }; 00251 00252 00253 static const byte ed25519_d[F25519_SIZE] = { 00254 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 00255 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, 00256 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 00257 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 00258 }; 00259 00260 00261 /* k = 2d */ 00262 static const byte ed25519_k[F25519_SIZE] = { 00263 0x59, 0xf1, 0xb2, 0x26, 0x94, 0x9b, 0xd6, 0xeb, 00264 0x56, 0xb1, 0x83, 0x82, 0x9a, 0x14, 0xe0, 0x00, 00265 0x30, 0xd1, 0xf3, 0xee, 0xf2, 0x80, 0x8e, 0x19, 00266 0xe7, 0xfc, 0xdf, 0x56, 0xdc, 0xd9, 0x06, 0x24 00267 }; 00268 00269 00270 void ed25519_add(ge_p3 *r, 00271 const ge_p3 *p1, const ge_p3 *p2) 00272 { 00273 /* Explicit formulas database: add-2008-hwcd-3 00274 * 00275 * source 2008 Hisil--Wong--Carter--Dawson, 00276 * http://eprint.iacr.org/2008/522, Section 3.1 00277 * appliesto extended-1 00278 * parameter k 00279 * assume k = 2 d 00280 * compute A = (Y1-X1)(Y2-X2) 00281 * compute B = (Y1+X1)(Y2+X2) 00282 * compute C = T1 k T2 00283 * compute D = Z1 2 Z2 00284 * compute E = B - A 00285 * compute F = D - C 00286 * compute G = D + C 00287 * compute H = B + A 00288 * compute X3 = E F 00289 * compute Y3 = G H 00290 * compute T3 = E H 00291 * compute Z3 = F G 00292 */ 00293 byte a[F25519_SIZE]; 00294 byte b[F25519_SIZE]; 00295 byte c[F25519_SIZE]; 00296 byte d[F25519_SIZE]; 00297 byte e[F25519_SIZE]; 00298 byte f[F25519_SIZE]; 00299 byte g[F25519_SIZE]; 00300 byte h[F25519_SIZE]; 00301 00302 /* A = (Y1-X1)(Y2-X2) */ 00303 fe_sub(c, p1->Y, p1->X); 00304 fe_sub(d, p2->Y, p2->X); 00305 fe_mul__distinct(a, c, d); 00306 00307 /* B = (Y1+X1)(Y2+X2) */ 00308 fe_add(c, p1->Y, p1->X); 00309 fe_add(d, p2->Y, p2->X); 00310 fe_mul__distinct(b, c, d); 00311 00312 /* C = T1 k T2 */ 00313 fe_mul__distinct(d, p1->T, p2->T); 00314 fe_mul__distinct(c, d, ed25519_k); 00315 00316 /* D = Z1 2 Z2 */ 00317 fe_mul__distinct(d, p1->Z, p2->Z); 00318 fe_add(d, d, d); 00319 00320 /* E = B - A */ 00321 fe_sub(e, b, a); 00322 00323 /* F = D - C */ 00324 fe_sub(f, d, c); 00325 00326 /* G = D + C */ 00327 fe_add(g, d, c); 00328 00329 /* H = B + A */ 00330 fe_add(h, b, a); 00331 00332 /* X3 = E F */ 00333 fe_mul__distinct(r->X, e, f); 00334 00335 /* Y3 = G H */ 00336 fe_mul__distinct(r->Y, g, h); 00337 00338 /* T3 = E H */ 00339 fe_mul__distinct(r->T, e, h); 00340 00341 /* Z3 = F G */ 00342 fe_mul__distinct(r->Z, f, g); 00343 } 00344 00345 00346 void ed25519_double(ge_p3 *r, const ge_p3 *p) 00347 { 00348 /* Explicit formulas database: dbl-2008-hwcd 00349 * 00350 * source 2008 Hisil--Wong--Carter--Dawson, 00351 * http://eprint.iacr.org/2008/522, Section 3.3 00352 * compute A = X1^2 00353 * compute B = Y1^2 00354 * compute C = 2 Z1^2 00355 * compute D = a A 00356 * compute E = (X1+Y1)^2-A-B 00357 * compute G = D + B 00358 * compute F = G - C 00359 * compute H = D - B 00360 * compute X3 = E F 00361 * compute Y3 = G H 00362 * compute T3 = E H 00363 * compute Z3 = F G 00364 */ 00365 byte a[F25519_SIZE]; 00366 byte b[F25519_SIZE]; 00367 byte c[F25519_SIZE]; 00368 byte e[F25519_SIZE]; 00369 byte f[F25519_SIZE]; 00370 byte g[F25519_SIZE]; 00371 byte h[F25519_SIZE]; 00372 00373 /* A = X1^2 */ 00374 fe_mul__distinct(a, p->X, p->X); 00375 00376 /* B = Y1^2 */ 00377 fe_mul__distinct(b, p->Y, p->Y); 00378 00379 /* C = 2 Z1^2 */ 00380 fe_mul__distinct(c, p->Z, p->Z); 00381 fe_add(c, c, c); 00382 00383 /* D = a A (alter sign) */ 00384 /* E = (X1+Y1)^2-A-B */ 00385 fe_add(f, p->X, p->Y); 00386 fe_mul__distinct(e, f, f); 00387 fe_sub(e, e, a); 00388 fe_sub(e, e, b); 00389 00390 /* G = D + B */ 00391 fe_sub(g, b, a); 00392 00393 /* F = G - C */ 00394 fe_sub(f, g, c); 00395 00396 /* H = D - B */ 00397 fe_neg(h, b); 00398 fe_sub(h, h, a); 00399 00400 /* X3 = E F */ 00401 fe_mul__distinct(r->X, e, f); 00402 00403 /* Y3 = G H */ 00404 fe_mul__distinct(r->Y, g, h); 00405 00406 /* T3 = E H */ 00407 fe_mul__distinct(r->T, e, h); 00408 00409 /* Z3 = F G */ 00410 fe_mul__distinct(r->Z, f, g); 00411 } 00412 00413 00414 void ed25519_smult(ge_p3 *r_out, const ge_p3 *p, const byte *e) 00415 { 00416 ge_p3 r; 00417 int i; 00418 00419 XMEMCPY(&r, &ed25519_neutral, sizeof(r)); 00420 00421 for (i = 255; i >= 0; i--) { 00422 const byte bit = (e[i >> 3] >> (i & 7)) & 1; 00423 ge_p3 s; 00424 00425 ed25519_double(&r, &r); 00426 ed25519_add(&s, &r, p); 00427 00428 fe_select(r.X, r.X, s.X, bit); 00429 fe_select(r.Y, r.Y, s.Y, bit); 00430 fe_select(r.Z, r.Z, s.Z, bit); 00431 fe_select(r.T, r.T, s.T, bit); 00432 } 00433 XMEMCPY(r_out, &r, sizeof(r)); 00434 } 00435 00436 00437 void ge_scalarmult_base(ge_p3 *R,const unsigned char *nonce) 00438 { 00439 ed25519_smult(R, &ed25519_base, nonce); 00440 } 00441 00442 00443 /* pack the point h into array s */ 00444 void ge_p3_tobytes(unsigned char *s,const ge_p3 *h) 00445 { 00446 byte x[F25519_SIZE]; 00447 byte y[F25519_SIZE]; 00448 byte z1[F25519_SIZE]; 00449 byte parity; 00450 00451 fe_inv__distinct(z1, h->Z); 00452 fe_mul__distinct(x, h->X, z1); 00453 fe_mul__distinct(y, h->Y, z1); 00454 00455 fe_normalize(x); 00456 fe_normalize(y); 00457 00458 parity = (x[0] & 1) << 7; 00459 fe_copy(s, y); 00460 fe_normalize(s); 00461 s[31] |= parity; 00462 } 00463 00464 00465 /* pack the point h into array s */ 00466 void ge_tobytes(unsigned char *s,const ge_p2 *h) 00467 { 00468 byte x[F25519_SIZE]; 00469 byte y[F25519_SIZE]; 00470 byte z1[F25519_SIZE]; 00471 byte parity; 00472 00473 fe_inv__distinct(z1, h->Z); 00474 fe_mul__distinct(x, h->X, z1); 00475 fe_mul__distinct(y, h->Y, z1); 00476 00477 fe_normalize(x); 00478 fe_normalize(y); 00479 00480 parity = (x[0] & 1) << 7; 00481 fe_copy(s, y); 00482 fe_normalize(s); 00483 s[31] |= parity; 00484 } 00485 00486 00487 /* 00488 Test if the public key can be uncompressed and negate it (-X,Y,Z,-T) 00489 return 0 on success 00490 */ 00491 int ge_frombytes_negate_vartime(ge_p3 *p,const unsigned char *s) 00492 { 00493 00494 byte parity; 00495 byte x[F25519_SIZE]; 00496 byte y[F25519_SIZE]; 00497 byte a[F25519_SIZE]; 00498 byte b[F25519_SIZE]; 00499 byte c[F25519_SIZE]; 00500 int ret = 0; 00501 00502 /* unpack the key s */ 00503 parity = s[31] >> 7; 00504 fe_copy(y, s); 00505 y[31] &= 127; 00506 00507 fe_mul__distinct(c, y, y); 00508 fe_mul__distinct(b, c, ed25519_d); 00509 fe_add(a, b, f25519_one); 00510 fe_inv__distinct(b, a); 00511 fe_sub(a, c, f25519_one); 00512 fe_mul__distinct(c, a, b); 00513 fe_sqrt(a, c); 00514 fe_neg(b, a); 00515 fe_select(x, a, b, (a[0] ^ parity) & 1); 00516 00517 /* test that x^2 is equal to c */ 00518 fe_mul__distinct(a, x, x); 00519 fe_normalize(a); 00520 fe_normalize(c); 00521 ret |= ConstantCompare(a, c, F25519_SIZE); 00522 00523 /* project the key s onto p */ 00524 fe_copy(p->X, x); 00525 fe_copy(p->Y, y); 00526 fe_load(p->Z, 1); 00527 fe_mul__distinct(p->T, x, y); 00528 00529 /* negate, the point becomes (-X,Y,Z,-T) */ 00530 fe_neg(p->X,p->X); 00531 fe_neg(p->T,p->T); 00532 00533 return ret; 00534 } 00535 00536 00537 int ge_double_scalarmult_vartime(ge_p2* R, const unsigned char *h, 00538 const ge_p3 *inA,const unsigned char *sig) 00539 { 00540 ge_p3 p, A; 00541 int ret = 0; 00542 00543 XMEMCPY(&A, inA, sizeof(ge_p3)); 00544 00545 /* find SB */ 00546 ed25519_smult(&p, &ed25519_base, sig); 00547 00548 /* find H(R,A,M) * -A */ 00549 ed25519_smult(&A, &A, h); 00550 00551 /* SB + -H(R,A,M)A */ 00552 ed25519_add(&A, &p, &A); 00553 00554 fe_copy(R->X, A.X); 00555 fe_copy(R->Y, A.Y); 00556 fe_copy(R->Z, A.Z); 00557 00558 return ret; 00559 } 00560 00561 #endif /* HAVE_ED25519 */ 00562 #endif /* CURVED25519_SMALL */ 00563 00564
Generated on Tue Jul 12 2022 15:55:18 by
1.7.2