"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/jodid25519/lib/core.js" (11 Apr 2017, 20305 Bytes) of package /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript 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.

    1 "use strict";
    2 /**
    3  * @fileOverview
    4  * Core operations on curve 25519 required for the higher level modules.
    5  */
    6 
    7 /*
    8  * Copyright (c) 2007, 2013, 2014 Michele Bini
    9  * Copyright (c) 2014 Mega Limited
   10  * under the MIT License.
   11  *
   12  * Authors: Guy K. Kloss, Michele Bini
   13  *
   14  * You should have received a copy of the license along with this program.
   15  */
   16 
   17 var crypto = require('crypto');
   18 
   19     /**
   20      * @exports jodid25519/core
   21      * Core operations on curve 25519 required for the higher level modules.
   22      *
   23      * @description
   24      * Core operations on curve 25519 required for the higher level modules.
   25      *
   26      * <p>
   27      * This core code is extracted from Michele Bini's curve255.js implementation,
   28      * which is used as a base for Curve25519 ECDH and Ed25519 EdDSA operations.
   29      * </p>
   30      */
   31     var ns = {};
   32 
   33     function _setbit(n, c, v) {
   34         var i = c >> 4;
   35         var a = n[i];
   36         a = a + (1 << (c & 0xf)) * v;
   37         n[i] = a;
   38     }
   39 
   40     function _getbit(n, c) {
   41         return (n[c >> 4] >> (c & 0xf)) & 1;
   42     }
   43 
   44     function _ZERO() {
   45         return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
   46     }
   47 
   48     function _ONE() {
   49         return [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
   50     }
   51 
   52     // Basepoint.
   53     function _BASE() {
   54         return [9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
   55     }
   56 
   57     // return -1, 0, +1 when a is less than, equal, or greater than b
   58     function _bigintcmp(a, b) {
   59         // The following code is a bit tricky to avoid code branching
   60         var c, abs_r, mask;
   61         var r = 0;
   62         for (c = 15; c >= 0; c--) {
   63             var x = a[c];
   64             var y = b[c];
   65             r = r + (x - y) * (1 - r * r);
   66             // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
   67             // correct for [-294967295, 294967295]
   68             mask = r >> 31;
   69             abs_r = (r + mask) ^ mask;
   70             // http://stackoverflow.com/questions/596467/how-do-i-convert-a-number-to-an-integer-in-javascript
   71             // this rounds towards zero
   72             r = ~~((r << 1) / (abs_r + 1));
   73         }
   74         return r;
   75     }
   76 
   77     function _bigintadd(a, b) {
   78         var r = [];
   79         var v;
   80         r[0] = (v = a[0] + b[0]) & 0xffff;
   81         r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff;
   82         r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff;
   83         r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff;
   84         r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff;
   85         r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff;
   86         r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff;
   87         r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff;
   88         r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff;
   89         r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff;
   90         r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff;
   91         r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff;
   92         r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff;
   93         r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff;
   94         r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff;
   95         r[15] = (v >>> 16) + a[15] + b[15];
   96         return r;
   97     }
   98 
   99     function _bigintsub(a, b) {
  100         var r = [];
  101         var v;
  102         r[0] = (v = 0x80000 + a[0] - b[0]) & 0xffff;
  103         r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff;
  104         r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff;
  105         r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff;
  106         r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff;
  107         r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff;
  108         r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff;
  109         r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff;
  110         r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff;
  111         r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff;
  112         r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff;
  113         r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff;
  114         r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff;
  115         r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff;
  116         r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff;
  117         r[15] = (v >>> 16) - 8 + a[15] - b[15];
  118         return r;
  119     }
  120 
  121     function _sqr8h(a7, a6, a5, a4, a3, a2, a1, a0) {
  122         // 'division by 0x10000' can not be replaced by '>> 16' because
  123         // more than 32 bits of precision are needed similarly
  124         // 'multiplication by 2' cannot be replaced by '<< 1'
  125         var r = [];
  126         var v;
  127         r[0] = (v = a0 * a0) & 0xffff;
  128         r[1] = (v = (0 | (v / 0x10000)) + 2 * a0 * a1) & 0xffff;
  129         r[2] = (v = (0 | (v / 0x10000)) + 2 * a0 * a2 + a1 * a1) & 0xffff;
  130         r[3] = (v = (0 | (v / 0x10000)) + 2 * a0 * a3 + 2 * a1 * a2) & 0xffff;
  131         r[4] = (v = (0 | (v / 0x10000)) + 2 * a0 * a4 + 2 * a1 * a3 + a2
  132                     * a2) & 0xffff;
  133         r[5] = (v = (0 | (v / 0x10000)) + 2 * a0 * a5 + 2 * a1 * a4 + 2
  134                     * a2 * a3) & 0xffff;
  135         r[6] = (v = (0 | (v / 0x10000)) + 2 * a0 * a6 + 2 * a1 * a5 + 2
  136                     * a2 * a4 + a3 * a3) & 0xffff;
  137         r[7] = (v = (0 | (v / 0x10000)) + 2 * a0 * a7 + 2 * a1 * a6 + 2
  138                     * a2 * a5 + 2 * a3 * a4) & 0xffff;
  139         r[8] = (v = (0 | (v / 0x10000)) + 2 * a1 * a7 + 2 * a2 * a6 + 2
  140                     * a3 * a5 + a4 * a4) & 0xffff;
  141         r[9] = (v = (0 | (v / 0x10000)) + 2 * a2 * a7 + 2 * a3 * a6 + 2
  142                     * a4 * a5) & 0xffff;
  143         r[10] = (v = (0 | (v / 0x10000)) + 2 * a3 * a7 + 2 * a4 * a6
  144                      + a5 * a5) & 0xffff;
  145         r[11] = (v = (0 | (v / 0x10000)) + 2 * a4 * a7 + 2 * a5 * a6) & 0xffff;
  146         r[12] = (v = (0 | (v / 0x10000)) + 2 * a5 * a7 + a6 * a6) & 0xffff;
  147         r[13] = (v = (0 | (v / 0x10000)) + 2 * a6 * a7) & 0xffff;
  148         r[14] = (v = (0 | (v / 0x10000)) + a7 * a7) & 0xffff;
  149         r[15] = 0 | (v / 0x10000);
  150         return r;
  151     }
  152 
  153     function _sqrmodp(a) {
  154         var x = _sqr8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9],
  155                        a[8]);
  156         var z = _sqr8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]);
  157         var y = _sqr8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12]
  158                                                                  + a[4],
  159                        a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8]
  160                                                                 + a[0]);
  161         var r = [];
  162         var v;
  163         r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80)
  164                     * 38) & 0xffff;
  165         r[1] = (v = 0x7fff80 + (v >>> 16) + z[1]
  166                     + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff;
  167         r[2] = (v = 0x7fff80 + (v >>> 16) + z[2]
  168                     + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff;
  169         r[3] = (v = 0x7fff80 + (v >>> 16) + z[3]
  170                     + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff;
  171         r[4] = (v = 0x7fff80 + (v >>> 16) + z[4]
  172                     + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff;
  173         r[5] = (v = 0x7fff80 + (v >>> 16) + z[5]
  174                     + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff;
  175         r[6] = (v = 0x7fff80 + (v >>> 16) + z[6]
  176                     + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff;
  177         r[7] = (v = 0x7fff80 + (v >>> 16) + z[7]
  178                     + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff;
  179         r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0]
  180                     + x[8] * 38) & 0xffff;
  181         r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1]
  182                     + x[9] * 38) & 0xffff;
  183         r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2]
  184                      + x[10] * 38) & 0xffff;
  185         r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3]
  186                      + x[11] * 38) & 0xffff;
  187         r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4]
  188                      + x[12] * 38) & 0xffff;
  189         r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5]
  190                      + x[13] * 38) & 0xffff;
  191         r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6]
  192                      + x[14] * 38) & 0xffff;
  193         r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7]
  194                 + x[15] * 38;
  195         _reduce(r);
  196         return r;
  197     }
  198 
  199     function _mul8h(a7, a6, a5, a4, a3, a2, a1, a0, b7, b6, b5, b4, b3,
  200                     b2, b1, b0) {
  201         // 'division by 0x10000' can not be replaced by '>> 16' because
  202         // more than 32 bits of precision are needed
  203         var r = [];
  204         var v;
  205         r[0] = (v = a0 * b0) & 0xffff;
  206         r[1] = (v = (0 | (v / 0x10000)) + a0 * b1 + a1 * b0) & 0xffff;
  207         r[2] = (v = (0 | (v / 0x10000)) + a0 * b2 + a1 * b1 + a2 * b0) & 0xffff;
  208         r[3] = (v = (0 | (v / 0x10000)) + a0 * b3 + a1 * b2 + a2 * b1
  209                     + a3 * b0) & 0xffff;
  210         r[4] = (v = (0 | (v / 0x10000)) + a0 * b4 + a1 * b3 + a2 * b2
  211                     + a3 * b1 + a4 * b0) & 0xffff;
  212         r[5] = (v = (0 | (v / 0x10000)) + a0 * b5 + a1 * b4 + a2 * b3
  213                     + a3 * b2 + a4 * b1 + a5 * b0) & 0xffff;
  214         r[6] = (v = (0 | (v / 0x10000)) + a0 * b6 + a1 * b5 + a2 * b4
  215                     + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0) & 0xffff;
  216         r[7] = (v = (0 | (v / 0x10000)) + a0 * b7 + a1 * b6 + a2 * b5
  217                     + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0) & 0xffff;
  218         r[8] = (v = (0 | (v / 0x10000)) + a1 * b7 + a2 * b6 + a3 * b5
  219                     + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1) & 0xffff;
  220         r[9] = (v = (0 | (v / 0x10000)) + a2 * b7 + a3 * b6 + a4 * b5
  221                     + a5 * b4 + a6 * b3 + a7 * b2) & 0xffff;
  222         r[10] = (v = (0 | (v / 0x10000)) + a3 * b7 + a4 * b6 + a5 * b5
  223                      + a6 * b4 + a7 * b3) & 0xffff;
  224         r[11] = (v = (0 | (v / 0x10000)) + a4 * b7 + a5 * b6 + a6 * b5
  225                      + a7 * b4) & 0xffff;
  226         r[12] = (v = (0 | (v / 0x10000)) + a5 * b7 + a6 * b6 + a7 * b5) & 0xffff;
  227         r[13] = (v = (0 | (v / 0x10000)) + a6 * b7 + a7 * b6) & 0xffff;
  228         r[14] = (v = (0 | (v / 0x10000)) + a7 * b7) & 0xffff;
  229         r[15] = (0 | (v / 0x10000));
  230         return r;
  231     }
  232 
  233     function _mulmodp(a, b) {
  234         // Karatsuba multiplication scheme: x*y = (b^2+b)*x1*y1 -
  235         // b*(x1-x0)*(y1-y0) + (b+1)*x0*y0
  236         var x = _mul8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9],
  237                        a[8], b[15], b[14], b[13], b[12], b[11], b[10],
  238                        b[9], b[8]);
  239         var z = _mul8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0],
  240                        b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]);
  241         var y = _mul8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12]
  242                                                                  + a[4],
  243                        a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8]
  244                                                                 + a[0],
  245                        b[15] + b[7], b[14] + b[6], b[13] + b[5], b[12]
  246                                                                  + b[4],
  247                        b[11] + b[3], b[10] + b[2], b[9] + b[1], b[8]
  248                                                                 + b[0]);
  249         var r = [];
  250         var v;
  251         r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80)
  252                     * 38) & 0xffff;
  253         r[1] = (v = 0x7fff80 + (v >>> 16) + z[1]
  254                     + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff;
  255         r[2] = (v = 0x7fff80 + (v >>> 16) + z[2]
  256                     + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff;
  257         r[3] = (v = 0x7fff80 + (v >>> 16) + z[3]
  258                     + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff;
  259         r[4] = (v = 0x7fff80 + (v >>> 16) + z[4]
  260                     + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff;
  261         r[5] = (v = 0x7fff80 + (v >>> 16) + z[5]
  262                     + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff;
  263         r[6] = (v = 0x7fff80 + (v >>> 16) + z[6]
  264                     + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff;
  265         r[7] = (v = 0x7fff80 + (v >>> 16) + z[7]
  266                     + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff;
  267         r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0]
  268                     + x[8] * 38) & 0xffff;
  269         r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1]
  270                     + x[9] * 38) & 0xffff;
  271         r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2]
  272                      + x[10] * 38) & 0xffff;
  273         r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3]
  274                      + x[11] * 38) & 0xffff;
  275         r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4]
  276                      + x[12] * 38) & 0xffff;
  277         r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5]
  278                      + x[13] * 38) & 0xffff;
  279         r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6]
  280                      + x[14] * 38) & 0xffff;
  281         r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7]
  282                 + x[15] * 38;
  283         _reduce(r);
  284         return r;
  285     }
  286 
  287     function _reduce(arr) {
  288         var aCopy = arr.slice(0);
  289         var choice = [arr, aCopy];
  290         var v = arr[15];
  291         // Use the dummy copy instead of just returning to be more constant time.
  292         var a = choice[(v < 0x8000) & 1];
  293         a[15] = v & 0x7fff;
  294         // >32-bits of precision are required here so '/ 0x8000' can not be
  295         // replaced by the arithmetic equivalent '>>> 15'
  296         v = (0 | (v / 0x8000)) * 19;
  297         a[0] = (v += a[0]) & 0xffff;
  298         v = v >>> 16;
  299         a[1] = (v += a[1]) & 0xffff;
  300         v = v >>> 16;
  301         a[2] = (v += a[2]) & 0xffff;
  302         v = v >>> 16;
  303         a[3] = (v += a[3]) & 0xffff;
  304         v = v >>> 16;
  305         a[4] = (v += a[4]) & 0xffff;
  306         v = v >>> 16;
  307         a[5] = (v += a[5]) & 0xffff;
  308         v = v >>> 16;
  309         a[6] = (v += a[6]) & 0xffff;
  310         v = v >>> 16;
  311         a[7] = (v += a[7]) & 0xffff;
  312         v = v >>> 16;
  313         a[8] = (v += a[8]) & 0xffff;
  314         v = v >>> 16;
  315         a[9] = (v += a[9]) & 0xffff;
  316         v = v >>> 16;
  317         a[10] = (v += a[10]) & 0xffff;
  318         v = v >>> 16;
  319         a[11] = (v += a[11]) & 0xffff;
  320         v = v >>> 16;
  321         a[12] = (v += a[12]) & 0xffff;
  322         v = v >>> 16;
  323         a[13] = (v += a[13]) & 0xffff;
  324         v = v >>> 16;
  325         a[14] = (v += a[14]) & 0xffff;
  326         v = v >>> 16;
  327         a[15] += v;
  328     }
  329 
  330     function _addmodp(a, b) {
  331         var r = [];
  332         var v;
  333         r[0] = (v = ((0 | (a[15] >>> 15)) + (0 | (b[15] >>> 15))) * 19
  334                     + a[0] + b[0]) & 0xffff;
  335         r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff;
  336         r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff;
  337         r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff;
  338         r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff;
  339         r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff;
  340         r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff;
  341         r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff;
  342         r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff;
  343         r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff;
  344         r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff;
  345         r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff;
  346         r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff;
  347         r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff;
  348         r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff;
  349         r[15] = (v >>> 16) + (a[15] & 0x7fff) + (b[15] & 0x7fff);
  350         return r;
  351     }
  352 
  353     function _submodp(a, b) {
  354         var r = [];
  355         var v;
  356         r[0] = (v = 0x80000
  357                     + ((0 | (a[15] >>> 15)) - (0 | (b[15] >>> 15)) - 1)
  358                     * 19 + a[0] - b[0]) & 0xffff;
  359         r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff;
  360         r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff;
  361         r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff;
  362         r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff;
  363         r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff;
  364         r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff;
  365         r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff;
  366         r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff;
  367         r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff;
  368         r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff;
  369         r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff;
  370         r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff;
  371         r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff;
  372         r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff;
  373         r[15] = (v >>> 16) + 0x7ff8 + (a[15] & 0x7fff)
  374                 - (b[15] & 0x7fff);
  375         return r;
  376     }
  377 
  378     function _invmodp(a) {
  379         var c = a;
  380         var i = 250;
  381         while (--i) {
  382             a = _sqrmodp(a);
  383             a = _mulmodp(a, c);
  384         }
  385         a = _sqrmodp(a);
  386         a = _sqrmodp(a);
  387         a = _mulmodp(a, c);
  388         a = _sqrmodp(a);
  389         a = _sqrmodp(a);
  390         a = _mulmodp(a, c);
  391         a = _sqrmodp(a);
  392         a = _mulmodp(a, c);
  393         return a;
  394     }
  395 
  396     function _mulasmall(a) {
  397         // 'division by 0x10000' can not be replaced by '>> 16' because
  398         // more than 32 bits of precision are needed
  399         var m = 121665;
  400         var r = [];
  401         var v;
  402         r[0] = (v = a[0] * m) & 0xffff;
  403         r[1] = (v = (0 | (v / 0x10000)) + a[1] * m) & 0xffff;
  404         r[2] = (v = (0 | (v / 0x10000)) + a[2] * m) & 0xffff;
  405         r[3] = (v = (0 | (v / 0x10000)) + a[3] * m) & 0xffff;
  406         r[4] = (v = (0 | (v / 0x10000)) + a[4] * m) & 0xffff;
  407         r[5] = (v = (0 | (v / 0x10000)) + a[5] * m) & 0xffff;
  408         r[6] = (v = (0 | (v / 0x10000)) + a[6] * m) & 0xffff;
  409         r[7] = (v = (0 | (v / 0x10000)) + a[7] * m) & 0xffff;
  410         r[8] = (v = (0 | (v / 0x10000)) + a[8] * m) & 0xffff;
  411         r[9] = (v = (0 | (v / 0x10000)) + a[9] * m) & 0xffff;
  412         r[10] = (v = (0 | (v / 0x10000)) + a[10] * m) & 0xffff;
  413         r[11] = (v = (0 | (v / 0x10000)) + a[11] * m) & 0xffff;
  414         r[12] = (v = (0 | (v / 0x10000)) + a[12] * m) & 0xffff;
  415         r[13] = (v = (0 | (v / 0x10000)) + a[13] * m) & 0xffff;
  416         r[14] = (v = (0 | (v / 0x10000)) + a[14] * m) & 0xffff;
  417         r[15] = (0 | (v / 0x10000)) + a[15] * m;
  418         _reduce(r);
  419         return r;
  420     }
  421 
  422     function _dbl(x, z) {
  423         var x_2, z_2, m, n, o;
  424         m = _sqrmodp(_addmodp(x, z));
  425         n = _sqrmodp(_submodp(x, z));
  426         o = _submodp(m, n);
  427         x_2 = _mulmodp(n, m);
  428         z_2 = _mulmodp(_addmodp(_mulasmall(o), m), o);
  429         return [x_2, z_2];
  430     }
  431 
  432     function _sum(x, z, x_p, z_p, x_1) {
  433         var x_3, z_3, p, q;
  434         p = _mulmodp(_submodp(x, z), _addmodp(x_p, z_p));
  435         q = _mulmodp(_addmodp(x, z), _submodp(x_p, z_p));
  436         x_3 = _sqrmodp(_addmodp(p, q));
  437         z_3 = _mulmodp(_sqrmodp(_submodp(p, q)), x_1);
  438         return [x_3, z_3];
  439     }
  440 
  441     function _generateKey(curve25519) {
  442         var buffer = crypto.randomBytes(32);
  443 
  444         // For Curve25519 DH keys, we need to apply some bit mask on generated
  445         // keys:
  446         // * clear bit 0, 1, 2 of first byte
  447         // * clear bit 7 of last byte
  448         // * set bit 6 of last byte
  449         if (curve25519 === true) {
  450             buffer[0] &= 0xf8;
  451             buffer[31] = (buffer[31] & 0x7f) | 0x40;
  452         }
  453         var result = [];
  454         for (var i = 0; i < buffer.length; i++) {
  455             result.push(String.fromCharCode(buffer[i]));
  456         }
  457         return result.join('');
  458     }
  459 
  460     // Expose some functions to the outside through this name space.
  461     // Note: This is not part of the public API.
  462     ns.getbit = _getbit;
  463     ns.setbit = _setbit;
  464     ns.addmodp = _addmodp;
  465     ns.invmodp = _invmodp;
  466     ns.mulmodp = _mulmodp;
  467     ns.reduce = _reduce;
  468     ns.dbl = _dbl;
  469     ns.sum = _sum;
  470     ns.ZERO = _ZERO;
  471     ns.ONE = _ONE;
  472     ns.BASE = _BASE;
  473     ns.bigintadd = _bigintadd;
  474     ns.bigintsub = _bigintsub;
  475     ns.bigintcmp = _bigintcmp;
  476     ns.mulmodp = _mulmodp;
  477     ns.sqrmodp = _sqrmodp;
  478     ns.generateKey = _generateKey;
  479 
  480 
  481 module.exports = ns;