multichain-address-validator 0.8.2 → 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.
Files changed (32) hide show
  1. package/README.md +1 -0
  2. package/dist/cjs/chain-validators.js +4 -0
  3. package/dist/cjs/crypto/base32.d.ts +1 -1
  4. package/dist/cjs/crypto/utils.d.ts +5 -5
  5. package/dist/cjs/crypto/utils.js +13 -13
  6. package/dist/cjs/validators/bch_validator.js +49 -15
  7. package/dist/cjs/validators/cardano_validator.js +3 -3
  8. package/dist/cjs/validators/cosmos_validator.d.ts +5 -0
  9. package/dist/cjs/validators/cosmos_validator.js +17 -0
  10. package/dist/cjs/validators/index.d.ts +1 -0
  11. package/dist/cjs/validators/index.js +3 -1
  12. package/dist/cjs/validators/sia_validator.js +1 -9
  13. package/dist/cjs/validators/tezos_validator.js +16 -9
  14. package/dist/cjs/validators/xlm_validator.js +2 -1
  15. package/dist/esm/chain-validators.js +5 -1
  16. package/dist/esm/crypto/base32.d.ts +1 -1
  17. package/dist/esm/crypto/utils.d.ts +5 -5
  18. package/dist/esm/crypto/utils.js +11 -11
  19. package/dist/esm/validators/bch_validator.js +49 -15
  20. package/dist/esm/validators/cardano_validator.js +3 -3
  21. package/dist/esm/validators/cosmos_validator.d.ts +5 -0
  22. package/dist/esm/validators/cosmos_validator.js +12 -0
  23. package/dist/esm/validators/index.d.ts +1 -0
  24. package/dist/esm/validators/index.js +1 -0
  25. package/dist/esm/validators/sia_validator.js +1 -9
  26. package/dist/esm/validators/tezos_validator.js +16 -9
  27. package/dist/esm/validators/xlm_validator.js +2 -1
  28. package/package.json +8 -9
  29. package/dist/cjs/crypto/blake2b.d.ts +0 -13
  30. package/dist/cjs/crypto/blake2b.js +0 -243
  31. package/dist/esm/crypto/blake2b.d.ts +0 -13
  32. package/dist/esm/crypto/blake2b.js +0 -242
@@ -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 !!isEqual(blakeHash, check);
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 prefix = new Uint8Array([6, 161, 159]);
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
- let payload = buffer.slice(0, -4);
7
- let checksum = buffer.slice(-4);
8
- let newChecksum = cryptoUtils.hexStr2byteArray(cryptoUtils.sha256x2(cryptoUtils.byteArray2hexStr(payload)));
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
- let buffer = base58.decode(getAddress(address));
20
- let payload = decodeRaw(buffer);
27
+ const buffer = base58.decode(getAddress(address));
28
+ const payload = decodeRaw(buffer);
21
29
  if (!payload)
22
30
  return false;
23
- payload.slice(prefix.length);
24
- return true;
31
+ return hasValidPrefix(payload);
25
32
  }
26
- catch (e) {
33
+ catch {
27
34
  return false;
28
35
  }
29
36
  }
@@ -1,4 +1,5 @@
1
1
  import baseX from 'base-x';
2
+ import { Buffer } from 'buffer';
2
3
  import crc from 'crc';
3
4
  import cryptoUtils from '../crypto/utils.js';
4
5
  import { getAddress, getMemo } from '../helpers.js';
@@ -34,7 +35,7 @@ export default {
34
35
  if (bytes[0] !== ed25519PublicKeyVersionByte) {
35
36
  return false;
36
37
  }
37
- const computedChecksum = cryptoUtils.numberToHex(swap16(crc.crc16xmodem(bytes.slice(0, -2))), 4);
38
+ const computedChecksum = cryptoUtils.numberToHex(swap16(crc.crc16xmodem(Buffer.from(bytes.slice(0, -2)))), 4);
38
39
  const checksum = cryptoUtils.toHex(bytes.slice(-2));
39
40
  return computedChecksum === checksum;
40
41
  }
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.2",
4
+ "version": "0.8.4",
5
5
  "keywords": [
6
6
  "0x",
7
7
  "zrx",
@@ -343,23 +343,22 @@
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/**.test.ts",
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
  },
350
350
  "dependencies": {
351
- "@noble/hashes": "1.4.0",
352
- "base-x": "4.0.1",
351
+ "@noble/hashes": "2.0.1",
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
- "chai": "4.4.1",
358
+ "chai": "6.2.2",
360
359
  "mocha": "11.7.5",
361
- "tsx": "4.19.4",
362
- "typescript": "5.5.4"
360
+ "tsx": "4.21.0",
361
+ "typescript": "6.0.2"
363
362
  },
364
363
  "overrides": {
365
364
  "serialize-javascript": "7.0.5",
@@ -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;
6
- h: Uint32Array;
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;
6
- h: Uint32Array;
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;