@aztec/bb.js 3.0.0-nightly.20251114 → 3.0.0-nightly.20251118
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/build/amd64-linux/bb +0 -0
- package/build/amd64-linux/nodejs_module.node +0 -0
- package/build/amd64-macos/bb +0 -0
- package/build/amd64-macos/nodejs_module.node +0 -0
- package/build/arm64-linux/bb +0 -0
- package/build/arm64-linux/nodejs_module.node +0 -0
- package/build/arm64-macos/bb +0 -0
- package/build/arm64-macos/nodejs_module.node +0 -0
- package/dest/browser/barretenberg/backend.d.ts +9 -23
- package/dest/browser/barretenberg/backend.d.ts.map +1 -1
- package/dest/browser/barretenberg/backend.js +24 -84
- package/dest/browser/barretenberg/index.d.ts +1 -3
- package/dest/browser/barretenberg/index.d.ts.map +1 -1
- package/dest/browser/barretenberg/index.js +15 -24
- package/dest/browser/{bigint-array/index.d.ts → barretenberg/testing/bigint-buffer.d.ts} +1 -1
- package/dest/browser/barretenberg/testing/bigint-buffer.d.ts.map +1 -0
- package/dest/browser/barretenberg/testing/bigint-buffer.js +37 -0
- package/dest/browser/barretenberg/testing/fields.d.ts +16 -0
- package/dest/browser/barretenberg/testing/fields.d.ts.map +1 -0
- package/dest/browser/barretenberg/testing/fields.js +48 -0
- package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg-threads.js +1 -1
- package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg.js +1 -1
- package/dest/browser/bb_backends/index.d.ts +8 -5
- package/dest/browser/bb_backends/index.d.ts.map +1 -1
- package/dest/browser/bb_backends/index.js +5 -5
- package/dest/node/barretenberg/backend.d.ts +9 -23
- package/dest/node/barretenberg/backend.d.ts.map +1 -1
- package/dest/node/barretenberg/backend.js +24 -84
- package/dest/node/barretenberg/blake2s.test.js +2 -2
- package/dest/node/barretenberg/index.d.ts +1 -3
- package/dest/node/barretenberg/index.d.ts.map +1 -1
- package/dest/node/barretenberg/index.js +15 -24
- package/dest/node/barretenberg/pedersen.test.js +2 -2
- package/dest/node/barretenberg/poseidon.bench.test.js +27 -68
- package/dest/node/barretenberg/poseidon.test.js +2 -2
- package/dest/node/{bigint-array/index.d.ts → barretenberg/testing/bigint-buffer.d.ts} +1 -1
- package/dest/node/barretenberg/testing/bigint-buffer.d.ts.map +1 -0
- package/dest/node/barretenberg/testing/bigint-buffer.js +37 -0
- package/dest/node/barretenberg/testing/fields.d.ts +16 -0
- package/dest/node/barretenberg/testing/fields.d.ts.map +1 -0
- package/dest/node/barretenberg/testing/fields.js +48 -0
- package/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node/bb_backends/index.d.ts +8 -5
- package/dest/node/bb_backends/index.d.ts.map +1 -1
- package/dest/node/bb_backends/index.js +5 -5
- package/dest/node/bb_backends/node/index.d.ts.map +1 -1
- package/dest/node/bb_backends/node/index.js +12 -4
- package/dest/node/bb_backends/node/native_shm.d.ts +2 -1
- package/dest/node/bb_backends/node/native_shm.d.ts.map +1 -1
- package/dest/node/bb_backends/node/native_shm.js +50 -15
- package/dest/node/bb_backends/node/native_socket.d.ts +1 -1
- package/dest/node/bb_backends/node/native_socket.d.ts.map +1 -1
- package/dest/node/bb_backends/node/native_socket.js +28 -19
- package/dest/node-cjs/barretenberg/backend.d.ts +9 -23
- package/dest/node-cjs/barretenberg/backend.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/backend.js +30 -90
- package/dest/node-cjs/barretenberg/blake2s.test.js +6 -6
- package/dest/node-cjs/barretenberg/index.d.ts +1 -3
- package/dest/node-cjs/barretenberg/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/index.js +15 -24
- package/dest/node-cjs/barretenberg/pedersen.test.js +9 -9
- package/dest/node-cjs/barretenberg/poseidon.bench.test.js +36 -77
- package/dest/node-cjs/barretenberg/poseidon.test.js +4 -4
- package/dest/node-cjs/{bigint-array/index.d.ts → barretenberg/testing/bigint-buffer.d.ts} +1 -1
- package/dest/node-cjs/barretenberg/testing/bigint-buffer.d.ts.map +1 -0
- package/dest/node-cjs/barretenberg/testing/bigint-buffer.js +43 -0
- package/dest/node-cjs/barretenberg/testing/fields.d.ts +16 -0
- package/dest/node-cjs/barretenberg/testing/fields.d.ts.map +1 -0
- package/dest/node-cjs/barretenberg/testing/fields.js +52 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node-cjs/bb_backends/index.d.ts +8 -5
- package/dest/node-cjs/bb_backends/index.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/index.js +5 -5
- package/dest/node-cjs/bb_backends/node/index.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/node/index.js +12 -4
- package/dest/node-cjs/bb_backends/node/native_shm.d.ts +2 -1
- package/dest/node-cjs/bb_backends/node/native_shm.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/node/native_shm.js +50 -15
- package/dest/node-cjs/bb_backends/node/native_socket.d.ts +1 -1
- package/dest/node-cjs/bb_backends/node/native_socket.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/node/native_socket.js +28 -19
- package/package.json +1 -1
- package/src/barretenberg/backend.ts +19 -97
- package/src/barretenberg/blake2s.test.ts +1 -1
- package/src/barretenberg/index.ts +14 -24
- package/src/barretenberg/pedersen.test.ts +1 -1
- package/src/barretenberg/poseidon.bench.test.ts +109 -156
- package/src/barretenberg/poseidon.test.ts +1 -1
- package/src/{types → barretenberg/testing}/fields.ts +12 -26
- package/src/bb_backends/index.ts +8 -5
- package/src/bb_backends/node/index.ts +23 -3
- package/src/bb_backends/node/native_shm.ts +51 -14
- package/src/bb_backends/node/native_socket.ts +31 -17
- package/dest/browser/bigint-array/index.d.ts.map +0 -1
- package/dest/browser/bigint-array/index.js +0 -37
- package/dest/browser/serialize/index.d.ts +0 -2
- package/dest/browser/serialize/index.d.ts.map +0 -1
- package/dest/browser/serialize/index.js +0 -2
- package/dest/browser/serialize/serialize.d.ts +0 -18
- package/dest/browser/serialize/serialize.d.ts.map +0 -1
- package/dest/browser/serialize/serialize.js +0 -72
- package/dest/browser/types/fields.d.ts +0 -23
- package/dest/browser/types/fields.d.ts.map +0 -1
- package/dest/browser/types/fields.js +0 -61
- package/dest/browser/types/index.d.ts +0 -3
- package/dest/browser/types/index.d.ts.map +0 -1
- package/dest/browser/types/index.js +0 -3
- package/dest/browser/types/point.d.ts +0 -18
- package/dest/browser/types/point.d.ts.map +0 -1
- package/dest/browser/types/point.js +0 -28
- package/dest/node/bigint-array/index.d.ts.map +0 -1
- package/dest/node/bigint-array/index.js +0 -37
- package/dest/node/serialize/index.d.ts +0 -2
- package/dest/node/serialize/index.d.ts.map +0 -1
- package/dest/node/serialize/index.js +0 -2
- package/dest/node/serialize/serialize.d.ts +0 -18
- package/dest/node/serialize/serialize.d.ts.map +0 -1
- package/dest/node/serialize/serialize.js +0 -72
- package/dest/node/types/fields.d.ts +0 -23
- package/dest/node/types/fields.d.ts.map +0 -1
- package/dest/node/types/fields.js +0 -61
- package/dest/node/types/index.d.ts +0 -3
- package/dest/node/types/index.d.ts.map +0 -1
- package/dest/node/types/index.js +0 -3
- package/dest/node/types/point.d.ts +0 -18
- package/dest/node/types/point.d.ts.map +0 -1
- package/dest/node/types/point.js +0 -28
- package/dest/node-cjs/bigint-array/index.d.ts.map +0 -1
- package/dest/node-cjs/bigint-array/index.js +0 -43
- package/dest/node-cjs/serialize/index.d.ts +0 -2
- package/dest/node-cjs/serialize/index.d.ts.map +0 -1
- package/dest/node-cjs/serialize/index.js +0 -5
- package/dest/node-cjs/serialize/serialize.d.ts +0 -18
- package/dest/node-cjs/serialize/serialize.d.ts.map +0 -1
- package/dest/node-cjs/serialize/serialize.js +0 -82
- package/dest/node-cjs/types/fields.d.ts +0 -23
- package/dest/node-cjs/types/fields.d.ts.map +0 -1
- package/dest/node-cjs/types/fields.js +0 -65
- package/dest/node-cjs/types/index.d.ts +0 -3
- package/dest/node-cjs/types/index.d.ts.map +0 -1
- package/dest/node-cjs/types/index.js +0 -6
- package/dest/node-cjs/types/point.d.ts +0 -18
- package/dest/node-cjs/types/point.d.ts.map +0 -1
- package/dest/node-cjs/types/point.js +0 -32
- package/src/serialize/index.ts +0 -1
- package/src/serialize/serialize.ts +0 -75
- package/src/types/index.ts +0 -2
- package/src/types/point.ts +0 -32
- /package/src/{bigint-array/index.ts → barretenberg/testing/bigint-buffer.ts} +0 -0
|
@@ -31,7 +31,7 @@ export class Barretenberg extends AsyncApi {
|
|
|
31
31
|
*
|
|
32
32
|
* If options.backend is set: uses that specific backend (throws if unavailable)
|
|
33
33
|
* If options.backend is unset: tries backends in order with fallback:
|
|
34
|
-
* 1.
|
|
34
|
+
* 1. NativeUnixSocket (if bb binary available)
|
|
35
35
|
* 2. WasmWorker (in browser) or Wasm (in Node.js)
|
|
36
36
|
*/
|
|
37
37
|
static async new(options: BackendOptions = {}) {
|
|
@@ -39,35 +39,30 @@ export class Barretenberg extends AsyncApi {
|
|
|
39
39
|
|
|
40
40
|
if (options.backend) {
|
|
41
41
|
// Explicit backend required - no fallback
|
|
42
|
-
|
|
42
|
+
const backend = await createAsyncBackend(options.backend, options, logger);
|
|
43
|
+
if (options.backend === BackendType.Wasm || options.backend === BackendType.WasmWorker) {
|
|
44
|
+
await backend.initSRSChonk();
|
|
45
|
+
}
|
|
46
|
+
return backend;
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
if (typeof window === 'undefined') {
|
|
46
50
|
try {
|
|
47
|
-
return await createAsyncBackend(BackendType.
|
|
51
|
+
return await createAsyncBackend(BackendType.NativeUnixSocket, options, logger);
|
|
48
52
|
} catch (err: any) {
|
|
49
|
-
logger(`
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
logger(`Unix socket unavailable (${err.message}), falling back to WASM`);
|
|
54
|
-
return await createAsyncBackend(BackendType.Wasm, options, logger);
|
|
55
|
-
}
|
|
53
|
+
logger(`Unix socket unavailable (${err.message}), falling back to WASM`);
|
|
54
|
+
const backend = await createAsyncBackend(BackendType.Wasm, options, logger);
|
|
55
|
+
await backend.initSRSChonk();
|
|
56
|
+
return backend;
|
|
56
57
|
}
|
|
57
58
|
} else {
|
|
58
59
|
logger(`In browser, using WASM over worker backend.`);
|
|
59
|
-
|
|
60
|
+
const backend = await createAsyncBackend(BackendType.WasmWorker, options, logger);
|
|
61
|
+
await backend.initSRSChonk();
|
|
62
|
+
return backend;
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
async initSRSForCircuitSize(circuitSize: number): Promise<void> {
|
|
64
|
-
const minSRSSize = 2 ** 9; // 2**9 is the dyadic size for the SmallSubgroupIPA MSM.
|
|
65
|
-
const crs = await Crs.new(Math.max(circuitSize, minSRSSize) + 1, this.options.crsPath, this.options.logger);
|
|
66
|
-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1129): Do slab allocator initialization?
|
|
67
|
-
// await this.commonInitSlabAllocator(circuitSize);
|
|
68
|
-
await this.srsInitSrs({ pointsBuf: crs.getG1Data(), numPoints: crs.numPoints, g2Point: crs.getG2Data() });
|
|
69
|
-
}
|
|
70
|
-
|
|
71
66
|
async initSRSChonk(srsSize = this.getDefaultSrsSize()): Promise<void> {
|
|
72
67
|
// crsPath can be undefined
|
|
73
68
|
const crs = await Crs.new(srsSize + 1, this.options.crsPath, this.options.logger);
|
|
@@ -106,11 +101,6 @@ export class Barretenberg extends AsyncApi {
|
|
|
106
101
|
return [response.numGates, response.numGatesDyadic];
|
|
107
102
|
}
|
|
108
103
|
|
|
109
|
-
async acirInitSRS(bytecode: Uint8Array, recursive: boolean, honkRecursion: boolean): Promise<void> {
|
|
110
|
-
const [_, subgroupSize] = await this.acirGetCircuitSizes(bytecode, recursive, honkRecursion);
|
|
111
|
-
return this.initSRSForCircuitSize(subgroupSize);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
104
|
async destroy() {
|
|
115
105
|
return super.destroy();
|
|
116
106
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Barretenberg, BarretenbergSync } from '../index.js';
|
|
2
|
-
import { Fr } from '../types/fields.js';
|
|
3
|
-
import { serializeBufferable } from '../serialize/index.js';
|
|
4
2
|
import { BarretenbergWasmMain } from '../barretenberg_wasm/barretenberg_wasm_main/index.js';
|
|
5
3
|
import { fetchModuleAndThreads } from '../barretenberg_wasm/index.js';
|
|
6
4
|
import { BackendType } from './index.js';
|
|
5
|
+
import { Fr } from './testing/fields.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Async API benchmark test: WASM vs Native backends with proper non-blocking I/O
|
|
@@ -67,170 +66,129 @@ describe('poseidon2Hash benchmark (Async API): WASM vs Native', () => {
|
|
|
67
66
|
}
|
|
68
67
|
}, 20000);
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
if (nativeShmApi) {
|
|
79
|
-
await nativeShmApi.destroy();
|
|
80
|
-
}
|
|
81
|
-
if (nativeShmSyncApi) {
|
|
82
|
-
nativeShmSyncApi.destroy();
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
async function directPoseidon2Hash(inputsBuffer: Fr[]): Promise<Fr> {
|
|
87
|
-
const inArgs = [inputsBuffer].map(serializeBufferable);
|
|
88
|
-
const outTypes = [Fr];
|
|
89
|
-
const result = wasm.callWasmExport(
|
|
90
|
-
'poseidon2_hash',
|
|
91
|
-
inArgs,
|
|
92
|
-
outTypes.map(t => t.SIZE_IN_BYTES),
|
|
93
|
-
);
|
|
94
|
-
const out = result.map((r, i) => outTypes[i].fromBuffer(r));
|
|
95
|
-
return Promise.resolve(out[0]);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
it.each(SIZES)('benchmark with %p field elements', async size => {
|
|
99
|
-
// Generate random inputs
|
|
100
|
-
const inputs = Array(size)
|
|
101
|
-
.fill(0)
|
|
102
|
-
.map(() => Fr.random());
|
|
103
|
-
|
|
104
|
-
// Benchmark 1: Direct WASM (baseline - always available)
|
|
105
|
-
const directStart = performance.now();
|
|
106
|
-
for (let i = 0; i < ITERATIONS; i++) {
|
|
107
|
-
await directPoseidon2Hash(inputs);
|
|
108
|
-
}
|
|
109
|
-
const directTime = performance.now() - directStart;
|
|
69
|
+
it.each(SIZES)(
|
|
70
|
+
'benchmark with %p field elements',
|
|
71
|
+
async size => {
|
|
72
|
+
// Generate random inputs
|
|
73
|
+
const inputs = Array(size)
|
|
74
|
+
.fill(0)
|
|
75
|
+
.map(() => Fr.random().toBuffer());
|
|
110
76
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
77
|
+
// Benchmark 1: WASM (async)
|
|
78
|
+
let wasmTime = 0;
|
|
79
|
+
if (wasmApi) {
|
|
80
|
+
const wasmStart = performance.now();
|
|
81
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
82
|
+
await wasmApi.poseidon2Hash({ inputs });
|
|
83
|
+
}
|
|
84
|
+
wasmTime = performance.now() - wasmStart;
|
|
117
85
|
}
|
|
118
|
-
wasmTime = performance.now() - wasmStart;
|
|
119
|
-
}
|
|
120
86
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
87
|
+
// Benchmark 2: Native Socket (async with non-blocking I/O)
|
|
88
|
+
let nativeSocketTime = 0;
|
|
89
|
+
if (nativeSocketApi) {
|
|
90
|
+
const nativeSocketStart = performance.now();
|
|
91
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
92
|
+
await nativeSocketApi.poseidon2Hash({ inputs });
|
|
93
|
+
}
|
|
94
|
+
nativeSocketTime = performance.now() - nativeSocketStart;
|
|
127
95
|
}
|
|
128
|
-
nativeSocketTime = performance.now() - nativeSocketStart;
|
|
129
|
-
}
|
|
130
96
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
97
|
+
// Benchmark 3: Native Shared Memory (async)
|
|
98
|
+
let nativeShmTime = 0;
|
|
99
|
+
if (nativeShmApi) {
|
|
100
|
+
const nativeShmStart = performance.now();
|
|
101
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
102
|
+
await nativeShmApi.poseidon2Hash({ inputs });
|
|
103
|
+
}
|
|
104
|
+
nativeShmTime = performance.now() - nativeShmStart;
|
|
137
105
|
}
|
|
138
|
-
nativeShmTime = performance.now() - nativeShmStart;
|
|
139
|
-
}
|
|
140
106
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
107
|
+
// Benchmark 4: Native Shared Memory (sync)
|
|
108
|
+
let nativeShmSyncTime = 0;
|
|
109
|
+
if (nativeShmSyncApi) {
|
|
110
|
+
const nativeShmSyncStart = performance.now();
|
|
111
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
112
|
+
nativeShmSyncApi.poseidon2Hash({ inputs });
|
|
113
|
+
}
|
|
114
|
+
nativeShmSyncTime = performance.now() - nativeShmSyncStart;
|
|
147
115
|
}
|
|
148
|
-
nativeShmSyncTime = performance.now() - nativeShmSyncStart;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Calculate metrics (all relative to WASM baseline)
|
|
152
|
-
const directOverhead = ((directTime - wasmTime) / wasmTime) * 100;
|
|
153
|
-
const nativeSocketOverhead = ((nativeSocketTime - wasmTime) / wasmTime) * 100;
|
|
154
|
-
const nativeShmOverhead = ((nativeShmTime - wasmTime) / wasmTime) * 100;
|
|
155
|
-
const nativeShmSyncOverhead = ((nativeShmSyncTime - wasmTime) / wasmTime) * 100;
|
|
156
116
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const avgNativeShmSyncTimeUs = (nativeShmSyncTime / ITERATIONS) * 1000;
|
|
117
|
+
// Calculate metrics (all relative to WASM baseline)
|
|
118
|
+
const nativeSocketOverhead = ((nativeSocketTime - wasmTime) / wasmTime) * 100;
|
|
119
|
+
const nativeShmOverhead = ((nativeShmTime - wasmTime) / wasmTime) * 100;
|
|
120
|
+
const nativeShmSyncOverhead = ((nativeShmSyncTime - wasmTime) / wasmTime) * 100;
|
|
162
121
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
return `${sign}${value}%`;
|
|
168
|
-
};
|
|
122
|
+
const avgWasmTimeUs = (wasmTime / ITERATIONS) * 1000;
|
|
123
|
+
const avgNativeSocketTimeUs = (nativeSocketTime / ITERATIONS) * 1000;
|
|
124
|
+
const avgNativeShmTimeUs = (nativeShmTime / ITERATIONS) * 1000;
|
|
125
|
+
const avgNativeShmSyncTimeUs = (nativeShmSyncTime / ITERATIONS) * 1000;
|
|
169
126
|
|
|
170
|
-
if (wasmApi) {
|
|
171
127
|
process.stdout.write(
|
|
172
|
-
|
|
128
|
+
`┌─ Size ${size.toString().padStart(3)} field elements ──────────────────────────────────┐\n`,
|
|
173
129
|
);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
130
|
+
const formatOverhead = (overhead: number): string => {
|
|
131
|
+
const sign = overhead >= 0 ? '+' : '-';
|
|
132
|
+
const value = Math.abs(overhead).toFixed(1).padStart(6);
|
|
133
|
+
return `${sign}${value}%`;
|
|
134
|
+
};
|
|
177
135
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
);
|
|
186
|
-
} else {
|
|
187
|
-
process.stdout.write(`│ Native Socket: unavailable │\n`);
|
|
188
|
-
}
|
|
136
|
+
if (wasmApi) {
|
|
137
|
+
process.stdout.write(
|
|
138
|
+
`│ WASM: ${wasmTime.toFixed(2).padStart(8)}ms (${avgWasmTimeUs.toFixed(2).padStart(7)}µs/call) [baseline] │\n`,
|
|
139
|
+
);
|
|
140
|
+
} else {
|
|
141
|
+
process.stdout.write(`│ WASM: unavailable │\n`);
|
|
142
|
+
}
|
|
189
143
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
144
|
+
if (nativeSocketApi) {
|
|
145
|
+
process.stdout.write(
|
|
146
|
+
`│ Native Socket: ${nativeSocketTime.toFixed(2).padStart(8)}ms (${avgNativeSocketTimeUs.toFixed(2).padStart(7)}µs/call) ${formatOverhead(nativeSocketOverhead)} │\n`,
|
|
147
|
+
);
|
|
148
|
+
} else {
|
|
149
|
+
process.stdout.write(`│ Native Socket: unavailable │\n`);
|
|
150
|
+
}
|
|
197
151
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
152
|
+
if (nativeShmApi) {
|
|
153
|
+
process.stdout.write(
|
|
154
|
+
`│ Native Shared: ${nativeShmTime.toFixed(2).padStart(8)}ms (${avgNativeShmTimeUs.toFixed(2).padStart(7)}µs/call) ${formatOverhead(nativeShmOverhead)} │\n`,
|
|
155
|
+
);
|
|
156
|
+
} else {
|
|
157
|
+
process.stdout.write(`│ Native Shared: unavailable │\n`);
|
|
158
|
+
}
|
|
205
159
|
|
|
206
|
-
|
|
160
|
+
if (nativeShmSyncApi) {
|
|
161
|
+
process.stdout.write(
|
|
162
|
+
`│ Native Shared Sync: ${nativeShmSyncTime.toFixed(2).padStart(8)}ms (${avgNativeShmSyncTimeUs.toFixed(2).padStart(7)}µs/call) ${formatOverhead(nativeShmSyncOverhead)} │\n`,
|
|
163
|
+
);
|
|
164
|
+
} else {
|
|
165
|
+
process.stdout.write(`│ Native Shared Sync: unavailable │\n`);
|
|
166
|
+
}
|
|
207
167
|
|
|
208
|
-
|
|
209
|
-
const directResult = await directPoseidon2Hash(inputs);
|
|
168
|
+
process.stdout.write(`└────────────────────────────────────────────────────────────┘\n`);
|
|
210
169
|
|
|
211
|
-
|
|
212
|
-
const wasmResult = await wasmApi.poseidon2Hash({ inputs: inputs.map(fr => fr.toBuffer()) });
|
|
213
|
-
expect(Buffer.from(wasmResult.hash)).toEqual(directResult.toBuffer());
|
|
214
|
-
}
|
|
170
|
+
const wasmResult = await wasmApi!.poseidon2Hash({ inputs });
|
|
215
171
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
172
|
+
if (nativeSocketApi) {
|
|
173
|
+
const nativeSocketResult = await nativeSocketApi.poseidon2Hash({ inputs });
|
|
174
|
+
expect(Buffer.from(nativeSocketResult.hash)).toEqual(wasmResult.hash);
|
|
175
|
+
}
|
|
220
176
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
177
|
+
if (nativeShmApi) {
|
|
178
|
+
const nativeShmResult = await nativeShmApi.poseidon2Hash({ inputs });
|
|
179
|
+
expect(Buffer.from(nativeShmResult.hash)).toEqual(wasmResult.hash);
|
|
180
|
+
}
|
|
225
181
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
182
|
+
if (nativeShmSyncApi) {
|
|
183
|
+
const nativeShmSyncResult = nativeShmSyncApi.poseidon2Hash({ inputs });
|
|
184
|
+
expect(Buffer.from(nativeShmSyncResult.hash)).toEqual(wasmResult.hash);
|
|
185
|
+
}
|
|
230
186
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
187
|
+
// Test always passes, this is just for measuring performance
|
|
188
|
+
expect(true).toBe(true);
|
|
189
|
+
},
|
|
190
|
+
10000,
|
|
191
|
+
);
|
|
234
192
|
|
|
235
193
|
const TEST_VECTORS = [1, 2, 3, 5, 10, 50, 100];
|
|
236
194
|
const NUM_RANDOM_TESTS = 10;
|
|
@@ -240,28 +198,23 @@ describe('poseidon2Hash benchmark (Async API): WASM vs Native', () => {
|
|
|
240
198
|
for (let test = 0; test < NUM_RANDOM_TESTS; test++) {
|
|
241
199
|
const inputs = Array(size)
|
|
242
200
|
.fill(0)
|
|
243
|
-
.map(() => Fr.random());
|
|
201
|
+
.map(() => Fr.random().toBuffer());
|
|
244
202
|
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
if (wasmApi) {
|
|
248
|
-
const wasmResult = await wasmApi.poseidon2Hash({ inputs: inputs.map(fr => fr.toBuffer()) });
|
|
249
|
-
expect(Buffer.from(wasmResult.hash)).toEqual(directResult.toBuffer());
|
|
250
|
-
}
|
|
203
|
+
const wasmResult = await wasmApi!.poseidon2Hash({ inputs });
|
|
251
204
|
|
|
252
205
|
if (nativeSocketApi) {
|
|
253
|
-
const nativeSocketResult = await nativeSocketApi.poseidon2Hash({ inputs
|
|
254
|
-
expect(Buffer.from(nativeSocketResult.hash)).toEqual(
|
|
206
|
+
const nativeSocketResult = await nativeSocketApi.poseidon2Hash({ inputs });
|
|
207
|
+
expect(Buffer.from(nativeSocketResult.hash)).toEqual(wasmResult.hash);
|
|
255
208
|
}
|
|
256
209
|
|
|
257
210
|
if (nativeShmApi) {
|
|
258
|
-
const nativeShmResult = await nativeShmApi.poseidon2Hash({ inputs
|
|
259
|
-
expect(Buffer.from(nativeShmResult.hash)).toEqual(
|
|
211
|
+
const nativeShmResult = await nativeShmApi.poseidon2Hash({ inputs });
|
|
212
|
+
expect(Buffer.from(nativeShmResult.hash)).toEqual(wasmResult.hash);
|
|
260
213
|
}
|
|
261
214
|
|
|
262
215
|
if (nativeShmSyncApi) {
|
|
263
|
-
const nativeShmSyncResult = nativeShmSyncApi.poseidon2Hash({ inputs
|
|
264
|
-
expect(Buffer.from(nativeShmSyncResult.hash)).toEqual(
|
|
216
|
+
const nativeShmSyncResult = nativeShmSyncApi.poseidon2Hash({ inputs });
|
|
217
|
+
expect(Buffer.from(nativeShmSyncResult.hash)).toEqual(wasmResult.hash);
|
|
265
218
|
}
|
|
266
219
|
}
|
|
267
220
|
});
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { randomBytes } from '
|
|
1
|
+
import { randomBytes } from '../../random/index.js';
|
|
2
2
|
import {
|
|
3
3
|
buffer32BytesToBigIntBE,
|
|
4
4
|
uint8ArrayToBigIntBE,
|
|
5
5
|
bigIntToBufferBE,
|
|
6
6
|
bigIntToUint8ArrayBE,
|
|
7
|
-
} from '
|
|
7
|
+
} from './bigint-buffer.js';
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Internal Fr field class for tests.
|
|
11
|
-
* @dev This minimal implementation is provided for testing barretenberg directly.
|
|
12
|
-
* Projects using bb.js should create their own field abstraction using the curve constants
|
|
13
|
-
* exported from the barretenberg binary (see CurveConstants generation).
|
|
14
|
-
*/
|
|
15
9
|
export class Fr {
|
|
16
10
|
static ZERO = new Fr(0n);
|
|
17
11
|
static MODULUS = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n;
|
|
@@ -41,24 +35,6 @@ export class Fr {
|
|
|
41
35
|
return new this(r);
|
|
42
36
|
}
|
|
43
37
|
|
|
44
|
-
static fromBuffer(buffer: Uint8Array | Buffer) {
|
|
45
|
-
if (buffer.length !== this.SIZE_IN_BYTES) {
|
|
46
|
-
throw new Error(`Expected ${this.SIZE_IN_BYTES} bytes, got ${buffer.length}`);
|
|
47
|
-
}
|
|
48
|
-
return new this(buffer);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
static fromBufferReduce(buffer: Uint8Array | Buffer) {
|
|
52
|
-
if (buffer.length !== this.SIZE_IN_BYTES) {
|
|
53
|
-
throw new Error(`Expected ${this.SIZE_IN_BYTES} bytes, got ${buffer.length}`);
|
|
54
|
-
}
|
|
55
|
-
return new this(uint8ArrayToBigIntBE(buffer instanceof Buffer ? new Uint8Array(buffer) : buffer) % Fr.MODULUS);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static fromString(str: string) {
|
|
59
|
-
return this.fromBuffer(Buffer.from(str.replace(/^0x/i, ''), 'hex'));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
38
|
toBuffer() {
|
|
63
39
|
return this.value;
|
|
64
40
|
}
|
|
@@ -74,4 +50,14 @@ export class Fr {
|
|
|
74
50
|
isZero() {
|
|
75
51
|
return this.value.every(v => v === 0);
|
|
76
52
|
}
|
|
53
|
+
|
|
54
|
+
static fromBuffer(value: Uint8Array): Fr {
|
|
55
|
+
return Fr.fromBufferReduce(value);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static fromBufferReduce(value: Uint8Array): Fr {
|
|
59
|
+
const valueBigInt = uint8ArrayToBigIntBE(value);
|
|
60
|
+
const reducedValue = valueBigInt % Fr.MODULUS;
|
|
61
|
+
return new Fr(reducedValue);
|
|
62
|
+
}
|
|
77
63
|
}
|
package/src/bb_backends/index.ts
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export enum BackendType {
|
|
5
5
|
/** WASM direct execution (no worker) */
|
|
6
|
-
Wasm = '
|
|
6
|
+
Wasm = 'Wasm',
|
|
7
7
|
/** WASM with worker threads */
|
|
8
|
-
WasmWorker = '
|
|
8
|
+
WasmWorker = 'WasmWorker',
|
|
9
9
|
/** Native via Unix domain socket (async only) */
|
|
10
|
-
NativeUnixSocket = '
|
|
10
|
+
NativeUnixSocket = 'NativeUnixSocket',
|
|
11
11
|
/** Native via shared memory (sync only currently) */
|
|
12
|
-
NativeSharedMemory = '
|
|
12
|
+
NativeSharedMemory = 'NativeSharedMemory',
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export type BackendOptions = {
|
|
@@ -28,7 +28,10 @@ export type BackendOptions = {
|
|
|
28
28
|
/** @description Custom path to bb binary for native backend (overrides automatic detection) */
|
|
29
29
|
bbPath?: string;
|
|
30
30
|
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* @description Logging function
|
|
33
|
+
* Warning: Attaching a logger can prevent nodejs from exiting without explicitly destroying the backend.
|
|
34
|
+
*/
|
|
32
35
|
logger?: (msg: string) => void;
|
|
33
36
|
|
|
34
37
|
/**
|
|
@@ -14,6 +14,11 @@ export async function createAsyncBackend(
|
|
|
14
14
|
options: BackendOptions,
|
|
15
15
|
logger: (msg: string) => void,
|
|
16
16
|
): Promise<Barretenberg> {
|
|
17
|
+
options = {
|
|
18
|
+
...options,
|
|
19
|
+
wasmPath: options.wasmPath ?? process.env.BB_WASM_PATH,
|
|
20
|
+
};
|
|
21
|
+
|
|
17
22
|
switch (type) {
|
|
18
23
|
case BackendType.NativeUnixSocket: {
|
|
19
24
|
const bbPath = findBbBinary(options.bbPath);
|
|
@@ -21,7 +26,7 @@ export async function createAsyncBackend(
|
|
|
21
26
|
throw new Error('Native backend requires bb binary.');
|
|
22
27
|
}
|
|
23
28
|
logger(`Using native Unix socket backend: ${bbPath}`);
|
|
24
|
-
const socket = new BarretenbergNativeSocketAsyncBackend(bbPath, options.threads);
|
|
29
|
+
const socket = new BarretenbergNativeSocketAsyncBackend(bbPath, options.threads, options.logger);
|
|
25
30
|
return new Barretenberg(socket, options);
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -36,7 +41,12 @@ export async function createAsyncBackend(
|
|
|
36
41
|
}
|
|
37
42
|
logger(`Using native shared memory backend (via sync adapter): ${bbPath}`);
|
|
38
43
|
// Use sync backend with adapter to provide async interface
|
|
39
|
-
const syncBackend = await BarretenbergNativeShmSyncBackend.new(
|
|
44
|
+
const syncBackend = await BarretenbergNativeShmSyncBackend.new(
|
|
45
|
+
bbPath,
|
|
46
|
+
options.threads,
|
|
47
|
+
options.maxClients,
|
|
48
|
+
options.logger,
|
|
49
|
+
);
|
|
40
50
|
const asyncBackend = new SyncToAsyncAdapter(syncBackend);
|
|
41
51
|
return new Barretenberg(asyncBackend, options);
|
|
42
52
|
}
|
|
@@ -68,6 +78,11 @@ export async function createSyncBackend(
|
|
|
68
78
|
options: BackendOptions,
|
|
69
79
|
logger: (msg: string) => void,
|
|
70
80
|
): Promise<BarretenbergSync> {
|
|
81
|
+
options = {
|
|
82
|
+
...options,
|
|
83
|
+
wasmPath: options.wasmPath ?? process.env.BB_WASM_PATH,
|
|
84
|
+
};
|
|
85
|
+
|
|
71
86
|
switch (type) {
|
|
72
87
|
case BackendType.NativeSharedMemory: {
|
|
73
88
|
const bbPath = findBbBinary(options.bbPath);
|
|
@@ -79,7 +94,12 @@ export async function createSyncBackend(
|
|
|
79
94
|
throw new Error('Native sync backend requires napi client stub.');
|
|
80
95
|
}
|
|
81
96
|
logger(`Using native shared memory backend: ${bbPath}`);
|
|
82
|
-
const shm = await BarretenbergNativeShmSyncBackend.new(
|
|
97
|
+
const shm = await BarretenbergNativeShmSyncBackend.new(
|
|
98
|
+
bbPath,
|
|
99
|
+
options.threads,
|
|
100
|
+
options.maxClients,
|
|
101
|
+
options.logger,
|
|
102
|
+
);
|
|
83
103
|
return new BarretenbergSync(shm);
|
|
84
104
|
}
|
|
85
105
|
|