@xmbl/simulator 0.1.11 → 0.1.12
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/CHANGELOG.md +4 -2
- package/DEVNET-SEAM-FINDING.md +2 -2
- package/package.json +1 -1
- package/src/capabilities.js +5 -5
- package/src/devnet-rpc.js +2 -2
- package/src/devnet-rpc.test.mjs +1 -1
- package/src/simulator.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.12
|
|
4
|
+
|
|
3
5
|
## 0.1.11
|
|
4
6
|
|
|
5
7
|
### Patch Changes
|
|
@@ -18,7 +20,7 @@
|
|
|
18
20
|
never under the xid it claims (a datum fails `validateXid` precisely when that xid is somebody else's), and
|
|
19
21
|
the anchor dedup key claimed before validation is released on every failure. Both doors are closed on BOTH
|
|
20
22
|
entry points — `addTransaction` and `addSealedBatch`, the path a finalized transaction actually takes — and
|
|
21
|
-
one invalid entry in a batch no longer discards the
|
|
23
|
+
one invalid entry in a batch no longer discards the genuine transactions behind it.
|
|
22
24
|
- consensus: a content-addressed type-6 value tx is admitted on its content address (it carries no in-body
|
|
23
25
|
signature by design); a malformed anchor is refused at the door by the ledger's own `validateTransaction`;
|
|
24
26
|
`finalizeTransaction` preserves the signed `id`.
|
|
@@ -28,7 +30,7 @@
|
|
|
28
30
|
- networking: self-elected circuit-relay server; NO_FATAL transport tolerance; throttled bootstrap warnings.
|
|
29
31
|
- storage-compute: `CoordinateDelivery` (broken: `require` in ESM, keyed on the public key) is removed.
|
|
30
32
|
- core: ships the node daemon as the `xmbl-node` bin; the control socket implements the coordinator
|
|
31
|
-
contract (`xsc`, `submit_batch`, `ledger_capabilities`, `identity_status`, a signed `chain` claim,
|
|
33
|
+
contract (`xsc`, `submit_batch`, `ledger_capabilities`, `identity_status`, a signed `chain` claim, genuine
|
|
32
34
|
`submit_tx` rejections) and reports the RUNNING versions; boot waits for the stores.
|
|
33
35
|
- every package exports a load-time `VERSION`.
|
|
34
36
|
- PROTOCOL (operator, 2026-09-16): every transaction is typed by its xid (tokens.json type codes; `micromineTx`/
|
package/DEVNET-SEAM-FINDING.md
CHANGED
|
@@ -5,7 +5,7 @@ opts into ledger-side signature verification — it wires **both** `xid` and
|
|
|
5
5
|
`getPublicKeyByAddress` into the `Ledger` — which is precisely the caller configuration that
|
|
6
6
|
exercises defects no production code path currently reaches. Two of the three defects below are
|
|
7
7
|
now **FIXED**; the third is a genuine signature-domain decision left for the audit and documented
|
|
8
|
-
|
|
8
|
+
accurately rather than papered over. All are covered by `src/devnet.test.mjs`.
|
|
9
9
|
|
|
10
10
|
## Where ledger-side verification runs
|
|
11
11
|
|
|
@@ -92,7 +92,7 @@ architectural choices, **which is an audit-level signature-domain / block-identi
|
|
|
92
92
|
Both touch `block.js`, ledger dedup, and cross-node determinism, so neither rides in on a tooling
|
|
93
93
|
commit. Until one is made and audited, **ledger-side re-verification stays OFF in production**
|
|
94
94
|
(the `getPublicKeyByAddress` lookup is deliberately not wired into the `Ledger`), and consensus
|
|
95
|
-
remains the single verification point. This is the
|
|
95
|
+
remains the single verification point. This is the genuine, current posture — not a silent gap.
|
|
96
96
|
|
|
97
97
|
## Why the devnet drives the direct path
|
|
98
98
|
|
package/package.json
CHANGED
package/src/capabilities.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// zk / homomorphic-encryption / signature primitives in-page (they need node:crypto; an MV3 page
|
|
3
3
|
// CSP and WebCrypto's async sha256 make a faithful in-page port impossible), so the devnet node
|
|
4
4
|
// process — which already loads the REAL modules — runs each primitive end-to-end and returns a
|
|
5
|
-
// JSON-safe verdict. Each runner does the
|
|
5
|
+
// JSON-safe verdict. Each runner does the right thing and its NEGATIVE control in one call: it
|
|
6
6
|
// proves the capability verifies true input AND rejects tampered input, so a green card on screen
|
|
7
7
|
// is backed by a real refusal, not a fabricated pass. Every flow mirrors the headless
|
|
8
8
|
// reproductions in @xmbl/contracts (reproductions/contract-zk.mjs, contract-he.mjs,
|
|
@@ -25,7 +25,7 @@ const CUBE_CONTEXT = {
|
|
|
25
25
|
|
|
26
26
|
// ── Coordinate / curve zero-knowledge (@xmbl/zero-knowledge, FRI, ⛔ UNAUDITED) ──
|
|
27
27
|
// A prover shows a coordinate (derivedX, derivedY) lies on a curve through secret points, and a
|
|
28
|
-
// verifier checks it WITHOUT the secret points. We prove the
|
|
28
|
+
// verifier checks it WITHOUT the secret points. We prove the genuine coordinate and reject a
|
|
29
29
|
// tampered y (derivedY+1) — the exact pair reproductions/contract-zk.mjs gates a Verkle write on.
|
|
30
30
|
export function zkProof({ derivedX = 99 } = {}) {
|
|
31
31
|
const ctx = setup();
|
|
@@ -34,14 +34,14 @@ export function zkProof({ derivedX = 99 } = {}) {
|
|
|
34
34
|
const dX = bi(derivedX);
|
|
35
35
|
const { Pt, derivedY } = blindedCurve(ctx, { publicPoints, secretPoints, derivedX: dX });
|
|
36
36
|
const proof = prove(ctx, { Pt, publicPoints, derivedX: dX, derivedY });
|
|
37
|
-
const
|
|
37
|
+
const genuine = zkVerify(ctx, { proof, publicPoints, derivedX: dX, derivedY });
|
|
38
38
|
const tampered = zkVerify(ctx, { proof, publicPoints, derivedX: dX, derivedY: derivedY + 1n });
|
|
39
39
|
return {
|
|
40
|
-
ok:
|
|
40
|
+
ok: genuine === true && tampered === false,
|
|
41
41
|
scheme: 'xzk (FRI coordinate/curve proof, UNAUDITED)',
|
|
42
42
|
derivedX: str(dX), derivedY: str(derivedY),
|
|
43
43
|
publicAnchors: publicPoints.length,
|
|
44
|
-
|
|
44
|
+
genuineVerifies: genuine, tamperedRejected: tampered === false,
|
|
45
45
|
note: 'proof checked without the secret points; a coordinate off the curve is rejected',
|
|
46
46
|
};
|
|
47
47
|
}
|
package/src/devnet-rpc.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// It ALSO serves the node-side capability surface the extension cannot run in-page — each a REAL
|
|
18
18
|
// primitive run end-to-end in this node process, verdict returned JSON-safe (see capabilities.js):
|
|
19
19
|
// getStateRoot {type} → { root, pooled, landed } // live ledger state root
|
|
20
|
-
// zkProof {type, derivedX?} → { ok, derivedX, derivedY,
|
|
20
|
+
// zkProof {type, derivedX?} → { ok, derivedX, derivedY, genuineVerifies, tamperedRejected, … }
|
|
21
21
|
// heAdd {type, a?, b?} → { ok, a, b, sum, expected, … } // homomorphic add
|
|
22
22
|
// sigVerify {type, message?} → { ok, signedVerifies, tamperedRejected, … } // Cubic-SIG
|
|
23
23
|
// seal {type, secret?} → { ok, roundTrip, … } // PQ KEM seal
|
|
@@ -69,7 +69,7 @@ export class DevnetRpc {
|
|
|
69
69
|
}
|
|
70
70
|
default: {
|
|
71
71
|
// Node-side capability surface (zk / HE / signature / seal): a real primitive run to a
|
|
72
|
-
// verdict in this process. Unknown types still fall through to an
|
|
72
|
+
// verdict in this process. Unknown types still fall through to an genuine error.
|
|
73
73
|
const cap = CAPABILITIES[message && message.type];
|
|
74
74
|
if (cap) return cap(message || {});
|
|
75
75
|
return { error: `Unknown message type: ${message && message.type}` };
|
package/src/devnet-rpc.test.mjs
CHANGED
|
@@ -54,7 +54,7 @@ try {
|
|
|
54
54
|
|
|
55
55
|
// ── node-side capability surface: each a REAL primitive verified + negative-controlled ──
|
|
56
56
|
const zk = await call({ type: 'zkProof', derivedX: 99 });
|
|
57
|
-
ok('zkProof verifies the
|
|
57
|
+
ok('zkProof verifies the genuine coordinate and rejects the tampered one', zk.ok === true && zk.genuineVerifies === true && zk.tamperedRejected === true, JSON.stringify(zk));
|
|
58
58
|
|
|
59
59
|
const he1 = await call({ type: 'heAdd', a: 1, b: 0 });
|
|
60
60
|
ok('heAdd: ENC(1) ⊞ ENC(0) decrypts to 1 (blind add)', he1.ok === true && he1.sum === 1, JSON.stringify(he1));
|
package/src/simulator.js
CHANGED
|
@@ -613,7 +613,7 @@ export class SystemSimulator extends EventEmitter {
|
|
|
613
613
|
// Compute operations can trigger state changes. This used to call a fake
|
|
614
614
|
// xvsm.executeTransaction with a comment string as "WASM"; that path is gone (real
|
|
615
615
|
// contract execution is @xmbl/contracts' ContractHost over @xmbl/storage-compute). The
|
|
616
|
-
// simulator's
|
|
616
|
+
// simulator's genuine job here is just to drive a state change, so it uses the real
|
|
617
617
|
// state-diff path directly.
|
|
618
618
|
if (this.modules.xvsm && chance.bool({ likelihood: 70 })) {
|
|
619
619
|
setTimeout(() => {
|