@bitgo-beta/blake2b 3.2.1-alpha.9 → 3.2.1-alpha.90
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/CHANGELOG.md +10 -2
- package/README.md +25 -25
- package/example.js +7 -7
- package/index.js +242 -193
- package/package.json +3 -3
- package/test.js +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,21 +3,29 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
## [3.2.4](https://github.com/BitGo/BitGoJS/compare/@bitgo/blake2b@3.2.2...@bitgo/blake2b@3.2.4) (2023-08-04)
|
|
7
7
|
|
|
8
8
|
**Note:** Version bump only for package @bitgo/blake2b
|
|
9
9
|
|
|
10
|
+
## [3.2.3](https://github.com/BitGo/BitGoJS/compare/@bitgo/blake2b@3.2.2...@bitgo/blake2b@3.2.3) (2023-07-28)
|
|
10
11
|
|
|
12
|
+
**Note:** Version bump only for package @bitgo/blake2b
|
|
11
13
|
|
|
14
|
+
## [3.2.2](https://github.com/BitGo/BitGoJS/compare/@bitgo/blake2b@3.2.1...@bitgo/blake2b@3.2.2) (2023-07-18)
|
|
12
15
|
|
|
16
|
+
**Note:** Version bump only for package @bitgo/blake2b
|
|
13
17
|
|
|
14
|
-
## [3.
|
|
18
|
+
## [3.2.1](https://github.com/BitGo/BitGoJS/compare/@bitgo/blake2b@3.2.0...@bitgo/blake2b@3.2.1) (2022-11-29)
|
|
15
19
|
|
|
16
20
|
**Note:** Version bump only for package @bitgo/blake2b
|
|
17
21
|
|
|
22
|
+
# [3.2.0](https://github.com/BitGo/BitGoJS/compare/@bitgo/blake2b@3.0.3-rc.0...@bitgo/blake2b@3.2.0) (2022-10-18)
|
|
18
23
|
|
|
24
|
+
**Note:** Version bump only for package @bitgo/blake2b
|
|
19
25
|
|
|
26
|
+
## [3.0.3](https://github.com/BitGo/BitGoJS/compare/@bitgo/blake2b@3.0.3-rc.0...@bitgo/blake2b@3.0.3) (2022-07-19)
|
|
20
27
|
|
|
28
|
+
**Note:** Version bump only for package @bitgo/blake2b
|
|
21
29
|
|
|
22
30
|
## [3.0.3-rc.0](https://github.com/BitGo/BitGoJS/compare/@bitgo/blake2b@3.0.2...@bitgo/blake2b@3.0.3-rc.0) (2022-06-07)
|
|
23
31
|
|
package/README.md
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
This module is based on @dcposch
|
|
8
8
|
[implementation of BLAKE2b](https://github.com/dcposch/blakejs), with some changes:
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
- This module requires you to pass in a `out` buffer, saving an allocation
|
|
11
|
+
- This module allows you to set the `salt` and `personal` parameters
|
|
12
|
+
- This module exports constants for the parameters in libsodium style
|
|
13
|
+
- Uses a WASM version (where it is supported) for massive performance boosts
|
|
14
14
|
|
|
15
15
|
All credit goes to @dcposch for doing the hard work of porting the
|
|
16
16
|
implementation from C to JavaScript.
|
|
@@ -18,12 +18,12 @@ implementation from C to JavaScript.
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
20
|
```js
|
|
21
|
-
var blake2b = require('@bitgo/blake2b')
|
|
21
|
+
var blake2b = require('@bitgo/blake2b');
|
|
22
22
|
|
|
23
|
-
var output = new Uint8Array(64)
|
|
24
|
-
var input = Buffer.from('hello world')
|
|
23
|
+
var output = new Uint8Array(64);
|
|
24
|
+
var input = Buffer.from('hello world');
|
|
25
25
|
|
|
26
|
-
console.log('hash:', blake2b(output.length).update(input).digest('hex'))
|
|
26
|
+
console.log('hash:', blake2b(output.length).update(input).digest('hex'));
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## API
|
|
@@ -37,14 +37,14 @@ All parameters must be `Uint8Array`, `Buffer` or another object with a compatibl
|
|
|
37
37
|
API. All parameters must also fulfill the following constraints, or an
|
|
38
38
|
`AssertionError` will be thrown (unless `noAssert = true`):
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
- `outLength` must within the byte ranges defined by the constants below.
|
|
41
|
+
- `key` is optional, but must within the byte ranges defined by the constants
|
|
42
|
+
below, if given. This value must be kept secret, and can be used to create
|
|
43
|
+
prefix-MACs.
|
|
44
|
+
- `salt` is optional, but must be exactly `SALTBYTES`, if given. You can use
|
|
45
45
|
this parameter as a kind of per user id, or local versioning scheme. This
|
|
46
46
|
value is not required to be secret.
|
|
47
|
-
|
|
47
|
+
- `personal` is optional, but must be exactly `PERSONALBYTES`, if given. You can
|
|
48
48
|
use this parameter as a kind of app id, or global versioning scheme. This
|
|
49
49
|
value is not required to be secret.
|
|
50
50
|
|
|
@@ -63,14 +63,14 @@ to have the hash return a new Uint8Array with the hash.
|
|
|
63
63
|
|
|
64
64
|
### Constants
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
- `blake2b.BYTES_MIN` Minimum length of `out`
|
|
67
|
+
- `blake2b.BYTES_MAX` Maximum length of `out`
|
|
68
|
+
- `blake2b.BYTES` Recommended default length of `out`
|
|
69
|
+
- `blake2b.KEYBYTES_MIN` Minimum length of `key`
|
|
70
|
+
- `blake2b.KEYBYTES_MAX` Maximum length of `key`
|
|
71
|
+
- `blake2b.KEYBYTES` Recommended default length of `key`
|
|
72
|
+
- `blake2b.SALTBYTES` Required length of `salt`
|
|
73
|
+
- `blake2b.PERSONALBYTES` Required length of `personal`
|
|
74
74
|
|
|
75
75
|
## Install
|
|
76
76
|
|
|
@@ -84,9 +84,9 @@ This repository includes test vectors with
|
|
|
84
84
|
`{outlen, out, input, key, salt, personal}` objects for testing conformance
|
|
85
85
|
against the spec and other implementations:
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
- Lines [2 - 257](test-vectors.json#L2-L257) are tests for hashing with no key, taken from [BLAKE2 test vectors](https://github.com/BLAKE2/BLAKE2/blob/5cbb39c9ef8007f0b63723e3aea06cd0887e36ad/testvectors/blake2-kat.json)
|
|
88
|
+
- Lines [258 - 513](test-vectors.json#L258-L513) are tests for hashing with keys, taken from [BLAKE2 test vectors](https://github.com/BLAKE2/BLAKE2/blob/5cbb39c9ef8007f0b63723e3aea06cd0887e36ad/testvectors/blake2-kat.json)
|
|
89
|
+
- Lines [514- 577](test-vectors.json#L514-L577) are tests for hashing with key, salt and personalisation, derived from the [libsodium tests](https://github.com/jedisct1/libsodium/blob/3a9c4c38f7dbe671d91dcfa267c919734b4923df/test/default/generichash3.c)
|
|
90
90
|
|
|
91
91
|
## License
|
|
92
92
|
|
package/example.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var blake2b = require('./index.js')
|
|
1
|
+
var blake2b = require('./index.js');
|
|
2
2
|
|
|
3
|
-
var output = new Uint8Array(32)
|
|
4
|
-
var input = Buffer.alloc(2048)
|
|
3
|
+
var output = new Uint8Array(32);
|
|
4
|
+
var input = Buffer.alloc(2048);
|
|
5
5
|
|
|
6
|
-
console.log('hash:', blake2b(output.length).update(input).digest('hex'))
|
|
6
|
+
console.log('hash:', blake2b(output.length).update(input).digest('hex'));
|
|
7
7
|
|
|
8
8
|
blake2b.ready(function () {
|
|
9
|
-
console.log('has wasm?', blake2b.WASM_LOADED)
|
|
10
|
-
console.log('hash again:', blake2b(output.length).update(input).digest('hex'))
|
|
11
|
-
})
|
|
9
|
+
console.log('has wasm?', blake2b.WASM_LOADED);
|
|
10
|
+
console.log('hash again:', blake2b(output.length).update(input).digest('hex'));
|
|
11
|
+
});
|
package/index.js
CHANGED
|
@@ -1,323 +1,372 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const assert = require('nanoassert');
|
|
2
|
+
const b2wasm = require('@bitgo-beta/blake2b-wasm');
|
|
3
|
+
|
|
4
|
+
const BYTES_MIN = (module.exports.BYTES_MIN = 16);
|
|
5
|
+
const BYTES_MAX = (module.exports.BYTES_MAX = 64);
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
|
+
const BYTES = (module.exports.BYTES = 32);
|
|
8
|
+
const KEYBYTES_MIN = (module.exports.KEYBYTES_MIN = 16);
|
|
9
|
+
const KEYBYTES_MAX = (module.exports.KEYBYTES_MAX = 64);
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
11
|
+
const KEYBYTES = (module.exports.KEYBYTES = 32);
|
|
12
|
+
const SALTBYTES = (module.exports.SALTBYTES = 16);
|
|
13
|
+
const PERSONALBYTES = (module.exports.PERSONALBYTES = 16);
|
|
3
14
|
|
|
4
15
|
// 64-bit unsigned addition
|
|
5
16
|
// Sets v[a,a+1] += v[b,b+1]
|
|
6
17
|
// v should be a Uint32Array
|
|
7
|
-
function ADD64AA
|
|
8
|
-
|
|
9
|
-
|
|
18
|
+
function ADD64AA(v, a, b) {
|
|
19
|
+
const o0 = v[a] + v[b];
|
|
20
|
+
let o1 = v[a + 1] + v[b + 1];
|
|
10
21
|
if (o0 >= 0x100000000) {
|
|
11
|
-
o1
|
|
22
|
+
o1++;
|
|
12
23
|
}
|
|
13
|
-
v[a] = o0
|
|
14
|
-
v[a + 1] = o1
|
|
24
|
+
v[a] = o0;
|
|
25
|
+
v[a + 1] = o1;
|
|
15
26
|
}
|
|
16
27
|
|
|
17
28
|
// 64-bit unsigned addition
|
|
18
29
|
// Sets v[a,a+1] += b
|
|
19
30
|
// b0 is the low 32 bits of b, b1 represents the high 32 bits
|
|
20
|
-
function ADD64AC
|
|
21
|
-
|
|
31
|
+
function ADD64AC(v, a, b0, b1) {
|
|
32
|
+
let o0 = v[a] + b0;
|
|
22
33
|
if (b0 < 0) {
|
|
23
|
-
o0 += 0x100000000
|
|
34
|
+
o0 += 0x100000000;
|
|
24
35
|
}
|
|
25
|
-
|
|
36
|
+
let o1 = v[a + 1] + b1;
|
|
26
37
|
if (o0 >= 0x100000000) {
|
|
27
|
-
o1
|
|
38
|
+
o1++;
|
|
28
39
|
}
|
|
29
|
-
v[a] = o0
|
|
30
|
-
v[a + 1] = o1
|
|
40
|
+
v[a] = o0;
|
|
41
|
+
v[a + 1] = o1;
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
// Little-endian byte access
|
|
34
|
-
function B2B_GET32
|
|
35
|
-
return (arr[i] ^
|
|
36
|
-
(arr[i + 1] << 8) ^
|
|
37
|
-
(arr[i + 2] << 16) ^
|
|
38
|
-
(arr[i + 3] << 24))
|
|
45
|
+
function B2B_GET32(arr, i) {
|
|
46
|
+
return arr[i] ^ (arr[i + 1] << 8) ^ (arr[i + 2] << 16) ^ (arr[i + 3] << 24);
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
// G Mixing function
|
|
42
50
|
// The ROTRs are inlined for speed
|
|
43
|
-
function B2B_G
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
function B2B_G(a, b, c, d, ix, iy) {
|
|
52
|
+
const x0 = m[ix];
|
|
53
|
+
const x1 = m[ix + 1];
|
|
54
|
+
const y0 = m[iy];
|
|
55
|
+
const y1 = m[iy + 1];
|
|
48
56
|
|
|
49
|
-
ADD64AA(v, a, b) // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
|
|
50
|
-
ADD64AC(v, a, x0, x1) // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits
|
|
57
|
+
ADD64AA(v, a, b); // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
|
|
58
|
+
ADD64AC(v, a, x0, x1); // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits
|
|
51
59
|
|
|
52
60
|
// v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
v[d] = xor1
|
|
56
|
-
v[d + 1] = xor0
|
|
61
|
+
let xor0 = v[d] ^ v[a];
|
|
62
|
+
let xor1 = v[d + 1] ^ v[a + 1];
|
|
63
|
+
v[d] = xor1;
|
|
64
|
+
v[d + 1] = xor0;
|
|
57
65
|
|
|
58
|
-
ADD64AA(v, c, d)
|
|
66
|
+
ADD64AA(v, c, d);
|
|
59
67
|
|
|
60
68
|
// 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)
|
|
69
|
+
xor0 = v[b] ^ v[c];
|
|
70
|
+
xor1 = v[b + 1] ^ v[c + 1];
|
|
71
|
+
v[b] = (xor0 >>> 24) ^ (xor1 << 8);
|
|
72
|
+
v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8);
|
|
65
73
|
|
|
66
|
-
ADD64AA(v, a, b)
|
|
67
|
-
ADD64AC(v, a, y0, y1)
|
|
74
|
+
ADD64AA(v, a, b);
|
|
75
|
+
ADD64AC(v, a, y0, y1);
|
|
68
76
|
|
|
69
77
|
// v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
|
|
70
|
-
xor0 = v[d] ^ v[a]
|
|
71
|
-
xor1 = v[d + 1] ^ v[a + 1]
|
|
72
|
-
v[d] = (xor0 >>> 16) ^ (xor1 << 16)
|
|
73
|
-
v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16)
|
|
78
|
+
xor0 = v[d] ^ v[a];
|
|
79
|
+
xor1 = v[d + 1] ^ v[a + 1];
|
|
80
|
+
v[d] = (xor0 >>> 16) ^ (xor1 << 16);
|
|
81
|
+
v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16);
|
|
74
82
|
|
|
75
|
-
ADD64AA(v, c, d)
|
|
83
|
+
ADD64AA(v, c, d);
|
|
76
84
|
|
|
77
85
|
// v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
|
|
78
|
-
xor0 = v[b] ^ v[c]
|
|
79
|
-
xor1 = v[b + 1] ^ v[c + 1]
|
|
80
|
-
v[b] = (xor1 >>> 31) ^ (xor0 << 1)
|
|
81
|
-
v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1)
|
|
86
|
+
xor0 = v[b] ^ v[c];
|
|
87
|
+
xor1 = v[b + 1] ^ v[c + 1];
|
|
88
|
+
v[b] = (xor1 >>> 31) ^ (xor0 << 1);
|
|
89
|
+
v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1);
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
// Initialization Vector
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
|
99
|
-
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
|
100
|
-
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
|
101
|
-
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
|
102
|
-
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
|
|
103
|
-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
104
|
-
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
|
|
105
|
-
]
|
|
93
|
+
const BLAKE2B_IV32 = new Uint32Array([
|
|
94
|
+
0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, 0xade682d1,
|
|
95
|
+
0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19,
|
|
96
|
+
]);
|
|
97
|
+
|
|
98
|
+
const SIGMA8 = [
|
|
99
|
+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, 11, 8, 12,
|
|
100
|
+
0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, 9, 0, 5, 7, 2, 4, 10,
|
|
101
|
+
15, 14, 1, 11, 12, 6, 8, 3, 13, 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, 12, 5, 1, 15, 14, 13, 4, 10, 0,
|
|
102
|
+
7, 6, 3, 9, 2, 8, 11, 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7,
|
|
103
|
+
1, 4, 10, 5, 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
104
|
+
15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
|
105
|
+
];
|
|
106
106
|
|
|
107
107
|
// These are offsets into a uint64 buffer.
|
|
108
108
|
// Multiply them all by 2 to make them offsets into a uint32 buffer,
|
|
109
109
|
// because this is JavaScript and we don't have uint64s
|
|
110
|
-
|
|
110
|
+
const SIGMA82 = new Uint8Array(
|
|
111
|
+
SIGMA8.map(function (x) {
|
|
112
|
+
return x * 2;
|
|
113
|
+
})
|
|
114
|
+
);
|
|
111
115
|
|
|
112
116
|
// Compression function. 'last' flag indicates last block.
|
|
113
117
|
// Note we're representing 16 uint64s as 32 uint32s
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
function blake2bCompress
|
|
117
|
-
|
|
118
|
+
const v = new Uint32Array(32);
|
|
119
|
+
const m = new Uint32Array(32);
|
|
120
|
+
function blake2bCompress(ctx, last) {
|
|
121
|
+
let i = 0;
|
|
118
122
|
|
|
119
|
-
// init work
|
|
123
|
+
// init work letiables
|
|
120
124
|
for (i = 0; i < 16; i++) {
|
|
121
|
-
v[i] = ctx.h[i]
|
|
122
|
-
v[i + 16] = BLAKE2B_IV32[i]
|
|
125
|
+
v[i] = ctx.h[i];
|
|
126
|
+
v[i + 16] = BLAKE2B_IV32[i];
|
|
123
127
|
}
|
|
124
128
|
|
|
125
129
|
// low 64 bits of offset
|
|
126
|
-
v[24] = v[24] ^ ctx.t
|
|
127
|
-
v[25] = v[25] ^ (ctx.t / 0x100000000)
|
|
130
|
+
v[24] = v[24] ^ ctx.t;
|
|
131
|
+
v[25] = v[25] ^ (ctx.t / 0x100000000);
|
|
128
132
|
// high 64 bits not supported, offset may not be higher than 2**53-1
|
|
129
133
|
|
|
130
134
|
// last block flag set ?
|
|
131
135
|
if (last) {
|
|
132
|
-
v[28] = ~v[28]
|
|
133
|
-
v[29] = ~v[29]
|
|
136
|
+
v[28] = ~v[28];
|
|
137
|
+
v[29] = ~v[29];
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
// get little-endian words
|
|
137
141
|
for (i = 0; i < 32; i++) {
|
|
138
|
-
m[i] = B2B_GET32(ctx.b, 4 * i)
|
|
142
|
+
m[i] = B2B_GET32(ctx.b, 4 * i);
|
|
139
143
|
}
|
|
140
144
|
|
|
141
145
|
// twelve rounds of mixing
|
|
142
146
|
for (i = 0; i < 12; i++) {
|
|
143
|
-
B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1])
|
|
144
|
-
B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3])
|
|
145
|
-
B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5])
|
|
146
|
-
B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7])
|
|
147
|
-
B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9])
|
|
148
|
-
B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11])
|
|
149
|
-
B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13])
|
|
150
|
-
B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15])
|
|
147
|
+
B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]);
|
|
148
|
+
B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]);
|
|
149
|
+
B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]);
|
|
150
|
+
B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]);
|
|
151
|
+
B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]);
|
|
152
|
+
B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]);
|
|
153
|
+
B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]);
|
|
154
|
+
B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]);
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
for (i = 0; i < 16; i++) {
|
|
154
|
-
ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16]
|
|
158
|
+
ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16];
|
|
155
159
|
}
|
|
156
160
|
}
|
|
157
161
|
|
|
158
162
|
// reusable parameter_block
|
|
159
|
-
|
|
160
|
-
0,
|
|
161
|
-
0,
|
|
162
|
-
0,
|
|
163
|
-
0, 0,
|
|
164
|
-
0,
|
|
165
|
-
0,
|
|
166
|
-
0,
|
|
167
|
-
0,
|
|
168
|
-
0,
|
|
169
|
-
0,
|
|
170
|
-
0,
|
|
171
|
-
0,
|
|
172
|
-
0,
|
|
173
|
-
0,
|
|
174
|
-
0,
|
|
175
|
-
0,
|
|
176
|
-
|
|
163
|
+
const parameter_block = new Uint8Array([
|
|
164
|
+
0,
|
|
165
|
+
0,
|
|
166
|
+
0,
|
|
167
|
+
0, // 0: outlen, keylen, fanout, depth
|
|
168
|
+
0,
|
|
169
|
+
0,
|
|
170
|
+
0,
|
|
171
|
+
0, // 4: leaf length, sequential mode
|
|
172
|
+
0,
|
|
173
|
+
0,
|
|
174
|
+
0,
|
|
175
|
+
0, // 8: node offset
|
|
176
|
+
0,
|
|
177
|
+
0,
|
|
178
|
+
0,
|
|
179
|
+
0, // 12: node offset
|
|
180
|
+
0,
|
|
181
|
+
0,
|
|
182
|
+
0,
|
|
183
|
+
0, // 16: node depth, inner length, rfu
|
|
184
|
+
0,
|
|
185
|
+
0,
|
|
186
|
+
0,
|
|
187
|
+
0, // 20: rfu
|
|
188
|
+
0,
|
|
189
|
+
0,
|
|
190
|
+
0,
|
|
191
|
+
0, // 24: rfu
|
|
192
|
+
0,
|
|
193
|
+
0,
|
|
194
|
+
0,
|
|
195
|
+
0, // 28: rfu
|
|
196
|
+
0,
|
|
197
|
+
0,
|
|
198
|
+
0,
|
|
199
|
+
0, // 32: salt
|
|
200
|
+
0,
|
|
201
|
+
0,
|
|
202
|
+
0,
|
|
203
|
+
0, // 36: salt
|
|
204
|
+
0,
|
|
205
|
+
0,
|
|
206
|
+
0,
|
|
207
|
+
0, // 40: salt
|
|
208
|
+
0,
|
|
209
|
+
0,
|
|
210
|
+
0,
|
|
211
|
+
0, // 44: salt
|
|
212
|
+
0,
|
|
213
|
+
0,
|
|
214
|
+
0,
|
|
215
|
+
0, // 48: personal
|
|
216
|
+
0,
|
|
217
|
+
0,
|
|
218
|
+
0,
|
|
219
|
+
0, // 52: personal
|
|
220
|
+
0,
|
|
221
|
+
0,
|
|
222
|
+
0,
|
|
223
|
+
0, // 56: personal
|
|
224
|
+
0,
|
|
225
|
+
0,
|
|
226
|
+
0,
|
|
227
|
+
0, // 60: personal
|
|
228
|
+
]);
|
|
177
229
|
|
|
178
230
|
// Creates a BLAKE2b hashing context
|
|
179
231
|
// Requires an output length between 1 and 64 bytes
|
|
180
232
|
// Takes an optional Uint8Array key
|
|
181
|
-
function Blake2b
|
|
233
|
+
function Blake2b(outlen, key, salt, personal) {
|
|
182
234
|
// zero out parameter_block before usage
|
|
183
|
-
parameter_block.fill(0)
|
|
235
|
+
parameter_block.fill(0);
|
|
184
236
|
// state, 'param block'
|
|
185
237
|
|
|
186
|
-
this.b = new Uint8Array(128)
|
|
187
|
-
this.h = new Uint32Array(16)
|
|
188
|
-
this.t = 0 // input count
|
|
189
|
-
this.c = 0 // pointer within buffer
|
|
190
|
-
this.outlen = outlen // output length in bytes
|
|
238
|
+
this.b = new Uint8Array(128);
|
|
239
|
+
this.h = new Uint32Array(16);
|
|
240
|
+
this.t = 0; // input count
|
|
241
|
+
this.c = 0; // pointer within buffer
|
|
242
|
+
this.outlen = outlen; // output length in bytes
|
|
191
243
|
|
|
192
|
-
parameter_block[0] = outlen
|
|
193
|
-
if (key) parameter_block[1] = key.length
|
|
194
|
-
parameter_block[2] = 1 // fanout
|
|
195
|
-
parameter_block[3] = 1 // depth
|
|
244
|
+
parameter_block[0] = outlen;
|
|
245
|
+
if (key) parameter_block[1] = key.length;
|
|
246
|
+
parameter_block[2] = 1; // fanout
|
|
247
|
+
parameter_block[3] = 1; // depth
|
|
196
248
|
|
|
197
|
-
if (salt) parameter_block.set(salt, 32)
|
|
198
|
-
if (personal) parameter_block.set(personal, 48)
|
|
249
|
+
if (salt) parameter_block.set(salt, 32);
|
|
250
|
+
if (personal) parameter_block.set(personal, 48);
|
|
199
251
|
|
|
200
252
|
// initialize hash state
|
|
201
|
-
for (
|
|
202
|
-
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4)
|
|
253
|
+
for (let i = 0; i < 16; i++) {
|
|
254
|
+
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4);
|
|
203
255
|
}
|
|
204
256
|
|
|
205
257
|
// key the hash, if applicable
|
|
206
258
|
if (key) {
|
|
207
|
-
blake2bUpdate(this, key)
|
|
259
|
+
blake2bUpdate(this, key);
|
|
208
260
|
// at the end
|
|
209
|
-
this.c = 128
|
|
261
|
+
this.c = 128;
|
|
210
262
|
}
|
|
211
263
|
}
|
|
212
264
|
|
|
213
265
|
Blake2b.prototype.update = function (input) {
|
|
214
|
-
assert(input instanceof Uint8Array, 'input must be Uint8Array or Buffer')
|
|
215
|
-
blake2bUpdate(this, input)
|
|
216
|
-
return this
|
|
217
|
-
}
|
|
266
|
+
assert(input instanceof Uint8Array, 'input must be Uint8Array or Buffer');
|
|
267
|
+
blake2bUpdate(this, input);
|
|
268
|
+
return this;
|
|
269
|
+
};
|
|
218
270
|
|
|
219
271
|
Blake2b.prototype.digest = function (out) {
|
|
220
|
-
|
|
221
|
-
assert(buf instanceof Uint8Array, 'out must be "binary", "hex", Uint8Array, or Buffer')
|
|
222
|
-
assert(buf.length >= this.outlen, 'out must have at least outlen bytes of space')
|
|
223
|
-
blake2bFinal(this, buf)
|
|
224
|
-
if (out === 'hex') return hexSlice(buf)
|
|
225
|
-
return buf
|
|
226
|
-
}
|
|
272
|
+
const buf = !out || out === 'binary' || out === 'hex' ? new Uint8Array(this.outlen) : out;
|
|
273
|
+
assert(buf instanceof Uint8Array, 'out must be "binary", "hex", Uint8Array, or Buffer');
|
|
274
|
+
assert(buf.length >= this.outlen, 'out must have at least outlen bytes of space');
|
|
275
|
+
blake2bFinal(this, buf);
|
|
276
|
+
if (out === 'hex') return hexSlice(buf);
|
|
277
|
+
return buf;
|
|
278
|
+
};
|
|
227
279
|
|
|
228
|
-
Blake2b.prototype.final = Blake2b.prototype.digest
|
|
280
|
+
Blake2b.prototype.final = Blake2b.prototype.digest;
|
|
229
281
|
|
|
230
282
|
Blake2b.ready = function (cb) {
|
|
231
283
|
b2wasm.ready(function () {
|
|
232
|
-
cb() // ignore the error
|
|
233
|
-
})
|
|
234
|
-
}
|
|
284
|
+
cb(); // ignore the error
|
|
285
|
+
});
|
|
286
|
+
};
|
|
235
287
|
|
|
236
288
|
// Updates a BLAKE2b streaming hash
|
|
237
289
|
// Requires hash context and Uint8Array (byte array)
|
|
238
|
-
function blake2bUpdate
|
|
239
|
-
for (
|
|
240
|
-
if (ctx.c === 128) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
ctx
|
|
290
|
+
function blake2bUpdate(ctx, input) {
|
|
291
|
+
for (let i = 0; i < input.length; i++) {
|
|
292
|
+
if (ctx.c === 128) {
|
|
293
|
+
// buffer full ?
|
|
294
|
+
ctx.t += ctx.c; // add counters
|
|
295
|
+
blake2bCompress(ctx, false); // compress (not last)
|
|
296
|
+
ctx.c = 0; // counter to zero
|
|
244
297
|
}
|
|
245
|
-
ctx.b[ctx.c++] = input[i]
|
|
298
|
+
ctx.b[ctx.c++] = input[i];
|
|
246
299
|
}
|
|
247
300
|
}
|
|
248
301
|
|
|
249
302
|
// Completes a BLAKE2b streaming hash
|
|
250
303
|
// Returns a Uint8Array containing the message digest
|
|
251
|
-
function blake2bFinal
|
|
252
|
-
ctx.t += ctx.c // mark last block offset
|
|
304
|
+
function blake2bFinal(ctx, out) {
|
|
305
|
+
ctx.t += ctx.c; // mark last block offset
|
|
253
306
|
|
|
254
|
-
while (ctx.c < 128) {
|
|
255
|
-
|
|
307
|
+
while (ctx.c < 128) {
|
|
308
|
+
// fill up with zeros
|
|
309
|
+
ctx.b[ctx.c++] = 0;
|
|
256
310
|
}
|
|
257
|
-
blake2bCompress(ctx, true) // final block flag = 1
|
|
311
|
+
blake2bCompress(ctx, true); // final block flag = 1
|
|
258
312
|
|
|
259
|
-
for (
|
|
260
|
-
out[i] = ctx.h[i >> 2] >> (8 * (i & 3))
|
|
313
|
+
for (let i = 0; i < ctx.outlen; i++) {
|
|
314
|
+
out[i] = ctx.h[i >> 2] >> (8 * (i & 3));
|
|
261
315
|
}
|
|
262
|
-
return out
|
|
316
|
+
return out;
|
|
263
317
|
}
|
|
264
318
|
|
|
265
|
-
function hexSlice
|
|
266
|
-
|
|
267
|
-
for (
|
|
268
|
-
return str
|
|
319
|
+
function hexSlice(buf) {
|
|
320
|
+
let str = '';
|
|
321
|
+
for (let i = 0; i < buf.length; i++) str += toHex(buf[i]);
|
|
322
|
+
return str;
|
|
269
323
|
}
|
|
270
324
|
|
|
271
|
-
function toHex
|
|
272
|
-
if (n < 16) return '0' + n.toString(16)
|
|
273
|
-
return n.toString(16)
|
|
325
|
+
function toHex(n) {
|
|
326
|
+
if (n < 16) return '0' + n.toString(16);
|
|
327
|
+
return n.toString(16);
|
|
274
328
|
}
|
|
275
329
|
|
|
276
|
-
|
|
330
|
+
const Proto = Blake2b;
|
|
277
331
|
|
|
278
|
-
module.exports = function createHash
|
|
332
|
+
module.exports = function createHash(outlen, key, salt, personal, noAssert) {
|
|
279
333
|
if (noAssert !== true) {
|
|
280
|
-
assert(outlen >= BYTES_MIN, 'outlen must be at least ' + BYTES_MIN + ', was given ' + outlen)
|
|
281
|
-
assert(outlen <= BYTES_MAX, 'outlen must be at most ' + BYTES_MAX + ', was given ' + outlen)
|
|
334
|
+
assert(outlen >= BYTES_MIN, 'outlen must be at least ' + BYTES_MIN + ', was given ' + outlen);
|
|
335
|
+
assert(outlen <= BYTES_MAX, 'outlen must be at most ' + BYTES_MAX + ', was given ' + outlen);
|
|
282
336
|
if (key != null) {
|
|
283
|
-
assert(key instanceof Uint8Array, 'key must be Uint8Array or Buffer')
|
|
284
|
-
assert(key.length >= KEYBYTES_MIN, 'key must be at least ' + KEYBYTES_MIN + ', was given ' + key.length)
|
|
285
|
-
assert(key.length <= KEYBYTES_MAX, 'key must be at most ' + KEYBYTES_MAX + ', was given ' + key.length)
|
|
337
|
+
assert(key instanceof Uint8Array, 'key must be Uint8Array or Buffer');
|
|
338
|
+
assert(key.length >= KEYBYTES_MIN, 'key must be at least ' + KEYBYTES_MIN + ', was given ' + key.length);
|
|
339
|
+
assert(key.length <= KEYBYTES_MAX, 'key must be at most ' + KEYBYTES_MAX + ', was given ' + key.length);
|
|
286
340
|
}
|
|
287
341
|
if (salt != null) {
|
|
288
|
-
assert(salt instanceof Uint8Array, 'salt must be Uint8Array or Buffer')
|
|
289
|
-
assert(salt.length === SALTBYTES, 'salt must be exactly ' + SALTBYTES + ', was given ' + salt.length)
|
|
342
|
+
assert(salt instanceof Uint8Array, 'salt must be Uint8Array or Buffer');
|
|
343
|
+
assert(salt.length === SALTBYTES, 'salt must be exactly ' + SALTBYTES + ', was given ' + salt.length);
|
|
290
344
|
}
|
|
291
345
|
if (personal != null) {
|
|
292
|
-
assert(personal instanceof Uint8Array, 'personal must be Uint8Array or Buffer')
|
|
293
|
-
assert(
|
|
346
|
+
assert(personal instanceof Uint8Array, 'personal must be Uint8Array or Buffer');
|
|
347
|
+
assert(
|
|
348
|
+
personal.length === PERSONALBYTES,
|
|
349
|
+
'personal must be exactly ' + PERSONALBYTES + ', was given ' + personal.length
|
|
350
|
+
);
|
|
294
351
|
}
|
|
295
352
|
}
|
|
296
353
|
|
|
297
|
-
return new Proto(outlen, key, salt, personal)
|
|
298
|
-
}
|
|
354
|
+
return new Proto(outlen, key, salt, personal);
|
|
355
|
+
};
|
|
299
356
|
|
|
300
357
|
module.exports.ready = function (cb) {
|
|
301
|
-
b2wasm.ready(function () {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
module.exports.WASM_SUPPORTED = b2wasm.SUPPORTED
|
|
307
|
-
module.exports.WASM_LOADED = false
|
|
358
|
+
b2wasm.ready(function () {
|
|
359
|
+
// ignore errors
|
|
360
|
+
cb();
|
|
361
|
+
});
|
|
362
|
+
};
|
|
308
363
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
var BYTES = module.exports.BYTES = 32
|
|
312
|
-
var KEYBYTES_MIN = module.exports.KEYBYTES_MIN = 16
|
|
313
|
-
var KEYBYTES_MAX = module.exports.KEYBYTES_MAX = 64
|
|
314
|
-
var KEYBYTES = module.exports.KEYBYTES = 32
|
|
315
|
-
var SALTBYTES = module.exports.SALTBYTES = 16
|
|
316
|
-
var PERSONALBYTES = module.exports.PERSONALBYTES = 16
|
|
364
|
+
module.exports.WASM_SUPPORTED = b2wasm.SUPPORTED;
|
|
365
|
+
module.exports.WASM_LOADED = false;
|
|
317
366
|
|
|
318
367
|
b2wasm.ready(function (err) {
|
|
319
368
|
if (!err) {
|
|
320
|
-
module.exports.WASM_LOADED = true
|
|
321
|
-
module.exports = b2wasm
|
|
369
|
+
module.exports.WASM_LOADED = true;
|
|
370
|
+
module.exports = b2wasm;
|
|
322
371
|
}
|
|
323
|
-
})
|
|
372
|
+
});
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitgo-beta/blake2b",
|
|
3
|
-
"version": "3.2.1-alpha.
|
|
3
|
+
"version": "3.2.1-alpha.90",
|
|
4
4
|
"description": "Blake2b (64-bit version) in pure JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@bitgo-beta/blake2b-wasm": "3.2.1-alpha.
|
|
7
|
+
"@bitgo-beta/blake2b-wasm": "3.2.1-alpha.90",
|
|
8
8
|
"nanoassert": "^2.0.0"
|
|
9
9
|
},
|
|
10
10
|
"publishConfig": {
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"url": "https://github.com/emilbayes/blake2b/issues"
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/emilbayes/blake2b#readme",
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "f2a40747ace18421aadb1e339857e0f5a1fab259"
|
|
32
32
|
}
|
package/test.js
CHANGED
|
@@ -10,7 +10,7 @@ test('wait for ready', function (assert) {
|
|
|
10
10
|
});
|
|
11
11
|
setup();
|
|
12
12
|
|
|
13
|
-
function setup
|
|
13
|
+
function setup() {
|
|
14
14
|
test('vectors', function (assert) {
|
|
15
15
|
for (let i = 0; i < vectors.length; i++) {
|
|
16
16
|
const v = vectors[i];
|
|
@@ -69,7 +69,11 @@ function setup () {
|
|
|
69
69
|
const out = Buffer.alloc(blake2b.BYTES);
|
|
70
70
|
instance.digest(out);
|
|
71
71
|
|
|
72
|
-
t.same(
|
|
72
|
+
t.same(
|
|
73
|
+
out.toString('hex'),
|
|
74
|
+
'405f14acbeeb30396b8030f78e6a84bab0acf08cb1376aa200a500f669f675dc',
|
|
75
|
+
'streaming keyed hash'
|
|
76
|
+
);
|
|
73
77
|
t.end();
|
|
74
78
|
});
|
|
75
79
|
|
|
@@ -103,7 +107,7 @@ function setup () {
|
|
|
103
107
|
});
|
|
104
108
|
}
|
|
105
109
|
|
|
106
|
-
function hexWrite
|
|
110
|
+
function hexWrite(buf, string) {
|
|
107
111
|
// must be an even number of digits
|
|
108
112
|
const strLen = string.length;
|
|
109
113
|
if (strLen % 2 !== 0) throw new TypeError('Invalid hex string');
|