@forestrie/receipt-verify 0.1.1 → 0.4.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/attach-transparent-statement-receipt.d.ts +4 -0
- package/dist/attach-transparent-statement-receipt.d.ts.map +1 -0
- package/dist/attach-transparent-statement-receipt.js +21 -0
- package/dist/build-receipt-offline.d.ts +78 -0
- package/dist/build-receipt-offline.d.ts.map +1 -0
- package/dist/build-receipt-offline.js +353 -0
- package/dist/decode-forestrie-grant-cose.d.ts +1 -1
- package/dist/decode-forestrie-grant-cose.d.ts.map +1 -1
- package/dist/entry-id.d.ts +13 -0
- package/dist/entry-id.d.ts.map +1 -0
- package/dist/entry-id.js +37 -0
- package/dist/grant-codec.d.ts +1 -1
- package/dist/grant-codec.d.ts.map +1 -1
- package/dist/grant-codec.js +1 -1
- package/dist/grant-commitment.d.ts +1 -1
- package/dist/grant-commitment.d.ts.map +1 -1
- package/dist/grant-commitment.js +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/parse-receipt.d.ts +4 -2
- package/dist/parse-receipt.d.ts.map +1 -1
- package/dist/parse-receipt.js +3 -3
- package/dist/verify-grant-receipt-offline.d.ts +1 -1
- package/dist/verify-grant-receipt-offline.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/attach-transparent-statement-receipt.ts +30 -0
- package/src/build-receipt-offline.ts +477 -0
- package/src/decode-forestrie-grant-cose.ts +1 -1
- package/src/entry-id.ts +46 -0
- package/src/grant-codec.ts +2 -2
- package/src/grant-commitment.ts +2 -2
- package/src/index.ts +23 -1
- package/src/parse-receipt.ts +4 -4
- package/src/verify-grant-receipt-offline.ts +1 -1
- package/dist/grant-data.d.ts +0 -7
- package/dist/grant-data.d.ts.map +0 -1
- package/dist/grant-data.js +0 -7
- package/dist/grant.d.ts +0 -12
- package/dist/grant.d.ts.map +0 -1
- package/dist/grant.js +0 -1
- package/src/grant-data.ts +0 -12
- package/src/grant.ts +0 -12
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** SCITT transparent statement unprotected receipt label (grants.md §3.2). */
|
|
2
|
+
export declare const HEADER_RECEIPT = 396;
|
|
3
|
+
export declare function attachReceiptAndIdtimestampToTransparentStatement(statementBytes: Uint8Array, receiptCborBytes: Uint8Array, idtimestampBe8: Uint8Array): Uint8Array;
|
|
4
|
+
//# sourceMappingURL=attach-transparent-statement-receipt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach-transparent-statement-receipt.d.ts","sourceRoot":"","sources":["../src/attach-transparent-statement-receipt.ts"],"names":[],"mappings":"AAWA,8EAA8E;AAC9E,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,wBAAgB,iDAAiD,CAC/D,cAAc,EAAE,UAAU,EAC1B,gBAAgB,EAAE,UAAU,EAC5B,cAAc,EAAE,UAAU,GACzB,UAAU,CAWZ"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attach resolve-receipt bytes and idtimestamp to SCITT transparent statement
|
|
3
|
+
* unprotected headers (Plan 0005). Deterministic receipt construction moved
|
|
4
|
+
* from @forestrie/canopy-e2e-kit (plan-2607-12 Phase 2, FOR-353).
|
|
5
|
+
*
|
|
6
|
+
* Golden vectors for receipt construction/verification are tracked by
|
|
7
|
+
* FOR-289.
|
|
8
|
+
*/
|
|
9
|
+
import { mergeUnprotectedIntoCoseSign1 } from "@forestrie/encoding";
|
|
10
|
+
import { HEADER_IDTIMESTAMP } from "./forest-genesis-labels.js";
|
|
11
|
+
/** SCITT transparent statement unprotected receipt label (grants.md §3.2). */
|
|
12
|
+
export const HEADER_RECEIPT = 396;
|
|
13
|
+
export function attachReceiptAndIdtimestampToTransparentStatement(statementBytes, receiptCborBytes, idtimestampBe8) {
|
|
14
|
+
if (idtimestampBe8.length !== 8) {
|
|
15
|
+
throw new Error("idtimestamp must be 8 bytes (big-endian)");
|
|
16
|
+
}
|
|
17
|
+
return mergeUnprotectedIntoCoseSign1(statementBytes, new Map([
|
|
18
|
+
[HEADER_RECEIPT, receiptCborBytes],
|
|
19
|
+
[HEADER_IDTIMESTAMP, idtimestampBe8],
|
|
20
|
+
]));
|
|
21
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-created SCITT receipts from local artifacts.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors canopy-api resolve-receipt receipt assembly, but over local massif
|
|
5
|
+
* (`.log`) and checkpoint (`.sth`) bytes instead of R2 objects. The checkpoint
|
|
6
|
+
* signature covers only the accumulator, so the inclusion path is free to
|
|
7
|
+
* rebuild client-side: read massif nodes, build the leaf→peak path, attach it
|
|
8
|
+
* at header 396 to the checkpoint's pre-signed peak receipt. The result is
|
|
9
|
+
* verify-equivalent with an API-issued receipt (FOR-334 AC: both pass
|
|
10
|
+
* verifyGrantReceiptOffline identically; byte-equality is intentionally not
|
|
11
|
+
* claimed — encoder-level variation is known-benign, see plan-2607-15 §2).
|
|
12
|
+
*
|
|
13
|
+
* `computeAccumulatorPeak` supports the chain-anchored variant: build the path
|
|
14
|
+
* at an externally attested tree size (e.g. Univocity `logState` on Base
|
|
15
|
+
* Sepolia) and compare the computed peak with the published accumulator.
|
|
16
|
+
*/
|
|
17
|
+
import { type CoseSign1 } from "./parse-receipt.js";
|
|
18
|
+
export type MassifNodeStore = {
|
|
19
|
+
/** 32-byte node at MMR index `i` (log data or ancestor peak stack). */
|
|
20
|
+
get(i: bigint): Uint8Array;
|
|
21
|
+
massifHeight: number;
|
|
22
|
+
massifIndex: bigint;
|
|
23
|
+
firstIndex: bigint;
|
|
24
|
+
/** Last MMR index with log data in this massif blob. */
|
|
25
|
+
lastIndex: bigint;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Open a v2 massif blob for MMR node reads. Nodes below `firstIndex` resolve
|
|
29
|
+
* through the ancestor peak stack; nodes above `lastIndex` are not present in
|
|
30
|
+
* this blob and throw.
|
|
31
|
+
*/
|
|
32
|
+
export declare function openMassifNodeStore(massifBytes: Uint8Array): MassifNodeStore;
|
|
33
|
+
export type ParsedCheckpoint = {
|
|
34
|
+
coseSign1: CoseSign1;
|
|
35
|
+
unprotected: Map<number, unknown>;
|
|
36
|
+
/** Pre-signed peak receipts (label -65931), or null when absent. */
|
|
37
|
+
peakReceipts: unknown[] | null;
|
|
38
|
+
/** Sealed tree size (tree-size-2 of the embedded consistency proof). */
|
|
39
|
+
mmrSize: bigint | null;
|
|
40
|
+
delegationCert: Uint8Array | null;
|
|
41
|
+
};
|
|
42
|
+
/** Parse a format-v3 checkpoint (`.sth`) COSE Sign1. */
|
|
43
|
+
export declare function parseCheckpoint(checkpointBytes: Uint8Array): ParsedCheckpoint;
|
|
44
|
+
export type BuildReceiptOfflineInput = {
|
|
45
|
+
massifBytes: Uint8Array;
|
|
46
|
+
checkpointBytes: Uint8Array;
|
|
47
|
+
mmrIndex: bigint;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Assemble a receipt for the entry at `mmrIndex` from a local massif blob and
|
|
51
|
+
* its checkpoint. Pure over bytes; no network, no signing key — the signature
|
|
52
|
+
* is the checkpoint's pre-signed peak receipt. Throws with a specific reason
|
|
53
|
+
* on any failure.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildReceiptOffline(input: BuildReceiptOfflineInput): Uint8Array;
|
|
56
|
+
export type ComputedAccumulatorPeak = {
|
|
57
|
+
/** Root computed from the massif's leaf value and rebuilt path. */
|
|
58
|
+
peak: Uint8Array;
|
|
59
|
+
/** Position of that peak in the accumulator, left to right. */
|
|
60
|
+
peakIndex: number;
|
|
61
|
+
proof: Uint8Array[];
|
|
62
|
+
leafValue: Uint8Array;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Chain-anchored variant: rebuild the inclusion path for `mmrIndex` at an
|
|
66
|
+
* externally attested tree size and compute the accumulator peak it commits
|
|
67
|
+
* to. Compare `peak` with `accumulator[peakIndex]` published by the Univocity
|
|
68
|
+
* contract (`logState`). Requires the local massif to hold nodes up to
|
|
69
|
+
* `mmrSize`.
|
|
70
|
+
*/
|
|
71
|
+
export declare function computeAccumulatorPeak(opts: {
|
|
72
|
+
massifBytes: Uint8Array;
|
|
73
|
+
mmrIndex: bigint;
|
|
74
|
+
mmrSize: bigint;
|
|
75
|
+
}): Promise<ComputedAccumulatorPeak>;
|
|
76
|
+
/** MMR indices of the peaks of the tree ending at `mmrIndex` (inclusive). */
|
|
77
|
+
export declare function peakMMRIndexes(mmrIndex: bigint): bigint[];
|
|
78
|
+
//# sourceMappingURL=build-receipt-offline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-receipt-offline.d.ts","sourceRoot":"","sources":["../src/build-receipt-offline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAW5B,MAAM,MAAM,eAAe,GAAG;IAC5B,uEAAuE;IACvE,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,UAAU,GAAG,eAAe,CA8C5E;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,oEAAoE;IACpE,YAAY,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,wEAAwE;IACxE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,EAAE,UAAU,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,eAAe,EAAE,UAAU,GAAG,gBAAgB,CAqB7E;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,EAAE,UAAU,CAAC;IACxB,eAAe,EAAE,UAAU,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,wBAAwB,GAC9B,UAAU,CA2EZ;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,mEAAmE;IACnE,IAAI,EAAE,UAAU,CAAC;IACjB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,UAAU,CAAC;CACvB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,WAAW,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAwBnC;AA2ID,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAczD"}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-created SCITT receipts from local artifacts.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors canopy-api resolve-receipt receipt assembly, but over local massif
|
|
5
|
+
* (`.log`) and checkpoint (`.sth`) bytes instead of R2 objects. The checkpoint
|
|
6
|
+
* signature covers only the accumulator, so the inclusion path is free to
|
|
7
|
+
* rebuild client-side: read massif nodes, build the leaf→peak path, attach it
|
|
8
|
+
* at header 396 to the checkpoint's pre-signed peak receipt. The result is
|
|
9
|
+
* verify-equivalent with an API-issued receipt (FOR-334 AC: both pass
|
|
10
|
+
* verifyGrantReceiptOffline identically; byte-equality is intentionally not
|
|
11
|
+
* claimed — encoder-level variation is known-benign, see plan-2607-15 §2).
|
|
12
|
+
*
|
|
13
|
+
* `computeAccumulatorPeak` supports the chain-anchored variant: build the path
|
|
14
|
+
* at an externally attested tree size (e.g. Univocity `logState` on Base
|
|
15
|
+
* Sepolia) and compare the computed peak with the published accumulator.
|
|
16
|
+
*/
|
|
17
|
+
import { decode as decodeCbor, encode as encodeCbor } from "cbor-x";
|
|
18
|
+
import { calculateRoot, Massif, peakStackEnd, } from "@forestrie/merklelog";
|
|
19
|
+
import { requireCoseSign1, toHeaderMap, unwrapCoseSign1Tag, } from "./parse-receipt.js";
|
|
20
|
+
import { SubtleHasher } from "./subtle-hasher.js";
|
|
21
|
+
const VDS_COSE_RECEIPT_PROOFS_TAG = 396;
|
|
22
|
+
const SEAL_PEAK_RECEIPTS_LABEL = -65931;
|
|
23
|
+
const DELEGATION_CERT_LABEL = 1000;
|
|
24
|
+
const VDP_CONSISTENCY_PROOF_KEY = -2;
|
|
25
|
+
const VALUE_BYTES = 32n;
|
|
26
|
+
const MAX_MMR_HEIGHT = 64n;
|
|
27
|
+
/**
|
|
28
|
+
* Open a v2 massif blob for MMR node reads. Nodes below `firstIndex` resolve
|
|
29
|
+
* through the ancestor peak stack; nodes above `lastIndex` are not present in
|
|
30
|
+
* this blob and throw.
|
|
31
|
+
*/
|
|
32
|
+
export function openMassifNodeStore(massifBytes) {
|
|
33
|
+
const massif = new Massif(massifBytes);
|
|
34
|
+
const start = massif.getStart();
|
|
35
|
+
const massifHeight = start.massifHeight;
|
|
36
|
+
if (!Number.isInteger(massifHeight) ||
|
|
37
|
+
massifHeight < 1 ||
|
|
38
|
+
massifHeight > 64) {
|
|
39
|
+
throw new Error(`massif header has invalid height ${massifHeight}`);
|
|
40
|
+
}
|
|
41
|
+
const massifIndex = BigInt(start.massifIndex);
|
|
42
|
+
const firstIndex = start.firstIndex;
|
|
43
|
+
const logStart = peakStackEnd(massifHeight);
|
|
44
|
+
const peakStackStart = logStart - MAX_MMR_HEIGHT * VALUE_BYTES;
|
|
45
|
+
const blobLen = BigInt(massifBytes.byteLength);
|
|
46
|
+
if (blobLen < logStart) {
|
|
47
|
+
throw new Error("massif blob too short for v2 layout");
|
|
48
|
+
}
|
|
49
|
+
const logNodeCount = (blobLen - logStart) / VALUE_BYTES;
|
|
50
|
+
const lastIndex = firstIndex + logNodeCount - 1n;
|
|
51
|
+
const stackMap = peakStackMapForMassif(massifHeight, firstIndex);
|
|
52
|
+
const get = (i) => {
|
|
53
|
+
if (i >= firstIndex) {
|
|
54
|
+
if (i > lastIndex) {
|
|
55
|
+
throw new Error(`mmr index ${i.toString(10)} is beyond this massif's log data ` +
|
|
56
|
+
`(last ${lastIndex.toString(10)}); local content does not cover ` +
|
|
57
|
+
`the requested tree size`);
|
|
58
|
+
}
|
|
59
|
+
const off = logStart + (i - firstIndex) * VALUE_BYTES;
|
|
60
|
+
return slice32(massifBytes, off, "log-data");
|
|
61
|
+
}
|
|
62
|
+
const peakIdx = stackMap.get(i);
|
|
63
|
+
if (peakIdx === undefined) {
|
|
64
|
+
throw new Error(`missing ancestor peak for mmr index ${i.toString(10)}`);
|
|
65
|
+
}
|
|
66
|
+
const off = peakStackStart + BigInt(peakIdx) * VALUE_BYTES;
|
|
67
|
+
return slice32(massifBytes, off, "peak-stack");
|
|
68
|
+
};
|
|
69
|
+
return { get, massifHeight, massifIndex, firstIndex, lastIndex };
|
|
70
|
+
}
|
|
71
|
+
/** Parse a format-v3 checkpoint (`.sth`) COSE Sign1. */
|
|
72
|
+
export function parseCheckpoint(checkpointBytes) {
|
|
73
|
+
const decoded = decodeCbor(checkpointBytes);
|
|
74
|
+
const coseSign1 = requireCoseSign1(unwrapCoseSign1Tag(decoded));
|
|
75
|
+
const unprotected = toHeaderMap(coseSign1[1]);
|
|
76
|
+
const peakReceiptsRaw = unprotected.get(SEAL_PEAK_RECEIPTS_LABEL);
|
|
77
|
+
const peakReceipts = Array.isArray(peakReceiptsRaw) ? peakReceiptsRaw : null;
|
|
78
|
+
const delegationCertRaw = unprotected.get(DELEGATION_CERT_LABEL);
|
|
79
|
+
const delegationCert = delegationCertRaw instanceof Uint8Array && delegationCertRaw.length > 0
|
|
80
|
+
? delegationCertRaw
|
|
81
|
+
: null;
|
|
82
|
+
return {
|
|
83
|
+
coseSign1,
|
|
84
|
+
unprotected,
|
|
85
|
+
peakReceipts,
|
|
86
|
+
mmrSize: sealedSizeFromCheckpoint(unprotected),
|
|
87
|
+
delegationCert,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Assemble a receipt for the entry at `mmrIndex` from a local massif blob and
|
|
92
|
+
* its checkpoint. Pure over bytes; no network, no signing key — the signature
|
|
93
|
+
* is the checkpoint's pre-signed peak receipt. Throws with a specific reason
|
|
94
|
+
* on any failure.
|
|
95
|
+
*/
|
|
96
|
+
export function buildReceiptOffline(input) {
|
|
97
|
+
const { mmrIndex } = input;
|
|
98
|
+
if (mmrIndex < 0n) {
|
|
99
|
+
throw new Error("mmrIndex must be non-negative");
|
|
100
|
+
}
|
|
101
|
+
const checkpoint = parseCheckpoint(input.checkpointBytes);
|
|
102
|
+
if (!checkpoint.peakReceipts) {
|
|
103
|
+
throw new Error("checkpoint carries no pre-signed peak receipts (label -65931)");
|
|
104
|
+
}
|
|
105
|
+
if (checkpoint.mmrSize === null || checkpoint.mmrSize <= 0n) {
|
|
106
|
+
throw new Error("checkpoint carries no consistency proof (cannot determine sealed size)");
|
|
107
|
+
}
|
|
108
|
+
const mmrSize = checkpoint.mmrSize;
|
|
109
|
+
const mmrLastIndex = mmrSize - 1n;
|
|
110
|
+
if (mmrIndex > mmrLastIndex) {
|
|
111
|
+
throw new Error(`checkpoint does not cover entry: mmrIndex ${mmrIndex.toString(10)} ` +
|
|
112
|
+
`>= sealed size ${mmrSize.toString(10)}`);
|
|
113
|
+
}
|
|
114
|
+
const store = openMassifNodeStore(input.massifBytes);
|
|
115
|
+
const expectedMassifIndex = massifIndexFromMMRIndex(store.massifHeight, mmrIndex);
|
|
116
|
+
if (expectedMassifIndex !== store.massifIndex) {
|
|
117
|
+
throw new Error(`entry at mmrIndex ${mmrIndex.toString(10)} lives in massif ` +
|
|
118
|
+
`${expectedMassifIndex.toString(10)}, but this blob is massif ` +
|
|
119
|
+
`${store.massifIndex.toString(10)}`);
|
|
120
|
+
}
|
|
121
|
+
const proof = inclusionProof(store.get, mmrLastIndex, mmrIndex);
|
|
122
|
+
const peakIdx = peakIndexForLeafProof(mmrSize, proof.length);
|
|
123
|
+
const receiptBytes = checkpoint.peakReceipts[peakIdx];
|
|
124
|
+
if (!(receiptBytes instanceof Uint8Array)) {
|
|
125
|
+
throw new Error(`checkpoint peak receipt slot ${peakIdx} is missing or not bstr`);
|
|
126
|
+
}
|
|
127
|
+
const receiptSign1 = requireCoseSign1(unwrapCoseSign1Tag(decodeCbor(receiptBytes)));
|
|
128
|
+
const receiptUnprotected = toHeaderMap(receiptSign1[1]);
|
|
129
|
+
if (checkpoint.delegationCert) {
|
|
130
|
+
receiptUnprotected.set(DELEGATION_CERT_LABEL, checkpoint.delegationCert);
|
|
131
|
+
}
|
|
132
|
+
const inclusionProofEntry = new Map([
|
|
133
|
+
[1, mmrIndex],
|
|
134
|
+
[2, proof],
|
|
135
|
+
]);
|
|
136
|
+
const verifiableProofs = new Map([
|
|
137
|
+
[-1, [inclusionProofEntry]],
|
|
138
|
+
]);
|
|
139
|
+
receiptUnprotected.set(VDS_COSE_RECEIPT_PROOFS_TAG, verifiableProofs);
|
|
140
|
+
// Peak receipts are signed with detached payload; emit nil so verify uses
|
|
141
|
+
// the peak derived from the inclusion proof.
|
|
142
|
+
const assembled = [
|
|
143
|
+
receiptSign1[0],
|
|
144
|
+
receiptUnprotected,
|
|
145
|
+
null,
|
|
146
|
+
receiptSign1[3],
|
|
147
|
+
];
|
|
148
|
+
return cborBytes(assembled);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Chain-anchored variant: rebuild the inclusion path for `mmrIndex` at an
|
|
152
|
+
* externally attested tree size and compute the accumulator peak it commits
|
|
153
|
+
* to. Compare `peak` with `accumulator[peakIndex]` published by the Univocity
|
|
154
|
+
* contract (`logState`). Requires the local massif to hold nodes up to
|
|
155
|
+
* `mmrSize`.
|
|
156
|
+
*/
|
|
157
|
+
export async function computeAccumulatorPeak(opts) {
|
|
158
|
+
const { mmrIndex, mmrSize } = opts;
|
|
159
|
+
if (mmrSize <= 0n || mmrIndex >= mmrSize) {
|
|
160
|
+
throw new Error(`mmrIndex ${mmrIndex.toString(10)} is not covered by tree size ` +
|
|
161
|
+
`${mmrSize.toString(10)} (entry not anchored yet?)`);
|
|
162
|
+
}
|
|
163
|
+
const store = openMassifNodeStore(opts.massifBytes);
|
|
164
|
+
const leafValue = store.get(mmrIndex);
|
|
165
|
+
const path = inclusionProof(store.get, mmrSize - 1n, mmrIndex);
|
|
166
|
+
const proof = { path, mmrIndex };
|
|
167
|
+
const peak = await calculateRoot(new SubtleHasher(), leafValue, proof, mmrIndex);
|
|
168
|
+
return {
|
|
169
|
+
peak,
|
|
170
|
+
peakIndex: peakIndexForLeafProof(mmrSize, path.length),
|
|
171
|
+
proof: path,
|
|
172
|
+
leafValue,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// --- helpers ---
|
|
176
|
+
function cborBytes(value) {
|
|
177
|
+
const encoded = encodeCbor(value);
|
|
178
|
+
return encoded instanceof Uint8Array
|
|
179
|
+
? encoded
|
|
180
|
+
: new Uint8Array(encoded);
|
|
181
|
+
}
|
|
182
|
+
function slice32(buf, offset, label) {
|
|
183
|
+
if (offset < 0n || offset + 32n > BigInt(buf.byteLength)) {
|
|
184
|
+
throw new Error(`out of range read for ${label}: off=${offset.toString(10)}`);
|
|
185
|
+
}
|
|
186
|
+
const start = Number(offset);
|
|
187
|
+
return buf.slice(start, start + 32);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Sealed mmr size from a format-v3 checkpoint: tree-size-2 of the consistency
|
|
191
|
+
* proof (`bstr .cbor [tree-size-1, tree-size-2, paths, right-peaks]`) under
|
|
192
|
+
* the verifiable-proofs unprotected header (label 396, key -2).
|
|
193
|
+
*/
|
|
194
|
+
function sealedSizeFromCheckpoint(unprotected) {
|
|
195
|
+
const vdpRaw = unprotected.get(VDS_COSE_RECEIPT_PROOFS_TAG);
|
|
196
|
+
if (vdpRaw === undefined || vdpRaw === null)
|
|
197
|
+
return null;
|
|
198
|
+
const vdp = toHeaderMap(vdpRaw);
|
|
199
|
+
const proofBstr = vdp.get(VDP_CONSISTENCY_PROOF_KEY);
|
|
200
|
+
if (!(proofBstr instanceof Uint8Array))
|
|
201
|
+
return null;
|
|
202
|
+
const proof = decodeCbor(proofBstr);
|
|
203
|
+
if (!Array.isArray(proof) || proof.length < 2)
|
|
204
|
+
return null;
|
|
205
|
+
const treeSize2 = proof[1];
|
|
206
|
+
if (typeof treeSize2 === "bigint")
|
|
207
|
+
return treeSize2;
|
|
208
|
+
if (typeof treeSize2 === "number" && Number.isSafeInteger(treeSize2)) {
|
|
209
|
+
return BigInt(treeSize2);
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
// --- MMR index math (ported from go-merklelog/mmr, mirrors resolve-receipt) ---
|
|
214
|
+
function bitLength(num) {
|
|
215
|
+
if (num === 0n)
|
|
216
|
+
return 0;
|
|
217
|
+
return num.toString(2).length;
|
|
218
|
+
}
|
|
219
|
+
function allOnes(num) {
|
|
220
|
+
return num > 0n && (num & (num + 1n)) === 0n;
|
|
221
|
+
}
|
|
222
|
+
function jumpLeftPerfect(pos) {
|
|
223
|
+
const bl = bitLength(pos);
|
|
224
|
+
if (bl === 0)
|
|
225
|
+
return pos;
|
|
226
|
+
const msb = 1n << BigInt(bl - 1);
|
|
227
|
+
return pos - (msb - 1n);
|
|
228
|
+
}
|
|
229
|
+
function posHeight(pos) {
|
|
230
|
+
let current = pos;
|
|
231
|
+
while (!allOnes(current)) {
|
|
232
|
+
current = jumpLeftPerfect(current);
|
|
233
|
+
}
|
|
234
|
+
return bitLength(current) - 1;
|
|
235
|
+
}
|
|
236
|
+
function indexHeight(i) {
|
|
237
|
+
return posHeight(i + 1n);
|
|
238
|
+
}
|
|
239
|
+
function inclusionProof(getNode, mmrLastIndex, i) {
|
|
240
|
+
if (i > mmrLastIndex) {
|
|
241
|
+
throw new Error("index out of range");
|
|
242
|
+
}
|
|
243
|
+
let g = BigInt(indexHeight(i));
|
|
244
|
+
const proof = [];
|
|
245
|
+
while (true) {
|
|
246
|
+
const siblingOffset = 2n << g;
|
|
247
|
+
let iSibling;
|
|
248
|
+
if (BigInt(indexHeight(i + 1n)) > g) {
|
|
249
|
+
iSibling = i - siblingOffset + 1n;
|
|
250
|
+
i += 1n;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
iSibling = i + siblingOffset - 1n;
|
|
254
|
+
i += siblingOffset;
|
|
255
|
+
}
|
|
256
|
+
if (iSibling > mmrLastIndex) {
|
|
257
|
+
return proof;
|
|
258
|
+
}
|
|
259
|
+
proof.push(getNode(iSibling));
|
|
260
|
+
g += 1n;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function peaksBitmap(mmrSize) {
|
|
264
|
+
if (mmrSize === 0n)
|
|
265
|
+
return 0n;
|
|
266
|
+
let pos = mmrSize;
|
|
267
|
+
let peakSize = (1n << BigInt(bitLength(mmrSize))) - 1n;
|
|
268
|
+
let peakMap = 0n;
|
|
269
|
+
while (peakSize > 0n) {
|
|
270
|
+
peakMap <<= 1n;
|
|
271
|
+
if (pos >= peakSize) {
|
|
272
|
+
pos -= peakSize;
|
|
273
|
+
peakMap |= 1n;
|
|
274
|
+
}
|
|
275
|
+
peakSize >>= 1n;
|
|
276
|
+
}
|
|
277
|
+
return peakMap;
|
|
278
|
+
}
|
|
279
|
+
function popcount64(x) {
|
|
280
|
+
let count = 0;
|
|
281
|
+
let v = x;
|
|
282
|
+
while (v > 0n) {
|
|
283
|
+
if ((v & 1n) === 1n)
|
|
284
|
+
count += 1;
|
|
285
|
+
v >>= 1n;
|
|
286
|
+
}
|
|
287
|
+
return count;
|
|
288
|
+
}
|
|
289
|
+
function peakIndexForLeafProof(mmrSize, proofLen) {
|
|
290
|
+
const leafCount = peaksBitmap(mmrSize);
|
|
291
|
+
const peaksMask = (1n << BigInt(proofLen + 1)) - 1n;
|
|
292
|
+
return popcount64(leafCount) - popcount64(leafCount & peaksMask);
|
|
293
|
+
}
|
|
294
|
+
function topPeak(i) {
|
|
295
|
+
const bl = bitLength(i + 2n);
|
|
296
|
+
return (1n << BigInt(bl - 1)) - 2n;
|
|
297
|
+
}
|
|
298
|
+
/** MMR indices of the peaks of the tree ending at `mmrIndex` (inclusive). */
|
|
299
|
+
export function peakMMRIndexes(mmrIndex) {
|
|
300
|
+
let mmrSize = mmrIndex + 1n;
|
|
301
|
+
if (posHeight(mmrSize + 1n) > posHeight(mmrSize)) {
|
|
302
|
+
return [];
|
|
303
|
+
}
|
|
304
|
+
let peak = 0n;
|
|
305
|
+
const out = [];
|
|
306
|
+
while (mmrSize !== 0n) {
|
|
307
|
+
const peakSize = topPeak(mmrSize - 1n) + 1n;
|
|
308
|
+
peak = peak + peakSize;
|
|
309
|
+
out.push(peak - 1n);
|
|
310
|
+
mmrSize -= peakSize;
|
|
311
|
+
}
|
|
312
|
+
return out;
|
|
313
|
+
}
|
|
314
|
+
function peakStackMapForMassif(massifHeight, firstIndex) {
|
|
315
|
+
const map = new Map();
|
|
316
|
+
const iPeaks = peakMMRIndexes(firstIndex);
|
|
317
|
+
for (let i = 0; i < iPeaks.length; i++) {
|
|
318
|
+
const ip = iPeaks[i];
|
|
319
|
+
if (indexHeight(ip) < massifHeight - 1) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
map.set(ip, i);
|
|
323
|
+
}
|
|
324
|
+
return map;
|
|
325
|
+
}
|
|
326
|
+
function mmrIndexFromLeafIndex(leafIndex) {
|
|
327
|
+
let sum = 0n;
|
|
328
|
+
let current = leafIndex;
|
|
329
|
+
while (current > 0n) {
|
|
330
|
+
const h = BigInt(bitLength(current));
|
|
331
|
+
sum += (1n << h) - 1n;
|
|
332
|
+
const half = 1n << (h - 1n);
|
|
333
|
+
current -= half;
|
|
334
|
+
}
|
|
335
|
+
return sum;
|
|
336
|
+
}
|
|
337
|
+
function firstMMRSize(mmrIndex) {
|
|
338
|
+
let i = mmrIndex;
|
|
339
|
+
let h0 = indexHeight(i);
|
|
340
|
+
let h1 = indexHeight(i + 1n);
|
|
341
|
+
while (h0 < h1) {
|
|
342
|
+
i += 1n;
|
|
343
|
+
h0 = h1;
|
|
344
|
+
h1 = indexHeight(i + 1n);
|
|
345
|
+
}
|
|
346
|
+
return i + 1n;
|
|
347
|
+
}
|
|
348
|
+
function massifIndexFromMMRIndex(massifHeight, mmrIndex) {
|
|
349
|
+
const size = firstMMRSize(mmrIndex);
|
|
350
|
+
const leafIndex = peaksBitmap(size) - 1n;
|
|
351
|
+
const massifMaxLeaves = 1n << BigInt(massifHeight - 1);
|
|
352
|
+
return leafIndex / massifMaxLeaves;
|
|
353
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode-forestrie-grant-cose.d.ts","sourceRoot":"","sources":["../src/decode-forestrie-grant-cose.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"decode-forestrie-grant-cose.d.ts","sourceRoot":"","sources":["../src/decode-forestrie-grant-cose.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAmCjD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG;IAC3D,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,UAAU,CAAC;CAC5B,CAmCA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode permanent SCRAPI entryId (32 hex chars = idtimestamp_be8 ||
|
|
3
|
+
* mmrIndex_be8). Deterministic receipt helpers moved from
|
|
4
|
+
* @forestrie/canopy-e2e-kit (plan-2607-12 Phase 2, FOR-353).
|
|
5
|
+
*/
|
|
6
|
+
export interface DecodedEntryId {
|
|
7
|
+
idtimestamp: bigint;
|
|
8
|
+
mmrIndex: bigint;
|
|
9
|
+
}
|
|
10
|
+
export declare function decodeEntryIdHex(entryIdHex: string): DecodedEntryId;
|
|
11
|
+
/** First half of entryId (permanent URL): idtimestamp big-endian 8 bytes for header -65537. */
|
|
12
|
+
export declare function entryIdHexToIdtimestampBe8(entryIdHex: string): Uint8Array;
|
|
13
|
+
//# sourceMappingURL=entry-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-id.d.ts","sourceRoot":"","sources":["../src/entry-id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAkBD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAUnE;AAED,+FAA+F;AAC/F,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAKzE"}
|
package/dist/entry-id.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode permanent SCRAPI entryId (32 hex chars = idtimestamp_be8 ||
|
|
3
|
+
* mmrIndex_be8). Deterministic receipt helpers moved from
|
|
4
|
+
* @forestrie/canopy-e2e-kit (plan-2607-12 Phase 2, FOR-353).
|
|
5
|
+
*/
|
|
6
|
+
function readU64BE(buf, offset) {
|
|
7
|
+
let v = 0n;
|
|
8
|
+
for (let i = 0; i < 8; i++) {
|
|
9
|
+
v = (v << 8n) | BigInt(buf[offset + i]);
|
|
10
|
+
}
|
|
11
|
+
return v;
|
|
12
|
+
}
|
|
13
|
+
function hexToBytes(hex) {
|
|
14
|
+
const out = new Uint8Array(hex.length / 2);
|
|
15
|
+
for (let i = 0; i < out.length; i++) {
|
|
16
|
+
out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
export function decodeEntryIdHex(entryIdHex) {
|
|
21
|
+
if (!/^[0-9a-f]{32}$/i.test(entryIdHex)) {
|
|
22
|
+
throw new Error(`entryId must be 32 lowercase hex chars: ${entryIdHex}`);
|
|
23
|
+
}
|
|
24
|
+
const lower = entryIdHex.toLowerCase();
|
|
25
|
+
const bytes = hexToBytes(lower);
|
|
26
|
+
return {
|
|
27
|
+
idtimestamp: readU64BE(bytes, 0),
|
|
28
|
+
mmrIndex: readU64BE(bytes, 8),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** First half of entryId (permanent URL): idtimestamp big-endian 8 bytes for header -65537. */
|
|
32
|
+
export function entryIdHexToIdtimestampBe8(entryIdHex) {
|
|
33
|
+
const { idtimestamp } = decodeEntryIdHex(entryIdHex);
|
|
34
|
+
const out = new Uint8Array(8);
|
|
35
|
+
new DataView(out.buffer).setBigUint64(0, idtimestamp, false);
|
|
36
|
+
return out;
|
|
37
|
+
}
|
package/dist/grant-codec.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant-codec.d.ts","sourceRoot":"","sources":["../src/grant-codec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"grant-codec.d.ts","sourceRoot":"","sources":["../src/grant-codec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAuDjD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,CAO3D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG;IACtD,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,UAAU,CAAC;CACzB,CAsBA;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,UAAU,CAa3D"}
|
package/dist/grant-codec.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { decode as decodeCbor, encode as encodeCbor } from "cbor-x";
|
|
2
|
-
import { grantDataToBytes } from "
|
|
2
|
+
import { grantDataToBytes } from "@forestrie/encoding";
|
|
3
3
|
import { fromPaddedWire32, toPaddedWire32 } from "./uuid-bytes.js";
|
|
4
4
|
const CBOR_KEY_IDTIMESTAMP = 0;
|
|
5
5
|
const CBOR_KEY_LOG_ID = 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant-commitment.d.ts","sourceRoot":"","sources":["../src/grant-commitment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"grant-commitment.d.ts","sourceRoot":"","sources":["../src/grant-commitment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAwDjD,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,UAAU,CAAC,CAIrB"}
|
package/dist/grant-commitment.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
export type { ReceiptVerifyResult, ReceiptVerifyStage, } from "./receipt-verify-result.js";
|
|
2
|
-
|
|
2
|
+
/** Canonical grant wire type — owned by @forestrie/encoding (FOR-353, ADR-0048). */
|
|
3
|
+
export type { Grant } from "@forestrie/encoding";
|
|
3
4
|
export type { VerifyGrantReceiptOfflineInput } from "./verify-grant-receipt-offline.js";
|
|
4
5
|
export { parseReceipt } from "./parse-receipt.js";
|
|
6
|
+
export type { BuildReceiptOfflineInput, ComputedAccumulatorPeak, MassifNodeStore, ParsedCheckpoint, } from "./build-receipt-offline.js";
|
|
7
|
+
export { buildReceiptOffline, computeAccumulatorPeak, openMassifNodeStore, parseCheckpoint, peakMMRIndexes, } from "./build-receipt-offline.js";
|
|
5
8
|
export { decodeTrustRootFromGenesis } from "./decode-trust-root-from-genesis.js";
|
|
6
9
|
export { verifyGrantReceiptOffline } from "./verify-grant-receipt-offline.js";
|
|
7
10
|
export { decodeForestrieGrantCose } from "./decode-forestrie-grant-cose.js";
|
|
8
11
|
export { decodeGrantPayload, decodeGrantResponse } from "./grant-codec.js";
|
|
12
|
+
/** Deterministic receipt construction (plan-2607-12 Phase 2, FOR-353). */
|
|
13
|
+
export { HEADER_RECEIPT, attachReceiptAndIdtimestampToTransparentStatement, } from "./attach-transparent-statement-receipt.js";
|
|
14
|
+
export { decodeEntryIdHex, entryIdHexToIdtimestampBe8 } from "./entry-id.js";
|
|
15
|
+
export type { DecodedEntryId } from "./entry-id.js";
|
|
9
16
|
//# 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,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AACpC,oFAAoF;AACpF,YAAY,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EACV,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE3E,0EAA0E;AAC1E,OAAO,EACL,cAAc,EACd,iDAAiD,GAClD,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC7E,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export { parseReceipt } from "./parse-receipt.js";
|
|
2
|
+
export { buildReceiptOffline, computeAccumulatorPeak, openMassifNodeStore, parseCheckpoint, peakMMRIndexes, } from "./build-receipt-offline.js";
|
|
2
3
|
export { decodeTrustRootFromGenesis } from "./decode-trust-root-from-genesis.js";
|
|
3
4
|
export { verifyGrantReceiptOffline } from "./verify-grant-receipt-offline.js";
|
|
4
5
|
export { decodeForestrieGrantCose } from "./decode-forestrie-grant-cose.js";
|
|
5
6
|
export { decodeGrantPayload, decodeGrantResponse } from "./grant-codec.js";
|
|
7
|
+
/** Deterministic receipt construction (plan-2607-12 Phase 2, FOR-353). */
|
|
8
|
+
export { HEADER_RECEIPT, attachReceiptAndIdtimestampToTransparentStatement, } from "./attach-transparent-statement-receipt.js";
|
|
9
|
+
export { decodeEntryIdHex, entryIdHexToIdtimestampBe8 } from "./entry-id.js";
|
package/dist/parse-receipt.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import type { Proof } from "@forestrie/merklelog";
|
|
2
|
-
type CoseSign1 = [
|
|
2
|
+
export type CoseSign1 = [
|
|
3
3
|
protectedHeader: Uint8Array,
|
|
4
4
|
unprotectedHeader: Map<number, unknown> | Record<string, unknown>,
|
|
5
5
|
payload: Uint8Array | null,
|
|
6
6
|
signature: Uint8Array
|
|
7
7
|
];
|
|
8
|
+
export declare function unwrapCoseSign1Tag(value: unknown): unknown;
|
|
9
|
+
export declare function requireCoseSign1(value: unknown): CoseSign1;
|
|
10
|
+
export declare function toHeaderMap(value: Map<number, unknown> | Record<string, unknown>): Map<number, unknown>;
|
|
8
11
|
export declare function parseReceipt(receiptBytes: Uint8Array): {
|
|
9
12
|
explicitPeak: Uint8Array | null;
|
|
10
13
|
proof: Proof;
|
|
11
14
|
receiptCbor: Uint8Array;
|
|
12
15
|
coseSign1: CoseSign1;
|
|
13
16
|
};
|
|
14
|
-
export {};
|
|
15
17
|
//# sourceMappingURL=parse-receipt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-receipt.d.ts","sourceRoot":"","sources":["../src/parse-receipt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAIlD,
|
|
1
|
+
{"version":3,"file":"parse-receipt.d.ts","sourceRoot":"","sources":["../src/parse-receipt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAIlD,MAAM,MAAM,SAAS,GAAG;IACtB,eAAe,EAAE,UAAU;IAC3B,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,OAAO,EAAE,UAAU,GAAG,IAAI;IAC1B,SAAS,EAAE,UAAU;CACtB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAW1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAiB1D;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpD,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAUtB;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,UAAU,GAAG;IACtD,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,UAAU,CAAC;IACxB,SAAS,EAAE,SAAS,CAAC;CACtB,CAwDA"}
|