up8-ticket

Securely generate UP8-compatible, @q-encoded master tickets.
Log | Files | Refs | README | LICENSE

commit c0c5d77ce18c1ed8302c861726f838b60d85c92d
Author: Jared Tobin <jared@jtobin.io>
Date:   Wed, 16 Sep 2020 21:30:47 -0230

release: v0.1.0

Diffstat:
A.gitignore | 1+
AREADME.md | 18++++++++++++++++++
Apackage-lock.json | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apackage.json | 18++++++++++++++++++
Asrc/index.js | 29+++++++++++++++++++++++++++++
5 files changed, 127 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/README.md b/README.md @@ -0,0 +1,18 @@ +# master-ticket-generator + +Generate `@q` master tickets in exactly the same way +[urbit-wallet-generator][wgen] does. + +## but how + +Clone the repository, `npm install` to grab the dependencies, and then: + +``` +$ node --experimental-repl-await +> const tg = require('./src') +> let ticket = await tg.gen(384) // supply desired number of bits +> ticket +'~wisbyl-tarfes-biltug-datmyr-rigsyp-ribryc-nocmyr-bilres-mipset-patsut-todbur-foptev-lorfer-famtux-loppes-mismug-tobdyl-hopnes-lophul-tapdus-habtuc-ragseg-dossev-ramneb' +``` + +[wgen]: https://github.com/urbit/urbit-wallet-generator diff --git a/package-lock.json b/package-lock.json @@ -0,0 +1,61 @@ +{ + "name": "ticket-generator", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + }, + "iced-runtime": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/iced-runtime/-/iced-runtime-1.0.4.tgz", + "integrity": "sha512-rgiJXNF6ZgF2Clh/TKUlBDW3q51YPDJUXmxGQXx1b8tbZpVpTn+1RX9q1sjNkujXIIaVxZByQzPHHORg7KV51g==" + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "lodash.chunk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", + "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" + }, + "lodash.flatmap": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz", + "integrity": "sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.zipwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zipwith/-/lodash.zipwith-4.2.0.tgz", + "integrity": "sha1-r6zwP9LzhK8p4mPDxr2juA4/Uf0=" + }, + "more-entropy": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/more-entropy/-/more-entropy-0.0.7.tgz", + "integrity": "sha1-Z7/G96hvJvvDeqyD/UbYjGHRCbU=", + "requires": { + "iced-runtime": ">=0.0.1" + } + }, + "urbit-ob": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/urbit-ob/-/urbit-ob-5.0.1.tgz", + "integrity": "sha512-qGNAwu87XNkW3g8ah4fUwmh2EKXtsdhEbyEiE5qX4Op17rhLH3HSkvu8g9z+MhqX51Uz9sf8ktvqJj/IRwETIQ==", + "requires": { + "bn.js": "^4.11.8", + "lodash.chunk": "^4.2.0", + "lodash.isequal": "^4.5.0" + } + } + } +} diff --git a/package.json b/package.json @@ -0,0 +1,18 @@ +{ + "name": "master-ticket-generator", + "version": "0.1.0", + "description": "Generate master ticket-length @q values", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "~nidsut-tomdun", + "license": "MIT", + "dependencies": { + "lodash.chunk": "^4.2.0", + "lodash.flatmap": "^4.5.0", + "lodash.zipwith": "^4.2.0", + "more-entropy": "0.0.7", + "urbit-ob": "^5.0.1" + } +} diff --git a/src/index.js b/src/index.js @@ -0,0 +1,29 @@ +const more = require('more-entropy') +const ob = require('urbit-ob') +const chunk = require('lodash.chunk') +const flatMap = require('lodash.flatmap') +const zipWith = require('lodash.zipwith') + +const gen = bits => { + const bytes = bits / 8 + const some = crypto.rng(bytes) + + const prng = new more.Generator() + + return new Promise((resolve, reject) => { + prng.generate(bits, result => { + const chunked = chunk(result, 2) + const desired = chunked.slice(0, bytes) // only take required entropy + const more = flatMap(desired, arr => arr[0] ^ arr[1]) + const entropy = zipWith(some, more, (x, y) => x ^ y) + const buf = Buffer.from(entropy) + const patq = ob.hex2patq(buf.toString('hex')) + resolve(patq) + reject("entropy generation failed") + }) + }) +} + +module.exports = { + gen: gen +}