@forestrie/receipt-verify 2.1.0 → 3.0.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/dist/build-receipt-offline.js +14 -10
- package/dist/checkpoint-chain.d.ts +130 -48
- package/dist/checkpoint-chain.d.ts.map +1 -1
- package/dist/checkpoint-chain.js +212 -60
- package/dist/decode-checkpoint-consistency-proof.d.ts +47 -15
- package/dist/decode-checkpoint-consistency-proof.d.ts.map +1 -1
- package/dist/decode-checkpoint-consistency-proof.js +105 -33
- package/dist/freshen-receipt.d.ts +12 -6
- package/dist/freshen-receipt.d.ts.map +1 -1
- package/dist/freshen-receipt.js +34 -14
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/src/build-receipt-offline.ts +14 -10
- package/src/checkpoint-chain.ts +254 -79
- package/src/decode-checkpoint-consistency-proof.ts +118 -34
- package/src/freshen-receipt.ts +43 -16
- package/src/index.ts +6 -0
|
@@ -15,9 +15,13 @@ export type FreshenReceiptInput = {
|
|
|
15
15
|
* value `verify` recomputes from the entry (caller derives it). */
|
|
16
16
|
leafValue: Uint8Array;
|
|
17
17
|
/** Consistency-proof chain covering [0 or the trusted base] → the latest
|
|
18
|
-
* sealed size, in ascending contiguous order
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* sealed size, in ascending contiguous order: one entry per checkpoint,
|
|
19
|
+
* each holding the proofs that checkpoint relays (`proofs`, one or more —
|
|
20
|
+
* ADR-0066 D2). Every link's `signedTreeSize2` must equal its
|
|
21
|
+
* `treeSize2` — the size its LAST relayed proof reaches — as
|
|
22
|
+
* `checkpointConsistencyProof` requires of the checkpoint it decoded each
|
|
23
|
+
* link from. The chain's last link must end at the checkpoint's sealed
|
|
24
|
+
* size. */
|
|
21
25
|
consistencyProofs: readonly CheckpointConsistencyProof[];
|
|
22
26
|
/** Trusted base for a suffix chain — the size the caller already trusts
|
|
23
27
|
* and that size's accumulator; omit for a chain from base 0 (size 0, an
|
|
@@ -40,9 +44,11 @@ export type FreshenReceiptResult = {
|
|
|
40
44
|
sealedSize: bigint;
|
|
41
45
|
};
|
|
42
46
|
/**
|
|
43
|
-
* Freshen a stale receipt to the latest sealed state. Throws if
|
|
44
|
-
*
|
|
45
|
-
*
|
|
47
|
+
* Freshen a stale receipt to the latest sealed state. Throws if a link's
|
|
48
|
+
* signed `tree-size-2` disagrees with its declared one
|
|
49
|
+
* ({@link CheckpointSignedSizeMismatchError}), if the chain is not a
|
|
50
|
+
* contiguous cover from the trusted base to the checkpoint's sealed size, if
|
|
51
|
+
* a climb node is missing from the supplied proofs, or if the recomputed
|
|
46
52
|
* peak does not match the folded latest accumulator.
|
|
47
53
|
*/
|
|
48
54
|
export declare function freshenReceipt(input: FreshenReceiptInput): Promise<FreshenReceiptResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"freshen-receipt.d.ts","sourceRoot":"","sources":["../src/freshen-receipt.ts"],"names":[],"mappings":"AA2DA,OAAO,
|
|
1
|
+
{"version":3,"file":"freshen-receipt.d.ts","sourceRoot":"","sources":["../src/freshen-receipt.ts"],"names":[],"mappings":"AA2DA,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,uBAAuB,CAAC;AAI/B;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,iEAAiE;IACjE,eAAe,EAAE,UAAU,CAAC;IAC5B;uEACmE;IACnE,SAAS,EAAE,UAAU,CAAC;IACtB;;;;;;;eAOW;IACX,iBAAiB,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACzD;;;;;kDAK8C;IAC9C,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IAC1D;wDACoD;IACpD,qBAAqB,EAAE,UAAU,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,wEAAwE;IACxE,OAAO,EAAE,UAAU,CAAC;IACpB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AASF;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CA4L/B"}
|
package/dist/freshen-receipt.js
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
*/
|
|
48
48
|
import { calculateRoot, inclusionProofPath, mmrSizeForLeafCount, peakIndexForLeafProof, peakMMRIndexes, peaksBitmap, } from "@forestrie/merklelog";
|
|
49
49
|
import { assembleReceiptFromProof, parseCheckpoint, } from "./build-receipt-offline.js";
|
|
50
|
-
import { computeCheckpointAccumulator, } from "./checkpoint-chain.js";
|
|
50
|
+
import { CheckpointSignedSizeMismatchError, computeCheckpointAccumulator, } from "./checkpoint-chain.js";
|
|
51
51
|
import { parseReceipt } from "./parse-receipt.js";
|
|
52
52
|
import { SubtleHasher } from "./subtle-hasher.js";
|
|
53
53
|
function bytesEqual(a, b) {
|
|
@@ -59,9 +59,11 @@ function bytesEqual(a, b) {
|
|
|
59
59
|
return x === 0;
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
-
* Freshen a stale receipt to the latest sealed state. Throws if
|
|
63
|
-
*
|
|
64
|
-
*
|
|
62
|
+
* Freshen a stale receipt to the latest sealed state. Throws if a link's
|
|
63
|
+
* signed `tree-size-2` disagrees with its declared one
|
|
64
|
+
* ({@link CheckpointSignedSizeMismatchError}), if the chain is not a
|
|
65
|
+
* contiguous cover from the trusted base to the checkpoint's sealed size, if
|
|
66
|
+
* a climb node is missing from the supplied proofs, or if the recomputed
|
|
65
67
|
* peak does not match the folded latest accumulator.
|
|
66
68
|
*/
|
|
67
69
|
export async function freshenReceipt(input) {
|
|
@@ -106,12 +108,26 @@ export async function freshenReceipt(input) {
|
|
|
106
108
|
if (baseAccumulator.length !== basePeaks) {
|
|
107
109
|
throw new Error(`base accumulator has ${baseAccumulator.length} peaks; trusted base size ${baseSize} has ${basePeaks}`);
|
|
108
110
|
}
|
|
111
|
+
// Every link's SIGNED tree-size-2 must equal its declared one — the same
|
|
112
|
+
// equality `checkpointConsistencyProof` enforces when it decodes a
|
|
113
|
+
// checkpoint (ADR-0066 D1 as amended, D5.5). These links arrive already
|
|
114
|
+
// decoded, so nothing here had re-read the field the type says was pinned
|
|
115
|
+
// to the signature, and a link carrying `signedTreeSize2: 999n` beside
|
|
116
|
+
// `treeSize2: 7n` freshened (review finding I5).
|
|
117
|
+
for (let i = 0; i < links.length; i++) {
|
|
118
|
+
const link = links[i];
|
|
119
|
+
if (link.signedTreeSize2 !== link.treeSize2) {
|
|
120
|
+
throw new CheckpointSignedSizeMismatchError(`consistency proof ${i}: signed tree-size-2 (-65933) ${link.signedTreeSize2} != declared consistency-proof tree-size-2 ${link.treeSize2}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
109
123
|
// The first link must continue from that size, not from a size it names
|
|
110
124
|
// itself (ADR-0066 D5.4).
|
|
111
125
|
if (firstLink.treeSize1 !== baseSize) {
|
|
112
126
|
throw new Error(`first consistency proof declares tree-size-1 ${firstLink.treeSize1}; the trusted base size is ${baseSize}`);
|
|
113
127
|
}
|
|
114
|
-
// Contiguity: each link continues where the previous
|
|
128
|
+
// Contiguity BETWEEN checkpoints: each link continues where the previous
|
|
129
|
+
// one sealed. Contiguity WITHIN a link — between the proofs one
|
|
130
|
+
// checkpoint relays — is `computeCheckpointAccumulator`'s, below.
|
|
115
131
|
for (let i = 1; i < links.length; i++) {
|
|
116
132
|
if (links[i].treeSize1 !== links[i - 1].treeSize2) {
|
|
117
133
|
throw new Error(`consistency chain is not contiguous at link ${i}: base ${links[i].treeSize1} != previous sealed size ${links[i - 1].treeSize2}`);
|
|
@@ -122,10 +138,11 @@ export async function freshenReceipt(input) {
|
|
|
122
138
|
if (lastLink.treeSize2 !== sealedSize) {
|
|
123
139
|
throw new Error(`consistency chain ends at size ${lastLink.treeSize2} but the checkpoint sealed size ${sealedSize}`);
|
|
124
140
|
}
|
|
125
|
-
// Fold the chain to the latest accumulator (self-check target). Each
|
|
141
|
+
// Fold the chain to the latest accumulator (self-check target). Each link
|
|
126
142
|
// runs against a size the caller trusts, never one read off the link being
|
|
127
143
|
// folded: the trusted base for the first link, and the size the previous
|
|
128
|
-
// link was just folded TO for every link after it.
|
|
144
|
+
// link was just folded TO for every link after it. A link relaying several
|
|
145
|
+
// proofs folds them all, in order, and ends at its last one.
|
|
129
146
|
let accumulator = baseAccumulator;
|
|
130
147
|
let sizeFrom = baseSize;
|
|
131
148
|
for (const p of links) {
|
|
@@ -159,20 +176,23 @@ export async function freshenReceipt(input) {
|
|
|
159
176
|
for (let k = 0; k < oldPath.length; k++) {
|
|
160
177
|
store.set(fullIndices[k], oldPath[k]);
|
|
161
178
|
}
|
|
162
|
-
|
|
163
|
-
|
|
179
|
+
// Every relayed proof contributes, not just one per checkpoint: a link
|
|
180
|
+
// that relays several sealed steps (ADR-0066 D2) carries one set of paths
|
|
181
|
+
// per step, each addressed by that step's own two sizes.
|
|
182
|
+
for (const step of links.flatMap((link) => link.proofs)) {
|
|
183
|
+
// A base-0 step (treeSize1 === 0) has no from-peaks to climb — a 0→N
|
|
164
184
|
// consistency proof carries `paths: []` (the whole accumulator is its
|
|
165
185
|
// right-peaks). Skip it: it contributes no store nodes, and calling
|
|
166
186
|
// `peakMMRIndexes(-1n)` would throw (`posHeight(0)`, FOR-414). A genesis-
|
|
167
|
-
// rooted `.sth` chain always starts with such a
|
|
168
|
-
if (
|
|
187
|
+
// rooted `.sth` chain always starts with such a step.
|
|
188
|
+
if (step.treeSize1 === 0n)
|
|
169
189
|
continue;
|
|
170
|
-
const fromPeaks = peakMMRIndexes(
|
|
190
|
+
const fromPeaks = peakMMRIndexes(step.treeSize1 - 1n);
|
|
171
191
|
fromPeaks.forEach((peakIndex, j) => {
|
|
172
|
-
const climb =
|
|
192
|
+
const climb = step.paths[j];
|
|
173
193
|
if (climb === undefined)
|
|
174
194
|
return;
|
|
175
|
-
const climbIndices = inclusionProofPath(
|
|
195
|
+
const climbIndices = inclusionProofPath(step.treeSize2 - 1n, peakIndex);
|
|
176
196
|
climbIndices.forEach((ix, e) => {
|
|
177
197
|
const v = climb[e];
|
|
178
198
|
if (v !== undefined)
|
package/dist/index.d.ts
CHANGED
|
@@ -76,7 +76,10 @@ export { findGrantLeafInMassif } from "./find-grant-leaf.js";
|
|
|
76
76
|
export type { LocatedLeaf } from "./find-grant-leaf.js";
|
|
77
77
|
/** Re-exported so callers of findGrantLeafInMassif can catch it (FOR-344). */
|
|
78
78
|
export { MissingIndexError } from "@forestrie/merklelog";
|
|
79
|
-
export { accumulatorPayload, checkpointConsistencyProof, computeCheckpointAccumulator, verifyCheckpointChain, CheckpointHighSSignatureError, CheckpointSignedSizeMismatchError, type CheckpointChainLink, type CheckpointChainResult, type CheckpointConsistencyProof, } from "./checkpoint-chain.js";
|
|
79
|
+
export { accumulatorPayload, checkpointConsistencyProof, computeCheckpointAccumulator, verifyCheckpointChain, CheckpointHighSSignatureError, CheckpointProtectedHeaderAlgError, CheckpointSignedSizeMismatchError, ConsistencyChainNotContiguousError, EmptyConsistencyProofsError, type CheckpointChainLink, type CheckpointChainResult, type CheckpointConsistencyProof, } from "./checkpoint-chain.js";
|
|
80
|
+
/** One relayed consistency proof; `CheckpointConsistencyProof.proofs` holds
|
|
81
|
+
* the chain of them a checkpoint carries (ADR-0066 D2). */
|
|
82
|
+
export type { DecodedConsistencyProof } from "./decode-checkpoint-consistency-proof.js";
|
|
80
83
|
/**
|
|
81
84
|
* Univocity leaf commitment hash. Was CLI-private (forestrie-cli's own
|
|
82
85
|
* mirror, "hoist to the library when the FOR-297 multi-hop resolver lands");
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -61,7 +61,7 @@ export { grantCommitmentHashFromGrant } from "./grant-commitment.js";
|
|
|
61
61
|
export { findGrantLeafInMassif } from "./find-grant-leaf.js";
|
|
62
62
|
/** Re-exported so callers of findGrantLeafInMassif can catch it (FOR-344). */
|
|
63
63
|
export { MissingIndexError } from "@forestrie/merklelog";
|
|
64
|
-
export { accumulatorPayload, checkpointConsistencyProof, computeCheckpointAccumulator, verifyCheckpointChain, CheckpointHighSSignatureError, CheckpointSignedSizeMismatchError, } from "./checkpoint-chain.js";
|
|
64
|
+
export { accumulatorPayload, checkpointConsistencyProof, computeCheckpointAccumulator, verifyCheckpointChain, CheckpointHighSSignatureError, CheckpointProtectedHeaderAlgError, CheckpointSignedSizeMismatchError, ConsistencyChainNotContiguousError, EmptyConsistencyProofsError, } from "./checkpoint-chain.js";
|
|
65
65
|
/**
|
|
66
66
|
* Univocity leaf commitment hash. Was CLI-private (forestrie-cli's own
|
|
67
67
|
* mirror, "hoist to the library when the FOR-297 multi-hop resolver lands");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forestrie/receipt-verify",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Offline SCITT grant receipt verification (ADR-0045)",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@noble/hashes": "^1.7.1",
|
|
31
|
-
"@forestrie/
|
|
32
|
-
"@forestrie/merklelog": "0.
|
|
33
|
-
"@forestrie/
|
|
31
|
+
"@forestrie/encoding": "0.9.1",
|
|
32
|
+
"@forestrie/merklelog": "0.5.0",
|
|
33
|
+
"@forestrie/chain-rpc": "0.3.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"esbuild": "^0.24.0",
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
unwrapCoseSign1Tag,
|
|
38
38
|
type CoseSign1,
|
|
39
39
|
} from "./parse-receipt.js";
|
|
40
|
-
import {
|
|
40
|
+
import { decodeConsistencyProofsFromUnprotected } from "./decode-checkpoint-consistency-proof.js";
|
|
41
41
|
import { SubtleHasher } from "./subtle-hasher.js";
|
|
42
42
|
|
|
43
43
|
/** Not in scope for the shared cose-labels module (FOR-568 §4.1). */
|
|
@@ -265,15 +265,19 @@ function cborBytes(value: unknown): Uint8Array {
|
|
|
265
265
|
* (ADR-0066 D1 as amended, label -65933) from the PROTECTED header — not the
|
|
266
266
|
* unprotected consistency proof's declared value, which a checkpoint without
|
|
267
267
|
* a signing key could freely restate (ADR-0066's "keyless first checkpoint"
|
|
268
|
-
* case).
|
|
269
|
-
* with no proof is not sealed at all)
|
|
270
|
-
*
|
|
271
|
-
*
|
|
268
|
+
* case). At least one consistency proof must still be present (an unsigned
|
|
269
|
+
* checkpoint with no proof is not sealed at all) — one or more, since a
|
|
270
|
+
* checkpoint may relay a chain of sealed steps under one signature
|
|
271
|
+
* (ADR-0066 D2). Their declared sizes are not otherwise used here;
|
|
272
|
+
* {@link checkpointConsistencyProof} in `checkpoint-chain.ts` is the
|
|
273
|
+
* validating decode that requires the signed size and the last relayed
|
|
274
|
+
* proof's to agree.
|
|
272
275
|
*
|
|
273
|
-
* Lenient by design: an absent proof,
|
|
274
|
-
* malformed signed tree-size-2
|
|
275
|
-
*
|
|
276
|
-
*
|
|
276
|
+
* Lenient by design: an absent proof, an empty or malformed
|
|
277
|
+
* consistency-proofs array, or an absent or malformed signed tree-size-2
|
|
278
|
+
* all yield `null` rather than a throw, so a caller of
|
|
279
|
+
* {@link parseCheckpoint} sees exactly the same "not verifiable" outcome
|
|
280
|
+
* either way.
|
|
277
281
|
*/
|
|
278
282
|
function sealedSizeFromCheckpoint(
|
|
279
283
|
coseSign1: CoseSign1,
|
|
@@ -281,7 +285,7 @@ function sealedSizeFromCheckpoint(
|
|
|
281
285
|
): bigint | null {
|
|
282
286
|
let declared;
|
|
283
287
|
try {
|
|
284
|
-
declared =
|
|
288
|
+
declared = decodeConsistencyProofsFromUnprotected(unprotected);
|
|
285
289
|
} catch {
|
|
286
290
|
return null;
|
|
287
291
|
}
|