1 | import { jsSHABase, TWO_PWR_32, H_trunc, H_full, K_sha2, sha_variant_error, parseInputOption } from "./common";
|
2 | import {
|
3 | packedValue,
|
4 | FixedLengthOptionsEncodingType,
|
5 | FixedLengthOptionsNoEncodingType,
|
6 | FormatNoTextType,
|
7 | } from "./custom_types";
|
8 | import { getStrConverter } from "./converters";
|
9 | import {
|
10 | ch_64,
|
11 | gamma0_64,
|
12 | gamma1_64,
|
13 | Int_64,
|
14 | maj_64,
|
15 | safeAdd_64_2,
|
16 | safeAdd_64_4,
|
17 | safeAdd_64_5,
|
18 | sigma0_64,
|
19 | sigma1_64,
|
20 | } from "./primitives_64";
|
21 |
|
22 | type VariantType = "SHA-384" | "SHA-512";
|
23 |
|
24 | const K_sha512 = [
|
25 | new Int_64(K_sha2[0], 0xd728ae22),
|
26 | new Int_64(K_sha2[1], 0x23ef65cd),
|
27 | new Int_64(K_sha2[2], 0xec4d3b2f),
|
28 | new Int_64(K_sha2[3], 0x8189dbbc),
|
29 | new Int_64(K_sha2[4], 0xf348b538),
|
30 | new Int_64(K_sha2[5], 0xb605d019),
|
31 | new Int_64(K_sha2[6], 0xaf194f9b),
|
32 | new Int_64(K_sha2[7], 0xda6d8118),
|
33 | new Int_64(K_sha2[8], 0xa3030242),
|
34 | new Int_64(K_sha2[9], 0x45706fbe),
|
35 | new Int_64(K_sha2[10], 0x4ee4b28c),
|
36 | new Int_64(K_sha2[11], 0xd5ffb4e2),
|
37 | new Int_64(K_sha2[12], 0xf27b896f),
|
38 | new Int_64(K_sha2[13], 0x3b1696b1),
|
39 | new Int_64(K_sha2[14], 0x25c71235),
|
40 | new Int_64(K_sha2[15], 0xcf692694),
|
41 | new Int_64(K_sha2[16], 0x9ef14ad2),
|
42 | new Int_64(K_sha2[17], 0x384f25e3),
|
43 | new Int_64(K_sha2[18], 0x8b8cd5b5),
|
44 | new Int_64(K_sha2[19], 0x77ac9c65),
|
45 | new Int_64(K_sha2[20], 0x592b0275),
|
46 | new Int_64(K_sha2[21], 0x6ea6e483),
|
47 | new Int_64(K_sha2[22], 0xbd41fbd4),
|
48 | new Int_64(K_sha2[23], 0x831153b5),
|
49 | new Int_64(K_sha2[24], 0xee66dfab),
|
50 | new Int_64(K_sha2[25], 0x2db43210),
|
51 | new Int_64(K_sha2[26], 0x98fb213f),
|
52 | new Int_64(K_sha2[27], 0xbeef0ee4),
|
53 | new Int_64(K_sha2[28], 0x3da88fc2),
|
54 | new Int_64(K_sha2[29], 0x930aa725),
|
55 | new Int_64(K_sha2[30], 0xe003826f),
|
56 | new Int_64(K_sha2[31], 0x0a0e6e70),
|
57 | new Int_64(K_sha2[32], 0x46d22ffc),
|
58 | new Int_64(K_sha2[33], 0x5c26c926),
|
59 | new Int_64(K_sha2[34], 0x5ac42aed),
|
60 | new Int_64(K_sha2[35], 0x9d95b3df),
|
61 | new Int_64(K_sha2[36], 0x8baf63de),
|
62 | new Int_64(K_sha2[37], 0x3c77b2a8),
|
63 | new Int_64(K_sha2[38], 0x47edaee6),
|
64 | new Int_64(K_sha2[39], 0x1482353b),
|
65 | new Int_64(K_sha2[40], 0x4cf10364),
|
66 | new Int_64(K_sha2[41], 0xbc423001),
|
67 | new Int_64(K_sha2[42], 0xd0f89791),
|
68 | new Int_64(K_sha2[43], 0x0654be30),
|
69 | new Int_64(K_sha2[44], 0xd6ef5218),
|
70 | new Int_64(K_sha2[45], 0x5565a910),
|
71 | new Int_64(K_sha2[46], 0x5771202a),
|
72 | new Int_64(K_sha2[47], 0x32bbd1b8),
|
73 | new Int_64(K_sha2[48], 0xb8d2d0c8),
|
74 | new Int_64(K_sha2[49], 0x5141ab53),
|
75 | new Int_64(K_sha2[50], 0xdf8eeb99),
|
76 | new Int_64(K_sha2[51], 0xe19b48a8),
|
77 | new Int_64(K_sha2[52], 0xc5c95a63),
|
78 | new Int_64(K_sha2[53], 0xe3418acb),
|
79 | new Int_64(K_sha2[54], 0x7763e373),
|
80 | new Int_64(K_sha2[55], 0xd6b2b8a3),
|
81 | new Int_64(K_sha2[56], 0x5defb2fc),
|
82 | new Int_64(K_sha2[57], 0x43172f60),
|
83 | new Int_64(K_sha2[58], 0xa1f0ab72),
|
84 | new Int_64(K_sha2[59], 0x1a6439ec),
|
85 | new Int_64(K_sha2[60], 0x23631e28),
|
86 | new Int_64(K_sha2[61], 0xde82bde9),
|
87 | new Int_64(K_sha2[62], 0xb2c67915),
|
88 | new Int_64(K_sha2[63], 0xe372532b),
|
89 | new Int_64(0xca273ece, 0xea26619c),
|
90 | new Int_64(0xd186b8c7, 0x21c0c207),
|
91 | new Int_64(0xeada7dd6, 0xcde0eb1e),
|
92 | new Int_64(0xf57d4f7f, 0xee6ed178),
|
93 | new Int_64(0x06f067aa, 0x72176fba),
|
94 | new Int_64(0x0a637dc5, 0xa2c898a6),
|
95 | new Int_64(0x113f9804, 0xbef90dae),
|
96 | new Int_64(0x1b710b35, 0x131c471b),
|
97 | new Int_64(0x28db77f5, 0x23047d84),
|
98 | new Int_64(0x32caab7b, 0x40c72493),
|
99 | new Int_64(0x3c9ebe0a, 0x15c9bebc),
|
100 | new Int_64(0x431d67c4, 0x9c100d4c),
|
101 | new Int_64(0x4cc5d4be, 0xcb3e42b6),
|
102 | new Int_64(0x597f299c, 0xfc657e2a),
|
103 | new Int_64(0x5fcb6fab, 0x3ad6faec),
|
104 | new Int_64(0x6c44198c, 0x4a475817),
|
105 | ];
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 | function getNewState512(variant: VariantType): Int_64[] {
|
114 | if ("SHA-384" === variant) {
|
115 | return [
|
116 | new Int_64(0xcbbb9d5d, H_trunc[0]),
|
117 | new Int_64(0x0629a292a, H_trunc[1]),
|
118 | new Int_64(0x9159015a, H_trunc[2]),
|
119 | new Int_64(0x0152fecd8, H_trunc[3]),
|
120 | new Int_64(0x67332667, H_trunc[4]),
|
121 | new Int_64(0x98eb44a87, H_trunc[5]),
|
122 | new Int_64(0xdb0c2e0d, H_trunc[6]),
|
123 | new Int_64(0x047b5481d, H_trunc[7]),
|
124 | ];
|
125 | } else {
|
126 |
|
127 | return [
|
128 | new Int_64(H_full[0], 0xf3bcc908),
|
129 | new Int_64(H_full[1], 0x84caa73b),
|
130 | new Int_64(H_full[2], 0xfe94f82b),
|
131 | new Int_64(H_full[3], 0x5f1d36f1),
|
132 | new Int_64(H_full[4], 0xade682d1),
|
133 | new Int_64(H_full[5], 0x2b3e6c1f),
|
134 | new Int_64(H_full[6], 0xfb41bd6b),
|
135 | new Int_64(H_full[7], 0x137e2179),
|
136 | ];
|
137 | }
|
138 | }
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 | function roundSHA512(block: number[], H: Int_64[]): Int_64[] {
|
148 | let a, b, c, d, e, f, g, h, T1, T2, t, offset;
|
149 |
|
150 | const W: Int_64[] = [];
|
151 |
|
152 | a = H[0];
|
153 | b = H[1];
|
154 | c = H[2];
|
155 | d = H[3];
|
156 | e = H[4];
|
157 | f = H[5];
|
158 | g = H[6];
|
159 | h = H[7];
|
160 |
|
161 | for (t = 0; t < 80; t += 1) {
|
162 | if (t < 16) {
|
163 | offset = t * 2;
|
164 | W[t] = new Int_64(block[offset], block[offset + 1]);
|
165 | } else {
|
166 | W[t] = safeAdd_64_4(gamma1_64(W[t - 2]), W[t - 7], gamma0_64(W[t - 15]), W[t - 16]);
|
167 | }
|
168 | T1 = safeAdd_64_5(h, sigma1_64(e), ch_64(e, f, g), K_sha512[t], W[t]);
|
169 | T2 = safeAdd_64_2(sigma0_64(a), maj_64(a, b, c));
|
170 | h = g;
|
171 | g = f;
|
172 | f = e;
|
173 | e = safeAdd_64_2(d, T1);
|
174 | d = c;
|
175 | c = b;
|
176 | b = a;
|
177 | a = safeAdd_64_2(T1, T2);
|
178 | }
|
179 |
|
180 | H[0] = safeAdd_64_2(a, H[0]);
|
181 | H[1] = safeAdd_64_2(b, H[1]);
|
182 | H[2] = safeAdd_64_2(c, H[2]);
|
183 | H[3] = safeAdd_64_2(d, H[3]);
|
184 | H[4] = safeAdd_64_2(e, H[4]);
|
185 | H[5] = safeAdd_64_2(f, H[5]);
|
186 | H[6] = safeAdd_64_2(g, H[6]);
|
187 | H[7] = safeAdd_64_2(h, H[7]);
|
188 |
|
189 | return H;
|
190 | }
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 | function finalizeSHA512(
|
203 | remainder: number[],
|
204 | remainderBinLen: number,
|
205 | processedBinLen: number,
|
206 | H: Int_64[],
|
207 | variant: VariantType
|
208 | ): number[] {
|
209 | let i, retVal;
|
210 |
|
211 | |
212 |
|
213 |
|
214 |
|
215 | const offset = (((remainderBinLen + 129) >>> 10) << 5) + 31,
|
216 | binaryStringInc = 32,
|
217 | totalLen = remainderBinLen + processedBinLen;
|
218 |
|
219 | while (remainder.length <= offset) {
|
220 | remainder.push(0);
|
221 | }
|
222 |
|
223 | remainder[remainderBinLen >>> 5] |= 0x80 << (24 - (remainderBinLen % 32));
|
224 | |
225 |
|
226 |
|
227 |
|
228 | remainder[offset] = totalLen & 0xffffffff;
|
229 | |
230 |
|
231 | remainder[offset - 1] = (totalLen / TWO_PWR_32) | 0;
|
232 |
|
233 |
|
234 | for (i = 0; i < remainder.length; i += binaryStringInc) {
|
235 | H = roundSHA512(remainder.slice(i, i + binaryStringInc), H);
|
236 | }
|
237 |
|
238 | if ("SHA-384" === variant) {
|
239 | H = (H as unknown) as Int_64[];
|
240 | retVal = [
|
241 | H[0].highOrder,
|
242 | H[0].lowOrder,
|
243 | H[1].highOrder,
|
244 | H[1].lowOrder,
|
245 | H[2].highOrder,
|
246 | H[2].lowOrder,
|
247 | H[3].highOrder,
|
248 | H[3].lowOrder,
|
249 | H[4].highOrder,
|
250 | H[4].lowOrder,
|
251 | H[5].highOrder,
|
252 | H[5].lowOrder,
|
253 | ];
|
254 | } else {
|
255 |
|
256 | retVal = [
|
257 | H[0].highOrder,
|
258 | H[0].lowOrder,
|
259 | H[1].highOrder,
|
260 | H[1].lowOrder,
|
261 | H[2].highOrder,
|
262 | H[2].lowOrder,
|
263 | H[3].highOrder,
|
264 | H[3].lowOrder,
|
265 | H[4].highOrder,
|
266 | H[4].lowOrder,
|
267 | H[5].highOrder,
|
268 | H[5].lowOrder,
|
269 | H[6].highOrder,
|
270 | H[6].lowOrder,
|
271 | H[7].highOrder,
|
272 | H[7].lowOrder,
|
273 | ];
|
274 | }
|
275 | return retVal;
|
276 | }
|
277 |
|
278 | export default class jsSHA extends jsSHABase<Int_64[], VariantType> {
|
279 | intermediateState: Int_64[];
|
280 | variantBlockSize: number;
|
281 | bigEndianMod: -1 | 1;
|
282 | outputBinLen: number;
|
283 | isVariableLen: boolean;
|
284 | HMACSupported: boolean;
|
285 |
|
286 |
|
287 | converterFunc: (input: any, existingBin: number[], existingBinLen: number) => packedValue;
|
288 | roundFunc: (block: number[], H: Int_64[]) => Int_64[];
|
289 | finalizeFunc: (remainder: number[], remainderBinLen: number, processedBinLen: number, H: Int_64[]) => number[];
|
290 | stateCloneFunc: (state: Int_64[]) => Int_64[];
|
291 | newStateFunc: (variant: VariantType) => Int_64[];
|
292 | getMAC: () => number[];
|
293 |
|
294 | constructor(variant: VariantType, inputFormat: "TEXT", options?: FixedLengthOptionsEncodingType);
|
295 | constructor(variant: VariantType, inputFormat: FormatNoTextType, options?: FixedLengthOptionsNoEncodingType);
|
296 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
297 | constructor(variant: any, inputFormat: any, options?: any) {
|
298 | if (!("SHA-384" === variant || "SHA-512" === variant)) {
|
299 | throw new Error(sha_variant_error);
|
300 | }
|
301 | super(variant, inputFormat, options);
|
302 | const resolvedOptions = options || {};
|
303 |
|
304 |
|
305 | this.getMAC = this._getHMAC;
|
306 | this.HMACSupported = true;
|
307 | this.bigEndianMod = -1;
|
308 | this.converterFunc = getStrConverter(this.inputFormat, this.utfType, this.bigEndianMod);
|
309 | this.roundFunc = roundSHA512;
|
310 | this.stateCloneFunc = function (state): Int_64[] {
|
311 | return state.slice();
|
312 | };
|
313 | this.newStateFunc = getNewState512;
|
314 | this.finalizeFunc = function (remainder, remainderBinLen, processedBinLen, H): number[] {
|
315 | return finalizeSHA512(remainder, remainderBinLen, processedBinLen, H, variant);
|
316 | };
|
317 |
|
318 | this.intermediateState = getNewState512(variant);
|
319 | this.variantBlockSize = 1024;
|
320 | this.outputBinLen = "SHA-384" === variant ? 384 : 512;
|
321 | this.isVariableLen = false;
|
322 |
|
323 | if (resolvedOptions["hmacKey"]) {
|
324 | this._setHMACKey(parseInputOption("hmacKey", resolvedOptions["hmacKey"], this.bigEndianMod));
|
325 | }
|
326 | }
|
327 | }
|