@cello-protocol/crypto 0.0.22 → 0.0.24
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/dist/ae-peer-auth.d.ts +66 -0
- package/dist/ae-peer-auth.d.ts.map +1 -0
- package/dist/ae-peer-auth.js +96 -0
- package/dist/ae-peer-auth.js.map +1 -0
- package/dist/hex.d.ts +14 -0
- package/dist/hex.d.ts.map +1 -0
- package/dist/hex.js +22 -0
- package/dist/hex.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest-test-fixture.d.ts +4 -0
- package/dist/manifest-test-fixture.d.ts.map +1 -1
- package/dist/manifest-test-fixture.js.map +1 -1
- package/dist/manifest.d.ts +4 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +33 -18
- package/dist/manifest.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M12 DOD-AE-APPEND-1 — directory↔directory anti-entropy peer-auth TBS.
|
|
3
|
+
*
|
|
4
|
+
* The mutual, manifest-pinned handshake for the `/cello/anti-entropy/1.0.0` channel
|
|
5
|
+
* (M12-ANTI-ENTROPY-DESIGN §1c). Each directory proves possession of its manifest-pinned NODE key
|
|
6
|
+
* (the key the officer-signed consortium manifest binds to its nodeId) over a TBS that binds:
|
|
7
|
+
* - both nodeIds (who is talking to whom),
|
|
8
|
+
* - both libp2p PeerIds (channel binding — ties the manifest identity to the actual Noise
|
|
9
|
+
* connection, closing the gap the client step-6 handshake leaves open),
|
|
10
|
+
* - both nonces (replay defense in EACH direction),
|
|
11
|
+
* - a timestamp (freshness, defense-in-depth).
|
|
12
|
+
*
|
|
13
|
+
* Roles A/B are fixed by who dialed (A = dialer), so the TBS is asymmetric and a signature from
|
|
14
|
+
* one side cannot be reflected as the other's. A brand-new domain is used — reusing any existing
|
|
15
|
+
* domain string would let a signature minted for another purpose verify here.
|
|
16
|
+
*
|
|
17
|
+
* SHARED builder: signer (each directory) and verifier (its peer) both call this, so neither can
|
|
18
|
+
* diverge. Newline-joined UTF-8 text TBS, matching the directory step-5 challenge style. The
|
|
19
|
+
* builder VALIDATES every field (no embedded newline; nonces are 32-byte hex; A≠B) so the
|
|
20
|
+
* newline-join is injective by construction — two different param sets can never produce the same
|
|
21
|
+
* TBS bytes, closing the cross-context signature-reuse footgun. `verifyAePeerAuth` treats an
|
|
22
|
+
* invalid param set as a failed verification (fail closed), never a throw.
|
|
23
|
+
*
|
|
24
|
+
* Channel obligations this primitive CANNOT enforce (the `/cello/anti-entropy/1.0.0` handler MUST):
|
|
25
|
+
* - each side mints its own nonce from a CSPRNG;
|
|
26
|
+
* - a single-use nonce store rejects any replayed nonce;
|
|
27
|
+
* - a bounded timestamp-window check;
|
|
28
|
+
* - **peerIdA/peerIdB MUST be taken from the LOCAL Noise-authenticated connection, never from a
|
|
29
|
+
* wire claim** — this is the load-bearing channel-binding assumption; without it the binding is
|
|
30
|
+
* forgeable.
|
|
31
|
+
*
|
|
32
|
+
* Reference: RFC 8032 (Ed25519).
|
|
33
|
+
*/
|
|
34
|
+
/** Dedicated domain — MUST NOT collide with any other TBS domain in the system. */
|
|
35
|
+
export declare const AE_PEER_AUTH_DOMAIN = "cello-ae-peer-auth-v1";
|
|
36
|
+
export interface AePeerAuthParams {
|
|
37
|
+
/** Dialer nodeId. */
|
|
38
|
+
nodeIdA: string;
|
|
39
|
+
/** Responder nodeId. */
|
|
40
|
+
nodeIdB: string;
|
|
41
|
+
/** Dialer libp2p PeerId (from the Noise-authenticated connection). */
|
|
42
|
+
peerIdA: string;
|
|
43
|
+
/** Responder libp2p PeerId. */
|
|
44
|
+
peerIdB: string;
|
|
45
|
+
/** Dialer-minted 32-byte nonce, hex. */
|
|
46
|
+
nonceAHex: string;
|
|
47
|
+
/** Responder-minted 32-byte nonce, hex. */
|
|
48
|
+
nonceBHex: string;
|
|
49
|
+
/** ISO-8601 timestamp. */
|
|
50
|
+
timestamp: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build the canonical TBS bytes for the AE peer-auth handshake. Both sides compute the identical
|
|
54
|
+
* bytes from the same params (roles fixed by who dialed); each signs it with its own node key.
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildAePeerAuthTbs(p: AePeerAuthParams): Uint8Array;
|
|
57
|
+
/**
|
|
58
|
+
* Verify a peer's AE handshake signature against the pubkey the manifest pins for that peer's
|
|
59
|
+
* nodeId. Never throws — a malformed pubkey or signature returns false.
|
|
60
|
+
*
|
|
61
|
+
* @param peerPubkeyHex 64-char hex Ed25519 public key from the consortium manifest for the peer
|
|
62
|
+
* @param params the handshake params (must be byte-identical on both sides)
|
|
63
|
+
* @param signature the peer's 64-byte Ed25519 signature over buildAePeerAuthTbs(params)
|
|
64
|
+
*/
|
|
65
|
+
export declare function verifyAePeerAuth(peerPubkeyHex: string, params: AePeerAuthParams, signature: Uint8Array): boolean;
|
|
66
|
+
//# sourceMappingURL=ae-peer-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ae-peer-auth.d.ts","sourceRoot":"","sources":["../src/ae-peer-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,gBAAgB,GAAG,UAAU,CA6BlE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAYhH"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M12 DOD-AE-APPEND-1 — directory↔directory anti-entropy peer-auth TBS.
|
|
3
|
+
*
|
|
4
|
+
* The mutual, manifest-pinned handshake for the `/cello/anti-entropy/1.0.0` channel
|
|
5
|
+
* (M12-ANTI-ENTROPY-DESIGN §1c). Each directory proves possession of its manifest-pinned NODE key
|
|
6
|
+
* (the key the officer-signed consortium manifest binds to its nodeId) over a TBS that binds:
|
|
7
|
+
* - both nodeIds (who is talking to whom),
|
|
8
|
+
* - both libp2p PeerIds (channel binding — ties the manifest identity to the actual Noise
|
|
9
|
+
* connection, closing the gap the client step-6 handshake leaves open),
|
|
10
|
+
* - both nonces (replay defense in EACH direction),
|
|
11
|
+
* - a timestamp (freshness, defense-in-depth).
|
|
12
|
+
*
|
|
13
|
+
* Roles A/B are fixed by who dialed (A = dialer), so the TBS is asymmetric and a signature from
|
|
14
|
+
* one side cannot be reflected as the other's. A brand-new domain is used — reusing any existing
|
|
15
|
+
* domain string would let a signature minted for another purpose verify here.
|
|
16
|
+
*
|
|
17
|
+
* SHARED builder: signer (each directory) and verifier (its peer) both call this, so neither can
|
|
18
|
+
* diverge. Newline-joined UTF-8 text TBS, matching the directory step-5 challenge style. The
|
|
19
|
+
* builder VALIDATES every field (no embedded newline; nonces are 32-byte hex; A≠B) so the
|
|
20
|
+
* newline-join is injective by construction — two different param sets can never produce the same
|
|
21
|
+
* TBS bytes, closing the cross-context signature-reuse footgun. `verifyAePeerAuth` treats an
|
|
22
|
+
* invalid param set as a failed verification (fail closed), never a throw.
|
|
23
|
+
*
|
|
24
|
+
* Channel obligations this primitive CANNOT enforce (the `/cello/anti-entropy/1.0.0` handler MUST):
|
|
25
|
+
* - each side mints its own nonce from a CSPRNG;
|
|
26
|
+
* - a single-use nonce store rejects any replayed nonce;
|
|
27
|
+
* - a bounded timestamp-window check;
|
|
28
|
+
* - **peerIdA/peerIdB MUST be taken from the LOCAL Noise-authenticated connection, never from a
|
|
29
|
+
* wire claim** — this is the load-bearing channel-binding assumption; without it the binding is
|
|
30
|
+
* forgeable.
|
|
31
|
+
*
|
|
32
|
+
* Reference: RFC 8032 (Ed25519).
|
|
33
|
+
*/
|
|
34
|
+
import { verify as ed25519Verify } from "./ed25519.js";
|
|
35
|
+
import { hexToBytes } from "./hex.js";
|
|
36
|
+
/** Dedicated domain — MUST NOT collide with any other TBS domain in the system. */
|
|
37
|
+
export const AE_PEER_AUTH_DOMAIN = "cello-ae-peer-auth-v1";
|
|
38
|
+
/**
|
|
39
|
+
* Build the canonical TBS bytes for the AE peer-auth handshake. Both sides compute the identical
|
|
40
|
+
* bytes from the same params (roles fixed by who dialed); each signs it with its own node key.
|
|
41
|
+
*/
|
|
42
|
+
export function buildAePeerAuthTbs(p) {
|
|
43
|
+
// Injectivity: the fields are newline-joined, so a newline INSIDE a field would let two distinct
|
|
44
|
+
// param sets produce identical TBS bytes (cross-context signature reuse). Reject embedded
|
|
45
|
+
// newlines and pin the nonce format so the encoding is injective by construction. Build-time
|
|
46
|
+
// inputs are this node's own → throwing is correct (verifyAePeerAuth catches it → false).
|
|
47
|
+
const isHex64 = (s) => /^[0-9a-fA-F]{64}$/.test(s);
|
|
48
|
+
for (const f of [p.nodeIdA, p.nodeIdB, p.peerIdA, p.peerIdB, p.timestamp]) {
|
|
49
|
+
if (f.includes("\n"))
|
|
50
|
+
throw new Error("ae-peer-auth: field contains a newline");
|
|
51
|
+
}
|
|
52
|
+
if (!isHex64(p.nonceAHex) || !isHex64(p.nonceBHex)) {
|
|
53
|
+
throw new Error("ae-peer-auth: nonce must be 32-byte hex");
|
|
54
|
+
}
|
|
55
|
+
// A==B collapses the "mutual" handshake — both sides sign identical bytes verified against the
|
|
56
|
+
// same key, so ONE signature satisfies both directions (a single node completes it alone,
|
|
57
|
+
// violating the sovereign invariant). Distinct identities are required.
|
|
58
|
+
if (p.nodeIdA === p.nodeIdB || p.peerIdA === p.peerIdB) {
|
|
59
|
+
throw new Error("ae-peer-auth: A and B must be distinct nodes");
|
|
60
|
+
}
|
|
61
|
+
const tbs = [
|
|
62
|
+
AE_PEER_AUTH_DOMAIN,
|
|
63
|
+
p.nodeIdA,
|
|
64
|
+
p.nodeIdB,
|
|
65
|
+
p.peerIdA,
|
|
66
|
+
p.peerIdB,
|
|
67
|
+
p.nonceAHex,
|
|
68
|
+
p.nonceBHex,
|
|
69
|
+
p.timestamp,
|
|
70
|
+
].join("\n");
|
|
71
|
+
return new TextEncoder().encode(tbs);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Verify a peer's AE handshake signature against the pubkey the manifest pins for that peer's
|
|
75
|
+
* nodeId. Never throws — a malformed pubkey or signature returns false.
|
|
76
|
+
*
|
|
77
|
+
* @param peerPubkeyHex 64-char hex Ed25519 public key from the consortium manifest for the peer
|
|
78
|
+
* @param params the handshake params (must be byte-identical on both sides)
|
|
79
|
+
* @param signature the peer's 64-byte Ed25519 signature over buildAePeerAuthTbs(params)
|
|
80
|
+
*/
|
|
81
|
+
export function verifyAePeerAuth(peerPubkeyHex, params, signature) {
|
|
82
|
+
const pub = hexToBytes(peerPubkeyHex, 32);
|
|
83
|
+
if (pub === null)
|
|
84
|
+
return false;
|
|
85
|
+
let tbs;
|
|
86
|
+
try {
|
|
87
|
+
// Fail closed: a malformed/hostile param set (embedded newline, bad nonce, A==B) makes the
|
|
88
|
+
// builder throw; that is a verification failure, never an exception out of verify.
|
|
89
|
+
tbs = buildAePeerAuthTbs(params);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return ed25519Verify(pub, tbs, signature);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=ae-peer-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ae-peer-auth.js","sourceRoot":"","sources":["../src/ae-peer-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,mFAAmF;AACnF,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAmB3D;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAmB;IACpD,iGAAiG;IACjG,0FAA0F;IAC1F,6FAA6F;IAC7F,0FAA0F;IAC1F,MAAM,OAAO,GAAG,CAAC,CAAS,EAAW,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1E,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,+FAA+F;IAC/F,0FAA0F;IAC1F,wEAAwE;IACxE,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,GAAG,GAAG;QACV,mBAAmB;QACnB,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS;KACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,aAAqB,EAAE,MAAwB,EAAE,SAAqB;IACrG,MAAM,GAAG,GAAG,UAAU,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC/B,IAAI,GAAe,CAAC;IACpB,IAAI,CAAC;QACH,2FAA2F;QAC3F,mFAAmF;QACnF,GAAG,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC"}
|
package/dist/hex.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared hex decoding for @cello-protocol/crypto. Single source so callers (manifest verification,
|
|
3
|
+
* AE peer-auth) cannot diverge on validation strictness.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Decode an exact-length lowercase-or-uppercase hex string to bytes. Returns null on ANY
|
|
7
|
+
* malformation — wrong length, or a non-hex character (e.g. `parseInt("0g", 16)` would yield a
|
|
8
|
+
* partial value, so a strict regex check precedes decoding). Never throws.
|
|
9
|
+
*
|
|
10
|
+
* @param hex the hex string
|
|
11
|
+
* @param expectedBytes required byte length (the string must be exactly 2× this)
|
|
12
|
+
*/
|
|
13
|
+
export declare function hexToBytes(hex: string, expectedBytes: number): Uint8Array | null;
|
|
14
|
+
//# sourceMappingURL=hex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hex.d.ts","sourceRoot":"","sources":["../src/hex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAOhF"}
|
package/dist/hex.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared hex decoding for @cello-protocol/crypto. Single source so callers (manifest verification,
|
|
3
|
+
* AE peer-auth) cannot diverge on validation strictness.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Decode an exact-length lowercase-or-uppercase hex string to bytes. Returns null on ANY
|
|
7
|
+
* malformation — wrong length, or a non-hex character (e.g. `parseInt("0g", 16)` would yield a
|
|
8
|
+
* partial value, so a strict regex check precedes decoding). Never throws.
|
|
9
|
+
*
|
|
10
|
+
* @param hex the hex string
|
|
11
|
+
* @param expectedBytes required byte length (the string must be exactly 2× this)
|
|
12
|
+
*/
|
|
13
|
+
export function hexToBytes(hex, expectedBytes) {
|
|
14
|
+
if (hex.length !== expectedBytes * 2 || !/^[0-9a-fA-F]+$/.test(hex))
|
|
15
|
+
return null;
|
|
16
|
+
const out = new Uint8Array(expectedBytes);
|
|
17
|
+
for (let i = 0; i < expectedBytes; i++) {
|
|
18
|
+
out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=hex.js.map
|
package/dist/hex.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../src/hex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,aAAqB;IAC3D,IAAI,GAAG,CAAC,MAAM,KAAK,aAAa,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjF,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,4 +22,6 @@ export { canonicalCapabilityBody, signCapability, verifyCapability, encodeCapabi
|
|
|
22
22
|
export { CONSORTIUM_ROOT_KEYS, CONSORTIUM_THRESHOLD, TEST_CONSORTIUM_ROOT_KEYS, TEST_CONSORTIUM_THRESHOLD, } from "./consortium-keys.js";
|
|
23
23
|
export type { TestConsortiumNode, MakeTestManifestOpts } from "./manifest-test-fixture.js";
|
|
24
24
|
export { makeTestManifest, TEST_DIRECTORY_NODE_KEYPAIR } from "./manifest-test-fixture.js";
|
|
25
|
+
export { buildAePeerAuthTbs, verifyAePeerAuth, AE_PEER_AUTH_DOMAIN } from "./ae-peer-auth.js";
|
|
26
|
+
export type { AePeerAuthParams } from "./ae-peer-auth.js";
|
|
25
27
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACpI,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3F,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,0BAA0B,EAC1B,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,6BAA6B,EAC7B,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAIzE,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,YAAY,GACb,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAK3C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG5E,OAAO,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAGtG,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAG7F,YAAY,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACpK,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEtE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACxI,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACxI,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACpI,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3F,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,0BAA0B,EAC1B,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,6BAA6B,EAC7B,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAIzE,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,YAAY,GACb,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAK3C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG5E,OAAO,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAGtG,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAG7F,YAAY,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACpK,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEtE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACxI,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACxI,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAG3F,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC9F,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -24,4 +24,6 @@ export { canonicalManifestBody, verifyManifest } from "./manifest.js";
|
|
|
24
24
|
export { canonicalCapabilityBody, signCapability, verifyCapability, encodeCapability, decodeCapability } from "./preauth-capability.js";
|
|
25
25
|
export { CONSORTIUM_ROOT_KEYS, CONSORTIUM_THRESHOLD, TEST_CONSORTIUM_ROOT_KEYS, TEST_CONSORTIUM_THRESHOLD, } from "./consortium-keys.js";
|
|
26
26
|
export { makeTestManifest, TEST_DIRECTORY_NODE_KEYPAIR } from "./manifest-test-fixture.js";
|
|
27
|
+
// M12 DOD-AE-APPEND-1: directory<->directory anti-entropy peer-auth TBS
|
|
28
|
+
export { buildAePeerAuthTbs, verifyAePeerAuth, AE_PEER_AUTH_DOMAIN } from "./ae-peer-auth.js";
|
|
27
29
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEpI,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU3F,OAAO,EACL,6BAA6B,EAC7B,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,iGAAiG;AACjG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,uGAAuG;AACvG,0FAA0F;AAC1F,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,YAAY,GACb,MAAM,4BAA4B,CAAC;AAEpC,8FAA8F;AAC9F,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAE3C,qGAAqG;AACrG,mGAAmG;AACnG,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,8EAA8E;AAC9E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,oEAAoE;AACpE,OAAO,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAEtG,+EAA+E;AAC/E,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAI7F,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGtE,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACxI,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEpI,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU3F,OAAO,EACL,6BAA6B,EAC7B,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,iGAAiG;AACjG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,uGAAuG;AACvG,0FAA0F;AAC1F,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,YAAY,GACb,MAAM,4BAA4B,CAAC;AAEpC,8FAA8F;AAC9F,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAE3C,qGAAqG;AACrG,mGAAmG;AACnG,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,8EAA8E;AAC9E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,oEAAoE;AACpE,OAAO,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAEtG,+EAA+E;AAC/E,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAI7F,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGtE,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACxI,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAE3F,wEAAwE;AACxE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -26,6 +26,10 @@ export type TestConsortiumNode = {
|
|
|
26
26
|
region: string;
|
|
27
27
|
provider: "aws" | "gcp" | "azure";
|
|
28
28
|
endpoint: string;
|
|
29
|
+
/** M12 role split — optional; absent ⇒ validator (canonical body omits absent fields). */
|
|
30
|
+
role?: "validator" | "replica";
|
|
31
|
+
/** M12 anti-entropy dial identity — optional. */
|
|
32
|
+
peerId?: string;
|
|
29
33
|
};
|
|
30
34
|
export interface MakeTestManifestOpts {
|
|
31
35
|
version?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-test-fixture.d.ts","sourceRoot":"","sources":["../src/manifest-test-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAM3F,CAAC;AAEX,sGAAsG;AACtG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest-test-fixture.d.ts","sourceRoot":"","sources":["../src/manifest-test-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAM3F,CAAC;AAEX,sGAAsG;AACtG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,EAAE,EAC3B,IAAI,CAAC,EAAE,oBAAoB,GAC1B,uBAAuB,CAoBzB;AAID;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B;;;CAG9B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-test-fixture.js","sourceRoot":"","sources":["../src/manifest-test-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA0E;IACvG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;CACrB,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest-test-fixture.js","sourceRoot":"","sources":["../src/manifest-test-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA0E;IACvG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;CACrB,CAAC;AAqBX;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAA2B,EAC3B,IAA2B;IAE3B,MAAM,QAAQ,GAA4B;QACxC,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,CAAC;QAC3B,UAAU,EAAE,IAAI,EAAE,SAAS,IAAI,sBAAsB;QACrD,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,sBAAsB;QAChD,KAAK,EAAE,KAA2C;QAClD,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,qCAAqC;IACrC,MAAM,IAAI,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAE7C,sDAAsD;IACtD,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACzC,YAAY,EAAE,GAAG;QACjB,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;KACpF,CAAC,CAAC,CAAC;IAEJ,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,aAAa,EAAE,kEAAkE;IACjF,YAAY,EAAE,kEAAkE;CACxE,CAAC"}
|
package/dist/manifest.d.ts
CHANGED
|
@@ -86,4 +86,8 @@ export declare function canonicalManifestBody(manifest: ConsortiumManifestInput)
|
|
|
86
86
|
* This function NEVER throws. All error conditions produce a result value.
|
|
87
87
|
*/
|
|
88
88
|
export declare function verifyManifest(manifest: ConsortiumManifestInput, rootKeys: readonly string[], threshold: number): ManifestVerifyResult;
|
|
89
|
+
/**
|
|
90
|
+
* hexToBytes is shared from ./hex.js (also used by ae-peer-auth) so validation strictness cannot
|
|
91
|
+
* diverge between callers — strict regex + exact length, never throws.
|
|
92
|
+
*/
|
|
89
93
|
//# sourceMappingURL=manifest.d.ts.map
|
package/dist/manifest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC1C,UAAU,EAAE,SAAS;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,WAAW,GAAG,qBAAqB,GAAG,eAAe,GAAG,qBAAqB,CAAC;AAEvI,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,wBAAwB,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,0BAA0B,EAAE,CAAC;CAC9C;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,4BAA4B,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,yBAAyB,CAAA;CAAE,CAAC;AAIhH;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,UAAU,CAcnF;AAmBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,uBAAuB,EACjC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,SAAS,EAAE,MAAM,GAChB,oBAAoB,CAgHtB;AAID;;;GAGG"}
|
package/dist/manifest.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* Crypto reference: RFC 8032 (Ed25519).
|
|
22
22
|
*/
|
|
23
23
|
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
24
|
+
import { hexToBytes } from "./hex.js";
|
|
24
25
|
// ─── Canonical serialization ─────────────────────────────────────────────────
|
|
25
26
|
/**
|
|
26
27
|
* Produce the canonical byte representation of a manifest body for signing.
|
|
@@ -89,6 +90,36 @@ export function verifyManifest(manifest, rootKeys, threshold) {
|
|
|
89
90
|
diagnostics: { threshold, validOfficers: [], skippedEntries: [] },
|
|
90
91
|
};
|
|
91
92
|
}
|
|
93
|
+
// M12 ROLE-MANIFEST-1: close the role domain at the verification boundary. `role` is
|
|
94
|
+
// untrusted input; nothing upstream validates it. Reject any node whose role is PRESENT and
|
|
95
|
+
// is neither exactly "validator" nor exactly "replica" — otherwise a one-character tooling
|
|
96
|
+
// error (e.g. "Replica") would be counted as a validator here (`!== "replica"`) while the
|
|
97
|
+
// directory's `validatorNodes` helper (`role === "validator"`) excludes it, a cross-repo
|
|
98
|
+
// gate/arithmetic split-brain. On the validated domain the two spellings coincide.
|
|
99
|
+
for (const n of manifest.nodes) {
|
|
100
|
+
const role = n.role;
|
|
101
|
+
if (role !== undefined && role !== "validator" && role !== "replica") {
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
reason: "manifest_signature_invalid",
|
|
105
|
+
detail: `node has unknown role ${JSON.stringify(role)} (expected "validator" or "replica")`,
|
|
106
|
+
diagnostics: { threshold, validOfficers: [], skippedEntries: [] },
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// A manifest with nodes but ZERO validators (every node role="replica") is rejected loudly.
|
|
111
|
+
// Replicas hold no shares and never sign, so no ceremony could ever complete — a replica-only
|
|
112
|
+
// consortium is non-functional and is treated as tampered, exactly like the empty case.
|
|
113
|
+
// Absent `role` ⇒ validator (backward compat), so pre-M12 manifests always have ≥1 validator.
|
|
114
|
+
const validatorCount = manifest.nodes.filter((n) => n.role !== "replica").length;
|
|
115
|
+
if (validatorCount === 0) {
|
|
116
|
+
return {
|
|
117
|
+
ok: false,
|
|
118
|
+
reason: "manifest_signature_invalid",
|
|
119
|
+
detail: "manifest contains no validator nodes (all replicas)",
|
|
120
|
+
diagnostics: { threshold, validOfficers: [], skippedEntries: [] },
|
|
121
|
+
};
|
|
122
|
+
}
|
|
92
123
|
const body = canonicalManifestBody(manifest);
|
|
93
124
|
const verifiedIndices = new Set();
|
|
94
125
|
const skippedEntries = [];
|
|
@@ -148,23 +179,7 @@ export function verifyManifest(manifest, rootKeys, threshold) {
|
|
|
148
179
|
}
|
|
149
180
|
// ─── Internal helpers ────────────────────────────────────────────────────────
|
|
150
181
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* Never throws.
|
|
182
|
+
* hexToBytes is shared from ./hex.js (also used by ae-peer-auth) so validation strictness cannot
|
|
183
|
+
* diverge between callers — strict regex + exact length, never throws.
|
|
154
184
|
*/
|
|
155
|
-
function hexToBytes(hex, expectedBytes) {
|
|
156
|
-
if (hex.length !== expectedBytes * 2) {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
// Strict hex validation before parsing — parseInt("0g", 16) returns 0 (not NaN),
|
|
160
|
-
// so the NaN check alone does not catch strings with invalid non-leading characters.
|
|
161
|
-
if (!/^[0-9a-fA-F]+$/.test(hex)) {
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
const bytes = new Uint8Array(expectedBytes);
|
|
165
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
166
|
-
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
167
|
-
}
|
|
168
|
-
return bytes;
|
|
169
|
-
}
|
|
170
185
|
//# sourceMappingURL=manifest.js.map
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|