]> zoso.dev Git - libnemo.git/commitdiff
Backup working copy of nano-nacl prior to optimization efforts.
authorChris Duncan <chris@zoso.dev>
Sat, 30 Nov 2024 05:38:10 +0000 (21:38 -0800)
committerChris Duncan <chris@zoso.dev>
Sat, 30 Nov 2024 05:38:10 +0000 (21:38 -0800)
src/lib/workers/nano-nacl.ts.bkp [new file with mode: 0644]

diff --git a/src/lib/workers/nano-nacl.ts.bkp b/src/lib/workers/nano-nacl.ts.bkp
new file mode 100644 (file)
index 0000000..9d011de
--- /dev/null
@@ -0,0 +1,869 @@
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>\r
+// SPDX-License-Identifier: GPL-3.0-or-later\r
+//@ts-nocheck\r
+'use strict'\r
+\r
+// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.\r
+// Public domain.\r
+//\r
+// Implementation derived from TweetNaCl version 20140427.\r
+// See for details: http://tweetnacl.cr.yp.to/\r
+//\r
+// Modified in 2024 by Chris Duncan to hash secret key to public key using\r
+// BLAKE2b instead of SHA-512 as specified in the documentation for Nano\r
+// cryptocurrency.\r
+// See for details: https://docs.nano.org/integration-guides/the-basics/\r
+// Original source commit: https://github.com/dchest/tweetnacl-js/blob/71df1d6a1d78236ca3e9f6c788786e21f5a651a6/nacl-fast.js\r
+\r
+import type { Blake2b } from '../blake2b.js'\r
+\r
+async function NanoNaCl (Blake2b: Blake2b) {\r
+       /**\r
+       * Listens for messages from a calling function.\r
+       */\r
+       addEventListener('message', (message) => {\r
+               const { privateKey, index } = message.data ?? message\r
+               const { publicKey } = keyPair.fromSeed(privateKey)\r
+               postMessage({ publicKey, privateKey, index })\r
+       })\r
+\r
+       var gf = function (init?: any) {\r
+               var i, r = new Float64Array(16)\r
+               if (init) for (i = 0; i < init.length; i++) r[i] = init[i]\r
+               return r\r
+       }\r
+\r
+       var gf0 = gf(),\r
+               gf1 = gf([1]),\r
+               D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),\r
+               D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),\r
+               X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),\r
+               Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),\r
+               I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83])\r
+\r
+       function vn (x, xi, y, yi, n) {\r
+               var i, d = 0\r
+               for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]\r
+               return (1 & ((d - 1) >>> 8)) - 1\r
+       }\r
+\r
+       function crypto_verify_32 (x, xi, y, yi) {\r
+               return vn(x, xi, y, yi, 32)\r
+       }\r
+\r
+       function set25519 (r, a) {\r
+               var i\r
+               for (i = 0; i < 16; i++) r[i] = a[i] | 0\r
+       }\r
+\r
+       function car25519 (o) {\r
+               var i, v, c = 1\r
+               for (i = 0; i < 16; i++) {\r
+                       v = o[i] + c + 65535\r
+                       c = Math.floor(v / 65536)\r
+                       o[i] = v - c * 65536\r
+               }\r
+               o[0] += c - 1 + 37 * (c - 1)\r
+       }\r
+\r
+       function sel25519 (p, q, b) {\r
+               var t, c = ~(b - 1)\r
+               for (var i = 0; i < 16; i++) {\r
+                       t = c & (p[i] ^ q[i])\r
+                       p[i] ^= t\r
+                       q[i] ^= t\r
+               }\r
+       }\r
+\r
+       function pack25519 (o, n) {\r
+               var i, j, b\r
+               var m = gf(), t = gf()\r
+               for (i = 0; i < 16; i++) t[i] = n[i]\r
+               car25519(t)\r
+               car25519(t)\r
+               car25519(t)\r
+               for (j = 0; j < 2; j++) {\r
+                       m[0] = t[0] - 0xffed\r
+                       for (i = 1; i < 15; i++) {\r
+                               m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1)\r
+                               m[i - 1] &= 0xffff\r
+                       }\r
+                       m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1)\r
+                       b = (m[15] >> 16) & 1\r
+                       m[14] &= 0xffff\r
+                       sel25519(t, m, 1 - b)\r
+               }\r
+               for (i = 0; i < 16; i++) {\r
+                       o[2 * i] = t[i] & 0xff\r
+                       o[2 * i + 1] = t[i] >> 8\r
+               }\r
+       }\r
+\r
+       function neq25519 (a, b) {\r
+               var c = new Uint8Array(32), d = new Uint8Array(32)\r
+               pack25519(c, a)\r
+               pack25519(d, b)\r
+               return crypto_verify_32(c, 0, d, 0)\r
+       }\r
+\r
+       function par25519 (a) {\r
+               var d = new Uint8Array(32)\r
+               pack25519(d, a)\r
+               return d[0] & 1\r
+       }\r
+\r
+       function unpack25519 (o, n) {\r
+               var i\r
+               for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8)\r
+               o[15] &= 0x7fff\r
+       }\r
+\r
+       function A (o, a, b) {\r
+               for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]\r
+       }\r
+\r
+       function Z (o, a, b) {\r
+               for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]\r
+       }\r
+\r
+       function M (o, a, b) {\r
+               var v, c,\r
+                       t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,\r
+                       t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,\r
+                       t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,\r
+                       t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,\r
+                       b0 = b[0],\r
+                       b1 = b[1],\r
+                       b2 = b[2],\r
+                       b3 = b[3],\r
+                       b4 = b[4],\r
+                       b5 = b[5],\r
+                       b6 = b[6],\r
+                       b7 = b[7],\r
+                       b8 = b[8],\r
+                       b9 = b[9],\r
+                       b10 = b[10],\r
+                       b11 = b[11],\r
+                       b12 = b[12],\r
+                       b13 = b[13],\r
+                       b14 = b[14],\r
+                       b15 = b[15]\r
+\r
+               v = a[0]\r
+               t0 += v * b0\r
+               t1 += v * b1\r
+               t2 += v * b2\r
+               t3 += v * b3\r
+               t4 += v * b4\r
+               t5 += v * b5\r
+               t6 += v * b6\r
+               t7 += v * b7\r
+               t8 += v * b8\r
+               t9 += v * b9\r
+               t10 += v * b10\r
+               t11 += v * b11\r
+               t12 += v * b12\r
+               t13 += v * b13\r
+               t14 += v * b14\r
+               t15 += v * b15\r
+               v = a[1]\r
+               t1 += v * b0\r
+               t2 += v * b1\r
+               t3 += v * b2\r
+               t4 += v * b3\r
+               t5 += v * b4\r
+               t6 += v * b5\r
+               t7 += v * b6\r
+               t8 += v * b7\r
+               t9 += v * b8\r
+               t10 += v * b9\r
+               t11 += v * b10\r
+               t12 += v * b11\r
+               t13 += v * b12\r
+               t14 += v * b13\r
+               t15 += v * b14\r
+               t16 += v * b15\r
+               v = a[2]\r
+               t2 += v * b0\r
+               t3 += v * b1\r
+               t4 += v * b2\r
+               t5 += v * b3\r
+               t6 += v * b4\r
+               t7 += v * b5\r
+               t8 += v * b6\r
+               t9 += v * b7\r
+               t10 += v * b8\r
+               t11 += v * b9\r
+               t12 += v * b10\r
+               t13 += v * b11\r
+               t14 += v * b12\r
+               t15 += v * b13\r
+               t16 += v * b14\r
+               t17 += v * b15\r
+               v = a[3]\r
+               t3 += v * b0\r
+               t4 += v * b1\r
+               t5 += v * b2\r
+               t6 += v * b3\r
+               t7 += v * b4\r
+               t8 += v * b5\r
+               t9 += v * b6\r
+               t10 += v * b7\r
+               t11 += v * b8\r
+               t12 += v * b9\r
+               t13 += v * b10\r
+               t14 += v * b11\r
+               t15 += v * b12\r
+               t16 += v * b13\r
+               t17 += v * b14\r
+               t18 += v * b15\r
+               v = a[4]\r
+               t4 += v * b0\r
+               t5 += v * b1\r
+               t6 += v * b2\r
+               t7 += v * b3\r
+               t8 += v * b4\r
+               t9 += v * b5\r
+               t10 += v * b6\r
+               t11 += v * b7\r
+               t12 += v * b8\r
+               t13 += v * b9\r
+               t14 += v * b10\r
+               t15 += v * b11\r
+               t16 += v * b12\r
+               t17 += v * b13\r
+               t18 += v * b14\r
+               t19 += v * b15\r
+               v = a[5]\r
+               t5 += v * b0\r
+               t6 += v * b1\r
+               t7 += v * b2\r
+               t8 += v * b3\r
+               t9 += v * b4\r
+               t10 += v * b5\r
+               t11 += v * b6\r
+               t12 += v * b7\r
+               t13 += v * b8\r
+               t14 += v * b9\r
+               t15 += v * b10\r
+               t16 += v * b11\r
+               t17 += v * b12\r
+               t18 += v * b13\r
+               t19 += v * b14\r
+               t20 += v * b15\r
+               v = a[6]\r
+               t6 += v * b0\r
+               t7 += v * b1\r
+               t8 += v * b2\r
+               t9 += v * b3\r
+               t10 += v * b4\r
+               t11 += v * b5\r
+               t12 += v * b6\r
+               t13 += v * b7\r
+               t14 += v * b8\r
+               t15 += v * b9\r
+               t16 += v * b10\r
+               t17 += v * b11\r
+               t18 += v * b12\r
+               t19 += v * b13\r
+               t20 += v * b14\r
+               t21 += v * b15\r
+               v = a[7]\r
+               t7 += v * b0\r
+               t8 += v * b1\r
+               t9 += v * b2\r
+               t10 += v * b3\r
+               t11 += v * b4\r
+               t12 += v * b5\r
+               t13 += v * b6\r
+               t14 += v * b7\r
+               t15 += v * b8\r
+               t16 += v * b9\r
+               t17 += v * b10\r
+               t18 += v * b11\r
+               t19 += v * b12\r
+               t20 += v * b13\r
+               t21 += v * b14\r
+               t22 += v * b15\r
+               v = a[8]\r
+               t8 += v * b0\r
+               t9 += v * b1\r
+               t10 += v * b2\r
+               t11 += v * b3\r
+               t12 += v * b4\r
+               t13 += v * b5\r
+               t14 += v * b6\r
+               t15 += v * b7\r
+               t16 += v * b8\r
+               t17 += v * b9\r
+               t18 += v * b10\r
+               t19 += v * b11\r
+               t20 += v * b12\r
+               t21 += v * b13\r
+               t22 += v * b14\r
+               t23 += v * b15\r
+               v = a[9]\r
+               t9 += v * b0\r
+               t10 += v * b1\r
+               t11 += v * b2\r
+               t12 += v * b3\r
+               t13 += v * b4\r
+               t14 += v * b5\r
+               t15 += v * b6\r
+               t16 += v * b7\r
+               t17 += v * b8\r
+               t18 += v * b9\r
+               t19 += v * b10\r
+               t20 += v * b11\r
+               t21 += v * b12\r
+               t22 += v * b13\r
+               t23 += v * b14\r
+               t24 += v * b15\r
+               v = a[10]\r
+               t10 += v * b0\r
+               t11 += v * b1\r
+               t12 += v * b2\r
+               t13 += v * b3\r
+               t14 += v * b4\r
+               t15 += v * b5\r
+               t16 += v * b6\r
+               t17 += v * b7\r
+               t18 += v * b8\r
+               t19 += v * b9\r
+               t20 += v * b10\r
+               t21 += v * b11\r
+               t22 += v * b12\r
+               t23 += v * b13\r
+               t24 += v * b14\r
+               t25 += v * b15\r
+               v = a[11]\r
+               t11 += v * b0\r
+               t12 += v * b1\r
+               t13 += v * b2\r
+               t14 += v * b3\r
+               t15 += v * b4\r
+               t16 += v * b5\r
+               t17 += v * b6\r
+               t18 += v * b7\r
+               t19 += v * b8\r
+               t20 += v * b9\r
+               t21 += v * b10\r
+               t22 += v * b11\r
+               t23 += v * b12\r
+               t24 += v * b13\r
+               t25 += v * b14\r
+               t26 += v * b15\r
+               v = a[12]\r
+               t12 += v * b0\r
+               t13 += v * b1\r
+               t14 += v * b2\r
+               t15 += v * b3\r
+               t16 += v * b4\r
+               t17 += v * b5\r
+               t18 += v * b6\r
+               t19 += v * b7\r
+               t20 += v * b8\r
+               t21 += v * b9\r
+               t22 += v * b10\r
+               t23 += v * b11\r
+               t24 += v * b12\r
+               t25 += v * b13\r
+               t26 += v * b14\r
+               t27 += v * b15\r
+               v = a[13]\r
+               t13 += v * b0\r
+               t14 += v * b1\r
+               t15 += v * b2\r
+               t16 += v * b3\r
+               t17 += v * b4\r
+               t18 += v * b5\r
+               t19 += v * b6\r
+               t20 += v * b7\r
+               t21 += v * b8\r
+               t22 += v * b9\r
+               t23 += v * b10\r
+               t24 += v * b11\r
+               t25 += v * b12\r
+               t26 += v * b13\r
+               t27 += v * b14\r
+               t28 += v * b15\r
+               v = a[14]\r
+               t14 += v * b0\r
+               t15 += v * b1\r
+               t16 += v * b2\r
+               t17 += v * b3\r
+               t18 += v * b4\r
+               t19 += v * b5\r
+               t20 += v * b6\r
+               t21 += v * b7\r
+               t22 += v * b8\r
+               t23 += v * b9\r
+               t24 += v * b10\r
+               t25 += v * b11\r
+               t26 += v * b12\r
+               t27 += v * b13\r
+               t28 += v * b14\r
+               t29 += v * b15\r
+               v = a[15]\r
+               t15 += v * b0\r
+               t16 += v * b1\r
+               t17 += v * b2\r
+               t18 += v * b3\r
+               t19 += v * b4\r
+               t20 += v * b5\r
+               t21 += v * b6\r
+               t22 += v * b7\r
+               t23 += v * b8\r
+               t24 += v * b9\r
+               t25 += v * b10\r
+               t26 += v * b11\r
+               t27 += v * b12\r
+               t28 += v * b13\r
+               t29 += v * b14\r
+               t30 += v * b15\r
+\r
+               t0 += 38 * t16\r
+               t1 += 38 * t17\r
+               t2 += 38 * t18\r
+               t3 += 38 * t19\r
+               t4 += 38 * t20\r
+               t5 += 38 * t21\r
+               t6 += 38 * t22\r
+               t7 += 38 * t23\r
+               t8 += 38 * t24\r
+               t9 += 38 * t25\r
+               t10 += 38 * t26\r
+               t11 += 38 * t27\r
+               t12 += 38 * t28\r
+               t13 += 38 * t29\r
+               t14 += 38 * t30\r
+               // t15 left as is\r
+\r
+               // first car\r
+               c = 1\r
+               v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536\r
+               v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536\r
+               v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536\r
+               v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536\r
+               v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536\r
+               v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536\r
+               v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536\r
+               v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536\r
+               v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536\r
+               v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536\r
+               v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536\r
+               v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536\r
+               v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536\r
+               v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536\r
+               v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536\r
+               v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536\r
+               t0 += c - 1 + 37 * (c - 1)\r
+\r
+               // second car\r
+               c = 1\r
+               v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536\r
+               v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536\r
+               v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536\r
+               v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536\r
+               v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536\r
+               v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536\r
+               v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536\r
+               v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536\r
+               v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536\r
+               v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536\r
+               v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536\r
+               v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536\r
+               v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536\r
+               v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536\r
+               v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536\r
+               v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536\r
+               t0 += c - 1 + 37 * (c - 1)\r
+\r
+               o[0] = t0\r
+               o[1] = t1\r
+               o[2] = t2\r
+               o[3] = t3\r
+               o[4] = t4\r
+               o[5] = t5\r
+               o[6] = t6\r
+               o[7] = t7\r
+               o[8] = t8\r
+               o[9] = t9\r
+               o[10] = t10\r
+               o[11] = t11\r
+               o[12] = t12\r
+               o[13] = t13\r
+               o[14] = t14\r
+               o[15] = t15\r
+       }\r
+\r
+       function S (o, a) {\r
+               M(o, a, a)\r
+       }\r
+\r
+       function inv25519 (o, i) {\r
+               var c = gf()\r
+               var a\r
+               for (a = 0; a < 16; a++) c[a] = i[a]\r
+               for (a = 253; a >= 0; a--) {\r
+                       S(c, c)\r
+                       if (a !== 2 && a !== 4) M(c, c, i)\r
+               }\r
+               for (a = 0; a < 16; a++) o[a] = c[a]\r
+       }\r
+\r
+       function pow2523 (o, i) {\r
+               var c = gf()\r
+               var a\r
+               for (a = 0; a < 16; a++) c[a] = i[a]\r
+               for (a = 250; a >= 0; a--) {\r
+                       S(c, c)\r
+                       if (a !== 1) M(c, c, i)\r
+               }\r
+               for (a = 0; a < 16; a++) o[a] = c[a]\r
+       }\r
+\r
+       // Note: difference from TweetNaCl - BLAKE2b used to hash instead of SHA-512.\r
+       function crypto_hash (out: Uint8Array, m: Uint8Array, n: number) {\r
+               const hash = new Blake2b(64).update(m).digest()\r
+               for (let i = 0; i < 64; ++i) {\r
+                       out[i] = hash[i]\r
+               }\r
+               return 0\r
+       }\r
+\r
+       function add (p, q) {\r
+               var a = gf(), b = gf(), c = gf(),\r
+                       d = gf(), e = gf(), f = gf(),\r
+                       g = gf(), h = gf(), t = gf()\r
+\r
+               Z(a, p[1], p[0])\r
+               Z(t, q[1], q[0])\r
+               M(a, a, t)\r
+               A(b, p[0], p[1])\r
+               A(t, q[0], q[1])\r
+               M(b, b, t)\r
+               M(c, p[3], q[3])\r
+               M(c, c, D2)\r
+               M(d, p[2], q[2])\r
+               A(d, d, d)\r
+               Z(e, b, a)\r
+               Z(f, d, c)\r
+               A(g, d, c)\r
+               A(h, b, a)\r
+\r
+               M(p[0], e, f)\r
+               M(p[1], h, g)\r
+               M(p[2], g, f)\r
+               M(p[3], e, h)\r
+       }\r
+\r
+       function cswap (p, q, b) {\r
+               var i\r
+               for (i = 0; i < 4; i++) {\r
+                       sel25519(p[i], q[i], b)\r
+               }\r
+       }\r
+\r
+       function pack (r, p) {\r
+               var tx = gf(), ty = gf(), zi = gf()\r
+               inv25519(zi, p[2])\r
+               M(tx, p[0], zi)\r
+               M(ty, p[1], zi)\r
+               pack25519(r, ty)\r
+               r[31] ^= par25519(tx) << 7\r
+       }\r
+\r
+       function scalarmult (p, q, s) {\r
+               var b, i\r
+               set25519(p[0], gf0)\r
+               set25519(p[1], gf1)\r
+               set25519(p[2], gf1)\r
+               set25519(p[3], gf0)\r
+               for (i = 255; i >= 0; --i) {\r
+                       b = (s[(i / 8) | 0] >> (i & 7)) & 1\r
+                       cswap(p, q, b)\r
+                       add(q, p)\r
+                       add(p, p)\r
+                       cswap(p, q, b)\r
+               }\r
+       }\r
+\r
+       function scalarbase (p, s) {\r
+               var q = [gf(), gf(), gf(), gf()]\r
+               set25519(q[0], X)\r
+               set25519(q[1], Y)\r
+               set25519(q[2], gf1)\r
+               M(q[3], X, Y)\r
+               scalarmult(p, q, s)\r
+       }\r
+\r
+       function crypto_sign_keypair (pk: Uint8Array, sk: Uint8Array, seeded?: boolean) {\r
+               var d = new Uint8Array(64)\r
+               var p = [gf(), gf(), gf(), gf()]\r
+               var i\r
+\r
+               if (!seeded) {\r
+                       var QUOTA = 65536       // https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues\r
+                       var i, n = 32, v = new Uint8Array(n)\r
+                       for (i = 0; i < n; i += QUOTA) {\r
+                               crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)))\r
+                       }\r
+                       for (i = 0; i < n; i++) sk[i] = v[i]\r
+                       cleanup(v)\r
+               }\r
+\r
+               crypto_hash(d, sk, 32)\r
+               d[0] &= 248\r
+               d[31] &= 127\r
+               d[31] |= 64\r
+\r
+               scalarbase(p, d)\r
+               pack(pk, p)\r
+\r
+               for (i = 0; i < 32; i++) sk[i + 32] = pk[i]\r
+               return 0\r
+       }\r
+\r
+       var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10])\r
+\r
+       function modL (r, x) {\r
+               var carry, i, j, k\r
+               for (i = 63; i >= 32; --i) {\r
+                       carry = 0\r
+                       for (j = i - 32, k = i - 12; j < k; ++j) {\r
+                               x[j] += carry - 16 * x[i] * L[j - (i - 32)]\r
+                               carry = Math.floor((x[j] + 128) / 256)\r
+                               x[j] -= carry * 256\r
+                       }\r
+                       x[j] += carry\r
+                       x[i] = 0\r
+               }\r
+               carry = 0\r
+               for (j = 0; j < 32; j++) {\r
+                       x[j] += carry - (x[31] >> 4) * L[j]\r
+                       carry = x[j] >> 8\r
+                       x[j] &= 255\r
+               }\r
+               for (j = 0; j < 32; j++) x[j] -= carry * L[j]\r
+               for (i = 0; i < 32; i++) {\r
+                       x[i + 1] += x[i] >> 8\r
+                       r[i] = x[i] & 255\r
+               }\r
+       }\r
+\r
+       function reduce (r) {\r
+               var x = new Float64Array(64), i\r
+               for (i = 0; i < 64; i++) x[i] = r[i]\r
+               for (i = 0; i < 64; i++) r[i] = 0\r
+               modL(r, x)\r
+       }\r
+\r
+       // Note: difference from C - smlen returned, not passed as argument.\r
+       function crypto_sign (sm: Uint8Array, m: Uint8Array, n: number, sk: Uint8Array) {\r
+               var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64)\r
+               var i, j, x = new Float64Array(64)\r
+               var p = [gf(), gf(), gf(), gf()]\r
+\r
+               crypto_hash(d, sk, 32)\r
+               d[0] &= 248\r
+               d[31] &= 127\r
+               d[31] |= 64\r
+\r
+               var smlen = n + 64\r
+               for (i = 0; i < n; i++) sm[64 + i] = m[i]\r
+               for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]\r
+\r
+               crypto_hash(r, sm.subarray(32), n + 32)\r
+               reduce(r)\r
+               scalarbase(p, r)\r
+               pack(sm, p)\r
+\r
+               for (i = 32; i < 64; i++) sm[i] = sk[i]\r
+               crypto_hash(h, sm, n + 64)\r
+               reduce(h)\r
+\r
+               for (i = 0; i < 64; i++) x[i] = 0\r
+               for (i = 0; i < 32; i++) x[i] = r[i]\r
+               for (i = 0; i < 32; i++) {\r
+                       for (j = 0; j < 32; j++) {\r
+                               x[i + j] += h[i] * d[j]\r
+                       }\r
+               }\r
+\r
+               modL(sm.subarray(32), x)\r
+               return smlen\r
+       }\r
+\r
+       function unpackneg (r, p) {\r
+               var t = gf(), chk = gf(), num = gf(),\r
+                       den = gf(), den2 = gf(), den4 = gf(),\r
+                       den6 = gf()\r
+\r
+               set25519(r[2], gf1)\r
+               unpack25519(r[1], p)\r
+               S(num, r[1])\r
+               M(den, num, D)\r
+               Z(num, num, r[2])\r
+               A(den, r[2], den)\r
+\r
+               S(den2, den)\r
+               S(den4, den2)\r
+               M(den6, den4, den2)\r
+               M(t, den6, num)\r
+               M(t, t, den)\r
+\r
+               pow2523(t, t)\r
+               M(t, t, num)\r
+               M(t, t, den)\r
+               M(t, t, den)\r
+               M(r[0], t, den)\r
+\r
+               S(chk, r[0])\r
+               M(chk, chk, den)\r
+               if (neq25519(chk, num)) M(r[0], r[0], I)\r
+\r
+               S(chk, r[0])\r
+               M(chk, chk, den)\r
+               if (neq25519(chk, num)) return -1\r
+\r
+               if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0])\r
+\r
+               M(r[3], r[0], r[1])\r
+               return 0\r
+       }\r
+\r
+       function crypto_sign_open (m: Uint8Array, sm: Uint8Array, n: number, pk: Uint8Array) {\r
+               var i\r
+               var t = new Uint8Array(32), h = new Uint8Array(64)\r
+               var p = [gf(), gf(), gf(), gf()],\r
+                       q = [gf(), gf(), gf(), gf()]\r
+\r
+               if (n < 64) return -1\r
+\r
+               if (unpackneg(q, pk)) return -1\r
+\r
+               for (i = 0; i < n; i++) m[i] = sm[i]\r
+               for (i = 0; i < 32; i++) m[i + 32] = pk[i]\r
+               crypto_hash(h, m, n)\r
+               reduce(h)\r
+               scalarmult(p, q, h)\r
+\r
+               scalarbase(q, sm.subarray(32))\r
+               add(p, q)\r
+               pack(t, p)\r
+\r
+               n -= 64\r
+               if (crypto_verify_32(sm, 0, t, 0)) {\r
+                       for (i = 0; i < n; i++) m[i] = 0\r
+                       return -1\r
+               }\r
+\r
+               for (i = 0; i < n; i++) m[i] = sm[i + 64]\r
+               return n\r
+       }\r
+\r
+       var crypto_sign_BYTES = 64,\r
+               crypto_sign_PUBLICKEYBYTES = 32,\r
+               crypto_sign_SECRETKEYBYTES = 64,\r
+               crypto_sign_SEEDBYTES = 32\r
+\r
+       /* High-level API */\r
+\r
+       function checkArrayTypes (...args: Uint8Array[]) {\r
+               for (var i = 0; i < args.length; i++) {\r
+                       if (!(args[i] instanceof Uint8Array))\r
+                               throw new TypeError(`expected Uint8Array; received ${args[i].constructor?.name ?? typeof args[i]}`)\r
+               }\r
+       }\r
+\r
+       function cleanup (arr: Uint8Array | any[]) {\r
+               for (var i = 0; i < arr.length; i++) arr[i] = 0\r
+       }\r
+\r
+       const sign = function (msg: Uint8Array, secretKey: Uint8Array) {\r
+               checkArrayTypes(msg, secretKey)\r
+               if (secretKey.length !== crypto_sign_SECRETKEYBYTES)\r
+                       throw new Error('bad secret key size')\r
+               var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length)\r
+               crypto_sign(signedMsg, msg, msg.length, secretKey)\r
+               return signedMsg\r
+       }\r
+\r
+       const open = function (signedMsg: Uint8Array, publicKey: Uint8Array) {\r
+               checkArrayTypes(signedMsg, publicKey)\r
+               if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)\r
+                       throw new Error('bad public key size')\r
+               var tmp = new Uint8Array(signedMsg.length)\r
+               var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey)\r
+               if (mlen < 0) return null\r
+               var m = new Uint8Array(mlen)\r
+               for (var i = 0; i < m.length; i++) m[i] = tmp[i]\r
+               return m\r
+       }\r
+\r
+       const detached = function (msg: Uint8Array, secretKey: Uint8Array) {\r
+               var signedMsg = sign(msg, secretKey)\r
+               var sig = new Uint8Array(crypto_sign_BYTES)\r
+               for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]\r
+               return sig\r
+       }\r
+\r
+       const verify = function (msg: Uint8Array, sig: Uint8Array, publicKey: Uint8Array) {\r
+               checkArrayTypes(msg, sig, publicKey)\r
+               if (sig.length !== crypto_sign_BYTES)\r
+                       throw new Error('bad signature size')\r
+               if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)\r
+                       throw new Error('bad public key size')\r
+               var sm = new Uint8Array(crypto_sign_BYTES + msg.length)\r
+               var m = new Uint8Array(crypto_sign_BYTES + msg.length)\r
+               var i\r
+               for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]\r
+               for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i]\r
+               return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0)\r
+       }\r
+\r
+       const keyPair = {\r
+               create () {\r
+                       var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES)\r
+                       var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES)\r
+                       crypto_sign_keypair(pk, sk)\r
+                       return { publicKey: pk, secretKey: sk }\r
+               },\r
+\r
+               fromSecretKey (secretKey: Uint8Array) {\r
+                       checkArrayTypes(secretKey)\r
+                       if (secretKey.length !== crypto_sign_SECRETKEYBYTES)\r
+                               throw new Error('bad secret key size')\r
+                       var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES)\r
+                       for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32 + i]\r
+                       return { publicKey: pk, secretKey: new Uint8Array(secretKey) }\r
+               },\r
+\r
+               fromSeed (seed: Uint8Array) {\r
+                       checkArrayTypes(seed)\r
+                       if (seed.length !== crypto_sign_SEEDBYTES)\r
+                               throw new Error('bad seed size')\r
+                       var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES)\r
+                       var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES)\r
+                       for (var i = 0; i < 32; i++) sk[i] = seed[i]\r
+                       crypto_sign_keypair(pk, sk, true)\r
+                       return { publicKey: pk, secretKey: sk }\r
+               }\r
+       }\r
+\r
+       const publicKeyLength = crypto_sign_PUBLICKEYBYTES\r
+       const secretKeyLength = crypto_sign_SECRETKEYBYTES\r
+       const seedLength = crypto_sign_SEEDBYTES\r
+       const signatureLength = crypto_sign_BYTES\r
+\r
+}\r
+\r
+export const nacl = {\r
+       sign: NanoNaCl.sign,\r
+       open: NanoNaCl.open,\r
+       detached: NanoNaCl.detached,\r
+       verify: NanoNaCl.verify,\r
+       keyPair: NanoNaCl.keyPair\r
+}\r
+export default NanoNaCl.toString()\r