@bitgo-beta/blake2b 3.2.1-alpha.53 → 3.2.1-alpha.54
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 +25 -25
- package/example.js +7 -7
- package/index.js +233 -186
- package/package.json +3 -3
- package/test.js +7 -3
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,370 @@
|
|
|
1
|
-
var assert = require('nanoassert')
|
|
2
|
-
var b2wasm = require('@bitgo-beta/blake2b-wasm')
|
|
1
|
+
var assert = require('nanoassert');
|
|
2
|
+
var b2wasm = require('@bitgo-beta/blake2b-wasm');
|
|
3
3
|
|
|
4
4
|
// 64-bit unsigned addition
|
|
5
5
|
// Sets v[a,a+1] += v[b,b+1]
|
|
6
6
|
// v should be a Uint32Array
|
|
7
|
-
function ADD64AA
|
|
8
|
-
var o0 = v[a] + v[b]
|
|
9
|
-
var o1 = v[a + 1] + v[b + 1]
|
|
7
|
+
function ADD64AA(v, a, b) {
|
|
8
|
+
var o0 = v[a] + v[b];
|
|
9
|
+
var o1 = v[a + 1] + v[b + 1];
|
|
10
10
|
if (o0 >= 0x100000000) {
|
|
11
|
-
o1
|
|
11
|
+
o1++;
|
|
12
12
|
}
|
|
13
|
-
v[a] = o0
|
|
14
|
-
v[a + 1] = o1
|
|
13
|
+
v[a] = o0;
|
|
14
|
+
v[a + 1] = o1;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
// 64-bit unsigned addition
|
|
18
18
|
// Sets v[a,a+1] += b
|
|
19
19
|
// b0 is the low 32 bits of b, b1 represents the high 32 bits
|
|
20
|
-
function ADD64AC
|
|
21
|
-
var o0 = v[a] + b0
|
|
20
|
+
function ADD64AC(v, a, b0, b1) {
|
|
21
|
+
var o0 = v[a] + b0;
|
|
22
22
|
if (b0 < 0) {
|
|
23
|
-
o0 += 0x100000000
|
|
23
|
+
o0 += 0x100000000;
|
|
24
24
|
}
|
|
25
|
-
var o1 = v[a + 1] + b1
|
|
25
|
+
var o1 = v[a + 1] + b1;
|
|
26
26
|
if (o0 >= 0x100000000) {
|
|
27
|
-
o1
|
|
27
|
+
o1++;
|
|
28
28
|
}
|
|
29
|
-
v[a] = o0
|
|
30
|
-
v[a + 1] = o1
|
|
29
|
+
v[a] = o0;
|
|
30
|
+
v[a + 1] = o1;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// 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))
|
|
34
|
+
function B2B_GET32(arr, i) {
|
|
35
|
+
return arr[i] ^ (arr[i + 1] << 8) ^ (arr[i + 2] << 16) ^ (arr[i + 3] << 24);
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
// G Mixing function
|
|
42
39
|
// The ROTRs are inlined for speed
|
|
43
|
-
function B2B_G
|
|
44
|
-
var x0 = m[ix]
|
|
45
|
-
var x1 = m[ix + 1]
|
|
46
|
-
var y0 = m[iy]
|
|
47
|
-
var y1 = m[iy + 1]
|
|
40
|
+
function B2B_G(a, b, c, d, ix, iy) {
|
|
41
|
+
var x0 = m[ix];
|
|
42
|
+
var x1 = m[ix + 1];
|
|
43
|
+
var y0 = m[iy];
|
|
44
|
+
var y1 = m[iy + 1];
|
|
48
45
|
|
|
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
|
|
46
|
+
ADD64AA(v, a, b); // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
|
|
47
|
+
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
48
|
|
|
52
49
|
// v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
|
|
53
|
-
var xor0 = v[d] ^ v[a]
|
|
54
|
-
var xor1 = v[d + 1] ^ v[a + 1]
|
|
55
|
-
v[d] = xor1
|
|
56
|
-
v[d + 1] = xor0
|
|
50
|
+
var xor0 = v[d] ^ v[a];
|
|
51
|
+
var xor1 = v[d + 1] ^ v[a + 1];
|
|
52
|
+
v[d] = xor1;
|
|
53
|
+
v[d + 1] = xor0;
|
|
57
54
|
|
|
58
|
-
ADD64AA(v, c, d)
|
|
55
|
+
ADD64AA(v, c, d);
|
|
59
56
|
|
|
60
57
|
// 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)
|
|
58
|
+
xor0 = v[b] ^ v[c];
|
|
59
|
+
xor1 = v[b + 1] ^ v[c + 1];
|
|
60
|
+
v[b] = (xor0 >>> 24) ^ (xor1 << 8);
|
|
61
|
+
v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8);
|
|
65
62
|
|
|
66
|
-
ADD64AA(v, a, b)
|
|
67
|
-
ADD64AC(v, a, y0, y1)
|
|
63
|
+
ADD64AA(v, a, b);
|
|
64
|
+
ADD64AC(v, a, y0, y1);
|
|
68
65
|
|
|
69
66
|
// 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)
|
|
67
|
+
xor0 = v[d] ^ v[a];
|
|
68
|
+
xor1 = v[d + 1] ^ v[a + 1];
|
|
69
|
+
v[d] = (xor0 >>> 16) ^ (xor1 << 16);
|
|
70
|
+
v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16);
|
|
74
71
|
|
|
75
|
-
ADD64AA(v, c, d)
|
|
72
|
+
ADD64AA(v, c, d);
|
|
76
73
|
|
|
77
74
|
// 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)
|
|
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);
|
|
82
79
|
}
|
|
83
80
|
|
|
84
81
|
// Initialization Vector
|
|
85
82
|
var BLAKE2B_IV32 = new Uint32Array([
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
0xFB41BD6B, 0x1F83D9AB, 0x137E2179, 0x5BE0CD19
|
|
90
|
-
])
|
|
83
|
+
0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, 0xade682d1,
|
|
84
|
+
0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19,
|
|
85
|
+
]);
|
|
91
86
|
|
|
92
87
|
var SIGMA8 = [
|
|
93
|
-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
7,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
]
|
|
88
|
+
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,
|
|
89
|
+
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,
|
|
90
|
+
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,
|
|
91
|
+
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,
|
|
92
|
+
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,
|
|
93
|
+
15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
|
94
|
+
];
|
|
106
95
|
|
|
107
96
|
// These are offsets into a uint64 buffer.
|
|
108
97
|
// Multiply them all by 2 to make them offsets into a uint32 buffer,
|
|
109
98
|
// because this is JavaScript and we don't have uint64s
|
|
110
|
-
var SIGMA82 = new Uint8Array(
|
|
99
|
+
var SIGMA82 = new Uint8Array(
|
|
100
|
+
SIGMA8.map(function (x) {
|
|
101
|
+
return x * 2;
|
|
102
|
+
})
|
|
103
|
+
);
|
|
111
104
|
|
|
112
105
|
// Compression function. 'last' flag indicates last block.
|
|
113
106
|
// Note we're representing 16 uint64s as 32 uint32s
|
|
114
|
-
var v = new Uint32Array(32)
|
|
115
|
-
var m = new Uint32Array(32)
|
|
116
|
-
function blake2bCompress
|
|
117
|
-
var i = 0
|
|
107
|
+
var v = new Uint32Array(32);
|
|
108
|
+
var m = new Uint32Array(32);
|
|
109
|
+
function blake2bCompress(ctx, last) {
|
|
110
|
+
var i = 0;
|
|
118
111
|
|
|
119
112
|
// init work variables
|
|
120
113
|
for (i = 0; i < 16; i++) {
|
|
121
|
-
v[i] = ctx.h[i]
|
|
122
|
-
v[i + 16] = BLAKE2B_IV32[i]
|
|
114
|
+
v[i] = ctx.h[i];
|
|
115
|
+
v[i + 16] = BLAKE2B_IV32[i];
|
|
123
116
|
}
|
|
124
117
|
|
|
125
118
|
// low 64 bits of offset
|
|
126
|
-
v[24] = v[24] ^ ctx.t
|
|
127
|
-
v[25] = v[25] ^ (ctx.t / 0x100000000)
|
|
119
|
+
v[24] = v[24] ^ ctx.t;
|
|
120
|
+
v[25] = v[25] ^ (ctx.t / 0x100000000);
|
|
128
121
|
// high 64 bits not supported, offset may not be higher than 2**53-1
|
|
129
122
|
|
|
130
123
|
// last block flag set ?
|
|
131
124
|
if (last) {
|
|
132
|
-
v[28] = ~v[28]
|
|
133
|
-
v[29] = ~v[29]
|
|
125
|
+
v[28] = ~v[28];
|
|
126
|
+
v[29] = ~v[29];
|
|
134
127
|
}
|
|
135
128
|
|
|
136
129
|
// get little-endian words
|
|
137
130
|
for (i = 0; i < 32; i++) {
|
|
138
|
-
m[i] = B2B_GET32(ctx.b, 4 * i)
|
|
131
|
+
m[i] = B2B_GET32(ctx.b, 4 * i);
|
|
139
132
|
}
|
|
140
133
|
|
|
141
134
|
// twelve rounds of mixing
|
|
142
135
|
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])
|
|
136
|
+
B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]);
|
|
137
|
+
B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]);
|
|
138
|
+
B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]);
|
|
139
|
+
B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]);
|
|
140
|
+
B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]);
|
|
141
|
+
B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]);
|
|
142
|
+
B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]);
|
|
143
|
+
B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]);
|
|
151
144
|
}
|
|
152
145
|
|
|
153
146
|
for (i = 0; i < 16; i++) {
|
|
154
|
-
ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16]
|
|
147
|
+
ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16];
|
|
155
148
|
}
|
|
156
149
|
}
|
|
157
150
|
|
|
158
151
|
// reusable parameter_block
|
|
159
152
|
var parameter_block = new Uint8Array([
|
|
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
|
-
|
|
153
|
+
0,
|
|
154
|
+
0,
|
|
155
|
+
0,
|
|
156
|
+
0, // 0: outlen, keylen, fanout, depth
|
|
157
|
+
0,
|
|
158
|
+
0,
|
|
159
|
+
0,
|
|
160
|
+
0, // 4: leaf length, sequential mode
|
|
161
|
+
0,
|
|
162
|
+
0,
|
|
163
|
+
0,
|
|
164
|
+
0, // 8: node offset
|
|
165
|
+
0,
|
|
166
|
+
0,
|
|
167
|
+
0,
|
|
168
|
+
0, // 12: node offset
|
|
169
|
+
0,
|
|
170
|
+
0,
|
|
171
|
+
0,
|
|
172
|
+
0, // 16: node depth, inner length, rfu
|
|
173
|
+
0,
|
|
174
|
+
0,
|
|
175
|
+
0,
|
|
176
|
+
0, // 20: rfu
|
|
177
|
+
0,
|
|
178
|
+
0,
|
|
179
|
+
0,
|
|
180
|
+
0, // 24: rfu
|
|
181
|
+
0,
|
|
182
|
+
0,
|
|
183
|
+
0,
|
|
184
|
+
0, // 28: rfu
|
|
185
|
+
0,
|
|
186
|
+
0,
|
|
187
|
+
0,
|
|
188
|
+
0, // 32: salt
|
|
189
|
+
0,
|
|
190
|
+
0,
|
|
191
|
+
0,
|
|
192
|
+
0, // 36: salt
|
|
193
|
+
0,
|
|
194
|
+
0,
|
|
195
|
+
0,
|
|
196
|
+
0, // 40: salt
|
|
197
|
+
0,
|
|
198
|
+
0,
|
|
199
|
+
0,
|
|
200
|
+
0, // 44: salt
|
|
201
|
+
0,
|
|
202
|
+
0,
|
|
203
|
+
0,
|
|
204
|
+
0, // 48: personal
|
|
205
|
+
0,
|
|
206
|
+
0,
|
|
207
|
+
0,
|
|
208
|
+
0, // 52: personal
|
|
209
|
+
0,
|
|
210
|
+
0,
|
|
211
|
+
0,
|
|
212
|
+
0, // 56: personal
|
|
213
|
+
0,
|
|
214
|
+
0,
|
|
215
|
+
0,
|
|
216
|
+
0, // 60: personal
|
|
217
|
+
]);
|
|
177
218
|
|
|
178
219
|
// Creates a BLAKE2b hashing context
|
|
179
220
|
// Requires an output length between 1 and 64 bytes
|
|
180
221
|
// Takes an optional Uint8Array key
|
|
181
|
-
function Blake2b
|
|
222
|
+
function Blake2b(outlen, key, salt, personal) {
|
|
182
223
|
// zero out parameter_block before usage
|
|
183
|
-
parameter_block.fill(0)
|
|
224
|
+
parameter_block.fill(0);
|
|
184
225
|
// state, 'param block'
|
|
185
226
|
|
|
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
|
|
227
|
+
this.b = new Uint8Array(128);
|
|
228
|
+
this.h = new Uint32Array(16);
|
|
229
|
+
this.t = 0; // input count
|
|
230
|
+
this.c = 0; // pointer within buffer
|
|
231
|
+
this.outlen = outlen; // output length in bytes
|
|
191
232
|
|
|
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
|
|
233
|
+
parameter_block[0] = outlen;
|
|
234
|
+
if (key) parameter_block[1] = key.length;
|
|
235
|
+
parameter_block[2] = 1; // fanout
|
|
236
|
+
parameter_block[3] = 1; // depth
|
|
196
237
|
|
|
197
|
-
if (salt) parameter_block.set(salt, 32)
|
|
198
|
-
if (personal) parameter_block.set(personal, 48)
|
|
238
|
+
if (salt) parameter_block.set(salt, 32);
|
|
239
|
+
if (personal) parameter_block.set(personal, 48);
|
|
199
240
|
|
|
200
241
|
// initialize hash state
|
|
201
242
|
for (var i = 0; i < 16; i++) {
|
|
202
|
-
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4)
|
|
243
|
+
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4);
|
|
203
244
|
}
|
|
204
245
|
|
|
205
246
|
// key the hash, if applicable
|
|
206
247
|
if (key) {
|
|
207
|
-
blake2bUpdate(this, key)
|
|
248
|
+
blake2bUpdate(this, key);
|
|
208
249
|
// at the end
|
|
209
|
-
this.c = 128
|
|
250
|
+
this.c = 128;
|
|
210
251
|
}
|
|
211
252
|
}
|
|
212
253
|
|
|
213
254
|
Blake2b.prototype.update = function (input) {
|
|
214
|
-
assert(input instanceof Uint8Array, 'input must be Uint8Array or Buffer')
|
|
215
|
-
blake2bUpdate(this, input)
|
|
216
|
-
return this
|
|
217
|
-
}
|
|
255
|
+
assert(input instanceof Uint8Array, 'input must be Uint8Array or Buffer');
|
|
256
|
+
blake2bUpdate(this, input);
|
|
257
|
+
return this;
|
|
258
|
+
};
|
|
218
259
|
|
|
219
260
|
Blake2b.prototype.digest = function (out) {
|
|
220
|
-
var buf =
|
|
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
|
-
}
|
|
261
|
+
var buf = !out || out === 'binary' || out === 'hex' ? new Uint8Array(this.outlen) : out;
|
|
262
|
+
assert(buf instanceof Uint8Array, 'out must be "binary", "hex", Uint8Array, or Buffer');
|
|
263
|
+
assert(buf.length >= this.outlen, 'out must have at least outlen bytes of space');
|
|
264
|
+
blake2bFinal(this, buf);
|
|
265
|
+
if (out === 'hex') return hexSlice(buf);
|
|
266
|
+
return buf;
|
|
267
|
+
};
|
|
227
268
|
|
|
228
|
-
Blake2b.prototype.final = Blake2b.prototype.digest
|
|
269
|
+
Blake2b.prototype.final = Blake2b.prototype.digest;
|
|
229
270
|
|
|
230
271
|
Blake2b.ready = function (cb) {
|
|
231
272
|
b2wasm.ready(function () {
|
|
232
|
-
cb() // ignore the error
|
|
233
|
-
})
|
|
234
|
-
}
|
|
273
|
+
cb(); // ignore the error
|
|
274
|
+
});
|
|
275
|
+
};
|
|
235
276
|
|
|
236
277
|
// Updates a BLAKE2b streaming hash
|
|
237
278
|
// Requires hash context and Uint8Array (byte array)
|
|
238
|
-
function blake2bUpdate
|
|
279
|
+
function blake2bUpdate(ctx, input) {
|
|
239
280
|
for (var i = 0; i < input.length; i++) {
|
|
240
|
-
if (ctx.c === 128) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
ctx
|
|
281
|
+
if (ctx.c === 128) {
|
|
282
|
+
// buffer full ?
|
|
283
|
+
ctx.t += ctx.c; // add counters
|
|
284
|
+
blake2bCompress(ctx, false); // compress (not last)
|
|
285
|
+
ctx.c = 0; // counter to zero
|
|
244
286
|
}
|
|
245
|
-
ctx.b[ctx.c++] = input[i]
|
|
287
|
+
ctx.b[ctx.c++] = input[i];
|
|
246
288
|
}
|
|
247
289
|
}
|
|
248
290
|
|
|
249
291
|
// Completes a BLAKE2b streaming hash
|
|
250
292
|
// Returns a Uint8Array containing the message digest
|
|
251
|
-
function blake2bFinal
|
|
252
|
-
ctx.t += ctx.c // mark last block offset
|
|
293
|
+
function blake2bFinal(ctx, out) {
|
|
294
|
+
ctx.t += ctx.c; // mark last block offset
|
|
253
295
|
|
|
254
|
-
while (ctx.c < 128) {
|
|
255
|
-
|
|
296
|
+
while (ctx.c < 128) {
|
|
297
|
+
// fill up with zeros
|
|
298
|
+
ctx.b[ctx.c++] = 0;
|
|
256
299
|
}
|
|
257
|
-
blake2bCompress(ctx, true) // final block flag = 1
|
|
300
|
+
blake2bCompress(ctx, true); // final block flag = 1
|
|
258
301
|
|
|
259
302
|
for (var i = 0; i < ctx.outlen; i++) {
|
|
260
|
-
out[i] = ctx.h[i >> 2] >> (8 * (i & 3))
|
|
303
|
+
out[i] = ctx.h[i >> 2] >> (8 * (i & 3));
|
|
261
304
|
}
|
|
262
|
-
return out
|
|
305
|
+
return out;
|
|
263
306
|
}
|
|
264
307
|
|
|
265
|
-
function hexSlice
|
|
266
|
-
var str = ''
|
|
267
|
-
for (var i = 0; i < buf.length; i++) str += toHex(buf[i])
|
|
268
|
-
return str
|
|
308
|
+
function hexSlice(buf) {
|
|
309
|
+
var str = '';
|
|
310
|
+
for (var i = 0; i < buf.length; i++) str += toHex(buf[i]);
|
|
311
|
+
return str;
|
|
269
312
|
}
|
|
270
313
|
|
|
271
|
-
function toHex
|
|
272
|
-
if (n < 16) return '0' + n.toString(16)
|
|
273
|
-
return n.toString(16)
|
|
314
|
+
function toHex(n) {
|
|
315
|
+
if (n < 16) return '0' + n.toString(16);
|
|
316
|
+
return n.toString(16);
|
|
274
317
|
}
|
|
275
318
|
|
|
276
|
-
var Proto = Blake2b
|
|
319
|
+
var Proto = Blake2b;
|
|
277
320
|
|
|
278
|
-
module.exports = function createHash
|
|
321
|
+
module.exports = function createHash(outlen, key, salt, personal, noAssert) {
|
|
279
322
|
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)
|
|
323
|
+
assert(outlen >= BYTES_MIN, 'outlen must be at least ' + BYTES_MIN + ', was given ' + outlen);
|
|
324
|
+
assert(outlen <= BYTES_MAX, 'outlen must be at most ' + BYTES_MAX + ', was given ' + outlen);
|
|
282
325
|
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)
|
|
326
|
+
assert(key instanceof Uint8Array, 'key must be Uint8Array or Buffer');
|
|
327
|
+
assert(key.length >= KEYBYTES_MIN, 'key must be at least ' + KEYBYTES_MIN + ', was given ' + key.length);
|
|
328
|
+
assert(key.length <= KEYBYTES_MAX, 'key must be at most ' + KEYBYTES_MAX + ', was given ' + key.length);
|
|
286
329
|
}
|
|
287
330
|
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)
|
|
331
|
+
assert(salt instanceof Uint8Array, 'salt must be Uint8Array or Buffer');
|
|
332
|
+
assert(salt.length === SALTBYTES, 'salt must be exactly ' + SALTBYTES + ', was given ' + salt.length);
|
|
290
333
|
}
|
|
291
334
|
if (personal != null) {
|
|
292
|
-
assert(personal instanceof Uint8Array, 'personal must be Uint8Array or Buffer')
|
|
293
|
-
assert(
|
|
335
|
+
assert(personal instanceof Uint8Array, 'personal must be Uint8Array or Buffer');
|
|
336
|
+
assert(
|
|
337
|
+
personal.length === PERSONALBYTES,
|
|
338
|
+
'personal must be exactly ' + PERSONALBYTES + ', was given ' + personal.length
|
|
339
|
+
);
|
|
294
340
|
}
|
|
295
341
|
}
|
|
296
342
|
|
|
297
|
-
return new Proto(outlen, key, salt, personal)
|
|
298
|
-
}
|
|
343
|
+
return new Proto(outlen, key, salt, personal);
|
|
344
|
+
};
|
|
299
345
|
|
|
300
346
|
module.exports.ready = function (cb) {
|
|
301
|
-
b2wasm.ready(function () {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
module.exports.
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
var
|
|
311
|
-
var
|
|
312
|
-
var
|
|
313
|
-
var
|
|
314
|
-
var
|
|
315
|
-
var
|
|
316
|
-
var
|
|
347
|
+
b2wasm.ready(function () {
|
|
348
|
+
// ignore errors
|
|
349
|
+
cb();
|
|
350
|
+
});
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
module.exports.WASM_SUPPORTED = b2wasm.SUPPORTED;
|
|
354
|
+
module.exports.WASM_LOADED = false;
|
|
355
|
+
|
|
356
|
+
var BYTES_MIN = (module.exports.BYTES_MIN = 16);
|
|
357
|
+
var BYTES_MAX = (module.exports.BYTES_MAX = 64);
|
|
358
|
+
var BYTES = (module.exports.BYTES = 32);
|
|
359
|
+
var KEYBYTES_MIN = (module.exports.KEYBYTES_MIN = 16);
|
|
360
|
+
var KEYBYTES_MAX = (module.exports.KEYBYTES_MAX = 64);
|
|
361
|
+
var KEYBYTES = (module.exports.KEYBYTES = 32);
|
|
362
|
+
var SALTBYTES = (module.exports.SALTBYTES = 16);
|
|
363
|
+
var PERSONALBYTES = (module.exports.PERSONALBYTES = 16);
|
|
317
364
|
|
|
318
365
|
b2wasm.ready(function (err) {
|
|
319
366
|
if (!err) {
|
|
320
|
-
module.exports.WASM_LOADED = true
|
|
321
|
-
module.exports = b2wasm
|
|
367
|
+
module.exports.WASM_LOADED = true;
|
|
368
|
+
module.exports = b2wasm;
|
|
322
369
|
}
|
|
323
|
-
})
|
|
370
|
+
});
|
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.54",
|
|
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.54",
|
|
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": "90bd3e274aecafbd5ac5fe37153e764dfe340e94"
|
|
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');
|