Skip to content

Instantly share code, notes, and snippets.

@pinheadmz
Last active November 20, 2019 14:26
Show Gist options
  • Select an option

  • Save pinheadmz/52853f865cdd530fff8421443fe40cab to your computer and use it in GitHub Desktop.

Select an option

Save pinheadmz/52853f865cdd530fff8421443fe40cab to your computer and use it in GitHub Desktop.
--- /Users/matthewzipkin/Desktop/work/hsd/node_modules/bstring/lib/bech32-browser.js Sat Oct 26 04:15:00 1985
+++ /Users/matthewzipkin/Desktop/work/hsd/lib/ui/bech32.js Tue Nov 19 18:35:47 2019
@@ -1,30 +1,24 @@
/*!
- * bech32.js - bech32 for bcoin
- * Copyright (c) 2017, Christopher Jeffrey (MIT License).
- * https://github.com/bcoin-org/bcoin
+ * hbech32.js - bech32 for hsd
+ * Copyright (c) 2019, Handshake Developers (MIT License).
+ * Copyright (c) 2017-2019, Christopher Jeffrey (MIT License).
+ * https://github.com/bcoin-org/bcrypto
*
- * Parts of this software are based on "bech32".
- * https://github.com/sipa/bech32
+ * bech32 without Bitcoin size restrictions.
*
- * Copyright (c) 2017 Pieter Wuille
+ * Parts of this software are based on lightningnetwork/lnd:
+ * Copyright (C) 2015-2018 Lightning Labs and The
+ * Lightning Network Developers.
+ * https://github.com/lightningnetwork/lnd
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Parts of this software are based on sipa/bech32:
+ * Copyright (c) 2017, Pieter Wuille (MIT License).
+ * https://github.com/sipa/bech32
*
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * Resources:
+ * https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
+ * https://github.com/sipa/bech32/blob/master/ref/c/segwit_addr.c
+ * https://github.com/bitcoin/bitcoin/blob/master/src/bech32.cpp
*/
'use strict';
@@ -35,7 +29,7 @@
* Constants
*/
-const POOL66 = Buffer.allocUnsafe(66);
+const POOL128 = Buffer.allocUnsafe(128);
const CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
const TABLE = [
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -67,7 +61,6 @@
/**
* Encode hrp and data as a bech32 string.
- * @ignore
* @param {String} hrp
* @param {Buffer} data
* @returns {String}
@@ -88,9 +81,6 @@
chk = polymod(chk) ^ (ch >>> 5);
}
-
- if (i + 7 + data.length > 90)
- throw new Error('Invalid bech32 data length.');
chk = polymod(chk);
@@ -107,8 +97,9 @@
for (let i = 0; i < data.length; i++) {
const ch = data[i];
- if ((ch >>> 5) !== 0)
+ if ((ch >>> 5) !== 0) {
throw new Error('Invalid bech32 value.');
+ }
chk = polymod(chk) ^ ch;
str += CHARSET[ch];
@@ -133,9 +124,6 @@
function deserialize(str) {
assert(typeof str === 'string');
-
- if (str.length < 8 || str.length > 90)
- throw new Error('Invalid bech32 string length.');
let dlen = 0;
@@ -217,8 +205,7 @@
*/
function is(str) {
- if (typeof str !== 'string')
- return false;
+ assert(typeof str === 'string');
try {
deserialize(str);
@@ -249,6 +236,8 @@
assert((frombits & 0xff) === frombits);
assert((tobits & 0xff) === tobits);
assert(typeof pad === 'boolean');
+ assert(frombits !== 0);
+ assert(tobits !== 0);
const maxv = (1 << tobits) - 1;
@@ -297,6 +286,7 @@
assert((frombits & 0xff) === frombits);
assert((tobits & 0xff) === tobits);
assert(typeof pad === 'boolean');
+ assert(frombits !== 0);
assert(tobits !== 0);
let size = (len * frombits + (tobits - 1)) / tobits;
@@ -320,9 +310,6 @@
function convertBits(data, frombits, tobits, pad) {
assert(Buffer.isBuffer(data));
- assert((frombits & 0xff) === frombits);
- assert((tobits & 0xff) === tobits);
- assert(typeof pad === 'boolean');
const size = convertSize(data.length, frombits, tobits, pad);
const out = Buffer.allocUnsafe(size);
@@ -343,13 +330,10 @@
assert((version & 0xff) === version);
assert(Buffer.isBuffer(hash));
- if (version < 0 || version > 31)
- throw new Error('Invalid bech32 version.');
-
- if (hash.length < 2 || hash.length > 40)
- throw new Error('Invalid bech32 data length.');
-
- const out = POOL66;
+ // TODO: figure out max size of encode
+ // to allow for the pool to work
+
+ const out = POOL128;
out[0] = version;
const data = convert(hash, 0, out, 1, 8, 5, true);
@@ -360,39 +344,31 @@
/**
* Deserialize data from bech32 address.
* @param {String} str
- * @returns {Object}
+ * @returns {Array}
*/
function decode(str) {
- assert(typeof str === 'string');
-
const [hrp, data] = deserialize(str);
- if (data.length === 0 || data.length > 65)
- throw new Error('Invalid bech32 data length.');
-
const version = data[0];
- if (version > 31)
- throw new Error('Invalid bech32 version.');
-
const hash = convert(data, 1, data, 0, 5, 8, false);
- if (hash.length < 2 || hash.length > 40)
- throw new Error('Invalid bech32 data length.');
-
- return new AddrResult(hrp, version, hash);
+ return [hrp, version, hash];
}
/**
* Test whether a string is a bech32 string.
* @param {String} str
+ * @param {Number} version - Maximum version
+ * @param {Number} size - Maximum data size
* @returns {Boolean}
*/
-function test(str) {
- if (typeof str !== 'string')
- return false;
+function test(str, version, size) {
+ assert(typeof str === 'string');
+ assert(typeof version === 'number');
+ assert(typeof size === 'number');
let data;
@@ -402,45 +378,26 @@
return false;
}
- if (data.length === 0 || data.length > 65)
+ if (data.length === 0 || data.length > size)
return false;
- const version = data[0];
-
- if (version > 31)
+ if (data[0] < 0 || data[0] > version)
return false;
return true;
-}
-
-/**
- * AddrResult
- * @constructor
- * @private
- * @param {String} hrp
- * @param {Number} version
- * @param {Buffer} hash
- * @property {String} hrp
- * @property {Number} version
- * @property {Buffer} hash
- */
-
-class AddrResult {
- constructor(hrp, version, hash) {
- this.hrp = hrp;
- this.version = version;
- this.hash = hash;
- }
}
/*
* Expose
*/
+exports.native = 0;
exports.serialize = serialize;
exports.deserialize = deserialize;
exports.is = is;
exports.convertBits = convertBits;
+exports.convert = convert;
exports.encode = encode;
exports.decode = decode;
exports.test = test;
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment