pdf-parser.js 4.8.5 → 4.8.7

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.
@@ -52,112 +52,175 @@ function expandKey(key) {
52
52
  const nk = key.length / 4;
53
53
  const rounds = nk + 6;
54
54
  const words = new Uint32Array(WORDS_PER_BLOCK * (rounds + 1));
55
- for (let i = 0; i < nk; i++) words[i] = (key[4 * i] << 24 | key[4 * i + 1] << 16 | key[4 * i + 2] << 8 | key[4 * i + 3]) >>> 0;
55
+ words.set(Array.from({ length: nk }, (_unused, i) => readWord(key, 4 * i)));
56
56
  let rcon = 1;
57
- for (let i = nk; i < words.length; i++) {
57
+ words.forEach((_word, i) => {
58
+ if (i < nk) return;
58
59
  let temp = words[i - 1];
59
60
  if (i % nk === 0) {
60
61
  temp = (subWord(rotWord(temp)) ^ rcon << 24) >>> 0;
61
62
  rcon = xtime(rcon);
62
63
  } else if (nk > 6 && i % nk === 4) temp = subWord(temp);
63
64
  words[i] = (words[i - nk] ^ temp) >>> 0;
64
- }
65
+ });
65
66
  return {
66
67
  words,
67
68
  rounds
68
69
  };
69
70
  }
70
- function addRoundKey(state, words, round) {
71
- for (let c = 0; c < WORDS_PER_BLOCK; c++) {
72
- const word = words[round * WORDS_PER_BLOCK + c];
73
- for (let r = 0; r < WORDS_PER_BLOCK; r++) state[4 * c + r] = state[4 * c + r] ^ word >>> 24 - r * 8 & 255;
74
- }
71
+ function packWord(row0, row1, row2, row3) {
72
+ return (row0 << 24 | row1 << 16 | row2 << 8 | row3) >>> 0;
73
+ }
74
+ function rotateRight8(word) {
75
+ return (word >>> 8 | word << 24) >>> 0;
75
76
  }
76
- function substituteBytes(state, table) {
77
- for (let i = 0; i < 16; i++) state[i] = table[state[i]];
78
- }
79
- function shiftRows(state, direction) {
80
- const source = Uint8Array.from(state);
81
- for (let r = 1; r < WORDS_PER_BLOCK; r++) for (let c = 0; c < WORDS_PER_BLOCK; c++) state[r + 4 * c] = source[r + 4 * (((c + direction * r) % WORDS_PER_BLOCK + WORDS_PER_BLOCK) % WORDS_PER_BLOCK)];
82
- }
83
- function mixColumns(state, coefficients) {
84
- const [k0, k1, k2, k3] = coefficients;
85
- for (let c = 0; c < WORDS_PER_BLOCK; c++) {
86
- const a0 = state[4 * c];
87
- const a1 = state[4 * c + 1];
88
- const a2 = state[4 * c + 2];
89
- const a3 = state[4 * c + 3];
90
- state[4 * c] = gmul(a0, k0) ^ gmul(a1, k1) ^ gmul(a2, k2) ^ gmul(a3, k3);
91
- state[4 * c + 1] = gmul(a0, k3) ^ gmul(a1, k0) ^ gmul(a2, k1) ^ gmul(a3, k2);
92
- state[4 * c + 2] = gmul(a0, k2) ^ gmul(a1, k3) ^ gmul(a2, k0) ^ gmul(a3, k1);
93
- state[4 * c + 3] = gmul(a0, k1) ^ gmul(a1, k2) ^ gmul(a2, k3) ^ gmul(a3, k0);
77
+ const { TE0, TE1, TE2, TE3, TD0, TD1, TD2, TD3 } = (() => {
78
+ const te0 = /* @__PURE__ */ new Uint32Array(256);
79
+ const te1 = /* @__PURE__ */ new Uint32Array(256);
80
+ const te2 = /* @__PURE__ */ new Uint32Array(256);
81
+ const te3 = /* @__PURE__ */ new Uint32Array(256);
82
+ const td0 = /* @__PURE__ */ new Uint32Array(256);
83
+ const td1 = /* @__PURE__ */ new Uint32Array(256);
84
+ const td2 = /* @__PURE__ */ new Uint32Array(256);
85
+ const td3 = /* @__PURE__ */ new Uint32Array(256);
86
+ for (let x = 0; x < 256; x++) {
87
+ const s = SBOX[x];
88
+ te0[x] = packWord(gmul(s, 2), s, s, gmul(s, 3));
89
+ te1[x] = rotateRight8(te0[x]);
90
+ te2[x] = rotateRight8(te1[x]);
91
+ te3[x] = rotateRight8(te2[x]);
92
+ const i = INV_SBOX[x];
93
+ td0[x] = packWord(gmul(i, 14), gmul(i, 9), gmul(i, 13), gmul(i, 11));
94
+ td1[x] = rotateRight8(td0[x]);
95
+ td2[x] = rotateRight8(td1[x]);
96
+ td3[x] = rotateRight8(td2[x]);
94
97
  }
98
+ return {
99
+ TE0: te0,
100
+ TE1: te1,
101
+ TE2: te2,
102
+ TE3: te3,
103
+ TD0: td0,
104
+ TD1: td1,
105
+ TD2: td2,
106
+ TD3: td3
107
+ };
108
+ })();
109
+ function inverseKeyWords(expanded) {
110
+ const { words, rounds } = expanded;
111
+ return Uint32Array.from(words, (_word, index) => {
112
+ const round = Math.floor(index / WORDS_PER_BLOCK);
113
+ const column = index % WORDS_PER_BLOCK;
114
+ const word = words[(rounds - round) * WORDS_PER_BLOCK + column];
115
+ return round === 0 || round === rounds ? word : TD0[SBOX[word >>> 24]] ^ TD1[SBOX[word >>> 16 & 255]] ^ TD2[SBOX[word >>> 8 & 255]] ^ TD3[SBOX[word & 255]];
116
+ });
95
117
  }
96
- const FORWARD_MIX = [
97
- 2,
98
- 3,
99
- 1,
100
- 1
101
- ];
102
- const INVERSE_MIX = [
103
- 14,
104
- 11,
105
- 13,
106
- 9
107
- ];
108
- function encryptBlock(state, key) {
109
- addRoundKey(state, key.words, 0);
118
+ function readWord(bytes, offset) {
119
+ return packWord(bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3]);
120
+ }
121
+ function writeWord(bytes, offset, word) {
122
+ bytes[offset] = word >>> 24;
123
+ bytes[offset + 1] = word >>> 16 & 255;
124
+ bytes[offset + 2] = word >>> 8 & 255;
125
+ bytes[offset + 3] = word & 255;
126
+ }
127
+ function encryptWords(key, a0, a1, a2, a3, out) {
128
+ const rk = key.words;
129
+ let s0 = a0 ^ rk[0];
130
+ let s1 = a1 ^ rk[1];
131
+ let s2 = a2 ^ rk[2];
132
+ let s3 = a3 ^ rk[3];
110
133
  for (let round = 1; round < key.rounds; round++) {
111
- substituteBytes(state, SBOX);
112
- shiftRows(state, 1);
113
- mixColumns(state, FORWARD_MIX);
114
- addRoundKey(state, key.words, round);
134
+ const at = round * WORDS_PER_BLOCK;
135
+ const t0 = TE0[s0 >>> 24] ^ TE1[s1 >>> 16 & 255] ^ TE2[s2 >>> 8 & 255] ^ TE3[s3 & 255] ^ rk[at];
136
+ const t1 = TE0[s1 >>> 24] ^ TE1[s2 >>> 16 & 255] ^ TE2[s3 >>> 8 & 255] ^ TE3[s0 & 255] ^ rk[at + 1];
137
+ const t2 = TE0[s2 >>> 24] ^ TE1[s3 >>> 16 & 255] ^ TE2[s0 >>> 8 & 255] ^ TE3[s1 & 255] ^ rk[at + 2];
138
+ const t3 = TE0[s3 >>> 24] ^ TE1[s0 >>> 16 & 255] ^ TE2[s1 >>> 8 & 255] ^ TE3[s2 & 255] ^ rk[at + 3];
139
+ s0 = t0;
140
+ s1 = t1;
141
+ s2 = t2;
142
+ s3 = t3;
115
143
  }
116
- substituteBytes(state, SBOX);
117
- shiftRows(state, 1);
118
- addRoundKey(state, key.words, key.rounds);
119
- }
120
- function decryptBlock(state, key) {
121
- addRoundKey(state, key.words, key.rounds);
122
- for (let round = key.rounds - 1; round >= 1; round--) {
123
- shiftRows(state, -1);
124
- substituteBytes(state, INV_SBOX);
125
- addRoundKey(state, key.words, round);
126
- mixColumns(state, INVERSE_MIX);
144
+ const at = key.rounds * WORDS_PER_BLOCK;
145
+ out[0] = packWord(SBOX[s0 >>> 24], SBOX[s1 >>> 16 & 255], SBOX[s2 >>> 8 & 255], SBOX[s3 & 255]) ^ rk[at];
146
+ out[1] = packWord(SBOX[s1 >>> 24], SBOX[s2 >>> 16 & 255], SBOX[s3 >>> 8 & 255], SBOX[s0 & 255]) ^ rk[at + 1];
147
+ out[2] = packWord(SBOX[s2 >>> 24], SBOX[s3 >>> 16 & 255], SBOX[s0 >>> 8 & 255], SBOX[s1 & 255]) ^ rk[at + 2];
148
+ out[3] = packWord(SBOX[s3 >>> 24], SBOX[s0 >>> 16 & 255], SBOX[s1 >>> 8 & 255], SBOX[s2 & 255]) ^ rk[at + 3];
149
+ }
150
+ function decryptWords(rk, rounds, a0, a1, a2, a3, out) {
151
+ let s0 = a0 ^ rk[0];
152
+ let s1 = a1 ^ rk[1];
153
+ let s2 = a2 ^ rk[2];
154
+ let s3 = a3 ^ rk[3];
155
+ for (let round = 1; round < rounds; round++) {
156
+ const at = round * WORDS_PER_BLOCK;
157
+ const t0 = TD0[s0 >>> 24] ^ TD1[s3 >>> 16 & 255] ^ TD2[s2 >>> 8 & 255] ^ TD3[s1 & 255] ^ rk[at];
158
+ const t1 = TD0[s1 >>> 24] ^ TD1[s0 >>> 16 & 255] ^ TD2[s3 >>> 8 & 255] ^ TD3[s2 & 255] ^ rk[at + 1];
159
+ const t2 = TD0[s2 >>> 24] ^ TD1[s1 >>> 16 & 255] ^ TD2[s0 >>> 8 & 255] ^ TD3[s3 & 255] ^ rk[at + 2];
160
+ const t3 = TD0[s3 >>> 24] ^ TD1[s2 >>> 16 & 255] ^ TD2[s1 >>> 8 & 255] ^ TD3[s0 & 255] ^ rk[at + 3];
161
+ s0 = t0;
162
+ s1 = t1;
163
+ s2 = t2;
164
+ s3 = t3;
127
165
  }
128
- shiftRows(state, -1);
129
- substituteBytes(state, INV_SBOX);
130
- addRoundKey(state, key.words, 0);
166
+ const at = rounds * WORDS_PER_BLOCK;
167
+ out[0] = packWord(INV_SBOX[s0 >>> 24], INV_SBOX[s3 >>> 16 & 255], INV_SBOX[s2 >>> 8 & 255], INV_SBOX[s1 & 255]) ^ rk[at];
168
+ out[1] = packWord(INV_SBOX[s1 >>> 24], INV_SBOX[s0 >>> 16 & 255], INV_SBOX[s3 >>> 8 & 255], INV_SBOX[s2 & 255]) ^ rk[at + 1];
169
+ out[2] = packWord(INV_SBOX[s2 >>> 24], INV_SBOX[s1 >>> 16 & 255], INV_SBOX[s0 >>> 8 & 255], INV_SBOX[s3 & 255]) ^ rk[at + 2];
170
+ out[3] = packWord(INV_SBOX[s3 >>> 24], INV_SBOX[s2 >>> 16 & 255], INV_SBOX[s1 >>> 8 & 255], INV_SBOX[s0 & 255]) ^ rk[at + 3];
131
171
  }
132
172
  function wholeBlockCount(byteLength) {
133
173
  return Math.floor(byteLength / 16);
134
174
  }
135
175
  function aesCbcDecrypt(key, iv, data) {
136
176
  const expanded = expandKey(key);
177
+ const inverseKey = inverseKeyWords(expanded);
137
178
  const blocks = wholeBlockCount(data.length);
138
179
  const out = new Uint8Array(blocks * 16);
139
- const chain = Uint8Array.from(iv.subarray(0, 16));
140
- for (let b = 0; b < blocks; b++) {
141
- const cipherBlock = data.subarray(b * 16, (b + 1) * 16);
142
- const state = Uint8Array.from(cipherBlock);
143
- decryptBlock(state, expanded);
144
- for (let i = 0; i < 16; i++) out[b * 16 + i] = state[i] ^ chain[i];
145
- chain.set(cipherBlock);
146
- }
180
+ const plain = new Uint32Array(WORDS_PER_BLOCK);
181
+ let c0 = readWord(iv, 0);
182
+ let c1 = readWord(iv, 4);
183
+ let c2 = readWord(iv, 8);
184
+ let c3 = readWord(iv, 12);
185
+ Array.from({ length: blocks }).forEach((_unused, b) => {
186
+ const at = b * 16;
187
+ const x0 = readWord(data, at);
188
+ const x1 = readWord(data, at + 4);
189
+ const x2 = readWord(data, at + 8);
190
+ const x3 = readWord(data, at + 12);
191
+ decryptWords(inverseKey, expanded.rounds, x0, x1, x2, x3, plain);
192
+ writeWord(out, at, plain[0] ^ c0);
193
+ writeWord(out, at + 4, plain[1] ^ c1);
194
+ writeWord(out, at + 8, plain[2] ^ c2);
195
+ writeWord(out, at + 12, plain[3] ^ c3);
196
+ c0 = x0;
197
+ c1 = x1;
198
+ c2 = x2;
199
+ c3 = x3;
200
+ });
147
201
  return out;
148
202
  }
149
203
  function aesCbcEncrypt(key, iv, data) {
150
204
  const expanded = expandKey(key);
151
205
  const blocks = wholeBlockCount(data.length);
152
206
  const out = new Uint8Array(blocks * 16);
153
- const chain = Uint8Array.from(iv.subarray(0, 16));
154
- for (let b = 0; b < blocks; b++) {
155
- const state = /* @__PURE__ */ new Uint8Array(16);
156
- for (let i = 0; i < 16; i++) state[i] = data[b * 16 + i] ^ chain[i];
157
- encryptBlock(state, expanded);
158
- out.set(state, b * 16);
159
- chain.set(state);
160
- }
207
+ const cipher = new Uint32Array(WORDS_PER_BLOCK);
208
+ let c0 = readWord(iv, 0);
209
+ let c1 = readWord(iv, 4);
210
+ let c2 = readWord(iv, 8);
211
+ let c3 = readWord(iv, 12);
212
+ Array.from({ length: blocks }).forEach((_unused, b) => {
213
+ const at = b * 16;
214
+ encryptWords(expanded, readWord(data, at) ^ c0, readWord(data, at + 4) ^ c1, readWord(data, at + 8) ^ c2, readWord(data, at + 12) ^ c3, cipher);
215
+ c0 = cipher[0];
216
+ c1 = cipher[1];
217
+ c2 = cipher[2];
218
+ c3 = cipher[3];
219
+ writeWord(out, at, c0);
220
+ writeWord(out, at + 4, c1);
221
+ writeWord(out, at + 8, c2);
222
+ writeWord(out, at + 12, c3);
223
+ });
161
224
  return out;
162
225
  }
163
226
  //#endregion
@@ -51,112 +51,175 @@ function expandKey(key) {
51
51
  const nk = key.length / 4;
52
52
  const rounds = nk + 6;
53
53
  const words = new Uint32Array(WORDS_PER_BLOCK * (rounds + 1));
54
- for (let i = 0; i < nk; i++) words[i] = (key[4 * i] << 24 | key[4 * i + 1] << 16 | key[4 * i + 2] << 8 | key[4 * i + 3]) >>> 0;
54
+ words.set(Array.from({ length: nk }, (_unused, i) => readWord(key, 4 * i)));
55
55
  let rcon = 1;
56
- for (let i = nk; i < words.length; i++) {
56
+ words.forEach((_word, i) => {
57
+ if (i < nk) return;
57
58
  let temp = words[i - 1];
58
59
  if (i % nk === 0) {
59
60
  temp = (subWord(rotWord(temp)) ^ rcon << 24) >>> 0;
60
61
  rcon = xtime(rcon);
61
62
  } else if (nk > 6 && i % nk === 4) temp = subWord(temp);
62
63
  words[i] = (words[i - nk] ^ temp) >>> 0;
63
- }
64
+ });
64
65
  return {
65
66
  words,
66
67
  rounds
67
68
  };
68
69
  }
69
- function addRoundKey(state, words, round) {
70
- for (let c = 0; c < WORDS_PER_BLOCK; c++) {
71
- const word = words[round * WORDS_PER_BLOCK + c];
72
- for (let r = 0; r < WORDS_PER_BLOCK; r++) state[4 * c + r] = state[4 * c + r] ^ word >>> 24 - r * 8 & 255;
73
- }
70
+ function packWord(row0, row1, row2, row3) {
71
+ return (row0 << 24 | row1 << 16 | row2 << 8 | row3) >>> 0;
72
+ }
73
+ function rotateRight8(word) {
74
+ return (word >>> 8 | word << 24) >>> 0;
74
75
  }
75
- function substituteBytes(state, table) {
76
- for (let i = 0; i < 16; i++) state[i] = table[state[i]];
77
- }
78
- function shiftRows(state, direction) {
79
- const source = Uint8Array.from(state);
80
- for (let r = 1; r < WORDS_PER_BLOCK; r++) for (let c = 0; c < WORDS_PER_BLOCK; c++) state[r + 4 * c] = source[r + 4 * (((c + direction * r) % WORDS_PER_BLOCK + WORDS_PER_BLOCK) % WORDS_PER_BLOCK)];
81
- }
82
- function mixColumns(state, coefficients) {
83
- const [k0, k1, k2, k3] = coefficients;
84
- for (let c = 0; c < WORDS_PER_BLOCK; c++) {
85
- const a0 = state[4 * c];
86
- const a1 = state[4 * c + 1];
87
- const a2 = state[4 * c + 2];
88
- const a3 = state[4 * c + 3];
89
- state[4 * c] = gmul(a0, k0) ^ gmul(a1, k1) ^ gmul(a2, k2) ^ gmul(a3, k3);
90
- state[4 * c + 1] = gmul(a0, k3) ^ gmul(a1, k0) ^ gmul(a2, k1) ^ gmul(a3, k2);
91
- state[4 * c + 2] = gmul(a0, k2) ^ gmul(a1, k3) ^ gmul(a2, k0) ^ gmul(a3, k1);
92
- state[4 * c + 3] = gmul(a0, k1) ^ gmul(a1, k2) ^ gmul(a2, k3) ^ gmul(a3, k0);
76
+ const { TE0, TE1, TE2, TE3, TD0, TD1, TD2, TD3 } = (() => {
77
+ const te0 = /* @__PURE__ */ new Uint32Array(256);
78
+ const te1 = /* @__PURE__ */ new Uint32Array(256);
79
+ const te2 = /* @__PURE__ */ new Uint32Array(256);
80
+ const te3 = /* @__PURE__ */ new Uint32Array(256);
81
+ const td0 = /* @__PURE__ */ new Uint32Array(256);
82
+ const td1 = /* @__PURE__ */ new Uint32Array(256);
83
+ const td2 = /* @__PURE__ */ new Uint32Array(256);
84
+ const td3 = /* @__PURE__ */ new Uint32Array(256);
85
+ for (let x = 0; x < 256; x++) {
86
+ const s = SBOX[x];
87
+ te0[x] = packWord(gmul(s, 2), s, s, gmul(s, 3));
88
+ te1[x] = rotateRight8(te0[x]);
89
+ te2[x] = rotateRight8(te1[x]);
90
+ te3[x] = rotateRight8(te2[x]);
91
+ const i = INV_SBOX[x];
92
+ td0[x] = packWord(gmul(i, 14), gmul(i, 9), gmul(i, 13), gmul(i, 11));
93
+ td1[x] = rotateRight8(td0[x]);
94
+ td2[x] = rotateRight8(td1[x]);
95
+ td3[x] = rotateRight8(td2[x]);
93
96
  }
97
+ return {
98
+ TE0: te0,
99
+ TE1: te1,
100
+ TE2: te2,
101
+ TE3: te3,
102
+ TD0: td0,
103
+ TD1: td1,
104
+ TD2: td2,
105
+ TD3: td3
106
+ };
107
+ })();
108
+ function inverseKeyWords(expanded) {
109
+ const { words, rounds } = expanded;
110
+ return Uint32Array.from(words, (_word, index) => {
111
+ const round = Math.floor(index / WORDS_PER_BLOCK);
112
+ const column = index % WORDS_PER_BLOCK;
113
+ const word = words[(rounds - round) * WORDS_PER_BLOCK + column];
114
+ return round === 0 || round === rounds ? word : TD0[SBOX[word >>> 24]] ^ TD1[SBOX[word >>> 16 & 255]] ^ TD2[SBOX[word >>> 8 & 255]] ^ TD3[SBOX[word & 255]];
115
+ });
94
116
  }
95
- const FORWARD_MIX = [
96
- 2,
97
- 3,
98
- 1,
99
- 1
100
- ];
101
- const INVERSE_MIX = [
102
- 14,
103
- 11,
104
- 13,
105
- 9
106
- ];
107
- function encryptBlock(state, key) {
108
- addRoundKey(state, key.words, 0);
117
+ function readWord(bytes, offset) {
118
+ return packWord(bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3]);
119
+ }
120
+ function writeWord(bytes, offset, word) {
121
+ bytes[offset] = word >>> 24;
122
+ bytes[offset + 1] = word >>> 16 & 255;
123
+ bytes[offset + 2] = word >>> 8 & 255;
124
+ bytes[offset + 3] = word & 255;
125
+ }
126
+ function encryptWords(key, a0, a1, a2, a3, out) {
127
+ const rk = key.words;
128
+ let s0 = a0 ^ rk[0];
129
+ let s1 = a1 ^ rk[1];
130
+ let s2 = a2 ^ rk[2];
131
+ let s3 = a3 ^ rk[3];
109
132
  for (let round = 1; round < key.rounds; round++) {
110
- substituteBytes(state, SBOX);
111
- shiftRows(state, 1);
112
- mixColumns(state, FORWARD_MIX);
113
- addRoundKey(state, key.words, round);
133
+ const at = round * WORDS_PER_BLOCK;
134
+ const t0 = TE0[s0 >>> 24] ^ TE1[s1 >>> 16 & 255] ^ TE2[s2 >>> 8 & 255] ^ TE3[s3 & 255] ^ rk[at];
135
+ const t1 = TE0[s1 >>> 24] ^ TE1[s2 >>> 16 & 255] ^ TE2[s3 >>> 8 & 255] ^ TE3[s0 & 255] ^ rk[at + 1];
136
+ const t2 = TE0[s2 >>> 24] ^ TE1[s3 >>> 16 & 255] ^ TE2[s0 >>> 8 & 255] ^ TE3[s1 & 255] ^ rk[at + 2];
137
+ const t3 = TE0[s3 >>> 24] ^ TE1[s0 >>> 16 & 255] ^ TE2[s1 >>> 8 & 255] ^ TE3[s2 & 255] ^ rk[at + 3];
138
+ s0 = t0;
139
+ s1 = t1;
140
+ s2 = t2;
141
+ s3 = t3;
114
142
  }
115
- substituteBytes(state, SBOX);
116
- shiftRows(state, 1);
117
- addRoundKey(state, key.words, key.rounds);
118
- }
119
- function decryptBlock(state, key) {
120
- addRoundKey(state, key.words, key.rounds);
121
- for (let round = key.rounds - 1; round >= 1; round--) {
122
- shiftRows(state, -1);
123
- substituteBytes(state, INV_SBOX);
124
- addRoundKey(state, key.words, round);
125
- mixColumns(state, INVERSE_MIX);
143
+ const at = key.rounds * WORDS_PER_BLOCK;
144
+ out[0] = packWord(SBOX[s0 >>> 24], SBOX[s1 >>> 16 & 255], SBOX[s2 >>> 8 & 255], SBOX[s3 & 255]) ^ rk[at];
145
+ out[1] = packWord(SBOX[s1 >>> 24], SBOX[s2 >>> 16 & 255], SBOX[s3 >>> 8 & 255], SBOX[s0 & 255]) ^ rk[at + 1];
146
+ out[2] = packWord(SBOX[s2 >>> 24], SBOX[s3 >>> 16 & 255], SBOX[s0 >>> 8 & 255], SBOX[s1 & 255]) ^ rk[at + 2];
147
+ out[3] = packWord(SBOX[s3 >>> 24], SBOX[s0 >>> 16 & 255], SBOX[s1 >>> 8 & 255], SBOX[s2 & 255]) ^ rk[at + 3];
148
+ }
149
+ function decryptWords(rk, rounds, a0, a1, a2, a3, out) {
150
+ let s0 = a0 ^ rk[0];
151
+ let s1 = a1 ^ rk[1];
152
+ let s2 = a2 ^ rk[2];
153
+ let s3 = a3 ^ rk[3];
154
+ for (let round = 1; round < rounds; round++) {
155
+ const at = round * WORDS_PER_BLOCK;
156
+ const t0 = TD0[s0 >>> 24] ^ TD1[s3 >>> 16 & 255] ^ TD2[s2 >>> 8 & 255] ^ TD3[s1 & 255] ^ rk[at];
157
+ const t1 = TD0[s1 >>> 24] ^ TD1[s0 >>> 16 & 255] ^ TD2[s3 >>> 8 & 255] ^ TD3[s2 & 255] ^ rk[at + 1];
158
+ const t2 = TD0[s2 >>> 24] ^ TD1[s1 >>> 16 & 255] ^ TD2[s0 >>> 8 & 255] ^ TD3[s3 & 255] ^ rk[at + 2];
159
+ const t3 = TD0[s3 >>> 24] ^ TD1[s2 >>> 16 & 255] ^ TD2[s1 >>> 8 & 255] ^ TD3[s0 & 255] ^ rk[at + 3];
160
+ s0 = t0;
161
+ s1 = t1;
162
+ s2 = t2;
163
+ s3 = t3;
126
164
  }
127
- shiftRows(state, -1);
128
- substituteBytes(state, INV_SBOX);
129
- addRoundKey(state, key.words, 0);
165
+ const at = rounds * WORDS_PER_BLOCK;
166
+ out[0] = packWord(INV_SBOX[s0 >>> 24], INV_SBOX[s3 >>> 16 & 255], INV_SBOX[s2 >>> 8 & 255], INV_SBOX[s1 & 255]) ^ rk[at];
167
+ out[1] = packWord(INV_SBOX[s1 >>> 24], INV_SBOX[s0 >>> 16 & 255], INV_SBOX[s3 >>> 8 & 255], INV_SBOX[s2 & 255]) ^ rk[at + 1];
168
+ out[2] = packWord(INV_SBOX[s2 >>> 24], INV_SBOX[s1 >>> 16 & 255], INV_SBOX[s0 >>> 8 & 255], INV_SBOX[s3 & 255]) ^ rk[at + 2];
169
+ out[3] = packWord(INV_SBOX[s3 >>> 24], INV_SBOX[s2 >>> 16 & 255], INV_SBOX[s1 >>> 8 & 255], INV_SBOX[s0 & 255]) ^ rk[at + 3];
130
170
  }
131
171
  function wholeBlockCount(byteLength) {
132
172
  return Math.floor(byteLength / 16);
133
173
  }
134
174
  function aesCbcDecrypt(key, iv, data) {
135
175
  const expanded = expandKey(key);
176
+ const inverseKey = inverseKeyWords(expanded);
136
177
  const blocks = wholeBlockCount(data.length);
137
178
  const out = new Uint8Array(blocks * 16);
138
- const chain = Uint8Array.from(iv.subarray(0, 16));
139
- for (let b = 0; b < blocks; b++) {
140
- const cipherBlock = data.subarray(b * 16, (b + 1) * 16);
141
- const state = Uint8Array.from(cipherBlock);
142
- decryptBlock(state, expanded);
143
- for (let i = 0; i < 16; i++) out[b * 16 + i] = state[i] ^ chain[i];
144
- chain.set(cipherBlock);
145
- }
179
+ const plain = new Uint32Array(WORDS_PER_BLOCK);
180
+ let c0 = readWord(iv, 0);
181
+ let c1 = readWord(iv, 4);
182
+ let c2 = readWord(iv, 8);
183
+ let c3 = readWord(iv, 12);
184
+ Array.from({ length: blocks }).forEach((_unused, b) => {
185
+ const at = b * 16;
186
+ const x0 = readWord(data, at);
187
+ const x1 = readWord(data, at + 4);
188
+ const x2 = readWord(data, at + 8);
189
+ const x3 = readWord(data, at + 12);
190
+ decryptWords(inverseKey, expanded.rounds, x0, x1, x2, x3, plain);
191
+ writeWord(out, at, plain[0] ^ c0);
192
+ writeWord(out, at + 4, plain[1] ^ c1);
193
+ writeWord(out, at + 8, plain[2] ^ c2);
194
+ writeWord(out, at + 12, plain[3] ^ c3);
195
+ c0 = x0;
196
+ c1 = x1;
197
+ c2 = x2;
198
+ c3 = x3;
199
+ });
146
200
  return out;
147
201
  }
148
202
  function aesCbcEncrypt(key, iv, data) {
149
203
  const expanded = expandKey(key);
150
204
  const blocks = wholeBlockCount(data.length);
151
205
  const out = new Uint8Array(blocks * 16);
152
- const chain = Uint8Array.from(iv.subarray(0, 16));
153
- for (let b = 0; b < blocks; b++) {
154
- const state = /* @__PURE__ */ new Uint8Array(16);
155
- for (let i = 0; i < 16; i++) state[i] = data[b * 16 + i] ^ chain[i];
156
- encryptBlock(state, expanded);
157
- out.set(state, b * 16);
158
- chain.set(state);
159
- }
206
+ const cipher = new Uint32Array(WORDS_PER_BLOCK);
207
+ let c0 = readWord(iv, 0);
208
+ let c1 = readWord(iv, 4);
209
+ let c2 = readWord(iv, 8);
210
+ let c3 = readWord(iv, 12);
211
+ Array.from({ length: blocks }).forEach((_unused, b) => {
212
+ const at = b * 16;
213
+ encryptWords(expanded, readWord(data, at) ^ c0, readWord(data, at + 4) ^ c1, readWord(data, at + 8) ^ c2, readWord(data, at + 12) ^ c3, cipher);
214
+ c0 = cipher[0];
215
+ c1 = cipher[1];
216
+ c2 = cipher[2];
217
+ c3 = cipher[3];
218
+ writeWord(out, at, c0);
219
+ writeWord(out, at + 4, c1);
220
+ writeWord(out, at + 8, c2);
221
+ writeWord(out, at + 12, c3);
222
+ });
160
223
  return out;
161
224
  }
162
225
  //#endregion
@@ -5,7 +5,6 @@ const SHA256_ROUNDS = 64;
5
5
  const SHA512_BLOCK_BYTES = 128;
6
6
  const SHA512_ROUNDS = 80;
7
7
  const WORDS_PER_BLOCK = 16;
8
- const MASK64 = 18446744073709551615n;
9
8
  const K512 = [
10
9
  4794697086780616226n,
11
10
  8158064640168781261n,
@@ -110,6 +109,9 @@ const H384 = [
110
109
  ];
111
110
  const K256 = Uint32Array.from(K512.slice(0, SHA256_ROUNDS), (k) => Number(k >> 32n));
112
111
  const H256 = Uint32Array.from(H512, (h) => Number(h >> 32n));
112
+ const K512_HIGH = Uint32Array.from(K512, (k) => Number(k >> 32n));
113
+ const K512_LOW = Uint32Array.from(K512, (k) => Number(BigInt.asUintN(32, k)));
114
+ const TWO_POW_32 = 4294967296;
113
115
  function padBigEndian(bytes, blockBytes, lengthBytes) {
114
116
  const paddedLength = (Math.floor((bytes.length + lengthBytes) / blockBytes) + 1) * blockBytes;
115
117
  const padded = new Uint8Array(paddedLength);
@@ -185,69 +187,115 @@ function sha256(bytes) {
185
187
  }
186
188
  return digest;
187
189
  }
188
- function rotr64(value, bits) {
189
- return (value >> bits | value << 64n - bits) & MASK64;
190
+ function readWord32(bytes, offset) {
191
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
190
192
  }
191
193
  function sha512Core(bytes, initialState, outputWords) {
192
194
  const padded = padBigEndian(bytes, SHA512_BLOCK_BYTES, 16);
193
- const state = Array.from(initialState);
194
- const w = new Array(SHA512_ROUNDS).fill(0n);
195
+ const stateHigh = Uint32Array.from(initialState, (word) => Number(word >> 32n));
196
+ const stateLow = Uint32Array.from(initialState, (word) => Number(BigInt.asUintN(32, word)));
197
+ const wHigh = new Uint32Array(SHA512_ROUNDS);
198
+ const wLow = new Uint32Array(SHA512_ROUNDS);
195
199
  for (let offset = 0; offset < padded.length; offset += SHA512_BLOCK_BYTES) {
196
- for (let t = 0; t < WORDS_PER_BLOCK; t++) {
197
- let word = 0n;
198
- for (let i = 0; i < 8; i++) word = word << 8n | BigInt(padded[offset + t * 8 + i]);
199
- w[t] = word;
200
- }
201
- for (let t = WORDS_PER_BLOCK; t < SHA512_ROUNDS; t++) {
202
- const x = w[t - 15];
203
- const y = w[t - 2];
204
- const s0 = rotr64(x, 1n) ^ rotr64(x, 8n) ^ x >> 7n;
205
- const s1 = rotr64(y, 19n) ^ rotr64(y, 61n) ^ y >> 6n;
206
- w[t] = w[t - 16] + s0 + w[t - 7] + s1 & MASK64;
207
- }
208
- let a = state[0];
209
- let b = state[1];
210
- let c = state[2];
211
- let d = state[3];
212
- let e = state[4];
213
- let f = state[5];
214
- let g = state[6];
215
- let h = state[7];
200
+ wHigh.forEach((_word, t) => {
201
+ if (t < WORDS_PER_BLOCK) {
202
+ const at = offset + t * 8;
203
+ wHigh[t] = readWord32(padded, at);
204
+ wLow[t] = readWord32(padded, at + 4);
205
+ return;
206
+ }
207
+ const xh = wHigh[t - 15];
208
+ const xl = wLow[t - 15];
209
+ const yh = wHigh[t - 2];
210
+ const yl = wLow[t - 2];
211
+ const s0h = (xh >>> 1 | xl << 31) ^ (xh >>> 8 | xl << 24) ^ xh >>> 7;
212
+ const s0l = (xl >>> 1 | xh << 31) ^ (xl >>> 8 | xh << 24) ^ (xl >>> 7 | xh << 25);
213
+ const s1h = (yh >>> 19 | yl << 13) ^ (yl >>> 29 | yh << 3) ^ yh >>> 6;
214
+ const s1l = (yl >>> 19 | yh << 13) ^ (yh >>> 29 | yl << 3) ^ (yl >>> 6 | yh << 26);
215
+ const low = wLow[t - 16] + (s0l >>> 0) + wLow[t - 7] + (s1l >>> 0);
216
+ const carry = Math.floor(low / TWO_POW_32);
217
+ wLow[t] = low;
218
+ wHigh[t] = wHigh[t - 16] + (s0h >>> 0) + wHigh[t - 7] + (s1h >>> 0) + carry;
219
+ });
220
+ let ah = stateHigh[0];
221
+ let al = stateLow[0];
222
+ let bh = stateHigh[1];
223
+ let bl = stateLow[1];
224
+ let ch = stateHigh[2];
225
+ let cl = stateLow[2];
226
+ let dh = stateHigh[3];
227
+ let dl = stateLow[3];
228
+ let eh = stateHigh[4];
229
+ let el = stateLow[4];
230
+ let fh = stateHigh[5];
231
+ let fl = stateLow[5];
232
+ let gh = stateHigh[6];
233
+ let gl = stateLow[6];
234
+ let hh = stateHigh[7];
235
+ let hl = stateLow[7];
216
236
  for (let t = 0; t < SHA512_ROUNDS; t++) {
217
- const bigS1 = rotr64(e, 14n) ^ rotr64(e, 18n) ^ rotr64(e, 41n);
218
- const ch = e & f ^ ~e & MASK64 & g;
219
- const t1 = h + bigS1 + ch + K512[t] + w[t] & MASK64;
220
- const t2 = (rotr64(a, 28n) ^ rotr64(a, 34n) ^ rotr64(a, 39n)) + (a & b ^ a & c ^ b & c) & MASK64;
221
- h = g;
222
- g = f;
223
- f = e;
224
- e = d + t1 & MASK64;
225
- d = c;
226
- c = b;
227
- b = a;
228
- a = t1 + t2 & MASK64;
237
+ const bigS1h = (eh >>> 14 | el << 18) ^ (eh >>> 18 | el << 14) ^ (el >>> 9 | eh << 23);
238
+ const bigS1l = (el >>> 14 | eh << 18) ^ (el >>> 18 | eh << 14) ^ (eh >>> 9 | el << 23);
239
+ const chh = eh & fh ^ ~eh & gh;
240
+ const chl = el & fl ^ ~el & gl;
241
+ const t1Sum = hl + (bigS1l >>> 0) + (chl >>> 0) + K512_LOW[t] + wLow[t];
242
+ const t1l = t1Sum >>> 0;
243
+ const t1h = hh + (bigS1h >>> 0) + (chh >>> 0) + K512_HIGH[t] + wHigh[t] + Math.floor(t1Sum / TWO_POW_32) >>> 0;
244
+ const bigS0h = (ah >>> 28 | al << 4) ^ (al >>> 2 | ah << 30) ^ (al >>> 7 | ah << 25);
245
+ const bigS0l = (al >>> 28 | ah << 4) ^ (ah >>> 2 | al << 30) ^ (ah >>> 7 | al << 25);
246
+ const majh = ah & bh ^ ah & ch ^ bh & ch;
247
+ const majl = al & bl ^ al & cl ^ bl & cl;
248
+ const t2Sum = (bigS0l >>> 0) + (majl >>> 0);
249
+ const t2l = t2Sum >>> 0;
250
+ const t2h = (bigS0h >>> 0) + (majh >>> 0) + Math.floor(t2Sum / TWO_POW_32) >>> 0;
251
+ hh = gh;
252
+ hl = gl;
253
+ gh = fh;
254
+ gl = fl;
255
+ fh = eh;
256
+ fl = el;
257
+ const eSum = dl + t1l;
258
+ eh = dh + t1h + Math.floor(eSum / TWO_POW_32) >>> 0;
259
+ el = eSum >>> 0;
260
+ dh = ch;
261
+ dl = cl;
262
+ ch = bh;
263
+ cl = bl;
264
+ bh = ah;
265
+ bl = al;
266
+ const aSum = t1l + t2l;
267
+ ah = t1h + t2h + Math.floor(aSum / TWO_POW_32) >>> 0;
268
+ al = aSum >>> 0;
229
269
  }
230
- const next = [
231
- a,
232
- b,
233
- c,
234
- d,
235
- e,
236
- f,
237
- g,
238
- h
270
+ const nextHigh = [
271
+ ah,
272
+ bh,
273
+ ch,
274
+ dh,
275
+ eh,
276
+ fh,
277
+ gh,
278
+ hh
239
279
  ];
240
- for (let i = 0; i < state.length; i++) state[i] = state[i] + next[i] & MASK64;
241
- }
242
- const digest = new Uint8Array(outputWords * 8);
243
- for (let i = 0; i < outputWords; i++) {
244
- let word = state[i];
245
- for (let j = 7; j >= 0; j--) {
246
- digest[i * 8 + j] = Number(word & 255n);
247
- word >>= 8n;
248
- }
280
+ const nextLow = [
281
+ al,
282
+ bl,
283
+ cl,
284
+ dl,
285
+ el,
286
+ fl,
287
+ gl,
288
+ hl
289
+ ];
290
+ stateHigh.forEach((word, i) => {
291
+ const sum = stateLow[i] + nextLow[i];
292
+ stateHigh[i] = word + nextHigh[i] + Math.floor(sum / TWO_POW_32);
293
+ stateLow[i] = sum;
294
+ });
249
295
  }
250
- return digest;
296
+ return Uint8Array.from({ length: outputWords * 8 }, (_unused, index) => {
297
+ return (index % 8 < 4 ? stateHigh : stateLow)[Math.floor(index / 8)] >>> 24 - 8 * (index % 4) & 255;
298
+ });
251
299
  }
252
300
  function sha512(bytes) {
253
301
  return sha512Core(bytes, H512, 8);
@@ -4,7 +4,6 @@ const SHA256_ROUNDS = 64;
4
4
  const SHA512_BLOCK_BYTES = 128;
5
5
  const SHA512_ROUNDS = 80;
6
6
  const WORDS_PER_BLOCK = 16;
7
- const MASK64 = 18446744073709551615n;
8
7
  const K512 = [
9
8
  4794697086780616226n,
10
9
  8158064640168781261n,
@@ -109,6 +108,9 @@ const H384 = [
109
108
  ];
110
109
  const K256 = Uint32Array.from(K512.slice(0, SHA256_ROUNDS), (k) => Number(k >> 32n));
111
110
  const H256 = Uint32Array.from(H512, (h) => Number(h >> 32n));
111
+ const K512_HIGH = Uint32Array.from(K512, (k) => Number(k >> 32n));
112
+ const K512_LOW = Uint32Array.from(K512, (k) => Number(BigInt.asUintN(32, k)));
113
+ const TWO_POW_32 = 4294967296;
112
114
  function padBigEndian(bytes, blockBytes, lengthBytes) {
113
115
  const paddedLength = (Math.floor((bytes.length + lengthBytes) / blockBytes) + 1) * blockBytes;
114
116
  const padded = new Uint8Array(paddedLength);
@@ -184,69 +186,115 @@ function sha256(bytes) {
184
186
  }
185
187
  return digest;
186
188
  }
187
- function rotr64(value, bits) {
188
- return (value >> bits | value << 64n - bits) & MASK64;
189
+ function readWord32(bytes, offset) {
190
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
189
191
  }
190
192
  function sha512Core(bytes, initialState, outputWords) {
191
193
  const padded = padBigEndian(bytes, SHA512_BLOCK_BYTES, 16);
192
- const state = Array.from(initialState);
193
- const w = new Array(SHA512_ROUNDS).fill(0n);
194
+ const stateHigh = Uint32Array.from(initialState, (word) => Number(word >> 32n));
195
+ const stateLow = Uint32Array.from(initialState, (word) => Number(BigInt.asUintN(32, word)));
196
+ const wHigh = new Uint32Array(SHA512_ROUNDS);
197
+ const wLow = new Uint32Array(SHA512_ROUNDS);
194
198
  for (let offset = 0; offset < padded.length; offset += SHA512_BLOCK_BYTES) {
195
- for (let t = 0; t < WORDS_PER_BLOCK; t++) {
196
- let word = 0n;
197
- for (let i = 0; i < 8; i++) word = word << 8n | BigInt(padded[offset + t * 8 + i]);
198
- w[t] = word;
199
- }
200
- for (let t = WORDS_PER_BLOCK; t < SHA512_ROUNDS; t++) {
201
- const x = w[t - 15];
202
- const y = w[t - 2];
203
- const s0 = rotr64(x, 1n) ^ rotr64(x, 8n) ^ x >> 7n;
204
- const s1 = rotr64(y, 19n) ^ rotr64(y, 61n) ^ y >> 6n;
205
- w[t] = w[t - 16] + s0 + w[t - 7] + s1 & MASK64;
206
- }
207
- let a = state[0];
208
- let b = state[1];
209
- let c = state[2];
210
- let d = state[3];
211
- let e = state[4];
212
- let f = state[5];
213
- let g = state[6];
214
- let h = state[7];
199
+ wHigh.forEach((_word, t) => {
200
+ if (t < WORDS_PER_BLOCK) {
201
+ const at = offset + t * 8;
202
+ wHigh[t] = readWord32(padded, at);
203
+ wLow[t] = readWord32(padded, at + 4);
204
+ return;
205
+ }
206
+ const xh = wHigh[t - 15];
207
+ const xl = wLow[t - 15];
208
+ const yh = wHigh[t - 2];
209
+ const yl = wLow[t - 2];
210
+ const s0h = (xh >>> 1 | xl << 31) ^ (xh >>> 8 | xl << 24) ^ xh >>> 7;
211
+ const s0l = (xl >>> 1 | xh << 31) ^ (xl >>> 8 | xh << 24) ^ (xl >>> 7 | xh << 25);
212
+ const s1h = (yh >>> 19 | yl << 13) ^ (yl >>> 29 | yh << 3) ^ yh >>> 6;
213
+ const s1l = (yl >>> 19 | yh << 13) ^ (yh >>> 29 | yl << 3) ^ (yl >>> 6 | yh << 26);
214
+ const low = wLow[t - 16] + (s0l >>> 0) + wLow[t - 7] + (s1l >>> 0);
215
+ const carry = Math.floor(low / TWO_POW_32);
216
+ wLow[t] = low;
217
+ wHigh[t] = wHigh[t - 16] + (s0h >>> 0) + wHigh[t - 7] + (s1h >>> 0) + carry;
218
+ });
219
+ let ah = stateHigh[0];
220
+ let al = stateLow[0];
221
+ let bh = stateHigh[1];
222
+ let bl = stateLow[1];
223
+ let ch = stateHigh[2];
224
+ let cl = stateLow[2];
225
+ let dh = stateHigh[3];
226
+ let dl = stateLow[3];
227
+ let eh = stateHigh[4];
228
+ let el = stateLow[4];
229
+ let fh = stateHigh[5];
230
+ let fl = stateLow[5];
231
+ let gh = stateHigh[6];
232
+ let gl = stateLow[6];
233
+ let hh = stateHigh[7];
234
+ let hl = stateLow[7];
215
235
  for (let t = 0; t < SHA512_ROUNDS; t++) {
216
- const bigS1 = rotr64(e, 14n) ^ rotr64(e, 18n) ^ rotr64(e, 41n);
217
- const ch = e & f ^ ~e & MASK64 & g;
218
- const t1 = h + bigS1 + ch + K512[t] + w[t] & MASK64;
219
- const t2 = (rotr64(a, 28n) ^ rotr64(a, 34n) ^ rotr64(a, 39n)) + (a & b ^ a & c ^ b & c) & MASK64;
220
- h = g;
221
- g = f;
222
- f = e;
223
- e = d + t1 & MASK64;
224
- d = c;
225
- c = b;
226
- b = a;
227
- a = t1 + t2 & MASK64;
236
+ const bigS1h = (eh >>> 14 | el << 18) ^ (eh >>> 18 | el << 14) ^ (el >>> 9 | eh << 23);
237
+ const bigS1l = (el >>> 14 | eh << 18) ^ (el >>> 18 | eh << 14) ^ (eh >>> 9 | el << 23);
238
+ const chh = eh & fh ^ ~eh & gh;
239
+ const chl = el & fl ^ ~el & gl;
240
+ const t1Sum = hl + (bigS1l >>> 0) + (chl >>> 0) + K512_LOW[t] + wLow[t];
241
+ const t1l = t1Sum >>> 0;
242
+ const t1h = hh + (bigS1h >>> 0) + (chh >>> 0) + K512_HIGH[t] + wHigh[t] + Math.floor(t1Sum / TWO_POW_32) >>> 0;
243
+ const bigS0h = (ah >>> 28 | al << 4) ^ (al >>> 2 | ah << 30) ^ (al >>> 7 | ah << 25);
244
+ const bigS0l = (al >>> 28 | ah << 4) ^ (ah >>> 2 | al << 30) ^ (ah >>> 7 | al << 25);
245
+ const majh = ah & bh ^ ah & ch ^ bh & ch;
246
+ const majl = al & bl ^ al & cl ^ bl & cl;
247
+ const t2Sum = (bigS0l >>> 0) + (majl >>> 0);
248
+ const t2l = t2Sum >>> 0;
249
+ const t2h = (bigS0h >>> 0) + (majh >>> 0) + Math.floor(t2Sum / TWO_POW_32) >>> 0;
250
+ hh = gh;
251
+ hl = gl;
252
+ gh = fh;
253
+ gl = fl;
254
+ fh = eh;
255
+ fl = el;
256
+ const eSum = dl + t1l;
257
+ eh = dh + t1h + Math.floor(eSum / TWO_POW_32) >>> 0;
258
+ el = eSum >>> 0;
259
+ dh = ch;
260
+ dl = cl;
261
+ ch = bh;
262
+ cl = bl;
263
+ bh = ah;
264
+ bl = al;
265
+ const aSum = t1l + t2l;
266
+ ah = t1h + t2h + Math.floor(aSum / TWO_POW_32) >>> 0;
267
+ al = aSum >>> 0;
228
268
  }
229
- const next = [
230
- a,
231
- b,
232
- c,
233
- d,
234
- e,
235
- f,
236
- g,
237
- h
269
+ const nextHigh = [
270
+ ah,
271
+ bh,
272
+ ch,
273
+ dh,
274
+ eh,
275
+ fh,
276
+ gh,
277
+ hh
238
278
  ];
239
- for (let i = 0; i < state.length; i++) state[i] = state[i] + next[i] & MASK64;
240
- }
241
- const digest = new Uint8Array(outputWords * 8);
242
- for (let i = 0; i < outputWords; i++) {
243
- let word = state[i];
244
- for (let j = 7; j >= 0; j--) {
245
- digest[i * 8 + j] = Number(word & 255n);
246
- word >>= 8n;
247
- }
279
+ const nextLow = [
280
+ al,
281
+ bl,
282
+ cl,
283
+ dl,
284
+ el,
285
+ fl,
286
+ gl,
287
+ hl
288
+ ];
289
+ stateHigh.forEach((word, i) => {
290
+ const sum = stateLow[i] + nextLow[i];
291
+ stateHigh[i] = word + nextHigh[i] + Math.floor(sum / TWO_POW_32);
292
+ stateLow[i] = sum;
293
+ });
248
294
  }
249
- return digest;
295
+ return Uint8Array.from({ length: outputWords * 8 }, (_unused, index) => {
296
+ return (index % 8 < 4 ? stateHigh : stateLow)[Math.floor(index / 8)] >>> 24 - 8 * (index % 4) & 255;
297
+ });
250
298
  }
251
299
  function sha512(bytes) {
252
300
  return sha512Core(bytes, H512, 8);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-parser.js",
3
- "version": "4.8.5",
3
+ "version": "4.8.7",
4
4
  "description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on its own codec-owned LayoutDocument item model and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {