@ethproofs/airbender-wasm-stark-verifier 0.1.1 → 0.2.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 +37 -61
- package/dist/index.cjs +58 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/package.json +18 -21
- package/pkg/README.md +0 -90
- package/pkg/ethproofs_verifier_lib.d.ts +0 -4
- package/pkg/ethproofs_verifier_lib.js +0 -5
- package/pkg/ethproofs_verifier_lib_bg.js +0 -176
- package/pkg/ethproofs_verifier_lib_bg.wasm +0 -0
- package/pkg/ethproofs_verifier_lib_bg.wasm.d.ts +0 -10
- package/pkg/package.json +0 -17
- package/test-browser.html +0 -323
- package/test-serve.mjs +0 -123
package/README.md
CHANGED
|
@@ -1,90 +1,66 @@
|
|
|
1
|
-
# Airbender
|
|
1
|
+
# Airbender WASM STARK Verifier
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A wrapper around [@matterlabs/ethproofs-airbender-verifier](https://www.npmjs.com/package/@matterlabs/ethproofs-airbender-verifier) providing a simple API for STARK proof verification.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
This module builds the `verify` function from `sp1-verifier` into WebAssembly, enabling STARK proof verification to run directly in both web browsers and Node.js environments.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
### Installation
|
|
5
|
+
## Installation
|
|
12
6
|
|
|
13
7
|
```bash
|
|
14
8
|
npm install @ethproofs/airbender-wasm-stark-verifier
|
|
15
9
|
```
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
import init, {
|
|
21
|
-
main,
|
|
22
|
-
verify_stark,
|
|
23
|
-
} from '@ethproofs/airbender-wasm-stark-verifier';
|
|
24
|
-
|
|
25
|
-
await init(); // Initialize WASM (if needed)
|
|
26
|
-
main(); // Initialize panic hook
|
|
27
|
-
|
|
28
|
-
// Verify a proof
|
|
29
|
-
const isValid = verify_stark(proofBytes, vkBytes);
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Node.js Usage
|
|
11
|
+
## Usage
|
|
33
12
|
|
|
34
|
-
|
|
35
|
-
const {
|
|
36
|
-
main,
|
|
37
|
-
verify_stark,
|
|
38
|
-
} = require('@ethproofs/airbender-wasm-stark-verifier');
|
|
13
|
+
### Simple API
|
|
39
14
|
|
|
40
|
-
|
|
15
|
+
```typescript
|
|
16
|
+
import { verify_stark } from '@ethproofs/airbender-wasm-stark-verifier';
|
|
41
17
|
|
|
42
|
-
|
|
43
|
-
const
|
|
18
|
+
// Verify a proof - returns true if valid
|
|
19
|
+
const isValid = await verify_stark(proofBytes);
|
|
44
20
|
```
|
|
45
21
|
|
|
46
|
-
|
|
22
|
+
### With Error Details
|
|
47
23
|
|
|
48
|
-
|
|
24
|
+
```typescript
|
|
25
|
+
import { verify_stark_with_result } from '@ethproofs/airbender-wasm-stark-verifier';
|
|
49
26
|
|
|
50
|
-
|
|
51
|
-
|
|
27
|
+
const result = await verify_stark_with_result(proofBytes);
|
|
28
|
+
if (!result.success) {
|
|
29
|
+
console.error('Verification failed:', result.error);
|
|
30
|
+
}
|
|
52
31
|
```
|
|
53
32
|
|
|
54
|
-
###
|
|
33
|
+
### Advanced Usage
|
|
55
34
|
|
|
56
|
-
|
|
57
|
-
- [wasm-pack](https://github.com/drager/wasm-pack)
|
|
35
|
+
For more control, use the full verifier API:
|
|
58
36
|
|
|
59
|
-
|
|
37
|
+
```typescript
|
|
38
|
+
import { createVerifier } from '@ethproofs/airbender-wasm-stark-verifier';
|
|
60
39
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
npm run build:all
|
|
64
|
-
```
|
|
40
|
+
// Create verifier with default options
|
|
41
|
+
const verifier = await createVerifier();
|
|
65
42
|
|
|
66
|
-
|
|
43
|
+
// Or with custom setup/layout for non-default circuit versions
|
|
44
|
+
const verifier = await createVerifier({
|
|
45
|
+
setupBin: setupBytes,
|
|
46
|
+
layoutBin: layoutBytes,
|
|
47
|
+
});
|
|
67
48
|
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
// Deserialize and verify
|
|
50
|
+
const handle = verifier.deserializeProofBytes(proofBytes);
|
|
51
|
+
const result = verifier.verifyProof(handle);
|
|
70
52
|
```
|
|
71
53
|
|
|
72
|
-
|
|
54
|
+
## API Reference
|
|
73
55
|
|
|
74
|
-
|
|
56
|
+
- `verify_stark(proofBytes: Uint8Array): Promise<boolean>` - simple verification that returns `true` if the proof is valid.
|
|
75
57
|
|
|
76
|
-
|
|
77
|
-
npm run test
|
|
78
|
-
```
|
|
58
|
+
- `verify_stark_with_result(proofBytes: Uint8Array): Promise<VerificationResult>` - returns an object with `success` boolean and optional `error` string.
|
|
79
59
|
|
|
80
|
-
|
|
60
|
+
- `createVerifier(options?: VerifierOptions): Promise<Verifier>` - creates a verifier instance for advanced usage. Optionally accepts custom `setupBin` and `layoutBin` for non-default circuit versions.
|
|
81
61
|
|
|
82
|
-
-
|
|
83
|
-
- File upload interface for proof and verification key files
|
|
84
|
-
- Interactive STARK proof verification
|
|
85
|
-
- Performance metrics and detailed logging
|
|
86
|
-
- Error handling and user feedback
|
|
62
|
+
- `resetVerifier(): void` - resets the cached verifier instance used by the simple API.
|
|
87
63
|
|
|
88
|
-
|
|
64
|
+
## License
|
|
89
65
|
|
|
90
|
-
|
|
66
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createVerifier: () => import_ethproofs_airbender_verifier.createVerifier,
|
|
24
|
+
resetVerifier: () => resetVerifier,
|
|
25
|
+
verify_stark: () => verify_stark,
|
|
26
|
+
verify_stark_with_result: () => verify_stark_with_result
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
var import_ethproofs_airbender_verifier = require("@matterlabs/ethproofs-airbender-verifier");
|
|
30
|
+
var cachedVerifier = null;
|
|
31
|
+
async function getVerifier() {
|
|
32
|
+
if (!cachedVerifier) {
|
|
33
|
+
cachedVerifier = await (0, import_ethproofs_airbender_verifier.createVerifier)();
|
|
34
|
+
}
|
|
35
|
+
return cachedVerifier;
|
|
36
|
+
}
|
|
37
|
+
async function verify_stark(proofBytes) {
|
|
38
|
+
const verifier = await getVerifier();
|
|
39
|
+
const handle = verifier.deserializeProofBytes(proofBytes);
|
|
40
|
+
const result = verifier.verifyProof(handle);
|
|
41
|
+
return result.success;
|
|
42
|
+
}
|
|
43
|
+
async function verify_stark_with_result(proofBytes) {
|
|
44
|
+
const verifier = await getVerifier();
|
|
45
|
+
const handle = verifier.deserializeProofBytes(proofBytes);
|
|
46
|
+
return verifier.verifyProof(handle);
|
|
47
|
+
}
|
|
48
|
+
function resetVerifier() {
|
|
49
|
+
cachedVerifier = null;
|
|
50
|
+
}
|
|
51
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
52
|
+
0 && (module.exports = {
|
|
53
|
+
createVerifier,
|
|
54
|
+
resetVerifier,
|
|
55
|
+
verify_stark,
|
|
56
|
+
verify_stark_with_result
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n createVerifier,\n type Verifier,\n type VerifierOptions,\n type VerificationResult,\n type ProofHandle,\n} from \"@matterlabs/ethproofs-airbender-verifier\";\n\n// Re-export all types and the createVerifier function for advanced usage\nexport {\n createVerifier,\n type Verifier,\n type VerifierOptions,\n type VerificationResult,\n type ProofHandle,\n};\n\n// Cached verifier instance for the simple API\nlet cachedVerifier: Verifier | null = null;\n\n/**\n * Gets or creates a verifier instance with default options.\n * The verifier is cached for subsequent calls.\n */\nasync function getVerifier(): Promise<Verifier> {\n if (!cachedVerifier) {\n cachedVerifier = await createVerifier();\n }\n return cachedVerifier;\n}\n\n/**\n * Simple verification API that takes proof bytes and returns a boolean.\n *\n * This is a convenience wrapper around the full verifier API.\n * For more control, use `createVerifier()` directly.\n *\n * @param proofBytes - The raw proof bytes to verify\n * @returns Promise<boolean> - true if the proof is valid, false otherwise\n */\nexport async function verify_stark(proofBytes: Uint8Array): Promise<boolean> {\n const verifier = await getVerifier();\n const handle = verifier.deserializeProofBytes(proofBytes);\n const result = verifier.verifyProof(handle);\n return result.success;\n}\n\n/**\n * Verification API that returns the full result including error details.\n *\n * @param proofBytes - The raw proof bytes to verify\n * @returns Promise<VerificationResult> - Object with success boolean and optional error string\n */\nexport async function verify_stark_with_result(\n proofBytes: Uint8Array\n): Promise<VerificationResult> {\n const verifier = await getVerifier();\n const handle = verifier.deserializeProofBytes(proofBytes);\n return verifier.verifyProof(handle);\n}\n\n/**\n * Resets the cached verifier instance.\n * Call this if you need to reinitialize with different options.\n */\nexport function resetVerifier(): void {\n cachedVerifier = null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0CAMO;AAYP,IAAI,iBAAkC;AAMtC,eAAe,cAAiC;AAC9C,MAAI,CAAC,gBAAgB;AACnB,qBAAiB,UAAM,oDAAe;AAAA,EACxC;AACA,SAAO;AACT;AAWA,eAAsB,aAAa,YAA0C;AAC3E,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,SAAS,SAAS,sBAAsB,UAAU;AACxD,QAAM,SAAS,SAAS,YAAY,MAAM;AAC1C,SAAO,OAAO;AAChB;AAQA,eAAsB,yBACpB,YAC6B;AAC7B,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,SAAS,SAAS,sBAAsB,UAAU;AACxD,SAAO,SAAS,YAAY,MAAM;AACpC;AAMO,SAAS,gBAAsB;AACpC,mBAAiB;AACnB;","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { VerificationResult } from '@matterlabs/ethproofs-airbender-verifier';
|
|
2
|
+
export { ProofHandle, VerificationResult, Verifier, VerifierOptions, createVerifier } from '@matterlabs/ethproofs-airbender-verifier';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Simple verification API that takes proof bytes and returns a boolean.
|
|
6
|
+
*
|
|
7
|
+
* This is a convenience wrapper around the full verifier API.
|
|
8
|
+
* For more control, use `createVerifier()` directly.
|
|
9
|
+
*
|
|
10
|
+
* @param proofBytes - The raw proof bytes to verify
|
|
11
|
+
* @returns Promise<boolean> - true if the proof is valid, false otherwise
|
|
12
|
+
*/
|
|
13
|
+
declare function verify_stark(proofBytes: Uint8Array): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Verification API that returns the full result including error details.
|
|
16
|
+
*
|
|
17
|
+
* @param proofBytes - The raw proof bytes to verify
|
|
18
|
+
* @returns Promise<VerificationResult> - Object with success boolean and optional error string
|
|
19
|
+
*/
|
|
20
|
+
declare function verify_stark_with_result(proofBytes: Uint8Array): Promise<VerificationResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Resets the cached verifier instance.
|
|
23
|
+
* Call this if you need to reinitialize with different options.
|
|
24
|
+
*/
|
|
25
|
+
declare function resetVerifier(): void;
|
|
26
|
+
|
|
27
|
+
export { resetVerifier, verify_stark, verify_stark_with_result };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { VerificationResult } from '@matterlabs/ethproofs-airbender-verifier';
|
|
2
|
+
export { ProofHandle, VerificationResult, Verifier, VerifierOptions, createVerifier } from '@matterlabs/ethproofs-airbender-verifier';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Simple verification API that takes proof bytes and returns a boolean.
|
|
6
|
+
*
|
|
7
|
+
* This is a convenience wrapper around the full verifier API.
|
|
8
|
+
* For more control, use `createVerifier()` directly.
|
|
9
|
+
*
|
|
10
|
+
* @param proofBytes - The raw proof bytes to verify
|
|
11
|
+
* @returns Promise<boolean> - true if the proof is valid, false otherwise
|
|
12
|
+
*/
|
|
13
|
+
declare function verify_stark(proofBytes: Uint8Array): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Verification API that returns the full result including error details.
|
|
16
|
+
*
|
|
17
|
+
* @param proofBytes - The raw proof bytes to verify
|
|
18
|
+
* @returns Promise<VerificationResult> - Object with success boolean and optional error string
|
|
19
|
+
*/
|
|
20
|
+
declare function verify_stark_with_result(proofBytes: Uint8Array): Promise<VerificationResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Resets the cached verifier instance.
|
|
23
|
+
* Call this if you need to reinitialize with different options.
|
|
24
|
+
*/
|
|
25
|
+
declare function resetVerifier(): void;
|
|
26
|
+
|
|
27
|
+
export { resetVerifier, verify_stark, verify_stark_with_result };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
createVerifier
|
|
4
|
+
} from "@matterlabs/ethproofs-airbender-verifier";
|
|
5
|
+
var cachedVerifier = null;
|
|
6
|
+
async function getVerifier() {
|
|
7
|
+
if (!cachedVerifier) {
|
|
8
|
+
cachedVerifier = await createVerifier();
|
|
9
|
+
}
|
|
10
|
+
return cachedVerifier;
|
|
11
|
+
}
|
|
12
|
+
async function verify_stark(proofBytes) {
|
|
13
|
+
const verifier = await getVerifier();
|
|
14
|
+
const handle = verifier.deserializeProofBytes(proofBytes);
|
|
15
|
+
const result = verifier.verifyProof(handle);
|
|
16
|
+
return result.success;
|
|
17
|
+
}
|
|
18
|
+
async function verify_stark_with_result(proofBytes) {
|
|
19
|
+
const verifier = await getVerifier();
|
|
20
|
+
const handle = verifier.deserializeProofBytes(proofBytes);
|
|
21
|
+
return verifier.verifyProof(handle);
|
|
22
|
+
}
|
|
23
|
+
function resetVerifier() {
|
|
24
|
+
cachedVerifier = null;
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
createVerifier,
|
|
28
|
+
resetVerifier,
|
|
29
|
+
verify_stark,
|
|
30
|
+
verify_stark_with_result
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n createVerifier,\n type Verifier,\n type VerifierOptions,\n type VerificationResult,\n type ProofHandle,\n} from \"@matterlabs/ethproofs-airbender-verifier\";\n\n// Re-export all types and the createVerifier function for advanced usage\nexport {\n createVerifier,\n type Verifier,\n type VerifierOptions,\n type VerificationResult,\n type ProofHandle,\n};\n\n// Cached verifier instance for the simple API\nlet cachedVerifier: Verifier | null = null;\n\n/**\n * Gets or creates a verifier instance with default options.\n * The verifier is cached for subsequent calls.\n */\nasync function getVerifier(): Promise<Verifier> {\n if (!cachedVerifier) {\n cachedVerifier = await createVerifier();\n }\n return cachedVerifier;\n}\n\n/**\n * Simple verification API that takes proof bytes and returns a boolean.\n *\n * This is a convenience wrapper around the full verifier API.\n * For more control, use `createVerifier()` directly.\n *\n * @param proofBytes - The raw proof bytes to verify\n * @returns Promise<boolean> - true if the proof is valid, false otherwise\n */\nexport async function verify_stark(proofBytes: Uint8Array): Promise<boolean> {\n const verifier = await getVerifier();\n const handle = verifier.deserializeProofBytes(proofBytes);\n const result = verifier.verifyProof(handle);\n return result.success;\n}\n\n/**\n * Verification API that returns the full result including error details.\n *\n * @param proofBytes - The raw proof bytes to verify\n * @returns Promise<VerificationResult> - Object with success boolean and optional error string\n */\nexport async function verify_stark_with_result(\n proofBytes: Uint8Array\n): Promise<VerificationResult> {\n const verifier = await getVerifier();\n const handle = verifier.deserializeProofBytes(proofBytes);\n return verifier.verifyProof(handle);\n}\n\n/**\n * Resets the cached verifier instance.\n * Call this if you need to reinitialize with different options.\n */\nexport function resetVerifier(): void {\n cachedVerifier = null;\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,OAKK;AAYP,IAAI,iBAAkC;AAMtC,eAAe,cAAiC;AAC9C,MAAI,CAAC,gBAAgB;AACnB,qBAAiB,MAAM,eAAe;AAAA,EACxC;AACA,SAAO;AACT;AAWA,eAAsB,aAAa,YAA0C;AAC3E,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,SAAS,SAAS,sBAAsB,UAAU;AACxD,QAAM,SAAS,SAAS,YAAY,MAAM;AAC1C,SAAO,OAAO;AAChB;AAQA,eAAsB,yBACpB,YAC6B;AAC7B,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,SAAS,SAAS,sBAAsB,UAAU;AACxD,SAAO,SAAS,YAAY,MAAM;AACpC;AAMO,SAAS,gBAAsB;AACpC,mBAAiB;AACnB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,32 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethproofs/airbender-wasm-stark-verifier",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Simplified API wrapper for Airbender STARK proof verification",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "
|
|
7
|
-
"module": "
|
|
8
|
-
"types": "
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"types": "./
|
|
12
|
-
"import": "./
|
|
13
|
-
"require": "./
|
|
14
|
-
}
|
|
15
|
-
"./pkg/*": "./pkg/*"
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
16
15
|
},
|
|
17
16
|
"files": [
|
|
18
|
-
"
|
|
19
|
-
"README.md"
|
|
20
|
-
"test-browser.html",
|
|
21
|
-
"test-serve.mjs"
|
|
17
|
+
"dist/",
|
|
18
|
+
"README.md"
|
|
22
19
|
],
|
|
23
20
|
"scripts": {
|
|
24
|
-
"build": "
|
|
25
|
-
"
|
|
26
|
-
"build:web": "wasm-pack build --target web --out-dir pkg-web --no-opt",
|
|
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"
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
30
23
|
},
|
|
31
24
|
"keywords": [
|
|
32
25
|
"wasm",
|
|
@@ -56,7 +49,11 @@
|
|
|
56
49
|
"publishConfig": {
|
|
57
50
|
"access": "public"
|
|
58
51
|
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@matterlabs/ethproofs-airbender-verifier": "^0.1.1"
|
|
54
|
+
},
|
|
59
55
|
"devDependencies": {
|
|
60
|
-
"
|
|
56
|
+
"tsup": "^8.0.1",
|
|
57
|
+
"typescript": "^5.4.5"
|
|
61
58
|
}
|
|
62
59
|
}
|
package/pkg/README.md
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# Airbender Wasm STARK Verifier
|
|
2
|
-
|
|
3
|
-
WebAssembly bindings for the Airbender verifier.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
This module builds the `verify` function from `sp1-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/airbender-wasm-stark-verifier
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### React Integration
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
import init, {
|
|
21
|
-
main,
|
|
22
|
-
verify_stark,
|
|
23
|
-
} from '@ethproofs/airbender-wasm-stark-verifier';
|
|
24
|
-
|
|
25
|
-
await init(); // Initialize WASM (if needed)
|
|
26
|
-
main(); // Initialize panic hook
|
|
27
|
-
|
|
28
|
-
// Verify a proof
|
|
29
|
-
const isValid = verify_stark(proofBytes, vkBytes);
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Node.js Usage
|
|
33
|
-
|
|
34
|
-
```javascript
|
|
35
|
-
const {
|
|
36
|
-
main,
|
|
37
|
-
verify_stark,
|
|
38
|
-
} = require('@ethproofs/airbender-wasm-stark-verifier');
|
|
39
|
-
|
|
40
|
-
// The Node.js version initializes automatically
|
|
41
|
-
|
|
42
|
-
main(); // Initialize panic hook
|
|
43
|
-
const result = verify_stark(proofBytes, vkBytes);
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Testing
|
|
47
|
-
|
|
48
|
-
### Installation
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
npm install
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Prerequisites
|
|
55
|
-
|
|
56
|
-
- [sp1](https://docs.succinct.xyz/docs/sp1/getting-started/install)
|
|
57
|
-
- [wasm-pack](https://github.com/drager/wasm-pack)
|
|
58
|
-
|
|
59
|
-
### Building
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# Build for all targets
|
|
63
|
-
npm run build:all
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Node.js Example
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
npm run test:node
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
This runs the Node.js example that loads proof and verification key files from the filesystem and verifies them.
|
|
73
|
-
|
|
74
|
-
### Browser Example
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
npm run test
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
This starts a local HTTP server at `http://localhost:8080` with a browser example that demonstrates:
|
|
81
|
-
|
|
82
|
-
- Loading the WASM module in a browser environment
|
|
83
|
-
- File upload interface for proof and verification key files
|
|
84
|
-
- Interactive STARK proof verification
|
|
85
|
-
- Performance metrics and detailed logging
|
|
86
|
-
- Error handling and user feedback
|
|
87
|
-
|
|
88
|
-
The browser example provides a complete UI for testing the WASM verifier with drag-and-drop file selection and real-time verification results.
|
|
89
|
-
|
|
90
|
-
**Note:** The browser example requires files to be served over HTTP due to WASM CORS restrictions. The included server script handles this automatically.
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
let wasm;
|
|
2
|
-
export function __wbg_set_wasm(val) {
|
|
3
|
-
wasm = val;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let cachedUint8ArrayMemory0 = null;
|
|
8
|
-
|
|
9
|
-
function getUint8ArrayMemory0() {
|
|
10
|
-
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
11
|
-
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
12
|
-
}
|
|
13
|
-
return cachedUint8ArrayMemory0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
17
|
-
|
|
18
|
-
cachedTextDecoder.decode();
|
|
19
|
-
|
|
20
|
-
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
|
21
|
-
let numBytesDecoded = 0;
|
|
22
|
-
function decodeText(ptr, len) {
|
|
23
|
-
numBytesDecoded += len;
|
|
24
|
-
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
|
25
|
-
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
26
|
-
cachedTextDecoder.decode();
|
|
27
|
-
numBytesDecoded = len;
|
|
28
|
-
}
|
|
29
|
-
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function getStringFromWasm0(ptr, len) {
|
|
33
|
-
ptr = ptr >>> 0;
|
|
34
|
-
return decodeText(ptr, len);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
let WASM_VECTOR_LEN = 0;
|
|
38
|
-
|
|
39
|
-
const cachedTextEncoder = new TextEncoder();
|
|
40
|
-
|
|
41
|
-
if (!('encodeInto' in cachedTextEncoder)) {
|
|
42
|
-
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
43
|
-
const buf = cachedTextEncoder.encode(arg);
|
|
44
|
-
view.set(buf);
|
|
45
|
-
return {
|
|
46
|
-
read: arg.length,
|
|
47
|
-
written: buf.length
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function passStringToWasm0(arg, malloc, realloc) {
|
|
53
|
-
|
|
54
|
-
if (realloc === undefined) {
|
|
55
|
-
const buf = cachedTextEncoder.encode(arg);
|
|
56
|
-
const ptr = malloc(buf.length, 1) >>> 0;
|
|
57
|
-
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
58
|
-
WASM_VECTOR_LEN = buf.length;
|
|
59
|
-
return ptr;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let len = arg.length;
|
|
63
|
-
let ptr = malloc(len, 1) >>> 0;
|
|
64
|
-
|
|
65
|
-
const mem = getUint8ArrayMemory0();
|
|
66
|
-
|
|
67
|
-
let offset = 0;
|
|
68
|
-
|
|
69
|
-
for (; offset < len; offset++) {
|
|
70
|
-
const code = arg.charCodeAt(offset);
|
|
71
|
-
if (code > 0x7F) break;
|
|
72
|
-
mem[ptr + offset] = code;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (offset !== len) {
|
|
76
|
-
if (offset !== 0) {
|
|
77
|
-
arg = arg.slice(offset);
|
|
78
|
-
}
|
|
79
|
-
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
80
|
-
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
81
|
-
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
82
|
-
|
|
83
|
-
offset += ret.written;
|
|
84
|
-
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
WASM_VECTOR_LEN = offset;
|
|
88
|
-
return ptr;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let cachedDataViewMemory0 = null;
|
|
92
|
-
|
|
93
|
-
function getDataViewMemory0() {
|
|
94
|
-
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
95
|
-
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
96
|
-
}
|
|
97
|
-
return cachedDataViewMemory0;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function main() {
|
|
101
|
-
wasm.main();
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function passArray8ToWasm0(arg, malloc) {
|
|
105
|
-
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
106
|
-
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
107
|
-
WASM_VECTOR_LEN = arg.length;
|
|
108
|
-
return ptr;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* @param {Uint8Array} data
|
|
112
|
-
* @returns {Array<any>}
|
|
113
|
-
*/
|
|
114
|
-
export function verify_stark(data) {
|
|
115
|
-
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
116
|
-
const len0 = WASM_VECTOR_LEN;
|
|
117
|
-
const ret = wasm.verify_stark(ptr0, len0);
|
|
118
|
-
return ret;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function __wbg___wbindgen_throw_b855445ff6a94295(arg0, arg1) {
|
|
122
|
-
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
export function __wbg_error_7534b8e9a36f1ab4(arg0, arg1) {
|
|
126
|
-
let deferred0_0;
|
|
127
|
-
let deferred0_1;
|
|
128
|
-
try {
|
|
129
|
-
deferred0_0 = arg0;
|
|
130
|
-
deferred0_1 = arg1;
|
|
131
|
-
console.error(getStringFromWasm0(arg0, arg1));
|
|
132
|
-
} finally {
|
|
133
|
-
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
export function __wbg_new_8a6f238a6ece86ea() {
|
|
138
|
-
const ret = new Error();
|
|
139
|
-
return ret;
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
export function __wbg_new_e17d9f43105b08be() {
|
|
143
|
-
const ret = new Array();
|
|
144
|
-
return ret;
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
export function __wbg_push_df81a39d04db858c(arg0, arg1) {
|
|
148
|
-
const ret = arg0.push(arg1);
|
|
149
|
-
return ret;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
export function __wbg_stack_0ed75d68575b0f3c(arg0, arg1) {
|
|
153
|
-
const ret = arg1.stack;
|
|
154
|
-
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
155
|
-
const len1 = WASM_VECTOR_LEN;
|
|
156
|
-
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
157
|
-
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
export function __wbindgen_cast_2241b6af4c4b2941(arg0, arg1) {
|
|
161
|
-
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
162
|
-
const ret = getStringFromWasm0(arg0, arg1);
|
|
163
|
-
return ret;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
export function __wbindgen_init_externref_table() {
|
|
167
|
-
const table = wasm.__wbindgen_externrefs;
|
|
168
|
-
const offset = table.grow(4);
|
|
169
|
-
table.set(0, undefined);
|
|
170
|
-
table.set(offset + 0, undefined);
|
|
171
|
-
table.set(offset + 1, null);
|
|
172
|
-
table.set(offset + 2, true);
|
|
173
|
-
table.set(offset + 3, false);
|
|
174
|
-
;
|
|
175
|
-
};
|
|
176
|
-
|
|
Binary file
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/* tslint:disable */
|
|
2
|
-
/* eslint-disable */
|
|
3
|
-
export const memory: WebAssembly.Memory;
|
|
4
|
-
export const verify_stark: (a: number, b: number) => any;
|
|
5
|
-
export const main: () => void;
|
|
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 __wbindgen_start: () => void;
|
package/pkg/package.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ethproofs_verifier",
|
|
3
|
-
"type": "module",
|
|
4
|
-
"version": "0.1.0",
|
|
5
|
-
"files": [
|
|
6
|
-
"ethproofs_verifier_lib_bg.wasm",
|
|
7
|
-
"ethproofs_verifier_lib.js",
|
|
8
|
-
"ethproofs_verifier_lib_bg.js",
|
|
9
|
-
"ethproofs_verifier_lib.d.ts"
|
|
10
|
-
],
|
|
11
|
-
"main": "ethproofs_verifier_lib.js",
|
|
12
|
-
"types": "ethproofs_verifier_lib.d.ts",
|
|
13
|
-
"sideEffects": [
|
|
14
|
-
"./ethproofs_verifier_lib.js",
|
|
15
|
-
"./snippets/*"
|
|
16
|
-
]
|
|
17
|
-
}
|
package/test-browser.html
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
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>Airbender 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>🧪 Airbender WASM STARK Verifier</h1>
|
|
147
|
-
|
|
148
|
-
<div class="container">
|
|
149
|
-
<h2>Browser Integration Example</h2>
|
|
150
|
-
<p>This example demonstrates how to use the Airbender 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 file 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
|
-
</div>
|
|
165
|
-
|
|
166
|
-
<div class="container">
|
|
167
|
-
<h2>Verification</h2>
|
|
168
|
-
<button id="verifyBtn" disabled onclick="runVerification()">Run Verification</button>
|
|
169
|
-
<button id="clearLogBtn" onclick="clearLog()">Clear Log</button>
|
|
170
|
-
|
|
171
|
-
<div id="result" class="result" style="display: none;"></div>
|
|
172
|
-
<div id="performance" class="performance" style="display: none;"></div>
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
|
-
<div class="container">
|
|
176
|
-
<h2>Console Output</h2>
|
|
177
|
-
<div id="log" class="log"></div>
|
|
178
|
-
</div>
|
|
179
|
-
|
|
180
|
-
<script type="module">
|
|
181
|
-
import init, { main, verify_stark } from './pkg-web/airbender_wasm_stark_verifier.js';
|
|
182
|
-
|
|
183
|
-
let wasmModule = null;
|
|
184
|
-
let proofBytes = null;
|
|
185
|
-
|
|
186
|
-
// Log function to display messages in the UI
|
|
187
|
-
function log(message) {
|
|
188
|
-
const logElement = document.getElementById('log');
|
|
189
|
-
const timestamp = new Date().toLocaleTimeString();
|
|
190
|
-
logElement.textContent += `[${timestamp}] ${message}\n`;
|
|
191
|
-
logElement.scrollTop = logElement.scrollHeight;
|
|
192
|
-
console.log(message);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function clearLog() {
|
|
196
|
-
document.getElementById('log').textContent = '';
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function updateStatus(elementId, message, className) {
|
|
200
|
-
const element = document.getElementById(elementId);
|
|
201
|
-
element.textContent = message;
|
|
202
|
-
element.className = `status ${className}`;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function updateFileInfo(elementId, file) {
|
|
206
|
-
const element = document.getElementById(elementId);
|
|
207
|
-
element.style.display = 'block';
|
|
208
|
-
element.innerHTML = `
|
|
209
|
-
<strong>File:</strong> ${file.name}<br>
|
|
210
|
-
<strong>Size:</strong> ${file.size.toLocaleString()} bytes<br>
|
|
211
|
-
<strong>Type:</strong> ${file.type || 'binary'}
|
|
212
|
-
`;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function checkCanVerify() {
|
|
216
|
-
const canVerify = wasmModule && proofBytes;
|
|
217
|
-
document.getElementById('verifyBtn').disabled = !canVerify;
|
|
218
|
-
return canVerify;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Initialize WASM module
|
|
222
|
-
async function initializeWasm() {
|
|
223
|
-
try {
|
|
224
|
-
log('🚀 Initializing WASM module...');
|
|
225
|
-
wasmModule = await init();
|
|
226
|
-
log('📦 WASM module loaded, initializing panic hook...');
|
|
227
|
-
main(); // Initialize panic hook and other setup
|
|
228
|
-
updateStatus('wasmStatus', '✅ WASM module loaded successfully', 'success');
|
|
229
|
-
log('✅ WASM module initialized successfully');
|
|
230
|
-
checkCanVerify();
|
|
231
|
-
} catch (error) {
|
|
232
|
-
updateStatus('wasmStatus', `❌ Failed to load WASM module: ${error.message}`, 'error');
|
|
233
|
-
log(`❌ Error initializing WASM: ${error.message}`);
|
|
234
|
-
console.error('WASM initialization error:', error);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// File reading helper
|
|
239
|
-
function readFileAsArrayBuffer(file) {
|
|
240
|
-
return new Promise((resolve, reject) => {
|
|
241
|
-
const reader = new FileReader();
|
|
242
|
-
reader.onload = (e) => resolve(new Uint8Array(e.target.result));
|
|
243
|
-
reader.onerror = (e) => reject(new Error(`Failed to read file: ${e.target.error}`));
|
|
244
|
-
reader.readAsArrayBuffer(file);
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// File input handlers
|
|
249
|
-
document.getElementById('proofFile').addEventListener('change', async (e) => {
|
|
250
|
-
const file = e.target.files[0];
|
|
251
|
-
if (file) {
|
|
252
|
-
try {
|
|
253
|
-
log(`📄 Loading proof file: ${file.name}`);
|
|
254
|
-
proofBytes = await readFileAsArrayBuffer(file);
|
|
255
|
-
updateFileInfo('proofInfo', file);
|
|
256
|
-
log(`✅ Proof file loaded: ${proofBytes.length} bytes`);
|
|
257
|
-
checkCanVerify();
|
|
258
|
-
} catch (error) {
|
|
259
|
-
log(`❌ Error loading proof file: ${error.message}`);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// Main verification function
|
|
266
|
-
window.runVerification = async function() {
|
|
267
|
-
if (!checkCanVerify()) {
|
|
268
|
-
log('❌ Cannot run verification: missing WASM module or proof');
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const resultElement = document.getElementById('result');
|
|
273
|
-
const performanceElement = document.getElementById('performance');
|
|
274
|
-
|
|
275
|
-
try {
|
|
276
|
-
log('🔍 Starting verification...');
|
|
277
|
-
log(`📊 Proof size: ${proofBytes.length.toLocaleString()} bytes`);
|
|
278
|
-
|
|
279
|
-
const startTime = performance.now();
|
|
280
|
-
const result = verify_stark(proofBytes);
|
|
281
|
-
const endTime = performance.now();
|
|
282
|
-
const duration = endTime - startTime;
|
|
283
|
-
|
|
284
|
-
// Display result
|
|
285
|
-
resultElement.style.display = 'block';
|
|
286
|
-
resultElement.className = `result ${result ? 'valid' : 'invalid'}`;
|
|
287
|
-
resultElement.textContent = result ? '✅ PROOF VALID' : '❌ PROOF INVALID';
|
|
288
|
-
|
|
289
|
-
// Display performance metrics
|
|
290
|
-
performanceElement.style.display = 'block';
|
|
291
|
-
performanceElement.innerHTML = `
|
|
292
|
-
<strong>⏱️ Performance Metrics:</strong><br>
|
|
293
|
-
Verification time: ${duration.toFixed(2)} milliseconds<br>
|
|
294
|
-
Throughput: ${(proofBytes.length / 1024 / (duration / 1000)).toFixed(2)} KB/s
|
|
295
|
-
`;
|
|
296
|
-
|
|
297
|
-
log(`✅ Verification completed: ${result ? 'VALID' : 'INVALID'}`);
|
|
298
|
-
log(`⏱️ Time taken: ${duration.toFixed(2)} milliseconds`);
|
|
299
|
-
|
|
300
|
-
} catch (error) {
|
|
301
|
-
resultElement.style.display = 'block';
|
|
302
|
-
resultElement.className = 'result invalid';
|
|
303
|
-
resultElement.textContent = `❌ VERIFICATION ERROR: ${error.message}`;
|
|
304
|
-
|
|
305
|
-
log(`❌ Verification error: ${error.message}`);
|
|
306
|
-
console.error('Verification error:', error);
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
// Initialize on page load
|
|
311
|
-
initializeWasm();
|
|
312
|
-
|
|
313
|
-
// Add some helpful information
|
|
314
|
-
log('🌐 Airbender WASM STARK Verifier browser example loaded');
|
|
315
|
-
log('📝 Instructions:');
|
|
316
|
-
log(' 1. Wait for WASM module to load');
|
|
317
|
-
log(' 2. Select a proof file (.bin)');
|
|
318
|
-
log(' 3. Click "Run Verification"');
|
|
319
|
-
log('');
|
|
320
|
-
log('💡 Tip: You can use the proof file from the data/ directory');
|
|
321
|
-
</script>
|
|
322
|
-
</body>
|
|
323
|
-
</html>
|
package/test-serve.mjs
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
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
|
-
// MIME types for different file extensions
|
|
12
|
-
const mimeTypes = {
|
|
13
|
-
'.html': 'text/html',
|
|
14
|
-
'.js': 'application/javascript',
|
|
15
|
-
'.wasm': 'application/wasm',
|
|
16
|
-
'.json': 'application/json',
|
|
17
|
-
'.bin': 'application/octet-stream',
|
|
18
|
-
'.css': 'text/css',
|
|
19
|
-
'.ts': 'application/typescript',
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
function getMimeType(filePath) {
|
|
23
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
24
|
-
return mimeTypes[ext] || 'application/octet-stream';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function serveFile(res, filePath) {
|
|
28
|
-
const fullPath = path.join(__dirname, filePath);
|
|
29
|
-
|
|
30
|
-
fs.readFile(fullPath, (err, data) => {
|
|
31
|
-
if (err) {
|
|
32
|
-
// Only log file not found for legitimate requests, not for browser probes
|
|
33
|
-
if (
|
|
34
|
-
!filePath.includes('favicon') &&
|
|
35
|
-
!filePath.includes('ws') &&
|
|
36
|
-
!filePath.includes('socket')
|
|
37
|
-
) {
|
|
38
|
-
console.error(`❌ File not found: ${filePath}`);
|
|
39
|
-
}
|
|
40
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
41
|
-
res.end('File not found');
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const mimeType = getMimeType(filePath);
|
|
46
|
-
const headers = {
|
|
47
|
-
'Content-Type': mimeType,
|
|
48
|
-
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
49
|
-
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Ensure WASM files are served with correct MIME type for streaming
|
|
53
|
-
if (filePath.endsWith('.wasm')) {
|
|
54
|
-
headers['Content-Type'] = 'application/wasm';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
res.writeHead(200, headers);
|
|
58
|
-
res.end(data);
|
|
59
|
-
|
|
60
|
-
console.log(`📄 Served: ${filePath} (${mimeType})`);
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const server = http.createServer((req, res) => {
|
|
65
|
-
let url = req.url;
|
|
66
|
-
|
|
67
|
-
// Handle root path
|
|
68
|
-
if (url === '/') {
|
|
69
|
-
url = '/test-browser.html';
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Remove query parameters and decode URL
|
|
73
|
-
url = decodeURIComponent(url.split('?')[0]);
|
|
74
|
-
|
|
75
|
-
// Security check - prevent directory traversal
|
|
76
|
-
if (url.includes('..')) {
|
|
77
|
-
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
78
|
-
res.end('Bad Request');
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Handle WebSocket upgrade attempts (reject them gracefully)
|
|
83
|
-
if (req.url === '/ws' || req.headers.upgrade === 'websocket') {
|
|
84
|
-
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
85
|
-
res.end('WebSocket connections not supported by this server');
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Remove leading slash for path.join
|
|
90
|
-
const filePath = url.startsWith('/') ? url.slice(1) : url;
|
|
91
|
-
|
|
92
|
-
console.log(`🌐 Request: ${req.method} ${req.url} -> ${filePath}`);
|
|
93
|
-
|
|
94
|
-
serveFile(res, filePath);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
server.listen(PORT, () => {
|
|
98
|
-
console.log('🚀 Airbender WASM STARK Verifier Example Server');
|
|
99
|
-
console.log(`📡 Server running at http://localhost:${PORT}`);
|
|
100
|
-
console.log('');
|
|
101
|
-
console.log('📝 Available endpoints:');
|
|
102
|
-
console.log(
|
|
103
|
-
` http://localhost:${PORT}/ - Browser example`
|
|
104
|
-
);
|
|
105
|
-
console.log(
|
|
106
|
-
` http://localhost:${PORT}/pkg/ - WASM package files`
|
|
107
|
-
);
|
|
108
|
-
console.log(` http://localhost:${PORT}/data/ - Proof files`);
|
|
109
|
-
console.log('');
|
|
110
|
-
console.log(
|
|
111
|
-
'💡 Open your browser and navigate to the server URL to test the WASM verifier!'
|
|
112
|
-
);
|
|
113
|
-
console.log('⏹️ Press Ctrl+C to stop the server');
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// Graceful shutdown
|
|
117
|
-
process.on('SIGINT', () => {
|
|
118
|
-
console.log('\n🛑 Shutting down server...');
|
|
119
|
-
server.close(() => {
|
|
120
|
-
console.log('✅ Server shut down gracefully');
|
|
121
|
-
process.exit(0);
|
|
122
|
-
});
|
|
123
|
-
});
|