@amritk/nish-aarch64-darwin 0.34.0 → 0.34.1

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/bin/nish CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amritk/nish-aarch64-darwin",
3
- "version": "0.34.0",
3
+ "version": "0.34.1",
4
4
  "description": "The nish native compiler for macOS on ARM64",
5
5
  "license": "MIT",
6
6
  "os": [
package/std/bytes.ts CHANGED
@@ -26,7 +26,10 @@
26
26
  * inside a call, and after `getU32LE` inlines, LLVM keeps the checks on
27
27
  * `off + 1` to `off + 3`, because the guard compares the length truncated to
28
28
  * `i32` and the checks compare it unsigned at 64 bits. A loop that needs them
29
- * gone indexes the bytes itself.
29
+ * gone indexes the bytes itself. `getU64BE`, and with it `getI64BE` and
30
+ * `getF64BE`, is the exception: it checks the whole range once and reads the
31
+ * eight bytes unchecked, which lowers to one load and a byte swap. An offset
32
+ * outside the range still goes byte by byte, so it panics as the others do.
30
33
  *
31
34
  * The in-range answers are byte for byte those of the copies `std/` keeps for
32
35
  * itself: `sha256LoadWord` (`std/crypto/sha256.ts`) for `getU32BE`,
@@ -91,8 +94,8 @@ export const getU64LE = (b: u8[], off: i32): u64 => {
91
94
  return v
92
95
  }
93
96
 
94
- /** The `u64` whose bytes, most significant first, are `b[off]` to `b[off + 7]`. */
95
- export const getU64BE = (b: u8[], off: i32): u64 => {
97
+ /** `getU64BE` a byte at a time, each index checked: the path for an offset whose eight bytes are not all in the array. */
98
+ const getU64BEByByte = (b: u8[], off: i32): u64 => {
96
99
  let v = toU64(0)
97
100
  for (let i: i32 = 0; i < 8; i++) {
98
101
  v = (v << toU64(8)) | toU64(b[off + i])
@@ -100,6 +103,26 @@ export const getU64BE = (b: u8[], off: i32): u64 => {
100
103
  return v
101
104
  }
102
105
 
106
+ /**
107
+ * The `u64` whose bytes, most significant first, are `b[off]` to `b[off + 7]`.
108
+ * The fast path's ors are grouped in pairs, which LLVM folds into one load and
109
+ * a `bswap`; a flat chain of eight `or`s stayed byte by byte. The byte loop is
110
+ * its own function so its last load is not merged with the fast path's.
111
+ */
112
+ export const getU64BE = (b: u8[], off: i32): u64 => {
113
+ if (off >= 0 && off < 2147483640 && off + 8 <= toI32(b.length)) {
114
+ return (
115
+ (toU64(b[off]) << toU64(56)) |
116
+ (toU64(b[off + 1]) << toU64(48)) |
117
+ ((toU64(b[off + 2]) << toU64(40)) | (toU64(b[off + 3]) << toU64(32))) |
118
+ ((toU64(b[off + 4]) << toU64(24)) |
119
+ (toU64(b[off + 5]) << toU64(16)) |
120
+ ((toU64(b[off + 6]) << toU64(8)) | toU64(b[off + 7])))
121
+ )
122
+ }
123
+ return getU64BEByByte(b, off)
124
+ }
125
+
103
126
  /** `getU32LE`'s bits as a two's-complement `i32`. */
104
127
  export const getI32LE = (b: u8[], off: i32): i32 => toI32(getU32LE(b, off))
105
128
 
@@ -127,8 +127,9 @@ export const base64urlEncode = (data: u8[]): string => {
127
127
  * one canonical spelling of any byte string — see the module comment for the
128
128
  * five refusals.
129
129
  *
130
- * The same accumulator as `base64urlEncode`, run the other way: six bits in per
131
- * character, eight out per byte.
130
+ * Each group of four characters becomes one 24-bit word, six bits a
131
+ * character, which splits into three bytes; a short final group of two or
132
+ * three characters fills the top of the word and gives one or two.
132
133
  */
133
134
  export const base64urlDecode = (text: string): u8[] | null => {
134
135
  // A text past 2^31 - 1 bytes is refused before `toI32`, which would
@@ -148,31 +149,51 @@ export const base64urlDecode = (text: string): u8[] | null => {
148
149
  // short final group; `n * 3 / 4` would overflow for a text over 700 MB.
149
150
  const out: u8[] = new Array<u8>((n >> 2) * 3 + (tail === 0 ? 0 : tail - 1))
150
151
  const outLen: i32 = toI32(out.length)
151
- // All ones once any character is outside the alphabet (its sextet of `-1`
152
+ // All ones once any character is outside the alphabet (a sextet of `-1`
152
153
  // shifted right by 31), and non-zero once the text ends on a bit that
153
154
  // encodes no byte.
154
155
  let bad: i32 = 0
155
- let acc: i32 = 0
156
- let bits: i32 = 0
156
+ // Four characters make one 24-bit word and three bytes, so a full group has
157
+ // no count of waiting bits to test, and its four sextets are independent.
157
158
  let j: i32 = 0
158
- for (let k: i32 = 0; k < n; k++) {
159
- const v: i32 = base64urlSextetOf(toI32(text.charCodeAt(k)))
160
- bad = bad | (v >> 31)
161
- acc = ((acc << 6) | (v & 63)) & 0xfff
162
- bits += 6
163
- if (bits >= 8) {
164
- bits -= 8
165
- // Always true — `out` was sized from the same length — but written out
166
- // so that the store keeps no bounds check.
167
- if (j >= 0 && j < outLen) {
168
- out[j] = toU8((acc >> bits) & 255)
169
- }
170
- j++
159
+ for (let k: i32 = 0; k + 3 < n; k += 4) {
160
+ const s0: i32 = base64urlSextetOf(toI32(text.charCodeAt(k)))
161
+ const s1: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 1)))
162
+ const s2: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 2)))
163
+ const s3: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 3)))
164
+ bad = bad | ((s0 | s1 | s2 | s3) >> 31)
165
+ const word: i32 = ((s0 & 63) << 18) | ((s1 & 63) << 12) | ((s2 & 63) << 6) | (s3 & 63)
166
+ // Always true — `out` was sized from the same length — but written out so
167
+ // that the three stores keep no bounds check.
168
+ if (j >= 0 && j + 2 < outLen) {
169
+ out[j] = toU8(word >> 16)
170
+ out[j + 1] = toU8((word >> 8) & 255)
171
+ out[j + 2] = toU8(word & 255)
171
172
  }
173
+ j += 3
174
+ }
175
+ // A short final group of two or three characters: one or two bytes, and the
176
+ // four or two bits left over belong to no byte, so they must be zero for `AA`
177
+ // to be the only spelling of a zero byte and `AB` refused (RFC 4648 §3.5).
178
+ if (tail !== 0) {
179
+ const k: i32 = n - tail
180
+ const s0: i32 = base64urlSextetOf(toI32(text.charCodeAt(k)))
181
+ const s1: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 1)))
182
+ // A third character only when the tail has one; a two-character tail reads
183
+ // its place as `A`, the zero sextet, which adds no bits.
184
+ const s2: i32 = tail === 3 ? base64urlSextetOf(toI32(text.charCodeAt(k + 2))) : 0
185
+ bad = bad | ((s0 | s1 | s2) >> 31)
186
+ const word: i32 = ((s0 & 63) << 18) | ((s1 & 63) << 12) | ((s2 & 63) << 6)
187
+ if (j >= 0 && j < outLen) {
188
+ out[j] = toU8(word >> 16)
189
+ }
190
+ if (tail === 3 && j + 1 >= 0 && j + 1 < outLen) {
191
+ out[j + 1] = toU8((word >> 8) & 255)
192
+ }
193
+ // The bits under the last byte written: sixteen of the word when one byte
194
+ // was, eight when two were.
195
+ bad = bad | (word & (tail === 2 ? 0xffff : 0xff))
172
196
  }
173
- // The two or four bits left over belong to no byte, and must be zero so that
174
- // `AA` is the only spelling of a zero byte and `AB` is refused (RFC 4648 §3.5).
175
- bad = bad | (acc & ((1 << bits) - 1))
176
197
  if (bad !== 0) {
177
198
  return null
178
199
  }
@@ -1021,12 +1021,14 @@ const bcryptLoadSlot = (state: Secret<u32[]>, password: Secret<u8[]>, slot: i32)
1021
1021
  }
1022
1022
 
1023
1023
  // The cost-round kernels, one per width. Each is `bcryptBody4`'s text with
1024
- // the lane count changed (bench/crypto/bcrypt/gen-body.mjs writes them), not
1024
+ // the lane count changed, except that six lanes' sixth lane takes its bytes
1025
+ // the previous way (see `bcryptBody4`); bench/crypto/bcrypt/gen-body.mjs
1026
+ // writes them all, so an edit is made there. They are not
1025
1027
  // one loop over a lane count: the lanes' l and r must live in registers and
1026
1028
  // their loads be scheduled together, which a loop over an array of lanes
1027
1029
  // does not give. Two lanes take each byte by its own shift and write every
1028
1030
  // lane's bytes before any lane's update, the form all widths had before the
1029
- // rotated copy, which measured slower there.
1031
+ // copies behind the barrier, which measured slower there.
1030
1032
 
1031
1033
  /** `bcryptBody4`'s interleave on two lanes. */
1032
1034
  const bcryptBody2 = (st: u32[]): void => {
@@ -1091,41 +1093,47 @@ const bcryptBody3 = (st: u32[]): void => {
1091
1093
  l1 ^= st[1042]
1092
1094
  l2 ^= st[2084]
1093
1095
  for (let n: i32 = 1; n < 17; n += 2) {
1094
- const l0e: u32 = ctSelect((l0 >>> 8) | (l0 << 24), 0xffffffff, 0)
1095
- const l0a: i32 = toI32(l0 >>> 24) & 0xff
1096
- const l0b: i32 = toI32(l0e >>> 8) & 0xff
1097
- const l0c: i32 = toI32(l0e) & 0xff
1098
- const l0d: i32 = toI32(l0) & 0xff
1096
+ const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
1097
+ const l0d: i32 = toI32(l0e) & 0xff
1098
+ const l0c: i32 = toI32(l0e >>> 8) & 0xff
1099
+ const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
1100
+ const l0b: i32 = toI32(l0f) & 0xff
1101
+ const l0a: i32 = toI32(l0f >>> 8) & 0xff
1099
1102
  r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
1100
- const l1e: u32 = ctSelect((l1 >>> 8) | (l1 << 24), 0xffffffff, 0)
1101
- const l1a: i32 = toI32(l1 >>> 24) & 0xff
1102
- const l1b: i32 = toI32(l1e >>> 8) & 0xff
1103
- const l1c: i32 = toI32(l1e) & 0xff
1104
- const l1d: i32 = toI32(l1) & 0xff
1103
+ const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
1104
+ const l1d: i32 = toI32(l1e) & 0xff
1105
+ const l1c: i32 = toI32(l1e >>> 8) & 0xff
1106
+ const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
1107
+ const l1b: i32 = toI32(l1f) & 0xff
1108
+ const l1a: i32 = toI32(l1f >>> 8) & 0xff
1105
1109
  r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
1106
- const l2e: u32 = ctSelect((l2 >>> 8) | (l2 << 24), 0xffffffff, 0)
1107
- const l2a: i32 = toI32(l2 >>> 24) & 0xff
1108
- const l2b: i32 = toI32(l2e >>> 8) & 0xff
1109
- const l2c: i32 = toI32(l2e) & 0xff
1110
- const l2d: i32 = toI32(l2) & 0xff
1110
+ const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
1111
+ const l2d: i32 = toI32(l2e) & 0xff
1112
+ const l2c: i32 = toI32(l2e >>> 8) & 0xff
1113
+ const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
1114
+ const l2b: i32 = toI32(l2f) & 0xff
1115
+ const l2a: i32 = toI32(l2f >>> 8) & 0xff
1111
1116
  r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
1112
- const r0e: u32 = ctSelect((r0 >>> 8) | (r0 << 24), 0xffffffff, 0)
1113
- const r0a: i32 = toI32(r0 >>> 24) & 0xff
1114
- const r0b: i32 = toI32(r0e >>> 8) & 0xff
1115
- const r0c: i32 = toI32(r0e) & 0xff
1116
- const r0d: i32 = toI32(r0) & 0xff
1117
+ const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
1118
+ const r0d: i32 = toI32(r0e) & 0xff
1119
+ const r0c: i32 = toI32(r0e >>> 8) & 0xff
1120
+ const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
1121
+ const r0b: i32 = toI32(r0f) & 0xff
1122
+ const r0a: i32 = toI32(r0f >>> 8) & 0xff
1117
1123
  l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
1118
- const r1e: u32 = ctSelect((r1 >>> 8) | (r1 << 24), 0xffffffff, 0)
1119
- const r1a: i32 = toI32(r1 >>> 24) & 0xff
1120
- const r1b: i32 = toI32(r1e >>> 8) & 0xff
1121
- const r1c: i32 = toI32(r1e) & 0xff
1122
- const r1d: i32 = toI32(r1) & 0xff
1124
+ const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
1125
+ const r1d: i32 = toI32(r1e) & 0xff
1126
+ const r1c: i32 = toI32(r1e >>> 8) & 0xff
1127
+ const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
1128
+ const r1b: i32 = toI32(r1f) & 0xff
1129
+ const r1a: i32 = toI32(r1f >>> 8) & 0xff
1123
1130
  l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
1124
- const r2e: u32 = ctSelect((r2 >>> 8) | (r2 << 24), 0xffffffff, 0)
1125
- const r2a: i32 = toI32(r2 >>> 24) & 0xff
1126
- const r2b: i32 = toI32(r2e >>> 8) & 0xff
1127
- const r2c: i32 = toI32(r2e) & 0xff
1128
- const r2d: i32 = toI32(r2) & 0xff
1131
+ const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
1132
+ const r2d: i32 = toI32(r2e) & 0xff
1133
+ const r2c: i32 = toI32(r2e >>> 8) & 0xff
1134
+ const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
1135
+ const r2b: i32 = toI32(r2f) & 0xff
1136
+ const r2a: i32 = toI32(r2f >>> 8) & 0xff
1129
1137
  l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
1130
1138
  }
1131
1139
  const t0: u32 = r0
@@ -1153,17 +1161,20 @@ const bcryptBody3 = (st: u32[]): void => {
1153
1161
  * hot loop of the batch: 2^(cost+1) calls of 521 blocks per lane.
1154
1162
  *
1155
1163
  * Each lane's half-round is written whole, its bytes and then its update,
1156
- * before the next lane's. The two middle index bytes come from one copy of the
1157
- * word rotated right by 8 (`e`: byte 1 is its low byte, byte 2 its second),
1158
- * behind the value barrier: `ctSelect(v, 0xffffffff, 0)` is `v`, opaque, so
1159
- * LLVM cannot fold the two bytes back into two shifts of the word, and copies
1160
- * it once instead of twice; on a BMI2 target the copy is one `rorx`. Three
1161
- * and five lanes rotate the copy the same way; six shift it right by 8, which
1162
- * has the same two low bytes and measured faster there. On a
1163
- * Xeon Platinum 8260 that is 6% less time a hash at the best width, 9% under
1164
- * `--cpu x86-64-v3` (docs/security/crypto-bcrypt.md, "Cascade Lake"). The
1165
- * barrier is an identity on a register: it adds no branch and no load, and
1166
- * the round reads the same four S-box words.
1164
+ * before the next lane's. The bytes come in two pairs, each the low and
1165
+ * second byte of a copy behind the value barrier: `ctSelect(v, 0xffffffff, 0)`
1166
+ * is `v`, opaque. A copy of the word (`e`) gives bytes 0 and 1, and that copy
1167
+ * moved down by 16 (`f`) bytes 2 and 3, so a second byte is one `movzx` from
1168
+ * `ah`, `bh`, `ch` or `dh` and a lane takes its four bytes in six
1169
+ * instructions; without the barriers LLVM folds the pairs back into shifts of
1170
+ * the word. Only four registers have a second byte, and with all six lanes
1171
+ * paired the loop spilled more than it saved (counted), so at six lanes the
1172
+ * sixth lane takes bytes 1 and 2 from one copy moved down by 8 and bytes 0
1173
+ * and 3 by shifts of the word, the way every lane had before. On a Xeon Platinum
1174
+ * 8260 the pairs take about 3.5% less time a hash than that way at the best
1175
+ * width, five lanes, and 5.6% less at six (docs/security/crypto-bcrypt.md,
1176
+ * "Cascade Lake"). The barrier is an identity on a register: it adds no
1177
+ * branch and no load, and the round reads the same four S-box words.
1167
1178
  */
1168
1179
  const bcryptBody4 = (st: u32[]): void => {
1169
1180
  if (st.length < 4168) {
@@ -1183,53 +1194,61 @@ const bcryptBody4 = (st: u32[]): void => {
1183
1194
  l2 ^= st[2084]
1184
1195
  l3 ^= st[3126]
1185
1196
  for (let n: i32 = 1; n < 17; n += 2) {
1186
- const l0e: u32 = ctSelect((l0 >>> 8) | (l0 << 24), 0xffffffff, 0)
1187
- const l0a: i32 = toI32(l0 >>> 24) & 0xff
1188
- const l0b: i32 = toI32(l0e >>> 8) & 0xff
1189
- const l0c: i32 = toI32(l0e) & 0xff
1190
- const l0d: i32 = toI32(l0) & 0xff
1197
+ const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
1198
+ const l0d: i32 = toI32(l0e) & 0xff
1199
+ const l0c: i32 = toI32(l0e >>> 8) & 0xff
1200
+ const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
1201
+ const l0b: i32 = toI32(l0f) & 0xff
1202
+ const l0a: i32 = toI32(l0f >>> 8) & 0xff
1191
1203
  r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
1192
- const l1e: u32 = ctSelect((l1 >>> 8) | (l1 << 24), 0xffffffff, 0)
1193
- const l1a: i32 = toI32(l1 >>> 24) & 0xff
1194
- const l1b: i32 = toI32(l1e >>> 8) & 0xff
1195
- const l1c: i32 = toI32(l1e) & 0xff
1196
- const l1d: i32 = toI32(l1) & 0xff
1204
+ const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
1205
+ const l1d: i32 = toI32(l1e) & 0xff
1206
+ const l1c: i32 = toI32(l1e >>> 8) & 0xff
1207
+ const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
1208
+ const l1b: i32 = toI32(l1f) & 0xff
1209
+ const l1a: i32 = toI32(l1f >>> 8) & 0xff
1197
1210
  r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
1198
- const l2e: u32 = ctSelect((l2 >>> 8) | (l2 << 24), 0xffffffff, 0)
1199
- const l2a: i32 = toI32(l2 >>> 24) & 0xff
1200
- const l2b: i32 = toI32(l2e >>> 8) & 0xff
1201
- const l2c: i32 = toI32(l2e) & 0xff
1202
- const l2d: i32 = toI32(l2) & 0xff
1211
+ const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
1212
+ const l2d: i32 = toI32(l2e) & 0xff
1213
+ const l2c: i32 = toI32(l2e >>> 8) & 0xff
1214
+ const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
1215
+ const l2b: i32 = toI32(l2f) & 0xff
1216
+ const l2a: i32 = toI32(l2f >>> 8) & 0xff
1203
1217
  r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
1204
- const l3e: u32 = ctSelect((l3 >>> 8) | (l3 << 24), 0xffffffff, 0)
1205
- const l3a: i32 = toI32(l3 >>> 24) & 0xff
1206
- const l3b: i32 = toI32(l3e >>> 8) & 0xff
1207
- const l3c: i32 = toI32(l3e) & 0xff
1208
- const l3d: i32 = toI32(l3) & 0xff
1218
+ const l3e: u32 = ctSelect(l3, 0xffffffff, 0)
1219
+ const l3d: i32 = toI32(l3e) & 0xff
1220
+ const l3c: i32 = toI32(l3e >>> 8) & 0xff
1221
+ const l3f: u32 = ctSelect(l3e >>> 16, 0xffffffff, 0)
1222
+ const l3b: i32 = toI32(l3f) & 0xff
1223
+ const l3a: i32 = toI32(l3f >>> 8) & 0xff
1209
1224
  r3 ^= st[3126 + n] ^ (((st[3144 + l3a] + st[3400 + l3b]) ^ st[3656 + l3c]) + st[3912 + l3d])
1210
- const r0e: u32 = ctSelect((r0 >>> 8) | (r0 << 24), 0xffffffff, 0)
1211
- const r0a: i32 = toI32(r0 >>> 24) & 0xff
1212
- const r0b: i32 = toI32(r0e >>> 8) & 0xff
1213
- const r0c: i32 = toI32(r0e) & 0xff
1214
- const r0d: i32 = toI32(r0) & 0xff
1225
+ const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
1226
+ const r0d: i32 = toI32(r0e) & 0xff
1227
+ const r0c: i32 = toI32(r0e >>> 8) & 0xff
1228
+ const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
1229
+ const r0b: i32 = toI32(r0f) & 0xff
1230
+ const r0a: i32 = toI32(r0f >>> 8) & 0xff
1215
1231
  l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
1216
- const r1e: u32 = ctSelect((r1 >>> 8) | (r1 << 24), 0xffffffff, 0)
1217
- const r1a: i32 = toI32(r1 >>> 24) & 0xff
1218
- const r1b: i32 = toI32(r1e >>> 8) & 0xff
1219
- const r1c: i32 = toI32(r1e) & 0xff
1220
- const r1d: i32 = toI32(r1) & 0xff
1232
+ const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
1233
+ const r1d: i32 = toI32(r1e) & 0xff
1234
+ const r1c: i32 = toI32(r1e >>> 8) & 0xff
1235
+ const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
1236
+ const r1b: i32 = toI32(r1f) & 0xff
1237
+ const r1a: i32 = toI32(r1f >>> 8) & 0xff
1221
1238
  l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
1222
- const r2e: u32 = ctSelect((r2 >>> 8) | (r2 << 24), 0xffffffff, 0)
1223
- const r2a: i32 = toI32(r2 >>> 24) & 0xff
1224
- const r2b: i32 = toI32(r2e >>> 8) & 0xff
1225
- const r2c: i32 = toI32(r2e) & 0xff
1226
- const r2d: i32 = toI32(r2) & 0xff
1239
+ const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
1240
+ const r2d: i32 = toI32(r2e) & 0xff
1241
+ const r2c: i32 = toI32(r2e >>> 8) & 0xff
1242
+ const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
1243
+ const r2b: i32 = toI32(r2f) & 0xff
1244
+ const r2a: i32 = toI32(r2f >>> 8) & 0xff
1227
1245
  l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
1228
- const r3e: u32 = ctSelect((r3 >>> 8) | (r3 << 24), 0xffffffff, 0)
1229
- const r3a: i32 = toI32(r3 >>> 24) & 0xff
1230
- const r3b: i32 = toI32(r3e >>> 8) & 0xff
1231
- const r3c: i32 = toI32(r3e) & 0xff
1232
- const r3d: i32 = toI32(r3) & 0xff
1246
+ const r3e: u32 = ctSelect(r3, 0xffffffff, 0)
1247
+ const r3d: i32 = toI32(r3e) & 0xff
1248
+ const r3c: i32 = toI32(r3e >>> 8) & 0xff
1249
+ const r3f: u32 = ctSelect(r3e >>> 16, 0xffffffff, 0)
1250
+ const r3b: i32 = toI32(r3f) & 0xff
1251
+ const r3a: i32 = toI32(r3f >>> 8) & 0xff
1233
1252
  l3 ^= st[3126 + n + 1] ^ (((st[3144 + r3a] + st[3400 + r3b]) ^ st[3656 + r3c]) + st[3912 + r3d])
1234
1253
  }
1235
1254
  const t0: u32 = r0
@@ -1277,65 +1296,75 @@ const bcryptBody5 = (st: u32[]): void => {
1277
1296
  l3 ^= st[3126]
1278
1297
  l4 ^= st[4168]
1279
1298
  for (let n: i32 = 1; n < 17; n += 2) {
1280
- const l0e: u32 = ctSelect((l0 >>> 8) | (l0 << 24), 0xffffffff, 0)
1281
- const l0a: i32 = toI32(l0 >>> 24) & 0xff
1282
- const l0b: i32 = toI32(l0e >>> 8) & 0xff
1283
- const l0c: i32 = toI32(l0e) & 0xff
1284
- const l0d: i32 = toI32(l0) & 0xff
1299
+ const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
1300
+ const l0d: i32 = toI32(l0e) & 0xff
1301
+ const l0c: i32 = toI32(l0e >>> 8) & 0xff
1302
+ const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
1303
+ const l0b: i32 = toI32(l0f) & 0xff
1304
+ const l0a: i32 = toI32(l0f >>> 8) & 0xff
1285
1305
  r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
1286
- const l1e: u32 = ctSelect((l1 >>> 8) | (l1 << 24), 0xffffffff, 0)
1287
- const l1a: i32 = toI32(l1 >>> 24) & 0xff
1288
- const l1b: i32 = toI32(l1e >>> 8) & 0xff
1289
- const l1c: i32 = toI32(l1e) & 0xff
1290
- const l1d: i32 = toI32(l1) & 0xff
1306
+ const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
1307
+ const l1d: i32 = toI32(l1e) & 0xff
1308
+ const l1c: i32 = toI32(l1e >>> 8) & 0xff
1309
+ const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
1310
+ const l1b: i32 = toI32(l1f) & 0xff
1311
+ const l1a: i32 = toI32(l1f >>> 8) & 0xff
1291
1312
  r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
1292
- const l2e: u32 = ctSelect((l2 >>> 8) | (l2 << 24), 0xffffffff, 0)
1293
- const l2a: i32 = toI32(l2 >>> 24) & 0xff
1294
- const l2b: i32 = toI32(l2e >>> 8) & 0xff
1295
- const l2c: i32 = toI32(l2e) & 0xff
1296
- const l2d: i32 = toI32(l2) & 0xff
1313
+ const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
1314
+ const l2d: i32 = toI32(l2e) & 0xff
1315
+ const l2c: i32 = toI32(l2e >>> 8) & 0xff
1316
+ const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
1317
+ const l2b: i32 = toI32(l2f) & 0xff
1318
+ const l2a: i32 = toI32(l2f >>> 8) & 0xff
1297
1319
  r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
1298
- const l3e: u32 = ctSelect((l3 >>> 8) | (l3 << 24), 0xffffffff, 0)
1299
- const l3a: i32 = toI32(l3 >>> 24) & 0xff
1300
- const l3b: i32 = toI32(l3e >>> 8) & 0xff
1301
- const l3c: i32 = toI32(l3e) & 0xff
1302
- const l3d: i32 = toI32(l3) & 0xff
1320
+ const l3e: u32 = ctSelect(l3, 0xffffffff, 0)
1321
+ const l3d: i32 = toI32(l3e) & 0xff
1322
+ const l3c: i32 = toI32(l3e >>> 8) & 0xff
1323
+ const l3f: u32 = ctSelect(l3e >>> 16, 0xffffffff, 0)
1324
+ const l3b: i32 = toI32(l3f) & 0xff
1325
+ const l3a: i32 = toI32(l3f >>> 8) & 0xff
1303
1326
  r3 ^= st[3126 + n] ^ (((st[3144 + l3a] + st[3400 + l3b]) ^ st[3656 + l3c]) + st[3912 + l3d])
1304
- const l4e: u32 = ctSelect((l4 >>> 8) | (l4 << 24), 0xffffffff, 0)
1305
- const l4a: i32 = toI32(l4 >>> 24) & 0xff
1306
- const l4b: i32 = toI32(l4e >>> 8) & 0xff
1307
- const l4c: i32 = toI32(l4e) & 0xff
1308
- const l4d: i32 = toI32(l4) & 0xff
1327
+ const l4e: u32 = ctSelect(l4, 0xffffffff, 0)
1328
+ const l4d: i32 = toI32(l4e) & 0xff
1329
+ const l4c: i32 = toI32(l4e >>> 8) & 0xff
1330
+ const l4f: u32 = ctSelect(l4e >>> 16, 0xffffffff, 0)
1331
+ const l4b: i32 = toI32(l4f) & 0xff
1332
+ const l4a: i32 = toI32(l4f >>> 8) & 0xff
1309
1333
  r4 ^= st[4168 + n] ^ (((st[4186 + l4a] + st[4442 + l4b]) ^ st[4698 + l4c]) + st[4954 + l4d])
1310
- const r0e: u32 = ctSelect((r0 >>> 8) | (r0 << 24), 0xffffffff, 0)
1311
- const r0a: i32 = toI32(r0 >>> 24) & 0xff
1312
- const r0b: i32 = toI32(r0e >>> 8) & 0xff
1313
- const r0c: i32 = toI32(r0e) & 0xff
1314
- const r0d: i32 = toI32(r0) & 0xff
1334
+ const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
1335
+ const r0d: i32 = toI32(r0e) & 0xff
1336
+ const r0c: i32 = toI32(r0e >>> 8) & 0xff
1337
+ const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
1338
+ const r0b: i32 = toI32(r0f) & 0xff
1339
+ const r0a: i32 = toI32(r0f >>> 8) & 0xff
1315
1340
  l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
1316
- const r1e: u32 = ctSelect((r1 >>> 8) | (r1 << 24), 0xffffffff, 0)
1317
- const r1a: i32 = toI32(r1 >>> 24) & 0xff
1318
- const r1b: i32 = toI32(r1e >>> 8) & 0xff
1319
- const r1c: i32 = toI32(r1e) & 0xff
1320
- const r1d: i32 = toI32(r1) & 0xff
1341
+ const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
1342
+ const r1d: i32 = toI32(r1e) & 0xff
1343
+ const r1c: i32 = toI32(r1e >>> 8) & 0xff
1344
+ const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
1345
+ const r1b: i32 = toI32(r1f) & 0xff
1346
+ const r1a: i32 = toI32(r1f >>> 8) & 0xff
1321
1347
  l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
1322
- const r2e: u32 = ctSelect((r2 >>> 8) | (r2 << 24), 0xffffffff, 0)
1323
- const r2a: i32 = toI32(r2 >>> 24) & 0xff
1324
- const r2b: i32 = toI32(r2e >>> 8) & 0xff
1325
- const r2c: i32 = toI32(r2e) & 0xff
1326
- const r2d: i32 = toI32(r2) & 0xff
1348
+ const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
1349
+ const r2d: i32 = toI32(r2e) & 0xff
1350
+ const r2c: i32 = toI32(r2e >>> 8) & 0xff
1351
+ const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
1352
+ const r2b: i32 = toI32(r2f) & 0xff
1353
+ const r2a: i32 = toI32(r2f >>> 8) & 0xff
1327
1354
  l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
1328
- const r3e: u32 = ctSelect((r3 >>> 8) | (r3 << 24), 0xffffffff, 0)
1329
- const r3a: i32 = toI32(r3 >>> 24) & 0xff
1330
- const r3b: i32 = toI32(r3e >>> 8) & 0xff
1331
- const r3c: i32 = toI32(r3e) & 0xff
1332
- const r3d: i32 = toI32(r3) & 0xff
1355
+ const r3e: u32 = ctSelect(r3, 0xffffffff, 0)
1356
+ const r3d: i32 = toI32(r3e) & 0xff
1357
+ const r3c: i32 = toI32(r3e >>> 8) & 0xff
1358
+ const r3f: u32 = ctSelect(r3e >>> 16, 0xffffffff, 0)
1359
+ const r3b: i32 = toI32(r3f) & 0xff
1360
+ const r3a: i32 = toI32(r3f >>> 8) & 0xff
1333
1361
  l3 ^= st[3126 + n + 1] ^ (((st[3144 + r3a] + st[3400 + r3b]) ^ st[3656 + r3c]) + st[3912 + r3d])
1334
- const r4e: u32 = ctSelect((r4 >>> 8) | (r4 << 24), 0xffffffff, 0)
1335
- const r4a: i32 = toI32(r4 >>> 24) & 0xff
1336
- const r4b: i32 = toI32(r4e >>> 8) & 0xff
1337
- const r4c: i32 = toI32(r4e) & 0xff
1338
- const r4d: i32 = toI32(r4) & 0xff
1362
+ const r4e: u32 = ctSelect(r4, 0xffffffff, 0)
1363
+ const r4d: i32 = toI32(r4e) & 0xff
1364
+ const r4c: i32 = toI32(r4e >>> 8) & 0xff
1365
+ const r4f: u32 = ctSelect(r4e >>> 16, 0xffffffff, 0)
1366
+ const r4b: i32 = toI32(r4f) & 0xff
1367
+ const r4a: i32 = toI32(r4f >>> 8) & 0xff
1339
1368
  l4 ^= st[4168 + n + 1] ^ (((st[4186 + r4a] + st[4442 + r4b]) ^ st[4698 + r4c]) + st[4954 + r4d])
1340
1369
  }
1341
1370
  const t0: u32 = r0
@@ -1391,35 +1420,40 @@ const bcryptBody6 = (st: u32[]): void => {
1391
1420
  l4 ^= st[4168]
1392
1421
  l5 ^= st[5210]
1393
1422
  for (let n: i32 = 1; n < 17; n += 2) {
1394
- const l0e: u32 = ctSelect(l0 >>> 8, 0xffffffff, 0)
1395
- const l0a: i32 = toI32(l0 >>> 24) & 0xff
1396
- const l0b: i32 = toI32(l0e >>> 8) & 0xff
1397
- const l0c: i32 = toI32(l0e) & 0xff
1398
- const l0d: i32 = toI32(l0) & 0xff
1423
+ const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
1424
+ const l0d: i32 = toI32(l0e) & 0xff
1425
+ const l0c: i32 = toI32(l0e >>> 8) & 0xff
1426
+ const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
1427
+ const l0b: i32 = toI32(l0f) & 0xff
1428
+ const l0a: i32 = toI32(l0f >>> 8) & 0xff
1399
1429
  r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
1400
- const l1e: u32 = ctSelect(l1 >>> 8, 0xffffffff, 0)
1401
- const l1a: i32 = toI32(l1 >>> 24) & 0xff
1402
- const l1b: i32 = toI32(l1e >>> 8) & 0xff
1403
- const l1c: i32 = toI32(l1e) & 0xff
1404
- const l1d: i32 = toI32(l1) & 0xff
1430
+ const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
1431
+ const l1d: i32 = toI32(l1e) & 0xff
1432
+ const l1c: i32 = toI32(l1e >>> 8) & 0xff
1433
+ const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
1434
+ const l1b: i32 = toI32(l1f) & 0xff
1435
+ const l1a: i32 = toI32(l1f >>> 8) & 0xff
1405
1436
  r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
1406
- const l2e: u32 = ctSelect(l2 >>> 8, 0xffffffff, 0)
1407
- const l2a: i32 = toI32(l2 >>> 24) & 0xff
1408
- const l2b: i32 = toI32(l2e >>> 8) & 0xff
1409
- const l2c: i32 = toI32(l2e) & 0xff
1410
- const l2d: i32 = toI32(l2) & 0xff
1437
+ const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
1438
+ const l2d: i32 = toI32(l2e) & 0xff
1439
+ const l2c: i32 = toI32(l2e >>> 8) & 0xff
1440
+ const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
1441
+ const l2b: i32 = toI32(l2f) & 0xff
1442
+ const l2a: i32 = toI32(l2f >>> 8) & 0xff
1411
1443
  r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
1412
- const l3e: u32 = ctSelect(l3 >>> 8, 0xffffffff, 0)
1413
- const l3a: i32 = toI32(l3 >>> 24) & 0xff
1414
- const l3b: i32 = toI32(l3e >>> 8) & 0xff
1415
- const l3c: i32 = toI32(l3e) & 0xff
1416
- const l3d: i32 = toI32(l3) & 0xff
1444
+ const l3e: u32 = ctSelect(l3, 0xffffffff, 0)
1445
+ const l3d: i32 = toI32(l3e) & 0xff
1446
+ const l3c: i32 = toI32(l3e >>> 8) & 0xff
1447
+ const l3f: u32 = ctSelect(l3e >>> 16, 0xffffffff, 0)
1448
+ const l3b: i32 = toI32(l3f) & 0xff
1449
+ const l3a: i32 = toI32(l3f >>> 8) & 0xff
1417
1450
  r3 ^= st[3126 + n] ^ (((st[3144 + l3a] + st[3400 + l3b]) ^ st[3656 + l3c]) + st[3912 + l3d])
1418
- const l4e: u32 = ctSelect(l4 >>> 8, 0xffffffff, 0)
1419
- const l4a: i32 = toI32(l4 >>> 24) & 0xff
1420
- const l4b: i32 = toI32(l4e >>> 8) & 0xff
1421
- const l4c: i32 = toI32(l4e) & 0xff
1422
- const l4d: i32 = toI32(l4) & 0xff
1451
+ const l4e: u32 = ctSelect(l4, 0xffffffff, 0)
1452
+ const l4d: i32 = toI32(l4e) & 0xff
1453
+ const l4c: i32 = toI32(l4e >>> 8) & 0xff
1454
+ const l4f: u32 = ctSelect(l4e >>> 16, 0xffffffff, 0)
1455
+ const l4b: i32 = toI32(l4f) & 0xff
1456
+ const l4a: i32 = toI32(l4f >>> 8) & 0xff
1423
1457
  r4 ^= st[4168 + n] ^ (((st[4186 + l4a] + st[4442 + l4b]) ^ st[4698 + l4c]) + st[4954 + l4d])
1424
1458
  const l5e: u32 = ctSelect(l5 >>> 8, 0xffffffff, 0)
1425
1459
  const l5a: i32 = toI32(l5 >>> 24) & 0xff
@@ -1427,35 +1461,40 @@ const bcryptBody6 = (st: u32[]): void => {
1427
1461
  const l5c: i32 = toI32(l5e) & 0xff
1428
1462
  const l5d: i32 = toI32(l5) & 0xff
1429
1463
  r5 ^= st[5210 + n] ^ (((st[5228 + l5a] + st[5484 + l5b]) ^ st[5740 + l5c]) + st[5996 + l5d])
1430
- const r0e: u32 = ctSelect(r0 >>> 8, 0xffffffff, 0)
1431
- const r0a: i32 = toI32(r0 >>> 24) & 0xff
1432
- const r0b: i32 = toI32(r0e >>> 8) & 0xff
1433
- const r0c: i32 = toI32(r0e) & 0xff
1434
- const r0d: i32 = toI32(r0) & 0xff
1464
+ const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
1465
+ const r0d: i32 = toI32(r0e) & 0xff
1466
+ const r0c: i32 = toI32(r0e >>> 8) & 0xff
1467
+ const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
1468
+ const r0b: i32 = toI32(r0f) & 0xff
1469
+ const r0a: i32 = toI32(r0f >>> 8) & 0xff
1435
1470
  l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
1436
- const r1e: u32 = ctSelect(r1 >>> 8, 0xffffffff, 0)
1437
- const r1a: i32 = toI32(r1 >>> 24) & 0xff
1438
- const r1b: i32 = toI32(r1e >>> 8) & 0xff
1439
- const r1c: i32 = toI32(r1e) & 0xff
1440
- const r1d: i32 = toI32(r1) & 0xff
1471
+ const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
1472
+ const r1d: i32 = toI32(r1e) & 0xff
1473
+ const r1c: i32 = toI32(r1e >>> 8) & 0xff
1474
+ const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
1475
+ const r1b: i32 = toI32(r1f) & 0xff
1476
+ const r1a: i32 = toI32(r1f >>> 8) & 0xff
1441
1477
  l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
1442
- const r2e: u32 = ctSelect(r2 >>> 8, 0xffffffff, 0)
1443
- const r2a: i32 = toI32(r2 >>> 24) & 0xff
1444
- const r2b: i32 = toI32(r2e >>> 8) & 0xff
1445
- const r2c: i32 = toI32(r2e) & 0xff
1446
- const r2d: i32 = toI32(r2) & 0xff
1478
+ const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
1479
+ const r2d: i32 = toI32(r2e) & 0xff
1480
+ const r2c: i32 = toI32(r2e >>> 8) & 0xff
1481
+ const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
1482
+ const r2b: i32 = toI32(r2f) & 0xff
1483
+ const r2a: i32 = toI32(r2f >>> 8) & 0xff
1447
1484
  l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
1448
- const r3e: u32 = ctSelect(r3 >>> 8, 0xffffffff, 0)
1449
- const r3a: i32 = toI32(r3 >>> 24) & 0xff
1450
- const r3b: i32 = toI32(r3e >>> 8) & 0xff
1451
- const r3c: i32 = toI32(r3e) & 0xff
1452
- const r3d: i32 = toI32(r3) & 0xff
1485
+ const r3e: u32 = ctSelect(r3, 0xffffffff, 0)
1486
+ const r3d: i32 = toI32(r3e) & 0xff
1487
+ const r3c: i32 = toI32(r3e >>> 8) & 0xff
1488
+ const r3f: u32 = ctSelect(r3e >>> 16, 0xffffffff, 0)
1489
+ const r3b: i32 = toI32(r3f) & 0xff
1490
+ const r3a: i32 = toI32(r3f >>> 8) & 0xff
1453
1491
  l3 ^= st[3126 + n + 1] ^ (((st[3144 + r3a] + st[3400 + r3b]) ^ st[3656 + r3c]) + st[3912 + r3d])
1454
- const r4e: u32 = ctSelect(r4 >>> 8, 0xffffffff, 0)
1455
- const r4a: i32 = toI32(r4 >>> 24) & 0xff
1456
- const r4b: i32 = toI32(r4e >>> 8) & 0xff
1457
- const r4c: i32 = toI32(r4e) & 0xff
1458
- const r4d: i32 = toI32(r4) & 0xff
1492
+ const r4e: u32 = ctSelect(r4, 0xffffffff, 0)
1493
+ const r4d: i32 = toI32(r4e) & 0xff
1494
+ const r4c: i32 = toI32(r4e >>> 8) & 0xff
1495
+ const r4f: u32 = ctSelect(r4e >>> 16, 0xffffffff, 0)
1496
+ const r4b: i32 = toI32(r4f) & 0xff
1497
+ const r4a: i32 = toI32(r4f >>> 8) & 0xff
1459
1498
  l4 ^= st[4168 + n + 1] ^ (((st[4186 + r4a] + st[4442 + r4b]) ^ st[4698 + r4c]) + st[4954 + r4d])
1460
1499
  const r5e: u32 = ctSelect(r5 >>> 8, 0xffffffff, 0)
1461
1500
  const r5a: i32 = toI32(r5 >>> 24) & 0xff
@@ -81,7 +81,25 @@
81
81
  * Written from RFC 9112 and RFC 9110, not ported from another implementation.
82
82
  */
83
83
  import { copyBytes } from "nish/bytes"
84
- import { extract, loadU8x16, u8x16 } from "nish:simd"
84
+ import {
85
+ and,
86
+ any,
87
+ bitmask,
88
+ eq,
89
+ extract,
90
+ gt,
91
+ loadU8x16,
92
+ lt,
93
+ mask8x16,
94
+ ne,
95
+ or,
96
+ replace,
97
+ select,
98
+ splatU8x16,
99
+ store,
100
+ subWrapping,
101
+ u8x16,
102
+ } from "nish:simd"
85
103
 
86
104
  /** `next()`: the input so far holds no further event; feed more. */
87
105
  export const HTTP1_NEED_MORE: i32 = 0
@@ -669,8 +687,9 @@ const http1TakeLine = (p: Http1Parser, limit: i32, overStatus: i32): i32 => {
669
687
  * third (0x57ffffff). No byte below 33 or above 126 is a tchar.
670
688
  * `http1IsTokenByte` reads them as two 64-bit masks, one for the bytes 0 to
671
689
  * 63 and one for 64 to 127, so the test is a select and a shift with no
672
- * branch on the byte: a name or method scan is the parser's hottest loop
673
- * after the line scan (`bench/http1-parse`).
690
+ * branch on the byte. A field name goes sixteen bytes at a time through
691
+ * `http1NonTokenLanes`, the same set; this test is for the method, a trailer's
692
+ * name, and a name's last bytes when fewer than sixteen are left in the head.
674
693
  */
675
694
  const HTTP1_TCHAR_32: i32 = 67071226
676
695
  const HTTP1_TCHAR_64: i32 = -939524098
@@ -684,6 +703,66 @@ export const http1IsTokenByte = (c: i32): boolean => {
684
703
  return c >= 0 && c < 128 && ((word >> toU64(c & 63)) & toU64(1)) !== toU64(0)
685
704
  }
686
705
 
706
+ /**
707
+ * Which lanes of `v` are not tchars, as `http1IsTokenByte` answers for each,
708
+ * bit `k` for lane `k`: a byte outside 33 to 126, or one of the seventeen
709
+ * delimiters among them, `"` `(` `)` `,` `/` `:` to `@` (seven), `[` `\` `]`
710
+ * `{` and `}`. A name is mostly one vector, so these compares run once for
711
+ * the sixteen bytes where the table test ran once for each.
712
+ */
713
+ const http1NonTokenLanes = (v: u8x16): i32 => {
714
+ const outside: mask8x16 = gt(subWrapping(v, splatU8x16(33)), splatU8x16(93))
715
+ const quote: mask8x16 = or(eq(v, splatU8x16(34)), lt(subWrapping(v, splatU8x16(40)), splatU8x16(2)))
716
+ const comma: mask8x16 = or(eq(v, splatU8x16(44)), eq(v, splatU8x16(47)))
717
+ const colon: mask8x16 = lt(subWrapping(v, splatU8x16(58)), splatU8x16(7))
718
+ const bracket: mask8x16 = lt(subWrapping(v, splatU8x16(91)), splatU8x16(3))
719
+ const brace: mask8x16 = or(eq(v, splatU8x16(123)), eq(v, splatU8x16(125)))
720
+ return bitmask(or(or(or(outside, quote), or(comma, colon)), or(bracket, brace)))
721
+ }
722
+
723
+ /**
724
+ * Lowercases a field name in `head` from `k`, sixteen bytes at a time, and
725
+ * answers where it ends: the first byte before `stop` that is not a tchar, or
726
+ * `stop`. Each vector's name lanes are lowered, and every other lane is
727
+ * stored back as it was, so the value after the name and the bytes past the
728
+ * line keep their case. A tail of under sixteen bytes before `head`'s end
729
+ * goes a byte at a time. The answer and the bytes written are the byte loop's.
730
+ */
731
+ const http1LowerName = (head: u8[], k0: i32, stop: i32): i32 => {
732
+ // Lane `j` holds `j`: the name's lanes are those below its length.
733
+ const lanes: u8x16 = u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
734
+ let k: i32 = k0
735
+ while (k >= 0 && k < stop && k <= toI32(head.length) - 16) {
736
+ const v: u8x16 = loadU8x16(head, k)
737
+ const bad: i32 = http1NonTokenLanes(v)
738
+ let run: i32 = 16
739
+ if (bad !== 0) {
740
+ run = toI32(31) - toI32(Math.clz32(toU32(bad & -bad)))
741
+ }
742
+ if (run > stop - k) {
743
+ run = stop - k
744
+ }
745
+ const upper: mask8x16 = and(
746
+ lt(subWrapping(v, splatU8x16(65)), splatU8x16(26)),
747
+ lt(lanes, splatU8x16(toU8(run)))
748
+ )
749
+ store(select(upper, or(v, splatU8x16(32)), v), head, k)
750
+ k += run
751
+ if (run < 16) {
752
+ return k
753
+ }
754
+ }
755
+ while (k >= 0 && k < stop && k < toI32(head.length)) {
756
+ const c: i32 = toI32(head[k])
757
+ if (!http1IsTokenByte(c)) {
758
+ break
759
+ }
760
+ head[k] = toU8(c >= 65 && c <= 90 ? c + 32 : c)
761
+ k += 1
762
+ }
763
+ return k
764
+ }
765
+
687
766
  /** Whether `c` may appear in a field value (RFC 9110 §5.5): HTAB, SP, VCHAR or obs-text. */
688
767
  export const http1IsValueByte = (c: i32): boolean => c === 9 || (c >= 32 && c !== 127)
689
768
 
@@ -1012,18 +1091,7 @@ const http1FieldLine = (p: Http1Parser, keep: boolean): i32 => {
1012
1091
  let i: i32 = a
1013
1092
  if (keep) {
1014
1093
  at = http1HeadAppend(p, a, b)
1015
- const head: u8[] = p.head
1016
- let k: i32 = at
1017
- const stop: i32 = at + (b - a)
1018
- while (k >= 0 && k < stop && k < toI32(head.length)) {
1019
- const c: i32 = toI32(head[k])
1020
- if (!http1IsTokenByte(c)) {
1021
- break
1022
- }
1023
- head[k] = toU8(c >= 65 && c <= 90 ? c + 32 : c)
1024
- k += 1
1025
- }
1026
- i = a + (k - at)
1094
+ i = a + (http1LowerName(p.head, at, at + (b - a)) - at)
1027
1095
  } else {
1028
1096
  while (i >= 0 && i < b && i < toI32(buf.length) && http1IsTokenByte(toI32(buf[i]))) {
1029
1097
  i += 1
@@ -1046,7 +1114,12 @@ const http1FieldLine = (p: Http1Parser, keep: boolean): i32 => {
1046
1114
  if (keep) {
1047
1115
  let valueStart: i32 = nameEnd + 1
1048
1116
  let valueEnd: i32 = b
1049
- while (valueStart >= 0 && valueStart < valueEnd && valueStart < n && http1IsOws(toI32(buf[valueStart]))) {
1117
+ while (
1118
+ valueStart >= 0 &&
1119
+ valueStart < valueEnd &&
1120
+ valueStart < toI32(buf.length) &&
1121
+ http1IsOws(toI32(buf[valueStart]))
1122
+ ) {
1050
1123
  valueStart += 1
1051
1124
  }
1052
1125
  while (valueEnd > valueStart && valueEnd - 1 >= 0 && http1IsOws(toI32(buf[valueEnd - 1]))) {
@@ -1591,14 +1664,39 @@ const http1BytesAreToken = (bytes: u8[]): boolean => {
1591
1664
  return toI32(bytes.length) > 0
1592
1665
  }
1593
1666
 
1594
- /** Whether every byte of `bytes` may stand in a field value. */
1667
+ /**
1668
+ * Whether no lane of `v` is a byte a field value may not hold: below 32 and
1669
+ * not HTAB, or DEL. `http1IsValueByte` on sixteen bytes at once, exactly, so
1670
+ * a vector may overlap one already checked.
1671
+ */
1672
+ const http1LanesAreFieldText = (v: u8x16): boolean => {
1673
+ const control: mask8x16 = and(lt(v, splatU8x16(32)), ne(v, splatU8x16(9)))
1674
+ return !any(or(control, eq(v, splatU8x16(127))))
1675
+ }
1676
+
1677
+ /**
1678
+ * Whether every byte of `bytes` may stand in a field value: sixteen at a
1679
+ * time, the last vector ending at the last byte and overlapping the one
1680
+ * before it, and one at a time below sixteen.
1681
+ */
1595
1682
  const http1BytesAreFieldText = (bytes: u8[]): boolean => {
1596
- for (const b of bytes) {
1597
- if (!http1IsValueByte(toI32(b))) {
1683
+ const n: i32 = toI32(bytes.length)
1684
+ if (n < 16) {
1685
+ for (let k: i32 = 0; k < n; k += 1) {
1686
+ if (!http1IsValueByte(toI32(bytes[k]))) {
1687
+ return false
1688
+ }
1689
+ }
1690
+ return true
1691
+ }
1692
+ let k: i32 = 0
1693
+ while (k >= 0 && k <= n - 16) {
1694
+ if (!http1LanesAreFieldText(loadU8x16(bytes, k))) {
1598
1695
  return false
1599
1696
  }
1697
+ k += 16
1600
1698
  }
1601
- return true
1699
+ return k === n || http1LanesAreFieldText(loadU8x16(bytes, n - 16))
1602
1700
  }
1603
1701
 
1604
1702
  /** Whether the octets of `bytes` spell `word`, which is lowercase, in any ASCII case: a field name compared as RFC 9110 §5.1 says. */
@@ -1628,6 +1726,14 @@ const http1DecimalDigits = (n: i32): i32 => {
1628
1726
  /** Writes `text` at `out[at ..)`, which the caller has made sure holds it, and answers where it ends. */
1629
1727
  export const http1PutText = (out: u8[], at: i32, text: string): i32 => {
1630
1728
  const n: i32 = toI32(text.length)
1729
+ if (at >= 0 && at <= toI32(out.length) - n) {
1730
+ // It fits, the case every caller makes sure of: one test, then a loop
1731
+ // with no bounds check in it.
1732
+ for (let k: i32 = 0; k < n; k += 1) {
1733
+ out[at + k] = toU8(text.charCodeAt(k))
1734
+ }
1735
+ return at + n
1736
+ }
1631
1737
  for (let k: i32 = 0; k < n && at + k < toI32(out.length); k += 1) {
1632
1738
  if (at + k >= 0) {
1633
1739
  out[at + k] = toU8(text.charCodeAt(k))
@@ -1669,6 +1775,50 @@ const http1PutBytes = (out: u8[], at: i32, bytes: u8[]): i32 => {
1669
1775
  return at + n
1670
1776
  }
1671
1777
 
1778
+ /**
1779
+ * Writes `text`, at most sixteen ASCII bytes, at `out[at ..)`, likewise, as
1780
+ * one sixteen-byte store of `v`, which holds `text` in its first lanes: when
1781
+ * `at + 16` does not pass `limit`, the end of the head being written, whose
1782
+ * every byte from `at` on is written after this one, so the lanes past
1783
+ * `text` are overwritten before the head is done. Byte by byte otherwise.
1784
+ */
1785
+ const http1PutFixed = (out: u8[], at: i32, limit: i32, v: u8x16, text: string): i32 => {
1786
+ if (at >= 0 && at <= limit - 16 && limit <= toI32(out.length)) {
1787
+ store(v, out, at)
1788
+ return at + toI32(text.length)
1789
+ }
1790
+ return http1PutText(out, at, text)
1791
+ }
1792
+
1793
+ /**
1794
+ * Writes `HTTP/1.1 `, the three digits of `status`, which is 100 to 599, and
1795
+ * a space at `out[at ..)`, likewise: one store, the digits replacing three
1796
+ * lanes of the constant.
1797
+ */
1798
+ const http1PutStatusLine = (out: u8[], at: i32, limit: i32, status: i32): i32 => {
1799
+ const hundreds: i32 = status / 100
1800
+ const tens: i32 = (status / 10) % 10
1801
+ const ones: i32 = status % 10
1802
+ if (at >= 0 && at <= limit - 16 && limit <= toI32(out.length)) {
1803
+ // "HTTP/1.1 000 ", and three lanes the head's next bytes overwrite.
1804
+ const line: u8x16 = u8x16(72, 84, 84, 80, 47, 49, 46, 49, 32, 48, 48, 48, 32, 32, 32, 32)
1805
+ store(
1806
+ replace(replace(replace(line, 9, toU8(48 + hundreds)), 10, toU8(48 + tens)), 11, toU8(48 + ones)),
1807
+ out,
1808
+ at
1809
+ )
1810
+ return at + 13
1811
+ }
1812
+ const end: i32 = http1PutText(out, at, "HTTP/1.1 ")
1813
+ if (end >= 0 && end < toI32(out.length) - 3) {
1814
+ out[end] = toU8(48 + hundreds)
1815
+ out[end + 1] = toU8(48 + tens)
1816
+ out[end + 2] = toU8(48 + ones)
1817
+ out[end + 3] = 32
1818
+ }
1819
+ return end + 4
1820
+ }
1821
+
1672
1822
  /** Writes the decimal digits of `n`, which is not negative, at `out[at ..)`, likewise. */
1673
1823
  const http1PutDecimal = (out: u8[], at: i32, n: i32): i32 => {
1674
1824
  const digits: i32 = http1DecimalDigits(n)
@@ -1725,7 +1875,7 @@ export const http1WriteResponseHead = (
1725
1875
  // is written, in 64 bits so that no caller's lengths can wrap the sum.
1726
1876
  let need: i64 = toI64(17) + toI64(reason.length)
1727
1877
  let sendDate: boolean = status >= 200 && toI32(date.length) > 0
1728
- for (let i: i32 = 0; i < count && i < toI32(values.length); i += 1) {
1878
+ for (let i: i32 = 0; i < toI32(names.length) && i < toI32(values.length); i += 1) {
1729
1879
  const name: u8[] = names[i]
1730
1880
  const value: u8[] = values[i]
1731
1881
  if (!http1BytesAreToken(name) || !http1BytesAreFieldText(value)) {
@@ -1757,41 +1907,49 @@ export const http1WriteResponseHead = (
1757
1907
  if (at < 0 || at > toI32(out.length) || need > toI64(toI32(out.length) - at)) {
1758
1908
  return HTTP1_NO_ROOM
1759
1909
  }
1760
- let end: i32 = http1PutText(out, at, "HTTP/1.1 ")
1761
1910
  // A status is three digits, checked above: no division loop for them.
1762
- if (end >= 0 && end < toI32(out.length) - 3) {
1763
- const hundreds: i32 = status / 100
1764
- const tens: i32 = status / 10
1765
- const tensDigit: i32 = tens % 10
1766
- const ones: i32 = status % 10
1767
- out[end] = toU8(48 + hundreds)
1768
- out[end + 1] = toU8(48 + tensDigit)
1769
- out[end + 2] = toU8(48 + ones)
1770
- out[end + 3] = 32
1771
- }
1772
- end = end + 4
1911
+ const limit: i32 = at + toI32(need)
1912
+ let end: i32 = http1PutStatusLine(out, at, limit, status)
1773
1913
  end = http1PutText(out, end, reason)
1774
1914
  end = http1PutCrlf(out, end)
1775
- for (let i: i32 = 0; i < count && i < toI32(values.length); i += 1) {
1915
+ for (let i: i32 = 0; i < toI32(names.length) && i < toI32(values.length); i += 1) {
1776
1916
  end = http1PutBytes(out, end, names[i])
1777
1917
  end = http1PutColonSpace(out, end)
1778
1918
  end = http1PutBytes(out, end, values[i])
1779
1919
  end = http1PutCrlf(out, end)
1780
1920
  }
1781
1921
  if (sendDate) {
1782
- end = http1PutText(out, end, "Date: ")
1922
+ end = http1PutFixed(
1923
+ out,
1924
+ end,
1925
+ limit,
1926
+ u8x16(68, 97, 116, 101, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32),
1927
+ "Date: "
1928
+ )
1783
1929
  end = http1PutBytes(out, end, date)
1784
1930
  end = http1PutCrlf(out, end)
1785
1931
  }
1786
1932
  if (bodyLength >= 0) {
1787
- end = http1PutText(out, end, "Content-Length: ")
1933
+ end = http1PutFixed(
1934
+ out,
1935
+ end,
1936
+ limit,
1937
+ u8x16(67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32),
1938
+ "Content-Length: "
1939
+ )
1788
1940
  end = http1PutDecimal(out, end, bodyLength)
1789
1941
  end = http1PutCrlf(out, end)
1790
1942
  } else if (bodyLength === HTTP1_CHUNKED) {
1791
1943
  end = http1PutText(out, end, "Transfer-Encoding: chunked\r\n")
1792
1944
  }
1793
1945
  if (toI32(connection.length) > 0) {
1794
- end = http1PutText(out, end, "Connection: ")
1946
+ end = http1PutFixed(
1947
+ out,
1948
+ end,
1949
+ limit,
1950
+ u8x16(67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 32, 32, 32, 32),
1951
+ "Connection: "
1952
+ )
1795
1953
  end = http1PutText(out, end, connection)
1796
1954
  end = http1PutCrlf(out, end)
1797
1955
  }
@@ -445,13 +445,56 @@ const pgBytesOf = (text: string): u8[] => {
445
445
 
446
446
  /** How many bytes `value` takes in decimal, its sign included. */
447
447
  const pgDecimalLength = (value: i64): i32 => {
448
+ // Counted on the negative side, where the most negative i64 fits, two digits a step.
448
449
  let n: i32 = value < 0 ? 2 : 1
449
450
  let v: i64 = value < 0 ? value : -value
450
- while (v <= -10) {
451
- v = v / 10
452
- n += 1
451
+ while (v <= -100) {
452
+ v = v / 100
453
+ n += 2
453
454
  }
454
- return n
455
+ return v <= -10 ? n + 1 : n
456
+ }
457
+
458
+ /**
459
+ * Writes `value` in decimal into `out[at, at + n)`, where `n` is
460
+ * `pgDecimalLength(value)`, and answers `at + n`. The digits go once, into
461
+ * their places, from the last, two a step from the magnitude as a `u64`
462
+ * (which holds the most negative i64's, and whose `/` and `%` are never
463
+ * checked). Panics unless the window is inside `out`; each step's guard
464
+ * restates it in the shape that proves its two stores.
465
+ */
466
+ const pgPutDecimal = (out: u8[], at: i32, value: i64, n: i32): i32 => {
467
+ if (!(at >= 0 && at < 2147483620 && n >= 1 && n <= 20 && at + n <= toI32(out.length))) {
468
+ panic("nish/net/postgres: a decimal outside its room")
469
+ }
470
+ const first: i32 = value < 0 ? at + 1 : at
471
+ let m: u64 = value < 0 ? toU64(0) - toU64(value) : toU64(value)
472
+ // Where the last two digits start.
473
+ let j: i32 = at + n - 2
474
+ while (m >= 100 && j >= first && j >= 0 && j < 2147483640 && j + 2 <= toI32(out.length)) {
475
+ const pair: u32 = toU32(m % 100)
476
+ const tens: u32 = pair / 10
477
+ out[j] = toU8(48 + tens)
478
+ out[j + 1] = toU8(48 + pair - tens * 10)
479
+ m = m / 100
480
+ j -= 2
481
+ }
482
+ // One or two digits are left, ending at `j + 2`.
483
+ const pair: u32 = toU32(m)
484
+ if (pair >= 10 && j >= first && j >= 0 && j < 2147483640 && j + 2 <= toI32(out.length)) {
485
+ const tens: u32 = pair / 10
486
+ out[j] = toU8(48 + tens)
487
+ out[j + 1] = toU8(48 + pair - tens * 10)
488
+ } else {
489
+ const last: i32 = j + 1
490
+ if (last >= first && last >= 0 && last < toI32(out.length)) {
491
+ out[last] = toU8(48 + pair)
492
+ }
493
+ }
494
+ if (value < 0 && at < toI32(out.length)) {
495
+ out[at] = toU8(45)
496
+ }
497
+ return at + n
455
498
  }
456
499
 
457
500
  /** Whether `value` is an `int4`, -2^31..2^31-1. */
@@ -2274,32 +2317,9 @@ export class PgConnection {
2274
2317
 
2275
2318
  /** `value` in decimal, `pgDecimalLength(value)` bytes. */
2276
2319
  private putDecimal(value: i64): void {
2277
- this.reserve(this.outEnd + 20)
2278
- // The digits are written from the least significant, then reversed; the
2279
- // value is made negative first so that the most negative i64 has its digits.
2280
- let v: i64 = value < 0 ? value : -value
2281
- if (value < 0) {
2282
- this.out[this.outEnd] = toU8(45)
2283
- this.outEnd += 1
2284
- }
2285
- const first: i32 = this.outEnd
2286
- while (true) {
2287
- this.out[this.outEnd] = toU8(48 - toI32(v % 10))
2288
- this.outEnd += 1
2289
- v = v / 10
2290
- if (v === 0) {
2291
- break
2292
- }
2293
- }
2294
- let lo: i32 = first
2295
- let hi: i32 = this.outEnd - 1
2296
- while (lo < hi) {
2297
- const t: u8 = this.out[lo]
2298
- this.out[lo] = this.out[hi]
2299
- this.out[hi] = t
2300
- lo++
2301
- hi--
2302
- }
2320
+ const n: i32 = pgDecimalLength(value)
2321
+ this.reserve(this.outEnd + n)
2322
+ this.outEnd = pgPutDecimal(this.out, this.outEnd, value, n)
2303
2323
  }
2304
2324
 
2305
2325
  /**