@peac/crypto 0.9.18

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/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # @peac/crypto
2
+
3
+ Ed25519 JWS signing and verification for PEAC protocol
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @peac/crypto
9
+ ```
10
+
11
+ ## Documentation
12
+
13
+ See [peacprotocol.org](https://peacprotocol.org) for full documentation.
14
+
15
+ ## License
16
+
17
+ Apache-2.0
18
+
19
+ ---
20
+
21
+ PEAC Protocol is an open source project stewarded by Originary and community contributors.
22
+
23
+ [Originary](https://www.originary.xyz) | [Docs](https://peacprotocol.org) | [GitHub](https://github.com/peacprotocol/peac)
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Base64url encoding/decoding (RFC 4648 §5)
3
+ * Used for JWS compact serialization
4
+ */
5
+ /**
6
+ * Encode bytes to base64url string (no padding)
7
+ */
8
+ export declare function base64urlEncode(bytes: Uint8Array): string;
9
+ /**
10
+ * Decode base64url string to bytes
11
+ */
12
+ export declare function base64urlDecode(str: string): Uint8Array;
13
+ /**
14
+ * Encode UTF-8 string to base64url
15
+ */
16
+ export declare function base64urlEncodeString(str: string): string;
17
+ /**
18
+ * Decode base64url to UTF-8 string
19
+ */
20
+ export declare function base64urlDecodeString(str: string): string;
21
+ //# sourceMappingURL=base64url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64url.d.ts","sourceRoot":"","sources":["../src/base64url.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAYvD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * Base64url encoding/decoding (RFC 4648 §5)
4
+ * Used for JWS compact serialization
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.base64urlEncode = base64urlEncode;
8
+ exports.base64urlDecode = base64urlDecode;
9
+ exports.base64urlEncodeString = base64urlEncodeString;
10
+ exports.base64urlDecodeString = base64urlDecodeString;
11
+ /**
12
+ * Encode bytes to base64url string (no padding)
13
+ */
14
+ function base64urlEncode(bytes) {
15
+ const base64 = Buffer.from(bytes).toString('base64');
16
+ return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
17
+ }
18
+ /**
19
+ * Decode base64url string to bytes
20
+ */
21
+ function base64urlDecode(str) {
22
+ // Add padding if needed
23
+ let padded = str;
24
+ const mod = str.length % 4;
25
+ if (mod > 0) {
26
+ padded += '='.repeat(4 - mod);
27
+ }
28
+ // Convert base64url to base64
29
+ const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');
30
+ return new Uint8Array(Buffer.from(base64, 'base64'));
31
+ }
32
+ /**
33
+ * Encode UTF-8 string to base64url
34
+ */
35
+ function base64urlEncodeString(str) {
36
+ return base64urlEncode(new TextEncoder().encode(str));
37
+ }
38
+ /**
39
+ * Decode base64url to UTF-8 string
40
+ */
41
+ function base64urlDecodeString(str) {
42
+ return new TextDecoder().decode(base64urlDecode(str));
43
+ }
44
+ //# sourceMappingURL=base64url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64url.js","sourceRoot":"","sources":["../src/base64url.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH,0CAGC;AAKD,0CAYC;AAKD,sDAEC;AAKD,sDAEC;AArCD;;GAEG;AACH,SAAgB,eAAe,CAAC,KAAiB;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,wBAAwB;IACxB,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,8BAA8B;IAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAE5D,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,OAAO,eAAe,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * PEAC Protocol Crypto Package
3
+ * Ed25519 JWS signing/verification and JSON Canonicalization (RFC 8785)
4
+ */
5
+ export * from './base64url';
6
+ export * from './jcs';
7
+ export * from './jws';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * PEAC Protocol Crypto Package
4
+ * Ed25519 JWS signing/verification and JSON Canonicalization (RFC 8785)
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ __exportStar(require("./base64url"), exports);
22
+ __exportStar(require("./jcs"), exports);
23
+ __exportStar(require("./jws"), exports);
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;AAEH,8CAA4B;AAC5B,wCAAsB;AACtB,wCAAsB"}
package/dist/jcs.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * JSON Canonicalization Scheme (RFC 8785)
3
+ * Deterministic JSON serialization for cryptographic hashing
4
+ */
5
+ /**
6
+ * Canonicalize a JSON value according to RFC 8785
7
+ */
8
+ export declare function canonicalize(obj: unknown): string;
9
+ /**
10
+ * Canonicalize and encode as UTF-8 bytes
11
+ */
12
+ export declare function canonicalizeBytes(obj: unknown): Uint8Array;
13
+ /**
14
+ * Compute JCS+SHA-256 hash of an object
15
+ */
16
+ export declare function jcsHash(obj: unknown): Promise<string>;
17
+ //# sourceMappingURL=jcs.d.ts.map
@@ -0,0 +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"}
package/dist/jcs.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * JSON Canonicalization Scheme (RFC 8785)
4
+ * Deterministic JSON serialization for cryptographic hashing
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.canonicalize = canonicalize;
8
+ exports.canonicalizeBytes = canonicalizeBytes;
9
+ exports.jcsHash = jcsHash;
10
+ /**
11
+ * Canonicalize a JSON value according to RFC 8785
12
+ */
13
+ function canonicalize(obj) {
14
+ if (obj === null) {
15
+ return 'null';
16
+ }
17
+ if (typeof obj === 'boolean') {
18
+ return obj ? 'true' : 'false';
19
+ }
20
+ if (typeof obj === 'number') {
21
+ // RFC 8785 number serialization (no trailing zeros, no exponential for small numbers)
22
+ if (!Number.isFinite(obj)) {
23
+ throw new Error('Cannot canonicalize non-finite number');
24
+ }
25
+ if (Object.is(obj, -0)) {
26
+ return '0';
27
+ }
28
+ // Use JSON.stringify for proper number formatting per RFC 8785
29
+ const str = JSON.stringify(obj);
30
+ // Ensure no exponential notation for integers
31
+ if (Number.isInteger(obj) && str.includes('e')) {
32
+ return obj.toString();
33
+ }
34
+ return str;
35
+ }
36
+ if (typeof obj === 'string') {
37
+ return JSON.stringify(obj);
38
+ }
39
+ if (Array.isArray(obj)) {
40
+ const elements = obj.map(canonicalize);
41
+ return `[${elements.join(',')}]`;
42
+ }
43
+ if (typeof obj === 'object') {
44
+ // Sort keys lexicographically by UTF-16 code unit
45
+ const keys = Object.keys(obj).sort();
46
+ const pairs = keys.map((key) => {
47
+ const value = obj[key];
48
+ return `${JSON.stringify(key)}:${canonicalize(value)}`;
49
+ });
50
+ return `{${pairs.join(',')}}`;
51
+ }
52
+ throw new Error(`Cannot canonicalize type: ${typeof obj}`);
53
+ }
54
+ /**
55
+ * Canonicalize and encode as UTF-8 bytes
56
+ */
57
+ function canonicalizeBytes(obj) {
58
+ const canonical = canonicalize(obj);
59
+ return new TextEncoder().encode(canonical);
60
+ }
61
+ /**
62
+ * Compute JCS+SHA-256 hash of an object
63
+ */
64
+ async function jcsHash(obj) {
65
+ const bytes = canonicalizeBytes(obj);
66
+ const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);
67
+ const hashArray = new Uint8Array(hashBuffer);
68
+ return Array.from(hashArray)
69
+ .map((b) => b.toString(16).padStart(2, '0'))
70
+ .join('');
71
+ }
72
+ //# sourceMappingURL=jcs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jcs.js","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH,oCA8CC;AAKD,8CAGC;AAKD,0BAOC;AArED;;GAEG;AACH,SAAgB,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,sFAAsF;QACtF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,+DAA+D;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,8CAA8C;QAC9C,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACvC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACnC,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,kDAAkD;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAI,GAA+B,CAAC,GAAG,CAAC,CAAC;YACpD,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAChC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,6BAA6B,OAAO,GAAG,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,GAAY;IAC5C,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,OAAO,CAAC,GAAY;IACxC,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
package/dist/jws.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * JWS compact serialization with Ed25519 (RFC 8032)
3
+ * Implements peac.receipt/0.9 wire format
4
+ */
5
+ import { PEAC_WIRE_TYP, PEAC_ALG } from '@peac/schema';
6
+ /**
7
+ * JWS header for PEAC receipts
8
+ */
9
+ export interface JWSHeader {
10
+ typ: typeof PEAC_WIRE_TYP;
11
+ alg: typeof PEAC_ALG;
12
+ kid: string;
13
+ }
14
+ /**
15
+ * Result of JWS verification
16
+ */
17
+ export interface VerifyResult<T = unknown> {
18
+ header: JWSHeader;
19
+ payload: T;
20
+ valid: boolean;
21
+ }
22
+ /**
23
+ * Sign a payload with Ed25519 and return JWS compact serialization
24
+ *
25
+ * @param payload - JSON-serializable payload
26
+ * @param privateKey - Ed25519 private key (32 bytes)
27
+ * @param kid - Key ID (ISO 8601 timestamp)
28
+ * @returns JWS compact serialization (header.payload.signature)
29
+ */
30
+ export declare function sign(payload: unknown, privateKey: Uint8Array, kid: string): Promise<string>;
31
+ /**
32
+ * Verify a JWS compact serialization with Ed25519
33
+ *
34
+ * @param jws - JWS compact serialization
35
+ * @param publicKey - Ed25519 public key (32 bytes)
36
+ * @returns Verification result with decoded header and payload
37
+ */
38
+ export declare function verify<T = unknown>(jws: string, publicKey: Uint8Array): Promise<VerifyResult<T>>;
39
+ /**
40
+ * Decode JWS without verifying signature (use with caution!)
41
+ *
42
+ * @param jws - JWS compact serialization
43
+ * @returns Decoded header and payload (unverified)
44
+ */
45
+ export declare function decode<T = unknown>(jws: string): {
46
+ header: JWSHeader;
47
+ payload: T;
48
+ };
49
+ /**
50
+ * Generate a random Ed25519 keypair
51
+ *
52
+ * @returns Private key (32 bytes) and public key (32 bytes)
53
+ */
54
+ export declare function generateKeypair(): Promise<{
55
+ privateKey: Uint8Array;
56
+ publicKey: Uint8Array;
57
+ }>;
58
+ //# sourceMappingURL=jws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jws.d.ts","sourceRoot":"","sources":["../src/jws.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQvD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,OAAO,aAAa,CAAC;IAC1B,GAAG,EAAE,OAAO,QAAQ,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BjG;AAED;;;;;;GAMG;AACH,wBAAsB,MAAM,CAAC,CAAC,GAAG,OAAO,EACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA2C1B;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,CAAC,CAAA;CAAE,CAelF;AAED;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,UAAU,CAAC;CACvB,CAAC,CAKD"}
package/dist/jws.js ADDED
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /**
3
+ * JWS compact serialization with Ed25519 (RFC 8032)
4
+ * Implements peac.receipt/0.9 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
+ const ed25519 = __importStar(require("@noble/ed25519"));
45
+ const schema_1 = require("@peac/schema");
46
+ const base64url_1 = require("./base64url");
47
+ /**
48
+ * Sign a payload with Ed25519 and return JWS compact serialization
49
+ *
50
+ * @param payload - JSON-serializable payload
51
+ * @param privateKey - Ed25519 private key (32 bytes)
52
+ * @param kid - Key ID (ISO 8601 timestamp)
53
+ * @returns JWS compact serialization (header.payload.signature)
54
+ */
55
+ async function sign(payload, privateKey, kid) {
56
+ if (privateKey.length !== 32) {
57
+ throw new Error('Ed25519 private key must be 32 bytes');
58
+ }
59
+ // Create header
60
+ const header = {
61
+ typ: schema_1.PEAC_WIRE_TYP,
62
+ alg: schema_1.PEAC_ALG,
63
+ kid,
64
+ };
65
+ // Encode header and payload
66
+ const headerB64 = (0, base64url_1.base64urlEncodeString)(JSON.stringify(header));
67
+ const payloadB64 = (0, base64url_1.base64urlEncodeString)(JSON.stringify(payload));
68
+ // Create signing input
69
+ const signingInput = `${headerB64}.${payloadB64}`;
70
+ const signingInputBytes = new TextEncoder().encode(signingInput);
71
+ // Sign with Ed25519
72
+ const signatureBytes = await ed25519.signAsync(signingInputBytes, privateKey);
73
+ // Encode signature
74
+ const signatureB64 = (0, base64url_1.base64urlEncode)(signatureBytes);
75
+ // Return JWS compact serialization
76
+ return `${signingInput}.${signatureB64}`;
77
+ }
78
+ /**
79
+ * Verify a JWS compact serialization with Ed25519
80
+ *
81
+ * @param jws - JWS compact serialization
82
+ * @param publicKey - Ed25519 public key (32 bytes)
83
+ * @returns Verification result with decoded header and payload
84
+ */
85
+ async function verify(jws, publicKey) {
86
+ if (publicKey.length !== 32) {
87
+ throw new Error('Ed25519 public key must be 32 bytes');
88
+ }
89
+ // Split JWS
90
+ const parts = jws.split('.');
91
+ if (parts.length !== 3) {
92
+ throw new Error('Invalid JWS: must have three dot-separated parts');
93
+ }
94
+ const [headerB64, payloadB64, signatureB64] = parts;
95
+ // Decode header
96
+ const headerJson = (0, base64url_1.base64urlDecodeString)(headerB64);
97
+ const header = JSON.parse(headerJson);
98
+ // Validate header
99
+ if (header.typ !== schema_1.PEAC_WIRE_TYP) {
100
+ throw new Error(`Invalid typ: expected ${schema_1.PEAC_WIRE_TYP}, got ${header.typ}`);
101
+ }
102
+ if (header.alg !== schema_1.PEAC_ALG) {
103
+ throw new Error(`Invalid alg: expected ${schema_1.PEAC_ALG}, got ${header.alg}`);
104
+ }
105
+ // Decode payload
106
+ const payloadJson = (0, base64url_1.base64urlDecodeString)(payloadB64);
107
+ const payload = JSON.parse(payloadJson);
108
+ // Decode signature
109
+ const signatureBytes = (0, base64url_1.base64urlDecode)(signatureB64);
110
+ // Verify signature
111
+ const signingInput = `${headerB64}.${payloadB64}`;
112
+ const signingInputBytes = new TextEncoder().encode(signingInput);
113
+ const valid = await ed25519.verifyAsync(signatureBytes, signingInputBytes, publicKey);
114
+ return {
115
+ header,
116
+ payload,
117
+ valid,
118
+ };
119
+ }
120
+ /**
121
+ * Decode JWS without verifying signature (use with caution!)
122
+ *
123
+ * @param jws - JWS compact serialization
124
+ * @returns Decoded header and payload (unverified)
125
+ */
126
+ function decode(jws) {
127
+ const parts = jws.split('.');
128
+ if (parts.length !== 3) {
129
+ throw new Error('Invalid JWS: must have three dot-separated parts');
130
+ }
131
+ const [headerB64, payloadB64] = parts;
132
+ const headerJson = (0, base64url_1.base64urlDecodeString)(headerB64);
133
+ const header = JSON.parse(headerJson);
134
+ const payloadJson = (0, base64url_1.base64urlDecodeString)(payloadB64);
135
+ const payload = JSON.parse(payloadJson);
136
+ return { header, payload };
137
+ }
138
+ /**
139
+ * Generate a random Ed25519 keypair
140
+ *
141
+ * @returns Private key (32 bytes) and public key (32 bytes)
142
+ */
143
+ async function generateKeypair() {
144
+ const privateKey = ed25519.utils.randomPrivateKey();
145
+ const publicKey = await ed25519.getPublicKeyAsync(privateKey);
146
+ return { privateKey, publicKey };
147
+ }
148
+ //# sourceMappingURL=jws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jws.js","sourceRoot":"","sources":["../src/jws.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@peac/crypto",
3
+ "version": "0.9.18",
4
+ "description": "Ed25519 JWS signing and verification for PEAC protocol",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/peacprotocol/peac.git",
10
+ "directory": "packages/crypto"
11
+ },
12
+ "author": "jithinraj <7850727+jithinraj@users.noreply.github.com>",
13
+ "license": "Apache-2.0",
14
+ "bugs": {
15
+ "url": "https://github.com/peacprotocol/peac/issues"
16
+ },
17
+ "homepage": "https://github.com/peacprotocol/peac#readme",
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "dependencies": {
32
+ "@noble/ed25519": "^2.0.0",
33
+ "@peac/schema": "workspace:*"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^20.10.0",
37
+ "typescript": "^5.3.3",
38
+ "vitest": "^1.1.0"
39
+ }
40
+ }