@peac/crypto 0.10.5 → 0.10.7

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/jcs.d.ts CHANGED
@@ -1,9 +1,54 @@
1
1
  /**
2
2
  * JSON Canonicalization Scheme (RFC 8785)
3
3
  * Deterministic JSON serialization for cryptographic hashing
4
+ *
5
+ * PROTOCOL DECISION: JavaScript `undefined` Handling
6
+ * ===================================================
7
+ *
8
+ * RFC 8785 canonicalizes JSON values, and `undefined` is NOT a JSON value.
9
+ * This implementation adopts "JS-ergonomic" semantics that match JSON.stringify:
10
+ *
11
+ * 1. **Object properties with undefined values are OMITTED**
12
+ * - `canonicalize({a: 1, b: undefined})` -> `{"a":1}`
13
+ * - Matches: `JSON.stringify({a: 1, b: undefined})` -> `{"a":1}`
14
+ *
15
+ * 2. **Array elements that are undefined become null**
16
+ * - `canonicalize([1, undefined, 3])` -> `[1,null,3]`
17
+ * - Matches: `JSON.stringify([1, undefined, 3])` -> `[1,null,3]`
18
+ *
19
+ * 3. **Top-level undefined THROWS**
20
+ * - `canonicalize(undefined)` -> throws Error
21
+ * - Rationale: No valid JSON representation exists
22
+ *
23
+ * CROSS-LANGUAGE INTEROPERABILITY WARNING:
24
+ * =========================================
25
+ * Cross-language producers MUST NOT rely on "undefined" semantics. To achieve
26
+ * identical hashes across implementations, explicitly encode `null` in arrays
27
+ * and omit keys in objects. Other language implementations (Go, Rust, Python)
28
+ * will never produce `undefined` since it's JavaScript-specific.
29
+ *
30
+ * Guidelines:
31
+ * - Producers MUST emit explicit `null` or omit keys; do NOT rely on coercion
32
+ * - Verifiers SHOULD sanitize inputs before hashing (remove undefined properties)
33
+ * - The canonical output is identical whether you pass `{a: undefined}` or `{}`
34
+ *
35
+ * This behavior is NORMATIVE for PEAC hashing and MUST NOT change without
36
+ * a wire format version bump.
4
37
  */
5
38
  /**
6
- * Canonicalize a JSON value according to RFC 8785
39
+ * Canonicalize a JSON value according to RFC 8785.
40
+ *
41
+ * @param obj - The value to canonicalize. Must be a valid JSON type (null, boolean,
42
+ * number, string, array, object). Functions and Symbols throw.
43
+ * @returns Canonical JSON string with sorted keys and no whitespace.
44
+ * @throws Error if the value cannot be canonicalized (undefined at top level,
45
+ * non-finite numbers, functions, symbols).
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * canonicalize({ b: 2, a: 1 }) // '{"a":1,"b":2}'
50
+ * canonicalize([1, null, "x"]) // '[1,null,"x"]'
51
+ * ```
7
52
  */
8
53
  export declare function canonicalize(obj: unknown): string;
9
54
  /**
package/dist/jcs.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jcs.d.ts","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CA8CjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAG1D;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3D"}
1
+ {"version":3,"file":"jcs.d.ts","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAsDjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAG1D;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3D"}
package/dist/jcs.js CHANGED
@@ -2,13 +2,58 @@
2
2
  /**
3
3
  * JSON Canonicalization Scheme (RFC 8785)
4
4
  * Deterministic JSON serialization for cryptographic hashing
5
+ *
6
+ * PROTOCOL DECISION: JavaScript `undefined` Handling
7
+ * ===================================================
8
+ *
9
+ * RFC 8785 canonicalizes JSON values, and `undefined` is NOT a JSON value.
10
+ * This implementation adopts "JS-ergonomic" semantics that match JSON.stringify:
11
+ *
12
+ * 1. **Object properties with undefined values are OMITTED**
13
+ * - `canonicalize({a: 1, b: undefined})` -> `{"a":1}`
14
+ * - Matches: `JSON.stringify({a: 1, b: undefined})` -> `{"a":1}`
15
+ *
16
+ * 2. **Array elements that are undefined become null**
17
+ * - `canonicalize([1, undefined, 3])` -> `[1,null,3]`
18
+ * - Matches: `JSON.stringify([1, undefined, 3])` -> `[1,null,3]`
19
+ *
20
+ * 3. **Top-level undefined THROWS**
21
+ * - `canonicalize(undefined)` -> throws Error
22
+ * - Rationale: No valid JSON representation exists
23
+ *
24
+ * CROSS-LANGUAGE INTEROPERABILITY WARNING:
25
+ * =========================================
26
+ * Cross-language producers MUST NOT rely on "undefined" semantics. To achieve
27
+ * identical hashes across implementations, explicitly encode `null` in arrays
28
+ * and omit keys in objects. Other language implementations (Go, Rust, Python)
29
+ * will never produce `undefined` since it's JavaScript-specific.
30
+ *
31
+ * Guidelines:
32
+ * - Producers MUST emit explicit `null` or omit keys; do NOT rely on coercion
33
+ * - Verifiers SHOULD sanitize inputs before hashing (remove undefined properties)
34
+ * - The canonical output is identical whether you pass `{a: undefined}` or `{}`
35
+ *
36
+ * This behavior is NORMATIVE for PEAC hashing and MUST NOT change without
37
+ * a wire format version bump.
5
38
  */
6
39
  Object.defineProperty(exports, "__esModule", { value: true });
7
40
  exports.canonicalize = canonicalize;
8
41
  exports.canonicalizeBytes = canonicalizeBytes;
9
42
  exports.jcsHash = jcsHash;
10
43
  /**
11
- * Canonicalize a JSON value according to RFC 8785
44
+ * Canonicalize a JSON value according to RFC 8785.
45
+ *
46
+ * @param obj - The value to canonicalize. Must be a valid JSON type (null, boolean,
47
+ * number, string, array, object). Functions and Symbols throw.
48
+ * @returns Canonical JSON string with sorted keys and no whitespace.
49
+ * @throws Error if the value cannot be canonicalized (undefined at top level,
50
+ * non-finite numbers, functions, symbols).
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * canonicalize({ b: 2, a: 1 }) // '{"a":1,"b":2}'
55
+ * canonicalize([1, null, "x"]) // '[1,null,"x"]'
56
+ * ```
12
57
  */
13
58
  function canonicalize(obj) {
14
59
  if (obj === null) {
@@ -37,16 +82,24 @@ function canonicalize(obj) {
37
82
  return JSON.stringify(obj);
38
83
  }
39
84
  if (Array.isArray(obj)) {
40
- const elements = obj.map(canonicalize);
85
+ // PROTOCOL DECISION: undefined in arrays becomes null (matches JSON.stringify)
86
+ // See module-level documentation for cross-language interoperability notes.
87
+ const elements = obj.map((el) => (el === undefined ? 'null' : canonicalize(el)));
41
88
  return `[${elements.join(',')}]`;
42
89
  }
43
90
  if (typeof obj === 'object') {
44
- // Sort keys lexicographically by UTF-16 code unit
91
+ // Sort keys lexicographically by UTF-16 code unit (RFC 8785 requirement)
45
92
  const keys = Object.keys(obj).sort();
46
- const pairs = keys.map((key) => {
93
+ const pairs = [];
94
+ for (const key of keys) {
47
95
  const value = obj[key];
48
- return `${JSON.stringify(key)}:${canonicalize(value)}`;
49
- });
96
+ // PROTOCOL DECISION: Skip undefined values (matches JSON.stringify)
97
+ // See module-level documentation for cross-language interoperability notes.
98
+ if (value === undefined) {
99
+ continue;
100
+ }
101
+ pairs.push(`${JSON.stringify(key)}:${canonicalize(value)}`);
102
+ }
50
103
  return `{${pairs.join(',')}}`;
51
104
  }
52
105
  throw new Error(`Cannot canonicalize type: ${typeof obj}`);
package/dist/jcs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jcs.js","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jcs.js","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peac/crypto",
3
- "version": "0.10.5",
3
+ "version": "0.10.7",
4
4
  "description": "Ed25519 JWS signing and verification for PEAC protocol",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@noble/ed25519": "^2.0.0",
41
- "@peac/schema": "0.10.5"
41
+ "@peac/schema": "0.10.7"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^20.10.0",