mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-20 02:25:53 +00:00
141 lines
3.4 KiB
JavaScript
141 lines
3.4 KiB
JavaScript
|
|
var sjcl = require('../../build/sjcl');
|
|
var utils = require('./utils');
|
|
var jsbn = require('./jsbn');
|
|
var extend = require('extend');
|
|
|
|
var BigInteger = jsbn.BigInteger;
|
|
var nbi = jsbn.nbi;
|
|
|
|
var Base = {};
|
|
|
|
var alphabets = Base.alphabets = {
|
|
'ripple' : "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
|
|
'tipple' : "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz",
|
|
'bitcoin' : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
|
};
|
|
|
|
extend(Base, {
|
|
'VER_NONE' : 1,
|
|
'VER_NODE_PUBLIC' : 28,
|
|
'VER_NODE_PRIVATE' : 32,
|
|
'VER_ACCOUNT_ID' : 0,
|
|
'VER_ACCOUNT_PUBLIC' : 35,
|
|
'VER_ACCOUNT_PRIVATE' : 34,
|
|
'VER_FAMILY_GENERATOR' : 41,
|
|
'VER_FAMILY_SEED' : 33
|
|
});
|
|
|
|
var sha256 = function (bytes) {
|
|
return sjcl.codec.bytes.fromBits(sjcl.hash.sha256.hash(sjcl.codec.bytes.toBits(bytes)));
|
|
};
|
|
|
|
var sha256hash = function (bytes) {
|
|
return sha256(sha256(bytes));
|
|
};
|
|
|
|
// --> input: big-endian array of bytes.
|
|
// <-- string at least as long as input.
|
|
Base.encode = function (input, alpha) {
|
|
var alphabet = alphabets[alpha || 'ripple'];
|
|
var bi_base = new BigInteger(String(alphabet.length));
|
|
var bi_q = nbi();
|
|
var bi_r = nbi();
|
|
var bi_value = new BigInteger(input);
|
|
var buffer = [];
|
|
|
|
while (bi_value.compareTo(BigInteger.ZERO) > 0)
|
|
{
|
|
bi_value.divRemTo(bi_base, bi_q, bi_r);
|
|
bi_q.copyTo(bi_value);
|
|
|
|
buffer.push(alphabet[bi_r.intValue()]);
|
|
}
|
|
|
|
var i;
|
|
|
|
for (i = 0; i != input.length && !input[i]; i += 1) {
|
|
buffer.push(alphabet[0]);
|
|
}
|
|
|
|
return buffer.reverse().join("");
|
|
};
|
|
|
|
// --> input: String
|
|
// <-- array of bytes or undefined.
|
|
Base.decode = function (input, alpha) {
|
|
var alphabet = alphabets[alpha || 'ripple'];
|
|
var bi_base = new BigInteger(String(alphabet.length));
|
|
var bi_value = nbi();
|
|
var i;
|
|
|
|
for (i = 0; i != input.length && input[i] === alphabet[0]; i += 1)
|
|
;
|
|
|
|
for (; i != input.length; i += 1) {
|
|
var v = alphabet.indexOf(input[i]);
|
|
|
|
if (v < 0)
|
|
return undefined;
|
|
|
|
var r = nbi();
|
|
|
|
r.fromInt(v);
|
|
|
|
bi_value = bi_value.multiply(bi_base).add(r);
|
|
}
|
|
|
|
// toByteArray:
|
|
// - Returns leading zeros!
|
|
// - Returns signed bytes!
|
|
var bytes = bi_value.toByteArray().map(function (b) { return b ? b < 0 ? 256+b : b : 0; });
|
|
var extra = 0;
|
|
|
|
while (extra != bytes.length && !bytes[extra])
|
|
extra += 1;
|
|
|
|
if (extra)
|
|
bytes = bytes.slice(extra);
|
|
|
|
var zeros = 0;
|
|
|
|
while (zeros !== input.length && input[zeros] === alphabet[0])
|
|
zeros += 1;
|
|
|
|
return [].concat(utils.arraySet(zeros, 0), bytes);
|
|
};
|
|
|
|
// --> input: Array
|
|
// <-- String
|
|
Base.encode_check = function (version, input, alphabet) {
|
|
var buffer = [].concat(version, input);
|
|
var check = sha256(sha256(buffer)).slice(0, 4);
|
|
|
|
return Base.encode([].concat(buffer, check), alphabet);
|
|
}
|
|
|
|
// --> input : String
|
|
// <-- NaN || BigInteger
|
|
Base.decode_check = function (version, input, alphabet) {
|
|
var buffer = Base.decode(input, alphabet);
|
|
|
|
if (!buffer || buffer[0] !== version || buffer.length < 5)
|
|
return NaN;
|
|
|
|
var computed = sha256hash(buffer.slice(0, -4)).slice(0, 4);
|
|
var checksum = buffer.slice(-4);
|
|
var i;
|
|
|
|
for (i = 0; i != 4; i += 1)
|
|
if (computed[i] !== checksum[i])
|
|
return NaN;
|
|
|
|
// We'll use the version byte to add a leading zero, this ensures JSBN doesn't
|
|
// intrepret the value as a negative number
|
|
buffer[0] = 0;
|
|
|
|
return new BigInteger(buffer.slice(0, -4), 256);
|
|
}
|
|
|
|
exports.Base = Base;
|