raz-encrypt 0.1.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/LICENSE +21 -0
- package/README.md +225 -0
- package/dist/canonicalJson.d.ts +3 -0
- package/dist/canonicalJson.js +25 -0
- package/dist/canonicalJson.js.map +1 -0
- package/dist/core.d.ts +23 -0
- package/dist/core.js +19 -0
- package/dist/core.js.map +1 -0
- package/dist/crypto/classical.d.ts +10 -0
- package/dist/crypto/classical.js +21 -0
- package/dist/crypto/classical.js.map +1 -0
- package/dist/crypto/frameCipher.d.ts +23 -0
- package/dist/crypto/frameCipher.js +58 -0
- package/dist/crypto/frameCipher.js.map +1 -0
- package/dist/crypto/hybrid.d.ts +117 -0
- package/dist/crypto/hybrid.js +180 -0
- package/dist/crypto/hybrid.js.map +1 -0
- package/dist/crypto/nodeHybrid.d.ts +42 -0
- package/dist/crypto/nodeHybrid.js +65 -0
- package/dist/crypto/nodeHybrid.js.map +1 -0
- package/dist/crypto/pqc.d.ts +19 -0
- package/dist/crypto/pqc.js +28 -0
- package/dist/crypto/pqc.js.map +1 -0
- package/dist/fileCrypto.d.ts +6 -0
- package/dist/fileCrypto.js +45 -0
- package/dist/fileCrypto.js.map +1 -0
- package/dist/fingerprint.d.ts +11 -0
- package/dist/fingerprint.js +18 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/identity.d.ts +42 -0
- package/dist/identity.js +87 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/store.d.ts +28 -0
- package/dist/store.js +62 -0
- package/dist/store.js.map +1 -0
- package/dist/trust.d.ts +41 -0
- package/dist/trust.js +98 -0
- package/dist/trust.js.map +1 -0
- package/package.json +48 -0
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Identity } from "./identity.js";
|
|
2
|
+
export interface LogEntry {
|
|
3
|
+
action: "sign" | "verify" | "encrypt" | "decrypt";
|
|
4
|
+
documentHash?: string;
|
|
5
|
+
counterpartAlias?: string;
|
|
6
|
+
result?: string;
|
|
7
|
+
at: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Appends one entry to the local, append-only audit log (public metadata
|
|
11
|
+
* only — no secrets). Each entry is chained to the previous one's hash
|
|
12
|
+
* (see verifyLogIntegrity) so tampering or deleting past entries is
|
|
13
|
+
* detectable, not just theoretically append-only.
|
|
14
|
+
*/
|
|
15
|
+
export declare function appendLogEntry(identity: Identity, entry: Omit<LogEntry, "at">): Promise<void>;
|
|
16
|
+
export declare function readLog(identity: Identity): Promise<LogEntry[]>;
|
|
17
|
+
export type LogIntegrityResult = {
|
|
18
|
+
intact: true;
|
|
19
|
+
} | {
|
|
20
|
+
intact: false;
|
|
21
|
+
brokenAtIndex: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Walks the hash chain and reports whether it's intact. If an entry was
|
|
25
|
+
* edited or deleted, `brokenAtIndex` is the (0-based) index of the first
|
|
26
|
+
* entry whose chain link no longer matches.
|
|
27
|
+
*/
|
|
28
|
+
export declare function verifyLogIntegrity(identity: Identity): Promise<LogIntegrityResult>;
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { sha384 } from "@noble/hashes/sha2.js";
|
|
2
|
+
import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
3
|
+
import { appendFile, mkdir, readFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { canonicalize } from "./canonicalJson.js";
|
|
6
|
+
const GENESIS_HASH = "GENESIS";
|
|
7
|
+
function logFilePath(storageDir) {
|
|
8
|
+
return join(storageDir, "log.jsonl");
|
|
9
|
+
}
|
|
10
|
+
function computeHash(entry) {
|
|
11
|
+
return bytesToHex(sha384(utf8ToBytes(canonicalize(entry))));
|
|
12
|
+
}
|
|
13
|
+
async function readStoredEntries(storageDir) {
|
|
14
|
+
try {
|
|
15
|
+
const raw = await readFile(logFilePath(storageDir), "utf8");
|
|
16
|
+
return raw
|
|
17
|
+
.split("\n")
|
|
18
|
+
.filter((line) => line.trim().length > 0)
|
|
19
|
+
.map((line) => JSON.parse(line));
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err.code === "ENOENT")
|
|
23
|
+
return [];
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Appends one entry to the local, append-only audit log (public metadata
|
|
29
|
+
* only — no secrets). Each entry is chained to the previous one's hash
|
|
30
|
+
* (see verifyLogIntegrity) so tampering or deleting past entries is
|
|
31
|
+
* detectable, not just theoretically append-only.
|
|
32
|
+
*/
|
|
33
|
+
export async function appendLogEntry(identity, entry) {
|
|
34
|
+
const full = { ...entry, at: new Date().toISOString() };
|
|
35
|
+
const existing = await readStoredEntries(identity.storageDir);
|
|
36
|
+
const prevHash = existing.length > 0 ? existing[existing.length - 1].hash : GENESIS_HASH;
|
|
37
|
+
const withPrev = { ...full, prevHash };
|
|
38
|
+
const stored = { ...withPrev, hash: computeHash(withPrev) };
|
|
39
|
+
await mkdir(identity.storageDir, { recursive: true });
|
|
40
|
+
await appendFile(logFilePath(identity.storageDir), JSON.stringify(stored) + "\n", { mode: 0o600 });
|
|
41
|
+
}
|
|
42
|
+
export async function readLog(identity) {
|
|
43
|
+
return (await readStoredEntries(identity.storageDir)).map(({ prevHash: _prevHash, hash: _hash, ...entry }) => entry);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Walks the hash chain and reports whether it's intact. If an entry was
|
|
47
|
+
* edited or deleted, `brokenAtIndex` is the (0-based) index of the first
|
|
48
|
+
* entry whose chain link no longer matches.
|
|
49
|
+
*/
|
|
50
|
+
export async function verifyLogIntegrity(identity) {
|
|
51
|
+
const entries = await readStoredEntries(identity.storageDir);
|
|
52
|
+
let expectedPrevHash = GENESIS_HASH;
|
|
53
|
+
for (let i = 0; i < entries.length; i++) {
|
|
54
|
+
const { prevHash, hash, ...rest } = entries[i];
|
|
55
|
+
if (prevHash !== expectedPrevHash || hash !== computeHash({ ...rest, prevHash })) {
|
|
56
|
+
return { intact: false, brokenAtIndex: i };
|
|
57
|
+
}
|
|
58
|
+
expectedPrevHash = hash;
|
|
59
|
+
}
|
|
60
|
+
return { intact: true };
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/dist/trust.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Identity, PublicCard } from "./identity.js";
|
|
2
|
+
export interface TrustRecord {
|
|
3
|
+
card: PublicCard;
|
|
4
|
+
trustedAt: string;
|
|
5
|
+
/** Set when this party was later revoked (see untrustParty). Absent = still trusted. */
|
|
6
|
+
revokedAt?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Records another party's public card as trusted, keyed by the card's
|
|
10
|
+
* fingerprint (not alias — two different real parties could otherwise pick
|
|
11
|
+
* the same alias and silently overwrite each other). Public keys are not
|
|
12
|
+
* secret, so this file is plain JSON (unlike identity.enc.json), though it's
|
|
13
|
+
* still permission-restricted to the owning user.
|
|
14
|
+
*
|
|
15
|
+
* Trusting a card again after it was revoked reinstates it (clears revokedAt).
|
|
16
|
+
*/
|
|
17
|
+
export declare function trustParty(identity: Identity, card: PublicCard): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Revokes every currently-trusted card recorded under `alias` — e.g. after a
|
|
20
|
+
* suspected key compromise. Records are tombstoned (kept, marked revokedAt),
|
|
21
|
+
* not deleted, so the history "this party was trusted, then revoked" isn't
|
|
22
|
+
* lost, and so verify() can report "revoked-signer" distinctly from
|
|
23
|
+
* "untrusted-signer" (never trusted at all).
|
|
24
|
+
*/
|
|
25
|
+
export declare function untrustParty(identity: Identity, alias: string): Promise<void>;
|
|
26
|
+
/** Every currently-trusted (non-revoked) card. */
|
|
27
|
+
export declare function listTrustedParties(identity: Identity): Promise<PublicCard[]>;
|
|
28
|
+
/** Every trust record ever made, revoked or not — for audit/history purposes. */
|
|
29
|
+
export declare function listTrustRecords(identity: Identity): Promise<TrustRecord[]>;
|
|
30
|
+
/** The first currently-trusted (non-revoked) card recorded under this alias, if any. */
|
|
31
|
+
export declare function getTrustedParty(identity: Identity, alias: string): Promise<PublicCard | undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* All currently-trusted (non-revoked) cards recorded under this alias. Alias
|
|
34
|
+
* is a non-unique display label (see ticket 02): two different real parties
|
|
35
|
+
* can legitimately share one, so callers that need to confirm a SPECIFIC
|
|
36
|
+
* card is trusted (not just "some card under this alias") should check every
|
|
37
|
+
* entry this returns.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getTrustedPartiesByAlias(identity: Identity, alias: string): Promise<PublicCard[]>;
|
|
40
|
+
/** All trust records (revoked or not) recorded under this alias. */
|
|
41
|
+
export declare function getTrustRecordsByAlias(identity: Identity, alias: string): Promise<TrustRecord[]>;
|
package/dist/trust.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { fingerprint } from "./fingerprint.js";
|
|
4
|
+
function trustFilePath(storageDir) {
|
|
5
|
+
return join(storageDir, "trust.json");
|
|
6
|
+
}
|
|
7
|
+
function isV2(data) {
|
|
8
|
+
return typeof data === "object" && data !== null && data.version === 2;
|
|
9
|
+
}
|
|
10
|
+
/** Migrates a legacy alias-keyed store to the fingerprint-keyed v2 shape. */
|
|
11
|
+
function migrateLegacy(legacy) {
|
|
12
|
+
const entries = {};
|
|
13
|
+
for (const card of Object.values(legacy)) {
|
|
14
|
+
entries[fingerprint(card)] = { card, trustedAt: new Date().toISOString() };
|
|
15
|
+
}
|
|
16
|
+
return { version: 2, entries };
|
|
17
|
+
}
|
|
18
|
+
async function readTrustStore(storageDir) {
|
|
19
|
+
let raw;
|
|
20
|
+
try {
|
|
21
|
+
raw = await readFile(trustFilePath(storageDir), "utf8");
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (err.code === "ENOENT")
|
|
25
|
+
return { version: 2, entries: {} };
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
const data = JSON.parse(raw);
|
|
29
|
+
return isV2(data) ? data : migrateLegacy(data);
|
|
30
|
+
}
|
|
31
|
+
async function writeTrustStore(storageDir, store) {
|
|
32
|
+
await mkdir(storageDir, { recursive: true });
|
|
33
|
+
await writeFile(trustFilePath(storageDir), JSON.stringify(store, null, 2), { mode: 0o600 });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Records another party's public card as trusted, keyed by the card's
|
|
37
|
+
* fingerprint (not alias — two different real parties could otherwise pick
|
|
38
|
+
* the same alias and silently overwrite each other). Public keys are not
|
|
39
|
+
* secret, so this file is plain JSON (unlike identity.enc.json), though it's
|
|
40
|
+
* still permission-restricted to the owning user.
|
|
41
|
+
*
|
|
42
|
+
* Trusting a card again after it was revoked reinstates it (clears revokedAt).
|
|
43
|
+
*/
|
|
44
|
+
export async function trustParty(identity, card) {
|
|
45
|
+
const store = await readTrustStore(identity.storageDir);
|
|
46
|
+
store.entries[fingerprint(card)] = { card, trustedAt: new Date().toISOString() };
|
|
47
|
+
await writeTrustStore(identity.storageDir, store);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Revokes every currently-trusted card recorded under `alias` — e.g. after a
|
|
51
|
+
* suspected key compromise. Records are tombstoned (kept, marked revokedAt),
|
|
52
|
+
* not deleted, so the history "this party was trusted, then revoked" isn't
|
|
53
|
+
* lost, and so verify() can report "revoked-signer" distinctly from
|
|
54
|
+
* "untrusted-signer" (never trusted at all).
|
|
55
|
+
*/
|
|
56
|
+
export async function untrustParty(identity, alias) {
|
|
57
|
+
const store = await readTrustStore(identity.storageDir);
|
|
58
|
+
const revokedAt = new Date().toISOString();
|
|
59
|
+
for (const record of Object.values(store.entries)) {
|
|
60
|
+
if (record.card.alias === alias && !record.revokedAt)
|
|
61
|
+
record.revokedAt = revokedAt;
|
|
62
|
+
}
|
|
63
|
+
await writeTrustStore(identity.storageDir, store);
|
|
64
|
+
}
|
|
65
|
+
/** Every currently-trusted (non-revoked) card. */
|
|
66
|
+
export async function listTrustedParties(identity) {
|
|
67
|
+
const store = await readTrustStore(identity.storageDir);
|
|
68
|
+
return Object.values(store.entries)
|
|
69
|
+
.filter((record) => !record.revokedAt)
|
|
70
|
+
.map((record) => record.card);
|
|
71
|
+
}
|
|
72
|
+
/** Every trust record ever made, revoked or not — for audit/history purposes. */
|
|
73
|
+
export async function listTrustRecords(identity) {
|
|
74
|
+
const store = await readTrustStore(identity.storageDir);
|
|
75
|
+
return Object.values(store.entries);
|
|
76
|
+
}
|
|
77
|
+
/** The first currently-trusted (non-revoked) card recorded under this alias, if any. */
|
|
78
|
+
export async function getTrustedParty(identity, alias) {
|
|
79
|
+
return (await getTrustedPartiesByAlias(identity, alias))[0];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* All currently-trusted (non-revoked) cards recorded under this alias. Alias
|
|
83
|
+
* is a non-unique display label (see ticket 02): two different real parties
|
|
84
|
+
* can legitimately share one, so callers that need to confirm a SPECIFIC
|
|
85
|
+
* card is trusted (not just "some card under this alias") should check every
|
|
86
|
+
* entry this returns.
|
|
87
|
+
*/
|
|
88
|
+
export async function getTrustedPartiesByAlias(identity, alias) {
|
|
89
|
+
return (await getTrustRecordsByAlias(identity, alias))
|
|
90
|
+
.filter((record) => !record.revokedAt)
|
|
91
|
+
.map((record) => record.card);
|
|
92
|
+
}
|
|
93
|
+
/** All trust records (revoked or not) recorded under this alias. */
|
|
94
|
+
export async function getTrustRecordsByAlias(identity, alias) {
|
|
95
|
+
const store = await readTrustStore(identity.storageDir);
|
|
96
|
+
return Object.values(store.entries).filter((record) => record.card.alias === alias);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=trust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.js","sourceRoot":"","sources":["../src/trust.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "raz-encrypt",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local-first, hybrid classical+post-quantum signing and verification for two consenting parties. No server, no database required.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./core": {
|
|
18
|
+
"types": "./dist/core.d.ts",
|
|
19
|
+
"import": "./dist/core.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"demo:setup": "tsx demo/alice.ts && tsx demo/bob.ts && tsx demo/exchange.ts",
|
|
31
|
+
"demo:sign": "tsx demo/sign-as-alice.ts",
|
|
32
|
+
"demo:verify": "tsx demo/verify-as-bob.ts",
|
|
33
|
+
"demo:tamper": "tsx demo/verify-as-bob.ts --tamper",
|
|
34
|
+
"demo:clean": "rm -rf demo/.alice-store demo/.bob-store demo/alice-card.json demo/bob-card.json demo/signed-doc.json"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@noble/ciphers": "^2.4.0",
|
|
38
|
+
"@noble/curves": "^2.4.0",
|
|
39
|
+
"@noble/hashes": "^2.4.0",
|
|
40
|
+
"@noble/post-quantum": "^0.7.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^22.10.2",
|
|
44
|
+
"tsx": "^4.19.2",
|
|
45
|
+
"typescript": "^5.7.2",
|
|
46
|
+
"vitest": "^5.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|