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