@attestplane/attestplane 0.0.1 → 0.0.4-alpha

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.
Files changed (106) hide show
  1. package/README.md +23 -9
  2. package/dist/adapter_conformance.d.ts +46 -0
  3. package/dist/adapter_conformance.d.ts.map +1 -0
  4. package/dist/adapter_conformance.js +160 -0
  5. package/dist/adapter_conformance.js.map +1 -0
  6. package/dist/adapters/langfuse.d.ts +51 -0
  7. package/dist/adapters/langfuse.d.ts.map +1 -0
  8. package/dist/adapters/langfuse.js +157 -0
  9. package/dist/adapters/langfuse.js.map +1 -0
  10. package/dist/adapters/langsmith.d.ts +53 -0
  11. package/dist/adapters/langsmith.d.ts.map +1 -0
  12. package/dist/adapters/langsmith.js +173 -0
  13. package/dist/adapters/langsmith.js.map +1 -0
  14. package/dist/adapters.d.ts +88 -0
  15. package/dist/adapters.d.ts.map +1 -0
  16. package/dist/adapters.js +109 -0
  17. package/dist/adapters.js.map +1 -0
  18. package/dist/anchoring.d.ts +119 -0
  19. package/dist/anchoring.d.ts.map +1 -0
  20. package/dist/anchoring.js +340 -0
  21. package/dist/anchoring.js.map +1 -0
  22. package/dist/canonical.d.ts +11 -2
  23. package/dist/canonical.d.ts.map +1 -1
  24. package/dist/canonical.js +44 -31
  25. package/dist/canonical.js.map +1 -1
  26. package/dist/canonical_text.d.ts +30 -0
  27. package/dist/canonical_text.d.ts.map +1 -0
  28. package/dist/canonical_text.js +100 -0
  29. package/dist/canonical_text.js.map +1 -0
  30. package/dist/der.d.ts +55 -0
  31. package/dist/der.d.ts.map +1 -0
  32. package/dist/der.js +200 -0
  33. package/dist/der.js.map +1 -0
  34. package/dist/event_payloads.d.ts +118 -0
  35. package/dist/event_payloads.d.ts.map +1 -0
  36. package/dist/event_payloads.js +348 -0
  37. package/dist/event_payloads.js.map +1 -0
  38. package/dist/event_types.d.ts +47 -0
  39. package/dist/event_types.d.ts.map +1 -0
  40. package/dist/event_types.js +63 -0
  41. package/dist/event_types.js.map +1 -0
  42. package/dist/hashchain.d.ts +1 -0
  43. package/dist/hashchain.d.ts.map +1 -1
  44. package/dist/hashchain.js +25 -1
  45. package/dist/hashchain.js.map +1 -1
  46. package/dist/index.d.ts +23 -2
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +24 -2
  49. package/dist/index.js.map +1 -1
  50. package/dist/index_version.d.ts +9 -0
  51. package/dist/index_version.d.ts.map +1 -0
  52. package/dist/index_version.js +11 -0
  53. package/dist/index_version.js.map +1 -0
  54. package/dist/intoto.d.ts +48 -0
  55. package/dist/intoto.d.ts.map +1 -0
  56. package/dist/intoto.js +106 -0
  57. package/dist/intoto.js.map +1 -0
  58. package/dist/obligations.d.ts +41 -0
  59. package/dist/obligations.d.ts.map +1 -0
  60. package/dist/obligations.js +312 -0
  61. package/dist/obligations.js.map +1 -0
  62. package/dist/proof_bundle.d.ts +186 -0
  63. package/dist/proof_bundle.d.ts.map +1 -0
  64. package/dist/proof_bundle.js +299 -0
  65. package/dist/proof_bundle.js.map +1 -0
  66. package/dist/reason_codes.d.ts +38 -0
  67. package/dist/reason_codes.d.ts.map +1 -0
  68. package/dist/reason_codes.js +97 -0
  69. package/dist/reason_codes.js.map +1 -0
  70. package/dist/replay_verifier.d.ts +43 -0
  71. package/dist/replay_verifier.d.ts.map +1 -0
  72. package/dist/replay_verifier.js +98 -0
  73. package/dist/replay_verifier.js.map +1 -0
  74. package/dist/rfc3161.d.ts +52 -0
  75. package/dist/rfc3161.d.ts.map +1 -0
  76. package/dist/rfc3161.js +640 -0
  77. package/dist/rfc3161.js.map +1 -0
  78. package/dist/settlement_verifier.d.ts +34 -0
  79. package/dist/settlement_verifier.d.ts.map +1 -0
  80. package/dist/settlement_verifier.js +139 -0
  81. package/dist/settlement_verifier.js.map +1 -0
  82. package/dist/signing/base.d.ts +101 -0
  83. package/dist/signing/base.d.ts.map +1 -0
  84. package/dist/signing/base.js +144 -0
  85. package/dist/signing/base.js.map +1 -0
  86. package/dist/signing/providers.d.ts +113 -0
  87. package/dist/signing/providers.d.ts.map +1 -0
  88. package/dist/signing/providers.js +230 -0
  89. package/dist/signing/providers.js.map +1 -0
  90. package/dist/signing/signer.d.ts +66 -0
  91. package/dist/signing/signer.d.ts.map +1 -0
  92. package/dist/signing/signer.js +146 -0
  93. package/dist/signing/signer.js.map +1 -0
  94. package/dist/signing/trust_roots.d.ts +71 -0
  95. package/dist/signing/trust_roots.d.ts.map +1 -0
  96. package/dist/signing/trust_roots.js +267 -0
  97. package/dist/signing/trust_roots.js.map +1 -0
  98. package/dist/signing/verifier_ext.d.ts +77 -0
  99. package/dist/signing/verifier_ext.d.ts.map +1 -0
  100. package/dist/signing/verifier_ext.js +340 -0
  101. package/dist/signing/verifier_ext.js.map +1 -0
  102. package/dist/verifier.d.ts +39 -0
  103. package/dist/verifier.d.ts.map +1 -0
  104. package/dist/verifier.js +374 -0
  105. package/dist/verifier.js.map +1 -0
  106. package/package.json +2 -2
@@ -0,0 +1,340 @@
1
+ // SPDX-FileCopyrightText: 2026 The Attestplane Authors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * RFC-3161 anchoring (TypeScript port of `sdk/python/src/attestplane/anchoring/`).
5
+ *
6
+ * Ships the design skeleton — types, abstract base, mock provider,
7
+ * multi-TSA composite, and an anchor-aware verifier API. Real
8
+ * cryptography-backed providers (Free TSA, DigiCert) ship in a
9
+ * follow-up alongside `anchor_vectors.json` cross-language fixtures.
10
+ *
11
+ * Surface parity with the Python module: anyone reading the Python
12
+ * skeleton at `attestplane.anchoring` finds the same shapes here.
13
+ */
14
+ import { createHash } from 'node:crypto';
15
+ import { verifyChain } from './hashchain.js';
16
+ import { parseTimestampResponse, verifyTimestampToken } from './rfc3161.js';
17
+ export const ANCHOR_SCHEMA_VERSION = 1;
18
+ // ----- Error hierarchy -----
19
+ export class AnchorError extends Error {
20
+ constructor(message) {
21
+ super(message);
22
+ this.name = 'AnchorError';
23
+ }
24
+ }
25
+ export class TSAUnavailableError extends AnchorError {
26
+ constructor(message) {
27
+ super(message);
28
+ this.name = 'TSAUnavailableError';
29
+ }
30
+ }
31
+ export class AnchorVerificationError extends AnchorError {
32
+ constructor(message) {
33
+ super(message);
34
+ this.name = 'AnchorVerificationError';
35
+ }
36
+ }
37
+ export function validateAnchorRecord(a) {
38
+ if (a.anchor_schema_version !== ANCHOR_SCHEMA_VERSION) {
39
+ throw new AnchorError(`AnchorRecord.anchor_schema_version must be ${ANCHOR_SCHEMA_VERSION}, got ${a.anchor_schema_version}`);
40
+ }
41
+ if (a.anchored_event_hash.length !== 32) {
42
+ throw new AnchorError(`AnchorRecord.anchored_event_hash must be 32 bytes, got ${a.anchored_event_hash.length}`);
43
+ }
44
+ if (a.anchored_seq < 0) {
45
+ throw new AnchorError('AnchorRecord.anchored_seq must be ≥ 0');
46
+ }
47
+ if (!a.tsa_provider_id) {
48
+ throw new AnchorError('AnchorRecord.tsa_provider_id must be non-empty');
49
+ }
50
+ }
51
+ export const DEFAULT_ANCHOR_POLICY = Object.freeze({
52
+ batch_size: 64,
53
+ max_idle_seconds: 60,
54
+ per_event: false,
55
+ });
56
+ export function makeAnchorPolicy(input) {
57
+ const merged = { ...DEFAULT_ANCHOR_POLICY, ...input };
58
+ if (merged.batch_size < 1) {
59
+ throw new AnchorError('AnchorPolicy.batch_size must be ≥ 1');
60
+ }
61
+ if (merged.max_idle_seconds < 1) {
62
+ throw new AnchorError('AnchorPolicy.max_idle_seconds must be ≥ 1');
63
+ }
64
+ return Object.freeze({ ...merged });
65
+ }
66
+ export function makeTimestampRequest(input) {
67
+ if (input.digest.length !== 32) {
68
+ throw new AnchorError(`TimestampRequest.digest must be 32 bytes (SHA-256), got ${input.digest.length}`);
69
+ }
70
+ return Object.freeze({ ...input });
71
+ }
72
+ // ----- Abstract provider -----
73
+ const FORBIDDEN_PROVIDER_METHODS = new Set([
74
+ 'mutate',
75
+ 'rewrite',
76
+ 'replace',
77
+ 'revoke',
78
+ 'retract',
79
+ 'delete',
80
+ 'remove',
81
+ ]);
82
+ /**
83
+ * Abstract base for any TSA provider implementation.
84
+ *
85
+ * TypeScript analogue of Python's `TSAProvider` ABC. The
86
+ * forbidden-mutating-verb check runs in the constructor (TS has no
87
+ * `__init_subclass__` equivalent).
88
+ */
89
+ export class TSAProvider {
90
+ constructor() {
91
+ const proto = Object.getPrototypeOf(this);
92
+ const offenders = [];
93
+ for (const name of Object.getOwnPropertyNames(proto)) {
94
+ if (name === 'constructor')
95
+ continue;
96
+ if (name.startsWith('_'))
97
+ continue;
98
+ if (FORBIDDEN_PROVIDER_METHODS.has(name)) {
99
+ offenders.push(name);
100
+ }
101
+ }
102
+ if (offenders.length > 0) {
103
+ offenders.sort();
104
+ throw new AnchorError(`${this.constructor.name} defines forbidden mutating method(s) [${offenders.join(', ')}]; TSA providers do not own anchor validity. See ADR-0003 § 4.`);
105
+ }
106
+ }
107
+ }
108
+ export class MockTSAProvider extends TSAProvider {
109
+ provider_id;
110
+ schema_version = ANCHOR_SCHEMA_VERSION;
111
+ _fixed_time;
112
+ _fail_with;
113
+ constructor(input = {}) {
114
+ super();
115
+ const pid = input.provider_id ?? 'mock.tsa.local';
116
+ if (!pid) {
117
+ throw new Error('MockTSAProvider provider_id must be non-empty');
118
+ }
119
+ this.provider_id = pid;
120
+ this._fixed_time = input.fixed_time ?? null;
121
+ this._fail_with = input.fail_with ?? null;
122
+ }
123
+ requestTimestamp(request, options = {}) {
124
+ if (this._fail_with !== null) {
125
+ throw this._fail_with;
126
+ }
127
+ const when = this._fixed_time ?? options.now ?? new Date();
128
+ if (Number.isNaN(when.getTime())) {
129
+ throw new TSAUnavailableError('MockTSAProvider requires a valid Date');
130
+ }
131
+ const sha = (label) => {
132
+ const h = createHash('sha256');
133
+ h.update(label);
134
+ h.update(request.digest);
135
+ return new Uint8Array(h.digest());
136
+ };
137
+ const record = {
138
+ anchor_schema_version: ANCHOR_SCHEMA_VERSION,
139
+ anchored_seq: options.anchoredSeq ?? 0,
140
+ anchored_event_hash: request.digest,
141
+ tsa_provider_id: this.provider_id,
142
+ tsa_token: sha('mock-token:'),
143
+ tsa_cert_chain: [sha('mock-cert:')],
144
+ ocsp_responses: [sha('mock-ocsp:')],
145
+ issued_at_claimed: when,
146
+ };
147
+ validateAnchorRecord(record);
148
+ return record;
149
+ }
150
+ }
151
+ export class MultiTSAProvider {
152
+ _providers;
153
+ _tolerate_partial;
154
+ constructor(input) {
155
+ if (input.providers.length === 0) {
156
+ throw new Error('MultiTSAProvider requires at least one provider');
157
+ }
158
+ const ids = new Set();
159
+ for (const p of input.providers) {
160
+ if (ids.has(p.provider_id)) {
161
+ throw new Error('MultiTSAProvider providers must have distinct provider_id values');
162
+ }
163
+ if (p.schema_version !== ANCHOR_SCHEMA_VERSION) {
164
+ throw new Error(`provider '${p.provider_id}' has schema_version=${p.schema_version}; ` +
165
+ `this composite only handles ANCHOR_SCHEMA_VERSION=${ANCHOR_SCHEMA_VERSION}`);
166
+ }
167
+ ids.add(p.provider_id);
168
+ }
169
+ this._providers = [...input.providers];
170
+ this._tolerate_partial = input.tolerate_partial ?? false;
171
+ }
172
+ get providerIds() {
173
+ return this._providers.map((p) => p.provider_id);
174
+ }
175
+ requestTimestamps(request, options) {
176
+ const results = [];
177
+ let firstError = null;
178
+ for (const provider of this._providers) {
179
+ try {
180
+ results.push(provider.requestTimestamp(request, options));
181
+ }
182
+ catch (exc) {
183
+ if (exc instanceof TSAUnavailableError) {
184
+ if (!this._tolerate_partial)
185
+ throw exc;
186
+ if (firstError === null)
187
+ firstError = exc;
188
+ }
189
+ else {
190
+ throw exc;
191
+ }
192
+ }
193
+ }
194
+ if (this._tolerate_partial && results.length === 0 && firstError !== null) {
195
+ throw firstError;
196
+ }
197
+ return results;
198
+ }
199
+ }
200
+ function bytesEqual(a, b) {
201
+ if (a.length !== b.length)
202
+ return false;
203
+ for (let i = 0; i < a.length; i++) {
204
+ if (a[i] !== b[i])
205
+ return false;
206
+ }
207
+ return true;
208
+ }
209
+ export function verifyChainWithAnchors(events, anchors, options = {}) {
210
+ const chainResult = verifyChain(events);
211
+ const seqsInChain = new Set(events.map((e) => e.seq));
212
+ const anchorResults = [];
213
+ const anchoredSeqs = new Set();
214
+ for (const anchor of anchors) {
215
+ const provider = anchor.tsa_provider_id;
216
+ if (anchor.anchor_schema_version !== ANCHOR_SCHEMA_VERSION) {
217
+ anchorResults.push({
218
+ seq: anchor.anchored_seq,
219
+ provider,
220
+ valid: false,
221
+ cert_status: 'MISSING_LTV_ARTIFACTS',
222
+ ltv_artifacts_present: false,
223
+ reason: `anchor_schema_version=${anchor.anchor_schema_version}; this verifier handles version ${ANCHOR_SCHEMA_VERSION} only`,
224
+ });
225
+ continue;
226
+ }
227
+ if (!seqsInChain.has(anchor.anchored_seq)) {
228
+ anchorResults.push({
229
+ seq: anchor.anchored_seq,
230
+ provider,
231
+ valid: false,
232
+ cert_status: 'MISSING_LTV_ARTIFACTS',
233
+ ltv_artifacts_present: anchor.tsa_cert_chain.length > 0,
234
+ reason: `anchored_seq=${anchor.anchored_seq} not in chain`,
235
+ });
236
+ continue;
237
+ }
238
+ const target = events[anchor.anchored_seq];
239
+ if (!bytesEqual(target.event_hash, anchor.anchored_event_hash)) {
240
+ anchorResults.push({
241
+ seq: anchor.anchored_seq,
242
+ provider,
243
+ valid: false,
244
+ cert_status: 'MISSING_LTV_ARTIFACTS',
245
+ ltv_artifacts_present: anchor.tsa_cert_chain.length > 0,
246
+ reason: `anchored_event_hash mismatch at seq ${anchor.anchored_seq}`,
247
+ });
248
+ continue;
249
+ }
250
+ if (Number.isNaN(anchor.issued_at_claimed.getTime())) {
251
+ anchorResults.push({
252
+ seq: anchor.anchored_seq,
253
+ provider,
254
+ valid: false,
255
+ cert_status: 'MISSING_LTV_ARTIFACTS',
256
+ ltv_artifacts_present: anchor.tsa_cert_chain.length > 0,
257
+ reason: 'issued_at_claimed is not a valid Date',
258
+ });
259
+ continue;
260
+ }
261
+ const ltv = anchor.tsa_cert_chain.length > 0 && anchor.ocsp_responses.length > 0;
262
+ if (!ltv) {
263
+ anchorResults.push({
264
+ seq: anchor.anchored_seq,
265
+ provider,
266
+ valid: false,
267
+ cert_status: 'MISSING_LTV_ARTIFACTS',
268
+ ltv_artifacts_present: false,
269
+ reason: 'tsa_cert_chain or ocsp_responses is empty; CAdES-A long-term validation requires both',
270
+ });
271
+ continue;
272
+ }
273
+ // If trust roots are configured, do real signature verification.
274
+ if (options.trustRootsDer && options.trustRootsDer.length > 0) {
275
+ try {
276
+ const parsed = parseTimestampResponse(anchor.tsa_token);
277
+ const verifyOpts = {
278
+ expectedDigest: anchor.anchored_event_hash,
279
+ trustRootsDer: options.trustRootsDer,
280
+ intermediatesDer: [...anchor.tsa_cert_chain, ...(options.intermediatesDer ?? [])],
281
+ ...(options.verificationTime !== undefined
282
+ ? { verificationTime: options.verificationTime }
283
+ : {}),
284
+ ...(options.maxChainDepth !== undefined ? { maxChainDepth: options.maxChainDepth } : {}),
285
+ };
286
+ verifyTimestampToken(parsed, verifyOpts);
287
+ }
288
+ catch (exc) {
289
+ if (exc instanceof AnchorVerificationError) {
290
+ anchorResults.push({
291
+ seq: anchor.anchored_seq,
292
+ provider,
293
+ valid: false,
294
+ cert_status: 'MISSING_LTV_ARTIFACTS',
295
+ ltv_artifacts_present: true,
296
+ reason: exc.message,
297
+ });
298
+ continue;
299
+ }
300
+ throw exc;
301
+ }
302
+ anchorResults.push({
303
+ seq: anchor.anchored_seq,
304
+ provider,
305
+ valid: true,
306
+ cert_status: 'VALID',
307
+ ltv_artifacts_present: true,
308
+ reason: null,
309
+ });
310
+ }
311
+ else {
312
+ anchorResults.push({
313
+ seq: anchor.anchored_seq,
314
+ provider,
315
+ valid: true,
316
+ cert_status: 'VALID_UNVERIFIED',
317
+ ltv_artifacts_present: true,
318
+ reason: null,
319
+ });
320
+ }
321
+ anchoredSeqs.add(anchor.anchored_seq);
322
+ }
323
+ const unanchoredSeqs = new Set();
324
+ for (const seq of seqsInChain) {
325
+ if (!anchoredSeqs.has(seq))
326
+ unanchoredSeqs.add(seq);
327
+ }
328
+ const allAnchorsValid = anchorResults.every((a) => a.valid);
329
+ const verificationStatus = anchorResults.length === 0 ? 'not_performed' : allAnchorsValid ? 'verified' : 'failed';
330
+ return {
331
+ chain_ok: chainResult.ok,
332
+ chain_reason: chainResult.reason,
333
+ anchored_seqs: anchoredSeqs,
334
+ unanchored_seqs: unanchoredSeqs,
335
+ anchor_results: anchorResults,
336
+ verification_status: verificationStatus,
337
+ ok: chainResult.ok && verificationStatus === 'verified',
338
+ };
339
+ }
340
+ //# sourceMappingURL=anchoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchoring.js","sourceRoot":"","sources":["../src/anchoring.ts"],"names":[],"mappings":"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"}
@@ -8,14 +8,23 @@
8
8
  *
9
9
  * Restricted profile (per ADR-0002):
10
10
  * - Strings are UTF-8 and must be NFC-normalized.
11
- * - Integers (number or bigint) are limited to the signed 64-bit range.
11
+ * - Integers are JSON numbers in the JS safe-integer range and limited to the
12
+ * signed 64-bit range; bigint is rejected because JSON has no bigint type.
12
13
  * - Floats / NaN / Infinity are forbidden.
13
14
  * - Object keys are strings, emitted in code-point order, no duplicates.
14
- * - Datetimes are RFC 3339 UTC microsecond strings with a `Z` suffix.
15
+ * - Datetimes are explicit RFC 3339 UTC microsecond strings with a `Z` suffix;
16
+ * Date objects are rejected to avoid implicit millisecond truncation.
15
17
  * - Uint8Array is encoded as base64url without padding.
16
18
  */
19
+ declare const INT64_LITERAL: unique symbol;
17
20
  export declare class CanonicalizationError extends Error {
18
21
  constructor(message: string);
19
22
  }
20
23
  export declare function canonicalize(value: unknown): Uint8Array;
24
+ export interface Int64LiteralForConformance {
25
+ readonly [INT64_LITERAL]: true;
26
+ readonly source: string;
27
+ }
28
+ export declare function int64LiteralForConformance(source: string): Int64LiteralForConformance;
29
+ export {};
21
30
  //# sourceMappingURL=canonical.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAgBH,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAIvD"}
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAOH,QAAA,MAAM,aAAa,eAAsC,CAAC;AAY1D,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAIvD;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,0BAA0B,CASrF"}
package/dist/canonical.js CHANGED
@@ -10,15 +10,20 @@
10
10
  *
11
11
  * Restricted profile (per ADR-0002):
12
12
  * - Strings are UTF-8 and must be NFC-normalized.
13
- * - Integers (number or bigint) are limited to the signed 64-bit range.
13
+ * - Integers are JSON numbers in the JS safe-integer range and limited to the
14
+ * signed 64-bit range; bigint is rejected because JSON has no bigint type.
14
15
  * - Floats / NaN / Infinity are forbidden.
15
16
  * - Object keys are strings, emitted in code-point order, no duplicates.
16
- * - Datetimes are RFC 3339 UTC microsecond strings with a `Z` suffix.
17
+ * - Datetimes are explicit RFC 3339 UTC microsecond strings with a `Z` suffix;
18
+ * Date objects are rejected to avoid implicit millisecond truncation.
17
19
  * - Uint8Array is encoded as base64url without padding.
18
20
  */
19
21
  const ASCII_CONTROL_LIMIT = 0x20;
20
22
  const INT64_MIN_BIGINT = -(2n ** 63n);
21
23
  const INT64_MAX_BIGINT = 2n ** 63n - 1n;
24
+ const HIGH_SURROGATE_MIN = 0xd800;
25
+ const LOW_SURROGATE_MAX = 0xdfff;
26
+ const INT64_LITERAL = Symbol('attestplane.int64_literal');
22
27
  const ESCAPES = new Map([
23
28
  [0x08, '\\b'],
24
29
  [0x09, '\\t'],
@@ -39,8 +44,21 @@ export function canonicalize(value) {
39
44
  emit(value, out, '$');
40
45
  return new TextEncoder().encode(out.join(''));
41
46
  }
47
+ export function int64LiteralForConformance(source) {
48
+ if (!/^-?\d+$/.test(source)) {
49
+ throw new CanonicalizationError(`int64 literal source must be base-10 integer, got ${source}`);
50
+ }
51
+ const asBigint = BigInt(source);
52
+ if (asBigint < INT64_MIN_BIGINT || asBigint > INT64_MAX_BIGINT) {
53
+ throw new CanonicalizationError(`int64 literal ${source} outside signed 64-bit range`);
54
+ }
55
+ return { [INT64_LITERAL]: true, source };
56
+ }
42
57
  function emit(value, out, path) {
43
- if (value === null || value === undefined) {
58
+ if (value === undefined) {
59
+ throw new CanonicalizationError(`${path}: undefined is forbidden in canonical payloads; use null explicitly`);
60
+ }
61
+ if (value === null) {
44
62
  out.push('null');
45
63
  return;
46
64
  }
@@ -55,18 +73,19 @@ function emit(value, out, path) {
55
73
  if (!Number.isInteger(value)) {
56
74
  throw new CanonicalizationError(`${path}: float values are forbidden in canonical payloads (use integers, base64-encoded bytes, or string representations)`);
57
75
  }
58
- // JS Number safely represents integers up to 2^53 - 1. Anything outside
59
- // the signed 64-bit range would be expressed as bigint by the caller.
60
- out.push(value.toString());
61
- return;
62
- }
63
- if (typeof value === 'bigint') {
64
- if (value < INT64_MIN_BIGINT || value > INT64_MAX_BIGINT) {
76
+ if (!Number.isSafeInteger(value)) {
77
+ throw new CanonicalizationError(`${path}: unsafe integer ${value} outside JavaScript safe-integer range`);
78
+ }
79
+ const asBigint = BigInt(value);
80
+ if (asBigint < INT64_MIN_BIGINT || asBigint > INT64_MAX_BIGINT) {
65
81
  throw new CanonicalizationError(`${path}: integer ${value} outside signed 64-bit range`);
66
82
  }
67
83
  out.push(value.toString());
68
84
  return;
69
85
  }
86
+ if (typeof value === 'bigint') {
87
+ throw new CanonicalizationError(`${path}: bigint is forbidden in canonical JSON payloads`);
88
+ }
70
89
  if (typeof value === 'string') {
71
90
  emitString(value, out, path);
72
91
  return;
@@ -76,7 +95,10 @@ function emit(value, out, path) {
76
95
  return;
77
96
  }
78
97
  if (value instanceof Date) {
79
- emitDate(value, out, path);
98
+ throw new CanonicalizationError(`${path}: Date objects are forbidden; pass an explicit RFC 3339 UTC timestamp string`);
99
+ }
100
+ if (isInt64LiteralForConformance(value)) {
101
+ out.push(value.source);
80
102
  return;
81
103
  }
82
104
  if (Array.isArray(value)) {
@@ -89,6 +111,11 @@ function emit(value, out, path) {
89
111
  }
90
112
  throw new CanonicalizationError(`${path}: unsupported type ${typeof value} in canonical payload`);
91
113
  }
114
+ function isInt64LiteralForConformance(value) {
115
+ return (value !== null &&
116
+ typeof value === 'object' &&
117
+ value[INT64_LITERAL] === true);
118
+ }
92
119
  function emitString(value, out, path) {
93
120
  if (value.normalize('NFC') !== value) {
94
121
  throw new CanonicalizationError(`${path}: string is not Unicode-NFC normalized; normalize before passing to the substrate`);
@@ -98,6 +125,9 @@ function emitString(value, out, path) {
98
125
  const code = ch.codePointAt(0);
99
126
  if (code === undefined)
100
127
  continue;
128
+ if (code >= HIGH_SURROGATE_MIN && code <= LOW_SURROGATE_MAX) {
129
+ throw new CanonicalizationError(`${path}: string contains lone surrogate code point`);
130
+ }
101
131
  const mapped = ESCAPES.get(code);
102
132
  if (mapped !== undefined) {
103
133
  out.push(mapped);
@@ -111,26 +141,6 @@ function emitString(value, out, path) {
111
141
  }
112
142
  out.push('"');
113
143
  }
114
- function emitDate(value, out, path) {
115
- const ms = value.getTime();
116
- if (Number.isNaN(ms)) {
117
- throw new CanonicalizationError(`${path}: invalid Date (NaN time value)`);
118
- }
119
- // JS Date is always interpreted as UTC milliseconds since epoch, so timezone
120
- // mismatch is not possible at the API boundary. We zero-pad milliseconds out
121
- // to six digits to match Python's microsecond formatting; values supplied at
122
- // sub-millisecond precision must be encoded as strings until a typed
123
- // Timestamp type is introduced.
124
- const yyyy = value.getUTCFullYear().toString().padStart(4, '0');
125
- const mm = (value.getUTCMonth() + 1).toString().padStart(2, '0');
126
- const dd = value.getUTCDate().toString().padStart(2, '0');
127
- const hh = value.getUTCHours().toString().padStart(2, '0');
128
- const mi = value.getUTCMinutes().toString().padStart(2, '0');
129
- const ss = value.getUTCSeconds().toString().padStart(2, '0');
130
- const milli = value.getUTCMilliseconds().toString().padStart(3, '0');
131
- const iso = `${yyyy}-${mm}-${dd}T${hh}:${mi}:${ss}.${milli}000Z`;
132
- emitString(iso, out, path);
133
- }
134
144
  function emitObject(value, out, path) {
135
145
  out.push('{');
136
146
  const keys = Object.keys(value).sort();
@@ -152,6 +162,9 @@ function emitObject(value, out, path) {
152
162
  function emitArray(value, out, path) {
153
163
  out.push('[');
154
164
  for (let i = 0; i < value.length; i++) {
165
+ if (!Object.prototype.hasOwnProperty.call(value, i)) {
166
+ throw new CanonicalizationError(`${path}[${i}]: sparse array holes are forbidden`);
167
+ }
155
168
  if (i > 0)
156
169
  out.push(',');
157
170
  emit(value[i], out, `${path}[${i}]`);
@@ -1 +1 @@
1
- {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Canonical text normalizer (TypeScript port of
3
+ * `sdk/python/src/attestplane/canonical_text.py`).
4
+ *
5
+ * Cross-language byte stable with the Python reference implementation
6
+ * across the conformance vectors in
7
+ * `sdk/python/tests/conformance/text_vectors.json`.
8
+ *
9
+ * Four-stage algorithm locked by `docs/spec/canonical-text-v1.md`:
10
+ * 1. NFC normalize
11
+ * 2. Unicode default lowercase
12
+ * 3. Zero-width strip (U+200B, U+200C, U+200D, U+FEFF)
13
+ * 4. Whitespace fold (split on \s+, rejoin with single space, trim)
14
+ */
15
+ export declare class CanonicalTextError extends Error {
16
+ constructor(message: string);
17
+ }
18
+ /**
19
+ * Return the canonical UTF-8 bytes of `text`.
20
+ *
21
+ * Pure, deterministic, cross-language byte stable across the
22
+ * conformance-vector set. Identical inputs in Python and TypeScript
23
+ * implementations produce identical output bytes.
24
+ */
25
+ export declare function canonicalizeText(text: string): Uint8Array;
26
+ /** SHA-256 of `canonicalizeText(text)`. Returns 32 raw bytes. */
27
+ export declare function textHash(text: string): Uint8Array;
28
+ /** Lowercase hex form of `textHash`. */
29
+ export declare function textHashHex(text: string): string;
30
+ //# sourceMappingURL=canonical_text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical_text.d.ts","sourceRoot":"","sources":["../src/canonical_text.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAMH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AA8CD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAsBzD;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEjD;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOhD"}