@peac/crypto 0.10.8 → 0.10.10
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/LICENSE +1 -1
- package/dist/hash.d.ts +31 -0
- package/dist/hash.d.ts.map +1 -1
- package/dist/index.cjs +365 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +320 -0
- package/dist/index.mjs.map +1 -0
- package/dist/testkit.cjs +50 -0
- package/dist/testkit.cjs.map +1 -0
- package/dist/testkit.mjs +28 -0
- package/dist/testkit.mjs.map +1 -0
- package/package.json +18 -13
- package/dist/base64url.js +0 -98
- package/dist/base64url.js.map +0 -1
- package/dist/errors.js +0 -45
- package/dist/errors.js.map +0 -1
- package/dist/hash.js +0 -171
- package/dist/hash.js.map +0 -1
- package/dist/index.js +0 -32
- package/dist/index.js.map +0 -1
- package/dist/jcs.js +0 -125
- package/dist/jcs.js.map +0 -1
- package/dist/jws.js +0 -219
- package/dist/jws.js.map +0 -1
- package/dist/testkit.js +0 -82
- package/dist/testkit.js.map +0 -1
package/dist/base64url.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base64url.js","sourceRoot":"","sources":["../src/base64url.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAwBH,0CAmBC;AAQD,0CA4BC;AAQD,sDAEC;AAQD,sDAEC;AAjGD,2BAA2B;AAC3B,MAAM,eAAe,GAAG,kEAAkE,CAAC;AAE3F,4CAA4C;AAC5C,IAAI,YAAY,GAA+B,IAAI,CAAC;AAEpD,SAAS,eAAe;IACtB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,KAAiB;IAC/C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACrB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAE1B,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAEzC,MAAM,IAAI,eAAe,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,eAAe,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,CAAC;IAED,oCAAoC;IACpC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,8BAA8B;IAC9B,IAAI,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAEvD,wBAAwB;IACxB,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEzC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,OAAO,eAAe,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC"}
|
package/dist/errors.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Typed errors for @peac/crypto
|
|
4
|
-
*
|
|
5
|
-
* These error codes are INTERNAL to @peac/crypto and should NOT be exposed
|
|
6
|
-
* as protocol-stable API. Higher-level packages (like @peac/protocol) should
|
|
7
|
-
* map these to canonical E_* codes from specs/kernel/errors.json.
|
|
8
|
-
*
|
|
9
|
-
* The CRYPTO_ prefix makes it clear these are package-internal codes.
|
|
10
|
-
*/
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.CryptoError = void 0;
|
|
13
|
-
exports.isFormatError = isFormatError;
|
|
14
|
-
/**
|
|
15
|
-
* Typed error for crypto operations
|
|
16
|
-
*
|
|
17
|
-
* Use `err.code` to handle errors programmatically without message parsing.
|
|
18
|
-
* The code is a CRYPTO_* internal code, not a canonical E_* protocol code.
|
|
19
|
-
*/
|
|
20
|
-
class CryptoError extends Error {
|
|
21
|
-
code;
|
|
22
|
-
constructor(code, message) {
|
|
23
|
-
super(message);
|
|
24
|
-
this.name = 'CryptoError';
|
|
25
|
-
this.code = code;
|
|
26
|
-
// Maintain proper prototype chain for instanceof checks
|
|
27
|
-
Object.setPrototypeOf(this, CryptoError.prototype);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.CryptoError = CryptoError;
|
|
31
|
-
/**
|
|
32
|
-
* Check if a CryptoError code indicates a format/structure issue
|
|
33
|
-
* (as opposed to a cryptographic verification failure)
|
|
34
|
-
*
|
|
35
|
-
* @internal This is an internal helper, not part of the public API.
|
|
36
|
-
* Use structural checks on CryptoError.code instead of relying on this function.
|
|
37
|
-
*/
|
|
38
|
-
function isFormatError(code) {
|
|
39
|
-
return (code === 'CRYPTO_INVALID_JWS_FORMAT' ||
|
|
40
|
-
code === 'CRYPTO_INVALID_TYP' ||
|
|
41
|
-
code === 'CRYPTO_INVALID_ALG' ||
|
|
42
|
-
code === 'CRYPTO_INVALID_KEY_LENGTH' ||
|
|
43
|
-
code === 'CRYPTO_INVALID_SEED_LENGTH');
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAyCH,sCAQC;AAjCD;;;;;GAKG;AACH,MAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAkB;IAE/B,YAAY,IAAqB,EAAE,OAAe;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,wDAAwD;QACxD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;CACF;AAVD,kCAUC;AAED;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,IAAqB;IACjD,OAAO,CACL,IAAI,KAAK,2BAA2B;QACpC,IAAI,KAAK,oBAAoB;QAC7B,IAAI,KAAK,oBAAoB;QAC7B,IAAI,KAAK,2BAA2B;QACpC,IAAI,KAAK,4BAA4B,CACtC,CAAC;AACJ,CAAC"}
|
package/dist/hash.js
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Cryptographic hash utilities
|
|
4
|
-
*
|
|
5
|
-
* Platform-agnostic SHA-256 implementation that works in Node.js, browser, and edge runtimes.
|
|
6
|
-
* Uses Web Crypto API with Node.js crypto fallback.
|
|
7
|
-
*
|
|
8
|
-
* @packageDocumentation
|
|
9
|
-
*/
|
|
10
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
-
}
|
|
16
|
-
Object.defineProperty(o, k2, desc);
|
|
17
|
-
}) : (function(o, m, k, k2) {
|
|
18
|
-
if (k2 === undefined) k2 = k;
|
|
19
|
-
o[k2] = m[k];
|
|
20
|
-
}));
|
|
21
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
-
}) : function(o, v) {
|
|
24
|
-
o["default"] = v;
|
|
25
|
-
});
|
|
26
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
-
var ownKeys = function(o) {
|
|
28
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
-
var ar = [];
|
|
30
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
-
return ar;
|
|
32
|
-
};
|
|
33
|
-
return ownKeys(o);
|
|
34
|
-
};
|
|
35
|
-
return function (mod) {
|
|
36
|
-
if (mod && mod.__esModule) return mod;
|
|
37
|
-
var result = {};
|
|
38
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
-
__setModuleDefault(result, mod);
|
|
40
|
-
return result;
|
|
41
|
-
};
|
|
42
|
-
})();
|
|
43
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.sha256Hex = sha256Hex;
|
|
45
|
-
exports.sha256Bytes = sha256Bytes;
|
|
46
|
-
exports.hexToBytes = hexToBytes;
|
|
47
|
-
exports.bytesToHex = bytesToHex;
|
|
48
|
-
exports.computeJwkThumbprint = computeJwkThumbprint;
|
|
49
|
-
exports.jwkToPublicKeyBytes = jwkToPublicKeyBytes;
|
|
50
|
-
const base64url_js_1 = require("./base64url.js");
|
|
51
|
-
/**
|
|
52
|
-
* Compute SHA-256 hash of data and return as lowercase hex string
|
|
53
|
-
*
|
|
54
|
-
* Uses Web Crypto API if available, falls back to Node.js crypto.
|
|
55
|
-
*
|
|
56
|
-
* @param data - Data to hash (Uint8Array or string)
|
|
57
|
-
* @returns Lowercase hex string (64 characters)
|
|
58
|
-
*/
|
|
59
|
-
async function sha256Hex(data) {
|
|
60
|
-
const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data;
|
|
61
|
-
// Try Web Crypto API first (works in browser, edge, and Node 20+)
|
|
62
|
-
if (typeof globalThis.crypto?.subtle?.digest === 'function') {
|
|
63
|
-
const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', bytes);
|
|
64
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
65
|
-
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
66
|
-
}
|
|
67
|
-
// Fallback to Node.js crypto
|
|
68
|
-
try {
|
|
69
|
-
const { createHash } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
70
|
-
const hash = createHash('sha256');
|
|
71
|
-
hash.update(bytes);
|
|
72
|
-
return hash.digest('hex');
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
throw new Error('No SHA-256 implementation available. Ensure Web Crypto API or Node.js crypto is available.');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Compute SHA-256 hash of data and return as Uint8Array (32 bytes)
|
|
80
|
-
*
|
|
81
|
-
* @param data - Data to hash (Uint8Array or string)
|
|
82
|
-
* @returns Hash as Uint8Array (32 bytes)
|
|
83
|
-
*/
|
|
84
|
-
async function sha256Bytes(data) {
|
|
85
|
-
const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data;
|
|
86
|
-
// Try Web Crypto API first
|
|
87
|
-
if (typeof globalThis.crypto?.subtle?.digest === 'function') {
|
|
88
|
-
const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', bytes);
|
|
89
|
-
return new Uint8Array(hashBuffer);
|
|
90
|
-
}
|
|
91
|
-
// Fallback to Node.js crypto
|
|
92
|
-
try {
|
|
93
|
-
const { createHash } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
94
|
-
const hash = createHash('sha256');
|
|
95
|
-
hash.update(bytes);
|
|
96
|
-
return new Uint8Array(hash.digest());
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
throw new Error('No SHA-256 implementation available.');
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Convert hex string to Uint8Array
|
|
104
|
-
*
|
|
105
|
-
* @param hex - Lowercase hex string
|
|
106
|
-
* @returns Uint8Array
|
|
107
|
-
*/
|
|
108
|
-
function hexToBytes(hex) {
|
|
109
|
-
// Validate: must be even length and contain only hex characters
|
|
110
|
-
if (hex.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(hex)) {
|
|
111
|
-
throw new Error('Invalid hex string');
|
|
112
|
-
}
|
|
113
|
-
if (hex.length === 0) {
|
|
114
|
-
return new Uint8Array([]);
|
|
115
|
-
}
|
|
116
|
-
const matches = hex.match(/.{2}/g);
|
|
117
|
-
if (!matches) {
|
|
118
|
-
throw new Error('Invalid hex string');
|
|
119
|
-
}
|
|
120
|
-
return new Uint8Array(matches.map((byte) => parseInt(byte, 16)));
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Convert Uint8Array to lowercase hex string
|
|
124
|
-
*
|
|
125
|
-
* @param bytes - Byte array
|
|
126
|
-
* @returns Lowercase hex string
|
|
127
|
-
*/
|
|
128
|
-
function bytesToHex(bytes) {
|
|
129
|
-
return Array.from(bytes)
|
|
130
|
-
.map((b) => b.toString(16).padStart(2, '0'))
|
|
131
|
-
.join('');
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Compute RFC 7638 JWK Thumbprint (base64url, SHA-256)
|
|
135
|
-
*
|
|
136
|
-
* For Ed25519 keys, the canonical JSON is: {"crv":"Ed25519","kty":"OKP","x":"<base64url>"}
|
|
137
|
-
* Returns base64url-encoded SHA-256 hash (43 characters).
|
|
138
|
-
*
|
|
139
|
-
* @param jwk - JWK with kty, crv, x fields
|
|
140
|
-
* @returns Base64url-encoded SHA-256 thumbprint (43 characters)
|
|
141
|
-
*/
|
|
142
|
-
async function computeJwkThumbprint(jwk) {
|
|
143
|
-
if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {
|
|
144
|
-
throw new Error('Only Ed25519 keys (OKP/Ed25519) are supported for thumbprint computation');
|
|
145
|
-
}
|
|
146
|
-
// Canonical JSON per RFC 7638 (alphabetically sorted members, no whitespace)
|
|
147
|
-
const canonical = JSON.stringify({
|
|
148
|
-
crv: jwk.crv,
|
|
149
|
-
kty: jwk.kty,
|
|
150
|
-
x: jwk.x,
|
|
151
|
-
});
|
|
152
|
-
const hashBytes = await sha256Bytes(canonical);
|
|
153
|
-
return (0, base64url_js_1.base64urlEncode)(hashBytes);
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Convert JWK to Ed25519 public key bytes (32 bytes)
|
|
157
|
-
*
|
|
158
|
-
* @param jwk - JWK with kty, crv, x fields
|
|
159
|
-
* @returns Public key as 32-byte Uint8Array
|
|
160
|
-
*/
|
|
161
|
-
function jwkToPublicKeyBytes(jwk) {
|
|
162
|
-
if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {
|
|
163
|
-
throw new Error('Only Ed25519 keys (OKP/Ed25519) are supported');
|
|
164
|
-
}
|
|
165
|
-
const xBytes = (0, base64url_js_1.base64urlDecode)(jwk.x);
|
|
166
|
-
if (xBytes.length !== 32) {
|
|
167
|
-
throw new Error(`Ed25519 public key must be 32 bytes, got ${xBytes.length}`);
|
|
168
|
-
}
|
|
169
|
-
return xBytes;
|
|
170
|
-
}
|
|
171
|
-
//# sourceMappingURL=hash.js.map
|
package/dist/hash.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* PEAC Protocol Crypto Package
|
|
4
|
-
*
|
|
5
|
-
* Ed25519 JWS signing/verification, JSON Canonicalization (RFC 8785),
|
|
6
|
-
* and platform-agnostic cryptographic utilities.
|
|
7
|
-
*
|
|
8
|
-
* All primitives are runtime-agnostic (Node.js, browser, edge workers).
|
|
9
|
-
*
|
|
10
|
-
* @packageDocumentation
|
|
11
|
-
*/
|
|
12
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
-
}
|
|
18
|
-
Object.defineProperty(o, k2, desc);
|
|
19
|
-
}) : (function(o, m, k, k2) {
|
|
20
|
-
if (k2 === undefined) k2 = k;
|
|
21
|
-
o[k2] = m[k];
|
|
22
|
-
}));
|
|
23
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
24
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
25
|
-
};
|
|
26
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
__exportStar(require("./base64url"), exports);
|
|
28
|
-
__exportStar(require("./errors"), exports);
|
|
29
|
-
__exportStar(require("./hash"), exports);
|
|
30
|
-
__exportStar(require("./jcs"), exports);
|
|
31
|
-
__exportStar(require("./jws"), exports);
|
|
32
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;AAEH,8CAA4B;AAC5B,2CAAyB;AACzB,yCAAuB;AACvB,wCAAsB;AACtB,wCAAsB"}
|
package/dist/jcs.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* JSON Canonicalization Scheme (RFC 8785)
|
|
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.
|
|
38
|
-
*/
|
|
39
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.canonicalize = canonicalize;
|
|
41
|
-
exports.canonicalizeBytes = canonicalizeBytes;
|
|
42
|
-
exports.jcsHash = jcsHash;
|
|
43
|
-
/**
|
|
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
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
function canonicalize(obj) {
|
|
59
|
-
if (obj === null) {
|
|
60
|
-
return 'null';
|
|
61
|
-
}
|
|
62
|
-
if (typeof obj === 'boolean') {
|
|
63
|
-
return obj ? 'true' : 'false';
|
|
64
|
-
}
|
|
65
|
-
if (typeof obj === 'number') {
|
|
66
|
-
// RFC 8785 number serialization (no trailing zeros, no exponential for small numbers)
|
|
67
|
-
if (!Number.isFinite(obj)) {
|
|
68
|
-
throw new Error('Cannot canonicalize non-finite number');
|
|
69
|
-
}
|
|
70
|
-
if (Object.is(obj, -0)) {
|
|
71
|
-
return '0';
|
|
72
|
-
}
|
|
73
|
-
// Use JSON.stringify for proper number formatting per RFC 8785
|
|
74
|
-
const str = JSON.stringify(obj);
|
|
75
|
-
// Ensure no exponential notation for integers
|
|
76
|
-
if (Number.isInteger(obj) && str.includes('e')) {
|
|
77
|
-
return obj.toString();
|
|
78
|
-
}
|
|
79
|
-
return str;
|
|
80
|
-
}
|
|
81
|
-
if (typeof obj === 'string') {
|
|
82
|
-
return JSON.stringify(obj);
|
|
83
|
-
}
|
|
84
|
-
if (Array.isArray(obj)) {
|
|
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)));
|
|
88
|
-
return `[${elements.join(',')}]`;
|
|
89
|
-
}
|
|
90
|
-
if (typeof obj === 'object') {
|
|
91
|
-
// Sort keys lexicographically by UTF-16 code unit (RFC 8785 requirement)
|
|
92
|
-
const keys = Object.keys(obj).sort();
|
|
93
|
-
const pairs = [];
|
|
94
|
-
for (const key of keys) {
|
|
95
|
-
const value = obj[key];
|
|
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
|
-
}
|
|
103
|
-
return `{${pairs.join(',')}}`;
|
|
104
|
-
}
|
|
105
|
-
throw new Error(`Cannot canonicalize type: ${typeof obj}`);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Canonicalize and encode as UTF-8 bytes
|
|
109
|
-
*/
|
|
110
|
-
function canonicalizeBytes(obj) {
|
|
111
|
-
const canonical = canonicalize(obj);
|
|
112
|
-
return new TextEncoder().encode(canonical);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Compute JCS+SHA-256 hash of an object
|
|
116
|
-
*/
|
|
117
|
-
async function jcsHash(obj) {
|
|
118
|
-
const bytes = canonicalizeBytes(obj);
|
|
119
|
-
const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);
|
|
120
|
-
const hashArray = new Uint8Array(hashBuffer);
|
|
121
|
-
return Array.from(hashArray)
|
|
122
|
-
.map((b) => b.toString(16).padStart(2, '0'))
|
|
123
|
-
.join('');
|
|
124
|
-
}
|
|
125
|
-
//# sourceMappingURL=jcs.js.map
|
package/dist/jcs.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jcs.js","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"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"}
|
package/dist/jws.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* JWS compact serialization with Ed25519 (RFC 8032)
|
|
4
|
-
* Implements peac-receipt/0.1 wire format
|
|
5
|
-
*/
|
|
6
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
-
if (k2 === undefined) k2 = k;
|
|
8
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
-
var ownKeys = function(o) {
|
|
24
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
-
var ar = [];
|
|
26
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
-
return ar;
|
|
28
|
-
};
|
|
29
|
-
return ownKeys(o);
|
|
30
|
-
};
|
|
31
|
-
return function (mod) {
|
|
32
|
-
if (mod && mod.__esModule) return mod;
|
|
33
|
-
var result = {};
|
|
34
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
-
__setModuleDefault(result, mod);
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
})();
|
|
39
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.sign = sign;
|
|
41
|
-
exports.verify = verify;
|
|
42
|
-
exports.decode = decode;
|
|
43
|
-
exports.generateKeypair = generateKeypair;
|
|
44
|
-
exports.derivePublicKey = derivePublicKey;
|
|
45
|
-
exports.validateKeypair = validateKeypair;
|
|
46
|
-
const ed25519 = __importStar(require("@noble/ed25519"));
|
|
47
|
-
const schema_1 = require("@peac/schema");
|
|
48
|
-
const base64url_1 = require("./base64url");
|
|
49
|
-
const errors_1 = require("./errors");
|
|
50
|
-
/**
|
|
51
|
-
* Sign a payload with Ed25519 and return JWS compact serialization
|
|
52
|
-
*
|
|
53
|
-
* @param payload - JSON-serializable payload
|
|
54
|
-
* @param privateKey - Ed25519 private key (32 bytes)
|
|
55
|
-
* @param kid - Key ID (ISO 8601 timestamp)
|
|
56
|
-
* @returns JWS compact serialization (header.payload.signature)
|
|
57
|
-
*/
|
|
58
|
-
async function sign(payload, privateKey, kid) {
|
|
59
|
-
if (privateKey.length !== 32) {
|
|
60
|
-
throw new errors_1.CryptoError('CRYPTO_INVALID_KEY_LENGTH', 'Ed25519 private key must be 32 bytes');
|
|
61
|
-
}
|
|
62
|
-
// Create header
|
|
63
|
-
const header = {
|
|
64
|
-
typ: schema_1.PEAC_WIRE_TYP,
|
|
65
|
-
alg: schema_1.PEAC_ALG,
|
|
66
|
-
kid,
|
|
67
|
-
};
|
|
68
|
-
// Encode header and payload
|
|
69
|
-
const headerB64 = (0, base64url_1.base64urlEncodeString)(JSON.stringify(header));
|
|
70
|
-
const payloadB64 = (0, base64url_1.base64urlEncodeString)(JSON.stringify(payload));
|
|
71
|
-
// Create signing input
|
|
72
|
-
const signingInput = `${headerB64}.${payloadB64}`;
|
|
73
|
-
const signingInputBytes = new TextEncoder().encode(signingInput);
|
|
74
|
-
// Sign with Ed25519
|
|
75
|
-
const signatureBytes = await ed25519.signAsync(signingInputBytes, privateKey);
|
|
76
|
-
// Encode signature
|
|
77
|
-
const signatureB64 = (0, base64url_1.base64urlEncode)(signatureBytes);
|
|
78
|
-
// Return JWS compact serialization
|
|
79
|
-
return `${signingInput}.${signatureB64}`;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Verify a JWS compact serialization with Ed25519
|
|
83
|
-
*
|
|
84
|
-
* @param jws - JWS compact serialization
|
|
85
|
-
* @param publicKey - Ed25519 public key (32 bytes)
|
|
86
|
-
* @returns Verification result with decoded header and payload
|
|
87
|
-
*/
|
|
88
|
-
async function verify(jws, publicKey) {
|
|
89
|
-
if (publicKey.length !== 32) {
|
|
90
|
-
throw new errors_1.CryptoError('CRYPTO_INVALID_KEY_LENGTH', 'Ed25519 public key must be 32 bytes');
|
|
91
|
-
}
|
|
92
|
-
// Split JWS
|
|
93
|
-
const parts = jws.split('.');
|
|
94
|
-
if (parts.length !== 3) {
|
|
95
|
-
throw new errors_1.CryptoError('CRYPTO_INVALID_JWS_FORMAT', 'Invalid JWS: must have three dot-separated parts');
|
|
96
|
-
}
|
|
97
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
98
|
-
// Decode header
|
|
99
|
-
const headerJson = (0, base64url_1.base64urlDecodeString)(headerB64);
|
|
100
|
-
const header = JSON.parse(headerJson);
|
|
101
|
-
// Validate header
|
|
102
|
-
if (header.typ !== schema_1.PEAC_WIRE_TYP) {
|
|
103
|
-
throw new errors_1.CryptoError('CRYPTO_INVALID_TYP', `Invalid typ: expected ${schema_1.PEAC_WIRE_TYP}, got ${header.typ}`);
|
|
104
|
-
}
|
|
105
|
-
if (header.alg !== schema_1.PEAC_ALG) {
|
|
106
|
-
throw new errors_1.CryptoError('CRYPTO_INVALID_ALG', `Invalid alg: expected ${schema_1.PEAC_ALG}, got ${header.alg}`);
|
|
107
|
-
}
|
|
108
|
-
// Decode payload
|
|
109
|
-
const payloadJson = (0, base64url_1.base64urlDecodeString)(payloadB64);
|
|
110
|
-
const payload = JSON.parse(payloadJson);
|
|
111
|
-
// Decode signature
|
|
112
|
-
const signatureBytes = (0, base64url_1.base64urlDecode)(signatureB64);
|
|
113
|
-
// Verify signature
|
|
114
|
-
const signingInput = `${headerB64}.${payloadB64}`;
|
|
115
|
-
const signingInputBytes = new TextEncoder().encode(signingInput);
|
|
116
|
-
const valid = await ed25519.verifyAsync(signatureBytes, signingInputBytes, publicKey);
|
|
117
|
-
return {
|
|
118
|
-
header,
|
|
119
|
-
payload,
|
|
120
|
-
valid,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Decode JWS without verifying signature (use with caution!)
|
|
125
|
-
*
|
|
126
|
-
* @param jws - JWS compact serialization
|
|
127
|
-
* @returns Decoded header and payload (unverified)
|
|
128
|
-
*/
|
|
129
|
-
function decode(jws) {
|
|
130
|
-
const parts = jws.split('.');
|
|
131
|
-
if (parts.length !== 3) {
|
|
132
|
-
throw new errors_1.CryptoError('CRYPTO_INVALID_JWS_FORMAT', 'Invalid JWS: must have three dot-separated parts');
|
|
133
|
-
}
|
|
134
|
-
const [headerB64, payloadB64] = parts;
|
|
135
|
-
const headerJson = (0, base64url_1.base64urlDecodeString)(headerB64);
|
|
136
|
-
const header = JSON.parse(headerJson);
|
|
137
|
-
const payloadJson = (0, base64url_1.base64urlDecodeString)(payloadB64);
|
|
138
|
-
const payload = JSON.parse(payloadJson);
|
|
139
|
-
return { header, payload };
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Generate a random Ed25519 keypair
|
|
143
|
-
*
|
|
144
|
-
* @returns Private key (32 bytes) and public key (32 bytes)
|
|
145
|
-
*/
|
|
146
|
-
async function generateKeypair() {
|
|
147
|
-
const privateKey = ed25519.utils.randomPrivateKey();
|
|
148
|
-
const publicKey = await ed25519.getPublicKeyAsync(privateKey);
|
|
149
|
-
return { privateKey, publicKey };
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Derive the Ed25519 public key from a private key
|
|
153
|
-
*
|
|
154
|
-
* @param privateKey - Ed25519 private key (32 bytes)
|
|
155
|
-
* @returns Public key (32 bytes)
|
|
156
|
-
*/
|
|
157
|
-
async function derivePublicKey(privateKey) {
|
|
158
|
-
if (privateKey.length !== 32) {
|
|
159
|
-
throw new errors_1.CryptoError('CRYPTO_INVALID_KEY_LENGTH', 'Ed25519 private key must be 32 bytes');
|
|
160
|
-
}
|
|
161
|
-
return ed25519.getPublicKeyAsync(privateKey);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Validate that an Ed25519 JWK has a consistent keypair
|
|
165
|
-
*
|
|
166
|
-
* Derives the public key from the private key (d) and verifies it matches
|
|
167
|
-
* the declared public key (x). This catches configuration errors where
|
|
168
|
-
* the wrong key components are paired.
|
|
169
|
-
*
|
|
170
|
-
* @param jwk - Ed25519 JWK with both public (x) and private (d) components
|
|
171
|
-
* @returns true if the keypair is consistent, false otherwise
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* ```typescript
|
|
175
|
-
* const jwk = {
|
|
176
|
-
* kty: 'OKP',
|
|
177
|
-
* crv: 'Ed25519',
|
|
178
|
-
* x: 'base64url-encoded-public-key',
|
|
179
|
-
* d: 'base64url-encoded-private-key',
|
|
180
|
-
* };
|
|
181
|
-
*
|
|
182
|
-
* if (!await validateKeypair(jwk)) {
|
|
183
|
-
* throw new Error('Invalid keypair: d does not derive to x');
|
|
184
|
-
* }
|
|
185
|
-
* ```
|
|
186
|
-
*/
|
|
187
|
-
async function validateKeypair(jwk) {
|
|
188
|
-
// Validate JWK structure
|
|
189
|
-
if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
// Decode the keys
|
|
193
|
-
let privateKeyBytes;
|
|
194
|
-
let declaredPublicKeyBytes;
|
|
195
|
-
try {
|
|
196
|
-
privateKeyBytes = (0, base64url_1.base64urlDecode)(jwk.d);
|
|
197
|
-
declaredPublicKeyBytes = (0, base64url_1.base64urlDecode)(jwk.x);
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
// Validate lengths
|
|
203
|
-
if (privateKeyBytes.length !== 32 || declaredPublicKeyBytes.length !== 32) {
|
|
204
|
-
return false;
|
|
205
|
-
}
|
|
206
|
-
// Derive the actual public key from the private key
|
|
207
|
-
const derivedPublicKeyBytes = await ed25519.getPublicKeyAsync(privateKeyBytes);
|
|
208
|
-
// Compare derived public key with declared public key
|
|
209
|
-
if (derivedPublicKeyBytes.length !== declaredPublicKeyBytes.length) {
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
for (let i = 0; i < derivedPublicKeyBytes.length; i++) {
|
|
213
|
-
if (derivedPublicKeyBytes[i] !== declaredPublicKeyBytes[i]) {
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return true;
|
|
218
|
-
}
|
|
219
|
-
//# sourceMappingURL=jws.js.map
|
package/dist/jws.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jws.js","sourceRoot":"","sources":["../src/jws.ts"],"names":[],"mappings":"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"}
|