"Fossies" - the Fresh Open Source Software Archive

Member "n2n-3.1.1/src/curve25519.c" (31 Mar 2022, 8563 Bytes) of package /linux/misc/n2n-3.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "curve25519.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.0_vs_3.1.1.

    1 /**
    2  * (C) 2007-22 - ntop.org and contributors
    3  *
    4  * This program is free software; you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation; either version 3 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not see see <http://www.gnu.org/licenses/>
   16  *
   17  */
   18 
   19 
   20 /**
   21  * version 20081011
   22  * Matthew Dempsky
   23  * Public domain.
   24  * Derived from public domain code by D. J. Bernstein.
   25  * 20140216 tweak: Mask top bit of point input.
   26  *
   27  */
   28 
   29 
   30 static void add (unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) {
   31 
   32     unsigned int j;
   33     unsigned int u;
   34 
   35     u = 0;
   36     for(j = 0; j < 31; ++j) {
   37         u += a[j] + b[j];
   38         out[j] = u & 255;
   39         u >>= 8;
   40     }
   41     u += a[31] + b[31];
   42     out[31] = u;
   43 }
   44 
   45 
   46 static void sub (unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) {
   47 
   48     unsigned int j;
   49     unsigned int u;
   50 
   51     u = 218;
   52     for(j = 0; j < 31; ++j) {
   53         u += a[j] + 65280 - b[j];
   54         out[j] = u & 255;
   55         u >>= 8;
   56     }
   57     u += a[31] - b[31];
   58     out[31] = u;
   59 }
   60 
   61 
   62 static void squeeze (unsigned int a[32]) {
   63 
   64     unsigned int j;
   65     unsigned int u;
   66 
   67     u = 0;
   68     for(j = 0; j < 31; ++j) {
   69         u += a[j];
   70         a[j] = u & 255;
   71         u >>= 8;
   72     }
   73     u += a[31];
   74     a[31] = u & 127;
   75     u = 19 * (u >> 7);
   76     for(j = 0; j < 31; ++j) {
   77         u += a[j];
   78         a[j] = u & 255;
   79         u >>= 8;
   80     }
   81     u += a[31];
   82     a[31] = u;
   83 }
   84 
   85 
   86 static const unsigned int minusp[32] = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   87                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
   88 
   89 
   90 static void freeze (unsigned int a[32]) {
   91 
   92     unsigned int aorig[32];
   93     unsigned int j;
   94     unsigned int negative;
   95 
   96     for(j = 0; j < 32; ++j)
   97         aorig[j] = a[j];
   98     add(a, a, minusp);
   99     negative = -((a[31] >> 7) & 1);
  100     for(j = 0; j < 32; ++j)
  101         a[j] ^= negative & (aorig[j] ^ a[j]);
  102 }
  103 
  104 
  105 static void mult (unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) {
  106 
  107     unsigned int i;
  108     unsigned int j;
  109     unsigned int u;
  110 
  111     for(i = 0; i < 32; ++i) {
  112         u = 0;
  113         for(j = 0; j <= i; ++j)
  114             u += a[j] * b[i - j];
  115         for(j = i + 1; j < 32; ++j)
  116             u += 38 * a[j] * b[i + 32 - j];
  117         out[i] = u;
  118     }
  119     squeeze(out);
  120 }
  121 
  122 
  123 static void mult121665 (unsigned int out[32], const unsigned int a[32]) {
  124 
  125     unsigned int j;
  126     unsigned int u;
  127 
  128     u = 0;
  129     for(j = 0; j < 31; ++j) {
  130         u += 121665 * a[j];
  131         out[j] = u & 255;
  132         u >>= 8;
  133     }
  134     u += 121665 * a[31];
  135     out[31] = u & 127;
  136     u = 19 * (u >> 7);
  137     for(j = 0; j < 31; ++j) {
  138         u += out[j];
  139         out[j] = u & 255;
  140         u >>= 8;
  141     }
  142     u += out[j];
  143     out[j] = u;
  144 }
  145 
  146 
  147 static void square (unsigned int out[32], const unsigned int a[32]) {
  148 
  149     unsigned int i;
  150     unsigned int j;
  151     unsigned int u;
  152 
  153     for(i = 0; i < 32; ++i) {
  154         u = 0;
  155         for(j = 0; j < i - j; ++j)
  156             u += a[j] * a[i - j];
  157         for(j = i + 1; j < i + 32 - j; ++j)
  158             u += 38 * a[j] * a[i + 32 - j];
  159         u *= 2;
  160         if((i & 1) == 0) {
  161             u += a[i / 2] * a[i / 2];
  162             u += 38 * a[i / 2 + 16] * a[i / 2 + 16];
  163         }
  164         out[i] = u;
  165     }
  166     squeeze(out);
  167 }
  168 
  169 
  170 static void select (unsigned int p[64], unsigned int q[64], const unsigned int r[64],
  171                     const unsigned int s[64], unsigned int b) {
  172 
  173     unsigned int j;
  174     unsigned int t;
  175     unsigned int bminus1;
  176 
  177     bminus1 = b - 1;
  178     for(j = 0; j < 64; ++j) {
  179         t = bminus1 & (r[j] ^ s[j]);
  180         p[j] = s[j] ^ t;
  181         q[j] = r[j] ^ t;
  182     }
  183 }
  184 
  185 
  186 static void mainloop (unsigned int work[64], const unsigned char e[32]) {
  187 
  188     unsigned int xzm1[64];
  189     unsigned int xzm[64];
  190     unsigned int xzmb[64];
  191     unsigned int xzm1b[64];
  192     unsigned int xznb[64];
  193     unsigned int xzn1b[64];
  194     unsigned int a0[64];
  195     unsigned int a1[64];
  196     unsigned int b0[64];
  197     unsigned int b1[64];
  198     unsigned int c1[64];
  199     unsigned int r[32];
  200     unsigned int s[32];
  201     unsigned int t[32];
  202     unsigned int u[32];
  203     unsigned int j;
  204     unsigned int b;
  205     int pos;
  206 
  207     for(j = 0; j < 32; ++j)
  208         xzm1[j] = work[j];
  209     xzm1[32] = 1;
  210     for(j = 33; j < 64; ++j)
  211         xzm1[j] = 0;
  212 
  213     xzm[0] = 1;
  214     for(j = 1; j < 64; ++j)
  215         xzm[j] = 0;
  216 
  217     for(pos = 254; pos >= 0; --pos) {
  218         b = e[pos / 8] >> (pos & 7);
  219         b &= 1;
  220         select(xzmb, xzm1b, xzm, xzm1, b);
  221         add(a0, xzmb, xzmb + 32);
  222         sub(a0 + 32, xzmb, xzmb + 32);
  223         add (a1, xzm1b, xzm1b + 32);
  224         sub(a1 + 32, xzm1b, xzm1b + 32);
  225         square(b0, a0);
  226         square(b0 + 32, a0 + 32);
  227         mult(b1, a1, a0 + 32);
  228         mult(b1 + 32, a1 + 32, a0);
  229         add(c1, b1, b1 + 32);
  230         sub(c1 + 32, b1, b1 + 32);
  231         square(r, c1 + 32);
  232         sub(s, b0, b0 + 32);
  233         mult121665 (t, s);
  234         add(u, t, b0);
  235         mult(xznb, b0, b0 + 32);
  236         mult(xznb + 32, s, u);
  237         square(xzn1b, c1);
  238         mult(xzn1b + 32, r, work);
  239         select(xzm, xzm1, xznb, xzn1b, b);
  240     }
  241 
  242     for(j = 0; j < 64; ++j)
  243         work[j] = xzm[j];
  244 }
  245 
  246 
  247 static void recip (unsigned int out[32], const unsigned int z[32]) {
  248 
  249     unsigned int z2[32];
  250     unsigned int z9[32];
  251     unsigned int z11[32];
  252     unsigned int z2_5_0[32];
  253     unsigned int z2_10_0[32];
  254     unsigned int z2_20_0[32];
  255     unsigned int z2_50_0[32];
  256     unsigned int z2_100_0[32];
  257     unsigned int t0[32];
  258     unsigned int t1[32];
  259     int i;
  260 
  261     /* 2 */ square(z2, z);
  262     /* 4 */ square(t1, z2);
  263     /* 8 */ square(t0, t1);
  264     /* 9 */ mult(z9, t0, z);
  265     /* 11 */ mult(z11, z9, z2);
  266     /* 22 */ square(t0, z11);
  267     /* 2^5 - 2^0 = 31 */ mult(z2_5_0, t0, z9);
  268 
  269     /* 2^6 - 2^1 */ square(t0, z2_5_0);
  270     /* 2^7 - 2^2 */ square(t1, t0);
  271     /* 2^8 - 2^3 */ square(t0, t1);
  272     /* 2^9 - 2^4 */ square(t1, t0);
  273     /* 2^10 - 2^5 */ square(t0, t1);
  274     /* 2^10 - 2^0 */ mult(z2_10_0, t0, z2_5_0);
  275 
  276     /* 2^11 - 2^1 */ square(t0, z2_10_0);
  277     /* 2^12 - 2^2 */ square(t1, t0);
  278     /* 2^20 - 2^10 */ for(i = 2; i < 10; i += 2) {
  279         square(t0, t1);
  280         square(t1, t0);
  281     }
  282     /* 2^20 - 2^0 */ mult(z2_20_0, t1, z2_10_0);
  283 
  284     /* 2^21 - 2^1 */ square(t0, z2_20_0);
  285     /* 2^22 - 2^2 */ square(t1, t0);
  286     /* 2^40 - 2^20 */ for(i = 2; i < 20; i += 2) {
  287         square(t0, t1);
  288         square(t1, t0);
  289     }
  290     /* 2^40 - 2^0 */ mult(t0, t1, z2_20_0);
  291 
  292     /* 2^41 - 2^1 */ square(t1, t0);
  293     /* 2^42 - 2^2 */ square(t0, t1);
  294     /* 2^50 - 2^10 */ for(i = 2; i < 10; i += 2) {
  295         square(t1, t0);
  296         square(t0, t1);
  297     }
  298     /* 2^50 - 2^0 */ mult(z2_50_0, t0, z2_10_0);
  299 
  300     /* 2^51 - 2^1 */ square(t0, z2_50_0);
  301     /* 2^52 - 2^2 */ square(t1, t0);
  302     /* 2^100 - 2^50 */ for(i = 2; i < 50; i += 2) {
  303         square(t0, t1);
  304         square(t1, t0);
  305     }
  306     /* 2^100 - 2^0 */ mult(z2_100_0, t1, z2_50_0);
  307 
  308     /* 2^101 - 2^1 */ square(t1, z2_100_0);
  309     /* 2^102 - 2^2 */ square(t0, t1);
  310     /* 2^200 - 2^100 */ for(i = 2; i < 100; i += 2) {
  311         square(t1, t0);
  312         square(t0, t1);
  313     }
  314     /* 2^200 - 2^0 */ mult(t1, t0, z2_100_0);
  315 
  316     /* 2^201 - 2^1 */ square(t0, t1);
  317     /* 2^202 - 2^2 */ square(t1, t0);
  318     /* 2^250 - 2^50 */ for(i = 2; i < 50; i += 2) {
  319         square(t0, t1);
  320         square(t1, t0);
  321     }
  322     /* 2^250 - 2^0 */ mult(t0, t1, z2_50_0);
  323 
  324     /* 2^251 - 2^1 */ square(t1, t0);
  325     /* 2^252 - 2^2 */ square(t0, t1);
  326     /* 2^253 - 2^3 */ square(t1, t0);
  327     /* 2^254 - 2^4 */ square(t0, t1);
  328     /* 2^255 - 2^5 */ square(t1, t0);
  329     /* 2^255 - 21 */ mult(out, t1, z11);
  330 }
  331 
  332 
  333 void curve25519 (unsigned char *q, const unsigned char *n, const unsigned char *p) {
  334 
  335     unsigned int work[96];
  336     unsigned char e[32];
  337     unsigned int i;
  338 
  339     for (i = 0; i < 32; ++i)
  340         e[i] = n[i];
  341     e[0] &= 248;
  342     e[31] &= 127;
  343     e[31] |= 64;
  344 
  345     for (i = 0; i < 32; ++i)
  346         work[i] = p[i];
  347     work[31] &= 127;
  348 
  349     mainloop(work, e);
  350     recip(work + 32, work + 32);
  351     mult(work + 64, work, work + 32);
  352     freeze(work + 64);
  353 
  354     for(i = 0; i < 32; ++i)
  355         q[i] = work[64 + i];
  356 }