From bace20efbf56a30faa8e98b1a9dfda184a9d8a3b Mon Sep 17 00:00:00 2001 From: Jose Pedro Sousa Date: Thu, 28 Apr 2022 16:12:50 +0100 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20scripts=20for=20MPC=20+=20removing?= =?UTF-8?q?=20MPC=20from=20the=20worker=20process=20=F0=9F=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MPC/.env | 3 + MPC/.gitignore | 3 + MPC/ceremony.js | 79 ++ MPC/contribution.js | 61 ++ MPC/package-lock.json | 920 ++++++++++++++++++ MPC/package.json | 20 + config/default.js | 3 +- doc/mpc.md | 32 - zokrates-worker/.gitignore | 2 +- zokrates-worker/package.json | 2 +- zokrates-worker/src/index.mjs | 16 +- zokrates-worker/src/mpc.sh | 19 - zokrates-worker/src/services/generateKeys.mjs | 40 +- zokrates-worker/src/zokrates-lib/beacon.mjs | 70 -- zokrates-worker/src/zokrates-lib/ceremony.mjs | 74 -- .../src/zokrates-lib/contribution.mjs | 59 -- .../src/zokrates-lib/exportKeys.mjs | 4 +- zokrates-worker/src/zokrates-lib/index.mjs | 16 +- 18 files changed, 1110 insertions(+), 313 deletions(-) create mode 100644 MPC/.env create mode 100644 MPC/.gitignore create mode 100644 MPC/ceremony.js create mode 100644 MPC/contribution.js create mode 100644 MPC/package-lock.json create mode 100644 MPC/package.json delete mode 100644 zokrates-worker/src/mpc.sh delete mode 100644 zokrates-worker/src/zokrates-lib/beacon.mjs delete mode 100644 zokrates-worker/src/zokrates-lib/ceremony.mjs delete mode 100644 zokrates-worker/src/zokrates-lib/contribution.mjs diff --git a/MPC/.env b/MPC/.env new file mode 100644 index 000000000..29b0d07cf --- /dev/null +++ b/MPC/.env @@ -0,0 +1,3 @@ +MPC_PARAMS_URL=https://nightfallv3-proving-files.s3.eu-west-1.amazonaws.com/phase2/mpc_params +RADIX_FILES_URL=https://nightfallv3-proving-files.s3.eu-west-1.amazonaws.com/radix +CIRCUIT_FILES_URL=https://nightfallv3-production.s3.eu-west-1.amazonaws.com/circuits diff --git a/MPC/.gitignore b/MPC/.gitignore new file mode 100644 index 000000000..8ba7d1376 --- /dev/null +++ b/MPC/.gitignore @@ -0,0 +1,3 @@ +radix +compiled_circuits +params diff --git a/MPC/ceremony.js b/MPC/ceremony.js new file mode 100644 index 000000000..59ed3ad74 --- /dev/null +++ b/MPC/ceremony.js @@ -0,0 +1,79 @@ +/* eslint-disable no-await-in-loop */ +import childProcess from 'child_process'; +import fs from 'fs'; + +import 'dotenv/config'; +import download from 'download'; + +const { spawn } = childProcess; + +async function ceremony(circuitName) { + return new Promise((resolve, reject) => { + const zokrates = spawn('zokrates', [ + 'mpc', + 'init', + '-i', + `./compiled_circuits/${circuitName}-program`, + '-o', + `./params/${circuitName}`, + '-r', + `./radix/${circuitName}`, + ]); + + let output = ''; + + zokrates.stdout.on('data', data => { + output += data.toString('utf8'); + }); + + zokrates.stderr.on('data', err => { + console.log(err); + reject(new Error(`Setup failed: ${err}`)); + }); + + zokrates.on('close', () => { + console.log(output); + // ZoKrates sometimes outputs error through stdout instead of stderr, + // so we need to catch those errors manually. + if (output.includes('panicked')) { + reject(new Error(output.slice(output.indexOf('panicked')))); + } + resolve(output); + }); + }); +} +const main = async () => { + try { + if (!fs.existsSync('./radix')) fs.mkdirSync('./radix'); + if (!fs.existsSync('./params')) fs.mkdirSync('./params'); + + for (const circuit of [ + 'deposit', + 'double_transfer', + 'single_transfer', + 'withdraw', + 'deposit_stub', + 'withdraw_stub', + 'double_transfer_stub', + 'single_transfer_stub', + ]) { + if (!fs.existsSync(`./compiled_circuits/${circuit}`)) { + await download( + `${process.env.CIRCUIT_FILES_URL}/${circuit}/artifacts/${circuit}-program`, + `./compiled_circuits`, + ); + } + + if (!fs.existsSync(`./radix/${circuit}`)) { + await download(`${process.env.RADIX_FILES_URL}/${circuit}`, `./radix`); + } + + await ceremony(circuit); + } + } catch (err) { + console.log(err); + process.exit(1); + } +}; + +main(); diff --git a/MPC/contribution.js b/MPC/contribution.js new file mode 100644 index 000000000..633bc13c0 --- /dev/null +++ b/MPC/contribution.js @@ -0,0 +1,61 @@ +/* eslint-disable no-await-in-loop */ +import childProcess from 'child_process'; +import fs from 'fs'; + +import download from 'download'; +import axios from 'axios'; + +const { spawn } = childProcess; + +async function contribution(circuitName, random) { + return new Promise((resolve, reject) => { + const zokrates = spawn('zokrates', [ + 'mpc', + 'contribute', + '-i', + `./params/${circuitName}`, + '-o', + `./params/out/${circuitName}`, + '-e', + random, + ]); + + zokrates.stderr.on('data', err => { + reject(new Error(`Setup failed: ${err}`)); + }); + + zokrates.on('close', () => { + resolve(); + }); + }); +} + +const main = async () => { + try { + const RANDOM = (await axios.get('https://api.drand.sh/public/latest')).data.randomness; + + if (!fs.existsSync('./params')) fs.mkdirSync('./params'); + if (!fs.existsSync('./params/out')) fs.mkdirSync('./params/out'); + + for (const circuit of [ + 'deposit', + 'double_transfer', + 'single_transfer', + 'withdraw', + 'deposit_stub', + 'withdraw_stub', + 'double_transfer_stub', + 'single_transfer_stub', + ]) { + if (!fs.existsSync(`./params/${circuit}`)) { + await download(`${process.env.MPC_PARAMS_URL}/${circuit}`, `./params`); + } + await contribution(circuit, RANDOM); + } + } catch (err) { + // console.log(err); + process.exit(1); + } +}; + +main(); diff --git a/MPC/package-lock.json b/MPC/package-lock.json new file mode 100644 index 000000000..c04dbbf2c --- /dev/null +++ b/MPC/package-lock.json @@ -0,0 +1,920 @@ +{ + "name": "mpc", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==" + }, + "archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", + "requires": { + "file-type": "^4.2.0" + }, + "dependencies": { + "file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=" + } + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "biskviit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/biskviit/-/biskviit-1.0.1.tgz", + "integrity": "sha1-A3oM1LcbnjMf2QoRIt4X3EnkIKc=", + "requires": { + "psl": "^1.1.7" + } + }, + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + } + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "requires": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "requires": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" + } + } + }, + "decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "requires": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "dependencies": { + "file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" + } + } + }, + "decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "requires": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" + } + } + }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "dotenv": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", + "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" + }, + "download": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz", + "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==", + "requires": { + "archive-type": "^4.0.0", + "content-disposition": "^0.5.2", + "decompress": "^4.2.1", + "ext-name": "^5.0.0", + "file-type": "^11.1.0", + "filenamify": "^3.0.0", + "get-stream": "^4.1.0", + "got": "^8.3.1", + "make-dir": "^2.1.0", + "p-event": "^2.1.0", + "pify": "^4.0.1" + } + }, + "drand-client": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/drand-client/-/drand-client-0.2.0.tgz", + "integrity": "sha512-0L+X8rm1XCN908cIOYXAauXyBK32zf7y0cGLcoZVaMQmuZwbuqcVrrvQCOgh3qjptYuvnEFncMGpKf3p/7YjFw==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "requires": { + "mime-db": "^1.28.0" + } + }, + "ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "requires": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-CoJ58Gvjf58Ou1Z1YKMKSA2lmi4=", + "requires": { + "biskviit": "1.0.1", + "encoding": "0.1.12" + } + }, + "file-type": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", + "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==" + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" + }, + "filenamify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz", + "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==", + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } + }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "requires": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + } + }, + "is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" + }, + "is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "dependencies": { + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "requires": { + "is-plain-obj": "^1.0.0" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" + }, + "p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "requires": { + "p-timeout": "^2.0.1" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=" + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "requires": { + "p-finally": "^1.0.0" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "requires": { + "commander": "^2.8.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", + "requires": { + "sort-keys": "^1.0.0" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "requires": { + "is-natural-number": "^4.0.1" + } + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/MPC/package.json b/MPC/package.json new file mode 100644 index 000000000..aee3cc0a9 --- /dev/null +++ b/MPC/package.json @@ -0,0 +1,20 @@ +{ + "name": "mpc", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "ceremony": "node ceremony.js", + "contribute": "node contribution.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^0.27.2", + "dotenv": "^16.0.0", + "download": "^8.0.0", + "drand-client": "^0.2.0", + "fetch": "^1.1.0" + } +} diff --git a/config/default.js b/config/default.js index 12c71f2e8..b1deaefc8 100644 --- a/config/default.js +++ b/config/default.js @@ -112,7 +112,8 @@ module.exports = { }, MAX_QUEUE: 5, MPC: { - RADIX_FILES_URL: 'https://nightfallv3-proving-files.s3.eu-west-1.amazonaws.com/radix', + MPC_PARAMS_URL: + 'https://nightfallv3-proving-files.s3.eu-west-1.amazonaws.com/phase2/mpc_params', }, ENVIRONMENTS: { mainnet: { diff --git a/doc/mpc.md b/doc/mpc.md index 27fda3213..076479971 100644 --- a/doc/mpc.md +++ b/doc/mpc.md @@ -9,35 +9,3 @@ The MPC envolves two phases: it ensures that if at least one participant of the ceremony is honest, then the result is forcibly trustablke. - Phase 2, which is circuit-specific and needs to be generated upon deployment. - -## Radix files - -The radix files are the MPC params that are calculated from the latest response file from PPOT. -These radix files have specific depths depending on the number of constraints for each circuit, and -can take a while to compute. They're also quite big in size so we shouldn't commit them to git. -Instead, we store them in a publicly accessible S3 bucket, and the `zokrates-worker` fetches them -synchonously if they're not present in the docker volume. - -Does this mean you have to trust these radix files? No! Because you can start the process on your -own, and create your own radix files. You don't need to trust anybody. - -## How can I not trust people - -You are able to bring your own keys to the table. For that, you need to get the latest response from -the [PPOT ceremony](https://github.com/weijiekoh/perpetualpowersoftau) and download the -`new_challenge` file, rename it to `challenge` and run the little `mpc.sh` script you'll find -[here](https://github.com/EYBlockchain/nightfall_3/blob/master/zokrates-worker/src/mpc.sh). This -script will spit out a bunch of radix files like `phase1radix2m2`, `phase1radix2m3`... -`phase1radix2m(n)` where `n` should be the depth of the circuit we're using. - -This means number of constraints, which you can get by running `zokrates compile` to compile the -circuits, and then `zokrates inspect` on the compiled circuits, which should spit out the number of -constraints. You should pick a value of `n` for which `2^n` is bigger than the number of -constraints. For example, at the time of writing, the compiled `deposit` circuit has `84766` -constraints so we need to pick up the `phase1radix2m17` as `2^16 < 84766 < 2^17`. - -You should rename these radix files to the name of the circuits, and host them somewhere. IPFS, S3 -buckets, your own webserver, whatever you want. - -Lastly, don't forget to modify the env variable `RADIX_FILES_URL` to point to the URL where you'll -get the radix files. diff --git a/zokrates-worker/.gitignore b/zokrates-worker/.gitignore index ee0988d90..a41cc9126 100644 --- a/zokrates-worker/.gitignore +++ b/zokrates-worker/.gitignore @@ -81,4 +81,4 @@ circuits/* !circuits/test/ # for now, ignore mpc parameters -radix +mpc_params diff --git a/zokrates-worker/package.json b/zokrates-worker/package.json index d42394370..35fb8f21e 100644 --- a/zokrates-worker/package.json +++ b/zokrates-worker/package.json @@ -7,7 +7,7 @@ "private": true, "scripts": { "start": "node ./src/index.mjs", - "dev": "nodemon ./src/index.mjs --ignore '**/*.params' --ignore '**/abi.json' --ignore '**/radix/**' --ignore '**/*_out'", + "dev": "nodemon ./src/index.mjs --ignore '**/*.params' --ignore '**/abi.json' --ignore '**/mpc_params/**' --ignore '**/*_out'", "setup": "./bin/setup.sh", "test": "mocha" }, diff --git a/zokrates-worker/src/index.mjs b/zokrates-worker/src/index.mjs index e1556f48b..d182027ab 100644 --- a/zokrates-worker/src/index.mjs +++ b/zokrates-worker/src/index.mjs @@ -7,14 +7,14 @@ import queues from './queues/index.mjs'; import logger from './utils/logger.mjs'; const { - MPC: { RADIX_FILES_URL }, + MPC: { MPC_PARAMS_URL }, } = config; const main = async () => { try { - if (!fs.existsSync('./src/radix')) fs.mkdirSync('./src/radix'); + if (!fs.existsSync('./mpc_params')) fs.mkdirSync('./mpc_params'); - const radixPromises = []; + const mpcPromises = []; for (const circuit of [ 'deposit', @@ -26,16 +26,16 @@ const main = async () => { 'double_transfer_stub', 'single_transfer_stub', ]) { - if (!fs.existsSync(`./src/radix/${circuit}`)) { - radixPromises.push( + if (!fs.existsSync(`./mpc_params/${circuit}`)) { + mpcPromises.push( new Promise((resolve, reject) => { axios - .get(`${RADIX_FILES_URL}/${circuit}`, { + .get(`${MPC_PARAMS_URL}/${circuit}`, { responseType: 'stream', }) .then(response => { resolve(); - response.data.pipe(fs.createWriteStream(`./src/radix/${circuit}`)); + response.data.pipe(fs.createWriteStream(`./mpc_params/${circuit}`)); }) .catch(error => { reject(); @@ -47,7 +47,7 @@ const main = async () => { } } - await Promise.all(radixPromises); + await Promise.all(mpcPromises); // 1 means enable it // 0 mean keep it disabled diff --git a/zokrates-worker/src/mpc.sh b/zokrates-worker/src/mpc.sh deleted file mode 100644 index e5f07594b..000000000 --- a/zokrates-worker/src/mpc.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -rm response* -rm transcript -rm phase1radix* -rm tmp_* - -set -e - -SIZE=28 -BATCH=256 - -yes | cargo run --release --bin compute_constrained challenge response1 $SIZE $BATCH -cargo run --release --bin verify_transform_constrained challenge response1 challenge2 $SIZE $BATCH - -cargo run --release --bin beacon_constrained challenge2 response2 $SIZE $BATCH 0000000000000000000a558a61ddc8ee4e488d647a747fe4dcc362fe2026c620 10 -cargo run --release --bin verify_transform_constrained challenge2 response2 challenge3 $SIZE $BATCH - -cargo run --release --bin prepare_phase2 response2 $SIZE $BATCH diff --git a/zokrates-worker/src/services/generateKeys.mjs b/zokrates-worker/src/services/generateKeys.mjs index 3e9cc5807..5bda452da 100644 --- a/zokrates-worker/src/services/generateKeys.mjs +++ b/zokrates-worker/src/services/generateKeys.mjs @@ -1,15 +1,6 @@ import fs from 'fs'; import path from 'path'; -import crypto from 'crypto'; -import { - compile, - extractVk, - ceremony, - beacon, - exportKeys, - contribution, - setup, -} from '../zokrates-lib/index.mjs'; +import { compile, extractVk, exportKeys, setup } from '../zokrates-lib/index.mjs'; import logger from '../utils/logger.mjs'; export default async function generateKeys({ filepath, curve = 'bn128' }) { @@ -29,31 +20,18 @@ export default async function generateKeys({ filepath, curve = 'bn128' }) { curve, ); - logger.info('Compile...'); - await compile( - `${circuitsPath}/${filepath}`, - `${outputPath}/${circuitDir}`, - `${circuitName}_out`, - curve, - ); - if (process.env.MPC) { - logger.info('MPC Ceremony...'); - await ceremony(`${outputPath}/${circuitDir}`, `${circuitName}`, { verbose: true }); - - // magic number is the max int for randomInt - let randomness = crypto.randomInt(281474976710655); - logger.info('Contributing...'); - await contribution(randomness); - - randomness = crypto.randomInt(281474976710655); - const hash = crypto.createHash('sha256').update(randomness.toString()).digest('hex'); - logger.info('MPC Beacon...'); - await beacon(hash, { verbose: true }); - logger.info('Export keys...'); await exportKeys(`${outputPath}/${circuitDir}`, `${circuitName}`); } else { + logger.info('Compile...'); + await compile( + `${circuitsPath}/${filepath}`, + `${outputPath}/${circuitDir}`, + `${circuitName}_out`, + curve, + ); + logger.info('Setup...'); await setup( `${outputPath}/${circuitDir}/${circuitName}_out`, diff --git a/zokrates-worker/src/zokrates-lib/beacon.mjs b/zokrates-worker/src/zokrates-lib/beacon.mjs deleted file mode 100644 index a1503e059..000000000 --- a/zokrates-worker/src/zokrates-lib/beacon.mjs +++ /dev/null @@ -1,70 +0,0 @@ -import childProcess from 'child_process'; - -const { spawn } = childProcess; - -/** - * Compiles code found at `codePath` and outputs verifying and proving keys. - * - * TODO: Needs to check that files and whatnot all exist. - * - * @example - * // Will generate keys at ft-mint-vk.key and ft-mint-pk.key - * setup('./code/ft-mint/ft-mint', './', 'gm17', 'ft-mint-vk', 'ft-mint-pk'); - * - * @param {String} codePath - Path of code file to compile - * @param {String} outputPath - Directory to output, defaults to current directory - * @param {String} provingScheme - Available options are g16, pghr13, gm17 - * @param {String} backEnd - Available options are 'libsnark', 'bellman', 'ark' - * @param {String} vkName - name of verification key file, defaults to verification.key - * @param {String} pkName - name of proving key file, defaults to proving.key - */ -export default async function beacon(random, options = {}) { - const { maxReturn = 10000000, verbose = false } = options; - - return new Promise((resolve, reject) => { - const zokrates = spawn( - '/app/zokrates', - [ - 'mpc', - 'beacon', - '-i', - 'contribution.params', - '-o', - 'final.params', - '-h', - random, - '-n', - '10', - ], - { - env: { - ZOKRATES_STDLIB: process.env.ZOKRATES_STDLIB, - }, - }, - ); - - let output = ''; - - zokrates.stdout.on('data', data => { - if (verbose) { - output += data.toString('utf8'); - // If the entire output gets too large, just send ...[truncated]. - if (output.length > maxReturn) output = '...[truncated]'; - } - }); - - zokrates.stderr.on('data', err => { - reject(new Error(`Setup failed: ${err}`)); - }); - - zokrates.on('close', () => { - // ZoKrates sometimes outputs error through stdout instead of stderr, - // so we need to catch those errors manually. - if (output.includes('panicked')) { - reject(new Error(output.slice(output.indexOf('panicked')))); - } - if (verbose) resolve(output); - else resolve(); - }); - }); -} diff --git a/zokrates-worker/src/zokrates-lib/ceremony.mjs b/zokrates-worker/src/zokrates-lib/ceremony.mjs deleted file mode 100644 index ad6413393..000000000 --- a/zokrates-worker/src/zokrates-lib/ceremony.mjs +++ /dev/null @@ -1,74 +0,0 @@ -import childProcess from 'child_process'; -import fs from 'fs'; - -const { spawn } = childProcess; - -/** - * Compiles code found at `codePath` and outputs verifying and proving keys. - * - * TODO: Needs to check that files and whatnot all exist. - * - * @example - * // Will generate keys at ft-mint-vk.key and ft-mint-pk.key - * setup('./code/ft-mint/ft-mint', './', 'gm17', 'ft-mint-vk', 'ft-mint-pk'); - * - * @param {String} codePath - Path of code file to compile - * @param {String} outputPath - Directory to output, defaults to current directory - * @param {String} provingScheme - Available options are g16, pghr13, gm17 - * @param {String} backEnd - Available options are 'libsnark', 'bellman', 'ark' - * @param {String} vkName - name of verification key file, defaults to verification.key - * @param {String} pkName - name of proving key file, defaults to proving.key - */ -export default async function ceremony(path, circuitName, options = {}) { - const { maxReturn = 10000000, verbose = false } = options; - - const fullPath = `${path}/${circuitName}_out`; - if (!fs.existsSync(fullPath)) { - throw new Error('Setup input file(s) not found'); - } - - if (fullPath.endsWith('.zok')) { - throw new Error( - 'Setup cannot take the .zok version, use the compiled version with no extension.', - ); - } - - // TODO use mpcParams out of the Powers of Tau, this is just for testing - return new Promise((resolve, reject) => { - const zokrates = spawn( - '/app/zokrates', - ['mpc', 'init', '-i', fullPath, '-o', 'mpc.params', '-r', `./src/radix/${circuitName}`], - { - // stdio: ['ignore', 'pipe', 'pipe'], - env: { - ZOKRATES_STDLIB: process.env.ZOKRATES_STDLIB, - }, - }, - ); - - let output = ''; - - zokrates.stdout.on('data', data => { - if (verbose) { - output += data.toString('utf8'); - // If the entire output gets too large, just send ...[truncated]. - if (output.length > maxReturn) output = '...[truncated]'; - } - }); - - zokrates.stderr.on('data', err => { - console.log(err); - reject(new Error(`Setup failed: ${err}`)); - }); - - zokrates.on('close', () => { - // ZoKrates sometimes outputs error through stdout instead of stderr, - // so we need to catch those errors manually. - if (output.includes('panicked')) { - reject(new Error(output.slice(output.indexOf('panicked')))); - } - if (verbose) resolve(output); - else resolve(); - }); - }); -} diff --git a/zokrates-worker/src/zokrates-lib/contribution.mjs b/zokrates-worker/src/zokrates-lib/contribution.mjs deleted file mode 100644 index 4141219b5..000000000 --- a/zokrates-worker/src/zokrates-lib/contribution.mjs +++ /dev/null @@ -1,59 +0,0 @@ -import childProcess from 'child_process'; - -const { spawn } = childProcess; - -/** - * Compiles code found at `codePath` and outputs verifying and proving keys. - * - * TODO: Needs to check that files and whatnot all exist. - * - * @example - * // Will generate keys at ft-mint-vk.key and ft-mint-pk.key - * setup('./code/ft-mint/ft-mint', './', 'gm17', 'ft-mint-vk', 'ft-mint-pk'); - * - * @param {String} codePath - Path of code file to compile - * @param {String} outputPath - Directory to output, defaults to current directory - * @param {String} provingScheme - Available options are g16, pghr13, gm17 - * @param {String} backEnd - Available options are 'libsnark', 'bellman', 'ark' - * @param {String} vkName - name of verification key file, defaults to verification.key - * @param {String} pkName - name of proving key file, defaults to proving.key - */ -export default async function ceremony(random, options = {}) { - const { maxReturn = 10000000, verbose = false } = options; - - return new Promise((resolve, reject) => { - const zokrates = spawn( - '/app/zokrates', - ['mpc', 'contribute', '-i', 'mpc.params', '-o', 'contribution.params', '-e', random], - { - env: { - ZOKRATES_STDLIB: process.env.ZOKRATES_STDLIB, - }, - }, - ); - - let output = ''; - - zokrates.stdout.on('data', data => { - if (verbose) { - output += data.toString('utf8'); - // If the entire output gets too large, just send ...[truncated]. - if (output.length > maxReturn) output = '...[truncated]'; - } - }); - - zokrates.stderr.on('data', err => { - reject(new Error(`Setup failed: ${err}`)); - }); - - zokrates.on('close', () => { - // ZoKrates sometimes outputs error through stdout instead of stderr, - // so we need to catch those errors manually. - if (output.includes('panicked')) { - reject(new Error(output.slice(output.indexOf('panicked')))); - } - if (verbose) resolve(output); - else resolve(); - }); - }); -} diff --git a/zokrates-worker/src/zokrates-lib/exportKeys.mjs b/zokrates-worker/src/zokrates-lib/exportKeys.mjs index 4ec4a1cf5..f69675aca 100644 --- a/zokrates-worker/src/zokrates-lib/exportKeys.mjs +++ b/zokrates-worker/src/zokrates-lib/exportKeys.mjs @@ -26,7 +26,7 @@ export default async function exportKeys(path, circuitName, options = {}) { 'mpc', 'export', '-i', - 'final.params', + `./mpc_params/${circuitName}`, '-v', `${path}/${circuitName}_vk.key`, '-p', @@ -38,7 +38,7 @@ export default async function exportKeys(path, circuitName, options = {}) { 'mpc', 'export', '-i', - 'final.params', + `./mpc_params/${circuitName}`, '-v', `${path}/${circuitName}_vk.key`, '-p', diff --git a/zokrates-worker/src/zokrates-lib/index.mjs b/zokrates-worker/src/zokrates-lib/index.mjs index 4afb0caff..1ceef7ef9 100644 --- a/zokrates-worker/src/zokrates-lib/index.mjs +++ b/zokrates-worker/src/zokrates-lib/index.mjs @@ -3,21 +3,7 @@ import computeWitness from './compute-witness.mjs'; import extractVk from './extract-vk.mjs'; import generateProof from './generate-proof.mjs'; import verify from './verify.mjs'; -import ceremony from './ceremony.mjs'; -import contribution from './contribution.mjs'; -import beacon from './beacon.mjs'; import exportKeys from './exportKeys.mjs'; import setup from './setup.mjs'; -export { - compile, - computeWitness, - extractVk, - generateProof, - verify, - ceremony, - contribution, - beacon, - exportKeys, - setup, -}; +export { compile, computeWitness, extractVk, generateProof, verify, exportKeys, setup }; From 3d381156579217214a3a7e0c081ec33f1b06ed50 Mon Sep 17 00:00:00 2001 From: Jose Pedro Sousa Date: Tue, 3 May 2022 15:31:53 +0100 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20moving=20MPC=20to=20another=20repo?= =?UTF-8?q?=20=F0=9F=96=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MPC/.env | 3 - MPC/.gitignore | 3 - MPC/ceremony.js | 79 -- MPC/contribution.js | 61 -- MPC/package-lock.json | 920 ------------------ MPC/package.json | 20 - config/default.js | 6 +- nightfall-client/src/classes/commitment.mjs | 18 +- nightfall-client/src/classes/nullifier.mjs | 4 +- nightfall-client/src/services/transfer.mjs | 9 +- .../circuits/double_transfer.zok | 22 +- .../circuits/double_transfer_stub.zok | 12 +- .../circuits/single_transfer.zok | 22 +- .../circuits/single_transfer_stub.zok | 12 +- nightfall-deployer/circuits/withdraw.zok | 9 +- nightfall-deployer/contracts/Challenges.sol | 15 + .../contracts/ChallengesUtil.sol | 16 + nightfall-deployer/contracts/State.sol | 2 + nightfall-deployer/contracts/Verifier.sol | 6 +- .../src/services/transaction-checker.mjs | 86 +- .../nightfall-browser/classes/commitment.js | 4 +- .../nightfall-browser/classes/nullifier.js | 2 +- zokrates-worker/src/index.mjs | 11 +- zokrates-worker/src/services/generateKeys.mjs | 16 +- 24 files changed, 204 insertions(+), 1154 deletions(-) delete mode 100644 MPC/.env delete mode 100644 MPC/.gitignore delete mode 100644 MPC/ceremony.js delete mode 100644 MPC/contribution.js delete mode 100644 MPC/package-lock.json delete mode 100644 MPC/package.json diff --git a/MPC/.env b/MPC/.env deleted file mode 100644 index 29b0d07cf..000000000 --- a/MPC/.env +++ /dev/null @@ -1,3 +0,0 @@ -MPC_PARAMS_URL=https://nightfallv3-proving-files.s3.eu-west-1.amazonaws.com/phase2/mpc_params -RADIX_FILES_URL=https://nightfallv3-proving-files.s3.eu-west-1.amazonaws.com/radix -CIRCUIT_FILES_URL=https://nightfallv3-production.s3.eu-west-1.amazonaws.com/circuits diff --git a/MPC/.gitignore b/MPC/.gitignore deleted file mode 100644 index 8ba7d1376..000000000 --- a/MPC/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -radix -compiled_circuits -params diff --git a/MPC/ceremony.js b/MPC/ceremony.js deleted file mode 100644 index 59ed3ad74..000000000 --- a/MPC/ceremony.js +++ /dev/null @@ -1,79 +0,0 @@ -/* eslint-disable no-await-in-loop */ -import childProcess from 'child_process'; -import fs from 'fs'; - -import 'dotenv/config'; -import download from 'download'; - -const { spawn } = childProcess; - -async function ceremony(circuitName) { - return new Promise((resolve, reject) => { - const zokrates = spawn('zokrates', [ - 'mpc', - 'init', - '-i', - `./compiled_circuits/${circuitName}-program`, - '-o', - `./params/${circuitName}`, - '-r', - `./radix/${circuitName}`, - ]); - - let output = ''; - - zokrates.stdout.on('data', data => { - output += data.toString('utf8'); - }); - - zokrates.stderr.on('data', err => { - console.log(err); - reject(new Error(`Setup failed: ${err}`)); - }); - - zokrates.on('close', () => { - console.log(output); - // ZoKrates sometimes outputs error through stdout instead of stderr, - // so we need to catch those errors manually. - if (output.includes('panicked')) { - reject(new Error(output.slice(output.indexOf('panicked')))); - } - resolve(output); - }); - }); -} -const main = async () => { - try { - if (!fs.existsSync('./radix')) fs.mkdirSync('./radix'); - if (!fs.existsSync('./params')) fs.mkdirSync('./params'); - - for (const circuit of [ - 'deposit', - 'double_transfer', - 'single_transfer', - 'withdraw', - 'deposit_stub', - 'withdraw_stub', - 'double_transfer_stub', - 'single_transfer_stub', - ]) { - if (!fs.existsSync(`./compiled_circuits/${circuit}`)) { - await download( - `${process.env.CIRCUIT_FILES_URL}/${circuit}/artifacts/${circuit}-program`, - `./compiled_circuits`, - ); - } - - if (!fs.existsSync(`./radix/${circuit}`)) { - await download(`${process.env.RADIX_FILES_URL}/${circuit}`, `./radix`); - } - - await ceremony(circuit); - } - } catch (err) { - console.log(err); - process.exit(1); - } -}; - -main(); diff --git a/MPC/contribution.js b/MPC/contribution.js deleted file mode 100644 index 633bc13c0..000000000 --- a/MPC/contribution.js +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable no-await-in-loop */ -import childProcess from 'child_process'; -import fs from 'fs'; - -import download from 'download'; -import axios from 'axios'; - -const { spawn } = childProcess; - -async function contribution(circuitName, random) { - return new Promise((resolve, reject) => { - const zokrates = spawn('zokrates', [ - 'mpc', - 'contribute', - '-i', - `./params/${circuitName}`, - '-o', - `./params/out/${circuitName}`, - '-e', - random, - ]); - - zokrates.stderr.on('data', err => { - reject(new Error(`Setup failed: ${err}`)); - }); - - zokrates.on('close', () => { - resolve(); - }); - }); -} - -const main = async () => { - try { - const RANDOM = (await axios.get('https://api.drand.sh/public/latest')).data.randomness; - - if (!fs.existsSync('./params')) fs.mkdirSync('./params'); - if (!fs.existsSync('./params/out')) fs.mkdirSync('./params/out'); - - for (const circuit of [ - 'deposit', - 'double_transfer', - 'single_transfer', - 'withdraw', - 'deposit_stub', - 'withdraw_stub', - 'double_transfer_stub', - 'single_transfer_stub', - ]) { - if (!fs.existsSync(`./params/${circuit}`)) { - await download(`${process.env.MPC_PARAMS_URL}/${circuit}`, `./params`); - } - await contribution(circuit, RANDOM); - } - } catch (err) { - // console.log(err); - process.exit(1); - } -}; - -main(); diff --git a/MPC/package-lock.json b/MPC/package-lock.json deleted file mode 100644 index c04dbbf2c..000000000 --- a/MPC/package-lock.json +++ /dev/null @@ -1,920 +0,0 @@ -{ - "name": "mpc", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==" - }, - "archive-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", - "requires": { - "file-type": "^4.2.0" - }, - "dependencies": { - "file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "biskviit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/biskviit/-/biskviit-1.0.1.tgz", - "integrity": "sha1-A3oM1LcbnjMf2QoRIt4X3EnkIKc=", - "requires": { - "psl": "^1.1.7" - } - }, - "bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" - }, - "cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", - "requires": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" - } - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "dependencies": { - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - } - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, - "dependencies": { - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" - } - } - }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, - "dependencies": { - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" - } - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "dotenv": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", - "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" - }, - "download": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz", - "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==", - "requires": { - "archive-type": "^4.0.0", - "content-disposition": "^0.5.2", - "decompress": "^4.2.1", - "ext-name": "^5.0.0", - "file-type": "^11.1.0", - "filenamify": "^3.0.0", - "get-stream": "^4.1.0", - "got": "^8.3.1", - "make-dir": "^2.1.0", - "p-event": "^2.1.0", - "pify": "^4.0.1" - } - }, - "drand-client": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/drand-client/-/drand-client-0.2.0.tgz", - "integrity": "sha512-0L+X8rm1XCN908cIOYXAauXyBK32zf7y0cGLcoZVaMQmuZwbuqcVrrvQCOgh3qjptYuvnEFncMGpKf3p/7YjFw==" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "requires": { - "mime-db": "^1.28.0" - } - }, - "ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "requires": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "requires": { - "pend": "~1.2.0" - } - }, - "fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-CoJ58Gvjf58Ou1Z1YKMKSA2lmi4=", - "requires": { - "biskviit": "1.0.1", - "encoding": "0.1.12" - } - }, - "file-type": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", - "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==" - }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" - }, - "filenamify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz", - "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==", - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", - "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", - "requires": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - } - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "into-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", - "requires": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - } - }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" - }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, - "keyv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", - "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - }, - "dependencies": { - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "requires": { - "is-plain-obj": "^1.0.0" - } - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" - }, - "p-event": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", - "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", - "requires": { - "p-timeout": "^2.0.1" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=" - }, - "p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", - "requires": { - "p-finally": "^1.0.0" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", - "requires": { - "commander": "^2.8.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", - "requires": { - "sort-keys": "^1.0.0" - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "requires": { - "is-natural-number": "^4.0.1" - } - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } -} diff --git a/MPC/package.json b/MPC/package.json deleted file mode 100644 index aee3cc0a9..000000000 --- a/MPC/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "mpc", - "version": "1.0.0", - "description": "", - "main": "index.js", - "type": "module", - "scripts": { - "ceremony": "node ceremony.js", - "contribute": "node contribution.js" - }, - "author": "", - "license": "ISC", - "dependencies": { - "axios": "^0.27.2", - "dotenv": "^16.0.0", - "download": "^8.0.0", - "drand-client": "^0.2.0", - "fetch": "^1.1.0" - } -} diff --git a/config/default.js b/config/default.js index b1deaefc8..ae9826ff6 100644 --- a/config/default.js +++ b/config/default.js @@ -86,7 +86,11 @@ module.exports = { USE_STUBS: process.env.USE_STUBS === 'true', VK_IDS: { deposit: 0, single_transfer: 1, double_transfer: 2, withdraw: 3 }, // used as an enum to mirror the Shield contracts enum for vk types. The keys of this object must correspond to a 'folderpath' (the .zok file without the '.zok' bit) TIMBER_HEIGHT: 32, - + MAX_PUBLIC_VALUES: { + ERCADDRESS: 2n ** 161n - 1n, + COMMITMENT: 2n ** 249n - 1n, + NULLIFIER: 2n ** 249n - 1n, + }, // the various parameters needed to describe the Babyjubjub curve that we use for El-Gamal // BABYJUBJUB // Montgomery EC form is y^2 = x^3 + Ax^2 + Bx diff --git a/nightfall-client/src/classes/commitment.mjs b/nightfall-client/src/classes/commitment.mjs index ccea45fed..993ef4008 100644 --- a/nightfall-client/src/classes/commitment.mjs +++ b/nightfall-client/src/classes/commitment.mjs @@ -31,13 +31,17 @@ class Commitment { compressedPkd, salt, }); - this.hash = sha256([ - this.preimage.ercAddress, - this.preimage.tokenId, - this.preimage.value, - this.preimage.compressedPkd, - this.preimage.salt, - ]); + // we truncate the hash down to 31 bytes but store it in a 32 byte variable + // this is consistent to what we do in the ZKP circuits + this.hash = generalise( + sha256([ + this.preimage.ercAddress, + this.preimage.tokenId, + this.preimage.value, + this.preimage.compressedPkd, + this.preimage.salt, + ]).hex(32, 31), + ); } // sometimes (e.g. going over http) the general-number class is inconvenient diff --git a/nightfall-client/src/classes/nullifier.mjs b/nightfall-client/src/classes/nullifier.mjs index fa0db1ab7..a1c6a26b9 100644 --- a/nightfall-client/src/classes/nullifier.mjs +++ b/nightfall-client/src/classes/nullifier.mjs @@ -16,7 +16,9 @@ class Nullifier { nsk, commitment: commitment.hash, }); - this.hash = sha256([this.preimage.nsk, this.preimage.commitment]); + // we truncate the hash down to 31 bytes but store it in a 32 byte variable + // this is consistent to what we do in the ZKP circuits + this.hash = generalise(sha256([this.preimage.nsk, this.preimage.commitment]).hex(32, 31)); } } diff --git a/nightfall-client/src/services/transfer.mjs b/nightfall-client/src/services/transfer.mjs index 8961acb8f..37f0cab1a 100644 --- a/nightfall-client/src/services/transfer.mjs +++ b/nightfall-client/src/services/transfer.mjs @@ -108,7 +108,6 @@ async function transfer(transferParams) { // compress the secrets to save gas const compressedSecrets = Secrets.compressSecrets(secrets); - const commitmentTreeInfo = await Promise.all(oldCommitments.map(c => getSiblingInfo(c))); const localSiblingPaths = commitmentTreeInfo.map(l => { const path = l.siblingPath.path.map(p => p.value); @@ -166,7 +165,13 @@ async function transfer(transferParams) { secrets.cipherText.flat().map(text => text.field(BN128_GROUP_ORDER)), ...secrets.squareRootsElligator2.map(sqroot => sqroot.field(BN128_GROUP_ORDER)), ], - compressedSecrets.map(text => generalise(text.hex(32, 31)).field(BN128_GROUP_ORDER)), + compressedSecrets.map(text => { + const bin = text.binary.padStart(256, '0'); + const parity = bin[0]; + const ordinate = bin.slice(1); + const fields = [parity, new GN(ordinate, 'binary').field(BN128_GROUP_ORDER)]; + return fields; + }), ].flat(Infinity); logger.debug(`witness input is ${witness.join(' ')}`); diff --git a/nightfall-deployer/circuits/double_transfer.zok b/nightfall-deployer/circuits/double_transfer.zok index a3c42b29e..80b669295 100644 --- a/nightfall-deployer/circuits/double_transfer.zok +++ b/nightfall-deployer/circuits/double_transfer.zok @@ -42,6 +42,11 @@ struct Secrets { field sqrtMessage4 } +struct CompressedPoint { + bool parity + field ordinate +} + def main(\ private field[2] fErcAddress,\ private OldCommitmentPreimage[2] oldCommitment,\ @@ -53,7 +58,7 @@ def main(\ private field[2][32] path,\ private field[2] order,\ private Secrets secrets,\ - field[8] compressedCipherText\ + CompressedPoint[8] compressedCipherText\ )->(): BabyJubJubParams context = curveParams() @@ -155,7 +160,6 @@ def main(\ assert(u32_to_bool_32(sha[0])[8..32] == u32_to_bool_32(newCommitmentHash[1][0])[8..32]) // check the old commitments are valid - // old commitments are private inputs, so they are u32[8] and not truncated for u32 i in 0..2 do sha = sha256of1280([\ ...ercAddress[i],\ @@ -164,7 +168,11 @@ def main(\ ...pkdU32,\ ...oldCommitment[i].salt\ ]) - assert(sha == oldCommitment[i].hash) + // assert(sha == oldCommitment[i].hash) + // last 224 bits: + assert(sha[1..8] == oldCommitment[i].hash[1..8]) + // first 24 bits: + assert(u32_to_bool_32(sha[0])[8..32] == u32_to_bool_32(oldCommitment[i].hash[0])[8..32]) endfor // And the encryption of the transaction (extend the value up to 256 bits) @@ -178,10 +186,10 @@ def main(\ // there is likely a compiler bug with zokrates 0.6.4 which makes using spreads (e.g. [8..256]) inside a function (e.g. assert()) very slow u32 j = 2*i bool[256] compressed256 = edwardsCompress([secrets.cipherText[j], secrets.cipherText[j+1]]) - bool[256] compressedCheck256 = field_to_bool_256(compressedCipherText[i]) - bool[248] compressed = compressed256[8..256] - bool[248] compressedCheck = compressedCheck256[8..256] - assert(compressed == compressedCheck) + bool parity = compressedCipherText[i].parity + bool[256] ordinate = field_to_bool_256(compressedCipherText[i].ordinate) + bool[256] compressedCheck256 = [ parity, ...ordinate[1..256] ] + assert(compressed256 == compressedCheck256) endfor // check that the old commitments are in the merkle tree diff --git a/nightfall-deployer/circuits/double_transfer_stub.zok b/nightfall-deployer/circuits/double_transfer_stub.zok index fb9b00128..94d4af937 100644 --- a/nightfall-deployer/circuits/double_transfer_stub.zok +++ b/nightfall-deployer/circuits/double_transfer_stub.zok @@ -25,6 +25,11 @@ struct Secrets { field sqrtMessage4 } +struct CompressedPoint { + bool parity + field ordinate +} + def main(\ private field[2] fErcAddress,\ private OldCommitmentPreimage[2] oldCommitment,\ @@ -36,11 +41,12 @@ def main(\ private field[2][32] path,\ private field[2] order,\ private Secrets secrets,\ - field[8] compressedCipherText\ + CompressedPoint[8] compressedCipherText\ )->(): field u = 0 u32 v = 0x00000000 + bool b = true for u32 j in 0..2 do u = u + fErcAddress[j] + fNewCommitmentHash[j] + fNullifier[j] - root[j] for u32 i in 0..8 do @@ -56,7 +62,8 @@ def main(\ u32 w = 0x00000000 for u32 i in 0..8 do - u = u + compressedCipherText[i] + u = u + compressedCipherText[i].ordinate + b = b && compressedCipherText[i].parity w = w + secrets.ephemeralKey1[i] +\ secrets.ephemeralKey2[i] +\ secrets.ephemeralKey3[i] +\ @@ -83,5 +90,6 @@ def main(\ assert(v == v) assert(u == u) assert(w == w) + assert(b == b) return diff --git a/nightfall-deployer/circuits/single_transfer.zok b/nightfall-deployer/circuits/single_transfer.zok index 39bc244a8..8df3561e9 100644 --- a/nightfall-deployer/circuits/single_transfer.zok +++ b/nightfall-deployer/circuits/single_transfer.zok @@ -42,6 +42,11 @@ struct Secrets { field sqrtMessage4 } +struct CompressedPoint { + bool parity + field ordinate +} + def main(\ private field fErcAddress,\ private OldCommitmentPreimage oldCommitment,\ @@ -53,7 +58,7 @@ def main(\ private field[32] path,\ private field order,\ private Secrets secrets,\ - field[8] compressedCipherText\ + CompressedPoint[8] compressedCipherText\ )->(): BabyJubJubParams context = curveParams() @@ -110,7 +115,6 @@ def main(\ assert(u32_to_bool_32(sha[0])[8..32] == u32_to_bool_32(newCommitmentHash[0])[8..32]) // check the old commitment is valid - // old commitments are private inputs, so they are u32[8] and not truncated sha = sha256of1280([\ ...ercAddress,\ ...oldCommitment.id,\ @@ -118,7 +122,11 @@ def main(\ ...pkdU32,\ ...oldCommitment.salt\ ]) - assert(sha == oldCommitment.hash) + // assert(sha == oldCommitment.hash) + // last 224 bits: + assert(sha[1..8] == oldCommitment.hash[1..8]) + // first 24 bits: + assert(u32_to_bool_32(sha[0])[8..32] == u32_to_bool_32(oldCommitment.hash[0])[8..32]) // And the encryption of the transaction (extend the value up to 256 bits) assert(secrets.cipherText == enc4(ercAddress, oldCommitment.id, oldCommitment.value, newCommitment.salt, newCommitment.pkdRecipient, secrets.ephemeralKey1, secrets.ephemeralKey2, secrets.ephemeralKey3, secrets.ephemeralKey4, secrets.sqrtMessage1, secrets.sqrtMessage2, secrets.sqrtMessage3, secrets.sqrtMessage4)) @@ -130,10 +138,10 @@ def main(\ // there is likely a compiler bug with zokrates 0.6.4 which makes using spreads (e.g. [8..256]) inside a function (e.g. assert()) very slow u32 j = 2*i bool[256] compressed256 = edwardsCompress([secrets.cipherText[j], secrets.cipherText[j+1]]) - bool[256] compressedCheck256 = field_to_bool_256(compressedCipherText[i]) - bool[248] compressed = compressed256[8..256] - bool[248] compressedCheck = compressedCheck256[8..256] - assert(compressed == compressedCheck) + bool parity = compressedCipherText[i].parity + bool[256] ordinate = field_to_bool_256(compressedCipherText[i].ordinate) + bool[256] compressedCheck256 = [ parity, ...ordinate[1..256] ] + assert(compressed256 == compressedCheck256) endfor // check that the old commitment is in the merkle tree (path[0] should be the root) diff --git a/nightfall-deployer/circuits/single_transfer_stub.zok b/nightfall-deployer/circuits/single_transfer_stub.zok index 5f620dda9..b9404f4ee 100644 --- a/nightfall-deployer/circuits/single_transfer_stub.zok +++ b/nightfall-deployer/circuits/single_transfer_stub.zok @@ -24,6 +24,11 @@ struct Secrets { field sqrtMessage4 } +struct CompressedPoint { + bool parity + field ordinate +} + def main(\ private field fErcAddress,\ private OldCommitmentPreimage oldCommitment,\ @@ -35,11 +40,12 @@ def main(\ private field[32] path,\ private field order,\ private Secrets secrets,\ - field[8] compressedCipherText\ + CompressedPoint[8] compressedCipherText\ )->(): field u = fErcAddress + fNewCommitmentHash + fNullifier - root u32 v = 0x00000000 + bool b = true for u32 i in 0..8 do v = v + oldCommitment.id[i] +\ oldCommitment.value[i] +\ @@ -52,7 +58,8 @@ def main(\ u32 w = 0x00000000 for u32 i in 0..8 do - u = u + compressedCipherText[i] + u = u + compressedCipherText[i].ordinate + b = b && compressedCipherText[i].parity w = w + secrets.ephemeralKey1[i] +\ secrets.ephemeralKey2[i] +\ secrets.ephemeralKey3[i] +\ @@ -71,5 +78,6 @@ def main(\ assert(v == v) assert(u == u) assert(w == w) + assert(b == b) return diff --git a/nightfall-deployer/circuits/withdraw.zok b/nightfall-deployer/circuits/withdraw.zok index f809c16a0..785bad35f 100644 --- a/nightfall-deployer/circuits/withdraw.zok +++ b/nightfall-deployer/circuits/withdraw.zok @@ -65,14 +65,17 @@ def main(\ assert(u32_to_bool_32(sha[0])[8..32] == u32_to_bool_32(nullifier[0])[8..32]) // check the old commitment is valid - // old commitments are private inputs, so they are u32[8] and not truncated - assert(oldCommitment.hash == sha256of1280([\ + sha = sha256of1280([\ ...ercAddress,\ ...id,\ ...value,\ ...pkdU32,\ ...oldCommitment.salt\ - ])) + ]) + // last 224 bits: + assert(sha[1..8] == oldCommitment.hash[1..8]) + // first 24 bits: + assert(u32_to_bool_32(sha[0])[8..32] == u32_to_bool_32(oldCommitment.hash[0])[8..32]) // check that the old commitment is in the merkle tree field mimcHash = u32_8_to_field(oldCommitment.hash) diff --git a/nightfall-deployer/contracts/Challenges.sol b/nightfall-deployer/contracts/Challenges.sol index 3642f161f..113c43f40 100644 --- a/nightfall-deployer/contracts/Challenges.sol +++ b/nightfall-deployer/contracts/Challenges.sol @@ -151,6 +151,11 @@ contract Challenges is Stateful, Key_Registry, Config { ) external onlyBootChallenger { checkCommit(msg.data); state.isBlockReal(blockL2, transactions, blockNumberL2); + // first check the transaction and block do not overflow + ChallengesUtil.libCheckOverflows( + blockL2, + transactions[transactionIndex] + ); // now we need to check that the proof is correct ChallengesUtil.libCheckCompressedProof( transactions[transactionIndex].proof, @@ -189,6 +194,11 @@ contract Challenges is Stateful, Key_Registry, Config { transactions[transactionIndex].historicRootBlockNumberL2[0] == blockNumberL2ContainingHistoricRoot ); + // first check the transaction and block do not overflow + ChallengesUtil.libCheckOverflows( + blockL2, + transactions[transactionIndex] + ); // now we need to check that the proof is correct ChallengesUtil.libCheckCompressedProof( transactions[transactionIndex].proof, @@ -236,6 +246,11 @@ contract Challenges is Stateful, Key_Registry, Config { blockNumberL2ContainingHistoricRoot[1], 'Incorrect historic root block' ); + // first check the transaction and block do not overflow + ChallengesUtil.libCheckOverflows( + blockL2, + transactions[transactionIndex] + ); // now we need to check that the proof is correct ChallengesUtil.libChallengeProofVerification( transactions[transactionIndex], diff --git a/nightfall-deployer/contracts/ChallengesUtil.sol b/nightfall-deployer/contracts/ChallengesUtil.sol index ac13fc05f..88bf83861 100644 --- a/nightfall-deployer/contracts/ChallengesUtil.sol +++ b/nightfall-deployer/contracts/ChallengesUtil.sol @@ -10,6 +10,9 @@ import './Structures.sol'; library ChallengesUtil { bytes32 public constant ZERO = 0x0000000000000000000000000000000000000000000000000000000000000000; + uint256 public constant MAX31 = 2 ** 249 - 1; + uint256 public constant MAX20 = 2 ** 161 - 1; + uint256 public constant BN128_GROUP_ORDER = 21888242871839275222246405745257275088548364400416034343698204186575808495617; function libChallengeLeafCountCorrect( Structures.Block memory priorBlockL2, @@ -203,6 +206,19 @@ library ChallengesUtil { ); } + function libCheckOverflows( + Structures.Block calldata blockL2, + Structures.Transaction calldata transaction + ) public pure { + require(uint256(transaction.ercAddress) <= MAX20, 'ERC address out of range'); + require(uint256(transaction.recipientAddress) <= MAX20, 'Recipient ERC address out of range'); + require(uint256(transaction.commitments[0]) <= MAX31, 'Commitment 0 out of range'); + require(uint256(transaction.commitments[1]) <= MAX31, 'Commitment 1 out of range'); + require(uint256(transaction.nullifiers[0]) <= MAX31, 'Nullifier 0 out of range'); + require(uint256(transaction.nullifiers[1]) <= MAX31, 'Nullifier 1 out of range'); + require(uint256(blockL2.root) < BN128_GROUP_ORDER, 'root out of range'); + } + function libChallengeNullifier( Structures.Transaction memory tx1, uint256 nullifierIndex1, diff --git a/nightfall-deployer/contracts/State.sol b/nightfall-deployer/contracts/State.sol index c1f0cf4c2..5ba505a5e 100644 --- a/nightfall-deployer/contracts/State.sol +++ b/nightfall-deployer/contracts/State.sol @@ -80,6 +80,8 @@ contract State is Structures, Initializable, ReentrancyGuardUpgradeable, Config ); // this will fail if a tx is re-mined out of order due to a chain reorg. require(BLOCK_STAKE <= msg.value, 'The stake payment is incorrect'); require(b.proposer == msg.sender, 'The proposer address is not the sender'); + // set the maximum tx/block to prevent unchallengably large blocks + require (t.length < 33, 'The block has too many transactions'); // We need to set the blockHash on chain here, because there is no way to // convince a challenge function of the (in)correctness by an offchain // computation; the on-chain code doesn't save the pre-image of the hash so diff --git a/nightfall-deployer/contracts/Verifier.sol b/nightfall-deployer/contracts/Verifier.sol index 6ef6c9924..2eda1c64d 100644 --- a/nightfall-deployer/contracts/Verifier.sol +++ b/nightfall-deployer/contracts/Verifier.sol @@ -34,6 +34,8 @@ library Verifier { using Pairing for *; + uint256 constant BN128_GROUP_ORDER = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + struct Proof_G16 { Pairing.G1Point A; Pairing.G2Point B; @@ -98,7 +100,9 @@ library Verifier { // The following success variables replace require statements with corresponding functions called. Removing require statements to ensure a wrong proof verification challenge's require statement correctly works bool success_sm_qpih; bool success_vkdi_sm_qpih; - for (uint i = 0; i < _publicInputs.length; i++) { + for (uint i = 0; i < _publicInputs.length; i++) { + // check for overflow attacks + if (_publicInputs[i] >= BN128_GROUP_ORDER) return 2; (sm_qpih, success_sm_qpih) = Pairing.scalar_mul(vk.gamma_abc[i+1], _publicInputs[i]); (vk_dot_inputs, success_vkdi_sm_qpih) = Pairing.addition( vk_dot_inputs, diff --git a/nightfall-optimist/src/services/transaction-checker.mjs b/nightfall-optimist/src/services/transaction-checker.mjs index cb31ef154..0f4f3d17e 100644 --- a/nightfall-optimist/src/services/transaction-checker.mjs +++ b/nightfall-optimist/src/services/transaction-checker.mjs @@ -13,8 +13,22 @@ import { waitForContract } from '../event-handlers/subscribe.mjs'; import { getBlockByBlockNumberL2 } from './database.mjs'; import verify from './verify.mjs'; -const { generalise } = gen; -const { PROVING_SCHEME, BACKEND, CURVE, ZERO, CHALLENGES_CONTRACT_NAME } = config; +const { generalise, GN } = gen; +const { + PROVING_SCHEME, + BACKEND, + CURVE, + ZERO, + CHALLENGES_CONTRACT_NAME, + BN128_GROUP_ORDER, + MAX_PUBLIC_VALUES, +} = config; + +function isOverflow(value, check) { + const bigValue = value.bigInt; + if (bigValue < 0 || bigValue >= check) return true; + return false; +} // first, let's check the hash. That's nice and easy: // NB as we actually now comput the hash on receipt of the transaction this @@ -162,22 +176,37 @@ async function verifyProof(transaction) { transaction.ercAddress, transaction.tokenId, transaction.value, - transaction.commitments[0], // not truncating here as we already ensured hash < group order + transaction.commitments[0], ].flat(Infinity), ); + if ( + isOverflow(transaction.ercAddress, MAX_PUBLIC_VALUES.ERCADDRESS) || + isOverflow(transaction.commitments[0], MAX_PUBLIC_VALUES.COMMITMENTS) + ) + throw new TransactionError('Truncated value overflow in public input', 4); break; case 1: // single transfer transaction inputs = generalise( [ - // transaction.ercAddress, - transaction.commitments[0], // not truncating here as we already ensured hash < group order - generalise(transaction.nullifiers[0]).hex(32, 31), + transaction.commitments[0], + transaction.nullifiers[0], historicRootFirst.root, - ...transaction.compressedSecrets.map(compressedSecret => - generalise(compressedSecret).hex(32, 31), - ), + // expand the compressed secrets slightly to extract the parity as a separate field + ...transaction.compressedSecrets.map(text => { + const bin = new GN(text).binary.padStart(256, '0'); + const parity = bin[0]; + const ordinate = bin.slice(1); + return [parity, new GN(ordinate, 'binary').field(BN128_GROUP_ORDER, false)]; + }), ].flat(Infinity), ); + // check for truncation overflow attacks + if ( + isOverflow(transaction.commitments[0], MAX_PUBLIC_VALUES.COMMITMENTS) || + isOverflow(transaction.nullifiers[0], MAX_PUBLIC_VALUES.NULLIFIER) || + isOverflow(historicRootFirst.root, BN128_GROUP_ORDER) + ) + throw new TransactionError('Overflow in public input', 4); break; case 2: // double transfer transaction inputs = generalise( @@ -185,14 +214,32 @@ async function verifyProof(transaction) { // transaction.ercAddress, // this is correct; ercAddress appears twice // transaction.ercAddress, // in a double-transfer public input hash transaction.commitments, // not truncating here as we already ensured hash < group order - transaction.nullifiers.map(nullifier => generalise(nullifier).hex(32, 31)), + transaction.nullifiers, historicRootFirst.root, historicRootSecond.root, - ...transaction.compressedSecrets.map(compressedSecret => - generalise(compressedSecret).hex(32, 31), - ), + // expand the compressed secrets slightly to extract the parity as a separate field + ...transaction.compressedSecrets.map(text => { + const bin = new GN(text).binary.padStart(256, '0'); + const parity = bin[0]; + const ordinate = bin.slice(1); + return [parity, new GN(ordinate, 'binary').field(BN128_GROUP_ORDER, false)]; + }), ].flat(Infinity), ); + // check for truncation overflow attacks + for (let i = 0; i < transaction.nullifiers.length; i++) { + if (isOverflow(transaction.nullifiers[i], MAX_PUBLIC_VALUES.NULLIFIER)) + throw new TransactionError('Overflow in public input', 4); + } + for (let i = 0; i < transaction.commitments.length; i++) { + if (isOverflow(transaction.commitments[i], MAX_PUBLIC_VALUES.COMMITMENT)) + throw new TransactionError('Overflow in public input', 4); + } + if ( + isOverflow(historicRootFirst.root, BN128_GROUP_ORDER) || + isOverflow(historicRootSecond.root, BN128_GROUP_ORDER) + ) + throw new TransactionError('Overflow in public input', 4); break; case 3: // withdraw transaction inputs = generalise( @@ -200,15 +247,26 @@ async function verifyProof(transaction) { transaction.ercAddress, transaction.tokenId, transaction.value, - generalise(transaction.nullifiers[0]).hex(32, 31), + transaction.nullifiers[0], transaction.recipientAddress, historicRootFirst.root, ].flat(Infinity), ); + // check for truncation overflow attacks + if ( + isOverflow(transaction.ercAddress, MAX_PUBLIC_VALUES.ERCADDRESS) || + isOverflow(transaction.recipientAddress, MAX_PUBLIC_VALUES.ERCADDRESS) || + isOverflow(transaction.nullifiers[0], MAX_PUBLIC_VALUES.NULLIFIER) || + isOverflow(historicRootFirst.root, BN128_GROUP_ORDER) + ) + throw new TransactionError('Truncated value overflow in public input', 4); break; default: throw new TransactionError('Unknown transaction type', 2); } + // check for modular overflow attacks + // if (inputs.filter(input => input.bigInt >= BN128_GROUP_ORDER).length > 0) + // throw new TransactionError('Modular overflow in public input', 4); const res = await verify({ vk: new VerificationKey(vkArray), proof: new Proof(transaction.proof), diff --git a/wallet/src/nightfall-browser/classes/commitment.js b/wallet/src/nightfall-browser/classes/commitment.js index a6c59eaa8..dca53a15d 100644 --- a/wallet/src/nightfall-browser/classes/commitment.js +++ b/wallet/src/nightfall-browser/classes/commitment.js @@ -33,13 +33,13 @@ class Commitment { compressedPkd, salt, }); - this.hash = sha256([ + this.hash = generalise(sha256([ this.preimage.ercAddress, this.preimage.tokenId, this.preimage.value, this.preimage.compressedPkd, this.preimage.salt, - ]); + ]).hex(32, 31)); } // sometimes (e.g. going over http) the general-number class is inconvenient diff --git a/wallet/src/nightfall-browser/classes/nullifier.js b/wallet/src/nightfall-browser/classes/nullifier.js index 12e79abaf..b6f4c1131 100644 --- a/wallet/src/nightfall-browser/classes/nullifier.js +++ b/wallet/src/nightfall-browser/classes/nullifier.js @@ -18,7 +18,7 @@ class Nullifier { nsk, commitment: commitment.hash, }); - this.hash = sha256([this.preimage.nsk, this.preimage.commitment]); + this.hash = generalise(sha256([this.preimage.nsk, this.preimage.commitment]).hex(32, 31)); } } diff --git a/zokrates-worker/src/index.mjs b/zokrates-worker/src/index.mjs index d182027ab..c55fcc0b1 100644 --- a/zokrates-worker/src/index.mjs +++ b/zokrates-worker/src/index.mjs @@ -16,16 +16,7 @@ const main = async () => { const mpcPromises = []; - for (const circuit of [ - 'deposit', - 'double_transfer', - 'single_transfer', - 'withdraw', - 'deposit_stub', - 'withdraw_stub', - 'double_transfer_stub', - 'single_transfer_stub', - ]) { + for (const circuit of ['deposit', 'double_transfer', 'single_transfer', 'withdraw']) { if (!fs.existsSync(`./mpc_params/${circuit}`)) { mpcPromises.push( new Promise((resolve, reject) => { diff --git a/zokrates-worker/src/services/generateKeys.mjs b/zokrates-worker/src/services/generateKeys.mjs index 5bda452da..2471eabab 100644 --- a/zokrates-worker/src/services/generateKeys.mjs +++ b/zokrates-worker/src/services/generateKeys.mjs @@ -20,18 +20,18 @@ export default async function generateKeys({ filepath, curve = 'bn128' }) { curve, ); + logger.info('Compile...'); + await compile( + `${circuitsPath}/${filepath}`, + `${outputPath}/${circuitDir}`, + `${circuitName}_out`, + curve, + ); + if (process.env.MPC) { logger.info('Export keys...'); await exportKeys(`${outputPath}/${circuitDir}`, `${circuitName}`); } else { - logger.info('Compile...'); - await compile( - `${circuitsPath}/${filepath}`, - `${outputPath}/${circuitDir}`, - `${circuitName}_out`, - curve, - ); - logger.info('Setup...'); await setup( `${outputPath}/${circuitDir}/${circuitName}_out`,