gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: JS-only crypto (only primitiv


From: gnunet
Subject: [taler-wallet-core] branch master updated: JS-only crypto (only primitives so far)
Date: Wed, 27 Nov 2019 18:00:12 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new c3ca556a JS-only crypto (only primitives so far)
c3ca556a is described below

commit c3ca556affe2f514aeb7fd052fe6d626d9319e99
Author: Florian Dold <address@hidden>
AuthorDate: Wed Nov 27 17:59:51 2019 +0100

    JS-only crypto (only primitives so far)
---
 package.json                       |    1 +
 src/crypto/cryptoImplementation.ts |    2 +-
 src/crypto/emscInterface-test.ts   |   31 +-
 src/crypto/kdf.ts                  |   58 +-
 src/crypto/nacl-fast.ts            | 1956 ++++++++++++++++++++++++------------
 src/crypto/nativeCrypto-test.ts    |   85 --
 src/crypto/nativeCrypto.ts         |  140 ---
 src/crypto/talerCrypto-test.ts     |  161 +++
 src/crypto/talerCrypto.ts          |  277 +++++
 src/headless/clk.ts                |   24 +-
 src/headless/integrationtest.ts    |    5 +-
 src/headless/taler-wallet-cli.ts   |   12 +
 tsconfig.json                      |    7 +-
 yarn.lock                          |    5 +
 14 files changed, 1803 insertions(+), 961 deletions(-)

diff --git a/package.json b/package.json
index fa8cd1d0..df470324 100644
--- a/package.json
+++ b/package.json
@@ -63,6 +63,7 @@
     "@types/chrome": "^0.0.91",
     "@types/urijs": "^1.19.3",
     "axios": "^0.19.0",
+    "big-integer": "^1.6.48",
     "idb-bridge": "^0.0.14",
     "qrcode-generator": "^1.4.3",
     "source-map-support": "^0.5.12",
diff --git a/src/crypto/cryptoImplementation.ts 
b/src/crypto/cryptoImplementation.ts
index 7dd019c1..38c63cee 100644
--- a/src/crypto/cryptoImplementation.ts
+++ b/src/crypto/cryptoImplementation.ts
@@ -45,7 +45,7 @@ import * as native from "./emscInterface";
 import { AmountJson } from "../amounts";
 import * as Amounts from "../amounts";
 import * as timer from "../timer";
-import { getRandomBytes, encodeCrock } from "./nativeCrypto";
+import { getRandomBytes, encodeCrock } from "./talerCrypto";
 
 export class CryptoImplementation {
   static enableTracing: boolean = false;
diff --git a/src/crypto/emscInterface-test.ts b/src/crypto/emscInterface-test.ts
index 422ee45e..30b9c2b5 100644
--- a/src/crypto/emscInterface-test.ts
+++ b/src/crypto/emscInterface-test.ts
@@ -20,8 +20,7 @@ import test from "ava";
 import { NodeEmscriptenLoader } from "./nodeEmscriptenLoader";
 import * as native from "./emscInterface";
 
-import nacl = require("./nacl-fast");
-import { encodeCrock, decodeCrock } from "./nativeCrypto";
+import { encodeCrock, decodeCrock } from "./talerCrypto";
 import { timestampCheck } from "../helpers";
 
 
@@ -37,12 +36,7 @@ test("string hashing", async (t) => {
 
   const te = new TextEncoder();
 
-  const x2 = te.encode("hello taler\0")
-
-  const hc2 = encodeCrock(nacl.hash(x2));
-
-  console.log(`# hc2 ${hc}`);
-  t.true(h === hc2);
+  const x2 = te.encode("hello taler\0");
 
   t.pass();
 });
@@ -68,29 +62,8 @@ test("signing", async (t) => {
   console.timeEnd("a");
   t.true(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
 
-  console.log("priv size", decodeCrock(privCrock).byteLength);
-
-  const pair = nacl.sign_keyPair_fromSeed(new 
Uint8Array(decodeCrock(privCrock)));
-
-  console.log("emsc priv", privCrock);
-  console.log("emsc pub", pubCrock);
-
-  console.log("nacl priv", encodeCrock(pair.secretKey));
-  console.log("nacl pub", encodeCrock(pair.publicKey));
-
   const d2 = new Uint8Array(decodeCrock(purposeDataCrock));
-  const d3 = nacl.hash(d2);
-
-  console.time("b");
-  for (let i = 0; i < 5000; i++) {
-    const s2 = nacl.sign_detached(d3, pair.secretKey);
-  }
-  console.timeEnd("b");
-
-  const s2 = nacl.sign_detached(d3, pair.secretKey);
-
   console.log("sig1:", sig.toCrock());
-  console.log("sig2:", encodeCrock(s2));
 
   t.pass();
 });
diff --git a/src/crypto/kdf.ts b/src/crypto/kdf.ts
index 3c44be3b..08296307 100644
--- a/src/crypto/kdf.ts
+++ b/src/crypto/kdf.ts
@@ -17,8 +17,6 @@
 import nacl = require("./nacl-fast");
 import { sha256 } from "./sha256";
 
-let createHmac: any;
-
 export function sha512(data: Uint8Array): Uint8Array {
   return nacl.hash(data);
 }
@@ -32,7 +30,6 @@ export function hmac(
   if (key.byteLength > blockSize) {
     key = digest(key);
   }
-  console.log("message", message);
   if (key.byteLength < blockSize) {
     const k = key;
     key = new Uint8Array(blockSize);
@@ -62,39 +59,34 @@ export function hmacSha256(key: Uint8Array, message: 
Uint8Array) {
   return hmac(sha256, 64, key, message);
 }
 
-/*
-function expand(prfAlgo: string, prk: Uint8Array, length: number, info: 
Uint8Array) {
-  let hashLength;
-  if (prfAlgo == "sha512") {
-    hashLength = 64;
-  } else if (prfAlgo == "sha256") {
-    hashLength = 32;
-  } else {
-    throw Error("unsupported hash");
-  }
-  info = info || Buffer.alloc(0);
-  var N = Math.ceil(length / hashLength);
-  var memo: Buffer[] = [];
-
-  for (var i = 0; i < N; i++) {
-    memo[i] = createHmac(prfAlgo, prk)
-      .update(memo[i - 1] || Buffer.alloc(0))
-      .update(info)
-      .update(Buffer.alloc(1, i + 1))
-      .digest();
-  }
-  return Buffer.concat(memo, length);
-}
-*/
-
-export function kdf(ikm: Uint8Array, salt: Uint8Array, info: Uint8Array) {
+export function kdf(
+  outputLength: number,
+  ikm: Uint8Array,
+  salt: Uint8Array,
+  info: Uint8Array,
+): Uint8Array {
   // extract
   const prk = hmacSha512(salt, ikm);
 
   // expand
+  const N = Math.ceil(outputLength / 32);
+  const output = new Uint8Array(N * 32);
+  for (let i = 0; i < N; i++) {
+    let buf;
+    if (i == 0) {
+      buf = new Uint8Array(info.byteLength + 1);
+      buf.set(info, 0);
+    } else {
+      buf = new Uint8Array(info.byteLength + 1 + 32);
+      for (let j = 0; j < 32; j++) {
+        buf[j] = output[(i - 1) * 32 + j];
+      }
+      buf.set(info, 32);
+    }
+    buf[buf.length - 1] = i + 1;
+    const chunk = hmacSha256(prk, buf);
+    output.set(chunk, i * 32);
+  }
 
-  var N = Math.ceil(length / 256);
-
-  //return expand(prfAlgo, prk, length, info);
-  return prk;
+  return output;
 }
diff --git a/src/crypto/nacl-fast.ts b/src/crypto/nacl-fast.ts
index 6757e7c5..418662e8 100644
--- a/src/crypto/nacl-fast.ts
+++ b/src/crypto/nacl-fast.ts
@@ -13,45 +13,142 @@ const gf = function(init: number[] = []) {
 
 //  Pluggable, initialized in high-level API below.
 let randombytes = function(x: Uint8Array, n: number): void {
-  throw new Error('no PRNG');
+  throw new Error("no PRNG");
 };
 
 const _0 = new Uint8Array(16);
-const _9 = new Uint8Array(32); _9[0] = 9;
+const _9 = new Uint8Array(32);
+_9[0] = 9;
 
 // prettier-ignore
 const gf0 = gf();
 const gf1 = gf([1]);
 const _121665 = gf([0xdb41, 1]);
-const D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 
0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]);
-const D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 
0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]);
-const X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 
0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]);
-const Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 
0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]);
-const I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 
0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
+const D = gf([
+  0x78a3,
+  0x1359,
+  0x4dca,
+  0x75eb,
+  0xd8ab,
+  0x4141,
+  0x0a4d,
+  0x0070,
+  0xe898,
+  0x7779,
+  0x4079,
+  0x8cc7,
+  0xfe73,
+  0x2b6f,
+  0x6cee,
+  0x5203,
+]);
+const D2 = gf([
+  0xf159,
+  0x26b2,
+  0x9b94,
+  0xebd6,
+  0xb156,
+  0x8283,
+  0x149a,
+  0x00e0,
+  0xd130,
+  0xeef3,
+  0x80f2,
+  0x198e,
+  0xfce7,
+  0x56df,
+  0xd9dc,
+  0x2406,
+]);
+const X = gf([
+  0xd51a,
+  0x8f25,
+  0x2d60,
+  0xc956,
+  0xa7b2,
+  0x9525,
+  0xc760,
+  0x692c,
+  0xdc5c,
+  0xfdd6,
+  0xe231,
+  0xc0a4,
+  0x53fe,
+  0xcd6e,
+  0x36d3,
+  0x2169,
+]);
+const Y = gf([
+  0x6658,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+  0x6666,
+]);
+const I = gf([
+  0xa0b0,
+  0x4a0e,
+  0x1b27,
+  0xc4ee,
+  0xe478,
+  0xad2f,
+  0x1806,
+  0x2f43,
+  0xd7a7,
+  0x3dfb,
+  0x0099,
+  0x2b4d,
+  0xdf0b,
+  0x4fc1,
+  0x2480,
+  0x2b83,
+]);
 
 function ts64(x: Uint8Array, i: number, h: number, l: number) {
-  x[i]   = (h >> 24) & 0xff;
-  x[i+1] = (h >> 16) & 0xff;
-  x[i+2] = (h >>  8) & 0xff;
-  x[i+3] = h & 0xff;
-  x[i+4] = (l >> 24)  & 0xff;
-  x[i+5] = (l >> 16)  & 0xff;
-  x[i+6] = (l >>  8)  & 0xff;
-  x[i+7] = l & 0xff;
+  x[i] = (h >> 24) & 0xff;
+  x[i + 1] = (h >> 16) & 0xff;
+  x[i + 2] = (h >> 8) & 0xff;
+  x[i + 3] = h & 0xff;
+  x[i + 4] = (l >> 24) & 0xff;
+  x[i + 5] = (l >> 16) & 0xff;
+  x[i + 6] = (l >> 8) & 0xff;
+  x[i + 7] = l & 0xff;
 }
 
 function vn(x: Uint8Array, xi: number, y: Uint8Array, yi: number, n: number) {
-  var i,d = 0;
-  for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];
+  var i,
+    d = 0;
+  for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i];
   return (1 & ((d - 1) >>> 8)) - 1;
 }
 
-function crypto_verify_16(x: Uint8Array, xi: number, y: Uint8Array, yi: 
number) {
-  return vn(x,xi,y,yi,16);
+function crypto_verify_16(
+  x: Uint8Array,
+  xi: number,
+  y: Uint8Array,
+  yi: number,
+) {
+  return vn(x, xi, y, yi, 16);
 }
 
-function crypto_verify_32(x: Uint8Array, xi: number, y: Uint8Array, yi: 
number) {
-  return vn(x,xi,y,yi,32);
+function crypto_verify_32(
+  x: Uint8Array,
+  xi: number,
+  y: Uint8Array,
+  yi: number,
+) {
+  return vn(x, xi, y, yi, 32);
 }
 
 // prettier-ignore
@@ -248,165 +345,284 @@ function core_salsa20(o: Uint8Array, p: Uint8Array, k: 
Uint8Array, c: Uint8Array
   o[63] = x15 >>> 24 & 0xff;
 }
 
-function core_hsalsa20(o: Uint8Array,p: Uint8Array,k: Uint8Array,c: 
Uint8Array) {
-  var j0  = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 
0xff)<<24,
-      j1  = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 
0xff)<<24,
-      j2  = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 
0xff)<<24,
-      j3  = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 
0xff)<<24,
-      j4  = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 
0xff)<<24,
-      j5  = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 
0xff)<<24,
-      j6  = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 
0xff)<<24,
-      j7  = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 
0xff)<<24,
-      j8  = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 
0xff)<<24,
-      j9  = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 
0xff)<<24,
-      j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 
0xff)<<24,
-      j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 
0xff)<<24,
-      j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 
0xff)<<24,
-      j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 
0xff)<<24,
-      j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 
0xff)<<24,
-      j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 
0xff)<<24;
-
-  var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7,
-      x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14,
-      x15 = j15, u;
+function core_hsalsa20(
+  o: Uint8Array,
+  p: Uint8Array,
+  k: Uint8Array,
+  c: Uint8Array,
+) {
+  var j0 =
+      (c[0] & 0xff) |
+      ((c[1] & 0xff) << 8) |
+      ((c[2] & 0xff) << 16) |
+      ((c[3] & 0xff) << 24),
+    j1 =
+      (k[0] & 0xff) |
+      ((k[1] & 0xff) << 8) |
+      ((k[2] & 0xff) << 16) |
+      ((k[3] & 0xff) << 24),
+    j2 =
+      (k[4] & 0xff) |
+      ((k[5] & 0xff) << 8) |
+      ((k[6] & 0xff) << 16) |
+      ((k[7] & 0xff) << 24),
+    j3 =
+      (k[8] & 0xff) |
+      ((k[9] & 0xff) << 8) |
+      ((k[10] & 0xff) << 16) |
+      ((k[11] & 0xff) << 24),
+    j4 =
+      (k[12] & 0xff) |
+      ((k[13] & 0xff) << 8) |
+      ((k[14] & 0xff) << 16) |
+      ((k[15] & 0xff) << 24),
+    j5 =
+      (c[4] & 0xff) |
+      ((c[5] & 0xff) << 8) |
+      ((c[6] & 0xff) << 16) |
+      ((c[7] & 0xff) << 24),
+    j6 =
+      (p[0] & 0xff) |
+      ((p[1] & 0xff) << 8) |
+      ((p[2] & 0xff) << 16) |
+      ((p[3] & 0xff) << 24),
+    j7 =
+      (p[4] & 0xff) |
+      ((p[5] & 0xff) << 8) |
+      ((p[6] & 0xff) << 16) |
+      ((p[7] & 0xff) << 24),
+    j8 =
+      (p[8] & 0xff) |
+      ((p[9] & 0xff) << 8) |
+      ((p[10] & 0xff) << 16) |
+      ((p[11] & 0xff) << 24),
+    j9 =
+      (p[12] & 0xff) |
+      ((p[13] & 0xff) << 8) |
+      ((p[14] & 0xff) << 16) |
+      ((p[15] & 0xff) << 24),
+    j10 =
+      (c[8] & 0xff) |
+      ((c[9] & 0xff) << 8) |
+      ((c[10] & 0xff) << 16) |
+      ((c[11] & 0xff) << 24),
+    j11 =
+      (k[16] & 0xff) |
+      ((k[17] & 0xff) << 8) |
+      ((k[18] & 0xff) << 16) |
+      ((k[19] & 0xff) << 24),
+    j12 =
+      (k[20] & 0xff) |
+      ((k[21] & 0xff) << 8) |
+      ((k[22] & 0xff) << 16) |
+      ((k[23] & 0xff) << 24),
+    j13 =
+      (k[24] & 0xff) |
+      ((k[25] & 0xff) << 8) |
+      ((k[26] & 0xff) << 16) |
+      ((k[27] & 0xff) << 24),
+    j14 =
+      (k[28] & 0xff) |
+      ((k[29] & 0xff) << 8) |
+      ((k[30] & 0xff) << 16) |
+      ((k[31] & 0xff) << 24),
+    j15 =
+      (c[12] & 0xff) |
+      ((c[13] & 0xff) << 8) |
+      ((c[14] & 0xff) << 16) |
+      ((c[15] & 0xff) << 24);
+
+  var x0 = j0,
+    x1 = j1,
+    x2 = j2,
+    x3 = j3,
+    x4 = j4,
+    x5 = j5,
+    x6 = j6,
+    x7 = j7,
+    x8 = j8,
+    x9 = j9,
+    x10 = j10,
+    x11 = j11,
+    x12 = j12,
+    x13 = j13,
+    x14 = j14,
+    x15 = j15,
+    u;
 
   for (var i = 0; i < 20; i += 2) {
-    u = x0 + x12 | 0;
-    x4 ^= u<<7 | u>>>(32-7);
-    u = x4 + x0 | 0;
-    x8 ^= u<<9 | u>>>(32-9);
-    u = x8 + x4 | 0;
-    x12 ^= u<<13 | u>>>(32-13);
-    u = x12 + x8 | 0;
-    x0 ^= u<<18 | u>>>(32-18);
-
-    u = x5 + x1 | 0;
-    x9 ^= u<<7 | u>>>(32-7);
-    u = x9 + x5 | 0;
-    x13 ^= u<<9 | u>>>(32-9);
-    u = x13 + x9 | 0;
-    x1 ^= u<<13 | u>>>(32-13);
-    u = x1 + x13 | 0;
-    x5 ^= u<<18 | u>>>(32-18);
-
-    u = x10 + x6 | 0;
-    x14 ^= u<<7 | u>>>(32-7);
-    u = x14 + x10 | 0;
-    x2 ^= u<<9 | u>>>(32-9);
-    u = x2 + x14 | 0;
-    x6 ^= u<<13 | u>>>(32-13);
-    u = x6 + x2 | 0;
-    x10 ^= u<<18 | u>>>(32-18);
-
-    u = x15 + x11 | 0;
-    x3 ^= u<<7 | u>>>(32-7);
-    u = x3 + x15 | 0;
-    x7 ^= u<<9 | u>>>(32-9);
-    u = x7 + x3 | 0;
-    x11 ^= u<<13 | u>>>(32-13);
-    u = x11 + x7 | 0;
-    x15 ^= u<<18 | u>>>(32-18);
-
-    u = x0 + x3 | 0;
-    x1 ^= u<<7 | u>>>(32-7);
-    u = x1 + x0 | 0;
-    x2 ^= u<<9 | u>>>(32-9);
-    u = x2 + x1 | 0;
-    x3 ^= u<<13 | u>>>(32-13);
-    u = x3 + x2 | 0;
-    x0 ^= u<<18 | u>>>(32-18);
-
-    u = x5 + x4 | 0;
-    x6 ^= u<<7 | u>>>(32-7);
-    u = x6 + x5 | 0;
-    x7 ^= u<<9 | u>>>(32-9);
-    u = x7 + x6 | 0;
-    x4 ^= u<<13 | u>>>(32-13);
-    u = x4 + x7 | 0;
-    x5 ^= u<<18 | u>>>(32-18);
-
-    u = x10 + x9 | 0;
-    x11 ^= u<<7 | u>>>(32-7);
-    u = x11 + x10 | 0;
-    x8 ^= u<<9 | u>>>(32-9);
-    u = x8 + x11 | 0;
-    x9 ^= u<<13 | u>>>(32-13);
-    u = x9 + x8 | 0;
-    x10 ^= u<<18 | u>>>(32-18);
-
-    u = x15 + x14 | 0;
-    x12 ^= u<<7 | u>>>(32-7);
-    u = x12 + x15 | 0;
-    x13 ^= u<<9 | u>>>(32-9);
-    u = x13 + x12 | 0;
-    x14 ^= u<<13 | u>>>(32-13);
-    u = x14 + x13 | 0;
-    x15 ^= u<<18 | u>>>(32-18);
+    u = (x0 + x12) | 0;
+    x4 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x4 + x0) | 0;
+    x8 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x8 + x4) | 0;
+    x12 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x12 + x8) | 0;
+    x0 ^= (u << 18) | (u >>> (32 - 18));
+
+    u = (x5 + x1) | 0;
+    x9 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x9 + x5) | 0;
+    x13 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x13 + x9) | 0;
+    x1 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x1 + x13) | 0;
+    x5 ^= (u << 18) | (u >>> (32 - 18));
+
+    u = (x10 + x6) | 0;
+    x14 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x14 + x10) | 0;
+    x2 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x2 + x14) | 0;
+    x6 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x6 + x2) | 0;
+    x10 ^= (u << 18) | (u >>> (32 - 18));
+
+    u = (x15 + x11) | 0;
+    x3 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x3 + x15) | 0;
+    x7 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x7 + x3) | 0;
+    x11 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x11 + x7) | 0;
+    x15 ^= (u << 18) | (u >>> (32 - 18));
+
+    u = (x0 + x3) | 0;
+    x1 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x1 + x0) | 0;
+    x2 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x2 + x1) | 0;
+    x3 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x3 + x2) | 0;
+    x0 ^= (u << 18) | (u >>> (32 - 18));
+
+    u = (x5 + x4) | 0;
+    x6 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x6 + x5) | 0;
+    x7 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x7 + x6) | 0;
+    x4 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x4 + x7) | 0;
+    x5 ^= (u << 18) | (u >>> (32 - 18));
+
+    u = (x10 + x9) | 0;
+    x11 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x11 + x10) | 0;
+    x8 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x8 + x11) | 0;
+    x9 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x9 + x8) | 0;
+    x10 ^= (u << 18) | (u >>> (32 - 18));
+
+    u = (x15 + x14) | 0;
+    x12 ^= (u << 7) | (u >>> (32 - 7));
+    u = (x12 + x15) | 0;
+    x13 ^= (u << 9) | (u >>> (32 - 9));
+    u = (x13 + x12) | 0;
+    x14 ^= (u << 13) | (u >>> (32 - 13));
+    u = (x14 + x13) | 0;
+    x15 ^= (u << 18) | (u >>> (32 - 18));
   }
 
-  o[ 0] = x0 >>>  0 & 0xff;
-  o[ 1] = x0 >>>  8 & 0xff;
-  o[ 2] = x0 >>> 16 & 0xff;
-  o[ 3] = x0 >>> 24 & 0xff;
-
-  o[ 4] = x5 >>>  0 & 0xff;
-  o[ 5] = x5 >>>  8 & 0xff;
-  o[ 6] = x5 >>> 16 & 0xff;
-  o[ 7] = x5 >>> 24 & 0xff;
-
-  o[ 8] = x10 >>>  0 & 0xff;
-  o[ 9] = x10 >>>  8 & 0xff;
-  o[10] = x10 >>> 16 & 0xff;
-  o[11] = x10 >>> 24 & 0xff;
-
-  o[12] = x15 >>>  0 & 0xff;
-  o[13] = x15 >>>  8 & 0xff;
-  o[14] = x15 >>> 16 & 0xff;
-  o[15] = x15 >>> 24 & 0xff;
-
-  o[16] = x6 >>>  0 & 0xff;
-  o[17] = x6 >>>  8 & 0xff;
-  o[18] = x6 >>> 16 & 0xff;
-  o[19] = x6 >>> 24 & 0xff;
-
-  o[20] = x7 >>>  0 & 0xff;
-  o[21] = x7 >>>  8 & 0xff;
-  o[22] = x7 >>> 16 & 0xff;
-  o[23] = x7 >>> 24 & 0xff;
-
-  o[24] = x8 >>>  0 & 0xff;
-  o[25] = x8 >>>  8 & 0xff;
-  o[26] = x8 >>> 16 & 0xff;
-  o[27] = x8 >>> 24 & 0xff;
-
-  o[28] = x9 >>>  0 & 0xff;
-  o[29] = x9 >>>  8 & 0xff;
-  o[30] = x9 >>> 16 & 0xff;
-  o[31] = x9 >>> 24 & 0xff;
+  o[0] = (x0 >>> 0) & 0xff;
+  o[1] = (x0 >>> 8) & 0xff;
+  o[2] = (x0 >>> 16) & 0xff;
+  o[3] = (x0 >>> 24) & 0xff;
+
+  o[4] = (x5 >>> 0) & 0xff;
+  o[5] = (x5 >>> 8) & 0xff;
+  o[6] = (x5 >>> 16) & 0xff;
+  o[7] = (x5 >>> 24) & 0xff;
+
+  o[8] = (x10 >>> 0) & 0xff;
+  o[9] = (x10 >>> 8) & 0xff;
+  o[10] = (x10 >>> 16) & 0xff;
+  o[11] = (x10 >>> 24) & 0xff;
+
+  o[12] = (x15 >>> 0) & 0xff;
+  o[13] = (x15 >>> 8) & 0xff;
+  o[14] = (x15 >>> 16) & 0xff;
+  o[15] = (x15 >>> 24) & 0xff;
+
+  o[16] = (x6 >>> 0) & 0xff;
+  o[17] = (x6 >>> 8) & 0xff;
+  o[18] = (x6 >>> 16) & 0xff;
+  o[19] = (x6 >>> 24) & 0xff;
+
+  o[20] = (x7 >>> 0) & 0xff;
+  o[21] = (x7 >>> 8) & 0xff;
+  o[22] = (x7 >>> 16) & 0xff;
+  o[23] = (x7 >>> 24) & 0xff;
+
+  o[24] = (x8 >>> 0) & 0xff;
+  o[25] = (x8 >>> 8) & 0xff;
+  o[26] = (x8 >>> 16) & 0xff;
+  o[27] = (x8 >>> 24) & 0xff;
+
+  o[28] = (x9 >>> 0) & 0xff;
+  o[29] = (x9 >>> 8) & 0xff;
+  o[30] = (x9 >>> 16) & 0xff;
+  o[31] = (x9 >>> 24) & 0xff;
 }
 
-function crypto_core_salsa20(out: Uint8Array, inp: Uint8Array, k: Uint8Array, 
c: Uint8Array) {
-  core_salsa20(out,inp,k,c);
+function crypto_core_salsa20(
+  out: Uint8Array,
+  inp: Uint8Array,
+  k: Uint8Array,
+  c: Uint8Array,
+) {
+  core_salsa20(out, inp, k, c);
 }
 
-function crypto_core_hsalsa20(out: Uint8Array,inp: Uint8Array,k: Uint8Array,c: 
Uint8Array) {
-  core_hsalsa20(out,inp,k,c);
+function crypto_core_hsalsa20(
+  out: Uint8Array,
+  inp: Uint8Array,
+  k: Uint8Array,
+  c: Uint8Array,
+) {
+  core_hsalsa20(out, inp, k, c);
 }
 
-var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 
121, 116, 101, 32, 107]);
-            // "expand 32-byte k"
-
-function crypto_stream_salsa20_xor(c: Uint8Array, cpos: number,m: Uint8Array, 
mpos: number,b: number,n: Uint8Array,k: Uint8Array) {
-  var z = new Uint8Array(16), x = new Uint8Array(64);
+var sigma = new Uint8Array([
+  101,
+  120,
+  112,
+  97,
+  110,
+  100,
+  32,
+  51,
+  50,
+  45,
+  98,
+  121,
+  116,
+  101,
+  32,
+  107,
+]);
+// "expand 32-byte k"
+
+function crypto_stream_salsa20_xor(
+  c: Uint8Array,
+  cpos: number,
+  m: Uint8Array,
+  mpos: number,
+  b: number,
+  n: Uint8Array,
+  k: Uint8Array,
+) {
+  var z = new Uint8Array(16),
+    x = new Uint8Array(64);
   var u, i;
   for (i = 0; i < 16; i++) z[i] = 0;
   for (i = 0; i < 8; i++) z[i] = n[i];
   while (b >= 64) {
-    crypto_core_salsa20(x,z,k,sigma);
-    for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i];
+    crypto_core_salsa20(x, z, k, sigma);
+    for (i = 0; i < 64; i++) c[cpos + i] = m[mpos + i] ^ x[i];
     u = 1;
     for (i = 8; i < 16; i++) {
-      u = u + (z[i] & 0xff) | 0;
+      u = (u + (z[i] & 0xff)) | 0;
       z[i] = u & 0xff;
       u >>>= 8;
     }
@@ -415,23 +631,30 @@ function crypto_stream_salsa20_xor(c: Uint8Array, cpos: 
number,m: Uint8Array, mp
     mpos += 64;
   }
   if (b > 0) {
-    crypto_core_salsa20(x,z,k,sigma);
-    for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i];
+    crypto_core_salsa20(x, z, k, sigma);
+    for (i = 0; i < b; i++) c[cpos + i] = m[mpos + i] ^ x[i];
   }
   return 0;
 }
 
-function crypto_stream_salsa20(c: Uint8Array ,cpos: number,b: number,n: 
Uint8Array,k: Uint8Array) {
-  var z = new Uint8Array(16), x = new Uint8Array(64);
+function crypto_stream_salsa20(
+  c: Uint8Array,
+  cpos: number,
+  b: number,
+  n: Uint8Array,
+  k: Uint8Array,
+) {
+  var z = new Uint8Array(16),
+    x = new Uint8Array(64);
   var u, i;
   for (i = 0; i < 16; i++) z[i] = 0;
   for (i = 0; i < 8; i++) z[i] = n[i];
   while (b >= 64) {
-    crypto_core_salsa20(x,z,k,sigma);
-    for (i = 0; i < 64; i++) c[cpos+i] = x[i];
+    crypto_core_salsa20(x, z, k, sigma);
+    for (i = 0; i < 64; i++) c[cpos + i] = x[i];
     u = 1;
     for (i = 8; i < 16; i++) {
-      u = u + (z[i] & 0xff) | 0;
+      u = (u + (z[i] & 0xff)) | 0;
       z[i] = u & 0xff;
       u >>>= 8;
     }
@@ -439,32 +662,46 @@ function crypto_stream_salsa20(c: Uint8Array ,cpos: 
number,b: number,n: Uint8Arr
     cpos += 64;
   }
   if (b > 0) {
-    crypto_core_salsa20(x,z,k,sigma);
-    for (i = 0; i < b; i++) c[cpos+i] = x[i];
+    crypto_core_salsa20(x, z, k, sigma);
+    for (i = 0; i < b; i++) c[cpos + i] = x[i];
   }
   return 0;
 }
 
-function crypto_stream(c: Uint8Array,cpos: number,d: number,n: Uint8Array,k: 
Uint8Array) {
+function crypto_stream(
+  c: Uint8Array,
+  cpos: number,
+  d: number,
+  n: Uint8Array,
+  k: Uint8Array,
+) {
   var s = new Uint8Array(32);
-  crypto_core_hsalsa20(s,n,k,sigma);
+  crypto_core_hsalsa20(s, n, k, sigma);
   var sn = new Uint8Array(8);
-  for (var i = 0; i < 8; i++) sn[i] = n[i+16];
-  return crypto_stream_salsa20(c,cpos,d,sn,s);
+  for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
+  return crypto_stream_salsa20(c, cpos, d, sn, s);
 }
 
-function crypto_stream_xor(c: Uint8Array, cpos: number,m: Uint8Array,mpos: 
number,d: number,n: Uint8Array,k: Uint8Array) {
+function crypto_stream_xor(
+  c: Uint8Array,
+  cpos: number,
+  m: Uint8Array,
+  mpos: number,
+  d: number,
+  n: Uint8Array,
+  k: Uint8Array,
+) {
   var s = new Uint8Array(32);
-  crypto_core_hsalsa20(s,n,k,sigma);
+  crypto_core_hsalsa20(s, n, k, sigma);
   var sn = new Uint8Array(8);
-  for (var i = 0; i < 8; i++) sn[i] = n[i+16];
-  return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s);
+  for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
+  return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, sn, s);
 }
 
 /*
-* Port of Andrew Moon's Poly1305-donna-16. Public domain.
-* https://github.com/floodyberry/poly1305-donna
-*/
+ * Port of Andrew Moon's Poly1305-donna-16. Public domain.
+ * https://github.com/floodyberry/poly1305-donna
+ */
 
 class poly1305 {
   buffer = new Uint8Array(16);
@@ -477,214 +714,250 @@ class poly1305 {
   constructor(key: Uint8Array) {
     var t0, t1, t2, t3, t4, t5, t6, t7;
 
-    t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0              
       ) & 0x1fff;
-    t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | 
(t1 <<  3)) & 0x1fff;
-    t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | 
(t2 <<  6)) & 0x1f03;
-    t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>>  7) | 
(t3 <<  9)) & 0x1fff;
-    t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>>  4) | 
(t4 << 12)) & 0x00ff;
-    this.r[5] = ((t4 >>>  1)) & 0x1ffe;
-    t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | 
(t5 <<  2)) & 0x1fff;
-    t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | 
(t6 <<  5)) & 0x1f81;
-    t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>>  8) | 
(t7 <<  8)) & 0x1fff;
-    this.r[9] = ((t7 >>>  5)) & 0x007f;
-  
-    this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8;
-    this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8;
-    this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8;
-    this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8;
-    this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8;
-    this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8;
-    this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8;
-    this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8;
+    t0 = (key[0] & 0xff) | ((key[1] & 0xff) << 8);
+    this.r[0] = t0 & 0x1fff;
+    t1 = (key[2] & 0xff) | ((key[3] & 0xff) << 8);
+    this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
+    t2 = (key[4] & 0xff) | ((key[5] & 0xff) << 8);
+    this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
+    t3 = (key[6] & 0xff) | ((key[7] & 0xff) << 8);
+    this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
+    t4 = (key[8] & 0xff) | ((key[9] & 0xff) << 8);
+    this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
+    this.r[5] = (t4 >>> 1) & 0x1ffe;
+    t5 = (key[10] & 0xff) | ((key[11] & 0xff) << 8);
+    this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
+    t6 = (key[12] & 0xff) | ((key[13] & 0xff) << 8);
+    this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
+    t7 = (key[14] & 0xff) | ((key[15] & 0xff) << 8);
+    this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
+    this.r[9] = (t7 >>> 5) & 0x007f;
+
+    this.pad[0] = (key[16] & 0xff) | ((key[17] & 0xff) << 8);
+    this.pad[1] = (key[18] & 0xff) | ((key[19] & 0xff) << 8);
+    this.pad[2] = (key[20] & 0xff) | ((key[21] & 0xff) << 8);
+    this.pad[3] = (key[22] & 0xff) | ((key[23] & 0xff) << 8);
+    this.pad[4] = (key[24] & 0xff) | ((key[25] & 0xff) << 8);
+    this.pad[5] = (key[26] & 0xff) | ((key[27] & 0xff) << 8);
+    this.pad[6] = (key[28] & 0xff) | ((key[29] & 0xff) << 8);
+    this.pad[7] = (key[30] & 0xff) | ((key[31] & 0xff) << 8);
   }
 
   blocks(m: Uint8Array, mpos: number, bytes: number) {
-    var hibit = this.fin ? 0 : (1 << 11);
+    var hibit = this.fin ? 0 : 1 << 11;
     var t0, t1, t2, t3, t4, t5, t6, t7, c;
     var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
-  
+
     var h0 = this.h[0],
-        h1 = this.h[1],
-        h2 = this.h[2],
-        h3 = this.h[3],
-        h4 = this.h[4],
-        h5 = this.h[5],
-        h6 = this.h[6],
-        h7 = this.h[7],
-        h8 = this.h[8],
-        h9 = this.h[9];
-  
+      h1 = this.h[1],
+      h2 = this.h[2],
+      h3 = this.h[3],
+      h4 = this.h[4],
+      h5 = this.h[5],
+      h6 = this.h[6],
+      h7 = this.h[7],
+      h8 = this.h[8],
+      h9 = this.h[9];
+
     var r0 = this.r[0],
-        r1 = this.r[1],
-        r2 = this.r[2],
-        r3 = this.r[3],
-        r4 = this.r[4],
-        r5 = this.r[5],
-        r6 = this.r[6],
-        r7 = this.r[7],
-        r8 = this.r[8],
-        r9 = this.r[9];
-  
+      r1 = this.r[1],
+      r2 = this.r[2],
+      r3 = this.r[3],
+      r4 = this.r[4],
+      r5 = this.r[5],
+      r6 = this.r[6],
+      r7 = this.r[7],
+      r8 = this.r[8],
+      r9 = this.r[9];
+
     while (bytes >= 16) {
-      t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0            
         ) & 0x1fff;
-      t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | 
(t1 <<  3)) & 0x1fff;
-      t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | 
(t2 <<  6)) & 0x1fff;
-      t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>>  7) | 
(t3 <<  9)) & 0x1fff;
-      t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>>  4) | 
(t4 << 12)) & 0x1fff;
-      h5 += ((t4 >>>  1)) & 0x1fff;
-      t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | 
(t5 <<  2)) & 0x1fff;
-      t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | 
(t6 <<  5)) & 0x1fff;
-      t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>>  8) | 
(t7 <<  8)) & 0x1fff;
-      h9 += ((t7 >>> 5)) | hibit;
-  
+      t0 = (m[mpos + 0] & 0xff) | ((m[mpos + 1] & 0xff) << 8);
+      h0 += t0 & 0x1fff;
+      t1 = (m[mpos + 2] & 0xff) | ((m[mpos + 3] & 0xff) << 8);
+      h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
+      t2 = (m[mpos + 4] & 0xff) | ((m[mpos + 5] & 0xff) << 8);
+      h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
+      t3 = (m[mpos + 6] & 0xff) | ((m[mpos + 7] & 0xff) << 8);
+      h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
+      t4 = (m[mpos + 8] & 0xff) | ((m[mpos + 9] & 0xff) << 8);
+      h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
+      h5 += (t4 >>> 1) & 0x1fff;
+      t5 = (m[mpos + 10] & 0xff) | ((m[mpos + 11] & 0xff) << 8);
+      h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
+      t6 = (m[mpos + 12] & 0xff) | ((m[mpos + 13] & 0xff) << 8);
+      h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
+      t7 = (m[mpos + 14] & 0xff) | ((m[mpos + 15] & 0xff) << 8);
+      h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
+      h9 += (t7 >>> 5) | hibit;
+
       c = 0;
-  
+
       d0 = c;
       d0 += h0 * r0;
       d0 += h1 * (5 * r9);
       d0 += h2 * (5 * r8);
       d0 += h3 * (5 * r7);
       d0 += h4 * (5 * r6);
-      c = (d0 >>> 13); d0 &= 0x1fff;
+      c = d0 >>> 13;
+      d0 &= 0x1fff;
       d0 += h5 * (5 * r5);
       d0 += h6 * (5 * r4);
       d0 += h7 * (5 * r3);
       d0 += h8 * (5 * r2);
       d0 += h9 * (5 * r1);
-      c += (d0 >>> 13); d0 &= 0x1fff;
-  
+      c += d0 >>> 13;
+      d0 &= 0x1fff;
+
       d1 = c;
       d1 += h0 * r1;
       d1 += h1 * r0;
       d1 += h2 * (5 * r9);
       d1 += h3 * (5 * r8);
       d1 += h4 * (5 * r7);
-      c = (d1 >>> 13); d1 &= 0x1fff;
+      c = d1 >>> 13;
+      d1 &= 0x1fff;
       d1 += h5 * (5 * r6);
       d1 += h6 * (5 * r5);
       d1 += h7 * (5 * r4);
       d1 += h8 * (5 * r3);
       d1 += h9 * (5 * r2);
-      c += (d1 >>> 13); d1 &= 0x1fff;
-  
+      c += d1 >>> 13;
+      d1 &= 0x1fff;
+
       d2 = c;
       d2 += h0 * r2;
       d2 += h1 * r1;
       d2 += h2 * r0;
       d2 += h3 * (5 * r9);
       d2 += h4 * (5 * r8);
-      c = (d2 >>> 13); d2 &= 0x1fff;
+      c = d2 >>> 13;
+      d2 &= 0x1fff;
       d2 += h5 * (5 * r7);
       d2 += h6 * (5 * r6);
       d2 += h7 * (5 * r5);
       d2 += h8 * (5 * r4);
       d2 += h9 * (5 * r3);
-      c += (d2 >>> 13); d2 &= 0x1fff;
-  
+      c += d2 >>> 13;
+      d2 &= 0x1fff;
+
       d3 = c;
       d3 += h0 * r3;
       d3 += h1 * r2;
       d3 += h2 * r1;
       d3 += h3 * r0;
       d3 += h4 * (5 * r9);
-      c = (d3 >>> 13); d3 &= 0x1fff;
+      c = d3 >>> 13;
+      d3 &= 0x1fff;
       d3 += h5 * (5 * r8);
       d3 += h6 * (5 * r7);
       d3 += h7 * (5 * r6);
       d3 += h8 * (5 * r5);
       d3 += h9 * (5 * r4);
-      c += (d3 >>> 13); d3 &= 0x1fff;
-  
+      c += d3 >>> 13;
+      d3 &= 0x1fff;
+
       d4 = c;
       d4 += h0 * r4;
       d4 += h1 * r3;
       d4 += h2 * r2;
       d4 += h3 * r1;
       d4 += h4 * r0;
-      c = (d4 >>> 13); d4 &= 0x1fff;
+      c = d4 >>> 13;
+      d4 &= 0x1fff;
       d4 += h5 * (5 * r9);
       d4 += h6 * (5 * r8);
       d4 += h7 * (5 * r7);
       d4 += h8 * (5 * r6);
       d4 += h9 * (5 * r5);
-      c += (d4 >>> 13); d4 &= 0x1fff;
-  
+      c += d4 >>> 13;
+      d4 &= 0x1fff;
+
       d5 = c;
       d5 += h0 * r5;
       d5 += h1 * r4;
       d5 += h2 * r3;
       d5 += h3 * r2;
       d5 += h4 * r1;
-      c = (d5 >>> 13); d5 &= 0x1fff;
+      c = d5 >>> 13;
+      d5 &= 0x1fff;
       d5 += h5 * r0;
       d5 += h6 * (5 * r9);
       d5 += h7 * (5 * r8);
       d5 += h8 * (5 * r7);
       d5 += h9 * (5 * r6);
-      c += (d5 >>> 13); d5 &= 0x1fff;
-  
+      c += d5 >>> 13;
+      d5 &= 0x1fff;
+
       d6 = c;
       d6 += h0 * r6;
       d6 += h1 * r5;
       d6 += h2 * r4;
       d6 += h3 * r3;
       d6 += h4 * r2;
-      c = (d6 >>> 13); d6 &= 0x1fff;
+      c = d6 >>> 13;
+      d6 &= 0x1fff;
       d6 += h5 * r1;
       d6 += h6 * r0;
       d6 += h7 * (5 * r9);
       d6 += h8 * (5 * r8);
       d6 += h9 * (5 * r7);
-      c += (d6 >>> 13); d6 &= 0x1fff;
-  
+      c += d6 >>> 13;
+      d6 &= 0x1fff;
+
       d7 = c;
       d7 += h0 * r7;
       d7 += h1 * r6;
       d7 += h2 * r5;
       d7 += h3 * r4;
       d7 += h4 * r3;
-      c = (d7 >>> 13); d7 &= 0x1fff;
+      c = d7 >>> 13;
+      d7 &= 0x1fff;
       d7 += h5 * r2;
       d7 += h6 * r1;
       d7 += h7 * r0;
       d7 += h8 * (5 * r9);
       d7 += h9 * (5 * r8);
-      c += (d7 >>> 13); d7 &= 0x1fff;
-  
+      c += d7 >>> 13;
+      d7 &= 0x1fff;
+
       d8 = c;
       d8 += h0 * r8;
       d8 += h1 * r7;
       d8 += h2 * r6;
       d8 += h3 * r5;
       d8 += h4 * r4;
-      c = (d8 >>> 13); d8 &= 0x1fff;
+      c = d8 >>> 13;
+      d8 &= 0x1fff;
       d8 += h5 * r3;
       d8 += h6 * r2;
       d8 += h7 * r1;
       d8 += h8 * r0;
       d8 += h9 * (5 * r9);
-      c += (d8 >>> 13); d8 &= 0x1fff;
-  
+      c += d8 >>> 13;
+      d8 &= 0x1fff;
+
       d9 = c;
       d9 += h0 * r9;
       d9 += h1 * r8;
       d9 += h2 * r7;
       d9 += h3 * r6;
       d9 += h4 * r5;
-      c = (d9 >>> 13); d9 &= 0x1fff;
+      c = d9 >>> 13;
+      d9 &= 0x1fff;
       d9 += h5 * r4;
       d9 += h6 * r3;
       d9 += h7 * r2;
       d9 += h8 * r1;
       d9 += h9 * r0;
-      c += (d9 >>> 13); d9 &= 0x1fff;
-  
-      c = (((c << 2) + c)) | 0;
+      c += d9 >>> 13;
+      d9 &= 0x1fff;
+
+      c = ((c << 2) + c) | 0;
       c = (c + d0) | 0;
       d0 = c & 0x1fff;
-      c = (c >>> 13);
+      c = c >>> 13;
       d1 += c;
-  
+
       h0 = d0;
       h1 = d1;
       h2 = d2;
@@ -695,7 +968,7 @@ class poly1305 {
       h7 = d7;
       h8 = d8;
       h9 = d9;
-  
+
       mpos += 16;
       bytes -= 16;
     }
@@ -714,7 +987,7 @@ class poly1305 {
   finish(mac: Uint8Array, macpos: number) {
     var g = new Uint16Array(10);
     var c, mask, f, i;
-  
+
     if (this.leftover) {
       i = this.leftover;
       this.buffer[i++] = 1;
@@ -722,7 +995,7 @@ class poly1305 {
       this.fin = 1;
       this.blocks(this.buffer, 0, 16);
     }
-  
+
     c = this.h[1] >>> 13;
     this.h[1] &= 0x1fff;
     for (i = 2; i < 10; i++) {
@@ -730,14 +1003,14 @@ class poly1305 {
       c = this.h[i] >>> 13;
       this.h[i] &= 0x1fff;
     }
-    this.h[0] += (c * 5);
+    this.h[0] += c * 5;
     c = this.h[0] >>> 13;
     this.h[0] &= 0x1fff;
     this.h[1] += c;
     c = this.h[1] >>> 13;
     this.h[1] &= 0x1fff;
     this.h[2] += c;
-  
+
     g[0] = this.h[0] + 5;
     c = g[0] >>> 13;
     g[0] &= 0x1fff;
@@ -746,131 +1019,156 @@ class poly1305 {
       c = g[i] >>> 13;
       g[i] &= 0x1fff;
     }
-    g[9] -= (1 << 13);
-  
+    g[9] -= 1 << 13;
+
     mask = (c ^ 1) - 1;
     for (i = 0; i < 10; i++) g[i] &= mask;
     mask = ~mask;
     for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i];
-  
-    this.h[0] = ((this.h[0]       ) | (this.h[1] << 13)                    ) & 
0xffff;
-    this.h[1] = ((this.h[1] >>>  3) | (this.h[2] << 10)                    ) & 
0xffff;
-    this.h[2] = ((this.h[2] >>>  6) | (this.h[3] <<  7)                    ) & 
0xffff;
-    this.h[3] = ((this.h[3] >>>  9) | (this.h[4] <<  4)                    ) & 
0xffff;
-    this.h[4] = ((this.h[4] >>> 12) | (this.h[5] <<  1) | (this.h[6] << 14)) & 
0xffff;
-    this.h[5] = ((this.h[6] >>>  2) | (this.h[7] << 11)                    ) & 
0xffff;
-    this.h[6] = ((this.h[7] >>>  5) | (this.h[8] <<  8)                    ) & 
0xffff;
-    this.h[7] = ((this.h[8] >>>  8) | (this.h[9] <<  5)                    ) & 
0xffff;
-  
+
+    this.h[0] = (this.h[0] | (this.h[1] << 13)) & 0xffff;
+    this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff;
+    this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff;
+    this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff;
+    this.h[4] =
+      ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
+    this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff;
+    this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff;
+    this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff;
+
     f = this.h[0] + this.pad[0];
     this.h[0] = f & 0xffff;
     for (i = 1; i < 8; i++) {
       f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0;
       this.h[i] = f & 0xffff;
     }
-  
-    mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff;
-    mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff;
-    mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff;
-    mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff;
-    mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff;
-    mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff;
-    mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff;
-    mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff;
-    mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff;
-    mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff;
-    mac[macpos+10] = (this.h[5] >>> 0) & 0xff;
-    mac[macpos+11] = (this.h[5] >>> 8) & 0xff;
-    mac[macpos+12] = (this.h[6] >>> 0) & 0xff;
-    mac[macpos+13] = (this.h[6] >>> 8) & 0xff;
-    mac[macpos+14] = (this.h[7] >>> 0) & 0xff;
-    mac[macpos+15] = (this.h[7] >>> 8) & 0xff;
+
+    mac[macpos + 0] = (this.h[0] >>> 0) & 0xff;
+    mac[macpos + 1] = (this.h[0] >>> 8) & 0xff;
+    mac[macpos + 2] = (this.h[1] >>> 0) & 0xff;
+    mac[macpos + 3] = (this.h[1] >>> 8) & 0xff;
+    mac[macpos + 4] = (this.h[2] >>> 0) & 0xff;
+    mac[macpos + 5] = (this.h[2] >>> 8) & 0xff;
+    mac[macpos + 6] = (this.h[3] >>> 0) & 0xff;
+    mac[macpos + 7] = (this.h[3] >>> 8) & 0xff;
+    mac[macpos + 8] = (this.h[4] >>> 0) & 0xff;
+    mac[macpos + 9] = (this.h[4] >>> 8) & 0xff;
+    mac[macpos + 10] = (this.h[5] >>> 0) & 0xff;
+    mac[macpos + 11] = (this.h[5] >>> 8) & 0xff;
+    mac[macpos + 12] = (this.h[6] >>> 0) & 0xff;
+    mac[macpos + 13] = (this.h[6] >>> 8) & 0xff;
+    mac[macpos + 14] = (this.h[7] >>> 0) & 0xff;
+    mac[macpos + 15] = (this.h[7] >>> 8) & 0xff;
   }
 
   update(m: Uint8Array, mpos: number, bytes: number) {
     var i, want;
-  
+
     if (this.leftover) {
-      want = (16 - this.leftover);
-      if (want > bytes)
-        want = bytes;
-      for (i = 0; i < want; i++)
-        this.buffer[this.leftover + i] = m[mpos+i];
+      want = 16 - this.leftover;
+      if (want > bytes) want = bytes;
+      for (i = 0; i < want; i++) this.buffer[this.leftover + i] = m[mpos + i];
       bytes -= want;
       mpos += want;
       this.leftover += want;
-      if (this.leftover < 16)
-        return;
+      if (this.leftover < 16) return;
       this.blocks(this.buffer, 0, 16);
       this.leftover = 0;
     }
-  
+
     if (bytes >= 16) {
       want = bytes - (bytes % 16);
       this.blocks(m, mpos, want);
       mpos += want;
       bytes -= want;
     }
-  
+
     if (bytes) {
-      for (i = 0; i < bytes; i++)
-        this.buffer[this.leftover + i] = m[mpos+i];
+      for (i = 0; i < bytes; i++) this.buffer[this.leftover + i] = m[mpos + i];
       this.leftover += bytes;
     }
   }
 }
 
-
-function crypto_onetimeauth(out: Uint8Array, outpos: number, m: Uint8Array, 
mpos: number, n: number, k: Uint8Array) {
+function crypto_onetimeauth(
+  out: Uint8Array,
+  outpos: number,
+  m: Uint8Array,
+  mpos: number,
+  n: number,
+  k: Uint8Array,
+) {
   var s = new poly1305(k);
   s.update(m, mpos, n);
   s.finish(out, outpos);
   return 0;
 }
 
-function crypto_onetimeauth_verify(h: Uint8Array, hpos: number, m: Uint8Array, 
mpos: number, n: number, k: Uint8Array) {
+function crypto_onetimeauth_verify(
+  h: Uint8Array,
+  hpos: number,
+  m: Uint8Array,
+  mpos: number,
+  n: number,
+  k: Uint8Array,
+) {
   var x = new Uint8Array(16);
-  crypto_onetimeauth(x,0,m,mpos,n,k);
-  return crypto_verify_16(h,hpos,x,0);
+  crypto_onetimeauth(x, 0, m, mpos, n, k);
+  return crypto_verify_16(h, hpos, x, 0);
 }
 
-function crypto_secretbox(c: Uint8Array,m: Uint8Array,d: number,n: 
Uint8Array,k: Uint8Array) {
+function crypto_secretbox(
+  c: Uint8Array,
+  m: Uint8Array,
+  d: number,
+  n: Uint8Array,
+  k: Uint8Array,
+) {
   var i;
   if (d < 32) return -1;
-  crypto_stream_xor(c,0,m,0,d,n,k);
+  crypto_stream_xor(c, 0, m, 0, d, n, k);
   crypto_onetimeauth(c, 16, c, 32, d - 32, c);
   for (i = 0; i < 16; i++) c[i] = 0;
   return 0;
 }
 
-function crypto_secretbox_open(m: Uint8Array,c: Uint8Array,d: number,n: 
Uint8Array,k: Uint8Array) {
+function crypto_secretbox_open(
+  m: Uint8Array,
+  c: Uint8Array,
+  d: number,
+  n: Uint8Array,
+  k: Uint8Array,
+) {
   var i;
   var x = new Uint8Array(32);
   if (d < 32) return -1;
-  crypto_stream(x,0,32,n,k);
-  if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1;
-  crypto_stream_xor(m,0,c,0,d,n,k);
+  crypto_stream(x, 0, 32, n, k);
+  if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) return -1;
+  crypto_stream_xor(m, 0, c, 0, d, n, k);
   for (i = 0; i < 32; i++) m[i] = 0;
   return 0;
 }
 
 function set25519(r: Float64Array, a: Float64Array) {
   var i;
-  for (i = 0; i < 16; i++) r[i] = a[i]|0;
+  for (i = 0; i < 16; i++) r[i] = a[i] | 0;
 }
 
 function car25519(o: Float64Array) {
-  var i, v, c = 1;
+  var i,
+    v,
+    c = 1;
   for (i = 0; i < 16; i++) {
     v = o[i] + c + 65535;
     c = Math.floor(v / 65536);
     o[i] = v - c * 65536;
   }
-  o[0] += c-1 + 37 * (c-1);
+  o[0] += c - 1 + 37 * (c - 1);
 }
 
 function sel25519(p: Float64Array, q: Float64Array, b: number) {
-  var t, c = ~(b-1);
+  var t,
+    c = ~(b - 1);
   for (var i = 0; i < 16; i++) {
     t = c & (p[i] ^ q[i]);
     p[i] ^= t;
@@ -880,7 +1178,8 @@ function sel25519(p: Float64Array, q: Float64Array, b: 
number) {
 
 function pack25519(o: Uint8Array, n: Float64Array) {
   var i, j, b;
-  var m = gf(), t = gf();
+  var m = gf(),
+    t = gf();
   for (i = 0; i < 16; i++) t[i] = n[i];
   car25519(t);
   car25519(t);
@@ -888,22 +1187,23 @@ function pack25519(o: Uint8Array, n: Float64Array) {
   for (j = 0; j < 2; j++) {
     m[0] = t[0] - 0xffed;
     for (i = 1; i < 15; i++) {
-      m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
-      m[i-1] &= 0xffff;
+      m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
+      m[i - 1] &= 0xffff;
     }
-    m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
-    b = (m[15]>>16) & 1;
+    m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
+    b = (m[15] >> 16) & 1;
     m[14] &= 0xffff;
-    sel25519(t, m, 1-b);
+    sel25519(t, m, 1 - b);
   }
   for (i = 0; i < 16; i++) {
-    o[2*i] = t[i] & 0xff;
-    o[2*i+1] = t[i]>>8;
+    o[2 * i] = t[i] & 0xff;
+    o[2 * i + 1] = t[i] >> 8;
   }
 }
 
 function neq25519(a: Float64Array, b: Float64Array) {
-  var c = new Uint8Array(32), d = new Uint8Array(32);
+  var c = new Uint8Array(32),
+    d = new Uint8Array(32);
   pack25519(c, a);
   pack25519(d, b);
   return crypto_verify_32(c, 0, d, 0);
@@ -917,7 +1217,7 @@ function par25519(a: Float64Array) {
 
 function unpack25519(o: Float64Array, n: Uint8Array) {
   var i;
-  for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
+  for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8);
   o[15] &= 0x7fff;
 }
 
@@ -930,11 +1230,39 @@ function Z(o: Float64Array, a: Float64Array, b: 
Float64Array) {
 }
 
 function M(o: Float64Array, a: Float64Array, b: Float64Array) {
-  var v, c,
-     t0 = 0,  t1 = 0,  t2 = 0,  t3 = 0,  t4 = 0,  t5 = 0,  t6 = 0,  t7 = 0,
-     t8 = 0,  t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,
-    t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,
-    t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,
+  var v,
+    c,
+    t0 = 0,
+    t1 = 0,
+    t2 = 0,
+    t3 = 0,
+    t4 = 0,
+    t5 = 0,
+    t6 = 0,
+    t7 = 0,
+    t8 = 0,
+    t9 = 0,
+    t10 = 0,
+    t11 = 0,
+    t12 = 0,
+    t13 = 0,
+    t14 = 0,
+    t15 = 0,
+    t16 = 0,
+    t17 = 0,
+    t18 = 0,
+    t19 = 0,
+    t20 = 0,
+    t21 = 0,
+    t22 = 0,
+    t23 = 0,
+    t24 = 0,
+    t25 = 0,
+    t26 = 0,
+    t27 = 0,
+    t28 = 0,
+    t29 = 0,
+    t30 = 0,
     b0 = b[0],
     b1 = b[1],
     b2 = b[2],
@@ -1225,16 +1553,16 @@ function M(o: Float64Array, a: Float64Array, b: 
Float64Array) {
   t29 += v * b14;
   t30 += v * b15;
 
-  t0  += 38 * t16;
-  t1  += 38 * t17;
-  t2  += 38 * t18;
-  t3  += 38 * t19;
-  t4  += 38 * t20;
-  t5  += 38 * t21;
-  t6  += 38 * t22;
-  t7  += 38 * t23;
-  t8  += 38 * t24;
-  t9  += 38 * t25;
+  t0 += 38 * t16;
+  t1 += 38 * t17;
+  t2 += 38 * t18;
+  t3 += 38 * t19;
+  t4 += 38 * t20;
+  t5 += 38 * t21;
+  t6 += 38 * t22;
+  t7 += 38 * t23;
+  t8 += 38 * t24;
+  t9 += 38 * t25;
   t10 += 38 * t26;
   t11 += 38 * t27;
   t12 += 38 * t28;
@@ -1244,54 +1572,118 @@ function M(o: Float64Array, a: Float64Array, b: 
Float64Array) {
 
   // first car
   c = 1;
-  v =  t0 + c + 65535; c = Math.floor(v / 65536);  t0 = v - c * 65536;
-  v =  t1 + c + 65535; c = Math.floor(v / 65536);  t1 = v - c * 65536;
-  v =  t2 + c + 65535; c = Math.floor(v / 65536);  t2 = v - c * 65536;
-  v =  t3 + c + 65535; c = Math.floor(v / 65536);  t3 = v - c * 65536;
-  v =  t4 + c + 65535; c = Math.floor(v / 65536);  t4 = v - c * 65536;
-  v =  t5 + c + 65535; c = Math.floor(v / 65536);  t5 = v - c * 65536;
-  v =  t6 + c + 65535; c = Math.floor(v / 65536);  t6 = v - c * 65536;
-  v =  t7 + c + 65535; c = Math.floor(v / 65536);  t7 = v - c * 65536;
-  v =  t8 + c + 65535; c = Math.floor(v / 65536);  t8 = v - c * 65536;
-  v =  t9 + c + 65535; c = Math.floor(v / 65536);  t9 = v - c * 65536;
-  v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
-  v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
-  v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
-  v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
-  v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
-  v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
-  t0 += c-1 + 37 * (c-1);
+  v = t0 + c + 65535;
+  c = Math.floor(v / 65536);
+  t0 = v - c * 65536;
+  v = t1 + c + 65535;
+  c = Math.floor(v / 65536);
+  t1 = v - c * 65536;
+  v = t2 + c + 65535;
+  c = Math.floor(v / 65536);
+  t2 = v - c * 65536;
+  v = t3 + c + 65535;
+  c = Math.floor(v / 65536);
+  t3 = v - c * 65536;
+  v = t4 + c + 65535;
+  c = Math.floor(v / 65536);
+  t4 = v - c * 65536;
+  v = t5 + c + 65535;
+  c = Math.floor(v / 65536);
+  t5 = v - c * 65536;
+  v = t6 + c + 65535;
+  c = Math.floor(v / 65536);
+  t6 = v - c * 65536;
+  v = t7 + c + 65535;
+  c = Math.floor(v / 65536);
+  t7 = v - c * 65536;
+  v = t8 + c + 65535;
+  c = Math.floor(v / 65536);
+  t8 = v - c * 65536;
+  v = t9 + c + 65535;
+  c = Math.floor(v / 65536);
+  t9 = v - c * 65536;
+  v = t10 + c + 65535;
+  c = Math.floor(v / 65536);
+  t10 = v - c * 65536;
+  v = t11 + c + 65535;
+  c = Math.floor(v / 65536);
+  t11 = v - c * 65536;
+  v = t12 + c + 65535;
+  c = Math.floor(v / 65536);
+  t12 = v - c * 65536;
+  v = t13 + c + 65535;
+  c = Math.floor(v / 65536);
+  t13 = v - c * 65536;
+  v = t14 + c + 65535;
+  c = Math.floor(v / 65536);
+  t14 = v - c * 65536;
+  v = t15 + c + 65535;
+  c = Math.floor(v / 65536);
+  t15 = v - c * 65536;
+  t0 += c - 1 + 37 * (c - 1);
 
   // second car
   c = 1;
-  v =  t0 + c + 65535; c = Math.floor(v / 65536);  t0 = v - c * 65536;
-  v =  t1 + c + 65535; c = Math.floor(v / 65536);  t1 = v - c * 65536;
-  v =  t2 + c + 65535; c = Math.floor(v / 65536);  t2 = v - c * 65536;
-  v =  t3 + c + 65535; c = Math.floor(v / 65536);  t3 = v - c * 65536;
-  v =  t4 + c + 65535; c = Math.floor(v / 65536);  t4 = v - c * 65536;
-  v =  t5 + c + 65535; c = Math.floor(v / 65536);  t5 = v - c * 65536;
-  v =  t6 + c + 65535; c = Math.floor(v / 65536);  t6 = v - c * 65536;
-  v =  t7 + c + 65535; c = Math.floor(v / 65536);  t7 = v - c * 65536;
-  v =  t8 + c + 65535; c = Math.floor(v / 65536);  t8 = v - c * 65536;
-  v =  t9 + c + 65535; c = Math.floor(v / 65536);  t9 = v - c * 65536;
-  v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
-  v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
-  v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
-  v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
-  v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
-  v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
-  t0 += c-1 + 37 * (c-1);
-
-  o[ 0] = t0;
-  o[ 1] = t1;
-  o[ 2] = t2;
-  o[ 3] = t3;
-  o[ 4] = t4;
-  o[ 5] = t5;
-  o[ 6] = t6;
-  o[ 7] = t7;
-  o[ 8] = t8;
-  o[ 9] = t9;
+  v = t0 + c + 65535;
+  c = Math.floor(v / 65536);
+  t0 = v - c * 65536;
+  v = t1 + c + 65535;
+  c = Math.floor(v / 65536);
+  t1 = v - c * 65536;
+  v = t2 + c + 65535;
+  c = Math.floor(v / 65536);
+  t2 = v - c * 65536;
+  v = t3 + c + 65535;
+  c = Math.floor(v / 65536);
+  t3 = v - c * 65536;
+  v = t4 + c + 65535;
+  c = Math.floor(v / 65536);
+  t4 = v - c * 65536;
+  v = t5 + c + 65535;
+  c = Math.floor(v / 65536);
+  t5 = v - c * 65536;
+  v = t6 + c + 65535;
+  c = Math.floor(v / 65536);
+  t6 = v - c * 65536;
+  v = t7 + c + 65535;
+  c = Math.floor(v / 65536);
+  t7 = v - c * 65536;
+  v = t8 + c + 65535;
+  c = Math.floor(v / 65536);
+  t8 = v - c * 65536;
+  v = t9 + c + 65535;
+  c = Math.floor(v / 65536);
+  t9 = v - c * 65536;
+  v = t10 + c + 65535;
+  c = Math.floor(v / 65536);
+  t10 = v - c * 65536;
+  v = t11 + c + 65535;
+  c = Math.floor(v / 65536);
+  t11 = v - c * 65536;
+  v = t12 + c + 65535;
+  c = Math.floor(v / 65536);
+  t12 = v - c * 65536;
+  v = t13 + c + 65535;
+  c = Math.floor(v / 65536);
+  t13 = v - c * 65536;
+  v = t14 + c + 65535;
+  c = Math.floor(v / 65536);
+  t14 = v - c * 65536;
+  v = t15 + c + 65535;
+  c = Math.floor(v / 65536);
+  t15 = v - c * 65536;
+  t0 += c - 1 + 37 * (c - 1);
+
+  o[0] = t0;
+  o[1] = t1;
+  o[2] = t2;
+  o[3] = t3;
+  o[4] = t4;
+  o[5] = t5;
+  o[6] = t6;
+  o[7] = t7;
+  o[8] = t8;
+  o[9] = t9;
   o[10] = t10;
   o[11] = t11;
   o[12] = t12;
@@ -1310,7 +1702,7 @@ function inv25519(o: Float64Array, i: Float64Array) {
   for (a = 0; a < 16; a++) c[a] = i[a];
   for (a = 253; a >= 0; a--) {
     S(c, c);
-    if(a !== 2 && a !== 4) M(c, c, i);
+    if (a !== 2 && a !== 4) M(c, c, i);
   }
   for (a = 0; a < 16; a++) o[a] = c[a];
 }
@@ -1320,62 +1712,68 @@ function pow2523(o: Float64Array, i: Float64Array) {
   var a;
   for (a = 0; a < 16; a++) c[a] = i[a];
   for (a = 250; a >= 0; a--) {
-      S(c, c);
-      if(a !== 1) M(c, c, i);
+    S(c, c);
+    if (a !== 1) M(c, c, i);
   }
   for (a = 0; a < 16; a++) o[a] = c[a];
 }
 
 function crypto_scalarmult(q: Uint8Array, n: Uint8Array, p: Uint8Array) {
   var z = new Uint8Array(32);
-  var x = new Float64Array(80), r, i;
-  var a = gf(), b = gf(), c = gf(),
-      d = gf(), e = gf(), f = gf();
+  var x = new Float64Array(80),
+    r,
+    i;
+  var a = gf(),
+    b = gf(),
+    c = gf(),
+    d = gf(),
+    e = gf(),
+    f = gf();
   for (i = 0; i < 31; i++) z[i] = n[i];
-  z[31]=(n[31]&127)|64;
-  z[0]&=248;
-  unpack25519(x,p);
+  z[31] = (n[31] & 127) | 64;
+  z[0] &= 248;
+  unpack25519(x, p);
   for (i = 0; i < 16; i++) {
-    b[i]=x[i];
-    d[i]=a[i]=c[i]=0;
+    b[i] = x[i];
+    d[i] = a[i] = c[i] = 0;
   }
-  a[0]=d[0]=1;
-  for (i=254; i>=0; --i) {
-    r=(z[i>>>3]>>>(i&7))&1;
-    sel25519(a,b,r);
-    sel25519(c,d,r);
-    A(e,a,c);
-    Z(a,a,c);
-    A(c,b,d);
-    Z(b,b,d);
-    S(d,e);
-    S(f,a);
-    M(a,c,a);
-    M(c,b,e);
-    A(e,a,c);
-    Z(a,a,c);
-    S(b,a);
-    Z(c,d,f);
-    M(a,c,_121665);
-    A(a,a,d);
-    M(c,c,a);
-    M(a,d,f);
-    M(d,b,x);
-    S(b,e);
-    sel25519(a,b,r);
-    sel25519(c,d,r);
+  a[0] = d[0] = 1;
+  for (i = 254; i >= 0; --i) {
+    r = (z[i >>> 3] >>> (i & 7)) & 1;
+    sel25519(a, b, r);
+    sel25519(c, d, r);
+    A(e, a, c);
+    Z(a, a, c);
+    A(c, b, d);
+    Z(b, b, d);
+    S(d, e);
+    S(f, a);
+    M(a, c, a);
+    M(c, b, e);
+    A(e, a, c);
+    Z(a, a, c);
+    S(b, a);
+    Z(c, d, f);
+    M(a, c, _121665);
+    A(a, a, d);
+    M(c, c, a);
+    M(a, d, f);
+    M(d, b, x);
+    S(b, e);
+    sel25519(a, b, r);
+    sel25519(c, d, r);
   }
   for (i = 0; i < 16; i++) {
-    x[i+16]=a[i];
-    x[i+32]=c[i];
-    x[i+48]=b[i];
-    x[i+64]=d[i];
+    x[i + 16] = a[i];
+    x[i + 32] = c[i];
+    x[i + 48] = b[i];
+    x[i + 64] = d[i];
   }
   var x32 = x.subarray(32);
   var x16 = x.subarray(16);
-  inv25519(x32,x32);
-  M(x16,x16,x32);
-  pack25519(q,x16);
+  inv25519(x32, x32);
+  M(x16, x16, x32);
+  pack25519(q, x16);
   return 0;
 }
 
@@ -1397,13 +1795,27 @@ function crypto_box_beforenm(k: Uint8Array, y: 
Uint8Array, x: Uint8Array) {
 var crypto_box_afternm = crypto_secretbox;
 var crypto_box_open_afternm = crypto_secretbox_open;
 
-function crypto_box(c: Uint8Array, m: Uint8Array, d: number, n: Uint8Array, y: 
Uint8Array, x: Uint8Array) {
+function crypto_box(
+  c: Uint8Array,
+  m: Uint8Array,
+  d: number,
+  n: Uint8Array,
+  y: Uint8Array,
+  x: Uint8Array,
+) {
   var k = new Uint8Array(32);
   crypto_box_beforenm(k, y, x);
   return crypto_box_afternm(c, m, d, n, k);
 }
 
-function crypto_box_open(m: Uint8Array, c: Uint8Array, d: number, n: 
Uint8Array, y: Uint8Array, x: Uint8Array) {
+function crypto_box_open(
+  m: Uint8Array,
+  c: Uint8Array,
+  d: number,
+  n: Uint8Array,
+  y: Uint8Array,
+  x: Uint8Array,
+) {
   var k = new Uint8Array(32);
   crypto_box_beforenm(k, y, x);
   return crypto_box_open_afternm(m, c, d, n, k);
@@ -1453,36 +1865,64 @@ var K = [
   0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
 ];
 
-function crypto_hashblocks_hl(hh: Int32Array, hl: Int32Array, m: Uint8Array, 
n: number) {
-  var wh = new Int32Array(16), wl = new Int32Array(16),
-      bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7,
-      bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7,
-      th, tl, i, j, h, l, a, b, c, d;
+function crypto_hashblocks_hl(
+  hh: Int32Array,
+  hl: Int32Array,
+  m: Uint8Array,
+  n: number,
+) {
+  var wh = new Int32Array(16),
+    wl = new Int32Array(16),
+    bh0,
+    bh1,
+    bh2,
+    bh3,
+    bh4,
+    bh5,
+    bh6,
+    bh7,
+    bl0,
+    bl1,
+    bl2,
+    bl3,
+    bl4,
+    bl5,
+    bl6,
+    bl7,
+    th,
+    tl,
+    i,
+    j,
+    h,
+    l,
+    a,
+    b,
+    c,
+    d;
 
   var ah0 = hh[0],
-      ah1 = hh[1],
-      ah2 = hh[2],
-      ah3 = hh[3],
-      ah4 = hh[4],
-      ah5 = hh[5],
-      ah6 = hh[6],
-      ah7 = hh[7],
-
-      al0 = hl[0],
-      al1 = hl[1],
-      al2 = hl[2],
-      al3 = hl[3],
-      al4 = hl[4],
-      al5 = hl[5],
-      al6 = hl[6],
-      al7 = hl[7];
+    ah1 = hh[1],
+    ah2 = hh[2],
+    ah3 = hh[3],
+    ah4 = hh[4],
+    ah5 = hh[5],
+    ah6 = hh[6],
+    ah7 = hh[7],
+    al0 = hl[0],
+    al1 = hl[1],
+    al2 = hl[2],
+    al3 = hl[3],
+    al4 = hl[4],
+    al5 = hl[5],
+    al6 = hl[6],
+    al7 = hl[7];
 
   var pos = 0;
   while (n >= 128) {
     for (i = 0; i < 16; i++) {
       j = 8 * i + pos;
-      wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3];
-      wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7];
+      wh[i] = (m[j + 0] << 24) | (m[j + 1] << 16) | (m[j + 2] << 8) | m[j + 3];
+      wl[i] = (m[j + 4] << 24) | (m[j + 5] << 16) | (m[j + 6] << 8) | m[j + 7];
     }
     for (i = 0; i < 80; i++) {
       bh0 = ah0;
@@ -1507,64 +1947,92 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
       h = ah7;
       l = al7;
 
-      a = l & 0xffff; b = l >>> 16;
-      c = h & 0xffff; d = h >>> 16;
+      a = l & 0xffff;
+      b = l >>> 16;
+      c = h & 0xffff;
+      d = h >>> 16;
 
       // Sigma1
-      h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << 
(32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32))));
-      l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << 
(32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32))));
-
-      a += l & 0xffff; b += l >>> 16;
-      c += h & 0xffff; d += h >>> 16;
+      h =
+        ((ah4 >>> 14) | (al4 << (32 - 14))) ^
+        ((ah4 >>> 18) | (al4 << (32 - 18))) ^
+        ((al4 >>> (41 - 32)) | (ah4 << (32 - (41 - 32))));
+      l =
+        ((al4 >>> 14) | (ah4 << (32 - 14))) ^
+        ((al4 >>> 18) | (ah4 << (32 - 18))) ^
+        ((ah4 >>> (41 - 32)) | (al4 << (32 - (41 - 32))));
+
+      a += l & 0xffff;
+      b += l >>> 16;
+      c += h & 0xffff;
+      d += h >>> 16;
 
       // Ch
       h = (ah4 & ah5) ^ (~ah4 & ah6);
       l = (al4 & al5) ^ (~al4 & al6);
 
-      a += l & 0xffff; b += l >>> 16;
-      c += h & 0xffff; d += h >>> 16;
+      a += l & 0xffff;
+      b += l >>> 16;
+      c += h & 0xffff;
+      d += h >>> 16;
 
       // K
-      h = K[i*2];
-      l = K[i*2+1];
+      h = K[i * 2];
+      l = K[i * 2 + 1];
 
-      a += l & 0xffff; b += l >>> 16;
-      c += h & 0xffff; d += h >>> 16;
+      a += l & 0xffff;
+      b += l >>> 16;
+      c += h & 0xffff;
+      d += h >>> 16;
 
       // w
-      h = wh[i%16];
-      l = wl[i%16];
+      h = wh[i % 16];
+      l = wl[i % 16];
 
-      a += l & 0xffff; b += l >>> 16;
-      c += h & 0xffff; d += h >>> 16;
+      a += l & 0xffff;
+      b += l >>> 16;
+      c += h & 0xffff;
+      d += h >>> 16;
 
       b += a >>> 16;
       c += b >>> 16;
       d += c >>> 16;
 
-      th = c & 0xffff | d << 16;
-      tl = a & 0xffff | b << 16;
+      th = (c & 0xffff) | (d << 16);
+      tl = (a & 0xffff) | (b << 16);
 
       // add
       h = th;
       l = tl;
 
-      a = l & 0xffff; b = l >>> 16;
-      c = h & 0xffff; d = h >>> 16;
+      a = l & 0xffff;
+      b = l >>> 16;
+      c = h & 0xffff;
+      d = h >>> 16;
 
       // Sigma0
-      h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << 
(32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32))));
-      l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << 
(32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32))));
-
-      a += l & 0xffff; b += l >>> 16;
-      c += h & 0xffff; d += h >>> 16;
+      h =
+        ((ah0 >>> 28) | (al0 << (32 - 28))) ^
+        ((al0 >>> (34 - 32)) | (ah0 << (32 - (34 - 32)))) ^
+        ((al0 >>> (39 - 32)) | (ah0 << (32 - (39 - 32))));
+      l =
+        ((al0 >>> 28) | (ah0 << (32 - 28))) ^
+        ((ah0 >>> (34 - 32)) | (al0 << (32 - (34 - 32)))) ^
+        ((ah0 >>> (39 - 32)) | (al0 << (32 - (39 - 32))));
+
+      a += l & 0xffff;
+      b += l >>> 16;
+      c += h & 0xffff;
+      d += h >>> 16;
 
       // Maj
       h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2);
       l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2);
 
-      a += l & 0xffff; b += l >>> 16;
-      c += h & 0xffff; d += h >>> 16;
+      a += l & 0xffff;
+      b += l >>> 16;
+      c += h & 0xffff;
+      d += h >>> 16;
 
       b += a >>> 16;
       c += b >>> 16;
@@ -1577,14 +2045,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
       h = bh3;
       l = bl3;
 
-      a = l & 0xffff; b = l >>> 16;
-      c = h & 0xffff; d = h >>> 16;
+      a = l & 0xffff;
+      b = l >>> 16;
+      c = h & 0xffff;
+      d = h >>> 16;
 
       h = th;
       l = tl;
 
-      a += l & 0xffff; b += l >>> 16;
-      c += h & 0xffff; d += h >>> 16;
+      a += l & 0xffff;
+      b += l >>> 16;
+      c += h & 0xffff;
+      d += h >>> 16;
 
       b += a >>> 16;
       c += b >>> 16;
@@ -1611,38 +2083,58 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
       al7 = bl6;
       al0 = bl7;
 
-      if (i%16 === 15) {
+      if (i % 16 === 15) {
         for (j = 0; j < 16; j++) {
           // add
           h = wh[j];
           l = wl[j];
 
-          a = l & 0xffff; b = l >>> 16;
-          c = h & 0xffff; d = h >>> 16;
+          a = l & 0xffff;
+          b = l >>> 16;
+          c = h & 0xffff;
+          d = h >>> 16;
 
-          h = wh[(j+9)%16];
-          l = wl[(j+9)%16];
+          h = wh[(j + 9) % 16];
+          l = wl[(j + 9) % 16];
 
-          a += l & 0xffff; b += l >>> 16;
-          c += h & 0xffff; d += h >>> 16;
+          a += l & 0xffff;
+          b += l >>> 16;
+          c += h & 0xffff;
+          d += h >>> 16;
 
           // sigma0
-          th = wh[(j+1)%16];
-          tl = wl[(j+1)%16];
-          h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ 
(th >>> 7);
-          l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ 
((tl >>> 7) | (th << (32-7)));
-
-          a += l & 0xffff; b += l >>> 16;
-          c += h & 0xffff; d += h >>> 16;
+          th = wh[(j + 1) % 16];
+          tl = wl[(j + 1) % 16];
+          h =
+            ((th >>> 1) | (tl << (32 - 1))) ^
+            ((th >>> 8) | (tl << (32 - 8))) ^
+            (th >>> 7);
+          l =
+            ((tl >>> 1) | (th << (32 - 1))) ^
+            ((tl >>> 8) | (th << (32 - 8))) ^
+            ((tl >>> 7) | (th << (32 - 7)));
+
+          a += l & 0xffff;
+          b += l >>> 16;
+          c += h & 0xffff;
+          d += h >>> 16;
 
           // sigma1
-          th = wh[(j+14)%16];
-          tl = wl[(j+14)%16];
-          h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << 
(32-(61-32)))) ^ (th >>> 6);
-          l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << 
(32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6)));
-
-          a += l & 0xffff; b += l >>> 16;
-          c += h & 0xffff; d += h >>> 16;
+          th = wh[(j + 14) % 16];
+          tl = wl[(j + 14) % 16];
+          h =
+            ((th >>> 19) | (tl << (32 - 19))) ^
+            ((tl >>> (61 - 32)) | (th << (32 - (61 - 32)))) ^
+            (th >>> 6);
+          l =
+            ((tl >>> 19) | (th << (32 - 19))) ^
+            ((th >>> (61 - 32)) | (tl << (32 - (61 - 32)))) ^
+            ((tl >>> 6) | (th << (32 - 6)));
+
+          a += l & 0xffff;
+          b += l >>> 16;
+          c += h & 0xffff;
+          d += h >>> 16;
 
           b += a >>> 16;
           c += b >>> 16;
@@ -1658,14 +2150,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah0;
     l = al0;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[0];
     l = hl[0];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1677,14 +2173,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah1;
     l = al1;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[1];
     l = hl[1];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1696,14 +2196,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah2;
     l = al2;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[2];
     l = hl[2];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1715,14 +2219,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah3;
     l = al3;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[3];
     l = hl[3];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1734,14 +2242,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah4;
     l = al4;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[4];
     l = hl[4];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1753,14 +2265,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah5;
     l = al5;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[5];
     l = hl[5];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1772,14 +2288,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah6;
     l = al6;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[6];
     l = hl[6];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1791,14 +2311,18 @@ function crypto_hashblocks_hl(hh: Int32Array, hl: 
Int32Array, m: Uint8Array, n:
     h = ah7;
     l = al7;
 
-    a = l & 0xffff; b = l >>> 16;
-    c = h & 0xffff; d = h >>> 16;
+    a = l & 0xffff;
+    b = l >>> 16;
+    c = h & 0xffff;
+    d = h >>> 16;
 
     h = hh[7];
     l = hl[7];
 
-    a += l & 0xffff; b += l >>> 16;
-    c += h & 0xffff; d += h >>> 16;
+    a += l & 0xffff;
+    b += l >>> 16;
+    c += h & 0xffff;
+    d += h >>> 16;
 
     b += a >>> 16;
     c += b >>> 16;
@@ -1842,23 +2366,29 @@ function crypto_hash(out: Uint8Array, m: Uint8Array, n: 
number) {
   crypto_hashblocks_hl(hh, hl, m, n);
   n %= 128;
 
-  for (i = 0; i < n; i++) x[i] = m[b-n+i];
+  for (i = 0; i < n; i++) x[i] = m[b - n + i];
   x[n] = 128;
 
-  n = 256-128*(n<112?1:0);
-  x[n-9] = 0;
-  ts64(x, n-8,  (b / 0x20000000) | 0, b << 3);
+  n = 256 - 128 * (n < 112 ? 1 : 0);
+  x[n - 9] = 0;
+  ts64(x, n - 8, (b / 0x20000000) | 0, b << 3);
   crypto_hashblocks_hl(hh, hl, x, n);
 
-  for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]);
+  for (i = 0; i < 8; i++) ts64(out, 8 * i, hh[i], hl[i]);
 
   return 0;
 }
 
 function add(p: Float64Array[], q: Float64Array[]) {
-  var a = gf(), b = gf(), c = gf(),
-      d = gf(), e = gf(), f = gf(),
-      g = gf(), h = gf(), t = gf();
+  var a = gf(),
+    b = gf(),
+    c = gf(),
+    d = gf(),
+    e = gf(),
+    f = gf(),
+    g = gf(),
+    h = gf(),
+    t = gf();
 
   Z(a, p[1], p[0]);
   Z(t, q[1], q[0]);
@@ -1889,7 +2419,9 @@ function cswap(p: Float64Array[], q: Float64Array[], b: 
number) {
 }
 
 function pack(r: Uint8Array, p: Float64Array[]) {
-  var tx = gf(), ty = gf(), zi = gf();
+  var tx = gf(),
+    ty = gf(),
+    zi = gf();
   inv25519(zi, p[2]);
   M(tx, p[0], zi);
   M(ty, p[1], zi);
@@ -1904,7 +2436,7 @@ function scalarmult(p: Float64Array[], q: Float64Array[], 
s: Uint8Array) {
   set25519(p[2], gf1);
   set25519(p[3], gf0);
   for (i = 255; i >= 0; --i) {
-    b = (s[(i/8)|0] >> (i&7)) & 1;
+    b = (s[(i / 8) | 0] >> (i & 7)) & 1;
     cswap(p, q, b);
     add(q, p);
     add(p, p);
@@ -1921,7 +2453,11 @@ function scalarbase(p: Float64Array[], s: Uint8Array) {
   scalarmult(p, q, s);
 }
 
-function crypto_sign_keypair(pk: Uint8Array, sk: Uint8Array, seeded: boolean): 
number {
+function crypto_sign_keypair(
+  pk: Uint8Array,
+  sk: Uint8Array,
+  seeded: boolean,
+): number {
   const d = new Uint8Array(64);
   const p = [gf(), gf(), gf(), gf()];
 
@@ -1934,11 +2470,44 @@ function crypto_sign_keypair(pk: Uint8Array, sk: 
Uint8Array, seeded: boolean): n
   scalarbase(p, d);
   pack(pk, p);
 
-  for (let i = 0; i < 32; i++) sk[i+32] = pk[i];
+  for (let i = 0; i < 32; i++) sk[i + 32] = pk[i];
   return 0;
 }
 
-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]);
+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,
+]);
 
 function modL(r: Uint8Array, x: Float64Array) {
   var carry, i, j, k;
@@ -1960,22 +2529,26 @@ function modL(r: Uint8Array, x: Float64Array) {
   }
   for (j = 0; j < 32; j++) x[j] -= carry * L[j];
   for (i = 0; i < 32; i++) {
-    x[i+1] += x[i] >> 8;
+    x[i + 1] += x[i] >> 8;
     r[i] = x[i] & 255;
   }
 }
 
 function reduce(r: Uint8Array) {
-  var x = new Float64Array(64), i;
-  for (i = 0; i < 64; i++) x[i] = r[i];
-  for (i = 0; i < 64; i++) r[i] = 0;
+  const x = new Float64Array(64);
+  for (let i = 0; i < 64; i++) x[i] = r[i];
+  for (let i = 0; i < 64; i++) r[i] = 0;
   modL(r, x);
 }
 
 // Note: difference from C - smlen returned, not passed as argument.
 function crypto_sign(sm: Uint8Array, m: Uint8Array, n: number, sk: Uint8Array) 
{
-  var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
-  var i, j, x = new Float64Array(64);
+  var d = new Uint8Array(64),
+    h = new Uint8Array(64),
+    r = new Uint8Array(64);
+  var i,
+    j,
+    x = new Float64Array(64);
   var p = [gf(), gf(), gf(), gf()];
 
   crypto_hash(d, sk, 32);
@@ -1987,7 +2560,7 @@ function crypto_sign(sm: Uint8Array, m: Uint8Array, n: 
number, sk: Uint8Array) {
   for (i = 0; i < n; i++) sm[64 + i] = m[i];
   for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
 
-  crypto_hash(r, sm.subarray(32), n+32);
+  crypto_hash(r, sm.subarray(32), n + 32);
   reduce(r);
   scalarbase(p, r);
   pack(sm, p);
@@ -2000,7 +2573,7 @@ function crypto_sign(sm: Uint8Array, m: Uint8Array, n: 
number, sk: Uint8Array) {
   for (i = 0; i < 32; i++) x[i] = r[i];
   for (i = 0; i < 32; i++) {
     for (j = 0; j < 32; j++) {
-      x[i+j] += h[i] * d[j];
+      x[i + j] += h[i] * d[j];
     }
   }
 
@@ -2009,9 +2582,13 @@ function crypto_sign(sm: Uint8Array, m: Uint8Array, n: 
number, sk: Uint8Array) {
 }
 
 function unpackneg(r: Float64Array[], p: Uint8Array) {
-  var t = gf(), chk = gf(), num = gf(),
-      den = gf(), den2 = gf(), den4 = gf(),
-      den6 = gf();
+  const t = gf();
+  const chk = gf();
+  const num = gf();
+  const den = gf();
+  const den2 = gf();
+  const den4 = gf();
+  const den6 = gf();
 
   set25519(r[2], gf1);
   unpack25519(r[1], p);
@@ -2040,17 +2617,23 @@ function unpackneg(r: Float64Array[], p: Uint8Array) {
   M(chk, chk, den);
   if (neq25519(chk, num)) return -1;
 
-  if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
+  if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0]);
 
   M(r[3], r[0], r[1]);
   return 0;
 }
 
-function crypto_sign_open(m: Uint8Array, sm: Uint8Array, n: number, pk: 
Uint8Array) {
+function crypto_sign_open(
+  m: Uint8Array,
+  sm: Uint8Array,
+  n: number,
+  pk: Uint8Array,
+) {
   var i, mlen;
-  var t = new Uint8Array(32), h = new Uint8Array(64);
+  var t = new Uint8Array(32),
+    h = new Uint8Array(64);
   var p = [gf(), gf(), gf(), gf()],
-      q = [gf(), gf(), gf(), gf()];
+    q = [gf(), gf(), gf(), gf()];
 
   mlen = -1;
   if (n < 64) return -1;
@@ -2058,7 +2641,7 @@ function crypto_sign_open(m: Uint8Array, sm: Uint8Array, 
n: number, pk: Uint8Arr
   if (unpackneg(q, pk)) return -1;
 
   for (i = 0; i < n; i++) m[i] = sm[i];
-  for (i = 0; i < 32; i++) m[i+32] = pk[i];
+  for (i = 0; i < 32; i++) m[i + 32] = pk[i];
   crypto_hash(h, m, n);
   reduce(h);
   scalarmult(p, q, h);
@@ -2079,23 +2662,22 @@ function crypto_sign_open(m: Uint8Array, sm: 
Uint8Array, n: number, pk: Uint8Arr
 }
 
 var crypto_secretbox_KEYBYTES = 32,
-    crypto_secretbox_NONCEBYTES = 24,
-    crypto_secretbox_ZEROBYTES = 32,
-    crypto_secretbox_BOXZEROBYTES = 16,
-    crypto_scalarmult_BYTES = 32,
-    crypto_scalarmult_SCALARBYTES = 32,
-    crypto_box_PUBLICKEYBYTES = 32,
-    crypto_box_SECRETKEYBYTES = 32,
-    crypto_box_BEFORENMBYTES = 32,
-    crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,
-    crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,
-    crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,
-    crypto_sign_BYTES = 64,
-    crypto_sign_PUBLICKEYBYTES = 32,
-    crypto_sign_SECRETKEYBYTES = 64,
-    crypto_sign_SEEDBYTES = 32,
-    crypto_hash_BYTES = 64;
-
+  crypto_secretbox_NONCEBYTES = 24,
+  crypto_secretbox_ZEROBYTES = 32,
+  crypto_secretbox_BOXZEROBYTES = 16,
+  crypto_scalarmult_BYTES = 32,
+  crypto_scalarmult_SCALARBYTES = 32,
+  crypto_box_PUBLICKEYBYTES = 32,
+  crypto_box_SECRETKEYBYTES = 32,
+  crypto_box_BEFORENMBYTES = 32,
+  crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,
+  crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,
+  crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,
+  crypto_sign_BYTES = 64,
+  crypto_sign_PUBLICKEYBYTES = 32,
+  crypto_sign_SECRETKEYBYTES = 64,
+  crypto_sign_SEEDBYTES = 32,
+  crypto_hash_BYTES = 64;
 
 const lowlevel = {
   crypto_core_hsalsa20: crypto_core_hsalsa20,
@@ -2137,25 +2719,28 @@ const lowlevel = {
   crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES,
   crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES,
   crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES,
-  crypto_hash_BYTES: crypto_hash_BYTES
+  crypto_hash_BYTES: crypto_hash_BYTES,
 };
 
 /* High-level API */
 
 function checkLengths(k: Uint8Array, n: Uint8Array) {
-  if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size');
-  if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce 
size');
+  if (k.length !== crypto_secretbox_KEYBYTES) throw new Error("bad key size");
+  if (n.length !== crypto_secretbox_NONCEBYTES)
+    throw new Error("bad nonce size");
 }
 
 function checkBoxLengths(pk: Uint8Array, sk: Uint8Array) {
-  if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key 
size');
-  if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key 
size');
+  if (pk.length !== crypto_box_PUBLICKEYBYTES)
+    throw new Error("bad public key size");
+  if (sk.length !== crypto_box_SECRETKEYBYTES)
+    throw new Error("bad secret key size");
 }
 
 function checkArrayTypes(...args: Uint8Array[]) {
   for (var i = 0; i < args.length; i++) {
     if (!(args[i] instanceof Uint8Array))
-      throw new TypeError('unexpected type, use Uint8Array');
+      throw new TypeError("unexpected type, use Uint8Array");
   }
 }
 
@@ -2167,29 +2752,34 @@ export function randomBytes(n: number) {
   var b = new Uint8Array(n);
   randombytes(b, n);
   return b;
-};
+}
 
 export function secretbox(msg: Uint8Array, nonce: Uint8Array, key: Uint8Array) 
{
   checkArrayTypes(msg, nonce, key);
   checkLengths(key, nonce);
   var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
   var c = new Uint8Array(m.length);
-  for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = 
msg[i];
+  for (var i = 0; i < msg.length; i++)
+    m[i + crypto_secretbox_ZEROBYTES] = msg[i];
   crypto_secretbox(c, m, m.length, nonce, key);
   return c.subarray(crypto_secretbox_BOXZEROBYTES);
-};
-
+}
 
-export function secretbox_open(box: Uint8Array, nonce: Uint8Array, key: 
Uint8Array) {
+export function secretbox_open(
+  box: Uint8Array,
+  nonce: Uint8Array,
+  key: Uint8Array,
+) {
   checkArrayTypes(box, nonce, key);
   checkLengths(key, nonce);
   var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
   var m = new Uint8Array(c.length);
-  for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = 
box[i];
+  for (var i = 0; i < box.length; i++)
+    c[i + crypto_secretbox_BOXZEROBYTES] = box[i];
   if (c.length < 32) return null;
   if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null;
   return m.subarray(crypto_secretbox_ZEROBYTES);
-};
+}
 
 export const secretbox_keyLength = crypto_secretbox_KEYBYTES;
 export const secretbox_nonceLength = crypto_secretbox_NONCEBYTES;
@@ -2197,28 +2787,33 @@ export const secretbox_overheadLength = 
crypto_secretbox_BOXZEROBYTES;
 
 export function scalarMult(n: Uint8Array, p: Uint8Array) {
   checkArrayTypes(n, p);
-  if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n 
size');
-  if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
+  if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n 
size");
+  if (p.length !== crypto_scalarmult_BYTES) throw new Error("bad p size");
   var q = new Uint8Array(crypto_scalarmult_BYTES);
   crypto_scalarmult(q, n, p);
   return q;
-};
+}
 
 export function scalarMult_base(n: Uint8Array) {
   checkArrayTypes(n);
-  if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n 
size');
+  if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n 
size");
   var q = new Uint8Array(crypto_scalarmult_BYTES);
   crypto_scalarmult_base(q, n);
   return q;
-};
+}
 
 export const scalarMult_scalarLength = crypto_scalarmult_SCALARBYTES;
 export const scalarMult_groupElementLength = crypto_scalarmult_BYTES;
 
-export function box(msg: Uint8Array, nonce: Uint8Array, publicKey: Uint8Array, 
secretKey: Uint8Array) {
+export function box(
+  msg: Uint8Array,
+  nonce: Uint8Array,
+  publicKey: Uint8Array,
+  secretKey: Uint8Array,
+) {
   var k = box_before(publicKey, secretKey);
   return secretbox(msg, nonce, k);
-};
+}
 
 export function box_before(publicKey: Uint8Array, secretKey: Uint8Array) {
   checkArrayTypes(publicKey, secretKey);
@@ -2226,14 +2821,19 @@ export function box_before(publicKey: Uint8Array, 
secretKey: Uint8Array) {
   var k = new Uint8Array(crypto_box_BEFORENMBYTES);
   crypto_box_beforenm(k, publicKey, secretKey);
   return k;
-};
+}
 
 export const box_after = secretbox;
 
-export function box_open(msg: Uint8Array, nonce: Uint8Array, publicKey: 
Uint8Array, secretKey: Uint8Array) {
+export function box_open(
+  msg: Uint8Array,
+  nonce: Uint8Array,
+  publicKey: Uint8Array,
+  secretKey: Uint8Array,
+) {
   var k = box_before(publicKey, secretKey);
   return secretbox_open(msg, nonce, k);
-};
+}
 
 export const box_open_after = secretbox_open;
 
@@ -2241,17 +2841,17 @@ export function box_keyPair() {
   var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
   var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
   crypto_box_keypair(pk, sk);
-  return {publicKey: pk, secretKey: sk};
-};
+  return { publicKey: pk, secretKey: sk };
+}
 
 export function box_keyPair_fromSecretKey(secretKey: Uint8Array) {
   checkArrayTypes(secretKey);
   if (secretKey.length !== crypto_box_SECRETKEYBYTES)
-    throw new Error('bad secret key size');
+    throw new Error("bad secret key size");
   var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
   crypto_scalarmult_base(pk, secretKey);
-  return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
-};
+  return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
+}
 
 export const box_publicKeyLength = crypto_box_PUBLICKEYBYTES;
 export const box_secretKeyLength = crypto_box_SECRETKEYBYTES;
@@ -2262,57 +2862,62 @@ export const box_overheadLength = 
secretbox_overheadLength;
 export function sign(msg: Uint8Array, secretKey: Uint8Array) {
   checkArrayTypes(msg, secretKey);
   if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
-    throw new Error('bad secret key size');
-  var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);
+    throw new Error("bad secret key size");
+  var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length);
   crypto_sign(signedMsg, msg, msg.length, secretKey);
   return signedMsg;
-};
+}
 
 export function sign_open(signedMsg: Uint8Array, publicKey: Uint8Array) {
   checkArrayTypes(signedMsg, publicKey);
   if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
-    throw new Error('bad public key size');
+    throw new Error("bad public key size");
   var tmp = new Uint8Array(signedMsg.length);
   var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
   if (mlen < 0) return null;
   var m = new Uint8Array(mlen);
   for (var i = 0; i < m.length; i++) m[i] = tmp[i];
   return m;
-};
+}
 
 export function sign_detached(msg: Uint8Array, secretKey: Uint8Array) {
   var signedMsg = sign(msg, secretKey);
   var sig = new Uint8Array(crypto_sign_BYTES);
   for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
   return sig;
-};
+}
 
-export function sign_detached_verify(msg: Uint8Array, sig: Uint8Array, 
publicKey: Uint8Array) {
+export function sign_detached_verify(
+  msg: Uint8Array,
+  sig: Uint8Array,
+  publicKey: Uint8Array,
+) {
   checkArrayTypes(msg, sig, publicKey);
-  if (sig.length !== crypto_sign_BYTES)
-    throw new Error('bad signature size');
+  if (sig.length !== crypto_sign_BYTES) throw new Error("bad signature size");
   if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
-    throw new Error('bad public key size');
+    throw new Error("bad public key size");
   var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
   var m = new Uint8Array(crypto_sign_BYTES + msg.length);
   var i;
   for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
-  for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
-  return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);
-};
+  for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i];
+  return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;
+}
 
 export function sign_keyPair() {
   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
   var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
   crypto_sign_keypair(pk, sk, false);
-  return {publicKey: pk, secretKey: sk};
-};
+  return { publicKey: pk, secretKey: sk };
+}
 
-export function x25519_edwards_keyPair_fromSecretKey(secretKey: Uint8Array): 
Uint8Array {
+export function x25519_edwards_keyPair_fromSecretKey(
+  secretKey: Uint8Array,
+): Uint8Array {
   const p = [gf(), gf(), gf(), gf()];
   const pk = new Uint8Array(32);
 
-  const d = new Uint8Array(64)
+  const d = new Uint8Array(64);
   if (secretKey.length != 32) {
     throw new Error("bad secret key size");
   }
@@ -2326,28 +2931,27 @@ export function 
x25519_edwards_keyPair_fromSecretKey(secretKey: Uint8Array): Uin
   scalarbase(p, d);
   pack(pk, p);
 
-  return pk
+  return pk;
 }
 
 export function sign_keyPair_fromSecretKey(secretKey: Uint8Array) {
   checkArrayTypes(secretKey);
   if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
-    throw new Error('bad secret key size');
+    throw new Error("bad secret key size");
   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
-  for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];
-  return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
-};
+  for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32 + i];
+  return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
+}
 
 export function sign_keyPair_fromSeed(seed: Uint8Array) {
   checkArrayTypes(seed);
-  if (seed.length !== crypto_sign_SEEDBYTES)
-    throw new Error('bad seed size');
+  if (seed.length !== crypto_sign_SEEDBYTES) throw new Error("bad seed size");
   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
   var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
   for (var i = 0; i < 32; i++) sk[i] = seed[i];
   crypto_sign_keypair(pk, sk, true);
-  return {publicKey: pk, secretKey: sk};
-};
+  return { publicKey: pk, secretKey: sk };
+}
 
 export const sign_publicKeyLength = crypto_sign_PUBLICKEYBYTES;
 export const sign_secretKeyLength = crypto_sign_SECRETKEYBYTES;
@@ -2359,7 +2963,7 @@ export function hash(msg: Uint8Array) {
   var h = new Uint8Array(crypto_hash_BYTES);
   crypto_hash(h, msg, msg.length);
   return h;
-};
+}
 
 export const hash_hashLength = crypto_hash_BYTES;
 
@@ -2368,37 +2972,65 @@ export function verify(x: Uint8Array, y: Uint8Array) {
   // Zero length arguments are considered not equal.
   if (x.length === 0 || y.length === 0) return false;
   if (x.length !== y.length) return false;
-  return (vn(x, 0, y, 0, x.length) === 0) ? true : false;
+  return vn(x, 0, y, 0, x.length) === 0 ? true : false;
 }
 
 export function setPRNG(fn: (x: Uint8Array, n: number) => void) {
   randombytes = fn;
 }
 
+export function sign_ed25519_pk_to_curve25519(
+  ed25519_pk: Uint8Array,
+): Uint8Array {
+  const ge_a = [gf(), gf(), gf(), gf()];
+  const x = gf();
+  const one_minus_y = gf();
+  const x25519_pk = new Uint8Array(32);
+
+  if (unpackneg(ge_a, ed25519_pk)) {
+    throw Error("invalid public key");
+  }
+
+  set25519(one_minus_y, gf1);
+  Z(one_minus_y, one_minus_y, ge_a[1]);
+
+  set25519(x, gf1);
+  A(x, x, ge_a[1]);
+
+  inv25519(one_minus_y, one_minus_y);
+  M(x, x, one_minus_y);
+  pack25519(x25519_pk, x);
+
+  return x25519_pk;
+}
+
 (function() {
   // Initialize PRNG if environment provides CSPRNG.
   // If not, methods calling randombytes will throw.
-  const crypto = typeof self !== 'undefined' ? (self.crypto || (self as 
any).msCrypto) : null;
+  const crypto =
+    typeof self !== "undefined" ? self.crypto || (self as any).msCrypto : null;
   if (crypto && crypto.getRandomValues) {
     // Browsers.
     var QUOTA = 65536;
     setPRNG(function(x: Uint8Array, n: number) {
-      var i, v = new Uint8Array(n);
+      var i,
+        v = new Uint8Array(n);
       for (i = 0; i < n; i += QUOTA) {
         crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
       }
       for (i = 0; i < n; i++) x[i] = v[i];
       cleanup(v);
     });
-  } else if (typeof require !== 'undefined') {
+  } else if (typeof require !== "undefined") {
     // Node.js.
-    const cr = require('crypto');
+    const cr = require("crypto");
     if (cr && cr.randomBytes) {
       setPRNG(function(x: Uint8Array, n: number) {
-        var i, v = cr.randomBytes(n);
+        var i,
+          v = cr.randomBytes(n);
         for (i = 0; i < n; i++) x[i] = v[i];
         cleanup(v);
       });
     }
   }
-})();
\ No newline at end of file
+})();
diff --git a/src/crypto/nativeCrypto-test.ts b/src/crypto/nativeCrypto-test.ts
deleted file mode 100644
index c3811057..00000000
--- a/src/crypto/nativeCrypto-test.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2019 GNUnet e.V.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- * Imports
- */
-import test from "ava";
-import { encodeCrock, decodeCrock } from "./nativeCrypto";
-import { hmacSha512, sha512 } from "./kdf";
-import nacl = require("./nacl-fast");
-
-function hexToBytes(hex: string) {
-  for (var bytes = [], c = 0; c < hex.length; c += 2)
-    bytes.push(parseInt(hex.substr(c, 2), 16));
-  return bytes;
-}
-
-function bytesToHex(bytes: Uint8Array): string {
-  for (var hex = [], i = 0; i < bytes.length; i++) {
-    var current = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];
-    hex.push((current >>> 4).toString(16));
-    hex.push((current & 0xf).toString(16));
-  }
-  return hex.join("");
-}
-
-test("encoding", t => {
-  const utf8decoder = new TextDecoder("utf-8");
-  const utf8encoder = new TextEncoder();
-  const s = "Hello, World";
-  const encStr = encodeCrock(utf8encoder.encode(s));
-  const outBuf = decodeCrock(encStr);
-  const sOut = utf8decoder.decode(outBuf);
-  t.deepEqual(s, sOut);
-});
-
-test("taler-exchange-tvg hash code", t => {
-  const input = "91JPRV3F5GG4EKJN41A62V35E8";
-  const output =
-    
"CW96WR74JS8T53EC8GKSGD49QKH4ZNFTZXDAWMMV5GJ1E4BM6B8GPN5NVHDJ8ZVXNCW7Q4WBYCV61HCA3PZC2YJD850DT29RHHN7ESR";
-
-  const myOutput = encodeCrock(sha512(decodeCrock(input)));
-
-  t.deepEqual(myOutput, output);
-});
-
-test("taler-exchange-tvg ecdhe key", t => {
-  const priv1 = "YSYA38XH1PH40ZPSEZCXEFX9PH9Q3A2PE19FHM54DMTZ4MAPH9S0";
-  const pub1 = "GNQRNSYF4BT4V0EV0DBXZCHFVQ79ATP0KBJ9EAY18FGSY513A5VG";
-
-  const myPub = nacl.x25519_edwards_keyPair_fromSecretKey(decodeCrock(priv1))
-  t.deepEqual(encodeCrock(myPub), pub1);
-
-  //const myPub1 = nacl.scalarMult.base(decodeCrock(priv1));
-  //t.deepEqual(encodeCrock(myPub1), pub1);
-
-  //const p = nacl.box.keyPair.fromSecretKey(decodeCrock(priv1))
-  //t.deepEqual(encodeCrock(p.publicKey), pub1);
-
-  //const r = nacl.scalarMult(decodeCrock(priv2), decodeCrock(pub1));
-  //t.deepEqual(encodeCrock(nacl.hash(r)), skm);
-
-  //const mySkm = nacl.
-});
-
-test("taler-exchange-tvg eddsa key", t => {
-  const priv = "H2JGQ2T3A5WBC5QV3YRFE31AMRGF2F9WPXZ03EM3NS3PYHM80WA0";
-  const pub = "QFGMB2WTPYXMXZRPFYFEM2VMQ028M71JMECF31P3J8VC3SCJ777G";
-  
-  const pair = nacl.sign_keyPair_fromSeed(decodeCrock(priv));
-  t.deepEqual(encodeCrock(pair.publicKey), pub);
-});
diff --git a/src/crypto/nativeCrypto.ts b/src/crypto/nativeCrypto.ts
deleted file mode 100644
index 306d2200..00000000
--- a/src/crypto/nativeCrypto.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2019 GNUnet e.V.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- * Native implementation of GNU Taler crypto.
- */
-
-let isNode;
-
-let myGetRandom: (n: number) => ArrayBuffer;
-
-if (require) {
-  // node.js
-  const cr = require("crypto");
-  myGetRandom = (n: number) => {
-    const buf = cr.randomBytes(n);
-    return Uint8Array.from(buf);
-  }
-} else {
-  // Browser
-  myGetRandom = (n: number) => {
-    const ret = new Uint8Array(n);
-    window.crypto.getRandomValues(ret);
-    return ret;
-  }
-}
-
-export function getRandomBytes(n: number): ArrayBuffer {
-  return myGetRandom(n);
-}
-
-const encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
-
-class EncodingError extends Error {
-  constructor() {
-    super("Encoding error");
-    Object.setPrototypeOf(this, EncodingError.prototype);
-  }
-}
-
-function getValue(chr: string): number {
-  let a = chr;
-  switch (chr) {
-    case "O":
-    case "o":
-      a = "0;";
-      break;
-    case "i":
-    case "I":
-    case "l":
-    case "L":
-      a = "1";
-      break;
-    case "u":
-    case "U":
-      a = "V";
-  }
-
-  if (a >= "0" && a <= "9") {
-    return a.charCodeAt(0) - "0".charCodeAt(0);
-  }
-
-  if (a >= "a" && a <= "z") a = a.toUpperCase();
-  let dec = 0;
-  if (a >= "A" && a <= "Z") {
-    if ("I" < a) dec++;
-    if ("L" < a) dec++;
-    if ("O" < a) dec++;
-    if ("U" < a) dec++;
-    return a.charCodeAt(0) - "A".charCodeAt(0) + 10 - dec;
-  }
-  throw new EncodingError();
-}
-
-export function encodeCrock(data: ArrayBuffer): string {
-  const dataBytes = new Uint8Array(data);
-  let sb = "";
-  const size = data.byteLength;
-  let bitBuf = 0;
-  let numBits = 0;
-  let pos = 0;
-  while (pos < size || numBits > 0) {
-    if (pos < size && numBits < 5) {
-      const d = dataBytes[pos++];
-      bitBuf = (bitBuf << 8) | d;
-      numBits += 8;
-    }
-    if (numBits < 5) {
-      // zero-padding
-      bitBuf = bitBuf << (5 - numBits);
-      numBits = 5;
-    }
-    const v = (bitBuf >>> (numBits - 5)) & 31;
-    sb += encTable[v];
-    numBits -= 5;
-  }
-  return sb;
-}
-
-export function decodeCrock(encoded: string): Uint8Array {
-  const size = encoded.length;
-  let bitpos = 0;
-  let bitbuf = 0;
-  let readPosition = 0;
-  const outLen = Math.floor((size * 5) / 8);
-  const out = new Uint8Array(outLen);
-  let outPos = 0;
-
-  while (readPosition < size || bitpos > 0) {
-    //println("at position $readPosition with bitpos $bitpos")
-    if (readPosition < size) {
-      const v = getValue(encoded[readPosition++]);
-      bitbuf = (bitbuf << 5) | v;
-      bitpos += 5;
-    }
-    while (bitpos >= 8) {
-      const d = (bitbuf >>> (bitpos - 8)) & 0xff;
-      out[outPos++] = d;
-      bitpos -= 8;
-    }
-    if (readPosition == size && bitpos > 0) {
-      bitbuf = (bitbuf << (8 - bitpos)) & 0xff;
-      bitpos = bitbuf == 0 ? 0 : 8;
-    }
-  }
-  return out;
-}
diff --git a/src/crypto/talerCrypto-test.ts b/src/crypto/talerCrypto-test.ts
new file mode 100644
index 00000000..3f9d6f39
--- /dev/null
+++ b/src/crypto/talerCrypto-test.ts
@@ -0,0 +1,161 @@
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Imports
+ */
+import test from "ava";
+import {
+  encodeCrock,
+  decodeCrock,
+  ecdheGetPublic,
+  eddsaGetPublic,
+  keyExchangeEddsaEcdhe,
+  keyExchangeEcdheEddsa,
+  rsaBlind,
+  rsaUnblind,
+  rsaVerify,
+} from "./talerCrypto";
+import { hmacSha512, sha512, kdf } from "./kdf";
+import nacl = require("./nacl-fast");
+
+function hexToBytes(hex: string) {
+  for (var bytes = [], c = 0; c < hex.length; c += 2)
+    bytes.push(parseInt(hex.substr(c, 2), 16));
+  return bytes;
+}
+
+function bytesToHex(bytes: Uint8Array): string {
+  for (var hex = [], i = 0; i < bytes.length; i++) {
+    var current = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];
+    hex.push((current >>> 4).toString(16));
+    hex.push((current & 0xf).toString(16));
+  }
+  return hex.join("");
+}
+
+test("encoding", t => {
+  const utf8decoder = new TextDecoder("utf-8");
+  const utf8encoder = new TextEncoder();
+  const s = "Hello, World";
+  const encStr = encodeCrock(utf8encoder.encode(s));
+  const outBuf = decodeCrock(encStr);
+  const sOut = utf8decoder.decode(outBuf);
+  t.deepEqual(s, sOut);
+});
+
+test("taler-exchange-tvg hash code", t => {
+  const input = "91JPRV3F5GG4EKJN41A62V35E8";
+  const output =
+    
"CW96WR74JS8T53EC8GKSGD49QKH4ZNFTZXDAWMMV5GJ1E4BM6B8GPN5NVHDJ8ZVXNCW7Q4WBYCV61HCA3PZC2YJD850DT29RHHN7ESR";
+
+  const myOutput = encodeCrock(sha512(decodeCrock(input)));
+
+  t.deepEqual(myOutput, output);
+});
+
+test("taler-exchange-tvg ecdhe key", t => {
+  const priv1 = "X4T4N0M8PVQXQEBW2BA7049KFSM7J437NSDFC6GDNM3N5J9367A0";
+  const pub1 = "M997P494MS6A95G1P0QYWW2VNPSHSX5Q6JBY5B9YMNYWP0B50X3G";
+  const priv2 = "14A0MMQ64DCV8HE0CS3WBC9DHFJAHXRGV7NEARFJPC5R5E1697E0";
+  const skm =
+    
"NXRY2YCY7H9B6KM928ZD55WG964G59YR0CPX041DYXKBZZ85SAWNPQ8B30QRM5FMHYCXJAN0EAADJYWEF1X3PAC2AJN28626TR5A6AR";
+
+  const myPub1 = nacl.scalarMult_base(decodeCrock(priv1));
+  t.deepEqual(encodeCrock(myPub1), pub1);
+
+  const mySkm = nacl.hash(
+    nacl.scalarMult(decodeCrock(priv2), decodeCrock(pub1)),
+  );
+  t.deepEqual(encodeCrock(mySkm), skm);
+});
+
+test("taler-exchange-tvg eddsa key", t => {
+  const priv = "9TM70AKDTS57AWY9JK2J4TMBTMW6K62WHHGZWYDG0VM5ABPZKD40";
+  const pub = "8GSJZ649T2PXMKZC01Y4ANNBE7MF14QVK9SQEC4E46ZHKCVG8AS0";
+
+  const pair = nacl.sign_keyPair_fromSeed(decodeCrock(priv));
+  t.deepEqual(encodeCrock(pair.publicKey), pub);
+});
+
+test("taler-exchange-tvg kdf", t => {
+  const salt = "94KPT83PCNS7J83KC5P78Y8";
+  const ikm = "94KPT83MD1JJ0WV5CDS6AX10D5Q70XBM41NPAY90DNGQ8SBJD5GPR";
+  const ctx =
+    
"94KPT83141HPYVKMCNW78833D1TPWTSC41GPRWVF41NPWVVQDRG62WS04XMPWSKF4WG6JVH0EHM6A82J8S1G";
+  const outLen = 64;
+  const out =
+    
"GTMR4QT05Z9WF5HKVG0WK9RPXGHSMHJNW377G9GJXCA8B0FEKPF4D27RJMSJZYWSQNTBJ5EYVV7ZW18B48Z0JVJJ80RHB706Y96Q358";
+
+  const myOut = kdf(
+    outLen,
+    decodeCrock(ikm),
+    decodeCrock(salt),
+    decodeCrock(ctx),
+  );
+
+  t.deepEqual(encodeCrock(myOut), out);
+});
+
+test("taler-exchange-tvg eddsa_ecdh", t => {
+  const priv_ecdhe = "4AFZWMSGTVCHZPQ0R81NWXDCK4N58G7SDBBE5KXE080Y50370JJG";
+  const pub_ecdhe = "FXFN5GPAFTKVPWJDPVXQ87167S8T82T5ZV8CDYC0NH2AE14X0M30";
+  const priv_eddsa = "1KG54M8T3X8BSFSZXCR3SQBSR7Y9P53NX61M864S7TEVMJ2XVPF0";
+  const pub_eddsa = "7BXWKG6N224C57RTDV8XEAHR108HG78NMA995BE8QAT5GC1S7E80";
+  const key_material =
+    
"PKZ42Z56SVK2796HG1QYBRJ6ZQM2T9QGA3JA4AAZ8G7CWK9FPX175Q9JE5P0ZAX3HWWPHAQV4DPCK10R9X3SAXHRV0WF06BHEC2ZTKR";
+
+  const myEcdhePub = ecdheGetPublic(decodeCrock(priv_ecdhe));
+  t.deepEqual(encodeCrock(myEcdhePub), pub_ecdhe);
+
+  const myEddsaPub = eddsaGetPublic(decodeCrock(priv_eddsa));
+  t.deepEqual(encodeCrock(myEddsaPub), pub_eddsa);
+
+  const myKm1 = keyExchangeEddsaEcdhe(
+    decodeCrock(priv_eddsa),
+    decodeCrock(pub_ecdhe),
+  );
+  t.deepEqual(encodeCrock(myKm1), key_material);
+
+  const myKm2 = keyExchangeEcdheEddsa(
+    decodeCrock(priv_ecdhe),
+    decodeCrock(pub_eddsa),
+  );
+  t.deepEqual(encodeCrock(myKm2), key_material);
+});
+
+test("taler-exchange-tvg blind signing", t => {
+  const messageHash =
+    
"TT1R28D79EJEJ9PC35AQS35CCG85DSXSZ508MV2HS2FN4ME6AHESZX5WP485R8A75KG53FN6F1YNW95008663TKAPWB81420VG17BY8";
+  const rsaPublicKey =
+    
"040000Y62RSDDKZXTE7GDVA302ZZR0DY224RSDT6WDWR1XGT8E3YG80XV6TMT3ZCNP8XC84W0N6MSZ0EF8S3YB1JJ2AXY9JQZW3MCA0CG38ER4YE2RY4Q2666DEZSNKT29V6CKZVCDHXSAKY8W6RPEKEQ5YSBYQK23MRK3CQTNNJXQFDKEMRHEC5Y6RDHAC5RJCV8JJ8BF18VPKZ2Q7BB14YN1HJ22H8EZGW0RDGG9YPEWA9183BHEQ651PP81J514TJ9K8DH23AJ50SZFNS429HQ390VRP5E4MQ7RK7ZJXXTSZAQSRTC0QF28P23PD37C17QFQB0BBC54MB8MDH7RW104STG6VN0J22P39JP4EXPVGK5D9AX5W869MDQ6SRD42ZYK5H20227Q8CCWSQ6C3132WP0F0H04002";
+  const bks = "7QD31RPJH0W306RJWBRG646Z2FTA1F89BKSXPDAG7YM0N5Z0B610";
+  const bm =
+    
"GA8PC6YH9VF5MW6P2DKTV0W0ZTQ24DZ9EAN5QH3SQXRH7SCZHFMM21ZY05F0BS7MFW8TSEP4SEB280BYP5ACHNQWGE10PCXDDMK7ECXJDPHJ224JBCV4KYNWG6NBR3SC9HK8FXVFX55GFBJFNQHNZGEB8DB0KN9MSVYFDXN45KPMSNY03FVX0JZ0R3YG9XQ8XVGB5SYZCF0QSHWH61MT0Q10CZD2V114BT64D3GD86EJ5S9WBMYG51SDN5CSKEJ734YAJ4HCEWW0RDN8GXA9ZMA18SKVW8T3TTBCPJRF2Y77JGQ08GF35SYGA2HWFV1HGVS8RCTER6GB9SZHRG4T7919H9C1KFAP50G2KSV6X42D6KNJANNSGKQH649TJ00YJQXPHPNFBSS198RY2C243D4B4W";
+  const bs =
+    
"5VW0MS5PRBA3W8TPATSTDA2YRFQM1Z7F2DWKQ8ATMZYYY768Q3STZ3HGNVYQ6JB5NKP80G5HGE58616FPA70SX9PTW7EN8EJ23E26FASBWZBP8E2RWQQ5E0F72B2PWRP5ZCA2J3AB3F6P86XK4PZYT64RF94MDGHY0GSDSSBH5YSFB3VM0KVXA52H2Y2G9S85AVCSD3BTMHQRF5BJJ8JE00T4GK70PSTVCGMRKRNA7DGW7GD2F35W55AXF7R2YJC8PAGNSJYWKC3PC75A5N8H69K299AK5PM3CDDHNS4BMRNGF7K49CR4ZBFRXDAWMB3X6T05Q4NKSG0F1KP5JA0XBMF2YJK7KEPRD1EWCHJE44T9YXBTK4W9CV77X7Z9P407ZC6YB3M2ARANZXHJKSM3XC33M";
+  const sig =
+    
"PFT6WQJGCM9DE6264DJS6RMG4XDMCDBJKZGSXAF3BEXWZ979Q13NETKK05S1YV91CX3Y034FSS86SSHZTTE8097RRESQP52EKFGTWJXKHZJEQJ49YHMBNQDHW4CFBJECNJSV2PMHWVGXV7HB84R6P0S3ES559HWQX01Q9MYDEGRNHKW87QR2BNSG951D5NQGAKEJ2SSJBE18S6WYAC24FAP8TT8ANECH5371J0DJY0YR0VWAFWVJDV8XQSFXWMJ80N3A80SPSHPYJY3WZZXW63WQ46WHYY56ZSNE5G1RZ5CR0XYV2ECKPM8R0FS58EV16WTRAM1ABBFVNAT3CAEFAZCWP3XHPVBQY5NZVTD5QS2Q8SKJQ2XB30E11CWDN9KTV5CBK4DN72EVG73F3W3BATAKHG";
+  
+  const myBm = rsaBlind(decodeCrock(messageHash), decodeCrock(bks), 
decodeCrock(rsaPublicKey));
+  t.deepEqual(encodeCrock(myBm), bm);
+
+  const mySig = rsaUnblind(decodeCrock(bs), decodeCrock(rsaPublicKey), 
decodeCrock(bks));
+  t.deepEqual(encodeCrock(mySig), sig);
+
+  const v = rsaVerify(decodeCrock(messageHash), decodeCrock(sig), 
decodeCrock(rsaPublicKey));
+  t.true(v);
+});
diff --git a/src/crypto/talerCrypto.ts b/src/crypto/talerCrypto.ts
new file mode 100644
index 00000000..0a36f0fe
--- /dev/null
+++ b/src/crypto/talerCrypto.ts
@@ -0,0 +1,277 @@
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Native implementation of GNU Taler crypto.
+ */
+
+import nacl = require("./nacl-fast");
+import bigint from "big-integer";
+import { kdf } from "./kdf";
+
+export function getRandomBytes(n: number): Uint8Array {
+  return nacl.randomBytes(n);
+}
+
+const encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
+
+class EncodingError extends Error {
+  constructor() {
+    super("Encoding error");
+    Object.setPrototypeOf(this, EncodingError.prototype);
+  }
+}
+
+function getValue(chr: string): number {
+  let a = chr;
+  switch (chr) {
+    case "O":
+    case "o":
+      a = "0;";
+      break;
+    case "i":
+    case "I":
+    case "l":
+    case "L":
+      a = "1";
+      break;
+    case "u":
+    case "U":
+      a = "V";
+  }
+
+  if (a >= "0" && a <= "9") {
+    return a.charCodeAt(0) - "0".charCodeAt(0);
+  }
+
+  if (a >= "a" && a <= "z") a = a.toUpperCase();
+  let dec = 0;
+  if (a >= "A" && a <= "Z") {
+    if ("I" < a) dec++;
+    if ("L" < a) dec++;
+    if ("O" < a) dec++;
+    if ("U" < a) dec++;
+    return a.charCodeAt(0) - "A".charCodeAt(0) + 10 - dec;
+  }
+  throw new EncodingError();
+}
+
+export function encodeCrock(data: ArrayBuffer): string {
+  const dataBytes = new Uint8Array(data);
+  let sb = "";
+  const size = data.byteLength;
+  let bitBuf = 0;
+  let numBits = 0;
+  let pos = 0;
+  while (pos < size || numBits > 0) {
+    if (pos < size && numBits < 5) {
+      const d = dataBytes[pos++];
+      bitBuf = (bitBuf << 8) | d;
+      numBits += 8;
+    }
+    if (numBits < 5) {
+      // zero-padding
+      bitBuf = bitBuf << (5 - numBits);
+      numBits = 5;
+    }
+    const v = (bitBuf >>> (numBits - 5)) & 31;
+    sb += encTable[v];
+    numBits -= 5;
+  }
+  return sb;
+}
+
+export function decodeCrock(encoded: string): Uint8Array {
+  const size = encoded.length;
+  let bitpos = 0;
+  let bitbuf = 0;
+  let readPosition = 0;
+  const outLen = Math.floor((size * 5) / 8);
+  const out = new Uint8Array(outLen);
+  let outPos = 0;
+
+  while (readPosition < size || bitpos > 0) {
+    if (readPosition < size) {
+      const v = getValue(encoded[readPosition++]);
+      bitbuf = (bitbuf << 5) | v;
+      bitpos += 5;
+    }
+    while (bitpos >= 8) {
+      const d = (bitbuf >>> (bitpos - 8)) & 0xff;
+      out[outPos++] = d;
+      bitpos -= 8;
+    }
+    if (readPosition == size && bitpos > 0) {
+      bitbuf = (bitbuf << (8 - bitpos)) & 0xff;
+      bitpos = bitbuf == 0 ? 0 : 8;
+    }
+  }
+  return out;
+}
+
+export function eddsaGetPublic(eddsaPriv: Uint8Array): Uint8Array {
+  const pair = nacl.sign_keyPair_fromSeed(eddsaPriv); 
+  return pair.publicKey;
+}
+
+export function ecdheGetPublic(ecdhePriv: Uint8Array): Uint8Array {
+  return nacl.scalarMult_base(ecdhePriv);
+}
+
+export function keyExchangeEddsaEcdhe(eddsaPriv: Uint8Array, ecdhePub: 
Uint8Array): Uint8Array {
+  const ph = nacl.hash(eddsaPriv);
+  const a = new Uint8Array(32);
+  for (let i = 0; i < 32; i++) {
+    a[i] = ph[i];
+  }
+  const x = nacl.scalarMult(a, ecdhePub);
+  return nacl.hash(x);
+}
+
+export function keyExchangeEcdheEddsa(ecdhePriv: Uint8Array, eddsaPub: 
Uint8Array): Uint8Array {
+  const curve25519Pub = nacl.sign_ed25519_pk_to_curve25519(eddsaPub);
+  const x = nacl.scalarMult(ecdhePriv, curve25519Pub);
+  return nacl.hash(x);
+}
+
+interface RsaPub {
+  N: bigint.BigInteger;
+  e: bigint.BigInteger;
+}
+
+interface RsaBlindingKey {
+  r: bigint.BigInteger;
+}
+
+/**
+ * KDF modulo a big integer.
+ */
+function kdfMod(
+  n: bigint.BigInteger,
+  ikm: Uint8Array,
+  salt: Uint8Array,
+  info: Uint8Array,
+): bigint.BigInteger {
+  const nbits = n.bitLength().toJSNumber();
+  const buflen = Math.floor((nbits - 1) / 8 + 1);
+  const mask = (1 << (8 - (buflen * 8 - nbits))) - 1;
+  let counter = 0;
+  while (true) {
+    const ctx = new Uint8Array(info.byteLength + 2);
+    ctx.set(info, 0);
+    ctx[ctx.length - 2] = (counter >>> 8) & 0xFF;
+    ctx[ctx.length - 1] = counter & 0xFF;
+    const buf = kdf(buflen, ikm, salt, ctx);
+    const arr = Array.from(buf);
+    arr[0] = arr[0] & mask;
+    const r = bigint.fromArray(arr, 256, false);
+    if (r.lt(n)) {
+      return r;
+    }
+    counter++;
+  }
+}
+
+function stringToBuf(s: string) {
+  const te = new TextEncoder();
+  return te.encode(s);
+}
+
+function loadBigInt(arr: Uint8Array) {
+  return bigint.fromArray(Array.from(arr), 256, false);
+}
+
+function rsaBlindingKeyDerive(rsaPub: RsaPub, bks: Uint8Array): 
bigint.BigInteger {
+  const salt = stringToBuf("Blinding KDF extrator HMAC key");
+  const info = stringToBuf("Blinding KDF");
+  return kdfMod(rsaPub.N, bks, salt, info);
+}
+
+/*
+ * Test for malicious RSA key.
+ *
+ * Assuming n is an RSA modulous and r is generated using a call to
+ * GNUNET_CRYPTO_kdf_mod_mpi, if gcd(r,n) != 1 then n must be a
+ * malicious RSA key designed to deanomize the user.
+ * 
+ * @param r KDF result
+ * @param n RSA modulus of the public key
+ */
+function rsaGcdValidate(r: bigint.BigInteger, n: bigint.BigInteger) {
+  const t = bigint.gcd(r, n);
+  if (!t.equals(bigint.one)) {
+    throw Error("malicious RSA public key");
+  }
+}
+
+function rsaFullDomainHash(hm: Uint8Array, rsaPub: RsaPub): bigint.BigInteger {
+  const info = stringToBuf("RSA-FDA FTpsW!");
+  const salt = rsaPubEncode(rsaPub);
+  const r = kdfMod(rsaPub.N, hm, salt, info);
+  rsaGcdValidate(r, rsaPub.N);
+  return r;
+}
+
+function rsaPubDecode(rsaPub: Uint8Array): RsaPub {
+  const modulusLength = (rsaPub[0] << 8) | rsaPub[1];
+  const exponentLength = (rsaPub[2] << 8) | rsaPub[3];
+  const modulus = rsaPub.slice(4, 4 + modulusLength)
+  const exponent = rsaPub.slice(4 + modulusLength, 4 + modulusLength + 
exponentLength);
+  const res = {
+    N: loadBigInt(modulus),
+    e: loadBigInt(exponent),
+  }
+  return res;
+}
+
+function rsaPubEncode(rsaPub: RsaPub): Uint8Array {
+  const mb = rsaPub.N.toArray(256).value;
+  const eb = rsaPub.e.toArray(256).value;
+  const out = new Uint8Array(4 + mb.length + eb.length);
+  out[0] = (mb.length >>> 8) & 0xFF;
+  out[1] = mb.length & 0xFF;
+  out[2] = (eb.length >>> 8) & 0xFF;
+  out[3] = eb.length & 0xFF;
+  out.set(mb, 4);
+  out.set(eb, 4 + mb.length);
+  return out;
+}
+
+export function rsaBlind(hm: Uint8Array, bks: Uint8Array, rsaPubEnc: 
Uint8Array): Uint8Array {
+  const rsaPub = rsaPubDecode(rsaPubEnc);
+  const data = rsaFullDomainHash(hm, rsaPub);
+  const r = rsaBlindingKeyDerive(rsaPub, bks);
+  const r_e = r.modPow(rsaPub.e, rsaPub.N);
+  const bm = r_e.multiply(data).mod(rsaPub.N);
+  return new Uint8Array(bm.toArray(256).value);
+}
+
+export function rsaUnblind(sig: Uint8Array, rsaPubEnc: Uint8Array, bks: 
Uint8Array): Uint8Array {
+  const rsaPub = rsaPubDecode(rsaPubEnc);
+  const blinded_s = loadBigInt(sig);
+  const r = rsaBlindingKeyDerive(rsaPub, bks);
+  const r_inv = r.modInv(rsaPub.N);
+  const s = blinded_s.multiply(r_inv).mod(rsaPub.N);
+  return new Uint8Array(s.toArray(256).value);
+}
+
+export function rsaVerify(hm: Uint8Array, rsaSig: Uint8Array, rsaPubEnc: 
Uint8Array): boolean {
+  const rsaPub = rsaPubDecode(rsaPubEnc);
+  const d = rsaFullDomainHash(hm, rsaPub);
+  const sig = loadBigInt(rsaSig);
+  const sig_e = sig.modPow(rsaPub.e, rsaPub.N);
+  return sig_e.equals(d);
+}
\ No newline at end of file
diff --git a/src/headless/clk.ts b/src/headless/clk.ts
index 51ee119c..4a568dc1 100644
--- a/src/headless/clk.ts
+++ b/src/headless/clk.ts
@@ -329,6 +329,7 @@ export class CommandGroup<GN extends keyof any, TG> {
     let foundSubcommand: CommandGroup<any, any> | undefined = undefined;
     const myArgs: any = (parsedArgs[this.argKey] = {});
     const foundOptions: { [name: string]: boolean } = {};
+    const currentName = this.name ?? progname;
     for (i = 0; i < unparsedArgs.length; i++) {
       const argVal = unparsedArgs[i];
       if (argsTerminated == false) {
@@ -341,8 +342,7 @@ export class CommandGroup<GN extends keyof any, TG> {
           const r = splitOpt(opt);
           const d = this.longOptions[r.key];
           if (!d) {
-            const n = this.name ?? progname;
-            console.error(`error: unknown option '--${r.key}' for ${n}`);
+            console.error(`error: unknown option '--${r.key}' for 
${currentName}`);
             process.exit(-1);
             throw Error("not reached");
           }
@@ -412,8 +412,7 @@ export class CommandGroup<GN extends keyof any, TG> {
       } else {
         const d = this.arguments[posArgIndex];
         if (!d) {
-          const n = this.name ?? progname;
-          console.error(`error: too many arguments for ${n}`);
+          console.error(`error: too many arguments for ${currentName}`);
           process.exit(-1);
           throw Error("not reached");
         }
@@ -424,12 +423,11 @@ export class CommandGroup<GN extends keyof any, TG> {
 
     for (let i = posArgIndex; i < this.arguments.length; i++) {
       const d = this.arguments[i];
-      const n = this.name ?? progname;
       if (d.required) {
         if (d.args.default !== undefined) {
           myArgs[d.name] = d.args.default;
         } else {
-          console.error(`error: missing positional argument '${d.name}' for 
${n}`);
+          console.error(`error: missing positional argument '${d.name}' for 
${currentName}`);
           process.exit(-1);
           throw Error("not reached");
         }
@@ -465,7 +463,19 @@ export class CommandGroup<GN extends keyof any, TG> {
         parsedArgs,
       );
     } else if (this.myAction) {
-      this.myAction(parsedArgs);
+      let r;
+      try {
+        r = this.myAction(parsedArgs);
+      } catch (e) {
+        console.error(`An error occured while running ${currentName}`);
+        console.error(e);
+        process.exit(1);
+      }
+      Promise.resolve(r).catch((e) => {
+        console.error(`An error occured while running ${currentName}`);
+        console.error(e);
+        process.exit(1);
+      });
     } else {
       this.printHelp(progname, parents);
       process.exit(-1);
diff --git a/src/headless/integrationtest.ts b/src/headless/integrationtest.ts
index 6f2139c9..91adfaa6 100644
--- a/src/headless/integrationtest.ts
+++ b/src/headless/integrationtest.ts
@@ -82,8 +82,9 @@ export async function runIntegrationTest(args: {
     throw Error("payment did not succeed");
   }
 
-  const refreshRes = await myWallet.refreshDirtyCoins();
-  console.log(`waited to refresh ${refreshRes.numRefreshed} coins`);
+  await myWallet.runPending();
+  //const refreshRes = await myWallet.refreshDirtyCoins();
+  //console.log(`waited to refresh ${refreshRes.numRefreshed} coins`);
 
   myWallet.stop();
 }
diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts
index 0a678080..bec098ac 100644
--- a/src/headless/taler-wallet-cli.ts
+++ b/src/headless/taler-wallet-cli.ts
@@ -15,6 +15,7 @@
  */
 
 import os = require("os");
+import fs = require("fs");
 import { getDefaultNodeWallet, withdrawTestBalance } from "./helpers";
 import { MerchantBackendConnection } from "./merchant";
 import { runIntegrationTest } from "./integrationtest";
@@ -24,6 +25,7 @@ import * as clk from "./clk";
 import { BridgeIDBFactory, MemoryBackend } from "idb-bridge";
 import { Logger } from "../logging";
 import * as Amounts from "../amounts";
+import { decodeCrock } from "../crypto/talerCrypto";
 
 const logger = new Logger("taler-wallet-cli.ts");
 
@@ -254,6 +256,16 @@ const advancedCli = walletCli.subcommand("advancedArgs", 
"advanced", {
     "Subcommands for advanced operations (only use if you know what you're 
doing!).",
 });
 
+advancedCli
+  .subcommand("decode", "decode", {
+    help: "Decode base32-crockford",
+  })
+  .action(args => {
+    const enc = fs.readFileSync(0, 'utf8');
+    fs.writeFileSync(1, decodeCrock(enc.trim()))
+  });
+
+
 advancedCli
   .subcommand("refresh", "force-refresh", {
     help: "Force a refresh on a coin.",
diff --git a/tsconfig.json b/tsconfig.json
index bcab91de..3a1a7652 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -33,12 +33,15 @@
     "src/crypto/cryptoWorker.ts",
     "src/crypto/emscInterface-test.ts",
     "src/crypto/emscInterface.ts",
-    "src/crypto/nativeCrypto-test.ts",
-    "src/crypto/nativeCrypto.ts",
+    "src/crypto/kdf.ts",
+    "src/crypto/nacl-fast.ts",
     "src/crypto/nodeEmscriptenLoader.ts",
     "src/crypto/nodeProcessWorker.ts",
     "src/crypto/nodeWorkerEntry.ts",
+    "src/crypto/sha256.ts",
     "src/crypto/synchronousWorker.ts",
+    "src/crypto/talerCrypto-test.ts",
+    "src/crypto/talerCrypto.ts",
     "src/db.ts",
     "src/dbTypes.ts",
     "src/headless/bank.ts",
diff --git a/yarn.lock b/yarn.lock
index aeec2b42..56697f55 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1120,6 +1120,11 @@ bfj@^6.1.1:
     hoopy "^0.1.4"
     tryer "^1.0.1"
 
+big-integer@^1.6.48:
+  version "1.6.48"
+  resolved 
"https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e";
+  integrity 
sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==
+
 big.js@^5.2.2:
   version "5.2.2"
   resolved 
"https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328";

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]