@atlasauth/pca-abe 0.0.0-stage → 0.2.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/sss.js ADDED
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.splitSecret = splitSecret;
4
+ exports.recoverSecret = recoverSecret;
5
+ exports.randomSecret = randomSecret;
6
+ const bls_1 = require("./bls");
7
+ /**
8
+ * Split `secret` into `n` shares with reconstruction threshold `t` (1 <= t <= n). Share `i` (1-based)
9
+ * is `f(i)` for a random degree `t-1` polynomial with `f(0) = secret`.
10
+ */
11
+ function splitSecret(secret, t, n) {
12
+ if (!Number.isInteger(t) || !Number.isInteger(n) || t < 1 || n < 1 || t > n) {
13
+ throw new RangeError(`splitSecret: need 1 <= t(${t}) <= n(${n})`);
14
+ }
15
+ // Coefficients a_0 = secret, a_1..a_{t-1} random.
16
+ const coeffs = [secret];
17
+ for (let i = 1; i < t; i++)
18
+ coeffs.push((0, bls_1.randomScalar)());
19
+ const shares = [];
20
+ for (let i = 1; i <= n; i++) {
21
+ const x = BigInt(i);
22
+ // Horner evaluation of f(x) in Z_r.
23
+ let acc = 0n;
24
+ for (let d = coeffs.length - 1; d >= 0; d--)
25
+ acc = (0, bls_1.frAdd)((0, bls_1.frMul)(acc, x), coeffs[d] ?? 0n);
26
+ shares.push({ x, y: acc });
27
+ }
28
+ return shares;
29
+ }
30
+ /**
31
+ * Reconstruct `f(0)` by Lagrange interpolation at 0 over Z_r. Requires at least one share and distinct,
32
+ * non-zero `x` coordinates. Given `>= t` consistent shares of a degree `t-1` sharing, this returns the
33
+ * original secret; with duplicate x's it returns null (fail-closed).
34
+ */
35
+ function recoverSecret(shares) {
36
+ if (shares.length === 0)
37
+ return null;
38
+ const seen = new Set();
39
+ for (const s of shares) {
40
+ if (s.x === 0n)
41
+ return null;
42
+ const k = s.x.toString();
43
+ if (seen.has(k))
44
+ return null;
45
+ seen.add(k);
46
+ }
47
+ let secret = 0n;
48
+ for (let i = 0; i < shares.length; i++) {
49
+ const si = shares[i];
50
+ if (si === undefined)
51
+ return null;
52
+ // Lagrange basis L_i(0) = prod_{j != i} x_j / (x_j - x_i).
53
+ let num = 1n;
54
+ let den = 1n;
55
+ for (let j = 0; j < shares.length; j++) {
56
+ if (j === i)
57
+ continue;
58
+ const sj = shares[j];
59
+ if (sj === undefined)
60
+ return null;
61
+ num = (0, bls_1.frMul)(num, sj.x);
62
+ den = (0, bls_1.frMul)(den, (0, bls_1.frSub)(sj.x, si.x));
63
+ }
64
+ const coeff = (0, bls_1.frMul)(num, (0, bls_1.frInv)(den));
65
+ secret = (0, bls_1.frAdd)(secret, (0, bls_1.frMul)(si.y, coeff));
66
+ }
67
+ return secret;
68
+ }
69
+ /** Convenience: a fresh random secret scalar together with its 32-byte big-endian encoding. */
70
+ function randomSecret() {
71
+ const scalar = (0, bls_1.randomScalar)();
72
+ return { scalar, bytes: (0, bls_1.scalarToBytes)(scalar) };
73
+ }
74
+ //# sourceMappingURL=sss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sss.js","sourceRoot":"","sources":["../src/sss.ts"],"names":[],"mappings":"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"}
package/dist/wire.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Wire helpers: base64url codec (no padding) and fail-closed structural type guards for parsing
3
+ * UNTRUSTED ciphertext/key material. Nothing here throws on bad input — every parser returns a typed
4
+ * value or `null`, so a malformed ciphertext is rejected cleanly rather than crashing the decryptor.
5
+ */
6
+ /** Encode bytes as unpadded base64url. */
7
+ export declare function b64u(bytes: Uint8Array): string;
8
+ /** Decode unpadded base64url; null on any non-string / malformed input (round-trip checked, never throws). */
9
+ export declare function unb64u(s: unknown): Uint8Array | null;
10
+ export declare function isObject(x: unknown): x is Record<string, unknown>;
11
+ export declare function isString(x: unknown): x is string;
12
+ export declare function isPosInt(x: unknown): x is number;
13
+ /** XOR two equal-length byte arrays; null if lengths differ. */
14
+ export declare function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array | null;
package/dist/wire.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * Wire helpers: base64url codec (no padding) and fail-closed structural type guards for parsing
4
+ * UNTRUSTED ciphertext/key material. Nothing here throws on bad input — every parser returns a typed
5
+ * value or `null`, so a malformed ciphertext is rejected cleanly rather than crashing the decryptor.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.b64u = b64u;
9
+ exports.unb64u = unb64u;
10
+ exports.isObject = isObject;
11
+ exports.isString = isString;
12
+ exports.isPosInt = isPosInt;
13
+ exports.xorBytes = xorBytes;
14
+ /** Encode bytes as unpadded base64url. */
15
+ function b64u(bytes) {
16
+ return Buffer.from(bytes).toString('base64url');
17
+ }
18
+ /** Decode unpadded base64url; null on any non-string / malformed input (round-trip checked, never throws). */
19
+ function unb64u(s) {
20
+ if (typeof s !== 'string')
21
+ return null;
22
+ if (!/^[A-Za-z0-9_-]*$/.test(s))
23
+ return null;
24
+ try {
25
+ const bytes = new Uint8Array(Buffer.from(s, 'base64url'));
26
+ // Reject non-canonical encodings (trailing bits / padding variance): require exact round-trip.
27
+ if (Buffer.from(bytes).toString('base64url') !== s)
28
+ return null;
29
+ return bytes;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ function isObject(x) {
36
+ return x !== null && typeof x === 'object' && !Array.isArray(x);
37
+ }
38
+ function isString(x) {
39
+ return typeof x === 'string';
40
+ }
41
+ function isPosInt(x) {
42
+ return typeof x === 'number' && Number.isInteger(x) && x > 0;
43
+ }
44
+ /** XOR two equal-length byte arrays; null if lengths differ. */
45
+ function xorBytes(a, b) {
46
+ if (a.length !== b.length)
47
+ return null;
48
+ const out = new Uint8Array(a.length);
49
+ for (let i = 0; i < a.length; i++)
50
+ out[i] = (a[i] ?? 0) ^ (b[i] ?? 0);
51
+ return out;
52
+ }
53
+ //# sourceMappingURL=wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.js","sourceRoot":"","sources":["../src/wire.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAGH,oBAEC;AAGD,wBAWC;AAED,4BAEC;AAED,4BAEC;AAED,4BAEC;AAGD,4BAKC;AArCD,0CAA0C;AAC1C,SAAgB,IAAI,CAAC,KAAiB;IACpC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAClD,CAAC;AAED,8GAA8G;AAC9G,SAAgB,MAAM,CAAC,CAAU;IAC/B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAC1D,+FAA+F;QAC/F,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAChE,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU;IACjC,OAAO,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC;AAC/B,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/D,CAAC;AAED,gEAAgE;AAChE,SAAgB,QAAQ,CAAC,CAAa,EAAE,CAAa;IACnD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,58 @@
1
1
  {
2
2
  "name": "@atlasauth/pca-abe",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "Proof-carrying encryption for PCA: attribute/policy-based encryption on BLS12-381 so a tool payload decrypts only for a holder whose capability satisfies the policy — binding confidentiality to proven authority.",
5
+ "keywords": [
6
+ "attribute-based encryption",
7
+ "bls12-381",
8
+ "policy encryption",
9
+ "agent authorization",
10
+ "proof-carrying authority",
11
+ "pca",
12
+ "ai agents"
13
+ ],
14
+ "license": "MIT",
15
+ "homepage": "https://github.com/Atlas-Authorization/pca#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/Atlas-Authorization/pca/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/Atlas-Authorization/pca.git",
22
+ "directory": "packages/pca-abe"
23
+ },
24
+ "main": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "dependencies": {
34
+ "@noble/curves": "^1.6.0",
35
+ "@noble/hashes": "^1.5.0",
36
+ "@atlasauth/pca": "0.2.0"
37
+ },
38
+ "devDependencies": {
39
+ "typescript": "^5.6.3",
40
+ "vitest": "^2.1.4"
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "README.md",
45
+ "LICENSE"
46
+ ],
47
+ "engines": {
48
+ "node": ">=20"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -p tsconfig.build.json",
55
+ "typecheck": "tsc -p tsconfig.json --noEmit",
56
+ "test": "vitest run"
57
+ }
6
58
  }