@ternent/seal-cli 0.1.8 → 0.3.0

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/cli.js CHANGED
@@ -3,9 +3,9 @@ import { resolve, basename, join, relative, dirname } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { createSealHash, createSealProof, createSealPublicKeyArtifact, parseSealProofJson, verifySealProofAgainstBytes } from "./proof.js";
5
5
  import { SEAL_MANIFEST_VERSION, SEAL_MANIFEST_TYPE, stringifySealManifest, parseSealManifestJson } from "./manifest.js";
6
+ import { p as parseIdentity } from "./chunks/crypto-38954ec7.js";
6
7
  import { EXIT_SUCCESS, EXIT_HASH_MISMATCH, EXIT_SIGNATURE_INVALID, SealCliError, EXIT_FAILURE, EXIT_INVALID_PROOF, EXIT_KEY_CONFIG, getExitCode } from "./errors.js";
7
- import "./chunks/utils.es-586f669f.js";
8
- import "./crypto.js";
8
+ import "./chunks/utils.es-7e2ade90.js";
9
9
  function normalizeRelativePath(value) {
10
10
  return value.split("\\").join("/");
11
11
  }
@@ -59,8 +59,7 @@ async function createProofArtifact(params) {
59
59
  const parsedManifest = parseSealManifestJson(raw);
60
60
  const proof = await createSealProof({
61
61
  signer: {
62
- privateKeyPem: params.privateKeyPem,
63
- publicKeyPem: params.publicKeyPem
62
+ identity: params.identity
64
63
  },
65
64
  subject: {
66
65
  kind: parsedManifest.ok ? "manifest" : "file",
@@ -75,10 +74,7 @@ async function createProofArtifact(params) {
75
74
  };
76
75
  }
77
76
  async function createPublicKeyArtifact(params) {
78
- return createSealPublicKeyArtifact({
79
- privateKeyPem: params.privateKeyPem,
80
- publicKeyPem: params.publicKeyPem
81
- });
77
+ return createSealPublicKeyArtifact(params);
82
78
  }
83
79
  async function verifyProofArtifact(params) {
84
80
  const rawProof = await readFile(params.proofPath, "utf8");
@@ -93,6 +89,19 @@ async function verifyProofArtifact(params) {
93
89
  result
94
90
  };
95
91
  }
92
+ async function resolveSealIdentityFromEnv(env) {
93
+ const identityJson = String(env.SEAL_IDENTITY || "").trim();
94
+ if (identityJson) {
95
+ return parseIdentity(identityJson);
96
+ }
97
+ const identityFile = String(env.SEAL_IDENTITY_FILE || "").trim();
98
+ if (identityFile) {
99
+ return parseIdentity(await readFile(identityFile, "utf8"));
100
+ }
101
+ throw new Error(
102
+ "Missing SEAL_IDENTITY or SEAL_IDENTITY_FILE environment variable."
103
+ );
104
+ }
96
105
  function parseArgs(argv) {
97
106
  const result = { _: [], flags: {} };
98
107
  for (let index = 0; index < argv.length; index += 1) {
@@ -144,10 +153,6 @@ function requireFlag(flags, key) {
144
153
  }
145
154
  return value;
146
155
  }
147
- function getEnvVar(env, name) {
148
- const value = env[name];
149
- return value && value.trim().length > 0 ? value : void 0;
150
- }
151
156
  async function writeOutputFile(filePath, content) {
152
157
  const resolvedPath = resolve(filePath);
153
158
  await mkdir(dirname(resolvedPath), { recursive: true });
@@ -184,19 +189,6 @@ function outputError(writer, json, error) {
184
189
  }
185
190
  return exitCode;
186
191
  }
187
- function readSigningEnv(env) {
188
- const privateKeyPem = getEnvVar(env, "SEAL_PRIVATE_KEY");
189
- if (!privateKeyPem) {
190
- throw new SealCliError(
191
- "Missing SEAL_PRIVATE_KEY environment variable.",
192
- EXIT_KEY_CONFIG
193
- );
194
- }
195
- return {
196
- privateKeyPem,
197
- publicKeyPem: getEnvVar(env, "SEAL_PUBLIC_KEY")
198
- };
199
- }
200
192
  async function runCli(argv, params = {}) {
201
193
  const parsed = parseArgs(argv);
202
194
  const env = params.env ?? process.env;
@@ -220,10 +212,10 @@ async function runCli(argv, params = {}) {
220
212
  return EXIT_SUCCESS;
221
213
  }
222
214
  if (command === "sign") {
223
- const signingEnv = readSigningEnv(env);
215
+ const identity = await resolveSealIdentityFromEnv(env);
224
216
  const artifact = await createProofArtifact({
225
217
  inputPath: requireFlag(parsed.flags, "input"),
226
- ...signingEnv
218
+ identity
227
219
  });
228
220
  const outPath = getFlag(parsed.flags, "out");
229
221
  if (outPath) {
@@ -260,7 +252,9 @@ async function runCli(argv, params = {}) {
260
252
  return EXIT_SUCCESS;
261
253
  }
262
254
  if (command === "public-key") {
263
- const artifact = await createPublicKeyArtifact(readSigningEnv(env));
255
+ const artifact = await createPublicKeyArtifact({
256
+ identity: await resolveSealIdentityFromEnv(env)
257
+ });
264
258
  outputResult(writer, true, quiet, artifact);
265
259
  return EXIT_SUCCESS;
266
260
  }
@@ -276,7 +270,7 @@ async function runCli(argv, params = {}) {
276
270
  new SealCliError(error.message, EXIT_INVALID_PROOF)
277
271
  );
278
272
  }
279
- if (error instanceof Error && (error.message.includes("public key") || error.message.includes("SEAL_PRIVATE_KEY") || error.message.includes("private key"))) {
273
+ if (error instanceof Error && (error.message.includes("public key") || error.message.includes("SEAL_IDENTITY") || error.message.includes("identity"))) {
280
274
  return outputError(
281
275
  writer,
282
276
  json,
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/commands/manifest.ts","../src/commands/sign.ts","../src/commands/publicKey.ts","../src/commands/verify.ts","../src/cli.ts"],"sourcesContent":["import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, join, relative, resolve } from \"node:path\";\nimport { createSealHash } from \"../proof\";\nimport {\n SEAL_MANIFEST_TYPE,\n SEAL_MANIFEST_VERSION,\n stringifySealManifest,\n type SealManifestV1,\n} from \"../manifest\";\n\nfunction normalizeRelativePath(value: string): string {\n return value.split(\"\\\\\").join(\"/\");\n}\n\nasync function collectFiles(\n rootPath: string,\n currentPath: string,\n files: Record<string, SealManifestV1[\"files\"][string]>\n): Promise<void> {\n const entries = await readdir(currentPath, { withFileTypes: true });\n const sorted = entries\n .filter((entry) => entry.name !== \".DS_Store\")\n .sort((a, b) => a.name.localeCompare(b.name));\n\n for (const entry of sorted) {\n const entryPath = join(currentPath, entry.name);\n if (entry.isDirectory()) {\n await collectFiles(rootPath, entryPath, files);\n continue;\n }\n if (!entry.isFile()) {\n continue;\n }\n const bytes = await readFile(entryPath);\n const relativePath = normalizeRelativePath(relative(rootPath, entryPath));\n files[relativePath] = await createSealHash(bytes);\n }\n}\n\nexport async function createManifestArtifact(inputPath: string): Promise<{\n manifest: SealManifestV1;\n content: string;\n}> {\n const resolvedInput = resolve(inputPath);\n const inputStat = await stat(resolvedInput);\n const root = basename(resolvedInput);\n const files: SealManifestV1[\"files\"] = {};\n\n if (inputStat.isDirectory()) {\n await collectFiles(resolvedInput, resolvedInput, files);\n } else if (inputStat.isFile()) {\n const bytes = await readFile(resolvedInput);\n files[root] = await createSealHash(bytes);\n } else {\n throw new Error(\"Manifest input must be a file or directory.\");\n }\n\n const manifest: SealManifestV1 = {\n version: SEAL_MANIFEST_VERSION,\n type: SEAL_MANIFEST_TYPE,\n root,\n files: Object.fromEntries(\n Object.entries(files).sort(([left], [right]) => left.localeCompare(right))\n ),\n };\n\n return {\n manifest,\n content: `${stringifySealManifest(manifest)}\\n`,\n };\n}\n","import { basename } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { parseSealManifestJson } from \"../manifest\";\nimport { createSealProof, createSealHash, type SealProofV1 } from \"../proof\";\n\nexport async function createProofArtifact(params: {\n inputPath: string;\n privateKeyPem: string;\n publicKeyPem?: string;\n}): Promise<{\n proof: SealProofV1;\n content: string;\n}> {\n const bytes = await readFile(params.inputPath);\n const raw = new TextDecoder().decode(bytes);\n const parsedManifest = parseSealManifestJson(raw);\n const proof = await createSealProof({\n signer: {\n privateKeyPem: params.privateKeyPem,\n publicKeyPem: params.publicKeyPem,\n },\n subject: {\n kind: parsedManifest.ok ? \"manifest\" : \"file\",\n path: basename(params.inputPath),\n hash: await createSealHash(bytes),\n },\n });\n\n return {\n proof,\n content: `${JSON.stringify(proof, null, 2)}\\n`,\n };\n}\n","import { createSealPublicKeyArtifact } from \"../proof\";\n\nexport async function createPublicKeyArtifact(params: {\n privateKeyPem: string;\n publicKeyPem?: string;\n}) {\n return createSealPublicKeyArtifact({\n privateKeyPem: params.privateKeyPem,\n publicKeyPem: params.publicKeyPem,\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport {\n parseSealProofJson,\n verifySealProofAgainstBytes,\n type SealProofV1,\n} from \"../proof\";\n\nexport type VerifyArtifactResult = {\n valid: boolean;\n hashMatch: boolean;\n signatureValid: boolean;\n keyId: string;\n algorithm: \"ECDSA-P256-SHA256\";\n subjectHash: `sha256:${string}`;\n};\n\nexport async function verifyProofArtifact(params: {\n proofPath: string;\n inputPath: string;\n}): Promise<{\n proof: SealProofV1;\n result: VerifyArtifactResult;\n}> {\n const rawProof = await readFile(params.proofPath, \"utf8\");\n const parsed = parseSealProofJson(rawProof);\n if (!parsed.ok || !parsed.proof) {\n throw new Error(parsed.errors.join(\" \"));\n }\n\n const subjectBytes = await readFile(params.inputPath);\n const result = await verifySealProofAgainstBytes(parsed.proof, subjectBytes);\n return {\n proof: parsed.proof,\n result,\n };\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createManifestArtifact } from \"./commands/manifest\";\nimport { createProofArtifact } from \"./commands/sign\";\nimport { createPublicKeyArtifact } from \"./commands/publicKey\";\nimport { verifyProofArtifact } from \"./commands/verify\";\nimport {\n EXIT_FAILURE,\n EXIT_HASH_MISMATCH,\n EXIT_INVALID_PROOF,\n EXIT_KEY_CONFIG,\n EXIT_SIGNATURE_INVALID,\n EXIT_SUCCESS,\n SealCliError,\n getExitCode,\n} from \"./errors\";\n\ntype ProcessEnvLike = Record<string, string | undefined>;\n\ndeclare const process: {\n argv: string[];\n env: ProcessEnvLike;\n stdout: { write: (value: string) => void };\n stderr: { write: (value: string) => void };\n exitCode?: number;\n};\n\ntype ParsedArgs = {\n _: string[];\n flags: Record<string, string | boolean | string[]>;\n};\n\ntype OutputWriter = {\n stdout: (value: string) => void;\n stderr: (value: string) => void;\n};\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const result: ParsedArgs = { _: [], flags: {} };\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (!arg.startsWith(\"--\")) {\n result._.push(arg);\n continue;\n }\n\n const [rawKey, inlineValue] = arg.slice(2).split(\"=\");\n const key = rawKey.trim();\n const next = argv[index + 1];\n const hasNextValue = inlineValue === undefined && next && !next.startsWith(\"--\");\n const value = inlineValue ?? (hasNextValue ? next : undefined);\n\n if (hasNextValue) {\n index += 1;\n }\n\n if (value === undefined) {\n result.flags[key] = true;\n continue;\n }\n\n const existing = result.flags[key];\n if (existing === undefined) {\n result.flags[key] = value;\n continue;\n }\n\n if (Array.isArray(existing)) {\n existing.push(value);\n result.flags[key] = existing;\n continue;\n }\n\n result.flags[key] = [String(existing), value];\n }\n\n return result;\n}\n\nfunction getFlag(flags: ParsedArgs[\"flags\"], key: string): string | undefined {\n const value = flags[key];\n if (Array.isArray(value)) {\n return value[value.length - 1];\n }\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction hasFlag(flags: ParsedArgs[\"flags\"], key: string): boolean {\n return flags[key] === true;\n}\n\nfunction requireFlag(flags: ParsedArgs[\"flags\"], key: string): string {\n const value = getFlag(flags, key);\n if (!value) {\n throw new SealCliError(`Missing --${key}`, EXIT_FAILURE);\n }\n return value;\n}\n\nfunction getEnvVar(env: ProcessEnvLike, name: string): string | undefined {\n const value = env[name];\n return value && value.trim().length > 0 ? value : undefined;\n}\n\nasync function writeOutputFile(filePath: string, content: string): Promise<void> {\n const resolvedPath = resolve(filePath);\n await mkdir(dirname(resolvedPath), { recursive: true });\n await writeFile(resolvedPath, content, \"utf8\");\n}\n\nfunction outputResult(\n writer: OutputWriter,\n json: boolean,\n quiet: boolean,\n value: unknown\n): void {\n if (quiet) {\n return;\n }\n\n if (typeof value === \"string\") {\n writer.stdout(`${value}\\n`);\n return;\n }\n\n if (json) {\n writer.stdout(`${JSON.stringify(value, null, 2)}\\n`);\n return;\n }\n\n writer.stdout(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction outputError(\n writer: OutputWriter,\n json: boolean,\n error: unknown\n): number {\n const exitCode = getExitCode(error);\n const message = error instanceof Error ? error.message : String(error);\n if (json) {\n writer.stderr(\n `${JSON.stringify({ error: message, exitCode }, null, 2)}\\n`\n );\n } else {\n writer.stderr(`${message}\\n`);\n }\n return exitCode;\n}\n\nfunction readSigningEnv(env: ProcessEnvLike): {\n privateKeyPem: string;\n publicKeyPem?: string;\n} {\n const privateKeyPem = getEnvVar(env, \"SEAL_PRIVATE_KEY\");\n if (!privateKeyPem) {\n throw new SealCliError(\n \"Missing SEAL_PRIVATE_KEY environment variable.\",\n EXIT_KEY_CONFIG\n );\n }\n\n return {\n privateKeyPem,\n publicKeyPem: getEnvVar(env, \"SEAL_PUBLIC_KEY\"),\n };\n}\n\nexport async function runCli(\n argv: string[],\n params: {\n env?: ProcessEnvLike;\n writer?: OutputWriter;\n } = {}\n): Promise<number> {\n const parsed = parseArgs(argv);\n const env = params.env ?? process.env;\n const writer: OutputWriter = params.writer ?? {\n stdout: (value) => process.stdout.write(value),\n stderr: (value) => process.stderr.write(value),\n };\n const json = hasFlag(parsed.flags, \"json\");\n const quiet = hasFlag(parsed.flags, \"quiet\");\n\n try {\n const [command, subcommand] = parsed._;\n\n if (command === \"manifest\" && subcommand === \"create\") {\n const artifact = await createManifestArtifact(requireFlag(parsed.flags, \"input\"));\n const outPath = getFlag(parsed.flags, \"out\");\n if (outPath) {\n await writeOutputFile(outPath, artifact.content);\n outputResult(writer, json, quiet, json ? artifact.manifest : outPath);\n } else {\n outputResult(writer, true, quiet, artifact.manifest);\n }\n return EXIT_SUCCESS;\n }\n\n if (command === \"sign\") {\n const signingEnv = readSigningEnv(env);\n const artifact = await createProofArtifact({\n inputPath: requireFlag(parsed.flags, \"input\"),\n ...signingEnv,\n });\n const outPath = getFlag(parsed.flags, \"out\");\n if (outPath) {\n await writeOutputFile(outPath, artifact.content);\n outputResult(writer, json, quiet, json ? artifact.proof : outPath);\n } else {\n outputResult(writer, true, quiet, artifact.proof);\n }\n return EXIT_SUCCESS;\n }\n\n if (command === \"verify\") {\n const proofPath = requireFlag(parsed.flags, \"proof\");\n const inputPath = requireFlag(parsed.flags, \"input\");\n const { result } = await verifyProofArtifact({ proofPath, inputPath });\n outputResult(\n writer,\n json,\n quiet,\n json\n ? result\n : [\n `valid=${result.valid}`,\n `hashMatch=${result.hashMatch}`,\n `signatureValid=${result.signatureValid}`,\n `keyId=${result.keyId}`,\n `algorithm=${result.algorithm}`,\n `subjectHash=${result.subjectHash}`,\n ].join(\"\\n\")\n );\n\n if (!result.hashMatch) {\n return EXIT_HASH_MISMATCH;\n }\n if (!result.signatureValid) {\n return EXIT_SIGNATURE_INVALID;\n }\n return EXIT_SUCCESS;\n }\n\n if (command === \"public-key\") {\n const artifact = await createPublicKeyArtifact(readSigningEnv(env));\n outputResult(writer, true, quiet, artifact);\n return EXIT_SUCCESS;\n }\n\n throw new SealCliError(\n \"Usage: seal manifest create --input <path> [--out <path>] [--json] [--quiet]\\n\" +\n \" seal sign --input <path> [--out <path>] [--json] [--quiet]\\n\" +\n \" seal verify --proof <proof.json> --input <path> [--json] [--quiet]\\n\" +\n \" seal public-key [--json] [--quiet]\",\n EXIT_FAILURE\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Proof\")) {\n return outputError(\n writer,\n json,\n new SealCliError(error.message, EXIT_INVALID_PROOF)\n );\n }\n if (\n error instanceof Error &&\n (error.message.includes(\"public key\") ||\n error.message.includes(\"SEAL_PRIVATE_KEY\") ||\n error.message.includes(\"private key\"))\n ) {\n return outputError(\n writer,\n json,\n new SealCliError(error.message, EXIT_KEY_CONFIG)\n );\n }\n return outputError(writer, json, error);\n }\n}\n\nconst isDirectRun =\n typeof process !== \"undefined\" &&\n process.argv[1] &&\n fileURLToPath(import.meta.url) === resolve(process.argv[1]);\n\nif (isDirectRun) {\n runCli(process.argv.slice(2)).then((exitCode) => {\n process.exitCode = exitCode;\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sources":["../src/commands/manifest.ts","../src/commands/sign.ts","../src/commands/publicKey.ts","../src/commands/verify.ts","../src/node.ts","../src/cli.ts"],"sourcesContent":["import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, join, relative, resolve } from \"node:path\";\nimport { createSealHash } from \"../proof\";\nimport {\n SEAL_MANIFEST_TYPE,\n SEAL_MANIFEST_VERSION,\n stringifySealManifest,\n type SealManifestV1,\n} from \"../manifest\";\n\nfunction normalizeRelativePath(value: string): string {\n return value.split(\"\\\\\").join(\"/\");\n}\n\nasync function collectFiles(\n rootPath: string,\n currentPath: string,\n files: Record<string, SealManifestV1[\"files\"][string]>\n): Promise<void> {\n const entries = await readdir(currentPath, { withFileTypes: true });\n const sorted = entries\n .filter((entry) => entry.name !== \".DS_Store\")\n .sort((a, b) => a.name.localeCompare(b.name));\n\n for (const entry of sorted) {\n const entryPath = join(currentPath, entry.name);\n if (entry.isDirectory()) {\n await collectFiles(rootPath, entryPath, files);\n continue;\n }\n if (!entry.isFile()) {\n continue;\n }\n const bytes = await readFile(entryPath);\n const relativePath = normalizeRelativePath(relative(rootPath, entryPath));\n files[relativePath] = await createSealHash(bytes);\n }\n}\n\nexport async function createManifestArtifact(inputPath: string): Promise<{\n manifest: SealManifestV1;\n content: string;\n}> {\n const resolvedInput = resolve(inputPath);\n const inputStat = await stat(resolvedInput);\n const root = basename(resolvedInput);\n const files: SealManifestV1[\"files\"] = {};\n\n if (inputStat.isDirectory()) {\n await collectFiles(resolvedInput, resolvedInput, files);\n } else if (inputStat.isFile()) {\n const bytes = await readFile(resolvedInput);\n files[root] = await createSealHash(bytes);\n } else {\n throw new Error(\"Manifest input must be a file or directory.\");\n }\n\n const manifest: SealManifestV1 = {\n version: SEAL_MANIFEST_VERSION,\n type: SEAL_MANIFEST_TYPE,\n root,\n files: Object.fromEntries(\n Object.entries(files).sort(([left], [right]) => left.localeCompare(right))\n ),\n };\n\n return {\n manifest,\n content: `${stringifySealManifest(manifest)}\\n`,\n };\n}\n","import { basename } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { parseSealManifestJson } from \"../manifest\";\nimport { createSealProof, createSealHash, type SealProofV1 } from \"../proof\";\n\nexport async function createProofArtifact(params: {\n inputPath: string;\n identity: import(\"@ternent/identity\").SerializedIdentity;\n}): Promise<{\n proof: SealProofV1;\n content: string;\n}> {\n const bytes = await readFile(params.inputPath);\n const raw = new TextDecoder().decode(bytes);\n const parsedManifest = parseSealManifestJson(raw);\n const proof = await createSealProof({\n signer: {\n identity: params.identity,\n },\n subject: {\n kind: parsedManifest.ok ? \"manifest\" : \"file\",\n path: basename(params.inputPath),\n hash: await createSealHash(bytes),\n },\n });\n\n return {\n proof,\n content: `${JSON.stringify(proof, null, 2)}\\n`,\n };\n}\n","import { createSealPublicKeyArtifact } from \"../proof\";\n\nexport async function createPublicKeyArtifact(params: {\n identity: import(\"@ternent/identity\").SerializedIdentity;\n}) {\n return createSealPublicKeyArtifact(params);\n}\n","import { readFile } from \"node:fs/promises\";\nimport {\n parseSealProofJson,\n verifySealProofAgainstBytes,\n type SealProofV1,\n} from \"../proof\";\n\nexport type VerifyArtifactResult = {\n valid: boolean;\n hashMatch: boolean;\n signatureValid: boolean;\n keyId: string;\n algorithm: \"Ed25519\";\n subjectHash: `sha256:${string}`;\n};\n\nexport async function verifyProofArtifact(params: {\n proofPath: string;\n inputPath: string;\n}): Promise<{\n proof: SealProofV1;\n result: VerifyArtifactResult;\n}> {\n const rawProof = await readFile(params.proofPath, \"utf8\");\n const parsed = parseSealProofJson(rawProof);\n if (!parsed.ok || !parsed.proof) {\n throw new Error(parsed.errors.join(\" \"));\n }\n\n const subjectBytes = await readFile(params.inputPath);\n const result = await verifySealProofAgainstBytes(parsed.proof, subjectBytes);\n return {\n proof: parsed.proof,\n result,\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { parseIdentity, type SerializedIdentity } from \"@ternent/identity\";\n\nexport async function resolveSealIdentityFromEnv(\n env: Record<string, string | undefined>\n): Promise<SerializedIdentity> {\n const identityJson = String(env.SEAL_IDENTITY || \"\").trim();\n if (identityJson) {\n return parseIdentity(identityJson);\n }\n\n const identityFile = String(env.SEAL_IDENTITY_FILE || \"\").trim();\n if (identityFile) {\n return parseIdentity(await readFile(identityFile, \"utf8\"));\n }\n\n throw new Error(\n \"Missing SEAL_IDENTITY or SEAL_IDENTITY_FILE environment variable.\"\n );\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createManifestArtifact } from \"./commands/manifest\";\nimport { createProofArtifact } from \"./commands/sign\";\nimport { createPublicKeyArtifact } from \"./commands/publicKey\";\nimport { verifyProofArtifact } from \"./commands/verify\";\nimport { resolveSealIdentityFromEnv } from \"./node\";\nimport {\n EXIT_FAILURE,\n EXIT_HASH_MISMATCH,\n EXIT_INVALID_PROOF,\n EXIT_KEY_CONFIG,\n EXIT_SIGNATURE_INVALID,\n EXIT_SUCCESS,\n SealCliError,\n getExitCode,\n} from \"./errors\";\n\ntype ProcessEnvLike = Record<string, string | undefined>;\n\ndeclare const process: {\n argv: string[];\n env: ProcessEnvLike;\n stdout: { write: (value: string) => void };\n stderr: { write: (value: string) => void };\n exitCode?: number;\n};\n\ntype ParsedArgs = {\n _: string[];\n flags: Record<string, string | boolean | string[]>;\n};\n\ntype OutputWriter = {\n stdout: (value: string) => void;\n stderr: (value: string) => void;\n};\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const result: ParsedArgs = { _: [], flags: {} };\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (!arg.startsWith(\"--\")) {\n result._.push(arg);\n continue;\n }\n\n const [rawKey, inlineValue] = arg.slice(2).split(\"=\");\n const key = rawKey.trim();\n const next = argv[index + 1];\n const hasNextValue = inlineValue === undefined && next && !next.startsWith(\"--\");\n const value = inlineValue ?? (hasNextValue ? next : undefined);\n\n if (hasNextValue) {\n index += 1;\n }\n\n if (value === undefined) {\n result.flags[key] = true;\n continue;\n }\n\n const existing = result.flags[key];\n if (existing === undefined) {\n result.flags[key] = value;\n continue;\n }\n\n if (Array.isArray(existing)) {\n existing.push(value);\n result.flags[key] = existing;\n continue;\n }\n\n result.flags[key] = [String(existing), value];\n }\n\n return result;\n}\n\nfunction getFlag(flags: ParsedArgs[\"flags\"], key: string): string | undefined {\n const value = flags[key];\n if (Array.isArray(value)) {\n return value[value.length - 1];\n }\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction hasFlag(flags: ParsedArgs[\"flags\"], key: string): boolean {\n return flags[key] === true;\n}\n\nfunction requireFlag(flags: ParsedArgs[\"flags\"], key: string): string {\n const value = getFlag(flags, key);\n if (!value) {\n throw new SealCliError(`Missing --${key}`, EXIT_FAILURE);\n }\n return value;\n}\n\nasync function writeOutputFile(filePath: string, content: string): Promise<void> {\n const resolvedPath = resolve(filePath);\n await mkdir(dirname(resolvedPath), { recursive: true });\n await writeFile(resolvedPath, content, \"utf8\");\n}\n\nfunction outputResult(\n writer: OutputWriter,\n json: boolean,\n quiet: boolean,\n value: unknown\n): void {\n if (quiet) {\n return;\n }\n\n if (typeof value === \"string\") {\n writer.stdout(`${value}\\n`);\n return;\n }\n\n if (json) {\n writer.stdout(`${JSON.stringify(value, null, 2)}\\n`);\n return;\n }\n\n writer.stdout(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction outputError(\n writer: OutputWriter,\n json: boolean,\n error: unknown\n): number {\n const exitCode = getExitCode(error);\n const message = error instanceof Error ? error.message : String(error);\n if (json) {\n writer.stderr(\n `${JSON.stringify({ error: message, exitCode }, null, 2)}\\n`\n );\n } else {\n writer.stderr(`${message}\\n`);\n }\n return exitCode;\n}\n\nexport async function runCli(\n argv: string[],\n params: {\n env?: ProcessEnvLike;\n writer?: OutputWriter;\n } = {}\n): Promise<number> {\n const parsed = parseArgs(argv);\n const env = params.env ?? process.env;\n const writer: OutputWriter = params.writer ?? {\n stdout: (value) => process.stdout.write(value),\n stderr: (value) => process.stderr.write(value),\n };\n const json = hasFlag(parsed.flags, \"json\");\n const quiet = hasFlag(parsed.flags, \"quiet\");\n\n try {\n const [command, subcommand] = parsed._;\n\n if (command === \"manifest\" && subcommand === \"create\") {\n const artifact = await createManifestArtifact(requireFlag(parsed.flags, \"input\"));\n const outPath = getFlag(parsed.flags, \"out\");\n if (outPath) {\n await writeOutputFile(outPath, artifact.content);\n outputResult(writer, json, quiet, json ? artifact.manifest : outPath);\n } else {\n outputResult(writer, true, quiet, artifact.manifest);\n }\n return EXIT_SUCCESS;\n }\n\n if (command === \"sign\") {\n const identity = await resolveSealIdentityFromEnv(env);\n const artifact = await createProofArtifact({\n inputPath: requireFlag(parsed.flags, \"input\"),\n identity,\n });\n const outPath = getFlag(parsed.flags, \"out\");\n if (outPath) {\n await writeOutputFile(outPath, artifact.content);\n outputResult(writer, json, quiet, json ? artifact.proof : outPath);\n } else {\n outputResult(writer, true, quiet, artifact.proof);\n }\n return EXIT_SUCCESS;\n }\n\n if (command === \"verify\") {\n const proofPath = requireFlag(parsed.flags, \"proof\");\n const inputPath = requireFlag(parsed.flags, \"input\");\n const { result } = await verifyProofArtifact({ proofPath, inputPath });\n outputResult(\n writer,\n json,\n quiet,\n json\n ? result\n : [\n `valid=${result.valid}`,\n `hashMatch=${result.hashMatch}`,\n `signatureValid=${result.signatureValid}`,\n `keyId=${result.keyId}`,\n `algorithm=${result.algorithm}`,\n `subjectHash=${result.subjectHash}`,\n ].join(\"\\n\")\n );\n\n if (!result.hashMatch) {\n return EXIT_HASH_MISMATCH;\n }\n if (!result.signatureValid) {\n return EXIT_SIGNATURE_INVALID;\n }\n return EXIT_SUCCESS;\n }\n\n if (command === \"public-key\") {\n const artifact = await createPublicKeyArtifact({\n identity: await resolveSealIdentityFromEnv(env),\n });\n outputResult(writer, true, quiet, artifact);\n return EXIT_SUCCESS;\n }\n\n throw new SealCliError(\n \"Usage: seal manifest create --input <path> [--out <path>] [--json] [--quiet]\\n\" +\n \" seal sign --input <path> [--out <path>] [--json] [--quiet]\\n\" +\n \" seal verify --proof <proof.json> --input <path> [--json] [--quiet]\\n\" +\n \" seal public-key [--json] [--quiet]\",\n EXIT_FAILURE\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Proof\")) {\n return outputError(\n writer,\n json,\n new SealCliError(error.message, EXIT_INVALID_PROOF)\n );\n }\n if (\n error instanceof Error &&\n (error.message.includes(\"public key\") ||\n error.message.includes(\"SEAL_IDENTITY\") ||\n error.message.includes(\"identity\"))\n ) {\n return outputError(\n writer,\n json,\n new SealCliError(error.message, EXIT_KEY_CONFIG)\n );\n }\n return outputError(writer, json, error);\n }\n}\n\nconst isDirectRun =\n typeof process !== \"undefined\" &&\n process.argv[1] &&\n fileURLToPath(import.meta.url) === resolve(process.argv[1]);\n\nif (isDirectRun) {\n runCli(process.argv.slice(2)).then((exitCode) => {\n process.exitCode = exitCode;\n });\n}\n"],"names":[],"mappings":"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"}
package/dist/crypto.js CHANGED
@@ -1,249 +1,2 @@
1
- import { f as formatIdentityKey } from "./chunks/utils.es-586f669f.js";
2
- function getBufferCtor() {
3
- const maybeBuffer = globalThis.Buffer;
4
- return maybeBuffer != null ? maybeBuffer : null;
5
- }
6
- function addNewLines(str) {
7
- let finalString = "";
8
- while (str.length > 0) {
9
- finalString += str.substring(0, 64) + "\n";
10
- str = str.substring(64);
11
- }
12
- return finalString;
13
- }
14
- function removeLines(str) {
15
- return str.replaceAll("\n", "");
16
- }
17
- function arrayBufferToBase64(arrayBuffer) {
18
- const byteArray = new Uint8Array(arrayBuffer);
19
- const bufferCtor = getBufferCtor();
20
- if (bufferCtor) {
21
- return bufferCtor.from(byteArray).toString("base64");
22
- }
23
- let byteString = "";
24
- for (let i = 0; i < byteArray.byteLength; i++) {
25
- byteString += String.fromCharCode(byteArray[i]);
26
- }
27
- return btoa(byteString);
28
- }
29
- function base64ToArrayBuffer(b64) {
30
- const bufferCtor = getBufferCtor();
31
- if (bufferCtor) {
32
- const bytes = Uint8Array.from(
33
- bufferCtor.from(b64, "base64").toString("binary"),
34
- (char) => char.charCodeAt(0)
35
- );
36
- return bytes.buffer.slice(
37
- bytes.byteOffset,
38
- bytes.byteOffset + bytes.byteLength
39
- );
40
- }
41
- const byteString = atob(b64);
42
- const byteArray = new Uint8Array(byteString.length);
43
- for (let i = 0; i < byteString.length; i++) {
44
- byteArray[i] = byteString.charCodeAt(i);
45
- }
46
- return byteArray.buffer;
47
- }
48
- function b64encode(buf) {
49
- return arrayBufferToBase64(buf);
50
- }
51
- function b64decode(str) {
52
- return base64ToArrayBuffer(str);
53
- }
54
- function encode(data) {
55
- const payload = typeof data === "string" ? data : JSON.stringify(data);
56
- return new TextEncoder().encode(payload);
57
- }
58
- function getHashBuffer(data) {
59
- return crypto.subtle.digest("SHA-256", encode(data));
60
- }
61
- function getHashArray(hash) {
62
- return Array.from(new Uint8Array(hash));
63
- }
64
- function getHashHex(hash) {
65
- return hash.map((buf) => buf.toString(16).padStart(2, "0")).join("");
66
- }
67
- function canonicalize(value, seen) {
68
- if (value === void 0) {
69
- throw new TypeError("Cannot hash undefined");
70
- }
71
- const valueType = typeof value;
72
- if (valueType === "function" || valueType === "symbol") {
73
- throw new TypeError(`Cannot hash ${valueType} values`);
74
- }
75
- if (value === null || valueType === "string" || valueType === "number" || valueType === "boolean") {
76
- return value;
77
- }
78
- if (valueType === "bigint") {
79
- throw new TypeError("Cannot hash bigint values");
80
- }
81
- if (typeof value.toJSON === "function") {
82
- return canonicalize(value.toJSON(), seen);
83
- }
84
- if (Array.isArray(value)) {
85
- return value.map((item) => canonicalize(item, seen));
86
- }
87
- if (typeof value === "object") {
88
- if (seen.has(value)) {
89
- throw new TypeError("Cannot hash circular references");
90
- }
91
- seen.add(value);
92
- const entries = Object.keys(value).sort();
93
- const result = {};
94
- for (const key of entries) {
95
- result[key] = canonicalize(value[key], seen);
96
- }
97
- seen.delete(value);
98
- return result;
99
- }
100
- throw new TypeError(`Cannot hash unsupported value type: ${valueType}`);
101
- }
102
- function canonicalStringify(data) {
103
- return JSON.stringify(canonicalize(data, /* @__PURE__ */ new WeakSet()));
104
- }
105
- async function hashData(data) {
106
- const hash_buffer = await getHashBuffer(canonicalStringify(data));
107
- const hash_array = getHashArray(hash_buffer);
108
- return getHashHex(hash_array);
109
- }
110
- async function importPrivateKeyFromPem(key) {
111
- const b64key = key.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "");
112
- return crypto.subtle.importKey(
113
- "pkcs8",
114
- base64ToArrayBuffer(removeLines(b64key)),
115
- { name: "ECDSA", namedCurve: "P-256" },
116
- true,
117
- ["sign"]
118
- );
119
- }
120
- async function exportPrivateKey(privateKey) {
121
- return crypto.subtle.exportKey("jwk", privateKey);
122
- }
123
- function importPublicKey(points) {
124
- return crypto.subtle.importKey(
125
- "jwk",
126
- {
127
- crv: "P-256",
128
- ext: true,
129
- kty: "EC",
130
- ...points
131
- },
132
- {
133
- name: "ECDSA",
134
- namedCurve: "P-256"
135
- },
136
- true,
137
- ["verify"]
138
- );
139
- }
140
- async function importPublicKeyFromPem(key) {
141
- const b64key = key.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "");
142
- return crypto.subtle.importKey(
143
- "spki",
144
- base64ToArrayBuffer(removeLines(b64key)),
145
- { name: "ECDSA", namedCurve: "P-256" },
146
- true,
147
- ["verify"]
148
- );
149
- }
150
- async function exportPublicKey(key) {
151
- const exported = await crypto.subtle.exportKey("spki", key);
152
- return b64encode(exported);
153
- }
154
- async function exportPublicKeyAsPem(key) {
155
- const exportedPublicKey = await crypto.subtle.exportKey("spki", key);
156
- return `-----BEGIN PUBLIC KEY-----
157
- ${addNewLines(arrayBufferToBase64(exportedPublicKey))}-----END PUBLIC KEY-----`;
158
- }
159
- async function derivePublicFromPrivatePEM(privateKeyPEM) {
160
- const key = await importPrivateKeyFromPem(privateKeyPEM);
161
- const priv = await exportPrivateKey(key);
162
- const pub = await importPublicKey({ x: priv.x, y: priv.y });
163
- return exportPublicKeyAsPem(pub);
164
- }
165
- async function signBytes(signingKey, data) {
166
- const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
167
- const signatureBuffer = await crypto.subtle.sign(
168
- {
169
- name: "ECDSA",
170
- hash: {
171
- name: "SHA-256"
172
- }
173
- },
174
- signingKey,
175
- bytes
176
- );
177
- return b64encode(signatureBuffer);
178
- }
179
- async function verifyBytes(signature, data, publicKey) {
180
- const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
181
- return crypto.subtle.verify(
182
- {
183
- name: "ECDSA",
184
- hash: { name: "SHA-256" }
185
- },
186
- publicKey,
187
- b64decode(signature),
188
- bytes
189
- );
190
- }
191
- function normalizePublicKeyBody(publicKeyBase64) {
192
- return addNewLines(publicKeyBase64).trimEnd();
193
- }
194
- async function deriveKeyIdFromPublicKeyBase64(publicKeyBase64) {
195
- return hashData(normalizePublicKeyBody(publicKeyBase64));
196
- }
197
- async function deriveKeyIdFromPublicKey(publicKey) {
198
- const publicKeyBase64 = await exportPublicKey(publicKey);
199
- return deriveKeyIdFromPublicKeyBase64(publicKeyBase64);
200
- }
201
- function utf8Bytes(value) {
202
- return new TextEncoder().encode(value);
203
- }
204
- async function importPublicKeyFromBase64(publicKeyBase64) {
205
- return importPublicKeyFromPem(formatIdentityKey(publicKeyBase64));
206
- }
207
- async function exportPublicKeyBase64(key) {
208
- return exportPublicKey(key);
209
- }
210
- async function derivePublicKeyBase64FromPrivateKeyPem(privateKeyPem) {
211
- const publicKeyPem = await derivePublicFromPrivatePEM(privateKeyPem);
212
- const publicKey = await importPublicKeyFromPem(publicKeyPem);
213
- return exportPublicKeyBase64(publicKey);
214
- }
215
- async function resolveSealSigner(input) {
216
- const privateKey = await importPrivateKeyFromPem(input.privateKeyPem);
217
- const publicKeyPem = input.publicKeyPem ? input.publicKeyPem : await derivePublicFromPrivatePEM(input.privateKeyPem);
218
- const publicKey = await importPublicKeyFromPem(publicKeyPem);
219
- const publicKeyBase64 = await exportPublicKeyBase64(publicKey);
220
- const derivedPublicKeyBase64 = await derivePublicKeyBase64FromPrivateKeyPem(
221
- input.privateKeyPem
222
- );
223
- if (publicKeyBase64 !== derivedPublicKeyBase64) {
224
- throw new Error("Provided public key does not match the private key.");
225
- }
226
- const derivedKeyId = await deriveKeyIdFromPublicKey(publicKey);
227
- if (input.keyId && input.keyId !== derivedKeyId) {
228
- throw new Error("Provided keyId does not match the signer public key.");
229
- }
230
- const keyId = input.keyId ?? derivedKeyId;
231
- return {
232
- privateKey,
233
- publicKey,
234
- publicKeyPem,
235
- publicKeyBase64,
236
- keyId
237
- };
238
- }
239
- async function signUtf8(signingKey, value) {
240
- return signBytes(signingKey, utf8Bytes(value));
241
- }
242
- async function verifyUtf8(signature, value, publicKey) {
243
- return verifyBytes(signature, utf8Bytes(value), publicKey);
244
- }
245
- async function verifyPublicKeyKeyId(publicKeyBase64, keyId) {
246
- return await deriveKeyIdFromPublicKeyBase64(publicKeyBase64) === keyId;
247
- }
248
- export { derivePublicKeyBase64FromPrivateKeyPem, exportPublicKeyBase64, importPublicKeyFromBase64, resolveSealSigner, signUtf8, verifyPublicKeyKeyId, verifyUtf8 };
1
+ export { S as SEAL_SIGNATURE_CONTEXT, e as exportIdentityJson, r as resolveSealSigner, s as signSealUtf8, v as verifyPublicKeyKeyId, a as verifySealUtf8 } from "./chunks/crypto-38954ec7.js";
249
2
  //# sourceMappingURL=crypto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sources":["../../identity/dist/identity.es.js","../src/crypto.ts"],"sourcesContent":["async function createIdentity() {\n return crypto.subtle.generateKey(\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"sign\", \"verify\"]\n );\n}\nfunction getBufferCtor() {\n const maybeBuffer = globalThis.Buffer;\n return maybeBuffer != null ? maybeBuffer : null;\n}\nfunction addNewLines(str) {\n let finalString = \"\";\n while (str.length > 0) {\n finalString += str.substring(0, 64) + \"\\n\";\n str = str.substring(64);\n }\n return finalString;\n}\nfunction removeLines(str) {\n return str.replaceAll(\"\\n\", \"\");\n}\nfunction stripIdentityKey(key) {\n return key.replace(\"-----BEGIN PUBLIC KEY-----\\n\", \"\").replace(\"\\n-----END PUBLIC KEY-----\", \"\");\n}\nfunction arrayBufferToBase64(arrayBuffer) {\n const byteArray = new Uint8Array(arrayBuffer);\n const bufferCtor = getBufferCtor();\n if (bufferCtor) {\n return bufferCtor.from(byteArray).toString(\"base64\");\n }\n let byteString = \"\";\n for (let i = 0; i < byteArray.byteLength; i++) {\n byteString += String.fromCharCode(byteArray[i]);\n }\n return btoa(byteString);\n}\nfunction base64ToArrayBuffer(b64) {\n const bufferCtor = getBufferCtor();\n if (bufferCtor) {\n const bytes = Uint8Array.from(\n bufferCtor.from(b64, \"base64\").toString(\"binary\"),\n (char) => char.charCodeAt(0)\n );\n return bytes.buffer.slice(\n bytes.byteOffset,\n bytes.byteOffset + bytes.byteLength\n );\n }\n const byteString = atob(b64);\n const byteArray = new Uint8Array(byteString.length);\n for (let i = 0; i < byteString.length; i++) {\n byteArray[i] = byteString.charCodeAt(i);\n }\n return byteArray.buffer;\n}\nfunction b64encode(buf) {\n return arrayBufferToBase64(buf);\n}\nfunction b64decode(str) {\n return base64ToArrayBuffer(str);\n}\nfunction encode(data) {\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n return new TextEncoder().encode(payload);\n}\nfunction getHashBuffer(data) {\n return crypto.subtle.digest(\"SHA-256\", encode(data));\n}\nfunction getHashArray(hash) {\n return Array.from(new Uint8Array(hash));\n}\nfunction getHashHex(hash) {\n return hash.map((buf) => buf.toString(16).padStart(2, \"0\")).join(\"\");\n}\nfunction canonicalize(value, seen) {\n if (value === void 0) {\n throw new TypeError(\"Cannot hash undefined\");\n }\n const valueType = typeof value;\n if (valueType === \"function\" || valueType === \"symbol\") {\n throw new TypeError(`Cannot hash ${valueType} values`);\n }\n if (value === null || valueType === \"string\" || valueType === \"number\" || valueType === \"boolean\") {\n return value;\n }\n if (valueType === \"bigint\") {\n throw new TypeError(\"Cannot hash bigint values\");\n }\n if (typeof value.toJSON === \"function\") {\n return canonicalize(value.toJSON(), seen);\n }\n if (Array.isArray(value)) {\n return value.map((item) => canonicalize(item, seen));\n }\n if (typeof value === \"object\") {\n if (seen.has(value)) {\n throw new TypeError(\"Cannot hash circular references\");\n }\n seen.add(value);\n const entries = Object.keys(value).sort();\n const result = {};\n for (const key of entries) {\n result[key] = canonicalize(value[key], seen);\n }\n seen.delete(value);\n return result;\n }\n throw new TypeError(`Cannot hash unsupported value type: ${valueType}`);\n}\nfunction canonicalStringify(data) {\n return JSON.stringify(canonicalize(data, /* @__PURE__ */ new WeakSet()));\n}\nasync function hashData(data) {\n const hash_buffer = await getHashBuffer(canonicalStringify(data));\n const hash_array = getHashArray(hash_buffer);\n return getHashHex(hash_array);\n}\nfunction importPrivateKey(points, secret) {\n return crypto.subtle.importKey(\n \"jwk\",\n {\n crv: \"P-256\",\n ext: true,\n kty: \"EC\",\n ...points,\n d: secret\n },\n {\n name: \"ECDSA\",\n namedCurve: \"P-256\"\n },\n true,\n [\"sign\"]\n );\n}\nasync function importPrivateKeyFromPem(key) {\n const b64key = key.replace(\"-----BEGIN PRIVATE KEY-----\", \"\").replace(\"-----END PRIVATE KEY-----\", \"\");\n return crypto.subtle.importKey(\n \"pkcs8\",\n base64ToArrayBuffer(removeLines(b64key)),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"sign\"]\n );\n}\nasync function exportPrivateKey(privateKey) {\n return crypto.subtle.exportKey(\"jwk\", privateKey);\n}\nasync function exportPrivateKeyAsPem(privateKey) {\n const exportedPrivateKey = await crypto.subtle.exportKey(\"pkcs8\", privateKey);\n return `-----BEGIN PRIVATE KEY-----\n${addNewLines(\n arrayBufferToBase64(exportedPrivateKey)\n )}-----END PRIVATE KEY-----`;\n}\nfunction importPublicKey(points) {\n return crypto.subtle.importKey(\n \"jwk\",\n {\n crv: \"P-256\",\n ext: true,\n kty: \"EC\",\n ...points\n },\n {\n name: \"ECDSA\",\n namedCurve: \"P-256\"\n },\n true,\n [\"verify\"]\n );\n}\nasync function importPublicKeyFromPem(key) {\n const b64key = key.replace(\"-----BEGIN PUBLIC KEY-----\", \"\").replace(\"-----END PUBLIC KEY-----\", \"\");\n return crypto.subtle.importKey(\n \"spki\",\n base64ToArrayBuffer(removeLines(b64key)),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"verify\"]\n );\n}\nasync function exportPublicKey(key) {\n const exported = await crypto.subtle.exportKey(\"spki\", key);\n return b64encode(exported);\n}\nasync function exportPublicKeyAsPem(key) {\n const exportedPublicKey = await crypto.subtle.exportKey(\"spki\", key);\n return `-----BEGIN PUBLIC KEY-----\n${addNewLines(arrayBufferToBase64(exportedPublicKey))}-----END PUBLIC KEY-----`;\n}\nasync function derivePublicFromPrivatePEM(privateKeyPEM) {\n const key = await importPrivateKeyFromPem(privateKeyPEM);\n const priv = await exportPrivateKey(key);\n const pub = await importPublicKey({ x: priv.x, y: priv.y });\n return exportPublicKeyAsPem(pub);\n}\nasync function signBytes(signingKey, data) {\n const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);\n const signatureBuffer = await crypto.subtle.sign(\n {\n name: \"ECDSA\",\n hash: {\n name: \"SHA-256\"\n }\n },\n signingKey,\n bytes\n );\n return b64encode(signatureBuffer);\n}\nasync function sign(signingKey, data) {\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n const dataBuffer = new TextEncoder().encode(payload);\n return signBytes(signingKey, dataBuffer);\n}\nasync function verifyBytes(signature, data, publicKey) {\n const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);\n return crypto.subtle.verify(\n {\n name: \"ECDSA\",\n hash: { name: \"SHA-256\" }\n },\n publicKey,\n b64decode(signature),\n bytes\n );\n}\nasync function verify(signature, data, publicKey) {\n const dataBuffer = new TextEncoder().encode(data);\n return verifyBytes(signature, dataBuffer, publicKey);\n}\nasync function verifyJson(signature, data, publicKey) {\n return verify(signature, JSON.stringify(data), publicKey);\n}\nfunction normalizePublicKeyBody(publicKeyBase64) {\n return addNewLines(publicKeyBase64).trimEnd();\n}\nasync function deriveKeyIdFromPublicKeyBase64(publicKeyBase64) {\n return hashData(normalizePublicKeyBody(publicKeyBase64));\n}\nasync function deriveKeyIdFromPublicKeyPem(publicKeyPem) {\n return hashData(stripIdentityKey(publicKeyPem));\n}\nasync function deriveKeyIdFromPublicKey(publicKey) {\n const publicKeyBase64 = await exportPublicKey(publicKey);\n return deriveKeyIdFromPublicKeyBase64(publicKeyBase64);\n}\nexport { createIdentity, deriveKeyIdFromPublicKey, deriveKeyIdFromPublicKeyBase64, deriveKeyIdFromPublicKeyPem, derivePublicFromPrivatePEM, exportPrivateKey, exportPrivateKeyAsPem, exportPublicKey, exportPublicKeyAsPem, importPrivateKey, importPrivateKeyFromPem, importPublicKey, importPublicKeyFromPem, sign, signBytes, verify, verifyBytes, verifyJson };\n","import {\n deriveKeyIdFromPublicKey,\n deriveKeyIdFromPublicKeyBase64,\n derivePublicFromPrivatePEM,\n exportPublicKey,\n importPrivateKeyFromPem,\n importPublicKeyFromPem,\n signBytes,\n verifyBytes,\n} from \"ternent-identity\";\nimport { formatIdentityKey } from \"ternent-utils\";\n\nexport type SealSignerInput = {\n privateKeyPem: string;\n publicKeyPem?: string;\n keyId?: string;\n};\n\nexport type ResolvedSealSigner = {\n privateKey: CryptoKey;\n publicKey: CryptoKey;\n publicKeyPem: string;\n publicKeyBase64: string;\n keyId: string;\n};\n\nfunction utf8Bytes(value: string): Uint8Array {\n return new TextEncoder().encode(value);\n}\n\nexport async function importPublicKeyFromBase64(\n publicKeyBase64: string\n): Promise<CryptoKey> {\n return importPublicKeyFromPem(formatIdentityKey(publicKeyBase64));\n}\n\nexport async function exportPublicKeyBase64(key: CryptoKey): Promise<string> {\n return exportPublicKey(key);\n}\n\nexport async function derivePublicKeyBase64FromPrivateKeyPem(\n privateKeyPem: string\n): Promise<string> {\n const publicKeyPem = await derivePublicFromPrivatePEM(privateKeyPem);\n const publicKey = await importPublicKeyFromPem(publicKeyPem);\n return exportPublicKeyBase64(publicKey);\n}\n\nexport async function resolveSealSigner(\n input: SealSignerInput\n): Promise<ResolvedSealSigner> {\n const privateKey = await importPrivateKeyFromPem(input.privateKeyPem);\n const publicKeyPem = input.publicKeyPem\n ? input.publicKeyPem\n : await derivePublicFromPrivatePEM(input.privateKeyPem);\n const publicKey = await importPublicKeyFromPem(publicKeyPem);\n const publicKeyBase64 = await exportPublicKeyBase64(publicKey);\n const derivedPublicKeyBase64 = await derivePublicKeyBase64FromPrivateKeyPem(\n input.privateKeyPem\n );\n\n if (publicKeyBase64 !== derivedPublicKeyBase64) {\n throw new Error(\"Provided public key does not match the private key.\");\n }\n\n const derivedKeyId = await deriveKeyIdFromPublicKey(publicKey);\n if (input.keyId && input.keyId !== derivedKeyId) {\n throw new Error(\"Provided keyId does not match the signer public key.\");\n }\n const keyId = input.keyId ?? derivedKeyId;\n\n return {\n privateKey,\n publicKey,\n publicKeyPem,\n publicKeyBase64,\n keyId,\n };\n}\n\nexport async function signUtf8(\n signingKey: CryptoKey,\n value: string\n): Promise<string> {\n return signBytes(signingKey, utf8Bytes(value));\n}\n\nexport async function verifyUtf8(\n signature: string,\n value: string,\n publicKey: CryptoKey\n): Promise<boolean> {\n return verifyBytes(signature, utf8Bytes(value), publicKey);\n}\n\nexport async function verifyPublicKeyKeyId(\n publicKeyBase64: string,\n keyId: string\n): Promise<boolean> {\n return (await deriveKeyIdFromPublicKeyBase64(publicKeyBase64)) === keyId;\n}\n"],"names":[],"mappings":";AAOA,SAAS,gBAAgB;AACvB,QAAM,cAAc,WAAW;AAC/B,SAAO,eAAe,OAAO,cAAc;AAC7C;AACA,SAAS,YAAY,KAAK;AACxB,MAAI,cAAc;AAClB,SAAO,IAAI,SAAS,GAAG;AACrB,mBAAe,IAAI,UAAU,GAAG,EAAE,IAAI;AACtC,UAAM,IAAI,UAAU,EAAE;AAAA,EACvB;AACD,SAAO;AACT;AACA,SAAS,YAAY,KAAK;AACxB,SAAO,IAAI,WAAW,MAAM,EAAE;AAChC;AAIA,SAAS,oBAAoB,aAAa;AACxC,QAAM,YAAY,IAAI,WAAW,WAAW;AAC5C,QAAM,aAAa;AACnB,MAAI,YAAY;AACd,WAAO,WAAW,KAAK,SAAS,EAAE,SAAS,QAAQ;AAAA,EACpD;AACD,MAAI,aAAa;AACjB,WAAS,IAAI,GAAG,IAAI,UAAU,YAAY,KAAK;AAC7C,kBAAc,OAAO,aAAa,UAAU,EAAE;AAAA,EAC/C;AACD,SAAO,KAAK,UAAU;AACxB;AACA,SAAS,oBAAoB,KAAK;AAChC,QAAM,aAAa;AACnB,MAAI,YAAY;AACd,UAAM,QAAQ,WAAW;AAAA,MACvB,WAAW,KAAK,KAAK,QAAQ,EAAE,SAAS,QAAQ;AAAA,MAChD,CAAC,SAAS,KAAK,WAAW,CAAC;AAAA,IACjC;AACI,WAAO,MAAM,OAAO;AAAA,MAClB,MAAM;AAAA,MACN,MAAM,aAAa,MAAM;AAAA,IAC/B;AAAA,EACG;AACD,QAAM,aAAa,KAAK,GAAG;AAC3B,QAAM,YAAY,IAAI,WAAW,WAAW,MAAM;AAClD,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,cAAU,KAAK,WAAW,WAAW,CAAC;AAAA,EACvC;AACD,SAAO,UAAU;AACnB;AACA,SAAS,UAAU,KAAK;AACtB,SAAO,oBAAoB,GAAG;AAChC;AACA,SAAS,UAAU,KAAK;AACtB,SAAO,oBAAoB,GAAG;AAChC;AACA,SAAS,OAAO,MAAM;AACpB,QAAM,UAAU,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,IAAI;AACrE,SAAO,IAAI,YAAW,EAAG,OAAO,OAAO;AACzC;AACA,SAAS,cAAc,MAAM;AAC3B,SAAO,OAAO,OAAO,OAAO,WAAW,OAAO,IAAI,CAAC;AACrD;AACA,SAAS,aAAa,MAAM;AAC1B,SAAO,MAAM,KAAK,IAAI,WAAW,IAAI,CAAC;AACxC;AACA,SAAS,WAAW,MAAM;AACxB,SAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACrE;AACA,SAAS,aAAa,OAAO,MAAM;AACjC,MAAI,UAAU,QAAQ;AACpB,UAAM,IAAI,UAAU,uBAAuB;AAAA,EAC5C;AACD,QAAM,YAAY,OAAO;AACzB,MAAI,cAAc,cAAc,cAAc,UAAU;AACtD,UAAM,IAAI,UAAU,eAAe,kBAAkB;AAAA,EACtD;AACD,MAAI,UAAU,QAAQ,cAAc,YAAY,cAAc,YAAY,cAAc,WAAW;AACjG,WAAO;AAAA,EACR;AACD,MAAI,cAAc,UAAU;AAC1B,UAAM,IAAI,UAAU,2BAA2B;AAAA,EAChD;AACD,MAAI,OAAO,MAAM,WAAW,YAAY;AACtC,WAAO,aAAa,MAAM,OAAQ,GAAE,IAAI;AAAA,EACzC;AACD,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,aAAa,MAAM,IAAI,CAAC;AAAA,EACpD;AACD,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,KAAK,IAAI,KAAK,GAAG;AACnB,YAAM,IAAI,UAAU,iCAAiC;AAAA,IACtD;AACD,SAAK,IAAI,KAAK;AACd,UAAM,UAAU,OAAO,KAAK,KAAK,EAAE,KAAI;AACvC,UAAM,SAAS,CAAA;AACf,eAAW,OAAO,SAAS;AACzB,aAAO,OAAO,aAAa,MAAM,MAAM,IAAI;AAAA,IAC5C;AACD,SAAK,OAAO,KAAK;AACjB,WAAO;AAAA,EACR;AACD,QAAM,IAAI,UAAU,uCAAuC,WAAW;AACxE;AACA,SAAS,mBAAmB,MAAM;AAChC,SAAO,KAAK,UAAU,aAAa,MAAsB,oBAAI,QAAS,CAAA,CAAC;AACzE;AACA,eAAe,SAAS,MAAM;AAC5B,QAAM,cAAc,MAAM,cAAc,mBAAmB,IAAI,CAAC;AAChE,QAAM,aAAa,aAAa,WAAW;AAC3C,SAAO,WAAW,UAAU;AAC9B;AAmBA,eAAe,wBAAwB,KAAK;AAC1C,QAAM,SAAS,IAAI,QAAQ,+BAA+B,EAAE,EAAE,QAAQ,6BAA6B,EAAE;AACrG,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,oBAAoB,YAAY,MAAM,CAAC;AAAA,IACvC,EAAE,MAAM,SAAS,YAAY,QAAS;AAAA,IACtC;AAAA,IACA,CAAC,MAAM;AAAA,EACX;AACA;AACA,eAAe,iBAAiB,YAAY;AAC1C,SAAO,OAAO,OAAO,UAAU,OAAO,UAAU;AAClD;AAQA,SAAS,gBAAgB,QAAQ;AAC/B,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,GAAG;AAAA,IACJ;AAAA,IACD;AAAA,MACE,MAAM;AAAA,MACN,YAAY;AAAA,IACb;AAAA,IACD;AAAA,IACA,CAAC,QAAQ;AAAA,EACb;AACA;AACA,eAAe,uBAAuB,KAAK;AACzC,QAAM,SAAS,IAAI,QAAQ,8BAA8B,EAAE,EAAE,QAAQ,4BAA4B,EAAE;AACnG,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,oBAAoB,YAAY,MAAM,CAAC;AAAA,IACvC,EAAE,MAAM,SAAS,YAAY,QAAS;AAAA,IACtC;AAAA,IACA,CAAC,QAAQ;AAAA,EACb;AACA;AACA,eAAe,gBAAgB,KAAK;AAClC,QAAM,WAAW,MAAM,OAAO,OAAO,UAAU,QAAQ,GAAG;AAC1D,SAAO,UAAU,QAAQ;AAC3B;AACA,eAAe,qBAAqB,KAAK;AACvC,QAAM,oBAAoB,MAAM,OAAO,OAAO,UAAU,QAAQ,GAAG;AACnE,SAAO;AAAA,EACP,YAAY,oBAAoB,iBAAiB,CAAC;AACpD;AACA,eAAe,2BAA2B,eAAe;AACvD,QAAM,MAAM,MAAM,wBAAwB,aAAa;AACvD,QAAM,OAAO,MAAM,iBAAiB,GAAG;AACvC,QAAM,MAAM,MAAM,gBAAgB,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,EAAC,CAAE;AAC1D,SAAO,qBAAqB,GAAG;AACjC;AACA,eAAe,UAAU,YAAY,MAAM;AACzC,QAAM,QAAQ,gBAAgB,aAAa,OAAO,IAAI,WAAW,IAAI;AACrE,QAAM,kBAAkB,MAAM,OAAO,OAAO;AAAA,IAC1C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,MAAM;AAAA,MACP;AAAA,IACF;AAAA,IACD;AAAA,IACA;AAAA,EACJ;AACE,SAAO,UAAU,eAAe;AAClC;AAMA,eAAe,YAAY,WAAW,MAAM,WAAW;AACrD,QAAM,QAAQ,gBAAgB,aAAa,OAAO,IAAI,WAAW,IAAI;AACrE,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,MACE,MAAM;AAAA,MACN,MAAM,EAAE,MAAM,UAAW;AAAA,IAC1B;AAAA,IACD;AAAA,IACA,UAAU,SAAS;AAAA,IACnB;AAAA,EACJ;AACA;AAQA,SAAS,uBAAuB,iBAAiB;AAC/C,SAAO,YAAY,eAAe,EAAE;AACtC;AACA,eAAe,+BAA+B,iBAAiB;AAC7D,SAAO,SAAS,uBAAuB,eAAe,CAAC;AACzD;AAIA,eAAe,yBAAyB,WAAW;AACjD,QAAM,kBAAkB,MAAM,gBAAgB,SAAS;AACvD,SAAO,+BAA+B,eAAe;AACvD;AC9NA,SAAS,UAAU,OAA2B;AAC5C,SAAO,IAAI,YAAA,EAAc,OAAO,KAAK;AACvC;AAEA,eAAsB,0BACpB,iBACoB;AACb,SAAA,uBAAuB,kBAAkB,eAAe,CAAC;AAClE;AAEA,eAAsB,sBAAsB,KAAiC;AAC3E,SAAO,gBAAgB,GAAG;AAC5B;AAEA,eAAsB,uCACpB,eACiB;AACX,QAAA,eAAe,MAAM,2BAA2B,aAAa;AAC7D,QAAA,YAAY,MAAM,uBAAuB,YAAY;AAC3D,SAAO,sBAAsB,SAAS;AACxC;AAEA,eAAsB,kBACpB,OAC6B;AAC7B,QAAM,aAAa,MAAM,wBAAwB,MAAM,aAAa;AAC9D,QAAA,eAAe,MAAM,eACvB,MAAM,eACN,MAAM,2BAA2B,MAAM,aAAa;AAClD,QAAA,YAAY,MAAM,uBAAuB,YAAY;AACrD,QAAA,kBAAkB,MAAM,sBAAsB,SAAS;AAC7D,QAAM,yBAAyB,MAAM;AAAA,IACnC,MAAM;AAAA,EAAA;AAGR,MAAI,oBAAoB,wBAAwB;AACxC,UAAA,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEM,QAAA,eAAe,MAAM,yBAAyB,SAAS;AAC7D,MAAI,MAAM,SAAS,MAAM,UAAU,cAAc;AACzC,UAAA,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACM,QAAA,QAAQ,MAAM,SAAS;AAEtB,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAEsB,eAAA,SACpB,YACA,OACiB;AACjB,SAAO,UAAU,YAAY,UAAU,KAAK,CAAC;AAC/C;AAEsB,eAAA,WACpB,WACA,OACA,WACkB;AAClB,SAAO,YAAY,WAAW,UAAU,KAAK,GAAG,SAAS;AAC3D;AAEsB,eAAA,qBACpB,iBACA,OACkB;AACV,SAAA,MAAM,+BAA+B,eAAe,MAAO;AACrE;;"}
1
+ {"version":3,"file":"crypto.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { SEAL_PROOF_TYPE, SEAL_PROOF_VERSION, SEAL_SIGNATURE_ALGORITHM, createSealHash, createSealProof, createSealPublicKeyArtifact, getSealProofSignableFields, getSealProofSigningPayload, parseSealProofJson, parseSealPublicKeyJson, validateSealProofShape, validateSealPublicKeyShape, verifySealProofAgainstBytes, verifySealProofSignature } from "./proof.js";
1
+ export { SEAL_PROOF_TYPE, SEAL_PROOF_VERSION, SEAL_PUBLIC_KEY_TYPE, SEAL_SIGNATURE_ALGORITHM, createSealHash, createSealProof, createSealPublicKeyArtifact, getSealProofSignableFields, getSealProofSigningPayload, parseSealProofJson, parseSealPublicKeyJson, validateSealProofShape, validateSealPublicKeyShape, verifySealProofAgainstBytes, verifySealProofSignature } from "./proof.js";
2
2
  export { SEAL_MANIFEST_TYPE, SEAL_MANIFEST_VERSION, parseSealManifestJson, stringifySealManifest, validateSealManifestShape } from "./manifest.js";
3
- export { derivePublicKeyBase64FromPrivateKeyPem, exportPublicKeyBase64, importPublicKeyFromBase64, resolveSealSigner, signUtf8, verifyPublicKeyKeyId, verifyUtf8 } from "./crypto.js";
3
+ export { S as SEAL_SIGNATURE_CONTEXT, e as exportIdentityJson, r as resolveSealSigner, s as signSealUtf8, v as verifyPublicKeyKeyId, a as verifySealUtf8 } from "./chunks/crypto-38954ec7.js";
4
4
  export { EXIT_FAILURE, EXIT_HASH_MISMATCH, EXIT_INVALID_PROOF, EXIT_KEY_CONFIG, EXIT_SIGNATURE_INVALID, EXIT_SUCCESS, SealCliError, getExitCode } from "./errors.js";
5
- import "./chunks/utils.es-586f669f.js";
5
+ import "./chunks/utils.es-7e2ade90.js";
6
6
  //# sourceMappingURL=index.js.map
package/dist/manifest.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as canonicalStringify } from "./chunks/utils.es-586f669f.js";
1
+ import { c as canonicalStringify } from "./chunks/utils.es-7e2ade90.js";
2
2
  const SEAL_MANIFEST_VERSION = "1";
3
3
  const SEAL_MANIFEST_TYPE = "seal-manifest";
4
4
  function isRecord(value) {
package/dist/proof.js CHANGED
@@ -1,8 +1,9 @@
1
- import { c as canonicalStringify, h as hashBytes } from "./chunks/utils.es-586f669f.js";
2
- import { resolveSealSigner, signUtf8, verifyPublicKeyKeyId, importPublicKeyFromBase64, verifyUtf8 } from "./crypto.js";
3
- const SEAL_PROOF_VERSION = "1";
1
+ import { c as canonicalStringify, h as hashBytes } from "./chunks/utils.es-7e2ade90.js";
2
+ import { r as resolveSealSigner, s as signSealUtf8, v as verifyPublicKeyKeyId, a as verifySealUtf8 } from "./chunks/crypto-38954ec7.js";
3
+ const SEAL_PROOF_VERSION = "2";
4
4
  const SEAL_PROOF_TYPE = "seal-proof";
5
- const SEAL_SIGNATURE_ALGORITHM = "ECDSA-P256-SHA256";
5
+ const SEAL_PUBLIC_KEY_TYPE = "seal-public-key";
6
+ const SEAL_SIGNATURE_ALGORITHM = "Ed25519";
6
7
  function isRecord(value) {
7
8
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8
9
  }
@@ -41,12 +42,12 @@ async function createSealProof(input) {
41
42
  createdAt: input.createdAt ?? new Date().toISOString(),
42
43
  subject: input.subject,
43
44
  signer: {
44
- publicKey: signer.publicKeyBase64,
45
+ publicKey: signer.publicKey,
45
46
  keyId: signer.keyId
46
47
  }
47
48
  };
48
- const signature = await signUtf8(
49
- signer.privateKey,
49
+ const signature = await signSealUtf8(
50
+ signer.identity,
50
51
  getSealProofSigningPayload(fields)
51
52
  );
52
53
  return {
@@ -57,8 +58,10 @@ async function createSealProof(input) {
57
58
  async function createSealPublicKeyArtifact(signer) {
58
59
  const resolved = await resolveSealSigner(signer);
59
60
  return {
61
+ version: SEAL_PROOF_VERSION,
62
+ type: SEAL_PUBLIC_KEY_TYPE,
60
63
  algorithm: SEAL_SIGNATURE_ALGORITHM,
61
- publicKey: resolved.publicKeyBase64,
64
+ publicKey: resolved.publicKey,
62
65
  keyId: resolved.keyId
63
66
  };
64
67
  }
@@ -91,7 +94,7 @@ function validateSealProofShape(value) {
91
94
  errors.push("Proof createdAt must be an ISO timestamp.");
92
95
  }
93
96
  if (typeof value.signature !== "string" || value.signature.length === 0) {
94
- errors.push("Proof signature must be a non-empty base64 string.");
97
+ errors.push("Proof signature must be a non-empty base64url string.");
95
98
  }
96
99
  if (!isRecord(value.subject)) {
97
100
  errors.push("Proof subject must be an object.");
@@ -118,7 +121,7 @@ function validateSealProofShape(value) {
118
121
  errors.push("Proof subject hash must be a sha256 hash.");
119
122
  }
120
123
  if (typeof value.signer.publicKey !== "string" || value.signer.publicKey.length === 0) {
121
- errors.push("Proof signer publicKey must be a non-empty base64 string.");
124
+ errors.push("Proof signer publicKey must be a non-empty base64url string.");
122
125
  }
123
126
  if (typeof value.signer.keyId !== "string" || value.signer.keyId.length === 0) {
124
127
  errors.push("Proof signer keyId must be a non-empty string.");
@@ -152,14 +155,20 @@ function validateSealPublicKeyShape(value) {
152
155
  };
153
156
  }
154
157
  const errors = [];
155
- if (!hasOnlyKeys(value, ["algorithm", "publicKey", "keyId"])) {
158
+ if (!hasOnlyKeys(value, ["version", "type", "algorithm", "publicKey", "keyId"])) {
156
159
  errors.push("Public key artifact contains unsupported fields.");
157
160
  }
161
+ if (value.version !== SEAL_PROOF_VERSION) {
162
+ errors.push(`Public key artifact version must be ${SEAL_PROOF_VERSION}.`);
163
+ }
164
+ if (value.type !== SEAL_PUBLIC_KEY_TYPE) {
165
+ errors.push(`Public key artifact type must be ${SEAL_PUBLIC_KEY_TYPE}.`);
166
+ }
158
167
  if (value.algorithm !== SEAL_SIGNATURE_ALGORITHM) {
159
168
  errors.push(`Public key artifact algorithm must be ${SEAL_SIGNATURE_ALGORITHM}.`);
160
169
  }
161
170
  if (typeof value.publicKey !== "string" || value.publicKey.length === 0) {
162
- errors.push("Public key artifact publicKey must be a non-empty base64 string.");
171
+ errors.push("Public key artifact publicKey must be a non-empty base64url string.");
163
172
  }
164
173
  if (typeof value.keyId !== "string" || value.keyId.length === 0) {
165
174
  errors.push("Public key artifact keyId must be a non-empty string.");
@@ -196,21 +205,19 @@ async function verifySealProofSignature(proof) {
196
205
  };
197
206
  }
198
207
  try {
199
- const publicKey = await importPublicKeyFromBase64(proof.signer.publicKey);
200
- const valid = await verifyUtf8(
208
+ const valid = await verifySealUtf8(
201
209
  proof.signature,
202
210
  getSealProofSigningPayload(proof),
203
- publicKey
211
+ proof.signer.publicKey
204
212
  );
205
213
  if (!valid) {
206
214
  return { ok: false, errors: ["Invalid signature."] };
207
215
  }
208
216
  return { ok: true, errors: [] };
209
217
  } catch (caught) {
210
- const message = caught instanceof Error ? caught.message : String(caught);
211
218
  return {
212
219
  ok: false,
213
- errors: [`Failed to verify signature: ${message}`]
220
+ errors: ["Invalid signature."]
214
221
  };
215
222
  }
216
223
  }
@@ -228,5 +235,5 @@ async function verifySealProofAgainstBytes(proof, bytes) {
228
235
  subjectHash
229
236
  };
230
237
  }
231
- export { SEAL_PROOF_TYPE, SEAL_PROOF_VERSION, SEAL_SIGNATURE_ALGORITHM, createSealHash, createSealProof, createSealPublicKeyArtifact, getSealProofSignableFields, getSealProofSigningPayload, parseSealProofJson, parseSealPublicKeyJson, validateSealProofShape, validateSealPublicKeyShape, verifySealProofAgainstBytes, verifySealProofSignature };
238
+ export { SEAL_PROOF_TYPE, SEAL_PROOF_VERSION, SEAL_PUBLIC_KEY_TYPE, SEAL_SIGNATURE_ALGORITHM, createSealHash, createSealProof, createSealPublicKeyArtifact, getSealProofSignableFields, getSealProofSigningPayload, parseSealProofJson, parseSealPublicKeyJson, validateSealProofShape, validateSealPublicKeyShape, verifySealProofAgainstBytes, verifySealProofSignature };
232
239
  //# sourceMappingURL=proof.js.map