1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | 'use strict'
|
9 |
|
10 | import { Workers } from './workers'
|
11 | import hashjs from 'hash.js'
|
12 |
|
13 | class Hash {}
|
14 |
|
15 | Hash.sha1 = function (buf) {
|
16 | if (!Buffer.isBuffer(buf)) {
|
17 | throw new Error('sha1 hash must be of a buffer')
|
18 | }
|
19 | const Sha1 = hashjs.sha1
|
20 | const hash = new Sha1().update(buf).digest()
|
21 | return Buffer.from(hash)
|
22 | }
|
23 |
|
24 | Hash.sha1.blockSize = 512
|
25 |
|
26 | Hash.asyncSha1 = async function (buf) {
|
27 | const args = [buf]
|
28 | const workersResult = await Workers.asyncClassMethod(Hash, 'sha1', args)
|
29 | return workersResult.resbuf
|
30 | }
|
31 |
|
32 | Hash.sha256 = function (buf) {
|
33 | if (!Buffer.isBuffer(buf)) {
|
34 | throw new Error('sha256 hash must be of a buffer')
|
35 | }
|
36 | const Sha256 = hashjs.sha256
|
37 | const hash = new Sha256().update(buf).digest()
|
38 | return Buffer.from(hash)
|
39 | }
|
40 |
|
41 | Hash.sha256.blockSize = 512
|
42 |
|
43 | Hash.asyncSha256 = async function (buf) {
|
44 | const args = [buf]
|
45 | const workersResult = await Workers.asyncClassMethod(Hash, 'sha256', args)
|
46 | return workersResult.resbuf
|
47 | }
|
48 |
|
49 | Hash.sha256Sha256 = function (buf) {
|
50 | try {
|
51 | return Hash.sha256(Hash.sha256(buf))
|
52 | } catch (e) {
|
53 | throw new Error('sha256Sha256 hash must be of a buffer: ' + e)
|
54 | }
|
55 | }
|
56 |
|
57 | Hash.asyncSha256Sha256 = async function (buf) {
|
58 | const args = [buf]
|
59 | const workersResult = await Workers.asyncClassMethod(
|
60 | Hash,
|
61 | 'sha256Sha256',
|
62 | args
|
63 | )
|
64 | return workersResult.resbuf
|
65 | }
|
66 |
|
67 | Hash.ripemd160 = function (buf) {
|
68 | if (!Buffer.isBuffer(buf)) {
|
69 | throw new Error('ripemd160 hash must be of a buffer')
|
70 | }
|
71 | const Ripemd160 = hashjs.ripemd160
|
72 | const hash = new Ripemd160().update(buf).digest()
|
73 | return Buffer.from(hash)
|
74 | }
|
75 |
|
76 | Hash.asyncRipemd160 = async function (buf) {
|
77 | const args = [buf]
|
78 | const workersResult = await Workers.asyncClassMethod(Hash, 'ripemd160', args)
|
79 | return workersResult.resbuf
|
80 | }
|
81 |
|
82 | Hash.sha256Ripemd160 = function (buf) {
|
83 | try {
|
84 | return Hash.ripemd160(Hash.sha256(buf))
|
85 | } catch (e) {
|
86 | throw new Error('sha256Ripemd160 hash must be of a buffer: ' + e)
|
87 | }
|
88 | }
|
89 |
|
90 | Hash.asyncSha256Ripemd160 = async function (buf) {
|
91 | const args = [buf]
|
92 | const workersResult = await Workers.asyncClassMethod(
|
93 | Hash,
|
94 | 'sha256Ripemd160',
|
95 | args
|
96 | )
|
97 | return workersResult.resbuf
|
98 | }
|
99 |
|
100 | Hash.sha512 = function (buf) {
|
101 | if (!Buffer.isBuffer(buf)) {
|
102 | throw new Error('sha512 hash must be of a buffer')
|
103 | }
|
104 | const Sha512 = hashjs.sha512
|
105 | const hash = new Sha512().update(buf).digest()
|
106 | return Buffer.from(hash)
|
107 | }
|
108 |
|
109 | Hash.asyncSha512 = async function (buf) {
|
110 | const args = [buf]
|
111 | const workersResult = await Workers.asyncClassMethod(Hash, 'sha512', args)
|
112 | return workersResult.resbuf
|
113 | }
|
114 |
|
115 | Hash.sha512.blockSize = 1024
|
116 |
|
117 | Hash.hmac = function (hashFStr, data, key) {
|
118 | if (hashFStr !== 'sha1' && hashFStr !== 'sha256' && hashFStr !== 'sha512') {
|
119 | throw new Error('invalid choice of hash function')
|
120 | }
|
121 |
|
122 | const hashf = Hash[hashFStr]
|
123 |
|
124 | if (!Buffer.isBuffer(data) || !Buffer.isBuffer(key)) {
|
125 | throw new Error('data and key must be buffers')
|
126 | }
|
127 |
|
128 |
|
129 |
|
130 | const blockSize = hashf.blockSize / 8
|
131 |
|
132 | if (key.length > blockSize) {
|
133 | key = hashf(key)
|
134 | }
|
135 |
|
136 | if (key.length < blockSize) {
|
137 | const fill = Buffer.alloc(blockSize)
|
138 | fill.fill(0, key.length)
|
139 | key.copy(fill)
|
140 | key = fill
|
141 | }
|
142 |
|
143 | const oKeyPad = Buffer.alloc(blockSize)
|
144 | const iKeyPad = Buffer.alloc(blockSize)
|
145 | for (let i = 0; i < blockSize; i++) {
|
146 | oKeyPad[i] = 0x5c ^ key[i]
|
147 | iKeyPad[i] = 0x36 ^ key[i]
|
148 | }
|
149 |
|
150 | return hashf(
|
151 | Buffer.concat([oKeyPad, hashf(Buffer.concat([iKeyPad, data]))])
|
152 | )
|
153 | }
|
154 |
|
155 | Hash.sha1Hmac = function (data, key) {
|
156 | return Hash.hmac('sha1', data, key)
|
157 | }
|
158 |
|
159 | Hash.asyncSha1Hmac = async function (data, key) {
|
160 | const args = [data, key]
|
161 | const workersResult = await Workers.asyncClassMethod(Hash, 'sha1Hmac', args)
|
162 | return workersResult.resbuf
|
163 | }
|
164 |
|
165 | Hash.sha1Hmac.bitsize = 160
|
166 |
|
167 | Hash.sha256Hmac = function (data, key) {
|
168 | return Hash.hmac('sha256', data, key)
|
169 | }
|
170 |
|
171 | Hash.asyncSha256Hmac = async function (data, key) {
|
172 | const args = [data, key]
|
173 | const workersResult = await Workers.asyncClassMethod(Hash, 'sha256Hmac', args)
|
174 | return workersResult.resbuf
|
175 | }
|
176 |
|
177 | Hash.sha256Hmac.bitsize = 256
|
178 |
|
179 | Hash.sha512Hmac = function (data, key) {
|
180 | return Hash.hmac('sha512', data, key)
|
181 | }
|
182 |
|
183 | Hash.asyncSha512Hmac = async function (data, key) {
|
184 | const args = [data, key]
|
185 | const workersResult = await Workers.asyncClassMethod(Hash, 'sha512Hmac', args)
|
186 | return workersResult.resbuf
|
187 | }
|
188 |
|
189 | Hash.sha512Hmac.bitsize = 512
|
190 |
|
191 | export { Hash }
|