@ethproofs/venus-wasm-stark-verifier 0.1.0

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/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # Venus Wasm Stark Verifier
2
+
3
+ WebAssembly bindings for the Venus STARK verifier.
4
+
5
+ ## Overview
6
+
7
+ This module builds the `verify_stark` function from Venus's `proofman-verifier` into WebAssembly, enabling STARK proof verification to run directly in both web browsers and Node.js environments.
8
+
9
+ ## Usage
10
+
11
+ ### Installation
12
+
13
+ ```bash
14
+ npm install @ethproofs/venus-wasm-stark-verifier
15
+ ```
16
+
17
+ ### React Integration
18
+
19
+ ```typescript
20
+ import init, { main, verify_stark } from '@ethproofs/venus-wasm-stark-verifier';
21
+
22
+ await init(); // Initialize WASM (if needed)
23
+ main(); // Initialize panic hook
24
+
25
+ // Verify a proof
26
+ const isValid = verify_stark(proofBytes, vkBytes);
27
+ ```
28
+
29
+ ### Node.js Usage
30
+
31
+ ```javascript
32
+ const { main, verify_stark } = require('@ethproofs/venus-wasm-stark-verifier');
33
+
34
+ // The Node.js version initializes automatically
35
+
36
+ main(); // Initialize panic hook
37
+ const result = verify_stark(proofBytes, vkBytes);
38
+ ```
39
+
40
+ ## Testing
41
+
42
+ ### Installation
43
+
44
+ ```bash
45
+ npm install
46
+ ```
47
+
48
+ ### Prerequisites
49
+
50
+ - [Rust](https://www.rust-lang.org/tools/install)
51
+ - [wasm-pack](https://github.com/drager/wasm-pack)
52
+
53
+ ### Building
54
+
55
+ ```bash
56
+ # Build for all targets
57
+ npm run build:all
58
+ ```
59
+
60
+ ### Node.js Example
61
+
62
+ ```bash
63
+ npm run test:node
64
+ ```
65
+
66
+ This runs the Node.js example that loads proof and verification key files from the filesystem and verifies them.
67
+
68
+ ### Browser Example
69
+
70
+ ```bash
71
+ npm run test
72
+ ```
73
+
74
+ This starts a local HTTP server at `http://localhost:8080` with a browser example that demonstrates:
75
+
76
+ - Loading the WASM module in a browser environment
77
+ - File upload interface for proof and verification key files
78
+ - Interactive STARK proof verification
79
+ - Performance metrics and detailed logging
80
+ - Error handling and user feedback
81
+
82
+ The browser example provides a complete UI for testing the WASM verifier with drag-and-drop file selection and real-time verification results.
83
+
84
+ **Note:** The browser example requires files to be served over HTTP due to WASM CORS restrictions. The included server script handles this automatically.
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@ethproofs/venus-wasm-stark-verifier",
3
+ "version": "0.1.0",
4
+ "description": "WASM wrapper for Venus STARK verifier - verify STARK proofs in browsers and Node.js",
5
+ "type": "module",
6
+ "main": "pkg/venus_wasm_stark_verifier.js",
7
+ "module": "pkg/venus_wasm_stark_verifier.js",
8
+ "types": "pkg/venus_wasm_stark_verifier.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./pkg/venus_wasm_stark_verifier.d.ts",
12
+ "import": "./pkg/venus_wasm_stark_verifier.js",
13
+ "require": "./pkg/venus_wasm_stark_verifier.js"
14
+ },
15
+ "./pkg/*": "./pkg/*"
16
+ },
17
+ "files": [
18
+ "pkg/",
19
+ "README.md",
20
+ "test-browser.html",
21
+ "test-serve.mjs"
22
+ ],
23
+ "scripts": {
24
+ "build": "wasm-pack build --target bundler --out-dir pkg",
25
+ "build:node": "wasm-pack build --target nodejs --out-dir pkg-node",
26
+ "build:web": "wasm-pack build --target web --out-dir pkg-web",
27
+ "build:all": "npm run build && npm run build:node && npm run build:web",
28
+ "test": "npm run build && node test-serve.mjs",
29
+ "test:node": "npm run build:node && node test-node.mjs"
30
+ },
31
+ "keywords": [
32
+ "wasm",
33
+ "webassembly",
34
+ "stark",
35
+ "verifier",
36
+ "venus",
37
+ "zero-knowledge",
38
+ "zk",
39
+ "proof",
40
+ "blockchain",
41
+ "cryptography"
42
+ ],
43
+ "author": "Ethproofs",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/ethproofs/venus-wasm-stark-verifier"
48
+ },
49
+ "homepage": "https://github.com/ethproofs/venus-wasm-stark-verifier#readme",
50
+ "bugs": {
51
+ "url": "https://github.com/ethproofs/venus-wasm-stark-verifier/issues"
52
+ },
53
+ "engines": {
54
+ "node": ">=16.0.0"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public"
58
+ },
59
+ "devDependencies": {
60
+ "wasm-pack": "^0.0.0"
61
+ }
62
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "venus-wasm-stark-verifier",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "files": [
6
+ "venus_wasm_stark_verifier_bg.wasm",
7
+ "venus_wasm_stark_verifier.js",
8
+ "venus_wasm_stark_verifier_bg.js",
9
+ "venus_wasm_stark_verifier.d.ts"
10
+ ],
11
+ "main": "venus_wasm_stark_verifier.js",
12
+ "types": "venus_wasm_stark_verifier.d.ts",
13
+ "sideEffects": [
14
+ "./venus_wasm_stark_verifier.js",
15
+ "./snippets/*"
16
+ ]
17
+ }
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ export function main(): void;
5
+
6
+ export function verify_stark(proof_bytes: Uint8Array, vk_bytes: Uint8Array): boolean;
@@ -0,0 +1,9 @@
1
+ /* @ts-self-types="./venus_wasm_stark_verifier.d.ts" */
2
+
3
+ import * as wasm from "./venus_wasm_stark_verifier_bg.wasm";
4
+ import { __wbg_set_wasm } from "./venus_wasm_stark_verifier_bg.js";
5
+ __wbg_set_wasm(wasm);
6
+ wasm.__wbindgen_start();
7
+ export {
8
+ main, verify_stark
9
+ } from "./venus_wasm_stark_verifier_bg.js";
@@ -0,0 +1,161 @@
1
+ export function main() {
2
+ wasm.main();
3
+ }
4
+
5
+ /**
6
+ * @param {Uint8Array} proof_bytes
7
+ * @param {Uint8Array} vk_bytes
8
+ * @returns {boolean}
9
+ */
10
+ export function verify_stark(proof_bytes, vk_bytes) {
11
+ const ptr0 = passArray8ToWasm0(proof_bytes, wasm.__wbindgen_malloc);
12
+ const len0 = WASM_VECTOR_LEN;
13
+ const ptr1 = passArray8ToWasm0(vk_bytes, wasm.__wbindgen_malloc);
14
+ const len1 = WASM_VECTOR_LEN;
15
+ const ret = wasm.verify_stark(ptr0, len0, ptr1, len1);
16
+ if (ret[2]) {
17
+ throw takeFromExternrefTable0(ret[1]);
18
+ }
19
+ return ret[0] !== 0;
20
+ }
21
+ export function __wbg_error_a6fa202b58aa1cd3(arg0, arg1) {
22
+ let deferred0_0;
23
+ let deferred0_1;
24
+ try {
25
+ deferred0_0 = arg0;
26
+ deferred0_1 = arg1;
27
+ console.error(getStringFromWasm0(arg0, arg1));
28
+ } finally {
29
+ wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
30
+ }
31
+ }
32
+ export function __wbg_new_227d7c05414eb861() {
33
+ const ret = new Error();
34
+ return ret;
35
+ }
36
+ export function __wbg_stack_3b0d974bbf31e44f(arg0, arg1) {
37
+ const ret = arg1.stack;
38
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
39
+ const len1 = WASM_VECTOR_LEN;
40
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
41
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
42
+ }
43
+ export function __wbindgen_cast_0000000000000001(arg0, arg1) {
44
+ // Cast intrinsic for `Ref(String) -> Externref`.
45
+ const ret = getStringFromWasm0(arg0, arg1);
46
+ return ret;
47
+ }
48
+ export function __wbindgen_init_externref_table() {
49
+ const table = wasm.__wbindgen_externrefs;
50
+ const offset = table.grow(4);
51
+ table.set(0, undefined);
52
+ table.set(offset + 0, undefined);
53
+ table.set(offset + 1, null);
54
+ table.set(offset + 2, true);
55
+ table.set(offset + 3, false);
56
+ }
57
+ let cachedDataViewMemory0 = null;
58
+ function getDataViewMemory0() {
59
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
60
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
61
+ }
62
+ return cachedDataViewMemory0;
63
+ }
64
+
65
+ function getStringFromWasm0(ptr, len) {
66
+ ptr = ptr >>> 0;
67
+ return decodeText(ptr, len);
68
+ }
69
+
70
+ let cachedUint8ArrayMemory0 = null;
71
+ function getUint8ArrayMemory0() {
72
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
73
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
74
+ }
75
+ return cachedUint8ArrayMemory0;
76
+ }
77
+
78
+ function passArray8ToWasm0(arg, malloc) {
79
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
80
+ getUint8ArrayMemory0().set(arg, ptr / 1);
81
+ WASM_VECTOR_LEN = arg.length;
82
+ return ptr;
83
+ }
84
+
85
+ function passStringToWasm0(arg, malloc, realloc) {
86
+ if (realloc === undefined) {
87
+ const buf = cachedTextEncoder.encode(arg);
88
+ const ptr = malloc(buf.length, 1) >>> 0;
89
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
90
+ WASM_VECTOR_LEN = buf.length;
91
+ return ptr;
92
+ }
93
+
94
+ let len = arg.length;
95
+ let ptr = malloc(len, 1) >>> 0;
96
+
97
+ const mem = getUint8ArrayMemory0();
98
+
99
+ let offset = 0;
100
+
101
+ for (; offset < len; offset++) {
102
+ const code = arg.charCodeAt(offset);
103
+ if (code > 0x7F) break;
104
+ mem[ptr + offset] = code;
105
+ }
106
+ if (offset !== len) {
107
+ if (offset !== 0) {
108
+ arg = arg.slice(offset);
109
+ }
110
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
111
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
112
+ const ret = cachedTextEncoder.encodeInto(arg, view);
113
+
114
+ offset += ret.written;
115
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
116
+ }
117
+
118
+ WASM_VECTOR_LEN = offset;
119
+ return ptr;
120
+ }
121
+
122
+ function takeFromExternrefTable0(idx) {
123
+ const value = wasm.__wbindgen_externrefs.get(idx);
124
+ wasm.__externref_table_dealloc(idx);
125
+ return value;
126
+ }
127
+
128
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
129
+ cachedTextDecoder.decode();
130
+ const MAX_SAFARI_DECODE_BYTES = 2146435072;
131
+ let numBytesDecoded = 0;
132
+ function decodeText(ptr, len) {
133
+ numBytesDecoded += len;
134
+ if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
135
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
136
+ cachedTextDecoder.decode();
137
+ numBytesDecoded = len;
138
+ }
139
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
140
+ }
141
+
142
+ const cachedTextEncoder = new TextEncoder();
143
+
144
+ if (!('encodeInto' in cachedTextEncoder)) {
145
+ cachedTextEncoder.encodeInto = function (arg, view) {
146
+ const buf = cachedTextEncoder.encode(arg);
147
+ view.set(buf);
148
+ return {
149
+ read: arg.length,
150
+ written: buf.length
151
+ };
152
+ };
153
+ }
154
+
155
+ let WASM_VECTOR_LEN = 0;
156
+
157
+
158
+ let wasm;
159
+ export function __wbg_set_wasm(val) {
160
+ wasm = val;
161
+ }
@@ -0,0 +1,11 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ export const memory: WebAssembly.Memory;
4
+ export const main: () => void;
5
+ export const verify_stark: (a: number, b: number, c: number, d: number) => [number, number, number];
6
+ export const __wbindgen_free: (a: number, b: number, c: number) => void;
7
+ export const __wbindgen_malloc: (a: number, b: number) => number;
8
+ export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
9
+ export const __wbindgen_externrefs: WebAssembly.Table;
10
+ export const __externref_table_dealloc: (a: number) => void;
11
+ export const __wbindgen_start: () => void;
@@ -0,0 +1,335 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Venus WASM STARK Verifier - Browser Example</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
10
+ max-width: 800px;
11
+ margin: 0 auto;
12
+ padding: 20px;
13
+ background-color: #1a1a1a;
14
+ color: #e0e0e0;
15
+ line-height: 1.6;
16
+ }
17
+
18
+ .container {
19
+ background-color: #2d2d2d;
20
+ border-radius: 8px;
21
+ padding: 20px;
22
+ margin-bottom: 20px;
23
+ box-shadow: 0 2px 10px rgba(0,0,0,0.3);
24
+ }
25
+
26
+ h1 {
27
+ color: #4CAF50;
28
+ text-align: center;
29
+ margin-bottom: 30px;
30
+ }
31
+
32
+ h2 {
33
+ color: #81C784;
34
+ border-bottom: 2px solid #4CAF50;
35
+ padding-bottom: 5px;
36
+ }
37
+
38
+ .status {
39
+ padding: 10px;
40
+ border-radius: 4px;
41
+ margin: 10px 0;
42
+ font-weight: bold;
43
+ }
44
+
45
+ .status.loading {
46
+ background-color: #FFF3E0;
47
+ color: #FF8F00;
48
+ border: 1px solid #FFB74D;
49
+ }
50
+
51
+ .status.success {
52
+ background-color: #E8F5E8;
53
+ color: #2E7D32;
54
+ border: 1px solid #4CAF50;
55
+ }
56
+
57
+ .status.error {
58
+ background-color: #FFEBEE;
59
+ color: #C62828;
60
+ border: 1px solid #F44336;
61
+ }
62
+
63
+ .file-info {
64
+ background-color: #424242;
65
+ padding: 10px;
66
+ border-radius: 4px;
67
+ margin: 10px 0;
68
+ font-family: monospace;
69
+ }
70
+
71
+ button {
72
+ background-color: #4CAF50;
73
+ color: white;
74
+ padding: 10px 20px;
75
+ border: none;
76
+ border-radius: 4px;
77
+ cursor: pointer;
78
+ font-size: 16px;
79
+ margin: 10px 5px;
80
+ }
81
+
82
+ button:hover {
83
+ background-color: #45a049;
84
+ }
85
+
86
+ button:disabled {
87
+ background-color: #666;
88
+ cursor: not-allowed;
89
+ }
90
+
91
+ .file-input {
92
+ margin: 10px 0;
93
+ }
94
+
95
+ input[type="file"] {
96
+ background-color: #424242;
97
+ color: #e0e0e0;
98
+ padding: 5px;
99
+ border: 1px solid #666;
100
+ border-radius: 4px;
101
+ }
102
+
103
+ .log {
104
+ background-color: #1e1e1e;
105
+ border: 1px solid #444;
106
+ border-radius: 4px;
107
+ padding: 15px;
108
+ margin: 15px 0;
109
+ font-family: monospace;
110
+ font-size: 12px;
111
+ white-space: pre-wrap;
112
+ max-height: 300px;
113
+ overflow-y: auto;
114
+ }
115
+
116
+ .performance {
117
+ background-color: #263238;
118
+ padding: 10px;
119
+ border-radius: 4px;
120
+ margin: 10px 0;
121
+ }
122
+
123
+ .result {
124
+ font-size: 18px;
125
+ font-weight: bold;
126
+ padding: 15px;
127
+ border-radius: 4px;
128
+ margin: 15px 0;
129
+ text-align: center;
130
+ }
131
+
132
+ .result.valid {
133
+ background-color: #1B5E20;
134
+ color: #4CAF50;
135
+ border: 2px solid #4CAF50;
136
+ }
137
+
138
+ .result.invalid {
139
+ background-color: #B71C1C;
140
+ color: #F44336;
141
+ border: 2px solid #F44336;
142
+ }
143
+ </style>
144
+ </head>
145
+ <body>
146
+ <h1>Venus WASM STARK Verifier</h1>
147
+
148
+ <div class="container">
149
+ <h2>Browser Integration Example</h2>
150
+ <p>This example demonstrates how to use the Venus WASM STARK verifier in a web browser environment.</p>
151
+
152
+ <div id="wasmStatus" class="status loading">Loading WASM module...</div>
153
+ </div>
154
+
155
+ <div class="container">
156
+ <h2>File Selection</h2>
157
+ <p>Select the proof and verification key files to test verification:</p>
158
+
159
+ <div class="file-input">
160
+ <label for="proofFile"><strong>Proof file (.bin):</strong></label><br>
161
+ <input type="file" id="proofFile" accept=".bin" />
162
+ <div id="proofInfo" class="file-info" style="display: none;"></div>
163
+ </div>
164
+
165
+ <div class="file-input">
166
+ <label for="vkFile"><strong>Verification Key file (.bin):</strong></label><br>
167
+ <input type="file" id="vkFile" accept=".bin" />
168
+ <div id="vkInfo" class="file-info" style="display: none;"></div>
169
+ </div>
170
+ </div>
171
+
172
+ <div class="container">
173
+ <h2>Verification</h2>
174
+ <button id="verifyBtn" disabled onclick="runVerification()">Run Verification</button>
175
+ <button id="clearLogBtn" onclick="clearLog()">Clear Log</button>
176
+
177
+ <div id="result" class="result" style="display: none;"></div>
178
+ <div id="performance" class="performance" style="display: none;"></div>
179
+ </div>
180
+
181
+ <div class="container">
182
+ <h2>Console Output</h2>
183
+ <div id="log" class="log"></div>
184
+ </div>
185
+
186
+ <script type="module">
187
+ import init, { main, verify_stark } from './pkg-web/venus_wasm_stark_verifier.js';
188
+
189
+ let wasmModule = null;
190
+ let proofBytes = null;
191
+ let vkBytes = null;
192
+
193
+ function log(message) {
194
+ const logElement = document.getElementById('log');
195
+ const timestamp = new Date().toLocaleTimeString();
196
+ logElement.textContent += `[${timestamp}] ${message}\n`;
197
+ logElement.scrollTop = logElement.scrollHeight;
198
+ console.log(message);
199
+ }
200
+
201
+ function clearLog() {
202
+ document.getElementById('log').textContent = '';
203
+ }
204
+
205
+ function updateStatus(elementId, message, className) {
206
+ const element = document.getElementById(elementId);
207
+ element.textContent = message;
208
+ element.className = `status ${className}`;
209
+ }
210
+
211
+ function updateFileInfo(elementId, file) {
212
+ const element = document.getElementById(elementId);
213
+ element.style.display = 'block';
214
+ element.innerHTML = `
215
+ <strong>File:</strong> ${file.name}<br>
216
+ <strong>Size:</strong> ${file.size.toLocaleString()} bytes<br>
217
+ <strong>Type:</strong> ${file.type || 'binary'}
218
+ `;
219
+ }
220
+
221
+ function checkCanVerify() {
222
+ const canVerify = wasmModule && proofBytes && vkBytes;
223
+ document.getElementById('verifyBtn').disabled = !canVerify;
224
+ return canVerify;
225
+ }
226
+
227
+ async function initializeWasm() {
228
+ try {
229
+ log('Initializing WASM module...');
230
+ wasmModule = await init();
231
+ log('WASM module loaded, initializing panic hook...');
232
+ main();
233
+ updateStatus('wasmStatus', 'WASM module loaded successfully', 'success');
234
+ log('WASM module initialized successfully');
235
+ checkCanVerify();
236
+ } catch (error) {
237
+ updateStatus('wasmStatus', `Failed to load WASM module: ${error.message}`, 'error');
238
+ log(`Error initializing WASM: ${error.message}`);
239
+ console.error('WASM initialization error:', error);
240
+ }
241
+ }
242
+
243
+ function readFileAsArrayBuffer(file) {
244
+ return new Promise((resolve, reject) => {
245
+ const reader = new FileReader();
246
+ reader.onload = (e) => resolve(new Uint8Array(e.target.result));
247
+ reader.onerror = (e) => reject(new Error(`Failed to read file: ${e.target.error}`));
248
+ reader.readAsArrayBuffer(file);
249
+ });
250
+ }
251
+
252
+ document.getElementById('proofFile').addEventListener('change', async (e) => {
253
+ const file = e.target.files[0];
254
+ if (file) {
255
+ try {
256
+ log(`Loading proof file: ${file.name}`);
257
+ proofBytes = await readFileAsArrayBuffer(file);
258
+ updateFileInfo('proofInfo', file);
259
+ log(`Proof file loaded: ${proofBytes.length} bytes`);
260
+ checkCanVerify();
261
+ } catch (error) {
262
+ log(`Error loading proof file: ${error.message}`);
263
+ }
264
+ }
265
+ });
266
+
267
+ document.getElementById('vkFile').addEventListener('change', async (e) => {
268
+ const file = e.target.files[0];
269
+ if (file) {
270
+ try {
271
+ log(`Loading verification key file: ${file.name}`);
272
+ vkBytes = await readFileAsArrayBuffer(file);
273
+ updateFileInfo('vkInfo', file);
274
+ log(`Verification key loaded: ${vkBytes.length} bytes`);
275
+ checkCanVerify();
276
+ } catch (error) {
277
+ log(`Error loading verification key file: ${error.message}`);
278
+ }
279
+ }
280
+ });
281
+
282
+ window.runVerification = async function() {
283
+ if (!checkCanVerify()) {
284
+ log('Cannot run verification: missing WASM module, proof, or verification key');
285
+ return;
286
+ }
287
+
288
+ const resultElement = document.getElementById('result');
289
+ const performanceElement = document.getElementById('performance');
290
+
291
+ try {
292
+ log('Starting verification...');
293
+ log(`Proof size: ${proofBytes.length.toLocaleString()} bytes`);
294
+ log(`VK size: ${vkBytes.length.toLocaleString()} bytes`);
295
+
296
+ const startTime = performance.now();
297
+ const result = verify_stark(proofBytes, vkBytes);
298
+ const endTime = performance.now();
299
+ const duration = endTime - startTime;
300
+
301
+ resultElement.style.display = 'block';
302
+ resultElement.className = `result ${result ? 'valid' : 'invalid'}`;
303
+ resultElement.textContent = result ? 'PROOF VALID' : 'PROOF INVALID';
304
+
305
+ performanceElement.style.display = 'block';
306
+ performanceElement.innerHTML = `
307
+ <strong>Performance Metrics:</strong><br>
308
+ Verification time: ${duration.toFixed(2)} milliseconds<br>
309
+ Throughput: ${((proofBytes.length + vkBytes.length) / 1024 / (duration / 1000)).toFixed(2)} KB/s
310
+ `;
311
+
312
+ log(`Verification completed: ${result ? 'VALID' : 'INVALID'}`);
313
+ log(`Time taken: ${duration.toFixed(2)} milliseconds`);
314
+
315
+ } catch (error) {
316
+ resultElement.style.display = 'block';
317
+ resultElement.className = 'result invalid';
318
+ resultElement.textContent = `VERIFICATION ERROR: ${error.message}`;
319
+
320
+ log(`Verification error: ${error.message}`);
321
+ console.error('Verification error:', error);
322
+ }
323
+ };
324
+
325
+ initializeWasm();
326
+
327
+ log('Venus WASM STARK Verifier browser example loaded');
328
+ log('Instructions:');
329
+ log(' 1. Wait for WASM module to load');
330
+ log(' 2. Select a proof file (.bin)');
331
+ log(' 3. Select a verification key file (.bin)');
332
+ log(' 4. Click "Run Verification"');
333
+ </script>
334
+ </body>
335
+ </html>
package/test-serve.mjs ADDED
@@ -0,0 +1,117 @@
1
+ import http from 'http';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const PORT = process.env.PORT || 8080;
10
+
11
+ const mimeTypes = {
12
+ '.html': 'text/html',
13
+ '.js': 'application/javascript',
14
+ '.wasm': 'application/wasm',
15
+ '.json': 'application/json',
16
+ '.bin': 'application/octet-stream',
17
+ '.css': 'text/css',
18
+ '.ts': 'application/typescript',
19
+ };
20
+
21
+ function getMimeType(filePath) {
22
+ const ext = path.extname(filePath).toLowerCase();
23
+ return mimeTypes[ext] || 'application/octet-stream';
24
+ }
25
+
26
+ function serveFile(res, filePath) {
27
+ const fullPath = path.join(__dirname, filePath);
28
+
29
+ fs.readFile(fullPath, (err, data) => {
30
+ if (err) {
31
+ if (
32
+ !filePath.includes('favicon') &&
33
+ !filePath.includes('ws') &&
34
+ !filePath.includes('socket')
35
+ ) {
36
+ console.error(`File not found: ${filePath}`);
37
+ }
38
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
39
+ res.end('File not found');
40
+ return;
41
+ }
42
+
43
+ const mimeType = getMimeType(filePath);
44
+ const headers = {
45
+ 'Content-Type': mimeType,
46
+ 'Cross-Origin-Embedder-Policy': 'require-corp',
47
+ 'Cross-Origin-Opener-Policy': 'same-origin',
48
+ };
49
+
50
+ if (filePath.endsWith('.wasm')) {
51
+ headers['Content-Type'] = 'application/wasm';
52
+ }
53
+
54
+ res.writeHead(200, headers);
55
+ res.end(data);
56
+
57
+ console.log(`Served: ${filePath} (${mimeType})`);
58
+ });
59
+ }
60
+
61
+ const server = http.createServer((req, res) => {
62
+ let url = req.url;
63
+
64
+ if (url === '/') {
65
+ url = '/test-browser.html';
66
+ }
67
+
68
+ url = decodeURIComponent(url.split('?')[0]);
69
+
70
+ if (url.includes('..')) {
71
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
72
+ res.end('Bad Request');
73
+ return;
74
+ }
75
+
76
+ if (req.url === '/ws' || req.headers.upgrade === 'websocket') {
77
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
78
+ res.end('WebSocket connections not supported by this server');
79
+ return;
80
+ }
81
+
82
+ const filePath = url.startsWith('/') ? url.slice(1) : url;
83
+
84
+ console.log(`Request: ${req.method} ${req.url} -> ${filePath}`);
85
+
86
+ serveFile(res, filePath);
87
+ });
88
+
89
+ server.listen(PORT, () => {
90
+ console.log('Venus WASM STARK Verifier Example Server');
91
+ console.log(`Server running at http://localhost:${PORT}`);
92
+ console.log('');
93
+ console.log('Available endpoints:');
94
+ console.log(
95
+ ` http://localhost:${PORT}/ - Browser example`
96
+ );
97
+ console.log(
98
+ ` http://localhost:${PORT}/pkg/ - WASM package files`
99
+ );
100
+ console.log(` http://localhost:${PORT}/proofs/ - Proof files`);
101
+ console.log(
102
+ ` http://localhost:${PORT}/vks/ - Verification keys`
103
+ );
104
+ console.log('');
105
+ console.log(
106
+ 'Open your browser and navigate to the server URL to test the WASM verifier!'
107
+ );
108
+ console.log('Press Ctrl+C to stop the server');
109
+ });
110
+
111
+ process.on('SIGINT', () => {
112
+ console.log('\nShutting down server...');
113
+ server.close(() => {
114
+ console.log('Server shut down gracefully');
115
+ process.exit(0);
116
+ });
117
+ });