Skip to content

Commit 4ae72c4

Browse files
authored
Merge pull request #735 from praisethemoon/sch/native-sha1
typev: use native sha1
2 parents bd9ba99 + d13c2cd commit 4ae72c4

41 files changed

Lines changed: 177 additions & 310 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

frameworks/typev/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ WORKDIR /app
1212
# typev VM — binary + FFI plugins (json, stdcore, stdsocket, ...). Pre-built
1313
# (-O3 -march=x86-64-v3, static liburing) and fetched from object storage
1414
RUN wget -q -O /tmp/typev.zip \
15-
https://typev.s3.fr-par.scw.cloud/typev-17-05-2026.zip && \
15+
https://typev.s3.fr-par.scw.cloud/typev-21-05-2026.zip && \
1616
unzip -q /tmp/typev.zip -d /app && \
1717
rm /tmp/typev.zip
1818

frameworks/typev/bundle/benchmark-code/src/ws.tc

Lines changed: 5 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,9 @@
33
// frame echo loop: read masked client frames, echo them unmasked.
44

55
from std.socket import tcp_write, tcp_read
6+
from std.internal.socket import socket
67
from response import writeBytes
78

8-
// Low 32 bits mask — SHA-1 is 32-bit arithmetic; typev `uint` is 64-bit.
9-
let local const M32: uint = 4294967295u
10-
11-
let local const B64: byte[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".bytes()
12-
let local const WS_GUID: byte[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".bytes()
139
let local const WS_101: byte[] = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ".bytes()
1410
let local const WS_CRLF2: byte[] = "\r\n\r\n".bytes()
1511
let local const WS_BAD: byte[] = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\nConnection: close\r\n\r\n".bytes()
@@ -36,136 +32,11 @@ local fn wsSend(fd: int, b: byte[], len: uint) -> bool {
3632
return true
3733
}
3834

39-
// 32-bit rotate-left.
40-
local fn rotl32(x: uint, n: uint) -> uint {
41-
return ((x << n) | (x >> (32u - n))) & M32
42-
}
43-
44-
// SHA-1 of data[0..n) — returns the 20-byte digest.
45-
local fn sha1(data: byte[], n: uint) -> byte[] {
46-
let padded: uint = ((n + 8u) / 64u + 1u) * 64u
47-
let msg: byte[] = new byte[](padded)
48-
foreach i: uint in 0u, n {
49-
msg[i] = data[i]
50-
}
51-
msg[n] = 128 as byte
52-
foreach i: uint in n + 1u, padded {
53-
msg[i] = 0 as byte
54-
}
55-
let bits: uint = n * 8u
56-
foreach i: uint in 0u, 8u {
57-
msg[padded - 1u - i] = ((bits >> (8u * i)) & 255u) as byte
58-
}
59-
60-
let h0: uint = 1732584193u
61-
let h1: uint = 4023233417u
62-
let h2: uint = 2562383102u
63-
let h3: uint = 271733878u
64-
let h4: uint = 3285377520u
65-
let w: uint[] = new uint[](80)
66-
let blocks: uint = padded / 64u
67-
68-
foreach b: uint in 0u, blocks {
69-
let base: uint = b * 64u
70-
foreach t: uint in 0u, 16u {
71-
let o: uint = base + t * 4u
72-
w[t] = (((msg[o] as uint) << 24u) | ((msg[o + 1u] as uint) << 16u)
73-
| ((msg[o + 2u] as uint) << 8u) | (msg[o + 3u] as uint)) & M32
74-
}
75-
foreach t: uint in 16u, 80u {
76-
w[t] = rotl32((w[t - 3u] ^ w[t - 8u] ^ w[t - 14u] ^ w[t - 16u]) & M32, 1u)
77-
}
78-
let a: uint = h0
79-
let bb: uint = h1
80-
let c: uint = h2
81-
let d: uint = h3
82-
let e: uint = h4
83-
foreach t: uint in 0u, 80u {
84-
let f: uint = 0u
85-
let k: uint = 0u
86-
if t < 20u {
87-
f = (bb & c) | ((M32 ^ bb) & d)
88-
k = 1518500249u
89-
} else if t < 40u {
90-
f = bb ^ c ^ d
91-
k = 1859775393u
92-
} else if t < 60u {
93-
f = (bb & c) | (bb & d) | (c & d)
94-
k = 2400959708u
95-
} else {
96-
f = bb ^ c ^ d
97-
k = 3395469782u
98-
}
99-
let tt: uint = (rotl32(a, 5u) + (f & M32) + e + k + w[t]) & M32
100-
e = d
101-
d = c
102-
c = rotl32(bb, 30u)
103-
bb = a
104-
a = tt
105-
}
106-
h0 = (h0 + a) & M32
107-
h1 = (h1 + bb) & M32
108-
h2 = (h2 + c) & M32
109-
h3 = (h3 + d) & M32
110-
h4 = (h4 + e) & M32
111-
}
112-
113-
let digest: byte[] = new byte[](20)
114-
let hs: uint[] = [h0, h1, h2, h3, h4]
115-
foreach i: uint in 0u, 5u {
116-
let v: uint = hs[i]
117-
digest[i * 4u] = ((v >> 24u) & 255u) as byte
118-
digest[i * 4u + 1u] = ((v >> 16u) & 255u) as byte
119-
digest[i * 4u + 2u] = ((v >> 8u) & 255u) as byte
120-
digest[i * 4u + 3u] = (v & 255u) as byte
121-
}
122-
return digest
123-
}
124-
125-
// Base64-encode data[0..n).
126-
local fn b64encode(data: byte[], n: uint) -> byte[] {
127-
let outLen: uint = ((n + 2u) / 3u) * 4u
128-
let out: byte[] = new byte[](outLen)
129-
let i: uint = 0u
130-
let o: uint = 0u
131-
while i + 3u <= n {
132-
let x: uint = ((data[i] as uint) << 16u) | ((data[i + 1u] as uint) << 8u) | (data[i + 2u] as uint)
133-
out[o] = B64[(x >> 18u) & 63u]
134-
out[o + 1u] = B64[(x >> 12u) & 63u]
135-
out[o + 2u] = B64[(x >> 6u) & 63u]
136-
out[o + 3u] = B64[x & 63u]
137-
i = i + 3u
138-
o = o + 4u
139-
}
140-
let rem: uint = n - i
141-
if rem == 1u {
142-
let x: uint = (data[i] as uint) << 16u
143-
out[o] = B64[(x >> 18u) & 63u]
144-
out[o + 1u] = B64[(x >> 12u) & 63u]
145-
out[o + 2u] = 61 as byte
146-
out[o + 3u] = 61 as byte
147-
} else if rem == 2u {
148-
let x: uint = ((data[i] as uint) << 16u) | ((data[i + 1u] as uint) << 8u)
149-
out[o] = B64[(x >> 18u) & 63u]
150-
out[o + 1u] = B64[(x >> 12u) & 63u]
151-
out[o + 2u] = B64[(x >> 6u) & 63u]
152-
out[o + 3u] = 61 as byte
153-
}
154-
return out
155-
}
156-
157-
// Sec-WebSocket-Accept = base64(SHA1(key + GUID)).
35+
// Sec-WebSocket-Accept = base64(SHA1(key + GUID)) — computed natively.
15836
local fn wsAccept(key: byte[], keyStart: uint, keyEnd: uint) -> byte[] {
159-
let keyLen: uint = keyEnd - keyStart
160-
let concat: byte[] = new byte[](keyLen + WS_GUID.length)
161-
foreach i: uint in 0u, keyLen {
162-
concat[i] = key[keyStart + i]
163-
}
164-
foreach i: uint in 0u, WS_GUID.length {
165-
concat[keyLen + i] = WS_GUID[i]
166-
}
167-
let digest: byte[] = sha1(concat, concat.length)
168-
return b64encode(digest, 20u)
37+
let out: byte[] = new byte[](28)
38+
socket.socket_ws_accept(key, keyStart, keyEnd - keyStart, out)
39+
return out
16940
}
17041

17142
// Send the 101 upgrade response; `scratch` is the caller's output buffer.

frameworks/typev/bundle/benchmark-code/stdlib/internal/socket.tc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,11 @@ extern socket from "stdsocket" = {
234234
* Returns the number of complete request terminators found.
235235
*/
236236
fn count_http_terminators(buf: uint[], n: uint) -> uint
237+
238+
/**
239+
* WebSocket Sec-WebSocket-Accept = base64(SHA1(key + GUID)), written as
240+
* 28 bytes into `out`. Native — the whole handshake digest in one call.
241+
* Returns 0, or -1 if out < 28.
242+
*/
243+
fn socket_ws_accept(key: uint[], start: uint, len: uint, out: uint[]) -> int
237244
}
-3.91 KB
Binary file not shown.

site/data/baseline-4096.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,19 +1268,19 @@
12681268
{
12691269
"framework": "typev",
12701270
"language": "Type-C",
1271-
"rps": 1920429,
1272-
"avg_latency": "182us",
1273-
"p99_latency": "961us",
1274-
"cpu": "6204.2%",
1275-
"memory": "390MiB",
1271+
"rps": 2238245,
1272+
"avg_latency": "160us",
1273+
"p99_latency": "681us",
1274+
"cpu": "6230.3%",
1275+
"memory": "448MiB",
12761276
"connections": 4096,
12771277
"threads": 64,
12781278
"duration": "5s",
12791279
"pipeline": 1,
1280-
"bandwidth": "164.75MB/s",
1281-
"input_bw": "148.35MB/s",
1280+
"bandwidth": "192.04MB/s",
1281+
"input_bw": "172.90MB/s",
12821282
"reconnects": 0,
1283-
"status_2xx": 9602145,
1283+
"status_2xx": 11191228,
12841284
"status_3xx": 0,
12851285
"status_4xx": 0,
12861286
"status_5xx": 0

site/data/baseline-512.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,19 +1268,19 @@
12681268
{
12691269
"framework": "typev",
12701270
"language": "Type-C",
1271-
"rps": 1920320,
1272-
"avg_latency": "134us",
1273-
"p99_latency": "764us",
1274-
"cpu": "6506.2%",
1275-
"memory": "209MiB",
1271+
"rps": 2230325,
1272+
"avg_latency": "125us",
1273+
"p99_latency": "665us",
1274+
"cpu": "6378.6%",
1275+
"memory": "211MiB",
12761276
"connections": 512,
12771277
"threads": 64,
12781278
"duration": "5s",
12791279
"pipeline": 1,
1280-
"bandwidth": "164.78MB/s",
1281-
"input_bw": "148.34MB/s",
1280+
"bandwidth": "191.36MB/s",
1281+
"input_bw": "172.29MB/s",
12821282
"reconnects": 0,
1283-
"status_2xx": 9601602,
1283+
"status_2xx": 11151628,
12841284
"status_3xx": 0,
12851285
"status_4xx": 0,
12861286
"status_5xx": 0

site/data/echo-ws-16384.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -369,18 +369,18 @@
369369
{
370370
"framework": "typev",
371371
"language": "Type-C",
372-
"rps": 2916886,
373-
"avg_latency": "181us",
374-
"p99_latency": "1.47ms",
375-
"cpu": "6178.8%",
376-
"memory": "500MiB",
372+
"rps": 3048278,
373+
"avg_latency": "170us",
374+
"p99_latency": "1.53ms",
375+
"cpu": "6266.4%",
376+
"memory": "751MiB",
377377
"connections": 16384,
378378
"threads": 64,
379379
"duration": "5s",
380380
"pipeline": 1,
381-
"bandwidth": "19.48MB/s",
382-
"reconnects": 4384,
383-
"status_2xx": 14584434,
381+
"bandwidth": "20.37MB/s",
382+
"reconnects": 0,
383+
"status_2xx": 15241392,
384384
"status_3xx": 0,
385385
"status_4xx": 0,
386386
"status_5xx": 0

site/data/echo-ws-4096.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,18 +369,18 @@
369369
{
370370
"framework": "typev",
371371
"language": "Type-C",
372-
"rps": 3032878,
373-
"avg_latency": "180us",
374-
"p99_latency": "794us",
375-
"cpu": "6184.7%",
376-
"memory": "454MiB",
372+
"rps": 2981735,
373+
"avg_latency": "145us",
374+
"p99_latency": "548us",
375+
"cpu": "6441.7%",
376+
"memory": "450MiB",
377377
"connections": 4096,
378378
"threads": 64,
379379
"duration": "5s",
380380
"pipeline": 1,
381-
"bandwidth": "20.24MB/s",
381+
"bandwidth": "19.90MB/s",
382382
"reconnects": 0,
383-
"status_2xx": 15164394,
383+
"status_2xx": 14908675,
384384
"status_3xx": 0,
385385
"status_4xx": 0,
386386
"status_5xx": 0

site/data/echo-ws-512.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,18 +369,18 @@
369369
{
370370
"framework": "typev",
371371
"language": "Type-C",
372-
"rps": 2870165,
373-
"avg_latency": "103us",
374-
"p99_latency": "347us",
375-
"cpu": "6621.8%",
376-
"memory": "270MiB",
372+
"rps": 3017632,
373+
"avg_latency": "105us",
374+
"p99_latency": "480us",
375+
"cpu": "6739.4%",
376+
"memory": "269MiB",
377377
"connections": 512,
378378
"threads": 64,
379379
"duration": "5s",
380380
"pipeline": 1,
381-
"bandwidth": "19.16MB/s",
381+
"bandwidth": "20.14MB/s",
382382
"reconnects": 0,
383-
"status_2xx": 14350827,
383+
"status_2xx": 15088164,
384384
"status_3xx": 0,
385385
"status_4xx": 0,
386386
"status_5xx": 0

site/data/echo-ws-pipeline-16384.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -230,18 +230,18 @@
230230
{
231231
"framework": "typev",
232232
"language": "Type-C",
233-
"rps": 19144384,
234-
"avg_latency": "182us",
235-
"p99_latency": "161us",
236-
"cpu": "6222.4%",
237-
"memory": "1.2GiB",
233+
"rps": 19139286,
234+
"avg_latency": "308us",
235+
"p99_latency": "1.04ms",
236+
"cpu": "6358.2%",
237+
"memory": "458MiB",
238238
"connections": 16384,
239239
"threads": 64,
240240
"duration": "5s",
241241
"pipeline": 16,
242-
"bandwidth": "127.79MB/s",
243-
"reconnects": 4093,
244-
"status_2xx": 95721920,
242+
"bandwidth": "127.73MB/s",
243+
"reconnects": 0,
244+
"status_2xx": 95696432,
245245
"status_3xx": 0,
246246
"status_4xx": 0,
247247
"status_5xx": 0

0 commit comments

Comments
 (0)