@parmanasystems/crypto 1.71.9 → 1.71.12

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/index.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  /**
2
- * Reads the root trust private key PEM.
3
- * Auto-generates a dev keypair at the default location if neither key file exists.
2
+ * Reads the root trust private key PEM from an explicit file path.
3
+ * Throws clearly if the file does not exist never auto-generates keys.
4
4
  *
5
- * @param keyPath - explicit path to the private key file; defaults to ./trust/root.key
5
+ * @param keyPath - Absolute or CWD-relative path to the private key PEM file.
6
6
  */
7
- declare function loadPrivateKey(keyPath?: string): string;
7
+ declare function loadPrivateKey(keyPath: string): string;
8
8
  /**
9
- * Reads the root trust public key PEM.
10
- * Auto-generates a dev keypair at the default location if neither key file exists.
9
+ * Reads the root trust public key PEM from an explicit file path.
10
+ * Throws clearly if the file does not exist never auto-generates keys.
11
11
  *
12
- * @param keyPath - explicit path to the public key file; defaults to ./trust/root.pub
12
+ * @param keyPath - Absolute or CWD-relative path to the public key PEM file.
13
13
  */
14
- declare function loadPublicKey(keyPath?: string): string;
14
+ declare function loadPublicKey(keyPath: string): string;
15
15
 
16
16
  /**
17
17
  * Writes a base64 signature string to `<directory>/bundle.sig`.
@@ -23,21 +23,23 @@ declare function readSignature(directory: string): string;
23
23
 
24
24
  /**
25
25
  * Reads the manifest JSON at `manifestPath`, canonicalizes it, and returns a
26
- * base64-encoded Ed25519 signature produced with the dev private key.
26
+ * base64-encoded Ed25519 signature produced with the private key at `privateKeyPath`.
27
27
  *
28
- * @param manifestPath - Absolute or CWD-relative path to a `bundle.manifest.json` file.
28
+ * @param manifestPath - Absolute or CWD-relative path to a `bundle.manifest.json` file.
29
+ * @param privateKeyPath - Explicit path to the PEM-encoded Ed25519 private key.
29
30
  * @returns Base64-encoded Ed25519 signature over the canonical manifest bytes.
30
31
  */
31
- declare function signManifest(manifestPath: string): string;
32
+ declare function signManifest(manifestPath: string, privateKeyPath: string): string;
32
33
 
33
34
  /**
34
35
  * Reads the manifest JSON at `manifestPath`, canonicalizes it, and verifies
35
- * `signature` (base64 Ed25519) against the dev public key.
36
+ * `signature` (base64 Ed25519) against the public key at `publicKeyPath`.
36
37
  *
37
- * @param manifestPath - Path to the `bundle.manifest.json` file.
38
- * @param signature - Base64-encoded Ed25519 signature to verify.
38
+ * @param manifestPath - Path to the `bundle.manifest.json` file.
39
+ * @param signature - Base64-encoded Ed25519 signature to verify.
40
+ * @param publicKeyPath - Explicit path to the PEM-encoded Ed25519 public key.
39
41
  */
40
- declare function verifySignature(manifestPath: string, signature: string): boolean;
42
+ declare function verifySignature(manifestPath: string, signature: string, publicKeyPath: string): boolean;
41
43
  /**
42
44
  * Verifies a base64-encoded Ed25519 `signature` over an arbitrary UTF-8
43
45
  * `payload` using the provided `publicKey` PEM. Unlike `verifySignature`,
@@ -52,15 +54,16 @@ declare function verifyPayloadSignature(payload: string, signature: string, publ
52
54
 
53
55
  /**
54
56
  * Verifies `signature` (base64 Ed25519) over the already-serialized canonical
55
- * `manifest` string against the dev public key.
57
+ * `manifest` string against the public key at `publicKeyPath`.
56
58
  *
57
59
  * Unlike `verifySignature`, this function accepts the manifest bytes directly
58
60
  * rather than reading them from disk — suited for in-memory verification flows.
59
61
  *
60
- * @param manifest - Canonical manifest bytes (UTF-8 string).
61
- * @param signature - Base64-encoded Ed25519 signature.
62
+ * @param manifest - Canonical manifest bytes (UTF-8 string).
63
+ * @param signature - Base64-encoded Ed25519 signature.
64
+ * @param publicKeyPath - Explicit path to the PEM-encoded Ed25519 public key.
62
65
  */
63
- declare function verifyManifestSignature(manifest: string, signature: string): boolean;
66
+ declare function verifyManifestSignature(manifest: string, signature: string, publicKeyPath: string): boolean;
64
67
 
65
68
  type SignBundleOptions = {
66
69
  bundlePath: string;
package/dist/index.js CHANGED
@@ -1,47 +1,23 @@
1
1
  // src/keys.ts
2
- import * as crypto from "crypto";
3
2
  import * as fs from "fs";
4
3
  import * as path from "path";
5
- function ensureTrustKeys(privateKeyPath, publicKeyPath) {
6
- if (fs.existsSync(privateKeyPath) && fs.existsSync(publicKeyPath)) {
7
- return;
8
- }
9
- const { privateKey, publicKey } = crypto.generateKeyPairSync("ed25519", {
10
- privateKeyEncoding: { type: "pkcs8", format: "pem" },
11
- publicKeyEncoding: { type: "spki", format: "pem" }
12
- });
13
- fs.mkdirSync(
14
- path.dirname(privateKeyPath),
15
- { recursive: true }
16
- );
17
- fs.writeFileSync(privateKeyPath, privateKey, "utf8");
18
- fs.writeFileSync(publicKeyPath, publicKey, "utf8");
19
- }
20
4
  function loadPrivateKey(keyPath) {
21
- const resolvedPath = keyPath ?? path.resolve(
22
- process.cwd(),
23
- "trust",
24
- "root.key"
25
- );
26
- const publicPath = resolvedPath.replace(/root\.key$/, "root.pub");
27
- ensureTrustKeys(resolvedPath, publicPath);
28
- return fs.readFileSync(
29
- resolvedPath,
30
- "utf8"
31
- );
5
+ const resolved = path.resolve(keyPath);
6
+ if (!fs.existsSync(resolved)) {
7
+ throw new Error(
8
+ `Trust key not found at ${resolved}. Provide an explicit key path or initialize trust keys using parmana workspace init.`
9
+ );
10
+ }
11
+ return fs.readFileSync(resolved, "utf8");
32
12
  }
33
13
  function loadPublicKey(keyPath) {
34
- const resolvedPath = keyPath ?? path.resolve(
35
- process.cwd(),
36
- "trust",
37
- "root.pub"
38
- );
39
- const privatePath = resolvedPath.replace(/root\.pub$/, "root.key");
40
- ensureTrustKeys(privatePath, resolvedPath);
41
- return fs.readFileSync(
42
- resolvedPath,
43
- "utf8"
44
- );
14
+ const resolved = path.resolve(keyPath);
15
+ if (!fs.existsSync(resolved)) {
16
+ throw new Error(
17
+ `Trust key not found at ${resolved}. Provide an explicit key path or initialize trust keys using parmana workspace init.`
18
+ );
19
+ }
20
+ return fs.readFileSync(resolved, "utf8");
45
21
  }
46
22
 
47
23
  // src/persist.ts
@@ -71,11 +47,11 @@ function readSignature(directory) {
71
47
 
72
48
  // src/sign.ts
73
49
  import * as fs3 from "fs";
74
- import * as crypto2 from "crypto";
50
+ import * as crypto from "crypto";
75
51
  import {
76
52
  canonicalize
77
53
  } from "@parmanasystems/bundle";
78
- function signManifest(manifestPath) {
54
+ function signManifest(manifestPath, privateKeyPath) {
79
55
  const manifest = JSON.parse(
80
56
  fs3.readFileSync(
81
57
  manifestPath,
@@ -85,8 +61,8 @@ function signManifest(manifestPath) {
85
61
  const canonical = canonicalize(
86
62
  manifest
87
63
  );
88
- const privateKey = loadPrivateKey();
89
- const signature = crypto2.sign(
64
+ const privateKey = loadPrivateKey(privateKeyPath);
65
+ const signature = crypto.sign(
90
66
  null,
91
67
  Buffer.from(
92
68
  canonical,
@@ -101,11 +77,11 @@ function signManifest(manifestPath) {
101
77
 
102
78
  // src/verify.ts
103
79
  import * as fs4 from "fs";
104
- import * as crypto3 from "crypto";
80
+ import * as crypto2 from "crypto";
105
81
  import {
106
82
  canonicalize as canonicalize2
107
83
  } from "@parmanasystems/bundle";
108
- function verifySignature(manifestPath, signature) {
84
+ function verifySignature(manifestPath, signature, publicKeyPath) {
109
85
  const manifest = JSON.parse(
110
86
  fs4.readFileSync(
111
87
  manifestPath,
@@ -115,8 +91,8 @@ function verifySignature(manifestPath, signature) {
115
91
  const canonical = canonicalize2(
116
92
  manifest
117
93
  );
118
- const publicKey = loadPublicKey();
119
- return crypto3.verify(
94
+ const publicKey = loadPublicKey(publicKeyPath);
95
+ return crypto2.verify(
120
96
  null,
121
97
  Buffer.from(
122
98
  canonical,
@@ -130,7 +106,7 @@ function verifySignature(manifestPath, signature) {
130
106
  );
131
107
  }
132
108
  function verifyPayloadSignature(payload, signature, publicKey) {
133
- return crypto3.verify(
109
+ return crypto2.verify(
134
110
  null,
135
111
  Buffer.from(
136
112
  payload,
@@ -145,10 +121,10 @@ function verifyPayloadSignature(payload, signature, publicKey) {
145
121
  }
146
122
 
147
123
  // src/verify-manifest-signature.ts
148
- import * as crypto4 from "crypto";
149
- function verifyManifestSignature(manifest, signature) {
150
- const publicKey = loadPublicKey();
151
- return crypto4.verify(
124
+ import * as crypto3 from "crypto";
125
+ function verifyManifestSignature(manifest, signature, publicKeyPath) {
126
+ const publicKey = loadPublicKey(publicKeyPath);
127
+ return crypto3.verify(
152
128
  null,
153
129
  Buffer.from(
154
130
  manifest
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/keys.ts","../src/persist.ts","../src/sign.ts","../src/verify.ts","../src/verify-manifest-signature.ts","../src/sign-bundle.ts"],"sourcesContent":["import * as crypto from \"node:crypto\";\r\nimport * as fs from \"node:fs\";\r\nimport * as path from \"node:path\";\r\n\r\nfunction ensureTrustKeys(\r\n privateKeyPath: string,\r\n publicKeyPath: string\r\n): void {\r\n if (\r\n fs.existsSync(privateKeyPath) &&\r\n fs.existsSync(publicKeyPath)\r\n ) {\r\n return;\r\n }\r\n\r\n const { privateKey, publicKey } =\r\n crypto.generateKeyPairSync(\"ed25519\", {\r\n privateKeyEncoding: { type: \"pkcs8\", format: \"pem\" },\r\n publicKeyEncoding: { type: \"spki\", format: \"pem\" },\r\n });\r\n\r\n fs.mkdirSync(\r\n path.dirname(privateKeyPath),\r\n { recursive: true }\r\n );\r\n\r\n fs.writeFileSync(privateKeyPath, privateKey, \"utf8\");\r\n fs.writeFileSync(publicKeyPath, publicKey, \"utf8\");\r\n}\r\n\r\n/**\r\n * Reads the root trust private key PEM.\r\n * Auto-generates a dev keypair at the default location if neither key file exists.\r\n *\r\n * @param keyPath - explicit path to the private key file; defaults to ./trust/root.key\r\n */\r\nexport function loadPrivateKey(keyPath?: string): string {\r\n\r\n const resolvedPath =\r\n keyPath ??\r\n path.resolve(\r\n process.cwd(),\r\n \"trust\",\r\n \"root.key\"\r\n );\r\n\r\n const publicPath =\r\n resolvedPath.replace(/root\\.key$/, \"root.pub\");\r\n\r\n ensureTrustKeys(resolvedPath, publicPath);\r\n\r\n return fs.readFileSync(\r\n resolvedPath,\r\n \"utf8\"\r\n );\r\n}\r\n\r\n/**\r\n * Reads the root trust public key PEM.\r\n * Auto-generates a dev keypair at the default location if neither key file exists.\r\n *\r\n * @param keyPath - explicit path to the public key file; defaults to ./trust/root.pub\r\n */\r\nexport function loadPublicKey(keyPath?: string): string {\r\n\r\n const resolvedPath =\r\n keyPath ??\r\n path.resolve(\r\n process.cwd(),\r\n \"trust\",\r\n \"root.pub\"\r\n );\r\n\r\n const privatePath =\r\n resolvedPath.replace(/root\\.pub$/, \"root.key\");\r\n\r\n ensureTrustKeys(privatePath, resolvedPath);\r\n\r\n return fs.readFileSync(\r\n resolvedPath,\r\n \"utf8\"\r\n );\r\n}\r\n","import * as fs from \"node:fs\";\r\nimport * as path from \"node:path\";\r\n\r\n/**\r\n * Writes a base64 signature string to `<directory>/bundle.sig`.\r\n * Overwrites any existing file at that path.\r\n */\r\nexport function writeSignature(\r\n signature: string,\r\n directory: string\r\n): void {\r\n const signaturePath = path.join(\r\n directory,\r\n \"bundle.sig\"\r\n );\r\n\r\n fs.writeFileSync(\r\n signaturePath,\r\n signature,\r\n \"utf8\"\r\n );\r\n}\r\n\r\n/** Reads and returns the raw base64 signature from `<directory>/bundle.sig`. */\r\nexport function readSignature(\r\n directory: string\r\n): string {\r\n const signaturePath = path.join(\r\n directory,\r\n \"bundle.sig\"\r\n );\r\n\r\n return fs.readFileSync(\r\n signaturePath,\r\n \"utf8\"\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import * as fs from \"node:fs\";\r\n\r\nimport * as crypto from \"node:crypto\";\r\nimport {\r\n canonicalize,\r\n} from \"@parmanasystems/bundle\";\r\n\r\nimport {\r\n loadPrivateKey,\r\n} from \"./keys.js\";\r\n\r\n/**\r\n * Reads the manifest JSON at `manifestPath`, canonicalizes it, and returns a\r\n * base64-encoded Ed25519 signature produced with the dev private key.\r\n *\r\n * @param manifestPath - Absolute or CWD-relative path to a `bundle.manifest.json` file.\r\n * @returns Base64-encoded Ed25519 signature over the canonical manifest bytes.\r\n */\r\nexport function signManifest(\r\n manifestPath: string\r\n): string {\r\n\r\n const manifest =\r\n JSON.parse(\r\n fs.readFileSync(\r\n manifestPath,\r\n \"utf8\"\r\n )\r\n );\r\n\r\n const canonical =\r\n canonicalize(\r\n manifest\r\n );\r\n\r\n const privateKey =\r\n loadPrivateKey();\r\n\r\n const signature =\r\n crypto.sign(\r\n null,\r\n\r\n Buffer.from(\r\n canonical,\r\n \"utf8\"\r\n ),\r\n\r\n privateKey\r\n );\r\n\r\n return signature.toString(\r\n \"base64\"\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import * as fs from \"node:fs\";\r\n\r\nimport * as crypto from \"node:crypto\";\r\n\r\nimport {\r\n canonicalize,\r\n} from \"@parmanasystems/bundle\";\r\n\r\nimport {\r\n loadPublicKey,\r\n} from \"./keys.js\";\r\n\r\n/**\r\n * Reads the manifest JSON at `manifestPath`, canonicalizes it, and verifies\r\n * `signature` (base64 Ed25519) against the dev public key.\r\n *\r\n * @param manifestPath - Path to the `bundle.manifest.json` file.\r\n * @param signature - Base64-encoded Ed25519 signature to verify.\r\n */\r\nexport function verifySignature(\r\n manifestPath: string,\r\n signature: string\r\n): boolean {\r\n\r\n const manifest =\r\n JSON.parse(\r\n fs.readFileSync(\r\n manifestPath,\r\n \"utf8\"\r\n )\r\n );\r\n\r\n const canonical =\r\n canonicalize(\r\n manifest\r\n );\r\n\r\n const publicKey =\r\n loadPublicKey();\r\n\r\n return crypto.verify(\r\n null,\r\n\r\n Buffer.from(\r\n canonical,\r\n \"utf8\"\r\n ),\r\n\r\n publicKey,\r\n\r\n Buffer.from(\r\n signature,\r\n \"base64\"\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * Verifies a base64-encoded Ed25519 `signature` over an arbitrary UTF-8\r\n * `payload` using the provided `publicKey` PEM. Unlike `verifySignature`,\r\n * this function accepts any payload string rather than reading a manifest\r\n * file from disk.\r\n *\r\n * @param payload - The original signed UTF-8 string.\r\n * @param signature - Base64-encoded Ed25519 signature.\r\n * @param publicKey - PEM-encoded Ed25519 public key.\r\n */\r\nexport function verifyPayloadSignature(\r\n payload: string,\r\n signature: string,\r\n publicKey: string\r\n): boolean {\r\n\r\n return crypto.verify(\r\n null,\r\n\r\n Buffer.from(\r\n payload,\r\n \"utf8\"\r\n ),\r\n\r\n publicKey,\r\n\r\n Buffer.from(\r\n signature,\r\n \"base64\"\r\n )\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import * as crypto from \"node:crypto\";\r\n\r\nimport {\r\n loadPublicKey,\r\n} from \"./keys.js\";\r\n\r\n/**\r\n * Verifies `signature` (base64 Ed25519) over the already-serialized canonical\r\n * `manifest` string against the dev public key.\r\n *\r\n * Unlike `verifySignature`, this function accepts the manifest bytes directly\r\n * rather than reading them from disk — suited for in-memory verification flows.\r\n *\r\n * @param manifest - Canonical manifest bytes (UTF-8 string).\r\n * @param signature - Base64-encoded Ed25519 signature.\r\n */\r\nexport function verifyManifestSignature(\r\n manifest: string,\r\n signature: string\r\n): boolean {\r\n\r\n const publicKey =\r\n loadPublicKey();\r\n\r\n return crypto.verify(\r\n null,\r\n\r\n Buffer.from(\r\n manifest\r\n ),\r\n\r\n publicKey,\r\n\r\n Buffer.from(\r\n signature,\r\n \"base64\"\r\n )\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\n\r\n// ----------------------------------\r\n// Local deterministic canonicalize\r\n// ----------------------------------\r\n\r\nfunction canonicalize(\r\n value: unknown\r\n): string {\r\n\r\n if (\r\n value === null ||\r\n typeof value !== \"object\"\r\n ) {\r\n return JSON.stringify(value);\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return `[${value\r\n .map(canonicalize)\r\n .join(\",\")}]`;\r\n }\r\n\r\n const entries =\r\n Object.entries(\r\n value as Record<string, unknown>\r\n )\r\n .sort(([a], [b]) =>\r\n a.localeCompare(b)\r\n );\r\n\r\n return `{${entries\r\n .map(\r\n ([key, val]) =>\r\n `${JSON.stringify(key)}:${canonicalize(val)}`\r\n )\r\n .join(\",\")}}`;\r\n}\r\n\r\ntype SignBundleOptions = {\r\n\r\n bundlePath: string;\r\n\r\n signer: {\r\n\r\n sign(\r\n payload: string\r\n ): Promise<string>;\r\n };\r\n};\r\n\r\nexport async function signBundle(\r\n options: SignBundleOptions\r\n): Promise<void> {\r\n\r\n const manifestPath =\r\n path.join(\r\n options.bundlePath,\r\n \"bundle.manifest.json\"\r\n );\r\n\r\n const manifest =\r\n JSON.parse(\r\n fs.readFileSync(\r\n manifestPath,\r\n \"utf8\"\r\n )\r\n );\r\n\r\n const canonical =\r\n canonicalize(manifest);\r\n\r\n const signature =\r\n await options.signer.sign(\r\n canonical\r\n );\r\n\r\n fs.writeFileSync(\r\n\r\n path.join(\r\n options.bundlePath,\r\n \"bundle.sig\"\r\n ),\r\n\r\n signature\r\n );\r\n}\r\n"],"mappings":"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","names":["fs","path","fs","crypto","fs","crypto","canonicalize","canonicalize","crypto","fs","path","canonicalize"]}
1
+ {"version":3,"sources":["../src/keys.ts","../src/persist.ts","../src/sign.ts","../src/verify.ts","../src/verify-manifest-signature.ts","../src/sign-bundle.ts"],"sourcesContent":["import * as fs from \"node:fs\";\n\nimport * as path from \"node:path\";\n\n/**\n * Reads the root trust private key PEM from an explicit file path.\n * Throws clearly if the file does not exist — never auto-generates keys.\n *\n * @param keyPath - Absolute or CWD-relative path to the private key PEM file.\n */\nexport function loadPrivateKey(keyPath: string): string {\n\n const resolved = path.resolve(keyPath);\n\n if (!fs.existsSync(resolved)) {\n throw new Error(\n `Trust key not found at ${resolved}. ` +\n `Provide an explicit key path or initialize trust keys ` +\n `using parmana workspace init.`\n );\n }\n\n return fs.readFileSync(resolved, \"utf8\");\n}\n\n/**\n * Reads the root trust public key PEM from an explicit file path.\n * Throws clearly if the file does not exist — never auto-generates keys.\n *\n * @param keyPath - Absolute or CWD-relative path to the public key PEM file.\n */\nexport function loadPublicKey(keyPath: string): string {\n\n const resolved = path.resolve(keyPath);\n\n if (!fs.existsSync(resolved)) {\n throw new Error(\n `Trust key not found at ${resolved}. ` +\n `Provide an explicit key path or initialize trust keys ` +\n `using parmana workspace init.`\n );\n }\n\n return fs.readFileSync(resolved, \"utf8\");\n}\n","import * as fs from \"node:fs\";\r\nimport * as path from \"node:path\";\r\n\r\n/**\r\n * Writes a base64 signature string to `<directory>/bundle.sig`.\r\n * Overwrites any existing file at that path.\r\n */\r\nexport function writeSignature(\r\n signature: string,\r\n directory: string\r\n): void {\r\n const signaturePath = path.join(\r\n directory,\r\n \"bundle.sig\"\r\n );\r\n\r\n fs.writeFileSync(\r\n signaturePath,\r\n signature,\r\n \"utf8\"\r\n );\r\n}\r\n\r\n/** Reads and returns the raw base64 signature from `<directory>/bundle.sig`. */\r\nexport function readSignature(\r\n directory: string\r\n): string {\r\n const signaturePath = path.join(\r\n directory,\r\n \"bundle.sig\"\r\n );\r\n\r\n return fs.readFileSync(\r\n signaturePath,\r\n \"utf8\"\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import * as fs from \"node:fs\";\r\n\r\nimport * as crypto from \"node:crypto\";\r\nimport {\r\n canonicalize,\r\n} from \"@parmanasystems/bundle\";\r\n\r\nimport {\r\n loadPrivateKey,\r\n} from \"./keys.js\";\r\n\r\n/**\r\n * Reads the manifest JSON at `manifestPath`, canonicalizes it, and returns a\r\n * base64-encoded Ed25519 signature produced with the private key at `privateKeyPath`.\r\n *\r\n * @param manifestPath - Absolute or CWD-relative path to a `bundle.manifest.json` file.\r\n * @param privateKeyPath - Explicit path to the PEM-encoded Ed25519 private key.\r\n * @returns Base64-encoded Ed25519 signature over the canonical manifest bytes.\r\n */\r\nexport function signManifest(\r\n manifestPath: string,\r\n privateKeyPath: string\r\n): string {\r\n\r\n const manifest =\r\n JSON.parse(\r\n fs.readFileSync(\r\n manifestPath,\r\n \"utf8\"\r\n )\r\n );\r\n\r\n const canonical =\r\n canonicalize(\r\n manifest\r\n );\r\n\r\n const privateKey =\r\n loadPrivateKey(privateKeyPath);\r\n\r\n const signature =\r\n crypto.sign(\r\n null,\r\n\r\n Buffer.from(\r\n canonical,\r\n \"utf8\"\r\n ),\r\n\r\n privateKey\r\n );\r\n\r\n return signature.toString(\r\n \"base64\"\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import * as fs from \"node:fs\";\r\n\r\nimport * as crypto from \"node:crypto\";\r\n\r\nimport {\r\n canonicalize,\r\n} from \"@parmanasystems/bundle\";\r\n\r\nimport {\r\n loadPublicKey,\r\n} from \"./keys.js\";\r\n\r\n/**\r\n * Reads the manifest JSON at `manifestPath`, canonicalizes it, and verifies\r\n * `signature` (base64 Ed25519) against the public key at `publicKeyPath`.\r\n *\r\n * @param manifestPath - Path to the `bundle.manifest.json` file.\r\n * @param signature - Base64-encoded Ed25519 signature to verify.\r\n * @param publicKeyPath - Explicit path to the PEM-encoded Ed25519 public key.\r\n */\r\nexport function verifySignature(\r\n manifestPath: string,\r\n signature: string,\r\n publicKeyPath: string\r\n): boolean {\r\n\r\n const manifest =\r\n JSON.parse(\r\n fs.readFileSync(\r\n manifestPath,\r\n \"utf8\"\r\n )\r\n );\r\n\r\n const canonical =\r\n canonicalize(\r\n manifest\r\n );\r\n\r\n const publicKey =\r\n loadPublicKey(publicKeyPath);\r\n\r\n return crypto.verify(\r\n null,\r\n\r\n Buffer.from(\r\n canonical,\r\n \"utf8\"\r\n ),\r\n\r\n publicKey,\r\n\r\n Buffer.from(\r\n signature,\r\n \"base64\"\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * Verifies a base64-encoded Ed25519 `signature` over an arbitrary UTF-8\r\n * `payload` using the provided `publicKey` PEM. Unlike `verifySignature`,\r\n * this function accepts any payload string rather than reading a manifest\r\n * file from disk.\r\n *\r\n * @param payload - The original signed UTF-8 string.\r\n * @param signature - Base64-encoded Ed25519 signature.\r\n * @param publicKey - PEM-encoded Ed25519 public key.\r\n */\r\nexport function verifyPayloadSignature(\r\n payload: string,\r\n signature: string,\r\n publicKey: string\r\n): boolean {\r\n\r\n return crypto.verify(\r\n null,\r\n\r\n Buffer.from(\r\n payload,\r\n \"utf8\"\r\n ),\r\n\r\n publicKey,\r\n\r\n Buffer.from(\r\n signature,\r\n \"base64\"\r\n )\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import * as crypto from \"node:crypto\";\r\n\r\nimport {\r\n loadPublicKey,\r\n} from \"./keys.js\";\r\n\r\n/**\r\n * Verifies `signature` (base64 Ed25519) over the already-serialized canonical\r\n * `manifest` string against the public key at `publicKeyPath`.\r\n *\r\n * Unlike `verifySignature`, this function accepts the manifest bytes directly\r\n * rather than reading them from disk — suited for in-memory verification flows.\r\n *\r\n * @param manifest - Canonical manifest bytes (UTF-8 string).\r\n * @param signature - Base64-encoded Ed25519 signature.\r\n * @param publicKeyPath - Explicit path to the PEM-encoded Ed25519 public key.\r\n */\r\nexport function verifyManifestSignature(\r\n manifest: string,\r\n signature: string,\r\n publicKeyPath: string\r\n): boolean {\r\n\r\n const publicKey =\r\n loadPublicKey(publicKeyPath);\r\n\r\n return crypto.verify(\r\n null,\r\n\r\n Buffer.from(\r\n manifest\r\n ),\r\n\r\n publicKey,\r\n\r\n Buffer.from(\r\n signature,\r\n \"base64\"\r\n )\r\n );\r\n}\r\n\r\n\r\n\r\n\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\n\r\n// ----------------------------------\r\n// Local deterministic canonicalize\r\n// ----------------------------------\r\n\r\nfunction canonicalize(\r\n value: unknown\r\n): string {\r\n\r\n if (\r\n value === null ||\r\n typeof value !== \"object\"\r\n ) {\r\n return JSON.stringify(value);\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return `[${value\r\n .map(canonicalize)\r\n .join(\",\")}]`;\r\n }\r\n\r\n const entries =\r\n Object.entries(\r\n value as Record<string, unknown>\r\n )\r\n .sort(([a], [b]) =>\r\n a.localeCompare(b)\r\n );\r\n\r\n return `{${entries\r\n .map(\r\n ([key, val]) =>\r\n `${JSON.stringify(key)}:${canonicalize(val)}`\r\n )\r\n .join(\",\")}}`;\r\n}\r\n\r\ntype SignBundleOptions = {\r\n\r\n bundlePath: string;\r\n\r\n signer: {\r\n\r\n sign(\r\n payload: string\r\n ): Promise<string>;\r\n };\r\n};\r\n\r\nexport async function signBundle(\r\n options: SignBundleOptions\r\n): Promise<void> {\r\n\r\n const manifestPath =\r\n path.join(\r\n options.bundlePath,\r\n \"bundle.manifest.json\"\r\n );\r\n\r\n const manifest =\r\n JSON.parse(\r\n fs.readFileSync(\r\n manifestPath,\r\n \"utf8\"\r\n )\r\n );\r\n\r\n const canonical =\r\n canonicalize(manifest);\r\n\r\n const signature =\r\n await options.signer.sign(\r\n canonical\r\n );\r\n\r\n fs.writeFileSync(\r\n\r\n path.join(\r\n options.bundlePath,\r\n \"bundle.sig\"\r\n ),\r\n\r\n signature\r\n );\r\n}\r\n"],"mappings":"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","names":["fs","path","fs","fs","crypto","canonicalize","canonicalize","crypto","fs","path","canonicalize"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parmanasystems/crypto",
3
- "version": "1.71.9",
3
+ "version": "1.71.12",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -18,7 +18,7 @@
18
18
  ],
19
19
  "sideEffects": false,
20
20
  "dependencies": {
21
- "@parmanasystems/bundle": "^1.71.9"
21
+ "@parmanasystems/bundle": "^1.71.12"
22
22
  },
23
23
  "description": "Signing and verification primitives for deterministic governance infrastructure.",
24
24
  "license": "Apache-2.0",