@ziffer-io/verify 0.1.1 → 0.2.1

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/chain.js ADDED
@@ -0,0 +1,430 @@
1
+ /**
2
+ * The audit chain export verifier (ACP-428) -- the TypeScript reader of the
3
+ * file the console's "Download the audit chain for this window" link gives.
4
+ *
5
+ * The link said the file was verifiable offline and nothing a customer held
6
+ * verified it. The Python SDK's `verify_chain` and this function are that
7
+ * verifier, and they are held to ONE verdict per file by the shared corpus in
8
+ * `fixtures/chain-export/` -- the same refusal name at the same record, the
9
+ * same recomputed last hash, the same report of what the anchors cover. The
10
+ * check order below is the Python reader's, step for step, because on a file
11
+ * with two defects the order decides which one is named.
12
+ *
13
+ * # What is recomputed, and what is only reported
14
+ *
15
+ * Every `chain_hash` is RECOMPUTED -- `sha256:` over the canonical bytes of the
16
+ * record (the first record of the chain) or of `{prev, record}` (every later
17
+ * one), the audit service's own link -- and the file's value is compared,
18
+ * never used. Every `previous_hash` after the first row is compared against
19
+ * the hash just recomputed. The first row's `previous_hash`, in a file that
20
+ * starts after the beginning of the chain, is the one link this file cannot
21
+ * recompute; it is reported as `startsAfter`, and it is checked only when an
22
+ * anchor names exactly that position.
23
+ *
24
+ * # The anchor key never comes from the file
25
+ *
26
+ * Every anchor entry carries an `anchor_identity` beside it. Reading the key
27
+ * from there would accept any file whose author signed their own anchors and
28
+ * wrote their own key next to them -- the party under verification supplying
29
+ * the value it is verified with. So the key is a parameter, from a file the
30
+ * customer holds, and with no key every anchor is reported `unchecked`: never
31
+ * passed, and never dropped from the report.
32
+ *
33
+ * # Numbers: the file's TEXT is read, not only its parsed values
34
+ *
35
+ * `JSON.parse` reads `1.0` as the integer 1. The record the writer hashed said
36
+ * `1.0`, so hashing `1` would compare bytes nobody wrote and name the wrong
37
+ * defect. The parser's reviver sees each number's source text (Node 22 and
38
+ * later), and a number written with a fraction or an exponent becomes a value
39
+ * the canonical encoder refuses -- `RecordNotCanonical` inside a record,
40
+ * `ExportMalformed` in the file's own fields, exactly where the Python reader
41
+ * says so. On a runtime whose parser does not hand the reviver the source
42
+ * text, that one case would be named `ChainHashMismatch` instead; the file is
43
+ * refused either way.
44
+ */
45
+ import { createHash } from 'node:crypto';
46
+ import { canon } from './canon.js';
47
+ import { ed25519IsSmallOrder } from './ed25519.js';
48
+ import { MLDSA65_PK_LEN, verifyUnderSuite } from './sig.js';
49
+ import { isRecord } from './wire.js';
50
+ /** The one suite an audit anchor is signed under here, and the only one an anchor key may name. */
51
+ export const ANCHOR_SUITE = 'hybrid-ed25519-mldsa65';
52
+ const ANCHOR_VERSION = 1;
53
+ const HASH_PATTERN = /^sha256:[0-9a-f]{64}$/;
54
+ const ED25519_PK_BYTES = 32;
55
+ /** A refusal of an export, by name, at the first record or anchor that broke. */
56
+ export class ChainRefusal extends Error {
57
+ /** The refusal name, identical to the Python reader's `ChainRefused.name`. */
58
+ refusal;
59
+ seq;
60
+ anchor;
61
+ constructor(refusal, detail, where = {}) {
62
+ super(`${refusal}: ${detail}`);
63
+ this.name = 'ChainRefusal';
64
+ this.refusal = refusal;
65
+ this.seq = where.seq ?? null;
66
+ this.anchor = where.anchor ?? null;
67
+ }
68
+ }
69
+ /** An anchor key file that cannot be used, by name. A defect in the caller's own file, not a verdict. */
70
+ export class AnchorKeyRefusal extends Error {
71
+ refusal;
72
+ constructor(refusal, detail) {
73
+ super(`${refusal}: ${detail}`);
74
+ this.name = 'AnchorKeyRefusal';
75
+ this.refusal = refusal;
76
+ }
77
+ }
78
+ // A number the source spelled with a fraction or an exponent. A symbol, so the
79
+ // canonical encoder refuses it wherever it lands and no field check mistakes it
80
+ // for an integer.
81
+ const NOT_AN_INTEGER = Symbol('a number written with a fraction or an exponent');
82
+ function reviver(_key, value, context) {
83
+ if (typeof value === 'number' && typeof context?.source === 'string' && /[.eE]/.test(context.source)) {
84
+ return NOT_AN_INTEGER;
85
+ }
86
+ return value;
87
+ }
88
+ function isInt(v) {
89
+ return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
90
+ }
91
+ // Half of a UTF-16 surrogate pair on its own: the Python reader cannot encode
92
+ // one at all, and JSON.stringify would escape it into bytes nobody wrote.
93
+ const LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
94
+ function canonicalValue(v) {
95
+ if (v === null || typeof v === 'boolean')
96
+ return true;
97
+ if (typeof v === 'number')
98
+ return Number.isSafeInteger(v);
99
+ if (typeof v === 'string')
100
+ return !LONE_SURROGATE.test(v);
101
+ if (Array.isArray(v))
102
+ return v.every(canonicalValue);
103
+ if (isRecord(v))
104
+ return Object.entries(v).every(([k, x]) => !LONE_SURROGATE.test(k) && canonicalValue(x));
105
+ return false;
106
+ }
107
+ function sha256Hex(bytes) {
108
+ return createHash('sha256').update(bytes).digest('hex');
109
+ }
110
+ /** The audit service's link: `sha256:` over the canonical bytes. */
111
+ function link(value) {
112
+ return `sha256:${sha256Hex(canon(value))}`;
113
+ }
114
+ /**
115
+ * RFC 4648 section 4 base64 with padding, in its one spelling: a value that
116
+ * does not re-encode to itself is refused, so two spellings of one signature
117
+ * are not two accepted signatures.
118
+ */
119
+ function b64Strict(value) {
120
+ if (typeof value !== 'string' || value.length === 0)
121
+ return null;
122
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value) || value.length % 4 !== 0)
123
+ return null;
124
+ const raw = Uint8Array.from(Buffer.from(value, 'base64'));
125
+ return Buffer.from(raw).toString('base64') === value ? raw : null;
126
+ }
127
+ function parseText(file) {
128
+ let text;
129
+ if (typeof file === 'string') {
130
+ text = file;
131
+ }
132
+ else {
133
+ try {
134
+ // ignoreBOM keeps a byte-order mark in the text, where JSON.parse refuses
135
+ // it -- as the Python reader's parser does.
136
+ text = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(file);
137
+ }
138
+ catch {
139
+ throw new ChainRefusal('ExportMalformed', 'the file is not UTF-8');
140
+ }
141
+ }
142
+ try {
143
+ const parsed = JSON.parse(text, reviver);
144
+ return parsed;
145
+ }
146
+ catch {
147
+ throw new ChainRefusal('ExportMalformed', 'the file is not JSON');
148
+ }
149
+ }
150
+ /**
151
+ * Read the audit anchor identity's public document -- `{alg, classical, pq,
152
+ * fingerprint}`, the halves in base64 -- checking every redundant field: the
153
+ * fingerprint is recomputed over both halves and compared, and a small-order
154
+ * Ed25519 half is refused, because under one a single signature verifies every
155
+ * message.
156
+ */
157
+ export function parseAnchorKey(file) {
158
+ let doc;
159
+ try {
160
+ doc = JSON.parse(typeof file === 'string' ? file : new TextDecoder('utf-8', { fatal: true }).decode(file));
161
+ }
162
+ catch {
163
+ throw new AnchorKeyRefusal('AnchorKeyMalformed', 'the anchor key file is not JSON');
164
+ }
165
+ if (!isRecord(doc)) {
166
+ throw new AnchorKeyRefusal('AnchorKeyMalformed', 'the anchor key document is not a JSON object');
167
+ }
168
+ if ('ed25519_pk_hex' in doc || 'identity' in doc) {
169
+ throw new AnchorKeyRefusal('AnchorKeyMalformed', 'this is a receipt trust anchor (the document `ziffer pubkey` writes), not the audit anchor identity');
170
+ }
171
+ if (doc['alg'] !== ANCHOR_SUITE) {
172
+ throw new AnchorKeyRefusal('AnchorKeyUnsupported', `audit anchors are verified under ${ANCHOR_SUITE} only`);
173
+ }
174
+ const classical = b64Strict(doc['classical']);
175
+ const pq = b64Strict(doc['pq']);
176
+ if (classical === null || classical.length !== ED25519_PK_BYTES || pq === null || pq.length !== MLDSA65_PK_LEN) {
177
+ throw new AnchorKeyRefusal('AnchorKeyMalformed', '`classical` must be 32 bytes and `pq` 1952 bytes, each in padded base64');
178
+ }
179
+ if (ed25519IsSmallOrder(classical)) {
180
+ throw new AnchorKeyRefusal('AnchorKeyMalformed', 'the Ed25519 half is a small-order point');
181
+ }
182
+ const both = new Uint8Array(classical.length + pq.length);
183
+ both.set(classical, 0);
184
+ both.set(pq, classical.length);
185
+ const fingerprint = `sha256:${sha256Hex(both)}`;
186
+ if (doc['fingerprint'] !== fingerprint) {
187
+ throw new AnchorKeyRefusal('AnchorKeyMalformed', 'the fingerprint is not the fingerprint of the document’s own keys; it was edited after it was written');
188
+ }
189
+ return { alg: ANCHOR_SUITE, classical, pq, fingerprint };
190
+ }
191
+ /**
192
+ * Both halves of the hybrid signature over the bytes the audit service signed:
193
+ * the canonical encoding of the anchor's `alg`, `heads`, `period_end` and `v`.
194
+ * Conjunctive, over exactly {classical, pq}.
195
+ */
196
+ function anchorSignatureOk(key, signed) {
197
+ const sig = signed['sig'];
198
+ if (!isRecord(sig))
199
+ return false;
200
+ const names = Object.keys(sig).sort();
201
+ if (names.length !== 2 || names[0] !== 'classical' || names[1] !== 'pq')
202
+ return false;
203
+ const classical = b64Strict(sig['classical']);
204
+ const pq = b64Strict(sig['pq']);
205
+ if (classical === null || pq === null)
206
+ return false;
207
+ const body = canon({
208
+ alg: signed['alg'],
209
+ heads: signed['heads'],
210
+ period_end: signed['period_end'],
211
+ v: signed['v'],
212
+ });
213
+ const parts = [
214
+ { primitive: 'classical', bytes: classical },
215
+ { primitive: 'pq', bytes: pq },
216
+ ];
217
+ return verifyUnderSuite(ANCHOR_SUITE, key, body, parts) === null;
218
+ }
219
+ function isHead(h) {
220
+ return (Array.isArray(h) && h.length === 3 && typeof h[0] === 'string' && isInt(h[1]) && typeof h[2] === 'string');
221
+ }
222
+ /**
223
+ * Verify an audit chain export, from the file's bytes or text.
224
+ *
225
+ * Throws {@link ChainRefusal} at the first break: `ExportMalformed`,
226
+ * `ExportEmpty`, `ChainSeqGap`, `RecordOutOfPlace`, `ChainLinkBroken`,
227
+ * `RecordNotCanonical`, `ChainHashMismatch`, `AnchorMalformed`,
228
+ * `AnchorSuiteNotEnrolled`, `AnchorSignatureInvalid`, `AnchorHeadMismatch`.
229
+ *
230
+ * NOT checked, on purpose, as in the Python reader: whether each record's
231
+ * fields are the set its kind of event carries, the transparency-log entry and
232
+ * timestamp stored beside each anchor, and whether the file holds EVERY record
233
+ * of its window -- a file cut short at the end verifies, and `unanchoredFrom`
234
+ * says how much of it nothing yet commits to.
235
+ */
236
+ export function verifyChain(file, anchorKey) {
237
+ const doc = parseText(file);
238
+ if (!isRecord(doc))
239
+ throw new ChainRefusal('ExportMalformed', 'the file is not a JSON object');
240
+ const tenant = doc['tenant'];
241
+ const chain = doc['chain'];
242
+ const anchors = doc['anchors'];
243
+ if (typeof tenant !== 'string' || !Array.isArray(chain) || !Array.isArray(anchors)) {
244
+ throw new ChainRefusal('ExportMalformed', 'the file carries no `tenant`, `chain` and `anchors`');
245
+ }
246
+ if (chain.length === 0)
247
+ throw new ChainRefusal('ExportEmpty', 'the file holds no records');
248
+ // ---- the chain: every link recomputed, in order -------------------------
249
+ const recomputed = [];
250
+ let firstSeq = 0;
251
+ let startsAfter = null;
252
+ for (let i = 0; i < chain.length; i += 1) {
253
+ const row = chain[i];
254
+ if (!isRecord(row) ||
255
+ !isInt(row['seq']) ||
256
+ typeof row['chain_hash'] !== 'string' ||
257
+ !('previous_hash' in row) ||
258
+ !(row['previous_hash'] === null || typeof row['previous_hash'] === 'string') ||
259
+ !isRecord(row['record'])) {
260
+ throw new ChainRefusal('ExportMalformed', `row ${i} is not {seq, previous_hash, chain_hash, record}`);
261
+ }
262
+ const seq = row['seq'];
263
+ const record = row['record'];
264
+ const previous = row['previous_hash'];
265
+ if (i === 0) {
266
+ firstSeq = seq;
267
+ }
268
+ else if (seq !== firstSeq + i) {
269
+ throw new ChainRefusal('ChainSeqGap', `follows record ${firstSeq + i - 1}; a chain has no gaps`, { seq });
270
+ }
271
+ const recordSeq = record['seq'];
272
+ if (record['tenant_id'] !== tenant || (seq > 0 && !(isInt(recordSeq) && recordSeq === seq))) {
273
+ throw new ChainRefusal('RecordOutOfPlace', 'the record names another tenant or another position', { seq });
274
+ }
275
+ let prev;
276
+ if (i === 0) {
277
+ if (seq === 0 && previous !== null) {
278
+ throw new ChainRefusal('ChainLinkBroken', 'the first record of a chain has no predecessor', { seq });
279
+ }
280
+ if (seq > 0) {
281
+ if (typeof previous !== 'string' || !HASH_PATTERN.test(previous)) {
282
+ throw new ChainRefusal('ChainLinkBroken', 'the file starts after the chain’s beginning and does not say which hash it continues from', { seq });
283
+ }
284
+ startsAfter = previous;
285
+ }
286
+ prev = typeof previous === 'string' ? previous : null;
287
+ }
288
+ else {
289
+ const before = recomputed[i - 1] ?? null;
290
+ if (previous !== before) {
291
+ throw new ChainRefusal('ChainLinkBroken', 'does not continue from the record before it', { seq });
292
+ }
293
+ prev = before;
294
+ }
295
+ if (!canonicalValue(record)) {
296
+ throw new ChainRefusal('RecordNotCanonical', 'the record holds a fraction or an integer too large to encode one way', { seq });
297
+ }
298
+ const hash = seq === 0 ? link(record) : link({ prev, record });
299
+ if (hash !== row['chain_hash']) {
300
+ throw new ChainRefusal('ChainHashMismatch', `the record hashes to ${hash}`, { seq });
301
+ }
302
+ recomputed.push(hash);
303
+ }
304
+ const lastSeq = firstSeq + chain.length - 1;
305
+ // ---- the anchors: each signature under YOUR key, each head against the chain
306
+ const results = [];
307
+ let anchoredThrough = null;
308
+ for (let j = 0; j < anchors.length; j += 1) {
309
+ const entry = anchors[j];
310
+ const signed = isRecord(entry) ? entry['anchor'] : undefined;
311
+ if (!isRecord(signed) ||
312
+ typeof signed['alg'] !== 'string' ||
313
+ !isInt(signed['v']) ||
314
+ signed['v'] !== ANCHOR_VERSION ||
315
+ !isInt(signed['period_end']) ||
316
+ !Array.isArray(signed['heads']) ||
317
+ !signed['heads'].every(isHead) ||
318
+ !('sig' in signed)) {
319
+ throw new ChainRefusal('AnchorMalformed', 'not {alg, heads, period_end, sig, v} with three-part heads', {
320
+ anchor: j,
321
+ });
322
+ }
323
+ const periodEnd = signed['period_end'];
324
+ const heads = signed['heads'];
325
+ const mine = heads.filter(isHead).filter((h) => h[0] === tenant);
326
+ if (mine.length > 1) {
327
+ throw new ChainRefusal('AnchorMalformed', `names this tenant ${mine.length} times`, { anchor: j });
328
+ }
329
+ let status = 'unchecked';
330
+ if (anchorKey !== undefined) {
331
+ if (signed['alg'] !== anchorKey.alg) {
332
+ throw new ChainRefusal('AnchorSuiteNotEnrolled', 'signed under a suite your anchor key is not', {
333
+ anchor: j,
334
+ });
335
+ }
336
+ if (!anchorSignatureOk(anchorKey, signed)) {
337
+ throw new ChainRefusal('AnchorSignatureInvalid', 'the anchor’s signature does not verify under your anchor key -- both halves must', { anchor: j });
338
+ }
339
+ status = 'verified';
340
+ }
341
+ let placement = 'no_head';
342
+ let headSeq = null;
343
+ const head = mine[0];
344
+ if (head !== undefined) {
345
+ const [, hSeq, hHash] = head;
346
+ headSeq = hSeq;
347
+ let expected = null;
348
+ if (firstSeq <= hSeq && hSeq <= lastSeq) {
349
+ placement = 'in_file';
350
+ expected = recomputed[hSeq - firstSeq] ?? null;
351
+ }
352
+ else if (hSeq === firstSeq - 1 && startsAfter !== null) {
353
+ placement = 'window_floor';
354
+ expected = startsAfter;
355
+ }
356
+ else {
357
+ placement = hSeq < firstSeq ? 'before_file' : 'after_file';
358
+ }
359
+ // Compared with or without a key, as in the Python reader: a file whose
360
+ // anchors disagree with its own recomputed chain is refused either way.
361
+ if (expected !== null && hHash !== expected) {
362
+ throw new ChainRefusal('AnchorHeadMismatch', `the chain recomputes to ${expected} at this position`, {
363
+ seq: hSeq,
364
+ anchor: j,
365
+ });
366
+ }
367
+ if (status === 'verified' && (placement === 'in_file' || placement === 'window_floor')) {
368
+ anchoredThrough = anchoredThrough === null ? hSeq : Math.max(anchoredThrough, hSeq);
369
+ }
370
+ }
371
+ results.push({ index: j, status, placement, headSeq, periodEnd });
372
+ }
373
+ let unanchoredFrom;
374
+ if (anchoredThrough === null)
375
+ unanchoredFrom = firstSeq;
376
+ else if (anchoredThrough < lastSeq)
377
+ unanchoredFrom = anchoredThrough + 1;
378
+ else
379
+ unanchoredFrom = null;
380
+ const lastChainHash = recomputed[recomputed.length - 1];
381
+ if (lastChainHash === undefined)
382
+ throw new ChainRefusal('ExportEmpty', 'the file holds no records');
383
+ return {
384
+ tenant,
385
+ firstSeq,
386
+ lastSeq,
387
+ records: chain.length,
388
+ lastChainHash,
389
+ startsAfter,
390
+ anchorsChecked: anchorKey !== undefined,
391
+ anchors: results,
392
+ anchoredThrough,
393
+ unanchoredFrom,
394
+ unanchoredCount: unanchoredFrom === null ? 0 : lastSeq - unanchoredFrom + 1,
395
+ };
396
+ }
397
+ /** {@link verifyChain}'s answer, or its refusal, as one corpus-shaped object. */
398
+ export function chainVerdict(file, anchorKey) {
399
+ let v;
400
+ try {
401
+ v = verifyChain(file, anchorKey);
402
+ }
403
+ catch (e) {
404
+ if (e instanceof ChainRefusal) {
405
+ return { verdict: 'refused', refusal: e.refusal, seq: e.seq, anchor: e.anchor };
406
+ }
407
+ throw e;
408
+ }
409
+ return {
410
+ verdict: 'verified',
411
+ tenant: v.tenant,
412
+ first_seq: v.firstSeq,
413
+ last_seq: v.lastSeq,
414
+ records: v.records,
415
+ last_chain_hash: v.lastChainHash,
416
+ starts_after: v.startsAfter,
417
+ anchors_checked: v.anchorsChecked,
418
+ anchors: v.anchors.map((a) => ({
419
+ index: a.index,
420
+ status: a.status,
421
+ placement: a.placement,
422
+ head_seq: a.headSeq,
423
+ period_end: a.periodEnd,
424
+ })),
425
+ anchored_through: v.anchoredThrough,
426
+ unanchored_from: v.unanchoredFrom,
427
+ unanchored_count: v.unanchoredCount,
428
+ };
429
+ }
430
+ //# sourceMappingURL=chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
package/dist/clauses.d.ts CHANGED
@@ -50,4 +50,74 @@ export declare const CLAUSE_WIRE_TYPE = "WE-4";
50
50
  * refusal carries the field's (ACP-88/ACP-89).
51
51
  */
52
52
  export declare const CLAUSE_RECEIPT_NONCE_SIZE = "L-17";
53
+ /** Rust `quorum::CLAUSE_NO_ATTESTATIONS` -- INV-1-HIGH, a receipt commits to
54
+ * attestations and none arrived. */
55
+ export declare const CLAUSE_NO_ATTESTATIONS = "INV-1-HIGH";
56
+ /** Rust `quorum::CLAUSE_NO_OBJECT` -- AT-8, an entry carrying no Attestation
57
+ * Object (the pre-v1.3.3 form, where only the id travelled). */
58
+ export declare const CLAUSE_NO_OBJECT = "AT-8";
59
+ /** Rust `quorum::CLAUSE_OBJECT_SCHEMA` -- AT-8b, the object's field set is not
60
+ * exactly AT-1's. CLOSED: an unknown field is refused, a missing one never
61
+ * defaulted (Z4). */
62
+ export declare const CLAUSE_OBJECT_SCHEMA = "AT-8b";
63
+ /** Rust `quorum::CLAUSE_NONCE_SIZE` -- AT-1, `att_nonce` is well-formed but is
64
+ * not 128-bit. The ATTESTATION nonce's own size clause, never L-17 (which sizes
65
+ * the receipt's): one number, two clauses, and the refusal carries the field's. */
66
+ export declare const CLAUSE_ATT_NONCE_SIZE = "AT-1";
67
+ /** Rust `quorum::CLAUSE_ATTESTATION_SUITE` -- CR-4. An UNKNOWN suite refuses
68
+ * here under CR-4 and not CR-1, matching `Bundle.suite_ok`, which returns False
69
+ * for a name it does not know; the receipt path spells the same condition CR-1
70
+ * and the differential compares names, so the reference wins. */
71
+ export declare const CLAUSE_ATTESTATION_SUITE = "CR-4";
72
+ /** Rust `quorum::CLAUSE_ATTESTER_SIG` -- §9.3 step 7b(i). */
73
+ export declare const CLAUSE_ATTESTER_SIG = "9.3-7b-i";
74
+ /** Rust `quorum::CLAUSE_BINDING` -- §9.3 step 7b(ii), the object binds a
75
+ * DIFFERENT proposal. This is Y1: a genuine quorum raised for P1 attached to a
76
+ * receipt for P2. */
77
+ export declare const CLAUSE_BINDING = "9.3-7b-ii";
78
+ /** Rust `quorum::CLAUSE_POLICY_BASIS` -- §9.3 step 7b(iii), policy basis or
79
+ * object freshness. */
80
+ export declare const CLAUSE_POLICY_BASIS = "9.3-7b-iii";
81
+ /** Rust `quorum::CLAUSE_OPERATOR_DISAGREE` -- §9.3 step 7b(iii-a), the objects
82
+ * disagree on who the operator is (Y4). */
83
+ export declare const CLAUSE_OPERATOR_DISAGREE = "9.3-7b-iii-a";
84
+ /** Rust `quorum::CLAUSE_CONSENT` -- AT-9's SECOND requirement: an attester
85
+ * signed for a quorum other than the bundle's. A CONSENT check, not a threshold
86
+ * one; deleting it cannot lower a quorum. */
87
+ export declare const CLAUSE_CONSENT = "AT-9";
88
+ /** Rust `quorum::CLAUSE_DERIVED_ID` -- Y1b, a transmitted `attestation_id`
89
+ * differing from the derived one. */
90
+ export declare const CLAUSE_DERIVED_ID = "Y1b";
91
+ /** Rust `quorum::CLAUSE_MEMBERSHIP` -- AB-1, the entry digest binding: entry
92
+ * schema, digest-list type, or membership. */
93
+ export declare const CLAUSE_MEMBERSHIP = "AB-1";
94
+ /** Rust `quorum::CLAUSE_DIGEST_ORDER` -- AB-2, `attestation_digests` is not in
95
+ * the one canonical ordering. */
96
+ export declare const CLAUSE_DIGEST_ORDER = "AB-2";
97
+ /** Rust `quorum::CLAUSE_DIGEST_DUP` -- AB-3, a repeated digest. */
98
+ export declare const CLAUSE_DIGEST_DUP = "AB-3";
99
+ /** Rust `quorum::CLAUSE_CARDINALITY` -- AB-4, entry count and signed digest
100
+ * count disagree. Fewer is withholding, more is injection. */
101
+ export declare const CLAUSE_CARDINALITY = "AB-4";
102
+ /** Rust `quorum::CLAUSE_ASSURANCE` -- AT-10, an identity enrolled below the
103
+ * registry's assurance floor. */
104
+ export declare const CLAUSE_ASSURANCE = "AT-10";
105
+ /** Rust `quorum::CLAUSE_QUORUM` -- AT-3, fewer distinct approvals than the
106
+ * threshold recomputed from the bundle. */
107
+ export declare const CLAUSE_QUORUM = "AT-3";
108
+ /** Rust `quorum::CLAUSE_OPERATOR_SELF` -- AT-2, the operator counted toward
109
+ * their own quorum. */
110
+ export declare const CLAUSE_OPERATOR_SELF = "AT-2";
111
+ /** Rust `quorum::CLAUSE_WEBAUTHN_ALG` -- HM-3. The object's declared `alg` and
112
+ * the registry's disagree about what KIND of key this identity holds. Either
113
+ * side alone decides nothing; the DISAGREEMENT is the refusal, raised before a
114
+ * byte of the assertion is parsed. */
115
+ export declare const CLAUSE_WEBAUTHN_ALG = "WebauthnAlgMismatch";
116
+ /** Rust `quorum::CLAUSE_WEBAUTHN_COUNTER` -- HM-4 (f). A regression is a CLONED
117
+ * AUTHENTICATOR, not a retry. */
118
+ export declare const CLAUSE_WEBAUTHN_COUNTER = "WebauthnCounter";
119
+ /** Rust `quorum::CLAUSE_MALFORMED` -- the entry's `sig`, the assertion or the
120
+ * credential is not the shape §8.6c declares. Not a statement about a
121
+ * signature. */
122
+ export declare const CLAUSE_MALFORMED = "Malformed";
53
123
  //# sourceMappingURL=clauses.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"clauses.d.ts","sourceRoot":"","sources":["../src/clauses.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sFAAsF;AACtF,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,SAAS,CAAC;AACvC,gGAAgG;AAChG,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAC3C,oGAAoG;AACpG,eAAO,MAAM,kBAAkB,SAAS,CAAC;AACzC,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,UAAU,CAAC;AACxC,oGAAoG;AACpG,eAAO,MAAM,gBAAgB,UAAU,CAAC;AACxC,4EAA4E;AAC5E,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,UAAU,CAAC;AAC/C,qGAAqG;AACrG,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,SAAS,CAAC;AAC7C,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,SAAS,CAAC;AACvC;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,SAAS,CAAC"}
1
+ {"version":3,"file":"clauses.d.ts","sourceRoot":"","sources":["../src/clauses.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sFAAsF;AACtF,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,SAAS,CAAC;AACvC,gGAAgG;AAChG,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAC3C,oGAAoG;AACpG,eAAO,MAAM,kBAAkB,SAAS,CAAC;AACzC,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,UAAU,CAAC;AACxC,oGAAoG;AACpG,eAAO,MAAM,gBAAgB,UAAU,CAAC;AACxC,4EAA4E;AAC5E,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,UAAU,CAAC;AAC/C,qGAAqG;AACrG,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,SAAS,CAAC;AAC7C,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,SAAS,CAAC;AACvC;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,SAAS,CAAC;AAUhD;oCACoC;AACpC,eAAO,MAAM,sBAAsB,eAAe,CAAC;AACnD;gEACgE;AAChE,eAAO,MAAM,gBAAgB,SAAS,CAAC;AACvC;;qBAEqB;AACrB,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAC5C;;mFAEmF;AACnF,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAC5C;;;iEAGiE;AACjE,eAAO,MAAM,wBAAwB,SAAS,CAAC;AAC/C,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C;;qBAEqB;AACrB,eAAO,MAAM,cAAc,cAAc,CAAC;AAC1C;uBACuB;AACvB,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAChD;2CAC2C;AAC3C,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AACvD;;6CAE6C;AAC7C,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC;qCACqC;AACrC,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AACvC;8CAC8C;AAC9C,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC;iCACiC;AACjC,eAAO,MAAM,mBAAmB,SAAS,CAAC;AAC1C,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC;8DAC8D;AAC9D,eAAO,MAAM,kBAAkB,SAAS,CAAC;AACzC;iCACiC;AACjC,eAAO,MAAM,gBAAgB,UAAU,CAAC;AACxC;2CAC2C;AAC3C,eAAO,MAAM,aAAa,SAAS,CAAC;AACpC;uBACuB;AACvB,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAC3C;;;sCAGsC;AACtC,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD;iCACiC;AACjC,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AACzD;;gBAEgB;AAChB,eAAO,MAAM,gBAAgB,cAAc,CAAC"}
package/dist/clauses.js CHANGED
@@ -50,4 +50,81 @@ export const CLAUSE_WIRE_TYPE = 'WE-4';
50
50
  * refusal carries the field's (ACP-88/ACP-89).
51
51
  */
52
52
  export const CLAUSE_RECEIPT_NONCE_SIZE = 'L-17';
53
+ // ------------------------------------------------------------------ step 7b
54
+ //
55
+ // The AT-* quorum and §8.6b's AB-*, spelled as `crates/acp-decision/src/quorum.rs`
56
+ // and `reference/src/acp_executor.py` spell them. Several are literals at the
57
+ // refusal site in Rust and named here; the VALUE is the contract either way, and
58
+ // the Rust constant name is kept beside each one so a reader diffing the two
59
+ // files sees one table rather than two vocabularies.
60
+ /** Rust `quorum::CLAUSE_NO_ATTESTATIONS` -- INV-1-HIGH, a receipt commits to
61
+ * attestations and none arrived. */
62
+ export const CLAUSE_NO_ATTESTATIONS = 'INV-1-HIGH';
63
+ /** Rust `quorum::CLAUSE_NO_OBJECT` -- AT-8, an entry carrying no Attestation
64
+ * Object (the pre-v1.3.3 form, where only the id travelled). */
65
+ export const CLAUSE_NO_OBJECT = 'AT-8';
66
+ /** Rust `quorum::CLAUSE_OBJECT_SCHEMA` -- AT-8b, the object's field set is not
67
+ * exactly AT-1's. CLOSED: an unknown field is refused, a missing one never
68
+ * defaulted (Z4). */
69
+ export const CLAUSE_OBJECT_SCHEMA = 'AT-8b';
70
+ /** Rust `quorum::CLAUSE_NONCE_SIZE` -- AT-1, `att_nonce` is well-formed but is
71
+ * not 128-bit. The ATTESTATION nonce's own size clause, never L-17 (which sizes
72
+ * the receipt's): one number, two clauses, and the refusal carries the field's. */
73
+ export const CLAUSE_ATT_NONCE_SIZE = 'AT-1';
74
+ /** Rust `quorum::CLAUSE_ATTESTATION_SUITE` -- CR-4. An UNKNOWN suite refuses
75
+ * here under CR-4 and not CR-1, matching `Bundle.suite_ok`, which returns False
76
+ * for a name it does not know; the receipt path spells the same condition CR-1
77
+ * and the differential compares names, so the reference wins. */
78
+ export const CLAUSE_ATTESTATION_SUITE = 'CR-4';
79
+ /** Rust `quorum::CLAUSE_ATTESTER_SIG` -- §9.3 step 7b(i). */
80
+ export const CLAUSE_ATTESTER_SIG = '9.3-7b-i';
81
+ /** Rust `quorum::CLAUSE_BINDING` -- §9.3 step 7b(ii), the object binds a
82
+ * DIFFERENT proposal. This is Y1: a genuine quorum raised for P1 attached to a
83
+ * receipt for P2. */
84
+ export const CLAUSE_BINDING = '9.3-7b-ii';
85
+ /** Rust `quorum::CLAUSE_POLICY_BASIS` -- §9.3 step 7b(iii), policy basis or
86
+ * object freshness. */
87
+ export const CLAUSE_POLICY_BASIS = '9.3-7b-iii';
88
+ /** Rust `quorum::CLAUSE_OPERATOR_DISAGREE` -- §9.3 step 7b(iii-a), the objects
89
+ * disagree on who the operator is (Y4). */
90
+ export const CLAUSE_OPERATOR_DISAGREE = '9.3-7b-iii-a';
91
+ /** Rust `quorum::CLAUSE_CONSENT` -- AT-9's SECOND requirement: an attester
92
+ * signed for a quorum other than the bundle's. A CONSENT check, not a threshold
93
+ * one; deleting it cannot lower a quorum. */
94
+ export const CLAUSE_CONSENT = 'AT-9';
95
+ /** Rust `quorum::CLAUSE_DERIVED_ID` -- Y1b, a transmitted `attestation_id`
96
+ * differing from the derived one. */
97
+ export const CLAUSE_DERIVED_ID = 'Y1b';
98
+ /** Rust `quorum::CLAUSE_MEMBERSHIP` -- AB-1, the entry digest binding: entry
99
+ * schema, digest-list type, or membership. */
100
+ export const CLAUSE_MEMBERSHIP = 'AB-1';
101
+ /** Rust `quorum::CLAUSE_DIGEST_ORDER` -- AB-2, `attestation_digests` is not in
102
+ * the one canonical ordering. */
103
+ export const CLAUSE_DIGEST_ORDER = 'AB-2';
104
+ /** Rust `quorum::CLAUSE_DIGEST_DUP` -- AB-3, a repeated digest. */
105
+ export const CLAUSE_DIGEST_DUP = 'AB-3';
106
+ /** Rust `quorum::CLAUSE_CARDINALITY` -- AB-4, entry count and signed digest
107
+ * count disagree. Fewer is withholding, more is injection. */
108
+ export const CLAUSE_CARDINALITY = 'AB-4';
109
+ /** Rust `quorum::CLAUSE_ASSURANCE` -- AT-10, an identity enrolled below the
110
+ * registry's assurance floor. */
111
+ export const CLAUSE_ASSURANCE = 'AT-10';
112
+ /** Rust `quorum::CLAUSE_QUORUM` -- AT-3, fewer distinct approvals than the
113
+ * threshold recomputed from the bundle. */
114
+ export const CLAUSE_QUORUM = 'AT-3';
115
+ /** Rust `quorum::CLAUSE_OPERATOR_SELF` -- AT-2, the operator counted toward
116
+ * their own quorum. */
117
+ export const CLAUSE_OPERATOR_SELF = 'AT-2';
118
+ /** Rust `quorum::CLAUSE_WEBAUTHN_ALG` -- HM-3. The object's declared `alg` and
119
+ * the registry's disagree about what KIND of key this identity holds. Either
120
+ * side alone decides nothing; the DISAGREEMENT is the refusal, raised before a
121
+ * byte of the assertion is parsed. */
122
+ export const CLAUSE_WEBAUTHN_ALG = 'WebauthnAlgMismatch';
123
+ /** Rust `quorum::CLAUSE_WEBAUTHN_COUNTER` -- HM-4 (f). A regression is a CLONED
124
+ * AUTHENTICATOR, not a retry. */
125
+ export const CLAUSE_WEBAUTHN_COUNTER = 'WebauthnCounter';
126
+ /** Rust `quorum::CLAUSE_MALFORMED` -- the entry's `sig`, the assertion or the
127
+ * credential is not the shape §8.6c declares. Not a statement about a
128
+ * signature. */
129
+ export const CLAUSE_MALFORMED = 'Malformed';
53
130
  //# sourceMappingURL=clauses.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"clauses.js","sourceRoot":"","sources":["../src/clauses.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC,gGAAgG;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C,oGAAoG;AACpG,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC,6FAA6F;AAC7F,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC,oGAAoG;AACpG,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AACvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAC/C,qGAAqG;AACrG,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AACvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAC7C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC"}
1
+ {"version":3,"file":"clauses.js","sourceRoot":"","sources":["../src/clauses.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC,gGAAgG;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C,oGAAoG;AACpG,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC,6FAA6F;AAC7F,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC,oGAAoG;AACpG,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AACvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAC/C,qGAAqG;AACrG,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AACvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAC7C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEhD,6EAA6E;AAC7E,EAAE;AACF,mFAAmF;AACnF,8EAA8E;AAC9E,iFAAiF;AACjF,6EAA6E;AAC7E,qDAAqD;AAErD;oCACoC;AACpC,MAAM,CAAC,MAAM,sBAAsB,GAAG,YAAY,CAAC;AACnD;gEACgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC;;qBAEqB;AACrB,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAC5C;;mFAEmF;AACnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C;;;iEAGiE;AACjE,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAC/C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C;;qBAEqB;AACrB,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC;AAC1C;uBACuB;AACvB,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAChD;2CAC2C;AAC3C,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAC;AACvD;;6CAE6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC;qCACqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AACvC;8CAC8C;AAC9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC;iCACiC;AACjC,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAC1C,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC;8DAC8D;AAC9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC;iCACiC;AACjC,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC;2CAC2C;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AACpC;uBACuB;AACvB,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C;;;sCAGsC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AACzD;iCACiC;AACjC,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AACzD;;gBAEgB;AAChB,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,11 +1,18 @@
1
1
  /**
2
2
  * @ziffer-io/verify -- the third receipt-verifier implementation (ACP-197 §5).
3
3
  *
4
- * `verifyReceipt` is the API; everything else is exported so the pieces are
4
+ * `verifyReceipt` is the API for a receipt and `verifyChain` for an exported
5
+ * audit chain (ACP-428); everything else is exported so the pieces are
5
6
  * individually testable and so `@ziffer-io/client` can re-export ONE verify (the
6
7
  * client adds no verification logic of its own -- one home per rule).
7
8
  */
8
9
  export { canon, compareCodePoints, type Json } from './canon.js';
10
+ export { ANCHOR_SUITE, AnchorKeyRefusal, ChainRefusal, chainVerdict, parseAnchorKey, verifyChain, type AnchorKey, type AnchorResult, type ChainVerdict, type ChainVerified, } from './chain.js';
11
+ export { CborError, cborAsBytes, cborEncode, cborGetInt, cborGetText, cborIsMap, cborKeys, decodeCanonical, type Cbor, type CborMap, } from './cbor.js';
12
+ export { CLAUSE_ASSURANCE, CLAUSE_ATTESTATION_SUITE, CLAUSE_ATTESTER_SIG, CLAUSE_ATT_NONCE_SIZE, CLAUSE_BINDING, CLAUSE_CARDINALITY, CLAUSE_CONSENT, CLAUSE_DERIVED_ID, CLAUSE_DIGEST_DUP, CLAUSE_DIGEST_ORDER, CLAUSE_MALFORMED, CLAUSE_MEMBERSHIP, CLAUSE_NO_ATTESTATIONS, CLAUSE_NO_OBJECT, CLAUSE_OBJECT_SCHEMA, CLAUSE_OPERATOR_DISAGREE, CLAUSE_OPERATOR_SELF, CLAUSE_POLICY_BASIS, CLAUSE_QUORUM, CLAUSE_WEBAUTHN_ALG, CLAUSE_WEBAUTHN_COUNTER, } from './clauses.js';
13
+ export { AT1_FIELDS, attestationId, entryDigest, verifyQuorum, type AttesterCredential, type DecisionBasis, type HybridAttester, type QuorumOutcome, type QuorumPolicy, type WebauthnAttester, } from './quorum.js';
14
+ export { ASSERTION_FIELDS, MALFORMED, REGISTRY_KEY_WEAK, WEBAUTHN_ALGS, WEBAUTHN_AUTHENTICATOR_DATA, WEBAUTHN_CHALLENGE, WEBAUTHN_ORIGIN, WEBAUTHN_PRIMITIVE, WEBAUTHN_SIGNATURE, WEBAUTHN_TYPE, WebauthnRefusal, coseKeyParse, decodeAssertion, verifyWebauthn, webauthnChallenge, type Assertion, type CredentialKey, } from './webauthn.js';
15
+ export { b64Decode } from './wire.js';
9
16
  export { CLAUSE_BODY_SIZE, CLAUSE_CANONICAL, CLAUSE_DECISION, CLAUSE_PROPOSAL_BINDING, CLAUSE_RECEIPT_NONCE_SIZE, CLAUSE_SIGNATURE, CLAUSE_SUITE_FLOOR, CLAUSE_TEMPORAL, CLAUSE_UNKNOWN_SUITE, CLAUSE_VALIDITY_WINDOW, CLAUSE_VERSION, CLAUSE_WIRE_TYPE, } from './clauses.js';
10
17
  export { ED25519_PK_LEN, ED25519_SIG_LEN, ed25519IsSmallOrder, verifyEd25519Strict, } from './ed25519.js';
11
18
  export { parseInstant } from './instant.js';