multichain-address-validator 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cjs/chain-validators.js +4 -0
- package/dist/cjs/crypto/utils.d.ts +2 -2
- package/dist/cjs/crypto/utils.js +3 -4
- package/dist/cjs/validators/bch_validator.js +49 -15
- package/dist/cjs/validators/cardano_validator.js +3 -3
- package/dist/cjs/validators/cosmos_validator.d.ts +5 -0
- package/dist/cjs/validators/cosmos_validator.js +17 -0
- package/dist/cjs/validators/index.d.ts +1 -0
- package/dist/cjs/validators/index.js +3 -1
- package/dist/cjs/validators/sia_validator.js +1 -9
- package/dist/cjs/validators/tezos_validator.js +16 -9
- package/dist/esm/chain-validators.js +5 -1
- package/dist/esm/crypto/utils.d.ts +2 -2
- package/dist/esm/crypto/utils.js +4 -5
- package/dist/esm/validators/bch_validator.js +49 -15
- package/dist/esm/validators/cardano_validator.js +3 -3
- package/dist/esm/validators/cosmos_validator.d.ts +5 -0
- package/dist/esm/validators/cosmos_validator.js +12 -0
- package/dist/esm/validators/index.d.ts +1 -0
- package/dist/esm/validators/index.js +1 -0
- package/dist/esm/validators/sia_validator.js +1 -9
- package/dist/esm/validators/tezos_validator.js +16 -9
- package/package.json +3 -4
- package/dist/cjs/crypto/blake2b.d.ts +0 -13
- package/dist/cjs/crypto/blake2b.js +0 -243
- package/dist/esm/crypto/blake2b.d.ts +0 -13
- package/dist/esm/crypto/blake2b.js +0 -242
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ npm install multichain-address-validator
|
|
|
30
30
|
* Bitcoin: `bitcoin`, `btc`, `omni`
|
|
31
31
|
* Bitcoin Cash: `bitcoin-cash`, `bitcoincash`, `bitcoin cash`, `bch`
|
|
32
32
|
* Cardano: `cardano`, `ada`
|
|
33
|
+
* Cosmos: `cosmos`, `atom`
|
|
33
34
|
* Dogecoin: `dogecoin`, `doge`
|
|
34
35
|
* EOS: `eos`
|
|
35
36
|
* Etherum: `ethereum`, `eth`, `erc20`, `flare`, `avalanche`, `avalanche-c`, `bsc`, `bnb`, `binance`, `sonic`, `berachain`, `story`
|
|
@@ -11,10 +11,10 @@ declare const _default: {
|
|
|
11
11
|
sha512_256: (payload: any, format?: string) => string;
|
|
12
12
|
blake256: (hexString: string) => string;
|
|
13
13
|
blake256Checksum: (payload: any) => any;
|
|
14
|
-
blake2b: (hexString: string, outlen: number) =>
|
|
14
|
+
blake2b: (hexString: string, outlen: number) => string;
|
|
15
15
|
keccak256: (input: string | Uint8Array) => string;
|
|
16
16
|
keccak256Checksum: (payload: any) => any;
|
|
17
|
-
blake2b256: (hexString: string) =>
|
|
17
|
+
blake2b256: (hexString: string) => string;
|
|
18
18
|
base58: (string: string) => number[];
|
|
19
19
|
byteArray2hexStr: typeof byteArray2hexStr;
|
|
20
20
|
hexStr2byteArray: typeof hexStr2byteArray;
|
package/dist/cjs/crypto/utils.js
CHANGED
|
@@ -3,15 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const buffer_1 = require("buffer");
|
|
7
6
|
const sha2_js_1 = require("@noble/hashes/sha2.js");
|
|
8
7
|
const sha2_js_2 = require("@noble/hashes/sha2.js");
|
|
9
8
|
const utils_js_1 = require("@noble/hashes/utils.js");
|
|
10
9
|
const sha3_js_1 = require("@noble/hashes/sha3.js");
|
|
10
|
+
const blake2_js_1 = require("@noble/hashes/blake2.js");
|
|
11
11
|
const base32_js_1 = __importDefault(require("./base32.js"));
|
|
12
12
|
const base58_js_1 = __importDefault(require("./base58.js"));
|
|
13
13
|
const blake256_js_1 = __importDefault(require("./blake256.js"));
|
|
14
|
-
const blake2b_js_1 = __importDefault(require("./blake2b.js"));
|
|
15
14
|
function numberToHex(number, length) {
|
|
16
15
|
let hex = number.toString(16);
|
|
17
16
|
if (hex.length % 2 === 1) {
|
|
@@ -110,7 +109,7 @@ exports.default = {
|
|
|
110
109
|
return this.blake256(this.blake256(payload)).substr(0, 8);
|
|
111
110
|
},
|
|
112
111
|
blake2b: function (hexString, outlen) {
|
|
113
|
-
return
|
|
112
|
+
return (0, utils_js_1.bytesToHex)((0, blake2_js_1.blake2b)((0, utils_js_1.hexToBytes)(hexString), { dkLen: outlen }));
|
|
114
113
|
},
|
|
115
114
|
keccak256: function (input) {
|
|
116
115
|
const data = typeof input === 'string' ? new TextEncoder().encode(input) : input;
|
|
@@ -120,7 +119,7 @@ exports.default = {
|
|
|
120
119
|
return this.keccak256(payload).toString().substr(0, 8);
|
|
121
120
|
},
|
|
122
121
|
blake2b256: function (hexString) {
|
|
123
|
-
return
|
|
122
|
+
return (0, utils_js_1.bytesToHex)((0, blake2_js_1.blake2b)((0, utils_js_1.hexToBytes)(hexString), { dkLen: 32 }));
|
|
124
123
|
},
|
|
125
124
|
base58: base58_js_1.default.decode,
|
|
126
125
|
byteArray2hexStr: byteArray2hexStr,
|
|
@@ -3,53 +3,87 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const utils_js_1 = __importDefault(require("../crypto/utils.js"));
|
|
7
|
-
const bech32_js_1 = __importDefault(require("../crypto/bech32.js"));
|
|
8
6
|
const types_js_1 = require("../types.js");
|
|
9
7
|
const bitcoin_validator_js_1 = __importDefault(require("./bitcoin_validator.js"));
|
|
10
8
|
const helpers_js_1 = require("../helpers.js");
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
|
|
10
|
+
const GENERATOR = [
|
|
11
|
+
0x98f2bc8e61n, 0x79b76d99e2n, 0xf33e5fb3c4n, 0xae2eabe2a8n, 0x1e4f43e470n
|
|
12
|
+
];
|
|
13
|
+
function cashAddrPolymod(values) {
|
|
14
|
+
let chk = 1n;
|
|
15
|
+
for (let i = 0; i < values.length; i++) {
|
|
16
|
+
const top = chk >> 35n;
|
|
17
|
+
chk = ((chk & 0x07ffffffffn) << 5n) ^ BigInt(values[i]);
|
|
18
|
+
for (let j = 0n; j < 5n; j++) {
|
|
19
|
+
if ((top >> j) & 1n) {
|
|
20
|
+
chk ^= GENERATOR[Number(j)];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return chk ^ 1n;
|
|
25
|
+
}
|
|
26
|
+
function prefixExpand(prefix) {
|
|
27
|
+
const ret = [];
|
|
28
|
+
for (let i = 0; i < prefix.length; i++) {
|
|
29
|
+
ret.push(prefix.charCodeAt(i) & 31);
|
|
30
|
+
}
|
|
31
|
+
ret.push(0);
|
|
32
|
+
return ret;
|
|
33
|
+
}
|
|
34
|
+
function verifyCashAddrChecksum(prefix, payload) {
|
|
35
|
+
const expanded = prefixExpand(prefix).concat(payload);
|
|
36
|
+
return cashAddrPolymod(expanded) === 0n;
|
|
37
|
+
}
|
|
38
|
+
function validateCashAddr(address, opts) {
|
|
13
39
|
let raw_address;
|
|
40
|
+
const prefix = opts.networkType === types_js_1.NetworkType.MainNet
|
|
41
|
+
? 'bitcoincash'
|
|
42
|
+
: 'bchtest';
|
|
14
43
|
const res = address.split(':');
|
|
15
44
|
if (res.length === 1) {
|
|
16
45
|
raw_address = address;
|
|
17
46
|
}
|
|
18
47
|
else {
|
|
19
|
-
if (res[0] !==
|
|
48
|
+
if (res[0] !== prefix) {
|
|
20
49
|
return false;
|
|
21
50
|
}
|
|
22
51
|
raw_address = res[1];
|
|
23
52
|
}
|
|
53
|
+
const regexp = new RegExp(opts.regexp);
|
|
24
54
|
if (!regexp.test(raw_address)) {
|
|
25
55
|
return false;
|
|
26
56
|
}
|
|
27
|
-
if (raw_address.toLowerCase()
|
|
57
|
+
if (raw_address.toLowerCase() !== raw_address && raw_address.toUpperCase() !== raw_address) {
|
|
28
58
|
return false;
|
|
29
59
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
60
|
+
raw_address = raw_address.toLowerCase();
|
|
61
|
+
// Decode characters using the bech32/CashAddr charset
|
|
62
|
+
const data = [];
|
|
63
|
+
for (const c of raw_address) {
|
|
64
|
+
const d = CHARSET.indexOf(c);
|
|
65
|
+
if (d === -1) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
data.push(d);
|
|
69
|
+
}
|
|
34
70
|
try {
|
|
35
|
-
if (
|
|
71
|
+
if (!verifyCashAddrChecksum(prefix, data)) {
|
|
36
72
|
return false;
|
|
37
73
|
}
|
|
38
74
|
}
|
|
39
|
-
catch
|
|
75
|
+
catch {
|
|
40
76
|
return false;
|
|
41
77
|
}
|
|
42
78
|
return true;
|
|
43
79
|
}
|
|
44
80
|
const DefaultBCHValidatorOpts = {
|
|
45
|
-
// addressTypes: {mainnet: ['00', '05'], testnet: ['6f', 'c4', '3c', '26']},
|
|
46
|
-
// bech32Hrp: {mainnet: ['bc'], testnet: ['tb']},
|
|
47
81
|
regexp: /^[qQpP][0-9a-zA-Z]{41}$/,
|
|
48
82
|
};
|
|
49
83
|
exports.default = (opts) => ({
|
|
50
84
|
isValidAddress: function (address) {
|
|
51
85
|
const addr = (0, helpers_js_1.getAddress)(address);
|
|
52
86
|
const _opts = { ...DefaultBCHValidatorOpts, ...opts };
|
|
53
|
-
return
|
|
87
|
+
return validateCashAddr(addr, _opts) || (0, bitcoin_validator_js_1.default)(opts).isValidAddress(address);
|
|
54
88
|
}
|
|
55
89
|
});
|
|
@@ -20,7 +20,7 @@ function getDecoded(address) {
|
|
|
20
20
|
}
|
|
21
21
|
function isValidAddressV1(address) {
|
|
22
22
|
const decoded = getDecoded(address);
|
|
23
|
-
if (!decoded ||
|
|
23
|
+
if (!decoded || !Array.isArray(decoded) || decoded.length !== 2) {
|
|
24
24
|
return false;
|
|
25
25
|
}
|
|
26
26
|
const tagged = decoded[0];
|
|
@@ -30,7 +30,7 @@ function isValidAddressV1(address) {
|
|
|
30
30
|
}
|
|
31
31
|
// get crc of the payload
|
|
32
32
|
const crc = crc_1.default.crc32(tagged);
|
|
33
|
-
return crc
|
|
33
|
+
return crc === validCrc;
|
|
34
34
|
}
|
|
35
35
|
function isValidAddressShelley(address, opts) {
|
|
36
36
|
// shelley address are just bip 173 - bech32 addresses (https://cips.cardano.org/cips/cip4/)
|
|
@@ -39,7 +39,7 @@ function isValidAddressShelley(address, opts) {
|
|
|
39
39
|
exports.default = {
|
|
40
40
|
isValidAddress(address) {
|
|
41
41
|
const addr = (0, helpers_js_1.getAddress)(address);
|
|
42
|
-
return isValidAddressV1(
|
|
42
|
+
return isValidAddressV1(addr) || isValidAddressShelley(addr, {
|
|
43
43
|
bech32Hrp: ['addr']
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const bip173_validator_js_1 = __importDefault(require("./bip173_validator.js"));
|
|
7
|
+
const helpers_js_1 = require("../helpers.js");
|
|
8
|
+
// Cosmos uses Bech32 encoding with 'cosmos' as the HRP (Human Readable Part)
|
|
9
|
+
// Mainnet addresses start with 'cosmos1'
|
|
10
|
+
exports.default = {
|
|
11
|
+
isValidAddress(address) {
|
|
12
|
+
const addr = (0, helpers_js_1.getAddress)(address);
|
|
13
|
+
return bip173_validator_js_1.default.isValidAddress(addr, {
|
|
14
|
+
bech32Hrp: ['cosmos']
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -3,6 +3,7 @@ export { default as BCHValidator } from "./bch_validator.js";
|
|
|
3
3
|
export { default as BittensorValidator } from "./bittensor_validator.js";
|
|
4
4
|
export { default as BTCValidator } from "./bitcoin_validator.js";
|
|
5
5
|
export { default as CardanoValidator } from "./cardano_validator.js";
|
|
6
|
+
export { default as CosmosValidator } from "./cosmos_validator.js";
|
|
6
7
|
export { default as EOSValidator } from "./eos_validator.js";
|
|
7
8
|
export { default as ETHValidator } from "./ethereum_validator.js";
|
|
8
9
|
export { default as HederaValidator } from "./hedera_validator.js";
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ZcashValidator = exports.XLMValidator = exports.TronValidator = exports.TezosValidator = exports.SolanaValidator = exports.SiaValidator = exports.RippleValidator = exports.PolkadotValidator = exports.NanoValidator = exports.NemValidator = exports.MoveValidator = exports.MoneroValidator = exports.HederaValidator = exports.ETHValidator = exports.EOSValidator = exports.CardanoValidator = exports.BTCValidator = exports.BittensorValidator = exports.BCHValidator = exports.AlgorandValidator = void 0;
|
|
6
|
+
exports.ZcashValidator = exports.XLMValidator = exports.TronValidator = exports.TezosValidator = exports.SolanaValidator = exports.SiaValidator = exports.RippleValidator = exports.PolkadotValidator = exports.NanoValidator = exports.NemValidator = exports.MoveValidator = exports.MoneroValidator = exports.HederaValidator = exports.ETHValidator = exports.EOSValidator = exports.CosmosValidator = exports.CardanoValidator = exports.BTCValidator = exports.BittensorValidator = exports.BCHValidator = exports.AlgorandValidator = void 0;
|
|
7
7
|
var algorand_validator_js_1 = require("./algorand_validator.js");
|
|
8
8
|
Object.defineProperty(exports, "AlgorandValidator", { enumerable: true, get: function () { return __importDefault(algorand_validator_js_1).default; } });
|
|
9
9
|
var bch_validator_js_1 = require("./bch_validator.js");
|
|
@@ -14,6 +14,8 @@ var bitcoin_validator_js_1 = require("./bitcoin_validator.js");
|
|
|
14
14
|
Object.defineProperty(exports, "BTCValidator", { enumerable: true, get: function () { return __importDefault(bitcoin_validator_js_1).default; } });
|
|
15
15
|
var cardano_validator_js_1 = require("./cardano_validator.js");
|
|
16
16
|
Object.defineProperty(exports, "CardanoValidator", { enumerable: true, get: function () { return __importDefault(cardano_validator_js_1).default; } });
|
|
17
|
+
var cosmos_validator_js_1 = require("./cosmos_validator.js");
|
|
18
|
+
Object.defineProperty(exports, "CosmosValidator", { enumerable: true, get: function () { return __importDefault(cosmos_validator_js_1).default; } });
|
|
17
19
|
var eos_validator_js_1 = require("./eos_validator.js");
|
|
18
20
|
Object.defineProperty(exports, "EOSValidator", { enumerable: true, get: function () { return __importDefault(eos_validator_js_1).default; } });
|
|
19
21
|
var ethereum_validator_js_1 = require("./ethereum_validator.js");
|
|
@@ -3,21 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const lodash_isequal_1 = __importDefault(require("lodash.isequal"));
|
|
7
6
|
const utils_js_1 = __importDefault(require("../crypto/utils.js"));
|
|
8
7
|
const helpers_js_1 = require("../helpers.js");
|
|
9
|
-
function hexToBytes(hex) {
|
|
10
|
-
const bytes = [];
|
|
11
|
-
for (let c = 0; c < hex.length; c += 2) {
|
|
12
|
-
bytes.push(parseInt(hex.substr(c, 2), 16));
|
|
13
|
-
}
|
|
14
|
-
return bytes;
|
|
15
|
-
}
|
|
16
8
|
function verifyChecksum(address) {
|
|
17
9
|
const checksumBytes = address.slice(0, 32 * 2);
|
|
18
10
|
const check = address.slice(32 * 2, 38 * 2);
|
|
19
11
|
const blakeHash = utils_js_1.default.blake2b(checksumBytes, 32).slice(0, 6 * 2);
|
|
20
|
-
return
|
|
12
|
+
return blakeHash === check;
|
|
21
13
|
}
|
|
22
14
|
exports.default = {
|
|
23
15
|
isValidAddress: function (address) {
|
|
@@ -6,11 +6,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const base58_js_1 = __importDefault(require("../crypto/base58.js"));
|
|
7
7
|
const utils_js_1 = __importDefault(require("../crypto/utils.js"));
|
|
8
8
|
const helpers_js_1 = require("../helpers.js");
|
|
9
|
-
const
|
|
9
|
+
const VALID_PREFIXES = [
|
|
10
|
+
[6, 161, 159], // tz1 (ed25519)
|
|
11
|
+
[6, 161, 161], // tz2 (secp256k1)
|
|
12
|
+
[6, 161, 164], // tz3 (p256)
|
|
13
|
+
[2, 90, 121], // KT1 (originated)
|
|
14
|
+
];
|
|
10
15
|
function decodeRaw(buffer) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const payload = buffer.slice(0, -4);
|
|
17
|
+
const checksum = buffer.slice(-4);
|
|
18
|
+
const newChecksum = utils_js_1.default.hexStr2byteArray(utils_js_1.default.sha256x2(utils_js_1.default.byteArray2hexStr(payload)));
|
|
14
19
|
if (checksum[0] ^ newChecksum[0] |
|
|
15
20
|
checksum[1] ^ newChecksum[1] |
|
|
16
21
|
checksum[2] ^ newChecksum[2] |
|
|
@@ -18,17 +23,19 @@ function decodeRaw(buffer) {
|
|
|
18
23
|
return;
|
|
19
24
|
return payload;
|
|
20
25
|
}
|
|
26
|
+
function hasValidPrefix(payload) {
|
|
27
|
+
return VALID_PREFIXES.some(prefix => prefix.every((byte, i) => payload[i] === byte));
|
|
28
|
+
}
|
|
21
29
|
exports.default = {
|
|
22
30
|
isValidAddress(address) {
|
|
23
31
|
try {
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
const buffer = base58_js_1.default.decode((0, helpers_js_1.getAddress)(address));
|
|
33
|
+
const payload = decodeRaw(buffer);
|
|
26
34
|
if (!payload)
|
|
27
35
|
return false;
|
|
28
|
-
payload
|
|
29
|
-
return true;
|
|
36
|
+
return hasValidPrefix(payload);
|
|
30
37
|
}
|
|
31
|
-
catch
|
|
38
|
+
catch {
|
|
32
39
|
return false;
|
|
33
40
|
}
|
|
34
41
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NetworkType } from './types.js';
|
|
2
|
-
import { AlgorandValidator, BCHValidator, BittensorValidator, BTCValidator, CardanoValidator, EOSValidator, ETHValidator, HederaValidator, MoneroValidator, MoveValidator, NanoValidator, NemValidator, PolkadotValidator, RippleValidator, SiaValidator, SolanaValidator, TezosValidator, TronValidator, XLMValidator, ZcashValidator, } from './validators/index.js';
|
|
2
|
+
import { AlgorandValidator, BCHValidator, BittensorValidator, BTCValidator, CardanoValidator, CosmosValidator, EOSValidator, ETHValidator, HederaValidator, MoneroValidator, MoveValidator, NanoValidator, NemValidator, PolkadotValidator, RippleValidator, SiaValidator, SolanaValidator, TezosValidator, TronValidator, XLMValidator, ZcashValidator, } from './validators/index.js';
|
|
3
3
|
import { SegwitVersion } from './validators/bitcoin_validator';
|
|
4
4
|
const chainValidators = {
|
|
5
5
|
algorand: { validator: AlgorandValidator },
|
|
@@ -42,6 +42,10 @@ const chainValidators = {
|
|
|
42
42
|
alternatives: ['ada'],
|
|
43
43
|
validator: CardanoValidator,
|
|
44
44
|
},
|
|
45
|
+
cosmos: {
|
|
46
|
+
alternatives: ['atom'],
|
|
47
|
+
validator: CosmosValidator,
|
|
48
|
+
},
|
|
45
49
|
doge: {
|
|
46
50
|
alternatives: ['dogecoin'],
|
|
47
51
|
validator: {
|
|
@@ -11,10 +11,10 @@ declare const _default: {
|
|
|
11
11
|
sha512_256: (payload: any, format?: string) => string;
|
|
12
12
|
blake256: (hexString: string) => string;
|
|
13
13
|
blake256Checksum: (payload: any) => any;
|
|
14
|
-
blake2b: (hexString: string, outlen: number) =>
|
|
14
|
+
blake2b: (hexString: string, outlen: number) => string;
|
|
15
15
|
keccak256: (input: string | Uint8Array) => string;
|
|
16
16
|
keccak256Checksum: (payload: any) => any;
|
|
17
|
-
blake2b256: (hexString: string) =>
|
|
17
|
+
blake2b256: (hexString: string) => string;
|
|
18
18
|
base58: (string: string) => number[];
|
|
19
19
|
byteArray2hexStr: typeof byteArray2hexStr;
|
|
20
20
|
hexStr2byteArray: typeof hexStr2byteArray;
|
package/dist/esm/crypto/utils.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { Buffer } from 'buffer';
|
|
2
1
|
import { sha256 } from '@noble/hashes/sha2.js';
|
|
3
2
|
import { sha512, sha512_256 } from '@noble/hashes/sha2.js';
|
|
4
|
-
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
3
|
+
import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js';
|
|
5
4
|
import { keccak_256 } from '@noble/hashes/sha3.js';
|
|
5
|
+
import { blake2b as nobleBlake2b } from '@noble/hashes/blake2.js';
|
|
6
6
|
import base32 from './base32.js';
|
|
7
7
|
import base58 from './base58.js';
|
|
8
8
|
import Blake256 from './blake256.js';
|
|
9
|
-
import Blake2B from './blake2b.js';
|
|
10
9
|
function numberToHex(number, length) {
|
|
11
10
|
let hex = number.toString(16);
|
|
12
11
|
if (hex.length % 2 === 1) {
|
|
@@ -105,7 +104,7 @@ export default {
|
|
|
105
104
|
return this.blake256(this.blake256(payload)).substr(0, 8);
|
|
106
105
|
},
|
|
107
106
|
blake2b: function (hexString, outlen) {
|
|
108
|
-
return
|
|
107
|
+
return bytesToHex(nobleBlake2b(hexToBytes(hexString), { dkLen: outlen }));
|
|
109
108
|
},
|
|
110
109
|
keccak256: function (input) {
|
|
111
110
|
const data = typeof input === 'string' ? new TextEncoder().encode(input) : input;
|
|
@@ -115,7 +114,7 @@ export default {
|
|
|
115
114
|
return this.keccak256(payload).toString().substr(0, 8);
|
|
116
115
|
},
|
|
117
116
|
blake2b256: function (hexString) {
|
|
118
|
-
return
|
|
117
|
+
return bytesToHex(nobleBlake2b(hexToBytes(hexString), { dkLen: 32 }));
|
|
119
118
|
},
|
|
120
119
|
base58: base58.decode,
|
|
121
120
|
byteArray2hexStr: byteArray2hexStr,
|
|
@@ -1,50 +1,84 @@
|
|
|
1
|
-
import cryptoUtils from '../crypto/utils.js';
|
|
2
|
-
import bech32 from '../crypto/bech32.js';
|
|
3
1
|
import { NetworkType } from '../types.js';
|
|
4
2
|
import BTCValidator from './bitcoin_validator.js';
|
|
5
3
|
import { getAddress } from '../helpers.js';
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
|
|
5
|
+
const GENERATOR = [
|
|
6
|
+
0x98f2bc8e61n, 0x79b76d99e2n, 0xf33e5fb3c4n, 0xae2eabe2a8n, 0x1e4f43e470n
|
|
7
|
+
];
|
|
8
|
+
function cashAddrPolymod(values) {
|
|
9
|
+
let chk = 1n;
|
|
10
|
+
for (let i = 0; i < values.length; i++) {
|
|
11
|
+
const top = chk >> 35n;
|
|
12
|
+
chk = ((chk & 0x07ffffffffn) << 5n) ^ BigInt(values[i]);
|
|
13
|
+
for (let j = 0n; j < 5n; j++) {
|
|
14
|
+
if ((top >> j) & 1n) {
|
|
15
|
+
chk ^= GENERATOR[Number(j)];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return chk ^ 1n;
|
|
20
|
+
}
|
|
21
|
+
function prefixExpand(prefix) {
|
|
22
|
+
const ret = [];
|
|
23
|
+
for (let i = 0; i < prefix.length; i++) {
|
|
24
|
+
ret.push(prefix.charCodeAt(i) & 31);
|
|
25
|
+
}
|
|
26
|
+
ret.push(0);
|
|
27
|
+
return ret;
|
|
28
|
+
}
|
|
29
|
+
function verifyCashAddrChecksum(prefix, payload) {
|
|
30
|
+
const expanded = prefixExpand(prefix).concat(payload);
|
|
31
|
+
return cashAddrPolymod(expanded) === 0n;
|
|
32
|
+
}
|
|
33
|
+
function validateCashAddr(address, opts) {
|
|
8
34
|
let raw_address;
|
|
35
|
+
const prefix = opts.networkType === NetworkType.MainNet
|
|
36
|
+
? 'bitcoincash'
|
|
37
|
+
: 'bchtest';
|
|
9
38
|
const res = address.split(':');
|
|
10
39
|
if (res.length === 1) {
|
|
11
40
|
raw_address = address;
|
|
12
41
|
}
|
|
13
42
|
else {
|
|
14
|
-
if (res[0] !==
|
|
43
|
+
if (res[0] !== prefix) {
|
|
15
44
|
return false;
|
|
16
45
|
}
|
|
17
46
|
raw_address = res[1];
|
|
18
47
|
}
|
|
48
|
+
const regexp = new RegExp(opts.regexp);
|
|
19
49
|
if (!regexp.test(raw_address)) {
|
|
20
50
|
return false;
|
|
21
51
|
}
|
|
22
|
-
if (raw_address.toLowerCase()
|
|
52
|
+
if (raw_address.toLowerCase() !== raw_address && raw_address.toUpperCase() !== raw_address) {
|
|
23
53
|
return false;
|
|
24
54
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
55
|
+
raw_address = raw_address.toLowerCase();
|
|
56
|
+
// Decode characters using the bech32/CashAddr charset
|
|
57
|
+
const data = [];
|
|
58
|
+
for (const c of raw_address) {
|
|
59
|
+
const d = CHARSET.indexOf(c);
|
|
60
|
+
if (d === -1) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
data.push(d);
|
|
64
|
+
}
|
|
29
65
|
try {
|
|
30
|
-
if (
|
|
66
|
+
if (!verifyCashAddrChecksum(prefix, data)) {
|
|
31
67
|
return false;
|
|
32
68
|
}
|
|
33
69
|
}
|
|
34
|
-
catch
|
|
70
|
+
catch {
|
|
35
71
|
return false;
|
|
36
72
|
}
|
|
37
73
|
return true;
|
|
38
74
|
}
|
|
39
75
|
const DefaultBCHValidatorOpts = {
|
|
40
|
-
// addressTypes: {mainnet: ['00', '05'], testnet: ['6f', 'c4', '3c', '26']},
|
|
41
|
-
// bech32Hrp: {mainnet: ['bc'], testnet: ['tb']},
|
|
42
76
|
regexp: /^[qQpP][0-9a-zA-Z]{41}$/,
|
|
43
77
|
};
|
|
44
78
|
export default (opts) => ({
|
|
45
79
|
isValidAddress: function (address) {
|
|
46
80
|
const addr = getAddress(address);
|
|
47
81
|
const _opts = { ...DefaultBCHValidatorOpts, ...opts };
|
|
48
|
-
return
|
|
82
|
+
return validateCashAddr(addr, _opts) || BTCValidator(opts).isValidAddress(address);
|
|
49
83
|
}
|
|
50
84
|
});
|
|
@@ -15,7 +15,7 @@ function getDecoded(address) {
|
|
|
15
15
|
}
|
|
16
16
|
function isValidAddressV1(address) {
|
|
17
17
|
const decoded = getDecoded(address);
|
|
18
|
-
if (!decoded ||
|
|
18
|
+
if (!decoded || !Array.isArray(decoded) || decoded.length !== 2) {
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
const tagged = decoded[0];
|
|
@@ -25,7 +25,7 @@ function isValidAddressV1(address) {
|
|
|
25
25
|
}
|
|
26
26
|
// get crc of the payload
|
|
27
27
|
const crc = CRC.crc32(tagged);
|
|
28
|
-
return crc
|
|
28
|
+
return crc === validCrc;
|
|
29
29
|
}
|
|
30
30
|
function isValidAddressShelley(address, opts) {
|
|
31
31
|
// shelley address are just bip 173 - bech32 addresses (https://cips.cardano.org/cips/cip4/)
|
|
@@ -34,7 +34,7 @@ function isValidAddressShelley(address, opts) {
|
|
|
34
34
|
export default {
|
|
35
35
|
isValidAddress(address) {
|
|
36
36
|
const addr = getAddress(address);
|
|
37
|
-
return isValidAddressV1(
|
|
37
|
+
return isValidAddressV1(addr) || isValidAddressShelley(addr, {
|
|
38
38
|
bech32Hrp: ['addr']
|
|
39
39
|
});
|
|
40
40
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import BIP173Validator from './bip173_validator.js';
|
|
2
|
+
import { getAddress } from '../helpers.js';
|
|
3
|
+
// Cosmos uses Bech32 encoding with 'cosmos' as the HRP (Human Readable Part)
|
|
4
|
+
// Mainnet addresses start with 'cosmos1'
|
|
5
|
+
export default {
|
|
6
|
+
isValidAddress(address) {
|
|
7
|
+
const addr = getAddress(address);
|
|
8
|
+
return BIP173Validator.isValidAddress(addr, {
|
|
9
|
+
bech32Hrp: ['cosmos']
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -3,6 +3,7 @@ export { default as BCHValidator } from "./bch_validator.js";
|
|
|
3
3
|
export { default as BittensorValidator } from "./bittensor_validator.js";
|
|
4
4
|
export { default as BTCValidator } from "./bitcoin_validator.js";
|
|
5
5
|
export { default as CardanoValidator } from "./cardano_validator.js";
|
|
6
|
+
export { default as CosmosValidator } from "./cosmos_validator.js";
|
|
6
7
|
export { default as EOSValidator } from "./eos_validator.js";
|
|
7
8
|
export { default as ETHValidator } from "./ethereum_validator.js";
|
|
8
9
|
export { default as HederaValidator } from "./hedera_validator.js";
|
|
@@ -3,6 +3,7 @@ export { default as BCHValidator } from "./bch_validator.js";
|
|
|
3
3
|
export { default as BittensorValidator } from "./bittensor_validator.js";
|
|
4
4
|
export { default as BTCValidator } from "./bitcoin_validator.js";
|
|
5
5
|
export { default as CardanoValidator } from "./cardano_validator.js";
|
|
6
|
+
export { default as CosmosValidator } from "./cosmos_validator.js";
|
|
6
7
|
export { default as EOSValidator } from "./eos_validator.js";
|
|
7
8
|
export { default as ETHValidator } from "./ethereum_validator.js";
|
|
8
9
|
export { default as HederaValidator } from "./hedera_validator.js";
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
import isEqual from 'lodash.isequal';
|
|
2
1
|
import cryptoUtils from '../crypto/utils.js';
|
|
3
2
|
import { getAddress } from '../helpers.js';
|
|
4
|
-
function hexToBytes(hex) {
|
|
5
|
-
const bytes = [];
|
|
6
|
-
for (let c = 0; c < hex.length; c += 2) {
|
|
7
|
-
bytes.push(parseInt(hex.substr(c, 2), 16));
|
|
8
|
-
}
|
|
9
|
-
return bytes;
|
|
10
|
-
}
|
|
11
3
|
function verifyChecksum(address) {
|
|
12
4
|
const checksumBytes = address.slice(0, 32 * 2);
|
|
13
5
|
const check = address.slice(32 * 2, 38 * 2);
|
|
14
6
|
const blakeHash = cryptoUtils.blake2b(checksumBytes, 32).slice(0, 6 * 2);
|
|
15
|
-
return
|
|
7
|
+
return blakeHash === check;
|
|
16
8
|
}
|
|
17
9
|
export default {
|
|
18
10
|
isValidAddress: function (address) {
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import base58 from '../crypto/base58.js';
|
|
2
2
|
import cryptoUtils from '../crypto/utils.js';
|
|
3
3
|
import { getAddress } from '../helpers.js';
|
|
4
|
-
const
|
|
4
|
+
const VALID_PREFIXES = [
|
|
5
|
+
[6, 161, 159], // tz1 (ed25519)
|
|
6
|
+
[6, 161, 161], // tz2 (secp256k1)
|
|
7
|
+
[6, 161, 164], // tz3 (p256)
|
|
8
|
+
[2, 90, 121], // KT1 (originated)
|
|
9
|
+
];
|
|
5
10
|
function decodeRaw(buffer) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
const payload = buffer.slice(0, -4);
|
|
12
|
+
const checksum = buffer.slice(-4);
|
|
13
|
+
const newChecksum = cryptoUtils.hexStr2byteArray(cryptoUtils.sha256x2(cryptoUtils.byteArray2hexStr(payload)));
|
|
9
14
|
if (checksum[0] ^ newChecksum[0] |
|
|
10
15
|
checksum[1] ^ newChecksum[1] |
|
|
11
16
|
checksum[2] ^ newChecksum[2] |
|
|
@@ -13,17 +18,19 @@ function decodeRaw(buffer) {
|
|
|
13
18
|
return;
|
|
14
19
|
return payload;
|
|
15
20
|
}
|
|
21
|
+
function hasValidPrefix(payload) {
|
|
22
|
+
return VALID_PREFIXES.some(prefix => prefix.every((byte, i) => payload[i] === byte));
|
|
23
|
+
}
|
|
16
24
|
export default {
|
|
17
25
|
isValidAddress(address) {
|
|
18
26
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
const buffer = base58.decode(getAddress(address));
|
|
28
|
+
const payload = decodeRaw(buffer);
|
|
21
29
|
if (!payload)
|
|
22
30
|
return false;
|
|
23
|
-
payload
|
|
24
|
-
return true;
|
|
31
|
+
return hasValidPrefix(payload);
|
|
25
32
|
}
|
|
26
|
-
catch
|
|
33
|
+
catch {
|
|
27
34
|
return false;
|
|
28
35
|
}
|
|
29
36
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multichain-address-validator",
|
|
3
3
|
"description": "Multichain address validator for Bitcoin and other blockchains.",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.4",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"0x",
|
|
7
7
|
"zrx",
|
|
@@ -343,7 +343,7 @@
|
|
|
343
343
|
"build:cjs": "tsc -p tsconfig.cjs.json && echo '{\"type\": \"commonjs\"}' > dist/cjs/package.json",
|
|
344
344
|
"build": "npm run clean && npm run build:esm && npm run build:cjs",
|
|
345
345
|
"clean": "npx rimraf dist",
|
|
346
|
-
"test": "mocha --import=tsx test
|
|
346
|
+
"test": "mocha --import=tsx --recursive 'test/**/*.test.ts'",
|
|
347
347
|
"start": "npm run build && npm test",
|
|
348
348
|
"release": "node scripts/release.mjs"
|
|
349
349
|
},
|
|
@@ -352,8 +352,7 @@
|
|
|
352
352
|
"base-x": "5.0.1",
|
|
353
353
|
"buffer": "6.0.3",
|
|
354
354
|
"cbor-js": "0.1.0",
|
|
355
|
-
"crc": "4.3.2"
|
|
356
|
-
"lodash.isequal": "4.5.0"
|
|
355
|
+
"crc": "4.3.2"
|
|
357
356
|
},
|
|
358
357
|
"devDependencies": {
|
|
359
358
|
"chai": "6.2.2",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export default Blake2b;
|
|
2
|
-
declare function Blake2b(outlen: any, key: any, salt: any, personal: any): void;
|
|
3
|
-
declare class Blake2b {
|
|
4
|
-
constructor(outlen: any, key: any, salt: any, personal: any);
|
|
5
|
-
b: Uint8Array<ArrayBuffer>;
|
|
6
|
-
h: Uint32Array<ArrayBuffer>;
|
|
7
|
-
t: number;
|
|
8
|
-
c: number;
|
|
9
|
-
outlen: any;
|
|
10
|
-
update(input: any): this;
|
|
11
|
-
digest(out: any): any;
|
|
12
|
-
final: any;
|
|
13
|
-
}
|
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
/**
|
|
4
|
-
* Credits to https://github.com/emilbayes/blake2b
|
|
5
|
-
*
|
|
6
|
-
* Copyright (c) 2017, Emil Bay github@tixz.dk
|
|
7
|
-
*
|
|
8
|
-
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
9
|
-
*
|
|
10
|
-
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
11
|
-
*/
|
|
12
|
-
// 64-bit unsigned addition
|
|
13
|
-
// Sets v[a,a+1] += v[b,b+1]
|
|
14
|
-
// v should be a Uint32Array
|
|
15
|
-
function ADD64AA(v, a, b) {
|
|
16
|
-
var o0 = v[a] + v[b];
|
|
17
|
-
var o1 = v[a + 1] + v[b + 1];
|
|
18
|
-
if (o0 >= 0x100000000) {
|
|
19
|
-
o1++;
|
|
20
|
-
}
|
|
21
|
-
v[a] = o0;
|
|
22
|
-
v[a + 1] = o1;
|
|
23
|
-
}
|
|
24
|
-
// 64-bit unsigned addition
|
|
25
|
-
// Sets v[a,a+1] += b
|
|
26
|
-
// b0 is the low 32 bits of b, b1 represents the high 32 bits
|
|
27
|
-
function ADD64AC(v, a, b0, b1) {
|
|
28
|
-
var o0 = v[a] + b0;
|
|
29
|
-
if (b0 < 0) {
|
|
30
|
-
o0 += 0x100000000;
|
|
31
|
-
}
|
|
32
|
-
var o1 = v[a + 1] + b1;
|
|
33
|
-
if (o0 >= 0x100000000) {
|
|
34
|
-
o1++;
|
|
35
|
-
}
|
|
36
|
-
v[a] = o0;
|
|
37
|
-
v[a + 1] = o1;
|
|
38
|
-
}
|
|
39
|
-
// Little-endian byte access
|
|
40
|
-
function B2B_GET32(arr, i) {
|
|
41
|
-
return (arr[i] ^
|
|
42
|
-
(arr[i + 1] << 8) ^
|
|
43
|
-
(arr[i + 2] << 16) ^
|
|
44
|
-
(arr[i + 3] << 24));
|
|
45
|
-
}
|
|
46
|
-
// G Mixing function
|
|
47
|
-
// The ROTRs are inlined for speed
|
|
48
|
-
function B2B_G(a, b, c, d, ix, iy) {
|
|
49
|
-
var x0 = m[ix];
|
|
50
|
-
var x1 = m[ix + 1];
|
|
51
|
-
var y0 = m[iy];
|
|
52
|
-
var y1 = m[iy + 1];
|
|
53
|
-
ADD64AA(v, a, b); // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
|
|
54
|
-
ADD64AC(v, a, x0, x1); // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits
|
|
55
|
-
// v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
|
|
56
|
-
var xor0 = v[d] ^ v[a];
|
|
57
|
-
var xor1 = v[d + 1] ^ v[a + 1];
|
|
58
|
-
v[d] = xor1;
|
|
59
|
-
v[d + 1] = xor0;
|
|
60
|
-
ADD64AA(v, c, d);
|
|
61
|
-
// v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits
|
|
62
|
-
xor0 = v[b] ^ v[c];
|
|
63
|
-
xor1 = v[b + 1] ^ v[c + 1];
|
|
64
|
-
v[b] = (xor0 >>> 24) ^ (xor1 << 8);
|
|
65
|
-
v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8);
|
|
66
|
-
ADD64AA(v, a, b);
|
|
67
|
-
ADD64AC(v, a, y0, y1);
|
|
68
|
-
// v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
|
|
69
|
-
xor0 = v[d] ^ v[a];
|
|
70
|
-
xor1 = v[d + 1] ^ v[a + 1];
|
|
71
|
-
v[d] = (xor0 >>> 16) ^ (xor1 << 16);
|
|
72
|
-
v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16);
|
|
73
|
-
ADD64AA(v, c, d);
|
|
74
|
-
// v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
|
|
75
|
-
xor0 = v[b] ^ v[c];
|
|
76
|
-
xor1 = v[b + 1] ^ v[c + 1];
|
|
77
|
-
v[b] = (xor1 >>> 31) ^ (xor0 << 1);
|
|
78
|
-
v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1);
|
|
79
|
-
}
|
|
80
|
-
// Initialization Vector
|
|
81
|
-
var BLAKE2B_IV32 = new Uint32Array([
|
|
82
|
-
0xF3BCC908, 0x6A09E667, 0x84CAA73B, 0xBB67AE85,
|
|
83
|
-
0xFE94F82B, 0x3C6EF372, 0x5F1D36F1, 0xA54FF53A,
|
|
84
|
-
0xADE682D1, 0x510E527F, 0x2B3E6C1F, 0x9B05688C,
|
|
85
|
-
0xFB41BD6B, 0x1F83D9AB, 0x137E2179, 0x5BE0CD19
|
|
86
|
-
]);
|
|
87
|
-
var SIGMA8 = [
|
|
88
|
-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
89
|
-
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
|
90
|
-
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
|
|
91
|
-
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
|
|
92
|
-
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
|
|
93
|
-
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
|
94
|
-
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
|
95
|
-
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
|
96
|
-
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
|
97
|
-
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
|
|
98
|
-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
99
|
-
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
|
|
100
|
-
];
|
|
101
|
-
// These are offsets into a uint64 buffer.
|
|
102
|
-
// Multiply them all by 2 to make them offsets into a uint32 buffer,
|
|
103
|
-
// because this is Javascript and we don't have uint64s
|
|
104
|
-
var SIGMA82 = new Uint8Array(SIGMA8.map(function (x) { return x * 2; }));
|
|
105
|
-
// Compression function. 'last' flag indicates last block.
|
|
106
|
-
// Note we're representing 16 uint64s as 32 uint32s
|
|
107
|
-
var v = new Uint32Array(32);
|
|
108
|
-
var m = new Uint32Array(32);
|
|
109
|
-
function blake2bCompress(ctx, last) {
|
|
110
|
-
var i = 0;
|
|
111
|
-
// init work variables
|
|
112
|
-
for (i = 0; i < 16; i++) {
|
|
113
|
-
v[i] = ctx.h[i];
|
|
114
|
-
v[i + 16] = BLAKE2B_IV32[i];
|
|
115
|
-
}
|
|
116
|
-
// low 64 bits of offset
|
|
117
|
-
v[24] = v[24] ^ ctx.t;
|
|
118
|
-
v[25] = v[25] ^ (ctx.t / 0x100000000);
|
|
119
|
-
// high 64 bits not supported, offset may not be higher than 2**53-1
|
|
120
|
-
// last block flag set ?
|
|
121
|
-
if (last) {
|
|
122
|
-
v[28] = ~v[28];
|
|
123
|
-
v[29] = ~v[29];
|
|
124
|
-
}
|
|
125
|
-
// get little-endian words
|
|
126
|
-
for (i = 0; i < 32; i++) {
|
|
127
|
-
m[i] = B2B_GET32(ctx.b, 4 * i);
|
|
128
|
-
}
|
|
129
|
-
// twelve rounds of mixing
|
|
130
|
-
for (i = 0; i < 12; i++) {
|
|
131
|
-
B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]);
|
|
132
|
-
B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]);
|
|
133
|
-
B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]);
|
|
134
|
-
B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]);
|
|
135
|
-
B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]);
|
|
136
|
-
B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]);
|
|
137
|
-
B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]);
|
|
138
|
-
B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]);
|
|
139
|
-
}
|
|
140
|
-
for (i = 0; i < 16; i++) {
|
|
141
|
-
ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16];
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// reusable parameter_block
|
|
145
|
-
var parameter_block = new Uint8Array([
|
|
146
|
-
0, 0, 0, 0, // 0: outlen, keylen, fanout, depth
|
|
147
|
-
0, 0, 0, 0, // 4: leaf length, sequential mode
|
|
148
|
-
0, 0, 0, 0, // 8: node offset
|
|
149
|
-
0, 0, 0, 0, // 12: node offset
|
|
150
|
-
0, 0, 0, 0, // 16: node depth, inner length, rfu
|
|
151
|
-
0, 0, 0, 0, // 20: rfu
|
|
152
|
-
0, 0, 0, 0, // 24: rfu
|
|
153
|
-
0, 0, 0, 0, // 28: rfu
|
|
154
|
-
0, 0, 0, 0, // 32: salt
|
|
155
|
-
0, 0, 0, 0, // 36: salt
|
|
156
|
-
0, 0, 0, 0, // 40: salt
|
|
157
|
-
0, 0, 0, 0, // 44: salt
|
|
158
|
-
0, 0, 0, 0, // 48: personal
|
|
159
|
-
0, 0, 0, 0, // 52: personal
|
|
160
|
-
0, 0, 0, 0, // 56: personal
|
|
161
|
-
0, 0, 0, 0 // 60: personal
|
|
162
|
-
]);
|
|
163
|
-
// Creates a BLAKE2b hashing context
|
|
164
|
-
// Requires an output length between 1 and 64 bytes
|
|
165
|
-
// Takes an optional Uint8Array key
|
|
166
|
-
function Blake2b(outlen, key, salt, personal) {
|
|
167
|
-
// zero out parameter_block before usage
|
|
168
|
-
parameter_block.fill(0);
|
|
169
|
-
// state, 'param block'
|
|
170
|
-
this.b = new Uint8Array(128);
|
|
171
|
-
this.h = new Uint32Array(16);
|
|
172
|
-
this.t = 0; // input count
|
|
173
|
-
this.c = 0; // pointer within buffer
|
|
174
|
-
this.outlen = outlen; // output length in bytes
|
|
175
|
-
parameter_block[0] = outlen;
|
|
176
|
-
if (key)
|
|
177
|
-
parameter_block[1] = key.length;
|
|
178
|
-
parameter_block[2] = 1; // fanout
|
|
179
|
-
parameter_block[3] = 1; // depth
|
|
180
|
-
if (salt)
|
|
181
|
-
parameter_block.set(salt, 32);
|
|
182
|
-
if (personal)
|
|
183
|
-
parameter_block.set(personal, 48);
|
|
184
|
-
// initialize hash state
|
|
185
|
-
for (var i = 0; i < 16; i++) {
|
|
186
|
-
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4);
|
|
187
|
-
}
|
|
188
|
-
// key the hash, if applicable
|
|
189
|
-
if (key) {
|
|
190
|
-
blake2bUpdate(this, key);
|
|
191
|
-
// at the end
|
|
192
|
-
this.c = 128;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
Blake2b.prototype.update = function (input) {
|
|
196
|
-
blake2bUpdate(this, input);
|
|
197
|
-
return this;
|
|
198
|
-
};
|
|
199
|
-
Blake2b.prototype.digest = function (out) {
|
|
200
|
-
var buf = (!out || out === 'binary' || out === 'hex') ? new Uint8Array(this.outlen) : out;
|
|
201
|
-
blake2bFinal(this, buf);
|
|
202
|
-
if (out === 'hex')
|
|
203
|
-
return hexSlice(buf);
|
|
204
|
-
return buf;
|
|
205
|
-
};
|
|
206
|
-
Blake2b.prototype.final = Blake2b.prototype.digest;
|
|
207
|
-
// Updates a BLAKE2b streaming hash
|
|
208
|
-
// Requires hash context and Uint8Array (byte array)
|
|
209
|
-
function blake2bUpdate(ctx, input) {
|
|
210
|
-
for (var i = 0; i < input.length; i++) {
|
|
211
|
-
if (ctx.c === 128) { // buffer full ?
|
|
212
|
-
ctx.t += ctx.c; // add counters
|
|
213
|
-
blake2bCompress(ctx, false); // compress (not last)
|
|
214
|
-
ctx.c = 0; // counter to zero
|
|
215
|
-
}
|
|
216
|
-
ctx.b[ctx.c++] = input[i];
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
// Completes a BLAKE2b streaming hash
|
|
220
|
-
// Returns a Uint8Array containing the message digest
|
|
221
|
-
function blake2bFinal(ctx, out) {
|
|
222
|
-
ctx.t += ctx.c; // mark last block offset
|
|
223
|
-
while (ctx.c < 128) { // fill up with zeros
|
|
224
|
-
ctx.b[ctx.c++] = 0;
|
|
225
|
-
}
|
|
226
|
-
blake2bCompress(ctx, true); // final block flag = 1
|
|
227
|
-
for (var i = 0; i < ctx.outlen; i++) {
|
|
228
|
-
out[i] = ctx.h[i >> 2] >> (8 * (i & 3));
|
|
229
|
-
}
|
|
230
|
-
return out;
|
|
231
|
-
}
|
|
232
|
-
function hexSlice(buf) {
|
|
233
|
-
var str = '';
|
|
234
|
-
for (var i = 0; i < buf.length; i++)
|
|
235
|
-
str += toHex(buf[i]);
|
|
236
|
-
return str;
|
|
237
|
-
}
|
|
238
|
-
function toHex(n) {
|
|
239
|
-
if (n < 16)
|
|
240
|
-
return '0' + n.toString(16);
|
|
241
|
-
return n.toString(16);
|
|
242
|
-
}
|
|
243
|
-
exports.default = Blake2b;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export default Blake2b;
|
|
2
|
-
declare function Blake2b(outlen: any, key: any, salt: any, personal: any): void;
|
|
3
|
-
declare class Blake2b {
|
|
4
|
-
constructor(outlen: any, key: any, salt: any, personal: any);
|
|
5
|
-
b: Uint8Array<ArrayBuffer>;
|
|
6
|
-
h: Uint32Array<ArrayBuffer>;
|
|
7
|
-
t: number;
|
|
8
|
-
c: number;
|
|
9
|
-
outlen: any;
|
|
10
|
-
update(input: any): this;
|
|
11
|
-
digest(out: any): any;
|
|
12
|
-
final: any;
|
|
13
|
-
}
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
/**
|
|
3
|
-
* Credits to https://github.com/emilbayes/blake2b
|
|
4
|
-
*
|
|
5
|
-
* Copyright (c) 2017, Emil Bay github@tixz.dk
|
|
6
|
-
*
|
|
7
|
-
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
8
|
-
*
|
|
9
|
-
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
10
|
-
*/
|
|
11
|
-
// 64-bit unsigned addition
|
|
12
|
-
// Sets v[a,a+1] += v[b,b+1]
|
|
13
|
-
// v should be a Uint32Array
|
|
14
|
-
function ADD64AA(v, a, b) {
|
|
15
|
-
var o0 = v[a] + v[b];
|
|
16
|
-
var o1 = v[a + 1] + v[b + 1];
|
|
17
|
-
if (o0 >= 0x100000000) {
|
|
18
|
-
o1++;
|
|
19
|
-
}
|
|
20
|
-
v[a] = o0;
|
|
21
|
-
v[a + 1] = o1;
|
|
22
|
-
}
|
|
23
|
-
// 64-bit unsigned addition
|
|
24
|
-
// Sets v[a,a+1] += b
|
|
25
|
-
// b0 is the low 32 bits of b, b1 represents the high 32 bits
|
|
26
|
-
function ADD64AC(v, a, b0, b1) {
|
|
27
|
-
var o0 = v[a] + b0;
|
|
28
|
-
if (b0 < 0) {
|
|
29
|
-
o0 += 0x100000000;
|
|
30
|
-
}
|
|
31
|
-
var o1 = v[a + 1] + b1;
|
|
32
|
-
if (o0 >= 0x100000000) {
|
|
33
|
-
o1++;
|
|
34
|
-
}
|
|
35
|
-
v[a] = o0;
|
|
36
|
-
v[a + 1] = o1;
|
|
37
|
-
}
|
|
38
|
-
// Little-endian byte access
|
|
39
|
-
function B2B_GET32(arr, i) {
|
|
40
|
-
return (arr[i] ^
|
|
41
|
-
(arr[i + 1] << 8) ^
|
|
42
|
-
(arr[i + 2] << 16) ^
|
|
43
|
-
(arr[i + 3] << 24));
|
|
44
|
-
}
|
|
45
|
-
// G Mixing function
|
|
46
|
-
// The ROTRs are inlined for speed
|
|
47
|
-
function B2B_G(a, b, c, d, ix, iy) {
|
|
48
|
-
var x0 = m[ix];
|
|
49
|
-
var x1 = m[ix + 1];
|
|
50
|
-
var y0 = m[iy];
|
|
51
|
-
var y1 = m[iy + 1];
|
|
52
|
-
ADD64AA(v, a, b); // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
|
|
53
|
-
ADD64AC(v, a, x0, x1); // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits
|
|
54
|
-
// v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
|
|
55
|
-
var xor0 = v[d] ^ v[a];
|
|
56
|
-
var xor1 = v[d + 1] ^ v[a + 1];
|
|
57
|
-
v[d] = xor1;
|
|
58
|
-
v[d + 1] = xor0;
|
|
59
|
-
ADD64AA(v, c, d);
|
|
60
|
-
// v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits
|
|
61
|
-
xor0 = v[b] ^ v[c];
|
|
62
|
-
xor1 = v[b + 1] ^ v[c + 1];
|
|
63
|
-
v[b] = (xor0 >>> 24) ^ (xor1 << 8);
|
|
64
|
-
v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8);
|
|
65
|
-
ADD64AA(v, a, b);
|
|
66
|
-
ADD64AC(v, a, y0, y1);
|
|
67
|
-
// v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
|
|
68
|
-
xor0 = v[d] ^ v[a];
|
|
69
|
-
xor1 = v[d + 1] ^ v[a + 1];
|
|
70
|
-
v[d] = (xor0 >>> 16) ^ (xor1 << 16);
|
|
71
|
-
v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16);
|
|
72
|
-
ADD64AA(v, c, d);
|
|
73
|
-
// v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
|
|
74
|
-
xor0 = v[b] ^ v[c];
|
|
75
|
-
xor1 = v[b + 1] ^ v[c + 1];
|
|
76
|
-
v[b] = (xor1 >>> 31) ^ (xor0 << 1);
|
|
77
|
-
v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1);
|
|
78
|
-
}
|
|
79
|
-
// Initialization Vector
|
|
80
|
-
var BLAKE2B_IV32 = new Uint32Array([
|
|
81
|
-
0xF3BCC908, 0x6A09E667, 0x84CAA73B, 0xBB67AE85,
|
|
82
|
-
0xFE94F82B, 0x3C6EF372, 0x5F1D36F1, 0xA54FF53A,
|
|
83
|
-
0xADE682D1, 0x510E527F, 0x2B3E6C1F, 0x9B05688C,
|
|
84
|
-
0xFB41BD6B, 0x1F83D9AB, 0x137E2179, 0x5BE0CD19
|
|
85
|
-
]);
|
|
86
|
-
var SIGMA8 = [
|
|
87
|
-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
88
|
-
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
|
89
|
-
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
|
|
90
|
-
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
|
|
91
|
-
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
|
|
92
|
-
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
|
93
|
-
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
|
94
|
-
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
|
95
|
-
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
|
96
|
-
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
|
|
97
|
-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
98
|
-
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
|
|
99
|
-
];
|
|
100
|
-
// These are offsets into a uint64 buffer.
|
|
101
|
-
// Multiply them all by 2 to make them offsets into a uint32 buffer,
|
|
102
|
-
// because this is Javascript and we don't have uint64s
|
|
103
|
-
var SIGMA82 = new Uint8Array(SIGMA8.map(function (x) { return x * 2; }));
|
|
104
|
-
// Compression function. 'last' flag indicates last block.
|
|
105
|
-
// Note we're representing 16 uint64s as 32 uint32s
|
|
106
|
-
var v = new Uint32Array(32);
|
|
107
|
-
var m = new Uint32Array(32);
|
|
108
|
-
function blake2bCompress(ctx, last) {
|
|
109
|
-
var i = 0;
|
|
110
|
-
// init work variables
|
|
111
|
-
for (i = 0; i < 16; i++) {
|
|
112
|
-
v[i] = ctx.h[i];
|
|
113
|
-
v[i + 16] = BLAKE2B_IV32[i];
|
|
114
|
-
}
|
|
115
|
-
// low 64 bits of offset
|
|
116
|
-
v[24] = v[24] ^ ctx.t;
|
|
117
|
-
v[25] = v[25] ^ (ctx.t / 0x100000000);
|
|
118
|
-
// high 64 bits not supported, offset may not be higher than 2**53-1
|
|
119
|
-
// last block flag set ?
|
|
120
|
-
if (last) {
|
|
121
|
-
v[28] = ~v[28];
|
|
122
|
-
v[29] = ~v[29];
|
|
123
|
-
}
|
|
124
|
-
// get little-endian words
|
|
125
|
-
for (i = 0; i < 32; i++) {
|
|
126
|
-
m[i] = B2B_GET32(ctx.b, 4 * i);
|
|
127
|
-
}
|
|
128
|
-
// twelve rounds of mixing
|
|
129
|
-
for (i = 0; i < 12; i++) {
|
|
130
|
-
B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]);
|
|
131
|
-
B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]);
|
|
132
|
-
B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]);
|
|
133
|
-
B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]);
|
|
134
|
-
B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]);
|
|
135
|
-
B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]);
|
|
136
|
-
B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]);
|
|
137
|
-
B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]);
|
|
138
|
-
}
|
|
139
|
-
for (i = 0; i < 16; i++) {
|
|
140
|
-
ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16];
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// reusable parameter_block
|
|
144
|
-
var parameter_block = new Uint8Array([
|
|
145
|
-
0, 0, 0, 0, // 0: outlen, keylen, fanout, depth
|
|
146
|
-
0, 0, 0, 0, // 4: leaf length, sequential mode
|
|
147
|
-
0, 0, 0, 0, // 8: node offset
|
|
148
|
-
0, 0, 0, 0, // 12: node offset
|
|
149
|
-
0, 0, 0, 0, // 16: node depth, inner length, rfu
|
|
150
|
-
0, 0, 0, 0, // 20: rfu
|
|
151
|
-
0, 0, 0, 0, // 24: rfu
|
|
152
|
-
0, 0, 0, 0, // 28: rfu
|
|
153
|
-
0, 0, 0, 0, // 32: salt
|
|
154
|
-
0, 0, 0, 0, // 36: salt
|
|
155
|
-
0, 0, 0, 0, // 40: salt
|
|
156
|
-
0, 0, 0, 0, // 44: salt
|
|
157
|
-
0, 0, 0, 0, // 48: personal
|
|
158
|
-
0, 0, 0, 0, // 52: personal
|
|
159
|
-
0, 0, 0, 0, // 56: personal
|
|
160
|
-
0, 0, 0, 0 // 60: personal
|
|
161
|
-
]);
|
|
162
|
-
// Creates a BLAKE2b hashing context
|
|
163
|
-
// Requires an output length between 1 and 64 bytes
|
|
164
|
-
// Takes an optional Uint8Array key
|
|
165
|
-
function Blake2b(outlen, key, salt, personal) {
|
|
166
|
-
// zero out parameter_block before usage
|
|
167
|
-
parameter_block.fill(0);
|
|
168
|
-
// state, 'param block'
|
|
169
|
-
this.b = new Uint8Array(128);
|
|
170
|
-
this.h = new Uint32Array(16);
|
|
171
|
-
this.t = 0; // input count
|
|
172
|
-
this.c = 0; // pointer within buffer
|
|
173
|
-
this.outlen = outlen; // output length in bytes
|
|
174
|
-
parameter_block[0] = outlen;
|
|
175
|
-
if (key)
|
|
176
|
-
parameter_block[1] = key.length;
|
|
177
|
-
parameter_block[2] = 1; // fanout
|
|
178
|
-
parameter_block[3] = 1; // depth
|
|
179
|
-
if (salt)
|
|
180
|
-
parameter_block.set(salt, 32);
|
|
181
|
-
if (personal)
|
|
182
|
-
parameter_block.set(personal, 48);
|
|
183
|
-
// initialize hash state
|
|
184
|
-
for (var i = 0; i < 16; i++) {
|
|
185
|
-
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4);
|
|
186
|
-
}
|
|
187
|
-
// key the hash, if applicable
|
|
188
|
-
if (key) {
|
|
189
|
-
blake2bUpdate(this, key);
|
|
190
|
-
// at the end
|
|
191
|
-
this.c = 128;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
Blake2b.prototype.update = function (input) {
|
|
195
|
-
blake2bUpdate(this, input);
|
|
196
|
-
return this;
|
|
197
|
-
};
|
|
198
|
-
Blake2b.prototype.digest = function (out) {
|
|
199
|
-
var buf = (!out || out === 'binary' || out === 'hex') ? new Uint8Array(this.outlen) : out;
|
|
200
|
-
blake2bFinal(this, buf);
|
|
201
|
-
if (out === 'hex')
|
|
202
|
-
return hexSlice(buf);
|
|
203
|
-
return buf;
|
|
204
|
-
};
|
|
205
|
-
Blake2b.prototype.final = Blake2b.prototype.digest;
|
|
206
|
-
// Updates a BLAKE2b streaming hash
|
|
207
|
-
// Requires hash context and Uint8Array (byte array)
|
|
208
|
-
function blake2bUpdate(ctx, input) {
|
|
209
|
-
for (var i = 0; i < input.length; i++) {
|
|
210
|
-
if (ctx.c === 128) { // buffer full ?
|
|
211
|
-
ctx.t += ctx.c; // add counters
|
|
212
|
-
blake2bCompress(ctx, false); // compress (not last)
|
|
213
|
-
ctx.c = 0; // counter to zero
|
|
214
|
-
}
|
|
215
|
-
ctx.b[ctx.c++] = input[i];
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
// Completes a BLAKE2b streaming hash
|
|
219
|
-
// Returns a Uint8Array containing the message digest
|
|
220
|
-
function blake2bFinal(ctx, out) {
|
|
221
|
-
ctx.t += ctx.c; // mark last block offset
|
|
222
|
-
while (ctx.c < 128) { // fill up with zeros
|
|
223
|
-
ctx.b[ctx.c++] = 0;
|
|
224
|
-
}
|
|
225
|
-
blake2bCompress(ctx, true); // final block flag = 1
|
|
226
|
-
for (var i = 0; i < ctx.outlen; i++) {
|
|
227
|
-
out[i] = ctx.h[i >> 2] >> (8 * (i & 3));
|
|
228
|
-
}
|
|
229
|
-
return out;
|
|
230
|
-
}
|
|
231
|
-
function hexSlice(buf) {
|
|
232
|
-
var str = '';
|
|
233
|
-
for (var i = 0; i < buf.length; i++)
|
|
234
|
-
str += toHex(buf[i]);
|
|
235
|
-
return str;
|
|
236
|
-
}
|
|
237
|
-
function toHex(n) {
|
|
238
|
-
if (n < 16)
|
|
239
|
-
return '0' + n.toString(16);
|
|
240
|
-
return n.toString(16);
|
|
241
|
-
}
|
|
242
|
-
export default Blake2b;
|