github.com/jiajun1992/watercarver@v0.0.0-20191031150618-dfc2b17c0c4a/StadiumForWaterCarver/src/ed.c (about) 1 #include <stddef.h> 2 #include <stdio.h> 3 4 // interface-needed 5 6 typedef uint64_t bignum256modm_element_t; 7 8 static void ed25519_randombytes_unsafe (void *p, size_t len); 9 static void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y); 10 static void expand_raw256_modm(bignum256modm out, const unsigned char in[32]); 11 static void contract256_modm(unsigned char out[32], const bignum256modm in); 12 13 static int ge25519_unpack_vartime(ge25519 *r, const unsigned char p[32]); 14 static int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]); 15 static void ge25519_pack(unsigned char r[32], const ge25519 *p); 16 static void ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q); 17 18 inline __attribute__((always_inline)) 19 static void curve25519_copy(bignum25519 out, const bignum25519 in); 20 inline __attribute__((always_inline)) 21 static void curve25519_neg(bignum25519 out, const bignum25519 a); 22 inline __attribute__((always_inline)) 23 static void curve25519_mul(bignum25519 out, const bignum25519 in2, const bignum25519 in); 24 25 // ??? 26 #include <stdlib.h> 27 #include <string.h> 28 29 typedef struct ge25519_pniels_t { 30 bignum25519 ysubx, xaddy, z, t2d; 31 } ge25519_pniels; 32 33 typedef struct ge25519_p1p1_t { 34 bignum25519 x, y, z, t; 35 } ge25519_p1p1; 36 37 static void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize); 38 39 static void ge25519_double(ge25519 *r, const ge25519 *p); 40 static void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p); 41 static void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p); 42 static void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p); 43 static void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r); 44 static void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q); 45 static void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit); 46 47 static void 48 ge25519_scale_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1) { 49 //printf("p1.x = %s\n s1 = %s\n", p1->x, s1); 50 signed char slide1[256]; 51 ge25519_pniels pre1[(1<<(5 -2))]; 52 ge25519 d1; 53 ge25519_p1p1 t; 54 int32_t i; 55 56 contract256_slidingwindow_modm(slide1, s1, 5); 57 58 ge25519_double(&d1, p1); 59 ge25519_full_to_pniels(pre1, p1); 60 for (i = 0; i < (1<<(5 -2)) - 1; i++) 61 ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]); 62 63 64 memset(r, 0, sizeof(ge25519)); 65 r->y[0] = 1; 66 r->z[0] = 1; 67 68 i = 255; 69 while ((i >= 0) && !(slide1[i])) 70 i--; 71 72 for (; i >= 1; i--) { 73 ge25519_double_p1p1(&t, r); 74 75 if (slide1[i]) { 76 int index = abs(slide1[i]) / 2; 77 ge25519_p1p1_to_full(r, &t); 78 ge25519_pnielsadd_p1p1(&t, r, &pre1[index], (unsigned char)slide1[i] >> 7); 79 } 80 81 ge25519_p1p1_to_partial(r, &t); 82 } 83 { 84 i = 0; 85 ge25519_double_p1p1(&t, r); 86 87 if (slide1[i]) { 88 int index = abs(slide1[i]) / 2; 89 ge25519_p1p1_to_full(r, &t); 90 ge25519_pnielsadd_p1p1(&t, r, &pre1[index], (unsigned char)slide1[i] >> 7); 91 } 92 93 ge25519_p1p1_to_full(r, &t); 94 } 95 } 96 97 98 // compile-needed 99 100 #define ALIGN(x) __attribute__((aligned(x))) 101 102 typedef struct ge25519_niels_t { 103 bignum25519 ysubx, xaddy, t2d; 104 } ge25519_niels; 105 106 #define ROTL32(a,b) (((a) << (b)) | ((a) >> (32 - b))) 107 #define ROTR32(a,b) (((a) >> (b)) | ((a) << (32 - b))) 108 static void U32TO8_LE(unsigned char *p, const uint32_t v); 109 110 111 112 // include ed25519-donna-64bit-tables.h 113 114 static const ge25519 ge25519_basepoint = { 115 {0x00062d608f25d51a,0x000412a4b4f6592a,0x00075b7171a4b31d,0x0001ff60527118fe,0x000216936d3cd6e5}, 116 {0x0006666666666658,0x0004cccccccccccc,0x0001999999999999,0x0003333333333333,0x0006666666666666}, 117 {0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000}, 118 {0x00068ab3a5b7dda3,0x00000eea2a5eadbb,0x0002af8df483c27e,0x000332b375274732,0x00067875f0fd78b7} 119 }; 120 121 static const bignum25519 ge25519_ecd = { 122 0x00034dca135978a3,0x0001a8283b156ebd,0x0005e7a26001c029,0x000739c663a03cbb,0x00052036cee2b6ff 123 }; 124 125 static const bignum25519 ge25519_ec2d = { 126 0x00069b9426b2f159,0x00035050762add7a,0x0003cf44c0038052,0x0006738cc7407977,0x0002406d9dc56dff 127 }; 128 129 static const bignum25519 ge25519_sqrtneg1 = { 130 0x00061b274a0ea0b0,0x0000d5a5fc8f189d,0x0007ef5e9cbd0c60,0x00078595a6804c9e,0x0002b8324804fc1d 131 }; 132 133 static const ge25519_niels ge25519_niels_sliding_multiples[32] = { 134 {{0x00003905d740913e,0x0000ba2817d673a2,0x00023e2827f4e67c,0x000133d2e0c21a34,0x00044fd2f9298f81},{0x000493c6f58c3b85,0x0000df7181c325f7,0x0000f50b0b3e4cb7,0x0005329385a44c32,0x00007cf9d3a33d4b},{0x00011205877aaa68,0x000479955893d579,0x00050d66309b67a0,0x0002d42d0dbee5ee,0x0006f117b689f0c6}}, 135 {{0x00011fe8a4fcd265,0x0007bcb8374faacc,0x00052f5af4ef4d4f,0x0005314098f98d10,0x0002ab91587555bd},{0x0005b0a84cee9730,0x00061d10c97155e4,0x0004059cc8096a10,0x00047a608da8014f,0x0007a164e1b9a80f},{0x0006933f0dd0d889,0x00044386bb4c4295,0x0003cb6d3162508c,0x00026368b872a2c6,0x0005a2826af12b9b}}, 136 {{0x000182c3a447d6ba,0x00022964e536eff2,0x000192821f540053,0x0002f9f19e788e5c,0x000154a7e73eb1b5},{0x0002bc4408a5bb33,0x000078ebdda05442,0x0002ffb112354123,0x000375ee8df5862d,0x0002945ccf146e20},{0x0003dbf1812a8285,0x0000fa17ba3f9797,0x0006f69cb49c3820,0x00034d5a0db3858d,0x00043aabe696b3bb}}, 137 {{0x00072c9aaa3221b1,0x000267774474f74d,0x000064b0e9b28085,0x0003f04ef53b27c9,0x0001d6edd5d2e531},{0x00025cd0944ea3bf,0x00075673b81a4d63,0x000150b925d1c0d4,0x00013f38d9294114,0x000461bea69283c9},{0x00036dc801b8b3a2,0x0000e0a7d4935e30,0x0001deb7cecc0d7d,0x000053a94e20dd2c,0x0007a9fbb1c6a0f9}}, 138 {{0x0006217e039d8064,0x0006dea408337e6d,0x00057ac112628206,0x000647cb65e30473,0x00049c05a51fadc9},{0x0006678aa6a8632f,0x0005ea3788d8b365,0x00021bd6d6994279,0x0007ace75919e4e3,0x00034b9ed338add7},{0x0004e8bf9045af1b,0x000514e33a45e0d6,0x0007533c5b8bfe0f,0x000583557b7e14c9,0x00073c172021b008}}, 139 {{0x00075b0249864348,0x00052ee11070262b,0x000237ae54fb5acd,0x0003bfd1d03aaab5,0x00018ab598029d5c},{0x000700848a802ade,0x0001e04605c4e5f7,0x0005c0d01b9767fb,0x0007d7889f42388b,0x0004275aae2546d8},{0x00032cc5fd6089e9,0x000426505c949b05,0x00046a18880c7ad2,0x0004a4221888ccda,0x0003dc65522b53df}}, 140 {{0x0007013b327fbf93,0x0001336eeded6a0d,0x0002b565a2bbf3af,0x000253ce89591955,0x0000267882d17602},{0x0000c222a2007f6d,0x000356b79bdb77ee,0x00041ee81efe12ce,0x000120a9bd07097d,0x000234fd7eec346f},{0x0000a119732ea378,0x00063bf1ba8e2a6c,0x00069f94cc90df9a,0x000431d1779bfc48,0x000497ba6fdaa097}}, 141 {{0x0003cd86468ccf0b,0x00048553221ac081,0x0006c9464b4e0a6e,0x00075fba84180403,0x00043b5cd4218d05},{0x0006cc0313cfeaa0,0x0001a313848da499,0x0007cb534219230a,0x00039596dedefd60,0x00061e22917f12de},{0x0002762f9bd0b516,0x0001c6e7fbddcbb3,0x00075909c3ace2bd,0x00042101972d3ec9,0x000511d61210ae4d}}, 142 {{0x000386484420de87,0x0002d6b25db68102,0x000650b4962873c0,0x0004081cfd271394,0x00071a7fe6fe2482},{0x000676ef950e9d81,0x0001b81ae089f258,0x00063c4922951883,0x0002f1d54d9b3237,0x0006d325924ddb85},{0x000182b8a5c8c854,0x00073fcbe5406d8e,0x0005de3430cff451,0x000554b967ac8c41,0x0004746c4b6559ee}}, 143 {{0x000546c864741147,0x0003a1df99092690,0x0001ca8cc9f4d6bb,0x00036b7fc9cd3b03,0x000219663497db5e},{0x00077b3c6dc69a2b,0x0004edf13ec2fa6e,0x0004e85ad77beac8,0x0007dba2b28e7bda,0x0005c9a51de34fe9},{0x0000f1cf79f10e67,0x00043ccb0a2b7ea2,0x00005089dfff776a,0x0001dd84e1d38b88,0x0004804503c60822}}, 144 {{0x000021d23a36d175,0x0004fd3373c6476d,0x00020e291eeed02a,0x00062f2ecf2e7210,0x000771e098858de4},{0x00049ed02ca37fc7,0x000474c2b5957884,0x0005b8388e816683,0x0004b6c454b76be4,0x000553398a516506},{0x0002f5d278451edf,0x000730b133997342,0x0006965420eb6975,0x000308a3bfa516cf,0x0005a5ed1d68ff5a}}, 145 {{0x0005e0c558527359,0x0003395b73afd75c,0x000072afa4e4b970,0x00062214329e0f6d,0x000019b60135fefd},{0x0005122afe150e83,0x0004afc966bb0232,0x0001c478833c8268,0x00017839c3fc148f,0x00044acb897d8bf9},{0x000068145e134b83,0x0001e4860982c3cc,0x000068fb5f13d799,0x0007c9283744547e,0x000150c49fde6ad2}}, 146 {{0x0001863c9cdca868,0x0003770e295a1709,0x0000d85a3720fd13,0x0005e0ff1f71ab06,0x00078a6d7791e05f},{0x0003f29509471138,0x000729eeb4ca31cf,0x00069c22b575bfbc,0x0004910857bce212,0x0006b2b5a075bb99},{0x0007704b47a0b976,0x0002ae82e91aab17,0x00050bd6429806cd,0x00068055158fd8ea,0x000725c7ffc4ad55}}, 147 {{0x00002bf71cd098c0,0x00049dabcc6cd230,0x00040a6533f905b2,0x000573efac2eb8a4,0x0004cd54625f855f},{0x00026715d1cf99b2,0x0002205441a69c88,0x000448427dcd4b54,0x0001d191e88abdc5,0x000794cc9277cb1f},{0x0006c426c2ac5053,0x0005a65ece4b095e,0x0000c44086f26bb6,0x0007429568197885,0x0007008357b6fcc8}}, 148 {{0x00039fbb82584a34,0x00047a568f257a03,0x00014d88091ead91,0x0002145b18b1ce24,0x00013a92a3669d6d},{0x0000672738773f01,0x000752bf799f6171,0x0006b4a6dae33323,0x0007b54696ead1dc,0x00006ef7e9851ad0},{0x0003771cc0577de5,0x0003ca06bb8b9952,0x00000b81c5d50390,0x00043512340780ec,0x0003c296ddf8a2af}}, 149 {{0x00034d2ebb1f2541,0x0000e815b723ff9d,0x000286b416e25443,0x0000bdfe38d1bee8,0x0000a892c7007477},{0x000515f9d914a713,0x00073191ff2255d5,0x00054f5cc2a4bdef,0x0003dd57fc118bcf,0x0007a99d393490c7},{0x0002ed2436bda3e8,0x00002afd00f291ea,0x0000be7381dea321,0x0003e952d4b2b193,0x000286762d28302f}}, 150 {{0x00058e2bce2ef5bd,0x00068ce8f78c6f8a,0x0006ee26e39261b2,0x00033d0aa50bcf9d,0x0007686f2a3d6f17},{0x000036093ce35b25,0x0003b64d7552e9cf,0x00071ee0fe0b8460,0x00069d0660c969e5,0x00032f1da046a9d9},{0x000512a66d597c6a,0x0000609a70a57551,0x000026c08a3c464c,0x0004531fc8ee39e1,0x000561305f8a9ad2}}, 151 {{0x0002cc28e7b0c0d5,0x00077b60eb8a6ce4,0x0004042985c277a6,0x000636657b46d3eb,0x000030a1aef2c57c},{0x0004978dec92aed1,0x000069adae7ca201,0x00011ee923290f55,0x00069641898d916c,0x00000aaec53e35d4},{0x0001f773003ad2aa,0x000005642cc10f76,0x00003b48f82cfca6,0x0002403c10ee4329,0x00020be9c1c24065}}, 152 {{0x0000e44ae2025e60,0x0005f97b9727041c,0x0005683472c0ecec,0x000188882eb1ce7c,0x00069764c545067e},{0x000387d8249673a6,0x0005bea8dc927c2a,0x0005bd8ed5650ef0,0x0000ef0e3fcd40e1,0x000750ab3361f0ac},{0x00023283a2f81037,0x000477aff97e23d1,0x0000b8958dbcbb68,0x0000205b97e8add6,0x00054f96b3fb7075}}, 153 {{0x0005afc616b11ecd,0x00039f4aec8f22ef,0x0003b39e1625d92e,0x0005f85bd4508873,0x00078e6839fbe85d},{0x0005f20429669279,0x00008fafae4941f5,0x00015d83c4eb7688,0x0001cf379eca4146,0x0003d7fe9c52bb75},{0x00032df737b8856b,0x0000608342f14e06,0x0003967889d74175,0x0001211907fba550,0x00070f268f350088}}, 154 {{0x0004112070dcf355,0x0007dcff9c22e464,0x00054ada60e03325,0x00025cd98eef769a,0x000404e56c039b8c},{0x00064583b1805f47,0x00022c1baf832cd0,0x000132c01bd4d717,0x0004ecf4c3a75b8f,0x0007c0d345cfad88},{0x00071f4b8c78338a,0x00062cfc16bc2b23,0x00017cf51280d9aa,0x0003bbae5e20a95a,0x00020d754762aaec}}, 155 {{0x0004feb135b9f543,0x00063bd192ad93ae,0x00044e2ea612cdf7,0x000670f4991583ab,0x00038b8ada8790b4},{0x0007c36fc73bb758,0x0004a6c797734bd1,0x0000ef248ab3950e,0x00063154c9a53ec8,0x0002b8f1e46f3cee},{0x00004a9cdf51f95d,0x0005d963fbd596b8,0x00022d9b68ace54a,0x0004a98e8836c599,0x000049aeb32ceba1}}, 156 {{0x00067d3c63dcfe7e,0x000112f0adc81aee,0x00053df04c827165,0x0002fe5b33b430f0,0x00051c665e0c8d62},{0x00007d0b75fc7931,0x00016f4ce4ba754a,0x0005ace4c03fbe49,0x00027e0ec12a159c,0x000795ee17530f67},{0x00025b0a52ecbd81,0x0005dc0695fce4a9,0x0003b928c575047d,0x00023bf3512686e5,0x0006cd19bf49dc54}}, 157 {{0x0007619052179ca3,0x0000c16593f0afd0,0x000265c4795c7428,0x00031c40515d5442,0x0007520f3db40b2e},{0x0006612165afc386,0x0001171aa36203ff,0x0002642ea820a8aa,0x0001f3bb7b313f10,0x0005e01b3a7429e4},{0x00050be3d39357a1,0x0003ab33d294a7b6,0x0004c479ba59edb3,0x0004c30d184d326f,0x00071092c9ccef3c}}, 158 {{0x0000523f0364918c,0x000687f56d638a7b,0x00020796928ad013,0x0005d38405a54f33,0x0000ea15b03d0257},{0x0003d8ac74051dcf,0x00010ab6f543d0ad,0x0005d0f3ac0fda90,0x0005ef1d2573e5e4,0x0004173a5bb7137a},{0x00056e31f0f9218a,0x0005635f88e102f8,0x0002cbc5d969a5b8,0x000533fbc98b347a,0x0005fc565614a4e3}}, 159 {{0x0006570dc46d7ae5,0x00018a9f1b91e26d,0x000436b6183f42ab,0x000550acaa4f8198,0x00062711c414c454},{0x0002e1e67790988e,0x0001e38b9ae44912,0x000648fbb4075654,0x00028df1d840cd72,0x0003214c7409d466},{0x0001827406651770,0x0004d144f286c265,0x00017488f0ee9281,0x00019e6cdb5c760c,0x0005bea94073ecb8}}, 160 {{0x0005bf0912c89be4,0x00062fadcaf38c83,0x00025ec196b3ce2c,0x00077655ff4f017b,0x0003aacd5c148f61},{0x0000ce63f343d2f8,0x0001e0a87d1e368e,0x000045edbc019eea,0x0006979aed28d0d1,0x0004ad0785944f1b},{0x00063b34c3318301,0x0000e0e62d04d0b1,0x000676a233726701,0x00029e9a042d9769,0x0003aff0cb1d9028}}, 161 {{0x0005c7eb3a20405e,0x0005fdb5aad930f8,0x0004a757e63b8c47,0x00028e9492972456,0x000110e7e86f4cd2},{0x0006430bf4c53505,0x000264c3e4507244,0x00074c9f19a39270,0x00073f84f799bc47,0x0002ccf9f732bd99},{0x0000d89ed603f5e4,0x00051e1604018af8,0x0000b8eedc4a2218,0x00051ba98b9384d0,0x00005c557e0b9693}}, 162 {{0x0001ce311fc97e6f,0x0006023f3fb5db1f,0x0007b49775e8fc98,0x0003ad70adbf5045,0x0006e154c178fe98},{0x0006bbb089c20eb0,0x0006df41fb0b9eee,0x00051087ed87e16f,0x000102db5c9fa731,0x000289fef0841861},{0x00016336fed69abf,0x0004f066b929f9ec,0x0004e9ff9e6c5b93,0x00018c89bc4bb2ba,0x0006afbf642a95ca}}, 163 {{0x0000de0c62f5d2c1,0x00049601cf734fb5,0x0006b5c38263f0f6,0x0004623ef5b56d06,0x0000db4b851b9503},{0x00055070f913a8cc,0x000765619eac2bbc,0x0003ab5225f47459,0x00076ced14ab5b48,0x00012c093cedb801},{0x00047f9308b8190f,0x000414235c621f82,0x00031f5ff41a5a76,0x0006736773aab96d,0x00033aa8799c6635}}, 164 {{0x0007f51ebd085cf2,0x00012cfa67e3f5e1,0x0001800cf1e3d46a,0x00054337615ff0a8,0x000233c6f29e8e21},{0x0000f588fc156cb1,0x000363414da4f069,0x0007296ad9b68aea,0x0004d3711316ae43,0x000212cd0c1c8d58},{0x0004d5107f18c781,0x00064a4fd3a51a5e,0x0004f4cd0448bb37,0x000671d38543151e,0x0001db7778911914}}, 165 {{0x000352397c6bc26f,0x00018a7aa0227bbe,0x0005e68cc1ea5f8b,0x0006fe3e3a7a1d5f,0x00031ad97ad26e2a},{0x00014769dd701ab6,0x00028339f1b4b667,0x0004ab214b8ae37b,0x00025f0aefa0b0fe,0x0007ae2ca8a017d2},{0x000017ed0920b962,0x000187e33b53b6fd,0x00055829907a1463,0x000641f248e0a792,0x0001ed1fc53a6622}} 166 }; 167 168 // include ed25519-randombytes.h 169 170 /* 171 ISAAC+ "variant", the paper is not clear on operator precedence and other 172 things. This is the "first in, first out" option! 173 Not threadsafe or securely initialized, only for deterministic testing 174 */ 175 typedef struct isaacp_state_t { 176 uint32_t state[256]; 177 unsigned char buffer[1024]; 178 uint32_t a, b, c; 179 size_t left; 180 } isaacp_state; 181 182 #define isaacp_step(offset, mix) \ 183 x = mm[i + offset]; \ 184 a = (a ^ (mix)) + (mm[(i + offset + 128) & 0xff]); \ 185 y = (a ^ b) + mm[(x >> 2) & 0xff]; \ 186 mm[i + offset] = y; \ 187 b = (x + a) ^ mm[(y >> 10) & 0xff]; \ 188 U32TO8_LE(out + (i + offset) * 4, b); 189 190 static void 191 isaacp_mix(isaacp_state *st) { 192 uint32_t i, x, y; 193 uint32_t a = st->a, b = st->b, c = st->c; 194 uint32_t *mm = st->state; 195 unsigned char *out = st->buffer; 196 197 c = c + 1; 198 b = b + c; 199 200 for (i = 0; i < 256; i += 4) { 201 isaacp_step(0, ROTL32(a,13)) 202 isaacp_step(1, ROTR32(a, 6)) 203 isaacp_step(2, ROTL32(a, 2)) 204 isaacp_step(3, ROTR32(a,16)) 205 } 206 207 st->a = a; 208 st->b = b; 209 st->c = c; 210 st->left = 1024; 211 } 212 213 static void 214 isaacp_random(isaacp_state *st, void *p, size_t len) { 215 size_t use; 216 unsigned char *c = (unsigned char *)p; 217 while (len) { 218 use = (len > st->left) ? st->left : len; 219 memcpy(c, st->buffer + (sizeof(st->buffer) - st->left), use); 220 221 st->left -= use; 222 c += use; 223 len -= use; 224 225 if (!st->left) 226 isaacp_mix(st); 227 } 228 } 229 230 // void 231 static void ed25519_randombytes_unsafe (void *p, size_t len) { 232 // ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) { 233 static int initialized = 0; 234 static isaacp_state rng; 235 236 if (!initialized) { 237 memset(&rng, 0, sizeof(rng)); 238 isaacp_mix(&rng); 239 isaacp_mix(&rng); 240 initialized = 1; 241 } 242 243 isaacp_random(&rng, p, len); 244 } 245 246 // 102 "ed25519-donna-portable-identify.h" 2 247 // 2 "ed25519-donna-portable.h" 2 248 // 50 "ed25519-donna-portable.h" 249 typedef unsigned __int128 uint128_t; 250 // 91 "ed25519-donna-portable.h" 251 static inline void U32TO8_LE(unsigned char *p, const uint32_t v) { 252 p[0] = (unsigned char)(v ); 253 p[1] = (unsigned char)(v >> 8); 254 p[2] = (unsigned char)(v >> 16); 255 p[3] = (unsigned char)(v >> 24); 256 } 257 // 108 "ed25519-donna-portable.h" 258 static inline uint64_t U8TO64_LE(const unsigned char *p) { 259 return 260 (((uint64_t)(p[0]) ) | 261 ((uint64_t)(p[1]) << 8) | 262 ((uint64_t)(p[2]) << 16) | 263 ((uint64_t)(p[3]) << 24) | 264 ((uint64_t)(p[4]) << 32) | 265 ((uint64_t)(p[5]) << 40) | 266 ((uint64_t)(p[6]) << 48) | 267 ((uint64_t)(p[7]) << 56)); 268 } 269 270 static inline void U64TO8_LE(unsigned char *p, const uint64_t v) { 271 p[0] = (unsigned char)(v ); 272 p[1] = (unsigned char)(v >> 8); 273 p[2] = (unsigned char)(v >> 16); 274 p[3] = (unsigned char)(v >> 24); 275 p[4] = (unsigned char)(v >> 32); 276 p[5] = (unsigned char)(v >> 40); 277 p[6] = (unsigned char)(v >> 48); 278 p[7] = (unsigned char)(v >> 56); 279 } 280 281 // 134 "ed25519-donna-portable.h" 2 282 // 13 "ed25519-donna.h" 2 283 // 47 "ed25519-donna.h" 284 // 1 "curve25519-donna-64bit.h" 1 285 // 9 "curve25519-donna-64bit.h" 286 /* typedef uint64_t bignum25519[5]; */ 287 288 static const uint64_t reduce_mask_40 = ((uint64_t)1 << 40) - 1; 289 static const uint64_t reduce_mask_51 = ((uint64_t)1 << 51) - 1; 290 static const uint64_t reduce_mask_56 = ((uint64_t)1 << 56) - 1; 291 292 293 inline __attribute__((always_inline)) static void 294 curve25519_copy(bignum25519 out, const bignum25519 in) { 295 out[0] = in[0]; 296 out[1] = in[1]; 297 out[2] = in[2]; 298 out[3] = in[3]; 299 out[4] = in[4]; 300 } 301 302 303 inline __attribute__((always_inline)) static void 304 curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { 305 out[0] = a[0] + b[0]; 306 out[1] = a[1] + b[1]; 307 out[2] = a[2] + b[2]; 308 out[3] = a[3] + b[3]; 309 out[4] = a[4] + b[4]; 310 } 311 312 313 inline __attribute__((always_inline)) static void 314 curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { 315 out[0] = a[0] + b[0]; 316 out[1] = a[1] + b[1]; 317 out[2] = a[2] + b[2]; 318 out[3] = a[3] + b[3]; 319 out[4] = a[4] + b[4]; 320 } 321 322 inline __attribute__((always_inline)) static void 323 curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { 324 uint64_t c; 325 out[0] = a[0] + b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; 326 out[1] = a[1] + b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; 327 out[2] = a[2] + b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; 328 out[3] = a[3] + b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; 329 out[4] = a[4] + b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; 330 out[0] += c * 19; 331 } 332 333 334 static const uint64_t twoP0 = 0x0fffffffffffda; 335 static const uint64_t twoP1234 = 0x0ffffffffffffe; 336 static const uint64_t fourP0 = 0x1fffffffffffb4; 337 static const uint64_t fourP1234 = 0x1ffffffffffffc; 338 339 340 inline __attribute__((always_inline)) static void 341 curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { 342 out[0] = a[0] + twoP0 - b[0]; 343 out[1] = a[1] + twoP1234 - b[1]; 344 out[2] = a[2] + twoP1234 - b[2]; 345 out[3] = a[3] + twoP1234 - b[3]; 346 out[4] = a[4] + twoP1234 - b[4]; 347 } 348 349 350 inline __attribute__((always_inline)) static void 351 curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { 352 out[0] = a[0] + fourP0 - b[0]; 353 out[1] = a[1] + fourP1234 - b[1]; 354 out[2] = a[2] + fourP1234 - b[2]; 355 out[3] = a[3] + fourP1234 - b[3]; 356 out[4] = a[4] + fourP1234 - b[4]; 357 } 358 359 inline __attribute__((always_inline)) static void 360 curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { 361 uint64_t c; 362 out[0] = a[0] + fourP0 - b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; 363 out[1] = a[1] + fourP1234 - b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; 364 out[2] = a[2] + fourP1234 - b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; 365 out[3] = a[3] + fourP1234 - b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; 366 out[4] = a[4] + fourP1234 - b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; 367 out[0] += c * 19; 368 } 369 370 371 inline __attribute__((always_inline)) static void 372 curve25519_neg(bignum25519 out, const bignum25519 a) { 373 uint64_t c; 374 out[0] = twoP0 - a[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; 375 out[1] = twoP1234 - a[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; 376 out[2] = twoP1234 - a[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; 377 out[3] = twoP1234 - a[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; 378 out[4] = twoP1234 - a[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; 379 out[0] += c * 19; 380 } 381 382 383 inline __attribute__((always_inline)) static void 384 curve25519_mul(bignum25519 out, const bignum25519 in2, const bignum25519 in) { 385 386 387 388 uint128_t t[5]; 389 uint64_t r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c; 390 391 r0 = in[0]; 392 r1 = in[1]; 393 r2 = in[2]; 394 r3 = in[3]; 395 r4 = in[4]; 396 397 s0 = in2[0]; 398 s1 = in2[1]; 399 s2 = in2[2]; 400 s3 = in2[3]; 401 s4 = in2[4]; 402 403 404 t[0] = ((uint128_t) r0) * s0; 405 t[1] = ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0; 406 t[2] = ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * s1; 407 t[3] = ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * s2 + ((uint128_t) r2) * s1; 408 t[4] = ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2; 409 // 140 "curve25519-donna-64bit.h" 410 r1 *= 19; 411 r2 *= 19; 412 r3 *= 19; 413 r4 *= 19; 414 415 416 t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * s3 + ((uint128_t) r3) * s2; 417 t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * s3; 418 t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4; 419 t[3] += ((uint128_t) r4) * s4; 420 // 158 "curve25519-donna-64bit.h" 421 r0 = ((uint64_t)t[0]) & reduce_mask_51; c = (uint64_t)(t[0] >> (51));; 422 t[1] += (uint64_t)c; r1 = ((uint64_t)t[1]) & reduce_mask_51; c = (uint64_t)(t[1] >> (51));; 423 t[2] += (uint64_t)c; r2 = ((uint64_t)t[2]) & reduce_mask_51; c = (uint64_t)(t[2] >> (51));; 424 t[3] += (uint64_t)c; r3 = ((uint64_t)t[3]) & reduce_mask_51; c = (uint64_t)(t[3] >> (51));; 425 t[4] += (uint64_t)c; r4 = ((uint64_t)t[4]) & reduce_mask_51; c = (uint64_t)(t[4] >> (51));; 426 r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; 427 r1 += c; 428 429 out[0] = r0; 430 out[1] = r1; 431 out[2] = r2; 432 out[3] = r3; 433 out[4] = r4; 434 } 435 436 __attribute__((noinline)) static void 437 curve25519_mul_noinline(bignum25519 out, const bignum25519 in2, const bignum25519 in) { 438 curve25519_mul(out, in2, in); 439 } 440 441 442 __attribute__((noinline)) static void 443 curve25519_square_times(bignum25519 out, const bignum25519 in, uint64_t count) { 444 445 446 447 uint128_t t[5]; 448 uint64_t r0,r1,r2,r3,r4,c; 449 uint64_t d0,d1,d2,d4,d419; 450 451 r0 = in[0]; 452 r1 = in[1]; 453 r2 = in[2]; 454 r3 = in[3]; 455 r4 = in[4]; 456 457 do { 458 d0 = r0 * 2; 459 d1 = r1 * 2; 460 d2 = r2 * 2 * 19; 461 d419 = r4 * 19; 462 d4 = d419 * 2; 463 464 465 t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 )); 466 t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19)); 467 t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 )); 468 t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 )); 469 t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 )); 470 // 215 "curve25519-donna-64bit.h" 471 r0 = ((uint64_t)t[0]) & reduce_mask_51; 472 r1 = ((uint64_t)t[1]) & reduce_mask_51; c = (uint64_t)((t[0] << 13) >> 64);; r1 += c; 473 r2 = ((uint64_t)t[2]) & reduce_mask_51; c = (uint64_t)((t[1] << 13) >> 64);; r2 += c; 474 r3 = ((uint64_t)t[3]) & reduce_mask_51; c = (uint64_t)((t[2] << 13) >> 64);; r3 += c; 475 r4 = ((uint64_t)t[4]) & reduce_mask_51; c = (uint64_t)((t[3] << 13) >> 64);; r4 += c; 476 c = (uint64_t)((t[4] << 13) >> 64);; r0 += c * 19; 477 c = r0 >> 51; r0 &= reduce_mask_51; 478 r1 += c ; c = r1 >> 51; r1 &= reduce_mask_51; 479 r2 += c ; c = r2 >> 51; r2 &= reduce_mask_51; 480 r3 += c ; c = r3 >> 51; r3 &= reduce_mask_51; 481 r4 += c ; c = r4 >> 51; r4 &= reduce_mask_51; 482 r0 += c * 19; 483 } while(--count); 484 485 out[0] = r0; 486 out[1] = r1; 487 out[2] = r2; 488 out[3] = r3; 489 out[4] = r4; 490 } 491 492 inline __attribute__((always_inline)) static void 493 curve25519_square(bignum25519 out, const bignum25519 in) { 494 495 496 497 uint128_t t[5]; 498 uint64_t r0,r1,r2,r3,r4,c; 499 uint64_t d0,d1,d2,d4,d419; 500 501 r0 = in[0]; 502 r1 = in[1]; 503 r2 = in[2]; 504 r3 = in[3]; 505 r4 = in[4]; 506 507 d0 = r0 * 2; 508 d1 = r1 * 2; 509 d2 = r2 * 2 * 19; 510 d419 = r4 * 19; 511 d4 = d419 * 2; 512 513 514 t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 )); 515 t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19)); 516 t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 )); 517 t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 )); 518 t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 )); 519 // 271 "curve25519-donna-64bit.h" 520 r0 = ((uint64_t)t[0]) & reduce_mask_51; c = (uint64_t)(t[0] >> (51));; 521 t[1] += (uint64_t)c; r1 = ((uint64_t)t[1]) & reduce_mask_51; c = (uint64_t)(t[1] >> (51));; 522 t[2] += (uint64_t)c; r2 = ((uint64_t)t[2]) & reduce_mask_51; c = (uint64_t)(t[2] >> (51));; 523 t[3] += (uint64_t)c; r3 = ((uint64_t)t[3]) & reduce_mask_51; c = (uint64_t)(t[3] >> (51));; 524 t[4] += (uint64_t)c; r4 = ((uint64_t)t[4]) & reduce_mask_51; c = (uint64_t)(t[4] >> (51));; 525 r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; 526 r1 += c; 527 528 out[0] = r0; 529 out[1] = r1; 530 out[2] = r2; 531 out[3] = r3; 532 out[4] = r4; 533 } 534 535 536 inline __attribute__((always_inline)) static void 537 curve25519_expand(bignum25519 out, const unsigned char *in) { 538 static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}}; 539 uint64_t x0,x1,x2,x3; 540 541 if (endian_check.s == 1) { 542 x0 = *(uint64_t *)(in + 0); 543 x1 = *(uint64_t *)(in + 8); 544 x2 = *(uint64_t *)(in + 16); 545 x3 = *(uint64_t *)(in + 24); 546 } else { 547 // 308 "curve25519-donna-64bit.h" 548 x0 = ((((uint64_t)in[0 + 0]) ) | (((uint64_t)in[0 + 1]) << 8) | (((uint64_t)in[0 + 2]) << 16) | (((uint64_t)in[0 + 3]) << 24) | (((uint64_t)in[0 + 4]) << 32) | (((uint64_t)in[0 + 5]) << 40) | (((uint64_t)in[0 + 6]) << 48) | (((uint64_t)in[0 + 7]) << 56)); 549 x1 = ((((uint64_t)in[8 + 0]) ) | (((uint64_t)in[8 + 1]) << 8) | (((uint64_t)in[8 + 2]) << 16) | (((uint64_t)in[8 + 3]) << 24) | (((uint64_t)in[8 + 4]) << 32) | (((uint64_t)in[8 + 5]) << 40) | (((uint64_t)in[8 + 6]) << 48) | (((uint64_t)in[8 + 7]) << 56)); 550 x2 = ((((uint64_t)in[16 + 0]) ) | (((uint64_t)in[16 + 1]) << 8) | (((uint64_t)in[16 + 2]) << 16) | (((uint64_t)in[16 + 3]) << 24) | (((uint64_t)in[16 + 4]) << 32) | (((uint64_t)in[16 + 5]) << 40) | (((uint64_t)in[16 + 6]) << 48) | (((uint64_t)in[16 + 7]) << 56)); 551 x3 = ((((uint64_t)in[24 + 0]) ) | (((uint64_t)in[24 + 1]) << 8) | (((uint64_t)in[24 + 2]) << 16) | (((uint64_t)in[24 + 3]) << 24) | (((uint64_t)in[24 + 4]) << 32) | (((uint64_t)in[24 + 5]) << 40) | (((uint64_t)in[24 + 6]) << 48) | (((uint64_t)in[24 + 7]) << 56)); 552 } 553 554 out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13); 555 out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26); 556 out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39); 557 out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12); 558 out[4] = x3 & reduce_mask_51; 559 } 560 561 562 563 564 inline __attribute__((always_inline)) static void 565 curve25519_contract(unsigned char *out, const bignum25519 input) { 566 uint64_t t[5]; 567 uint64_t f, i; 568 569 t[0] = input[0]; 570 t[1] = input[1]; 571 t[2] = input[2]; 572 t[3] = input[3]; 573 t[4] = input[4]; 574 // 347 "curve25519-donna-64bit.h" 575 t[1] += t[0] >> 51; t[0] &= reduce_mask_51; t[2] += t[1] >> 51; t[1] &= reduce_mask_51; t[3] += t[2] >> 51; t[2] &= reduce_mask_51; t[4] += t[3] >> 51; t[3] &= reduce_mask_51; t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51; 576 t[1] += t[0] >> 51; t[0] &= reduce_mask_51; t[2] += t[1] >> 51; t[1] &= reduce_mask_51; t[3] += t[2] >> 51; t[2] &= reduce_mask_51; t[4] += t[3] >> 51; t[3] &= reduce_mask_51; t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51; 577 578 579 580 t[0] += 19; 581 t[1] += t[0] >> 51; t[0] &= reduce_mask_51; t[2] += t[1] >> 51; t[1] &= reduce_mask_51; t[3] += t[2] >> 51; t[2] &= reduce_mask_51; t[4] += t[3] >> 51; t[3] &= reduce_mask_51; t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51; 582 583 584 t[0] += (reduce_mask_51 + 1) - 19; 585 t[1] += (reduce_mask_51 + 1) - 1; 586 t[2] += (reduce_mask_51 + 1) - 1; 587 t[3] += (reduce_mask_51 + 1) - 1; 588 t[4] += (reduce_mask_51 + 1) - 1; 589 590 591 t[1] += t[0] >> 51; t[0] &= reduce_mask_51; t[2] += t[1] >> 51; t[1] &= reduce_mask_51; t[3] += t[2] >> 51; t[2] &= reduce_mask_51; t[4] += t[3] >> 51; t[3] &= reduce_mask_51; t[4] &= reduce_mask_51; 592 593 594 595 596 597 f = ((t[0] >> 13*0) | (t[0 +1] << (51 - 13*0))); for (i = 0; i < 8; i++, f >>= 8) *out++ = (unsigned char)f; 598 f = ((t[1] >> 13*1) | (t[1 +1] << (51 - 13*1))); for (i = 0; i < 8; i++, f >>= 8) *out++ = (unsigned char)f; 599 f = ((t[2] >> 13*2) | (t[2 +1] << (51 - 13*2))); for (i = 0; i < 8; i++, f >>= 8) *out++ = (unsigned char)f; 600 f = ((t[3] >> 13*3) | (t[3 +1] << (51 - 13*3))); for (i = 0; i < 8; i++, f >>= 8) *out++ = (unsigned char)f; 601 } 602 603 604 605 606 inline __attribute__((always_inline)) static void 607 curve25519_move_conditional_bytes(uint8_t out[96], const uint8_t in[96], uint64_t flag) { 608 const uint64_t nb = flag - 1, b = ~nb; 609 const uint64_t *inq = (const uint64_t *)in; 610 uint64_t *outq = (uint64_t *)out; 611 outq[0] = (outq[0] & nb) | (inq[0] & b); 612 outq[1] = (outq[1] & nb) | (inq[1] & b); 613 outq[2] = (outq[2] & nb) | (inq[2] & b); 614 outq[3] = (outq[3] & nb) | (inq[3] & b); 615 outq[4] = (outq[4] & nb) | (inq[4] & b); 616 outq[5] = (outq[5] & nb) | (inq[5] & b); 617 outq[6] = (outq[6] & nb) | (inq[6] & b); 618 outq[7] = (outq[7] & nb) | (inq[7] & b); 619 outq[8] = (outq[8] & nb) | (inq[8] & b); 620 outq[9] = (outq[9] & nb) | (inq[9] & b); 621 outq[10] = (outq[10] & nb) | (inq[10] & b); 622 outq[11] = (outq[11] & nb) | (inq[11] & b); 623 } 624 625 626 inline __attribute__((always_inline)) static void 627 curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint64_t iswap) { 628 const uint64_t swap = (uint64_t)(-(int64_t)iswap); 629 uint64_t x0,x1,x2,x3,x4; 630 631 x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; 632 x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; 633 x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; 634 x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; 635 x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; 636 } 637 // 48 "ed25519-donna.h" 2 638 639 640 641 642 // 1 "curve25519-donna-helpers.h" 1 643 // 12 "curve25519-donna-helpers.h" 644 static void 645 curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { 646 bignum25519 __attribute__((aligned(16))) t0,c; 647 648 649 curve25519_square_times(t0, b, 5); 650 curve25519_mul_noinline(b, t0, b); 651 curve25519_square_times(t0, b, 10); 652 curve25519_mul_noinline(c, t0, b); 653 curve25519_square_times(t0, c, 20); 654 curve25519_mul_noinline(t0, t0, c); 655 curve25519_square_times(t0, t0, 10); 656 curve25519_mul_noinline(b, t0, b); 657 curve25519_square_times(t0, b, 50); 658 curve25519_mul_noinline(c, t0, b); 659 curve25519_square_times(t0, c, 100); 660 curve25519_mul_noinline(t0, t0, c); 661 curve25519_square_times(t0, t0, 50); 662 curve25519_mul_noinline(b, t0, b); 663 } 664 665 666 667 668 static void 669 curve25519_recip(bignum25519 out, const bignum25519 z) { 670 bignum25519 __attribute__((aligned(16))) a,t0,b; 671 672 curve25519_square_times(a, z, 1); 673 curve25519_square_times(t0, a, 2); 674 curve25519_mul_noinline(b, t0, z); 675 curve25519_mul_noinline(a, b, a); 676 curve25519_square_times(t0, a, 1); 677 curve25519_mul_noinline(b, t0, b); 678 curve25519_pow_two5mtwo0_two250mtwo0(b); 679 curve25519_square_times(b, b, 5); 680 curve25519_mul_noinline(out, b, a); 681 } 682 683 684 685 686 static void 687 curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { 688 bignum25519 __attribute__((aligned(16))) b,c,t0; 689 690 curve25519_square_times(c, z, 1); 691 curve25519_square_times(t0, c, 2); 692 curve25519_mul_noinline(b, t0, z); 693 curve25519_mul_noinline(c, b, c); 694 curve25519_square_times(t0, c, 1); 695 curve25519_mul_noinline(b, t0, b); 696 curve25519_pow_two5mtwo0_two250mtwo0(b); 697 curve25519_square_times(b, b, 2); 698 curve25519_mul_noinline(two252m3, b, z); 699 } 700 // 53 "ed25519-donna.h" 2 701 702 703 704 // 1 "modm-donna-64bit.h" 1 705 // 18 "modm-donna-64bit.h" 706 /* typedef uint64_t bignum256modm_element_t; */ 707 /* typedef bignum256modm_element_t bignum256modm[5]; */ 708 709 static const bignum256modm modm_m = { 710 0x12631a5cf5d3ed, 711 0xf9dea2f79cd658, 712 0x000000000014de, 713 0x00000000000000, 714 0x00000010000000 715 }; 716 717 static const bignum256modm modm_mu = { 718 0x9ce5a30a2c131b, 719 0x215d086329a7ed, 720 0xffffffffeb2106, 721 0xffffffffffffff, 722 0x00000fffffffff 723 }; 724 725 static bignum256modm_element_t 726 lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { 727 return (a - b) >> 63; 728 } 729 730 static void 731 reduce256_modm(bignum256modm r) { 732 bignum256modm t; 733 bignum256modm_element_t b = 0, pb, mask; 734 735 736 pb = 0; 737 pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 56)); pb = b; 738 pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 56)); pb = b; 739 pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 56)); pb = b; 740 pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 56)); pb = b; 741 pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 32)); 742 743 744 mask = b - 1; 745 746 r[0] ^= mask & (r[0] ^ t[0]); 747 r[1] ^= mask & (r[1] ^ t[1]); 748 r[2] ^= mask & (r[2] ^ t[2]); 749 r[3] ^= mask & (r[3] ^ t[3]); 750 r[4] ^= mask & (r[4] ^ t[4]); 751 } 752 753 static void 754 barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { 755 bignum256modm q3, r2; 756 uint128_t c, mul; 757 bignum256modm_element_t f, b, pb; 758 759 760 761 762 c = (uint128_t)modm_mu[0] * q1[3]; mul = (uint128_t)modm_mu[3] * q1[0]; c += mul; mul = (uint128_t)modm_mu[1] * q1[2]; c += mul; mul = (uint128_t)modm_mu[2] * q1[1]; c += mul; f = (uint64_t)(c >> (56));; 763 c = (uint128_t)modm_mu[0] * q1[4]; c += (uint64_t)f; mul = (uint128_t)modm_mu[4] * q1[0]; c += mul; mul = (uint128_t)modm_mu[3] * q1[1]; c += mul; mul = (uint128_t)modm_mu[1] * q1[3]; c += mul; mul = (uint128_t)modm_mu[2] * q1[2]; c += mul; 764 f = ((uint64_t)c); q3[0] = (f >> 40) & 0xffff; f = (uint64_t)(c >> (56));; 765 c = (uint128_t)modm_mu[4] * q1[1]; c += (uint64_t)f; mul = (uint128_t)modm_mu[1] * q1[4]; c += mul; mul = (uint128_t)modm_mu[2] * q1[3]; c += mul; mul = (uint128_t)modm_mu[3] * q1[2]; c += mul; 766 f = ((uint64_t)c); q3[0] |= (f << 16) & 0xffffffffffffff; q3[1] = (f >> 40) & 0xffff; f = (uint64_t)(c >> (56));; 767 c = (uint128_t)modm_mu[4] * q1[2]; c += (uint64_t)f; mul = (uint128_t)modm_mu[2] * q1[4]; c += mul; mul = (uint128_t)modm_mu[3] * q1[3]; c += mul; 768 f = ((uint64_t)c); q3[1] |= (f << 16) & 0xffffffffffffff; q3[2] = (f >> 40) & 0xffff; f = (uint64_t)(c >> (56));; 769 c = (uint128_t)modm_mu[4] * q1[3]; c += (uint64_t)f; mul = (uint128_t)modm_mu[3] * q1[4]; c += mul; 770 f = ((uint64_t)c); q3[2] |= (f << 16) & 0xffffffffffffff; q3[3] = (f >> 40) & 0xffff; f = (uint64_t)(c >> (56));; 771 c = (uint128_t)modm_mu[4] * q1[4]; c += (uint64_t)f; 772 f = ((uint64_t)c); q3[3] |= (f << 16) & 0xffffffffffffff; q3[4] = (f >> 40) & 0xffff; f = (uint64_t)(c >> (56));; 773 q3[4] |= (f << 16); 774 775 c = (uint128_t)modm_m[0] * q3[0]; 776 r2[0] = ((uint64_t)c) & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 777 c = (uint128_t)modm_m[0] * q3[1]; c += (uint64_t)f; mul = (uint128_t)modm_m[1] * q3[0]; c += mul; 778 r2[1] = ((uint64_t)c) & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 779 c = (uint128_t)modm_m[0] * q3[2]; c += (uint64_t)f; mul = (uint128_t)modm_m[2] * q3[0]; c += mul; mul = (uint128_t)modm_m[1] * q3[1]; c += mul; 780 r2[2] = ((uint64_t)c) & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 781 c = (uint128_t)modm_m[0] * q3[3]; c += (uint64_t)f; mul = (uint128_t)modm_m[3] * q3[0]; c += mul; mul = (uint128_t)modm_m[1] * q3[2]; c += mul; mul = (uint128_t)modm_m[2] * q3[1]; c += mul; 782 r2[3] = ((uint64_t)c) & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 783 c = (uint128_t)modm_m[0] * q3[4]; c += (uint64_t)f; mul = (uint128_t)modm_m[4] * q3[0]; c += mul; mul = (uint128_t)modm_m[3] * q3[1]; c += mul; mul = (uint128_t)modm_m[1] * q3[3]; c += mul; mul = (uint128_t)modm_m[2] * q3[2]; c += mul; 784 r2[4] = ((uint64_t)c) & 0x0000ffffffffff; 785 786 pb = 0; 787 pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 56)); pb = b; 788 pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 56)); pb = b; 789 pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 56)); pb = b; 790 pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 56)); pb = b; 791 pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 40)); 792 793 reduce256_modm(r); 794 reduce256_modm(r); 795 } 796 797 798 static void 799 add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { 800 bignum256modm_element_t c; 801 802 c = x[0] + y[0]; r[0] = c & 0xffffffffffffff; c >>= 56; 803 c += x[1] + y[1]; r[1] = c & 0xffffffffffffff; c >>= 56; 804 c += x[2] + y[2]; r[2] = c & 0xffffffffffffff; c >>= 56; 805 c += x[3] + y[3]; r[3] = c & 0xffffffffffffff; c >>= 56; 806 c += x[4] + y[4]; r[4] = c; 807 808 reduce256_modm(r); 809 } 810 811 static void 812 mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { 813 bignum256modm q1, r1; 814 uint128_t c, mul; 815 bignum256modm_element_t f; 816 817 c = (uint128_t)x[0] * y[0]; 818 f = ((uint64_t)c); r1[0] = f & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 819 c = (uint128_t)x[0] * y[1]; c += (uint64_t)f; mul = (uint128_t)x[1] * y[0]; c += mul; 820 f = ((uint64_t)c); r1[1] = f & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 821 c = (uint128_t)x[0] * y[2]; c += (uint64_t)f; mul = (uint128_t)x[2] * y[0]; c += mul; mul = (uint128_t)x[1] * y[1]; c += mul; 822 f = ((uint64_t)c); r1[2] = f & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 823 c = (uint128_t)x[0] * y[3]; c += (uint64_t)f; mul = (uint128_t)x[3] * y[0]; c += mul; mul = (uint128_t)x[1] * y[2]; c += mul; mul = (uint128_t)x[2] * y[1]; c += mul; 824 f = ((uint64_t)c); r1[3] = f & 0xffffffffffffff; f = (uint64_t)(c >> (56));; 825 c = (uint128_t)x[0] * y[4]; c += (uint64_t)f; mul = (uint128_t)x[4] * y[0]; c += mul; mul = (uint128_t)x[3] * y[1]; c += mul; mul = (uint128_t)x[1] * y[3]; c += mul; mul = (uint128_t)x[2] * y[2]; c += mul; 826 f = ((uint64_t)c); r1[4] = f & 0x0000ffffffffff; q1[0] = (f >> 24) & 0xffffffff; f = (uint64_t)(c >> (56));; 827 c = (uint128_t)x[4] * y[1]; c += (uint64_t)f; mul = (uint128_t)x[1] * y[4]; c += mul; mul = (uint128_t)x[2] * y[3]; c += mul; mul = (uint128_t)x[3] * y[2]; c += mul; 828 f = ((uint64_t)c); q1[0] |= (f << 32) & 0xffffffffffffff; q1[1] = (f >> 24) & 0xffffffff; f = (uint64_t)(c >> (56));; 829 c = (uint128_t)x[4] * y[2]; c += (uint64_t)f; mul = (uint128_t)x[2] * y[4]; c += mul; mul = (uint128_t)x[3] * y[3]; c += mul; 830 f = ((uint64_t)c); q1[1] |= (f << 32) & 0xffffffffffffff; q1[2] = (f >> 24) & 0xffffffff; f = (uint64_t)(c >> (56));; 831 c = (uint128_t)x[4] * y[3]; c += (uint64_t)f; mul = (uint128_t)x[3] * y[4]; c += mul; 832 f = ((uint64_t)c); q1[2] |= (f << 32) & 0xffffffffffffff; q1[3] = (f >> 24) & 0xffffffff; f = (uint64_t)(c >> (56));; 833 c = (uint128_t)x[4] * y[4]; c += (uint64_t)f; 834 f = ((uint64_t)c); q1[3] |= (f << 32) & 0xffffffffffffff; q1[4] = (f >> 24) & 0xffffffff; f = (uint64_t)(c >> (56));; 835 q1[4] |= (f << 32); 836 837 barrett_reduce256_modm(r, q1, r1); 838 } 839 840 static void 841 expand256_modm(bignum256modm out, const unsigned char *in, size_t len) { 842 unsigned char work[64] = {0}; 843 bignum256modm_element_t x[16]; 844 bignum256modm q1; 845 846 memcpy(work, in, len); 847 x[0] = U8TO64_LE(work + 0); 848 x[1] = U8TO64_LE(work + 8); 849 x[2] = U8TO64_LE(work + 16); 850 x[3] = U8TO64_LE(work + 24); 851 x[4] = U8TO64_LE(work + 32); 852 x[5] = U8TO64_LE(work + 40); 853 x[6] = U8TO64_LE(work + 48); 854 x[7] = U8TO64_LE(work + 56); 855 856 857 out[0] = ( x[0]) & 0xffffffffffffff; 858 out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff; 859 out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff; 860 out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff; 861 out[4] = ((x[ 3] >> 32) | (x[ 4] << 32)) & 0x0000ffffffffff; 862 863 864 if (len < 32) 865 return; 866 867 868 q1[0] = ((x[ 3] >> 56) | (x[ 4] << 8)) & 0xffffffffffffff; 869 q1[1] = ((x[ 4] >> 48) | (x[ 5] << 16)) & 0xffffffffffffff; 870 q1[2] = ((x[ 5] >> 40) | (x[ 6] << 24)) & 0xffffffffffffff; 871 q1[3] = ((x[ 6] >> 32) | (x[ 7] << 32)) & 0xffffffffffffff; 872 q1[4] = ((x[ 7] >> 24) ); 873 874 barrett_reduce256_modm(out, q1, out); 875 } 876 877 static void 878 expand_raw256_modm(bignum256modm out, const unsigned char in[32]) { 879 bignum256modm_element_t x[4]; 880 881 x[0] = U8TO64_LE(in + 0); 882 x[1] = U8TO64_LE(in + 8); 883 x[2] = U8TO64_LE(in + 16); 884 x[3] = U8TO64_LE(in + 24); 885 886 out[0] = ( x[0]) & 0xffffffffffffff; 887 out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff; 888 out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff; 889 out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff; 890 out[4] = ((x[ 3] >> 32) ) & 0x000000ffffffff; 891 } 892 893 static void 894 contract256_modm(unsigned char out[32], const bignum256modm in) { 895 U64TO8_LE(out + 0, (in[0] ) | (in[1] << 56)); 896 U64TO8_LE(out + 8, (in[1] >> 8) | (in[2] << 48)); 897 U64TO8_LE(out + 16, (in[2] >> 16) | (in[3] << 40)); 898 U64TO8_LE(out + 24, (in[3] >> 24) | (in[4] << 32)); 899 } 900 901 static void 902 contract256_window4_modm(signed char r[64], const bignum256modm in) { 903 char carry; 904 signed char *quads = r; 905 bignum256modm_element_t i, j, v, m; 906 907 for (i = 0; i < 5; i++) { 908 v = in[i]; 909 m = (i == 4) ? 8 : 14; 910 for (j = 0; j < m; j++) { 911 *quads++ = (v & 15); 912 v >>= 4; 913 } 914 } 915 916 917 carry = 0; 918 for(i = 0; i < 63; i++) { 919 r[i] += carry; 920 r[i+1] += (r[i] >> 4); 921 r[i] &= 15; 922 carry = (r[i] >> 3); 923 r[i] -= (carry << 4); 924 } 925 r[63] += carry; 926 } 927 928 static void 929 contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { 930 int i,j,k,b; 931 int m = (1 << (windowsize - 1)) - 1, soplen = 256; 932 signed char *bits = r; 933 bignum256modm_element_t v; 934 935 936 for (i = 0; i < 4; i++) { 937 v = s[i]; 938 for (j = 0; j < 56; j++, v >>= 1) 939 *bits++ = (v & 1); 940 } 941 v = s[4]; 942 for (j = 0; j < 32; j++, v >>= 1) 943 *bits++ = (v & 1); 944 945 946 for (j = 0; j < soplen; j++) { 947 if (!r[j]) 948 continue; 949 950 for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { 951 if ((r[j] + (r[j + b] << b)) <= m) { 952 r[j] += r[j + b] << b; 953 r[j + b] = 0; 954 } else if ((r[j] - (r[j + b] << b)) >= -m) { 955 r[j] -= r[j + b] << b; 956 for (k = j + b; k < soplen; k++) { 957 if (!r[k]) { 958 r[k] = 1; 959 break; 960 } 961 r[k] = 0; 962 } 963 } else if (r[j + b]) { 964 break; 965 } 966 } 967 } 968 } 969 970 971 972 973 974 975 static void 976 sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) { 977 size_t i = 0; 978 bignum256modm_element_t carry = 0; 979 switch (limbsize) { 980 case 4: out[i] = (a[i] - b[i]) ; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; 981 case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; 982 case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; 983 case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; 984 case 0: 985 default: out[i] = (a[i] - b[i]) - carry; 986 } 987 } 988 989 990 991 static int 992 lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { 993 size_t i = 0; 994 bignum256modm_element_t t, carry = 0; 995 switch (limbsize) { 996 case 4: t = (a[i] - b[i]) ; carry = (t >> 63); i++; 997 case 3: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; 998 case 2: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; 999 case 1: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; 1000 case 0: t = (a[i] - b[i]) - carry; carry = (t >> 63); 1001 } 1002 return (int)carry; 1003 } 1004 1005 1006 static int 1007 lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { 1008 size_t i = 0; 1009 bignum256modm_element_t t, carry = 0; 1010 switch (limbsize) { 1011 case 4: t = (b[i] - a[i]) ; carry = (t >> 63); i++; 1012 case 3: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; 1013 case 2: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; 1014 case 1: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; 1015 case 0: t = (b[i] - a[i]) - carry; carry = (t >> 63); 1016 } 1017 return (int)!carry; 1018 } 1019 1020 1021 static int 1022 iszero256_modm_batch(const bignum256modm a) { 1023 size_t i; 1024 for (i = 0; i < 5; i++) 1025 if (a[i]) 1026 return 0; 1027 return 1; 1028 } 1029 1030 1031 static int 1032 isone256_modm_batch(const bignum256modm a) { 1033 size_t i; 1034 for (i = 0; i < 5; i++) 1035 if (a[i] != ((i) ? 0 : 1)) 1036 return 0; 1037 return 1; 1038 } 1039 1040 1041 static int 1042 isatmost128bits256_modm_batch(const bignum256modm a) { 1043 uint64_t mask = 1044 ((a[4] ) | 1045 (a[3] ) | 1046 (a[2] & 0xffffffffff0000)); 1047 1048 return (mask == 0); 1049 } 1050 // 57 "ed25519-donna.h" 2 1051 1052 1053 1054 1055 typedef unsigned char hash_512bits[64]; 1056 1057 1058 1059 1060 static int 1061 ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) { 1062 size_t differentbits = 0; 1063 while (len--) 1064 differentbits |= (*x++ ^ *y++); 1065 return (int) (1 & ((differentbits - 1) >> 8)); 1066 } 1067 // 81 "ed25519-donna.h" 1068 /* typedef struct ge25519_t { */ 1069 /* bignum25519 x, y, z, t; */ 1070 /* } ge25519; */ 1071 1072 /* typedef struct ge25519_p1p1_t { */ 1073 /* bignum25519 x, y, z, t; */ 1074 /* } ge25519_p1p1; */ 1075 1076 /* typedef struct ge25519_niels_t { */ 1077 /* bignum25519 ysubx, xaddy, t2d; */ 1078 /* } ge25519_niels; */ 1079 1080 /* typedef struct ge25519_pniels_t { */ 1081 /* bignum25519 ysubx, xaddy, z, t2d; */ 1082 /* } ge25519_pniels; */ 1083 1084 #include "ed25519-donna-basepoint-table.h" 1085 1086 // 101 "ed25519-donna.h" 2 1087 // 1 "ed25519-donna-64bit-x86.h" 1 1088 1089 __attribute__((noinline)) static void 1090 ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { 1091 int64_t breg = (int64_t)b; 1092 uint64_t sign = (uint64_t)breg >> 63; 1093 uint64_t mask = ~(sign - 1); 1094 uint64_t u = (breg + mask) ^ mask; 1095 1096 __asm__ __volatile__ ( 1097 1098 "movq %0, %%rax ;\n" 1099 "movd %%rax, %%xmm14 ;\n" 1100 "pshufd $0x00, %%xmm14, %%xmm14 ;\n" 1101 "pxor %%xmm0, %%xmm0 ;\n" 1102 "pxor %%xmm1, %%xmm1 ;\n" 1103 "pxor %%xmm2, %%xmm2 ;\n" 1104 "pxor %%xmm3, %%xmm3 ;\n" 1105 "pxor %%xmm4, %%xmm4 ;\n" 1106 "pxor %%xmm5, %%xmm5 ;\n" 1107 1108 1109 "movq $0, %%rax ;\n" 1110 "movd %%rax, %%xmm15 ;\n" 1111 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1112 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1113 "movq $1, %%rax ;\n" 1114 "movd %%rax, %%xmm6 ;\n" 1115 "pxor %%xmm7, %%xmm7 ;\n" 1116 "pand %%xmm15, %%xmm6 ;\n" 1117 "pand %%xmm15, %%xmm7 ;\n" 1118 "por %%xmm6, %%xmm0 ;\n" 1119 "por %%xmm7, %%xmm1 ;\n" 1120 "por %%xmm6, %%xmm2 ;\n" 1121 "por %%xmm7, %%xmm3 ;\n" 1122 1123 1124 "movq $1, %%rax ;\n" 1125 "movd %%rax, %%xmm15 ;\n" 1126 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1127 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1128 "movdqa 0(%1), %%xmm6 ;\n" 1129 "movdqa 16(%1), %%xmm7 ;\n" 1130 "movdqa 32(%1), %%xmm8 ;\n" 1131 "movdqa 48(%1), %%xmm9 ;\n" 1132 "movdqa 64(%1), %%xmm10 ;\n" 1133 "movdqa 80(%1), %%xmm11 ;\n" 1134 "pand %%xmm15, %%xmm6 ;\n" 1135 "pand %%xmm15, %%xmm7 ;\n" 1136 "pand %%xmm15, %%xmm8 ;\n" 1137 "pand %%xmm15, %%xmm9 ;\n" 1138 "pand %%xmm15, %%xmm10 ;\n" 1139 "pand %%xmm15, %%xmm11 ;\n" 1140 "por %%xmm6, %%xmm0 ;\n" 1141 "por %%xmm7, %%xmm1 ;\n" 1142 "por %%xmm8, %%xmm2 ;\n" 1143 "por %%xmm9, %%xmm3 ;\n" 1144 "por %%xmm10, %%xmm4 ;\n" 1145 "por %%xmm11, %%xmm5 ;\n" 1146 1147 1148 "movq $2, %%rax ;\n" 1149 "movd %%rax, %%xmm15 ;\n" 1150 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1151 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1152 "movdqa 96(%1), %%xmm6 ;\n" 1153 "movdqa 112(%1), %%xmm7 ;\n" 1154 "movdqa 128(%1), %%xmm8 ;\n" 1155 "movdqa 144(%1), %%xmm9 ;\n" 1156 "movdqa 160(%1), %%xmm10 ;\n" 1157 "movdqa 176(%1), %%xmm11 ;\n" 1158 "pand %%xmm15, %%xmm6 ;\n" 1159 "pand %%xmm15, %%xmm7 ;\n" 1160 "pand %%xmm15, %%xmm8 ;\n" 1161 "pand %%xmm15, %%xmm9 ;\n" 1162 "pand %%xmm15, %%xmm10 ;\n" 1163 "pand %%xmm15, %%xmm11 ;\n" 1164 "por %%xmm6, %%xmm0 ;\n" 1165 "por %%xmm7, %%xmm1 ;\n" 1166 "por %%xmm8, %%xmm2 ;\n" 1167 "por %%xmm9, %%xmm3 ;\n" 1168 "por %%xmm10, %%xmm4 ;\n" 1169 "por %%xmm11, %%xmm5 ;\n" 1170 1171 1172 "movq $3, %%rax ;\n" 1173 "movd %%rax, %%xmm15 ;\n" 1174 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1175 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1176 "movdqa 192(%1), %%xmm6 ;\n" 1177 "movdqa 208(%1), %%xmm7 ;\n" 1178 "movdqa 224(%1), %%xmm8 ;\n" 1179 "movdqa 240(%1), %%xmm9 ;\n" 1180 "movdqa 256(%1), %%xmm10 ;\n" 1181 "movdqa 272(%1), %%xmm11 ;\n" 1182 "pand %%xmm15, %%xmm6 ;\n" 1183 "pand %%xmm15, %%xmm7 ;\n" 1184 "pand %%xmm15, %%xmm8 ;\n" 1185 "pand %%xmm15, %%xmm9 ;\n" 1186 "pand %%xmm15, %%xmm10 ;\n" 1187 "pand %%xmm15, %%xmm11 ;\n" 1188 "por %%xmm6, %%xmm0 ;\n" 1189 "por %%xmm7, %%xmm1 ;\n" 1190 "por %%xmm8, %%xmm2 ;\n" 1191 "por %%xmm9, %%xmm3 ;\n" 1192 "por %%xmm10, %%xmm4 ;\n" 1193 "por %%xmm11, %%xmm5 ;\n" 1194 1195 1196 "movq $4, %%rax ;\n" 1197 "movd %%rax, %%xmm15 ;\n" 1198 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1199 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1200 "movdqa 288(%1), %%xmm6 ;\n" 1201 "movdqa 304(%1), %%xmm7 ;\n" 1202 "movdqa 320(%1), %%xmm8 ;\n" 1203 "movdqa 336(%1), %%xmm9 ;\n" 1204 "movdqa 352(%1), %%xmm10 ;\n" 1205 "movdqa 368(%1), %%xmm11 ;\n" 1206 "pand %%xmm15, %%xmm6 ;\n" 1207 "pand %%xmm15, %%xmm7 ;\n" 1208 "pand %%xmm15, %%xmm8 ;\n" 1209 "pand %%xmm15, %%xmm9 ;\n" 1210 "pand %%xmm15, %%xmm10 ;\n" 1211 "pand %%xmm15, %%xmm11 ;\n" 1212 "por %%xmm6, %%xmm0 ;\n" 1213 "por %%xmm7, %%xmm1 ;\n" 1214 "por %%xmm8, %%xmm2 ;\n" 1215 "por %%xmm9, %%xmm3 ;\n" 1216 "por %%xmm10, %%xmm4 ;\n" 1217 "por %%xmm11, %%xmm5 ;\n" 1218 1219 1220 "movq $5, %%rax ;\n" 1221 "movd %%rax, %%xmm15 ;\n" 1222 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1223 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1224 "movdqa 384(%1), %%xmm6 ;\n" 1225 "movdqa 400(%1), %%xmm7 ;\n" 1226 "movdqa 416(%1), %%xmm8 ;\n" 1227 "movdqa 432(%1), %%xmm9 ;\n" 1228 "movdqa 448(%1), %%xmm10 ;\n" 1229 "movdqa 464(%1), %%xmm11 ;\n" 1230 "pand %%xmm15, %%xmm6 ;\n" 1231 "pand %%xmm15, %%xmm7 ;\n" 1232 "pand %%xmm15, %%xmm8 ;\n" 1233 "pand %%xmm15, %%xmm9 ;\n" 1234 "pand %%xmm15, %%xmm10 ;\n" 1235 "pand %%xmm15, %%xmm11 ;\n" 1236 "por %%xmm6, %%xmm0 ;\n" 1237 "por %%xmm7, %%xmm1 ;\n" 1238 "por %%xmm8, %%xmm2 ;\n" 1239 "por %%xmm9, %%xmm3 ;\n" 1240 "por %%xmm10, %%xmm4 ;\n" 1241 "por %%xmm11, %%xmm5 ;\n" 1242 1243 1244 "movq $6, %%rax ;\n" 1245 "movd %%rax, %%xmm15 ;\n" 1246 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1247 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1248 "movdqa 480(%1), %%xmm6 ;\n" 1249 "movdqa 496(%1), %%xmm7 ;\n" 1250 "movdqa 512(%1), %%xmm8 ;\n" 1251 "movdqa 528(%1), %%xmm9 ;\n" 1252 "movdqa 544(%1), %%xmm10 ;\n" 1253 "movdqa 560(%1), %%xmm11 ;\n" 1254 "pand %%xmm15, %%xmm6 ;\n" 1255 "pand %%xmm15, %%xmm7 ;\n" 1256 "pand %%xmm15, %%xmm8 ;\n" 1257 "pand %%xmm15, %%xmm9 ;\n" 1258 "pand %%xmm15, %%xmm10 ;\n" 1259 "pand %%xmm15, %%xmm11 ;\n" 1260 "por %%xmm6, %%xmm0 ;\n" 1261 "por %%xmm7, %%xmm1 ;\n" 1262 "por %%xmm8, %%xmm2 ;\n" 1263 "por %%xmm9, %%xmm3 ;\n" 1264 "por %%xmm10, %%xmm4 ;\n" 1265 "por %%xmm11, %%xmm5 ;\n" 1266 1267 1268 "movq $7, %%rax ;\n" 1269 "movd %%rax, %%xmm15 ;\n" 1270 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1271 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1272 "movdqa 576(%1), %%xmm6 ;\n" 1273 "movdqa 592(%1), %%xmm7 ;\n" 1274 "movdqa 608(%1), %%xmm8 ;\n" 1275 "movdqa 624(%1), %%xmm9 ;\n" 1276 "movdqa 640(%1), %%xmm10 ;\n" 1277 "movdqa 656(%1), %%xmm11 ;\n" 1278 "pand %%xmm15, %%xmm6 ;\n" 1279 "pand %%xmm15, %%xmm7 ;\n" 1280 "pand %%xmm15, %%xmm8 ;\n" 1281 "pand %%xmm15, %%xmm9 ;\n" 1282 "pand %%xmm15, %%xmm10 ;\n" 1283 "pand %%xmm15, %%xmm11 ;\n" 1284 "por %%xmm6, %%xmm0 ;\n" 1285 "por %%xmm7, %%xmm1 ;\n" 1286 "por %%xmm8, %%xmm2 ;\n" 1287 "por %%xmm9, %%xmm3 ;\n" 1288 "por %%xmm10, %%xmm4 ;\n" 1289 "por %%xmm11, %%xmm5 ;\n" 1290 1291 1292 "movq $8, %%rax ;\n" 1293 "movd %%rax, %%xmm15 ;\n" 1294 "pshufd $0x00, %%xmm15, %%xmm15 ;\n" 1295 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1296 "movdqa 672(%1), %%xmm6 ;\n" 1297 "movdqa 688(%1), %%xmm7 ;\n" 1298 "movdqa 704(%1), %%xmm8 ;\n" 1299 "movdqa 720(%1), %%xmm9 ;\n" 1300 "movdqa 736(%1), %%xmm10 ;\n" 1301 "movdqa 752(%1), %%xmm11 ;\n" 1302 "pand %%xmm15, %%xmm6 ;\n" 1303 "pand %%xmm15, %%xmm7 ;\n" 1304 "pand %%xmm15, %%xmm8 ;\n" 1305 "pand %%xmm15, %%xmm9 ;\n" 1306 "pand %%xmm15, %%xmm10 ;\n" 1307 "pand %%xmm15, %%xmm11 ;\n" 1308 "por %%xmm6, %%xmm0 ;\n" 1309 "por %%xmm7, %%xmm1 ;\n" 1310 "por %%xmm8, %%xmm2 ;\n" 1311 "por %%xmm9, %%xmm3 ;\n" 1312 "por %%xmm10, %%xmm4 ;\n" 1313 "por %%xmm11, %%xmm5 ;\n" 1314 1315 1316 "movq %3, %%rax ;\n" 1317 "xorq $1, %%rax ;\n" 1318 "movd %%rax, %%xmm14 ;\n" 1319 "pxor %%xmm15, %%xmm15 ;\n" 1320 "pshufd $0x00, %%xmm14, %%xmm14 ;\n" 1321 "pxor %%xmm0, %%xmm2 ;\n" 1322 "pxor %%xmm1, %%xmm3 ;\n" 1323 "pcmpeqd %%xmm14, %%xmm15 ;\n" 1324 "movdqa %%xmm2, %%xmm6 ;\n" 1325 "movdqa %%xmm3, %%xmm7 ;\n" 1326 "pand %%xmm15, %%xmm6 ;\n" 1327 "pand %%xmm15, %%xmm7 ;\n" 1328 "pxor %%xmm6, %%xmm0 ;\n" 1329 "pxor %%xmm7, %%xmm1 ;\n" 1330 "pxor %%xmm0, %%xmm2 ;\n" 1331 "pxor %%xmm1, %%xmm3 ;\n" 1332 1333 1334 "movq $0x7ffffffffffff, %%rax ;\n" 1335 "movd %%xmm0, %%rcx ;\n" 1336 "movd %%xmm0, %%r8 ;\n" 1337 "movd %%xmm1, %%rsi ;\n" 1338 "pshufd $0xee, %%xmm0, %%xmm0 ;\n" 1339 "pshufd $0xee, %%xmm1, %%xmm1 ;\n" 1340 "movd %%xmm0, %%rdx ;\n" 1341 "movd %%xmm1, %%rdi ;\n" 1342 "shrdq $51, %%rdx, %%r8 ;\n" 1343 "shrdq $38, %%rsi, %%rdx ;\n" 1344 "shrdq $25, %%rdi, %%rsi ;\n" 1345 "shrq $12, %%rdi ;\n" 1346 "andq %%rax, %%rcx ;\n" 1347 "andq %%rax, %%r8 ;\n" 1348 "andq %%rax, %%rdx ;\n" 1349 "andq %%rax, %%rsi ;\n" 1350 "andq %%rax, %%rdi ;\n" 1351 "movq %%rcx, 0(%2) ;\n" 1352 "movq %%r8, 8(%2) ;\n" 1353 "movq %%rdx, 16(%2) ;\n" 1354 "movq %%rsi, 24(%2) ;\n" 1355 "movq %%rdi, 32(%2) ;\n" 1356 1357 1358 "movq $0x7ffffffffffff, %%rax ;\n" 1359 "movd %%xmm2, %%rcx ;\n" 1360 "movd %%xmm2, %%r8 ;\n" 1361 "movd %%xmm3, %%rsi ;\n" 1362 "pshufd $0xee, %%xmm2, %%xmm2 ;\n" 1363 "pshufd $0xee, %%xmm3, %%xmm3 ;\n" 1364 "movd %%xmm2, %%rdx ;\n" 1365 "movd %%xmm3, %%rdi ;\n" 1366 "shrdq $51, %%rdx, %%r8 ;\n" 1367 "shrdq $38, %%rsi, %%rdx ;\n" 1368 "shrdq $25, %%rdi, %%rsi ;\n" 1369 "shrq $12, %%rdi ;\n" 1370 "andq %%rax, %%rcx ;\n" 1371 "andq %%rax, %%r8 ;\n" 1372 "andq %%rax, %%rdx ;\n" 1373 "andq %%rax, %%rsi ;\n" 1374 "andq %%rax, %%rdi ;\n" 1375 "movq %%rcx, 40(%2) ;\n" 1376 "movq %%r8, 48(%2) ;\n" 1377 "movq %%rdx, 56(%2) ;\n" 1378 "movq %%rsi, 64(%2) ;\n" 1379 "movq %%rdi, 72(%2) ;\n" 1380 1381 1382 "movq $0x7ffffffffffff, %%rax ;\n" 1383 "movd %%xmm4, %%rcx ;\n" 1384 "movd %%xmm4, %%r8 ;\n" 1385 "movd %%xmm5, %%rsi ;\n" 1386 "pshufd $0xee, %%xmm4, %%xmm4 ;\n" 1387 "pshufd $0xee, %%xmm5, %%xmm5 ;\n" 1388 "movd %%xmm4, %%rdx ;\n" 1389 "movd %%xmm5, %%rdi ;\n" 1390 "shrdq $51, %%rdx, %%r8 ;\n" 1391 "shrdq $38, %%rsi, %%rdx ;\n" 1392 "shrdq $25, %%rdi, %%rsi ;\n" 1393 "shrq $12, %%rdi ;\n" 1394 "andq %%rax, %%rcx ;\n" 1395 "andq %%rax, %%r8 ;\n" 1396 "andq %%rax, %%rdx ;\n" 1397 "andq %%rax, %%rsi ;\n" 1398 "andq %%rax, %%rdi ;\n" 1399 1400 1401 "movq %3, %%rax ;\n" 1402 "movq $0xfffffffffffda, %%r9 ;\n" 1403 "movq $0xffffffffffffe, %%r10 ;\n" 1404 "movq %%r10, %%r11 ;\n" 1405 "movq %%r10, %%r12 ;\n" 1406 "movq %%r10, %%r13 ;\n" 1407 "subq %%rcx, %%r9 ;\n" 1408 "subq %%r8, %%r10 ;\n" 1409 "subq %%rdx, %%r11 ;\n" 1410 "subq %%rsi, %%r12 ;\n" 1411 "subq %%rdi, %%r13 ;\n" 1412 "cmpq $1, %%rax ;\n" 1413 "cmove %%r9, %%rcx ;\n" 1414 "cmove %%r10, %%r8 ;\n" 1415 "cmove %%r11, %%rdx ;\n" 1416 "cmove %%r12, %%rsi ;\n" 1417 "cmove %%r13, %%rdi ;\n" 1418 1419 1420 "movq %%rcx, 80(%2) ;\n" 1421 "movq %%r8, 88(%2) ;\n" 1422 "movq %%rdx, 96(%2) ;\n" 1423 "movq %%rsi, 104(%2) ;\n" 1424 "movq %%rdi, 112(%2) ;\n" 1425 : 1426 : "m"(u), "r"(&table[pos * 8]), "r"(t), "m"(sign) 1427 : 1428 "%rax", "%rcx", "%rdx", "%rdi", "%rsi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", 1429 "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm14", "%xmm14", 1430 "cc", "memory" 1431 ); 1432 } 1433 // 102 "ed25519-donna.h" 2 1434 // 113 "ed25519-donna.h" 1435 // 1 "ed25519-donna-impl-base.h" 1 1436 1437 1438 1439 1440 inline __attribute__((always_inline)) static void 1441 ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) { 1442 curve25519_mul(r->x, p->x, p->t); 1443 curve25519_mul(r->y, p->y, p->z); 1444 curve25519_mul(r->z, p->z, p->t); 1445 } 1446 1447 inline __attribute__((always_inline)) static void 1448 ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) { 1449 curve25519_mul(r->x, p->x, p->t); 1450 curve25519_mul(r->y, p->y, p->z); 1451 curve25519_mul(r->z, p->z, p->t); 1452 curve25519_mul(r->t, p->x, p->y); 1453 } 1454 1455 static void 1456 ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) { 1457 curve25519_sub(p->ysubx, r->y, r->x); 1458 curve25519_add(p->xaddy, r->y, r->x); 1459 curve25519_copy(p->z, r->z); 1460 curve25519_mul(p->t2d, r->t, ge25519_ec2d); 1461 } 1462 1463 1464 1465 1466 1467 static void 1468 ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519 *q) { 1469 bignum25519 a,b,c,d,t,u; 1470 1471 curve25519_sub(a, p->y, p->x); 1472 curve25519_add(b, p->y, p->x); 1473 curve25519_sub(t, q->y, q->x); 1474 curve25519_add(u, q->y, q->x); 1475 curve25519_mul(a, a, t); 1476 curve25519_mul(b, b, u); 1477 curve25519_mul(c, p->t, q->t); 1478 curve25519_mul(c, c, ge25519_ec2d); 1479 curve25519_mul(d, p->z, q->z); 1480 curve25519_add(d, d, d); 1481 curve25519_sub(r->x, b, a); 1482 curve25519_add(r->y, b, a); 1483 curve25519_add_after_basic(r->z, d, c); 1484 curve25519_sub_after_basic(r->t, d, c); 1485 } 1486 1487 1488 static void 1489 ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) { 1490 bignum25519 a,b,c; 1491 1492 curve25519_square(a, p->x); 1493 curve25519_square(b, p->y); 1494 curve25519_square(c, p->z); 1495 curve25519_add_reduce(c, c, c); 1496 curve25519_add(r->x, p->x, p->y); 1497 curve25519_square(r->x, r->x); 1498 curve25519_add(r->y, b, a); 1499 curve25519_sub(r->z, b, a); 1500 curve25519_sub_after_basic(r->x, r->x, r->y); 1501 curve25519_sub_after_basic(r->t, c, r->z); 1502 } 1503 1504 static void 1505 ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) { 1506 const bignum25519 *qb = (const bignum25519 *)q; 1507 bignum25519 *rb = (bignum25519 *)r; 1508 bignum25519 a,b,c; 1509 1510 curve25519_sub(a, p->y, p->x); 1511 curve25519_add(b, p->y, p->x); 1512 curve25519_mul(a, a, qb[signbit]); 1513 curve25519_mul(r->x, b, qb[signbit^1]); 1514 curve25519_add(r->y, r->x, a); 1515 curve25519_sub(r->x, r->x, a); 1516 curve25519_mul(c, p->t, q->t2d); 1517 curve25519_add_reduce(r->t, p->z, p->z); 1518 curve25519_copy(r->z, r->t); 1519 curve25519_add(rb[2+signbit], rb[2+signbit], c); 1520 curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); 1521 } 1522 1523 static void 1524 ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) { 1525 const bignum25519 *qb = (const bignum25519 *)q; 1526 bignum25519 *rb = (bignum25519 *)r; 1527 bignum25519 a,b,c; 1528 1529 curve25519_sub(a, p->y, p->x); 1530 curve25519_add(b, p->y, p->x); 1531 curve25519_mul(a, a, qb[signbit]); 1532 curve25519_mul(r->x, b, qb[signbit^1]); 1533 curve25519_add(r->y, r->x, a); 1534 curve25519_sub(r->x, r->x, a); 1535 curve25519_mul(c, p->t, q->t2d); 1536 curve25519_mul(r->t, p->z, q->z); 1537 curve25519_add_reduce(r->t, r->t, r->t); 1538 curve25519_copy(r->z, r->t); 1539 curve25519_add(rb[2+signbit], rb[2+signbit], c); 1540 curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); 1541 } 1542 1543 static void 1544 ge25519_double_partial(ge25519 *r, const ge25519 *p) { 1545 ge25519_p1p1 t; 1546 ge25519_double_p1p1(&t, p); 1547 ge25519_p1p1_to_partial(r, &t); 1548 } 1549 1550 static void 1551 ge25519_double(ge25519 *r, const ge25519 *p) { 1552 ge25519_p1p1 t; 1553 ge25519_double_p1p1(&t, p); 1554 ge25519_p1p1_to_full(r, &t); 1555 } 1556 1557 static void 1558 ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) { 1559 ge25519_p1p1 t; 1560 ge25519_add_p1p1(&t, p, q); 1561 ge25519_p1p1_to_full(r, &t); 1562 } 1563 1564 static void 1565 ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) { 1566 bignum25519 a,b,c,e,f,g,h; 1567 1568 curve25519_sub(a, r->y, r->x); 1569 curve25519_add(b, r->y, r->x); 1570 curve25519_mul(a, a, q->ysubx); 1571 curve25519_mul(e, b, q->xaddy); 1572 curve25519_add(h, e, a); 1573 curve25519_sub(e, e, a); 1574 curve25519_mul(c, r->t, q->t2d); 1575 curve25519_add(f, r->z, r->z); 1576 curve25519_add_after_basic(g, f, c); 1577 curve25519_sub_after_basic(f, f, c); 1578 curve25519_mul(r->x, e, f); 1579 curve25519_mul(r->y, h, g); 1580 curve25519_mul(r->z, g, f); 1581 curve25519_mul(r->t, e, h); 1582 } 1583 1584 static void 1585 ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) { 1586 bignum25519 a,b,c,x,y,z,t; 1587 1588 curve25519_sub(a, p->y, p->x); 1589 curve25519_add(b, p->y, p->x); 1590 curve25519_mul(a, a, q->ysubx); 1591 curve25519_mul(x, b, q->xaddy); 1592 curve25519_add(y, x, a); 1593 curve25519_sub(x, x, a); 1594 curve25519_mul(c, p->t, q->t2d); 1595 curve25519_mul(t, p->z, q->z); 1596 curve25519_add(t, t, t); 1597 curve25519_add_after_basic(z, t, c); 1598 curve25519_sub_after_basic(t, t, c); 1599 curve25519_mul(r->xaddy, x, t); 1600 curve25519_mul(r->ysubx, y, z); 1601 curve25519_mul(r->z, z, t); 1602 curve25519_mul(r->t2d, x, y); 1603 curve25519_copy(y, r->ysubx); 1604 curve25519_sub(r->ysubx, r->ysubx, r->xaddy); 1605 curve25519_add(r->xaddy, r->xaddy, y); 1606 curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); 1607 } 1608 1609 1610 1611 1612 1613 1614 static void 1615 ge25519_pack(unsigned char r[32], const ge25519 *p) { 1616 bignum25519 tx, ty, zi; 1617 unsigned char parity[32]; 1618 curve25519_recip(zi, p->z); 1619 curve25519_mul(tx, p->x, zi); 1620 curve25519_mul(ty, p->y, zi); 1621 curve25519_contract(r, ty); 1622 curve25519_contract(parity, tx); 1623 r[31] ^= ((parity[0] & 1) << 7); 1624 } 1625 1626 static int 1627 ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) { 1628 static const unsigned char zero[32] = {0}; 1629 static const bignum25519 one = {1}; 1630 unsigned char parity = p[31] >> 7; 1631 unsigned char check[32]; 1632 bignum25519 t, root, num, den, d3; 1633 1634 curve25519_expand(r->y, p); 1635 curve25519_copy(r->z, one); 1636 curve25519_square(num, r->y); 1637 curve25519_mul(den, num, ge25519_ecd); 1638 curve25519_sub_reduce(num, num, r->z); 1639 curve25519_add(den, den, r->z); 1640 1641 1642 1643 curve25519_square(t, den); 1644 curve25519_mul(d3, t, den); 1645 curve25519_square(r->x, d3); 1646 curve25519_mul(r->x, r->x, den); 1647 curve25519_mul(r->x, r->x, num); 1648 curve25519_pow_two252m3(r->x, r->x); 1649 1650 1651 curve25519_mul(r->x, r->x, d3); 1652 curve25519_mul(r->x, r->x, num); 1653 1654 1655 curve25519_square(t, r->x); 1656 curve25519_mul(t, t, den); 1657 curve25519_sub_reduce(root, t, num); 1658 curve25519_contract(check, root); 1659 if (!ed25519_verify(check, zero, 32)) { 1660 curve25519_add_reduce(t, t, num); 1661 curve25519_contract(check, t); 1662 if (!ed25519_verify(check, zero, 32)) 1663 return 0; 1664 curve25519_mul(r->x, r->x, ge25519_sqrtneg1); 1665 } 1666 1667 curve25519_contract(check, r->x); 1668 if ((check[0] & 1) == parity) { 1669 curve25519_copy(t, r->x); 1670 curve25519_neg(r->x, t); 1671 } 1672 curve25519_mul(r->t, r->x, r->y); 1673 return 1; 1674 } 1675 // 252 "ed25519-donna-impl-base.h" 1676 static void 1677 ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) { 1678 signed char slide1[256], slide2[256]; 1679 ge25519_pniels pre1[(1<<(5 -2))]; 1680 ge25519 d1; 1681 ge25519_p1p1 t; 1682 int32_t i; 1683 1684 contract256_slidingwindow_modm(slide1, s1, 5); 1685 contract256_slidingwindow_modm(slide2, s2, 7); 1686 1687 ge25519_double(&d1, p1); 1688 ge25519_full_to_pniels(pre1, p1); 1689 for (i = 0; i < (1<<(5 -2)) - 1; i++) 1690 ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]); 1691 1692 1693 memset(r, 0, sizeof(ge25519)); 1694 r->y[0] = 1; 1695 r->z[0] = 1; 1696 1697 i = 255; 1698 while ((i >= 0) && !(slide1[i] | slide2[i])) 1699 i--; 1700 1701 for (; i >= 0; i--) { 1702 ge25519_double_p1p1(&t, r); 1703 1704 if (slide1[i]) { 1705 int index = abs(slide1[i]) / 2; 1706 ge25519_p1p1_to_full(r, &t); 1707 ge25519_pnielsadd_p1p1(&t, r, &pre1[index], (unsigned char)slide1[i] >> 7); 1708 } 1709 1710 if (slide2[i]) { 1711 int index = abs(slide2[i]) / 2; 1712 ge25519_p1p1_to_full(r, &t); 1713 ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[index], (unsigned char)slide2[i] >> 7); 1714 } 1715 1716 ge25519_p1p1_to_partial(r, &t); 1717 } 1718 } 1719 // 334 "ed25519-donna-impl-base.h" 1720 static void 1721 ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s) { 1722 signed char b[64]; 1723 uint32_t i; 1724 ge25519_niels t; 1725 1726 contract256_window4_modm(b, s); 1727 1728 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); 1729 curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); 1730 curve25519_add_reduce(r->y, t.xaddy, t.ysubx); 1731 memset(r->z, 0, sizeof(bignum25519)); 1732 curve25519_copy(r->t, t.t2d); 1733 r->z[0] = 2; 1734 for (i = 3; i < 64; i += 2) { 1735 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); 1736 ge25519_nielsadd2(r, &t); 1737 } 1738 ge25519_double_partial(r, r); 1739 ge25519_double_partial(r, r); 1740 ge25519_double_partial(r, r); 1741 ge25519_double(r, r); 1742 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); 1743 curve25519_mul(t.t2d, t.t2d, ge25519_ecd); 1744 ge25519_nielsadd2(r, &t); 1745 for(i = 2; i < 64; i += 2) { 1746 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); 1747 ge25519_nielsadd2(r, &t); 1748 } 1749 } 1750 // 114 "ed25519-donna.h" 2 1751 // 18 "ed25519.c" 2 1752 // 1 "ed25519.h" 1 1753 // 10 "ed25519.h" 1754 typedef unsigned char ed25519_signature[64]; 1755 typedef unsigned char ed25519_public_key[32]; 1756 typedef unsigned char ed25519_secret_key[32]; 1757 1758 typedef unsigned char curved25519_key[32]; 1759 1760 /* 1761 void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk); 1762 int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); 1763 void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS); 1764 1765 int ed25519_sign_open_batch(const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid); 1766 1767 void ed25519_randombytes_unsafe(void *out, size_t count); 1768 1769 void curved25519_scalarmult_basepoint(curved25519_key pk, const curved25519_key e); 1770 */ 1771 1772 // 195 "ed25519-hash.h" 2 1773 1774 //typedef SHA512_CTX ed25519_hash_context; 1775 1776 typedef int ed25519_hash_context; 1777 1778 static void 1779 ed25519_hash_init(ed25519_hash_context *ctx) { 1780 // SHA512_Init(ctx); 1781 } 1782 1783 static void 1784 ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen) { 1785 // SHA512_Update(ctx, in, inlen); 1786 } 1787 1788 static void 1789 ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash) { 1790 // SHA512_Final(hash, ctx); 1791 } 1792 1793 static void 1794 ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen) { 1795 // SHA512(in, inlen, hash); 1796 } 1797 // 21 "ed25519.c" 2 1798 1799 1800 1801 1802 1803 inline __attribute__((always_inline)) static void 1804 ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) { 1805 ed25519_hash(extsk, sk, 32); 1806 extsk[0] &= 248; 1807 extsk[31] &= 127; 1808 extsk[31] |= 64; 1809 } 1810 1811 static void 1812 ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) { 1813 ed25519_hash_context ctx; 1814 ed25519_hash_init(&ctx); 1815 ed25519_hash_update(&ctx, RS, 32); 1816 ed25519_hash_update(&ctx, pk, 32); 1817 ed25519_hash_update(&ctx, m, mlen); 1818 ed25519_hash_final(&ctx, hram); 1819 } 1820 /* 1821 void 1822 ed25519_publickey (const ed25519_secret_key sk, ed25519_public_key pk) { 1823 bignum256modm a; 1824 ge25519 __attribute__((aligned(16))) A; 1825 hash_512bits extsk; 1826 1827 1828 ed25519_extsk(extsk, sk); 1829 expand256_modm(a, extsk, 32); 1830 ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); 1831 ge25519_pack(pk, &A); 1832 } 1833 1834 1835 void 1836 ed25519_sign (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) { 1837 ed25519_hash_context ctx; 1838 bignum256modm r, S, a; 1839 ge25519 __attribute__((aligned(16))) R; 1840 hash_512bits extsk, hashr, hram; 1841 1842 ed25519_extsk(extsk, sk); 1843 1844 1845 ed25519_hash_init(&ctx); 1846 ed25519_hash_update(&ctx, extsk + 32, 32); 1847 ed25519_hash_update(&ctx, m, mlen); 1848 ed25519_hash_final(&ctx, hashr); 1849 expand256_modm(r, hashr, 64); 1850 1851 1852 ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); 1853 ge25519_pack(RS, &R); 1854 1855 1856 ed25519_hram(hram, RS, pk, m, mlen); 1857 expand256_modm(S, hram, 64); 1858 1859 1860 expand256_modm(a, extsk, 32); 1861 mul256_modm(S, S, a); 1862 1863 1864 add256_modm(S, S, r); 1865 1866 1867 contract256_modm(RS + 32, S); 1868 } 1869 1870 int 1871 ed25519_sign_open (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) { 1872 ge25519 __attribute__((aligned(16))) R, A; 1873 hash_512bits hash; 1874 bignum256modm hram, S; 1875 unsigned char checkR[32]; 1876 1877 if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) 1878 return -1; 1879 1880 1881 ed25519_hram(hash, RS, pk, m, mlen); 1882 expand256_modm(hram, hash, 64); 1883 1884 1885 expand256_modm(S, RS + 32, 32); 1886 1887 1888 ge25519_double_scalarmult_vartime(&R, &A, hram, S); 1889 ge25519_pack(checkR, &R); 1890 1891 1892 return ed25519_verify(RS, checkR, 32) ? 0 : -1; 1893 } 1894 */ 1895 // 1 "ed25519-donna-batchverify.h" 1 1896 // 9 "ed25519-donna-batchverify.h" 1897 static const size_t limb128bits = (128 + 56 - 1) / 56; 1898 1899 typedef size_t heap_index_t; 1900 1901 typedef struct batch_heap_t { 1902 unsigned char r[((64 * 2) + 1)][16]; 1903 ge25519 points[((64 * 2) + 1)]; 1904 bignum256modm scalars[((64 * 2) + 1)]; 1905 heap_index_t heap[((64 * 2) + 1)]; 1906 size_t size; 1907 } batch_heap; 1908 1909 1910 static void 1911 heap_swap(heap_index_t *heap, size_t a, size_t b) { 1912 heap_index_t temp; 1913 temp = heap[a]; 1914 heap[a] = heap[b]; 1915 heap[b] = temp; 1916 } 1917 1918 1919 static void 1920 heap_insert_next(batch_heap *heap) { 1921 size_t node = heap->size, parent; 1922 heap_index_t *pheap = heap->heap; 1923 bignum256modm *scalars = heap->scalars; 1924 1925 1926 pheap[node] = (heap_index_t)node; 1927 1928 1929 parent = (node - 1) / 2; 1930 while (node && lt256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], 5 - 1)) { 1931 heap_swap(pheap, parent, node); 1932 node = parent; 1933 parent = (node - 1) / 2; 1934 } 1935 heap->size++; 1936 } 1937 1938 1939 static void 1940 heap_updated_root(batch_heap *heap, size_t limbsize) { 1941 size_t node, parent, childr, childl; 1942 heap_index_t *pheap = heap->heap; 1943 bignum256modm *scalars = heap->scalars; 1944 1945 1946 parent = 0; 1947 node = 1; 1948 childl = 1; 1949 childr = 2; 1950 while ((childr < heap->size)) { 1951 node = lt256_modm_batch(scalars[pheap[childl]], scalars[pheap[childr]], limbsize) ? childr : childl; 1952 heap_swap(pheap, parent, node); 1953 parent = node; 1954 childl = (parent * 2) + 1; 1955 childr = childl + 1; 1956 } 1957 1958 1959 parent = (node - 1) / 2; 1960 while (node && lte256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], limbsize)) { 1961 heap_swap(pheap, parent, node); 1962 node = parent; 1963 parent = (node - 1) / 2; 1964 } 1965 } 1966 1967 1968 static void 1969 heap_build(batch_heap *heap, size_t count) { 1970 heap->heap[0] = 0; 1971 heap->size = 0; 1972 while (heap->size < count) 1973 heap_insert_next(heap); 1974 } 1975 1976 1977 static void 1978 heap_extend(batch_heap *heap, size_t new_count) { 1979 while (heap->size < new_count) 1980 heap_insert_next(heap); 1981 } 1982 1983 1984 static void 1985 heap_get_top2(batch_heap *heap, heap_index_t *max1, heap_index_t *max2, size_t limbsize) { 1986 heap_index_t h0 = heap->heap[0], h1 = heap->heap[1], h2 = heap->heap[2]; 1987 if (lt256_modm_batch(heap->scalars[h1], heap->scalars[h2], limbsize)) 1988 h1 = h2; 1989 *max1 = h0; 1990 *max2 = h1; 1991 } 1992 1993 1994 static void 1995 ge25519_multi_scalarmult_vartime_final(ge25519 *r, ge25519 *point, bignum256modm scalar) { 1996 const bignum256modm_element_t topbit = ((bignum256modm_element_t)1 << (56 - 1)); 1997 size_t limb = limb128bits; 1998 bignum256modm_element_t flag; 1999 2000 if (isone256_modm_batch(scalar)) { 2001 2002 *r = *point; 2003 return; 2004 } else if (iszero256_modm_batch(scalar)) { 2005 2006 memset(r, 0, sizeof(*r)); 2007 r->y[0] = 1; 2008 r->z[0] = 1; 2009 return; 2010 } 2011 2012 *r = *point; 2013 2014 2015 while (!scalar[limb]) 2016 limb--; 2017 2018 2019 flag = topbit; 2020 while ((scalar[limb] & flag) == 0) 2021 flag >>= 1; 2022 2023 2024 for (;;) { 2025 ge25519_double(r, r); 2026 if (scalar[limb] & flag) 2027 ge25519_add(r, r, point); 2028 2029 flag >>= 1; 2030 if (!flag) { 2031 if (!limb--) 2032 break; 2033 flag = topbit; 2034 } 2035 } 2036 } 2037 2038 2039 static void 2040 ge25519_multi_scalarmult_vartime(ge25519 *r, batch_heap *heap, size_t count) { 2041 heap_index_t max1, max2; 2042 2043 2044 size_t limbsize = 5 - 1; 2045 2046 2047 int extended = 0; 2048 2049 2050 heap_build(heap, ((count + 1) / 2) | 1); 2051 2052 for (;;) { 2053 heap_get_top2(heap, &max1, &max2, limbsize); 2054 2055 2056 if (iszero256_modm_batch(heap->scalars[max2])) 2057 break; 2058 2059 2060 if (!heap->scalars[max1][limbsize]) 2061 limbsize -= 1; 2062 2063 2064 if (!extended && isatmost128bits256_modm_batch(heap->scalars[max1])) { 2065 heap_extend(heap, count); 2066 heap_get_top2(heap, &max1, &max2, limbsize); 2067 extended = 1; 2068 } 2069 2070 sub256_modm_batch(heap->scalars[max1], heap->scalars[max1], heap->scalars[max2], limbsize); 2071 ge25519_add(&heap->points[max2], &heap->points[max2], &heap->points[max1]); 2072 heap_updated_root(heap, limbsize); 2073 } 2074 2075 ge25519_multi_scalarmult_vartime_final(r, &heap->points[max1], heap->scalars[max1]); 2076 } 2077 2078 /* 2079 unsigned char batch_point_buffer[3][32]; 2080 2081 static int 2082 ge25519_is_neutral_vartime(const ge25519 *p) { 2083 static const unsigned char zero[32] = {0}; 2084 unsigned char point_buffer[3][32]; 2085 curve25519_contract(point_buffer[0], p->x); 2086 curve25519_contract(point_buffer[1], p->y); 2087 curve25519_contract(point_buffer[2], p->z); 2088 memcpy(batch_point_buffer[1], point_buffer[1], 32); 2089 return (memcmp(point_buffer[0], zero, 32) == 0) && (memcmp(point_buffer[1], point_buffer[2], 32) == 0); 2090 } 2091 2092 int 2093 ed25519_sign_open_batch (const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid) { 2094 batch_heap __attribute__((aligned(16))) batch; 2095 ge25519 __attribute__((aligned(16))) p; 2096 bignum256modm *r_scalars; 2097 size_t i, batchsize; 2098 unsigned char hram[64]; 2099 int ret = 0; 2100 2101 for (i = 0; i < num; i++) 2102 valid[i] = 1; 2103 2104 while (num > 3) { 2105 batchsize = (num > 64) ? 64 : num; 2106 2107 2108 ed25519_randombytes_unsafe (batch.r, batchsize * 16); 2109 r_scalars = &batch.scalars[batchsize + 1]; 2110 for (i = 0; i < batchsize; i++) 2111 expand256_modm(r_scalars[i], batch.r[i], 16); 2112 2113 2114 for (i = 0; i < batchsize; i++) { 2115 expand256_modm(batch.scalars[i], RS[i] + 32, 32); 2116 mul256_modm(batch.scalars[i], batch.scalars[i], r_scalars[i]); 2117 } 2118 for (i = 1; i < batchsize; i++) 2119 add256_modm(batch.scalars[0], batch.scalars[0], batch.scalars[i]); 2120 2121 2122 for (i = 0; i < batchsize; i++) { 2123 ed25519_hram(hram, RS[i], pk[i], m[i], mlen[i]); 2124 expand256_modm(batch.scalars[i+1], hram, 64); 2125 mul256_modm(batch.scalars[i+1], batch.scalars[i+1], r_scalars[i]); 2126 } 2127 2128 2129 batch.points[0] = ge25519_basepoint; 2130 for (i = 0; i < batchsize; i++) 2131 if (!ge25519_unpack_negative_vartime(&batch.points[i+1], pk[i])) 2132 goto fallback; 2133 for (i = 0; i < batchsize; i++) 2134 if (!ge25519_unpack_negative_vartime(&batch.points[batchsize+i+1], RS[i])) 2135 goto fallback; 2136 2137 ge25519_multi_scalarmult_vartime(&p, &batch, (batchsize * 2) + 1); 2138 if (!ge25519_is_neutral_vartime(&p)) { 2139 ret |= 2; 2140 2141 fallback: 2142 for (i = 0; i < batchsize; i++) { 2143 valid[i] = ed25519_sign_open (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1; 2144 ret |= (valid[i] ^ 1); 2145 } 2146 } 2147 2148 m += batchsize; 2149 mlen += batchsize; 2150 pk += batchsize; 2151 RS += batchsize; 2152 num -= batchsize; 2153 valid += batchsize; 2154 } 2155 2156 for (i = 0; i < num; i++) { 2157 valid[i] = ed25519_sign_open (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1; 2158 ret |= (valid[i] ^ 1); 2159 } 2160 2161 return ret; 2162 } 2163 */ 2164 // 119 "ed25519.c" 2 2165 2166 2167 2168 2169 2170 /* void */ 2171 /* curved25519_scalarmult_basepoint (curved25519_key pk, const curved25519_key e) { */ 2172 /* curved25519_key ec; */ 2173 /* bignum256modm s; */ 2174 /* bignum25519 __attribute__((aligned(16))) yplusz, zminusy; */ 2175 /* ge25519 __attribute__((aligned(16))) p; */ 2176 /* size_t i; */ 2177 2178 2179 /* for (i = 0; i < 32; i++) ec[i] = e[i]; */ 2180 /* /\* ec[0] &= 248; *\/ */ 2181 /* /\* ec[31] &= 127; *\/ */ 2182 /* /\* ec[31] |= 64; *\/ */ 2183 2184 /* expand_raw256_modm(s, ec); */ 2185 2186 2187 /* ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s); */ 2188 2189 2190 /* curve25519_add(yplusz, p.y, p.z); */ 2191 /* curve25519_sub(zminusy, p.z, p.y); */ 2192 /* curve25519_recip(zminusy, zminusy); */ 2193 /* curve25519_mul(yplusz, yplusz, zminusy); */ 2194 /* curve25519_contract(pk, yplusz); */ 2195 /* } */ 2196 2197 2198 2199 // derek: added 2200 static int 2201 ge25519_unpack_vartime(ge25519 *r, const unsigned char p[32]) { 2202 static const unsigned char zero[32] = {0}; 2203 static const bignum25519 one = {1}; 2204 unsigned char parity = p[31] >> 7; 2205 unsigned char check[32]; 2206 bignum25519 t, root, num, den, d3; 2207 2208 curve25519_expand(r->y, p); 2209 curve25519_copy(r->z, one); 2210 curve25519_square(num, r->y); 2211 curve25519_mul(den, num, ge25519_ecd); 2212 curve25519_sub_reduce(num, num, r->z); 2213 curve25519_add(den, den, r->z); 2214 2215 2216 curve25519_square(t, den); 2217 curve25519_mul(d3, t, den); 2218 curve25519_square(r->x, d3); 2219 curve25519_mul(r->x, r->x, den); 2220 curve25519_mul(r->x, r->x, num); 2221 curve25519_pow_two252m3(r->x, r->x); 2222 2223 curve25519_mul(r->x, r->x, d3); 2224 curve25519_mul(r->x, r->x, num); 2225 2226 curve25519_square(t, r->x); 2227 curve25519_mul(t, t, den); 2228 curve25519_sub_reduce(root, t, num); 2229 curve25519_contract(check, root); 2230 2231 if (!ed25519_verify(check, zero, 32)) { 2232 curve25519_add_reduce(t, t, num); 2233 curve25519_contract(check, t); 2234 if (!ed25519_verify(check, zero, 32)) 2235 { 2236 return 0; 2237 } 2238 2239 curve25519_mul(r->x, r->x, ge25519_sqrtneg1); 2240 } 2241 2242 curve25519_contract(check, r->x); 2243 if ((check[0] & 1) != parity) { 2244 curve25519_copy(t, r->x); 2245 curve25519_neg(r->x, t); 2246 } 2247 curve25519_mul(r->t, r->x, r->y); 2248 return 1; 2249 } 2250