bech32: refactor.

This commit is contained in:
Christopher Jeffrey 2017-05-13 15:13:42 -07:00
parent 83060ee964
commit a9ea4e5531
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 83 additions and 28 deletions

View File

@ -9,16 +9,18 @@ var i, end, addr;
var addrs = [];
end = bench('serialize');
for (i = 0; i < 10000; i++) {
for (i = 0; i < 100000; i++) {
addr = Address.fromProgram(0, crypto.randomBytes(20));
addrs.push(addr.toBech32());
}
end(i);
end = bench('parse');
for (i = 0; i < 10000; i++) {
for (i = 0; i < 100000; i++) {
addr = addrs[i];
addr = Address.fromBech32(addr);
addrs[i] = addr;
}
end(i);
console.error(addrs);

View File

@ -236,9 +236,7 @@ Address.prototype.toBech32 = function toBech32(network) {
network = Network.get(network);
hrp = network.addressPrefix.bech32;
data = bech32.bitsify(hash, 65, 8, 5, version, 0);
return bech32.encode(hrp, data);
return bech32.encode(hrp, version, hash);
};
/**
@ -389,23 +387,18 @@ Address.fromBase58 = function fromBase58(address, network) {
/**
* Inject properties from bech32 address.
* @private
* @param {String} data
* @param {String} str
* @param {Network?} network
* @throws Parse error
*/
Address.prototype.fromBech32 = function fromBech32(data, network) {
Address.prototype.fromBech32 = function fromBech32(str, network) {
var type = Address.types.WITNESS;
var i, addr, hash, version;
var i, addr;
assert(typeof data === 'string');
assert(typeof str === 'string');
addr = bech32.decode(data);
if (addr.data.length < 1)
throw new Error('Invalid bech32 data length.');
version = addr.data[0];
addr = bech32.decode(str);
if (network) {
network = Network.get(network);
@ -421,9 +414,7 @@ Address.prototype.fromBech32 = function fromBech32(data, network) {
assert(i < networks.types.length, 'Unknown bech32 address prefix.');
}
hash = bech32.bitsify(addr.data, 84, 5, 8, -1, 1);
return this.fromHash(hash, type, version, network.type);
return this.fromHash(addr.hash, type, addr.version, network.type);
};
/**

View File

@ -29,6 +29,8 @@
'use strict';
var native = require('./native').binding;
/**
* @module utils/bech32
*/
@ -70,7 +72,7 @@ function polymod(pre) {
* @returns {String}
*/
function encode(hrp, data) {
function serialize(hrp, data) {
var str = '';
var chk = 1;
var i, ch;
@ -124,7 +126,7 @@ function encode(hrp, data) {
* @returns {Bech32Result}
*/
function decode(str) {
function deserialize(str) {
var chk = 1;
var lower = false;
var upper = false;
@ -211,7 +213,7 @@ function decode(str) {
* @returns {Buffer}
*/
function bitsify(data, size, frombits, tobits, pad, off) {
function convert(data, size, frombits, tobits, pad, off) {
var acc = 0;
var bits = 0;
var maxv = (1 << tobits) - 1;
@ -248,6 +250,46 @@ function bitsify(data, size, frombits, tobits, pad, off) {
return output.slice(0, j);
}
/**
* Serialize data to bech32 address.
* @param {String} hrp
* @param {Number} version
* @param {Buffer} hash
* @returns {String}
*/
function encode(hrp, version, hash) {
var data = convert(hash, 65, 8, 5, version, 0);
return serialize(hrp, data);
}
if (native && native.toBech32)
encode = native.toBech32;
/**
* Deserialize data from bech32 address.
* @param {String} str
* @returns {Object}
*/
function decode(str) {
var result = deserialize(str);
var hrp = result.hrp;
var data = result.data;
var version, hash;
if (data.length < 1)
throw new Error('Invalid bech32 data length.');
version = data[0];
hash = convert(data, 84, 5, 8, -1, 1);
return new AddrResult(hrp, version, hash);
}
if (native && native.fromBech32)
decode = native.fromBech32;
/**
* Bech32Result
* @constructor
@ -263,10 +305,30 @@ function Bech32Result(hrp, data) {
this.data = data;
}
/**
* AddrResult
* @constructor
* @private
* @param {String} hrp
* @param {Number} version
* @param {Buffer} hash
* @property {String} hrp
* @property {Number} version
* @property {Buffer} hash
*/
function AddrResult(hrp, version, hash) {
this.hrp = hrp;
this.version = version;
this.hash = hash;
}
/*
* Expose
*/
exports.decode = decode;
exports.deserialize = deserialize;
exports.serialize = serialize;
exports.convert = convert;
exports.encode = encode;
exports.bitsify = bitsify;
exports.decode = decode;

View File

@ -99,13 +99,13 @@ describe('Bech32', function() {
];
function fromAddress(hrp, addr) {
var dec = bech32.decode(addr);
var dec = bech32.deserialize(addr);
var data;
if (dec.hrp !== hrp || dec.data.length < 1 || dec.data[0] > 16)
throw new Error('Invalid bech32 prefix or data length.');
data = bech32.bitsify(dec.data, 84, 5, 8, -1, 1);
data = bech32.convert(dec.data, 84, 5, 8, -1, 1);
if (data.length < 2 || data.length > 40)
throw new Error('Invalid witness program size.');
@ -120,8 +120,8 @@ describe('Bech32', function() {
}
function toAddress(hrp, version, program) {
var data = bech32.bitsify(program, 65, 8, 5, version, 0);
var ret = bech32.encode(hrp, data);
var data = bech32.convert(program, 65, 8, 5, version, 0);
var ret = bech32.serialize(hrp, data);
fromAddress(hrp, ret);
@ -135,7 +135,7 @@ describe('Bech32', function() {
VALID_CHECKSUM.forEach(function(test) {
it('should have valid checksum for ' + test, function() {
var ret = bech32.decode(test);
var ret = bech32.deserialize(test);
assert(ret);
});
});