@atlasauth/pca-aggsig 0.0.0-stage → 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/dist/bls.d.ts ADDED
@@ -0,0 +1,77 @@
1
+ /**
2
+ * BLS signatures on BLS12-381, aggregation-ready.
3
+ *
4
+ * SCHEME — Proof-of-Possession (PoP), per draft-irtf-cfrg-bls-signature-05 §3.3.
5
+ * Variant: "minimal-pubkey-size" — public keys live in G1 (48 bytes compressed), signatures in
6
+ * G2 (96 bytes compressed). This is the eth2 / Ethereum-consensus convention.
7
+ *
8
+ * WHY PoP (not message-augmentation / basic): the whole point of this package is to aggregate
9
+ * signatures from DIFFERENT keys — a delegation chain's per-hop keys, and a quorum of transparency
10
+ * witnesses cosigning the SAME statement. Same-message aggregation is exactly where the rogue-key
11
+ * attack lives: an adversary who registers pk_adv = pk_victim^-1 · g^a can forge an aggregate that
12
+ * "verifies" against {pk_victim, pk_adv}. PoP closes this: every key must ship a proof-of-possession
13
+ * (a signature, under a DISTINCT domain, over its own public key) that only the true secret-key
14
+ * holder can produce, so a rogue key chosen as a function of other keys cannot pass {@link popVerify}.
15
+ * The signing and PoP ciphersuites therefore use the `_POP_` domain separation tags below.
16
+ *
17
+ * Every function is total: verification never throws, it returns `false` on any malformed input.
18
+ */
19
+ /** Ciphersuite ID / hash-to-curve DST for SIGNATURES (PoP variant, signatures in G2). */
20
+ export declare const SIG_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
21
+ /** DISTINCT DST for proofs-of-possession, so a PoP can never be replayed as a message signature. */
22
+ export declare const POP_DST = "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
23
+ /** Compressed G1 public-key length in bytes. */
24
+ export declare const PUBLIC_KEY_LENGTH = 48;
25
+ /** Compressed G2 signature length in bytes. */
26
+ export declare const SIGNATURE_LENGTH = 96;
27
+ export interface BlsKeyPair {
28
+ /** 32-byte scalar (mod r). */
29
+ secretKey: Uint8Array;
30
+ /** 48-byte compressed G1 point. */
31
+ publicKey: Uint8Array;
32
+ }
33
+ /** Fresh key pair: a random scalar mod r and its G1 public key. */
34
+ export declare function keyGen(): BlsKeyPair;
35
+ /** Public key (compressed G1) for a secret scalar. */
36
+ export declare function publicKeyOf(secretKey: Uint8Array): Uint8Array;
37
+ /**
38
+ * KeyValidate (draft §2.5): the public key decodes to a valid point, is NOT the identity, and lies
39
+ * in the prime-order subgroup. A key that fails this is rejected everywhere before it can contribute
40
+ * to an aggregate. Never throws.
41
+ */
42
+ export declare function keyValidate(publicKey: Uint8Array): boolean;
43
+ /** CoreSign: H(msg) in G2 under the signature DST, multiplied by the secret scalar. */
44
+ export declare function sign(secretKey: Uint8Array, msg: Uint8Array): Uint8Array;
45
+ /** CoreVerify of a single signature: e(pk, H(msg)) == e(g1, sig). Never throws. */
46
+ export declare function verify(publicKey: Uint8Array, msg: Uint8Array, sig: Uint8Array): boolean;
47
+ /**
48
+ * Aggregate: sum the G2 signature points into one 96-byte aggregate. Order-independent. Requires at
49
+ * least one signature.
50
+ */
51
+ export declare function aggregate(sigs: Uint8Array[]): Uint8Array;
52
+ /** Aggregate a set of G1 public keys into one 48-byte key (used by {@link fastAggregateVerify}). */
53
+ export declare function aggregatePublicKeys(publicKeys: Uint8Array[]): Uint8Array;
54
+ /**
55
+ * AggregateVerify (draft §3.1.1) for DISTINCT messages: one pairing-product check that all N hops'
56
+ * signatures are present in the aggregate — e(g1, aggSig) == Π e(pk_i, H(msg_i)).
57
+ *
58
+ * The draft REQUIRES the messages be pairwise distinct (same-message aggregation across different keys
59
+ * must go through {@link fastAggregateVerify}); we enforce that as defence-in-depth even though PoP
60
+ * already defeats the rogue-key attack. Every public key is KeyValidate'd first. Never throws; returns
61
+ * `false` on length mismatch, a repeated message, a bad key, or a failed pairing check.
62
+ */
63
+ export declare function aggregateVerify(publicKeys: Uint8Array[], msgs: Uint8Array[], aggSig: Uint8Array): boolean;
64
+ /**
65
+ * FastAggregateVerify (draft §3.3.4): all signers signed the SAME message. Aggregate the public keys
66
+ * into one, then a single CoreVerify — e(g1, aggSig) == e(Σ pk_i, H(msg)). This is the surface for a
67
+ * quorum of transparency witnesses cosigning one tree head. KeyValidate'd; never throws.
68
+ */
69
+ export declare function fastAggregateVerify(publicKeys: Uint8Array[], msg: Uint8Array, aggSig: Uint8Array): boolean;
70
+ /**
71
+ * PopProve (draft §3.3.2): sign one's OWN public key under the PoP DST. Only the holder of the secret
72
+ * scalar can produce this, so a rogue key defined as a function of other keys cannot.
73
+ */
74
+ export declare function popProve(secretKey: Uint8Array): Uint8Array;
75
+ /** PopVerify (draft §3.3.3): the proof-of-possession is a valid PoP-DST signature by `publicKey` over
76
+ * `publicKey`. A key must pass this before it is admitted to any aggregate. Never throws. */
77
+ export declare function popVerify(publicKey: Uint8Array, pop: Uint8Array): boolean;
package/dist/bls.js ADDED
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SIGNATURE_LENGTH = exports.PUBLIC_KEY_LENGTH = exports.POP_DST = exports.SIG_DST = void 0;
4
+ exports.keyGen = keyGen;
5
+ exports.publicKeyOf = publicKeyOf;
6
+ exports.keyValidate = keyValidate;
7
+ exports.sign = sign;
8
+ exports.verify = verify;
9
+ exports.aggregate = aggregate;
10
+ exports.aggregatePublicKeys = aggregatePublicKeys;
11
+ exports.aggregateVerify = aggregateVerify;
12
+ exports.fastAggregateVerify = fastAggregateVerify;
13
+ exports.popProve = popProve;
14
+ exports.popVerify = popVerify;
15
+ const bls12_381_1 = require("@noble/curves/bls12-381");
16
+ const utils_1 = require("@noble/hashes/utils");
17
+ /**
18
+ * BLS signatures on BLS12-381, aggregation-ready.
19
+ *
20
+ * SCHEME — Proof-of-Possession (PoP), per draft-irtf-cfrg-bls-signature-05 §3.3.
21
+ * Variant: "minimal-pubkey-size" — public keys live in G1 (48 bytes compressed), signatures in
22
+ * G2 (96 bytes compressed). This is the eth2 / Ethereum-consensus convention.
23
+ *
24
+ * WHY PoP (not message-augmentation / basic): the whole point of this package is to aggregate
25
+ * signatures from DIFFERENT keys — a delegation chain's per-hop keys, and a quorum of transparency
26
+ * witnesses cosigning the SAME statement. Same-message aggregation is exactly where the rogue-key
27
+ * attack lives: an adversary who registers pk_adv = pk_victim^-1 · g^a can forge an aggregate that
28
+ * "verifies" against {pk_victim, pk_adv}. PoP closes this: every key must ship a proof-of-possession
29
+ * (a signature, under a DISTINCT domain, over its own public key) that only the true secret-key
30
+ * holder can produce, so a rogue key chosen as a function of other keys cannot pass {@link popVerify}.
31
+ * The signing and PoP ciphersuites therefore use the `_POP_` domain separation tags below.
32
+ *
33
+ * Every function is total: verification never throws, it returns `false` on any malformed input.
34
+ */
35
+ /** Ciphersuite ID / hash-to-curve DST for SIGNATURES (PoP variant, signatures in G2). */
36
+ exports.SIG_DST = 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_';
37
+ /** DISTINCT DST for proofs-of-possession, so a PoP can never be replayed as a message signature. */
38
+ exports.POP_DST = 'BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_';
39
+ /** Compressed G1 public-key length in bytes. */
40
+ exports.PUBLIC_KEY_LENGTH = 48;
41
+ /** Compressed G2 signature length in bytes. */
42
+ exports.SIGNATURE_LENGTH = 96;
43
+ const SIG_OPTS = { DST: exports.SIG_DST };
44
+ const POP_OPTS = { DST: exports.POP_DST };
45
+ /** Fresh key pair: a random scalar mod r and its G1 public key. */
46
+ function keyGen() {
47
+ const secretKey = bls12_381_1.bls12_381.utils.randomPrivateKey();
48
+ return { secretKey, publicKey: bls12_381_1.bls12_381.getPublicKey(secretKey) };
49
+ }
50
+ /** Public key (compressed G1) for a secret scalar. */
51
+ function publicKeyOf(secretKey) {
52
+ return bls12_381_1.bls12_381.getPublicKey(secretKey);
53
+ }
54
+ /**
55
+ * KeyValidate (draft §2.5): the public key decodes to a valid point, is NOT the identity, and lies
56
+ * in the prime-order subgroup. A key that fails this is rejected everywhere before it can contribute
57
+ * to an aggregate. Never throws.
58
+ */
59
+ function keyValidate(publicKey) {
60
+ try {
61
+ const P = bls12_381_1.bls12_381.G1.ProjectivePoint.fromHex(publicKey);
62
+ if (P.equals(bls12_381_1.bls12_381.G1.ProjectivePoint.ZERO))
63
+ return false;
64
+ P.assertValidity();
65
+ return P.isTorsionFree();
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
71
+ /** CoreSign: H(msg) in G2 under the signature DST, multiplied by the secret scalar. */
72
+ function sign(secretKey, msg) {
73
+ return bls12_381_1.bls12_381.sign(msg, secretKey, SIG_OPTS);
74
+ }
75
+ /** CoreVerify of a single signature: e(pk, H(msg)) == e(g1, sig). Never throws. */
76
+ function verify(publicKey, msg, sig) {
77
+ try {
78
+ if (!keyValidate(publicKey))
79
+ return false;
80
+ return bls12_381_1.bls12_381.verify(sig, msg, publicKey, SIG_OPTS);
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ /**
87
+ * Aggregate: sum the G2 signature points into one 96-byte aggregate. Order-independent. Requires at
88
+ * least one signature.
89
+ */
90
+ function aggregate(sigs) {
91
+ if (sigs.length === 0)
92
+ throw new RangeError('aggregate: need at least one signature');
93
+ return bls12_381_1.bls12_381.aggregateSignatures(sigs);
94
+ }
95
+ /** Aggregate a set of G1 public keys into one 48-byte key (used by {@link fastAggregateVerify}). */
96
+ function aggregatePublicKeys(publicKeys) {
97
+ if (publicKeys.length === 0)
98
+ throw new RangeError('aggregatePublicKeys: need at least one key');
99
+ return bls12_381_1.bls12_381.aggregatePublicKeys(publicKeys);
100
+ }
101
+ function hasDistinctMessages(msgs) {
102
+ const seen = new Set();
103
+ for (const m of msgs) {
104
+ const h = (0, utils_1.bytesToHex)(m);
105
+ if (seen.has(h))
106
+ return false;
107
+ seen.add(h);
108
+ }
109
+ return true;
110
+ }
111
+ /**
112
+ * AggregateVerify (draft §3.1.1) for DISTINCT messages: one pairing-product check that all N hops'
113
+ * signatures are present in the aggregate — e(g1, aggSig) == Π e(pk_i, H(msg_i)).
114
+ *
115
+ * The draft REQUIRES the messages be pairwise distinct (same-message aggregation across different keys
116
+ * must go through {@link fastAggregateVerify}); we enforce that as defence-in-depth even though PoP
117
+ * already defeats the rogue-key attack. Every public key is KeyValidate'd first. Never throws; returns
118
+ * `false` on length mismatch, a repeated message, a bad key, or a failed pairing check.
119
+ */
120
+ function aggregateVerify(publicKeys, msgs, aggSig) {
121
+ try {
122
+ if (publicKeys.length === 0 || publicKeys.length !== msgs.length)
123
+ return false;
124
+ if (!hasDistinctMessages(msgs))
125
+ return false;
126
+ for (const pk of publicKeys) {
127
+ if (!keyValidate(pk))
128
+ return false;
129
+ }
130
+ return bls12_381_1.bls12_381.verifyBatch(aggSig, msgs, publicKeys, SIG_OPTS);
131
+ }
132
+ catch {
133
+ return false;
134
+ }
135
+ }
136
+ /**
137
+ * FastAggregateVerify (draft §3.3.4): all signers signed the SAME message. Aggregate the public keys
138
+ * into one, then a single CoreVerify — e(g1, aggSig) == e(Σ pk_i, H(msg)). This is the surface for a
139
+ * quorum of transparency witnesses cosigning one tree head. KeyValidate'd; never throws.
140
+ */
141
+ function fastAggregateVerify(publicKeys, msg, aggSig) {
142
+ try {
143
+ if (publicKeys.length === 0)
144
+ return false;
145
+ for (const pk of publicKeys) {
146
+ if (!keyValidate(pk))
147
+ return false;
148
+ }
149
+ const aggPk = bls12_381_1.bls12_381.aggregatePublicKeys(publicKeys);
150
+ return bls12_381_1.bls12_381.verify(aggSig, msg, aggPk, SIG_OPTS);
151
+ }
152
+ catch {
153
+ return false;
154
+ }
155
+ }
156
+ /**
157
+ * PopProve (draft §3.3.2): sign one's OWN public key under the PoP DST. Only the holder of the secret
158
+ * scalar can produce this, so a rogue key defined as a function of other keys cannot.
159
+ */
160
+ function popProve(secretKey) {
161
+ const pk = bls12_381_1.bls12_381.getPublicKey(secretKey);
162
+ return bls12_381_1.bls12_381.sign(pk, secretKey, POP_OPTS);
163
+ }
164
+ /** PopVerify (draft §3.3.3): the proof-of-possession is a valid PoP-DST signature by `publicKey` over
165
+ * `publicKey`. A key must pass this before it is admitted to any aggregate. Never throws. */
166
+ function popVerify(publicKey, pop) {
167
+ try {
168
+ if (!keyValidate(publicKey))
169
+ return false;
170
+ return bls12_381_1.bls12_381.verify(pop, publicKey, publicKey, POP_OPTS);
171
+ }
172
+ catch {
173
+ return false;
174
+ }
175
+ }
176
+ //# sourceMappingURL=bls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bls.js","sourceRoot":"","sources":["../src/bls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { type Caveat, type ChainResult } from '@atlasauth/pca';
2
+ /** The signature suite tag carried on every BLS hop. */
3
+ export declare const BLS_SUITE: "bls12-381-pop";
4
+ export interface BlsCapability {
5
+ /** Content address of the signed body (== `body_digest`). */
6
+ id: string;
7
+ /** b64u BLS12-381 G1 public key that signed this hop. Root: the principal; child: the parent's holder. */
8
+ issuer: string;
9
+ /** b64u BLS12-381 G1 public key this capability is bound to (cnf). */
10
+ holder: string;
11
+ caveats: Caveat[];
12
+ /** {@link capHash} of the parent capability; absent on the root. */
13
+ parent?: string;
14
+ body_digest: string;
15
+ /** b64u BLS12-381 G2 signature over the domain-separated hop body. */
16
+ sig: string;
17
+ suite: typeof BLS_SUITE;
18
+ }
19
+ export type BlsCapabilityChain = BlsCapability[];
20
+ /** Longest delegation chain accepted (bounds verification cost; mirrors the core chain's limit). */
21
+ export declare const MAX_CHAIN_DEPTH = 16;
22
+ /** Hash of a full capability (signature included); used as the child's `parent` link. */
23
+ export declare function capHash(c: BlsCapability): string;
24
+ /** b64u BLS G1 public key for a secret scalar — the identity a chain is rooted at / delegated to. */
25
+ export declare function blsPublicKey(secretKey: Uint8Array): string;
26
+ /** Mint a root capability, signed by the principal (root issuer). */
27
+ export declare function mintBlsRoot(args: {
28
+ principalSecret: Uint8Array;
29
+ /** b64u BLS G1 principal key. */
30
+ principalPublic: string;
31
+ /** b64u BLS G1 holder key. */
32
+ holder: string;
33
+ caveats: Caveat[];
34
+ }): BlsCapability;
35
+ /** Child with the SAME holder; caveats = parent.caveats ++ added. Signed by the parent's holder. */
36
+ export declare function blsAttenuate(parent: BlsCapability, addedCaveats: Caveat[], signerSecret: Uint8Array): BlsCapability;
37
+ /** Like {@link blsAttenuate}, but rebinds `holder` to a new sub-agent key. */
38
+ export declare function blsDelegate(parent: BlsCapability, toHolder: string, addedCaveats: Caveat[], signerSecret: Uint8Array): BlsCapability;
39
+ /**
40
+ * Collapse every per-hop BLS signature in `chain` into ONE 96-byte aggregate. The chain's hop bodies
41
+ * are not re-derived here — only the signatures are summed; {@link verifyAggregatedChain} re-derives
42
+ * and checks them. Throws on an empty chain or a hop whose `sig` is not valid b64u.
43
+ */
44
+ export declare function aggregateChainSignatures(chain: BlsCapabilityChain): Uint8Array;
45
+ /**
46
+ * Verify an ENTIRE BLS capability chain against one aggregate signature.
47
+ *
48
+ * Does all the structural checks the core `verifyChain` does — depth bound, well-typedness, root has
49
+ * no parent, optional expected root principal, parent hash-links, holder→issuer continuity, and
50
+ * append-only caveat prefixes — then verifies all M hop signatures at once with a single
51
+ * distinct-message AggregateVerify over each hop's (issuer key, signed body) pair. Never throws.
52
+ */
53
+ export declare function verifyAggregatedChain(chain: BlsCapabilityChain, aggSig: Uint8Array, expectedRootPrincipal?: string): ChainResult;
package/dist/chain.js ADDED
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_CHAIN_DEPTH = exports.BLS_SUITE = void 0;
4
+ exports.capHash = capHash;
5
+ exports.blsPublicKey = blsPublicKey;
6
+ exports.mintBlsRoot = mintBlsRoot;
7
+ exports.blsAttenuate = blsAttenuate;
8
+ exports.blsDelegate = blsDelegate;
9
+ exports.aggregateChainSignatures = aggregateChainSignatures;
10
+ exports.verifyAggregatedChain = verifyAggregatedChain;
11
+ const pca_1 = require("@atlasauth/pca");
12
+ const bls_1 = require("./bls");
13
+ /**
14
+ * A BLS-suite attenuable capability chain — the compact alternative to the core PCA chain's N
15
+ * separate Ed25519 hop signatures.
16
+ *
17
+ * The chain's STRUCTURE is identical to `@atlasauth/pca`'s Ed25519 `Capability`: each hop signs the
18
+ * canonical body `{ issuer, holder, caveats, parent }`, caveats are append-only (a child's array
19
+ * starts with the parent's exact prefix), holders bind to the next issuer, and parents are
20
+ * hash-linked. The ONLY difference is the signature: every hop is signed with the BLS12-381 PoP
21
+ * scheme (keys in G1, signatures in G2) instead of Ed25519.
22
+ *
23
+ * The payoff is {@link aggregateChainSignatures}: an M-hop chain's M per-hop signatures collapse into
24
+ * ONE 96-byte aggregate, and {@link verifyAggregatedChain} checks ALL M hops with a single
25
+ * pairing-product AggregateVerify instead of M separate verifications. Each hop signs a DISTINCT body
26
+ * (the parent hash-link alone differs per depth), so the distinct-message AggregateVerify applies.
27
+ */
28
+ /** Domain separator for a BLS capability hop — distinct from the core chain's `atlas-pca/cap/v1`. */
29
+ const CAP_BLS_DOMAIN = 'atlas-pca/cap-bls/v1\0';
30
+ /** The signature suite tag carried on every BLS hop. */
31
+ exports.BLS_SUITE = 'bls12-381-pop';
32
+ /** Longest delegation chain accepted (bounds verification cost; mirrors the core chain's limit). */
33
+ exports.MAX_CHAIN_DEPTH = 16;
34
+ function bodyOf(c) {
35
+ return { issuer: c.issuer, holder: c.holder, caveats: c.caveats, parent: c.parent ?? null };
36
+ }
37
+ /** The exact bytes a hop signs: the domain separator followed by the raw body digest. */
38
+ function sigMessage(bodyDigest) {
39
+ const d = (0, pca_1.unb64u)(bodyDigest);
40
+ const p = (0, pca_1.utf8)(CAP_BLS_DOMAIN);
41
+ const m = new Uint8Array(p.length + d.length);
42
+ m.set(p);
43
+ m.set(d, p.length);
44
+ return m;
45
+ }
46
+ /** Hash of a full capability (signature included); used as the child's `parent` link. */
47
+ function capHash(c) {
48
+ return (0, pca_1.hashCanonical)(c);
49
+ }
50
+ function cloneCaveats(cs) {
51
+ const parsed = JSON.parse(new TextDecoder().decode((0, pca_1.canonicalBytes)(cs)));
52
+ return parsed;
53
+ }
54
+ function seal(body, signerSecret) {
55
+ const body_digest = (0, pca_1.hashCanonical)(bodyOf(body));
56
+ const sig = (0, pca_1.b64u)((0, bls_1.sign)(signerSecret, sigMessage(body_digest)));
57
+ const cap = {
58
+ id: body_digest,
59
+ issuer: body.issuer,
60
+ holder: body.holder,
61
+ caveats: body.caveats,
62
+ body_digest,
63
+ sig,
64
+ suite: exports.BLS_SUITE,
65
+ };
66
+ if (body.parent !== undefined)
67
+ cap.parent = body.parent;
68
+ return cap;
69
+ }
70
+ /** b64u BLS G1 public key for a secret scalar — the identity a chain is rooted at / delegated to. */
71
+ function blsPublicKey(secretKey) {
72
+ return (0, pca_1.b64u)((0, bls_1.publicKeyOf)(secretKey));
73
+ }
74
+ /** Mint a root capability, signed by the principal (root issuer). */
75
+ function mintBlsRoot(args) {
76
+ return seal({ issuer: args.principalPublic, holder: args.holder, caveats: cloneCaveats(args.caveats) }, args.principalSecret);
77
+ }
78
+ /** Child with the SAME holder; caveats = parent.caveats ++ added. Signed by the parent's holder. */
79
+ function blsAttenuate(parent, addedCaveats, signerSecret) {
80
+ return blsDelegate(parent, parent.holder, addedCaveats, signerSecret);
81
+ }
82
+ /** Like {@link blsAttenuate}, but rebinds `holder` to a new sub-agent key. */
83
+ function blsDelegate(parent, toHolder, addedCaveats, signerSecret) {
84
+ return seal({
85
+ issuer: parent.holder,
86
+ holder: toHolder,
87
+ caveats: [...cloneCaveats(parent.caveats), ...cloneCaveats(addedCaveats)],
88
+ parent: capHash(parent),
89
+ }, signerSecret);
90
+ }
91
+ function wellTyped(c) {
92
+ if (c === null || typeof c !== 'object')
93
+ return false;
94
+ const x = c;
95
+ return (typeof x.id === 'string' &&
96
+ typeof x.issuer === 'string' &&
97
+ typeof x.holder === 'string' &&
98
+ typeof x.body_digest === 'string' &&
99
+ typeof x.sig === 'string' &&
100
+ x.suite === exports.BLS_SUITE &&
101
+ (x.parent === undefined || typeof x.parent === 'string') &&
102
+ Array.isArray(x.caveats) &&
103
+ x.caveats.every((cv) => cv !== null && typeof cv === 'object' && !Array.isArray(cv) && typeof cv.type === 'string'));
104
+ }
105
+ /**
106
+ * Collapse every per-hop BLS signature in `chain` into ONE 96-byte aggregate. The chain's hop bodies
107
+ * are not re-derived here — only the signatures are summed; {@link verifyAggregatedChain} re-derives
108
+ * and checks them. Throws on an empty chain or a hop whose `sig` is not valid b64u.
109
+ */
110
+ function aggregateChainSignatures(chain) {
111
+ if (!Array.isArray(chain) || chain.length === 0)
112
+ throw new RangeError('aggregateChainSignatures: empty chain');
113
+ return (0, bls_1.aggregate)(chain.map((c) => (0, pca_1.unb64u)(c.sig)));
114
+ }
115
+ /**
116
+ * Verify an ENTIRE BLS capability chain against one aggregate signature.
117
+ *
118
+ * Does all the structural checks the core `verifyChain` does — depth bound, well-typedness, root has
119
+ * no parent, optional expected root principal, parent hash-links, holder→issuer continuity, and
120
+ * append-only caveat prefixes — then verifies all M hop signatures at once with a single
121
+ * distinct-message AggregateVerify over each hop's (issuer key, signed body) pair. Never throws.
122
+ */
123
+ function verifyAggregatedChain(chain, aggSig, expectedRootPrincipal) {
124
+ if (!Array.isArray(chain) || chain.length === 0)
125
+ return { ok: false, reason: 'empty chain' };
126
+ if (chain.length > exports.MAX_CHAIN_DEPTH)
127
+ return { ok: false, reason: `chain too long (max ${exports.MAX_CHAIN_DEPTH} hops)` };
128
+ for (let i = 0; i < chain.length; i++) {
129
+ if (!wellTyped(chain[i]))
130
+ return { ok: false, reason: `hop ${i}: malformed capability` };
131
+ }
132
+ const pks = [];
133
+ const msgs = [];
134
+ const root = chain[0];
135
+ if (root === undefined)
136
+ return { ok: false, reason: 'empty chain' };
137
+ if (root.parent !== undefined)
138
+ return { ok: false, reason: 'hop 0: root must not have a parent' };
139
+ if (expectedRootPrincipal !== undefined && root.issuer !== expectedRootPrincipal) {
140
+ return { ok: false, reason: 'hop 0: root issuer is not the expected principal' };
141
+ }
142
+ for (let i = 0; i < chain.length; i++) {
143
+ const c = chain[i];
144
+ if (c === undefined)
145
+ return { ok: false, reason: `hop ${i}: missing` };
146
+ let digest;
147
+ try {
148
+ digest = (0, pca_1.hashCanonical)(bodyOf(c));
149
+ }
150
+ catch {
151
+ return { ok: false, reason: `hop ${i}: malformed body` };
152
+ }
153
+ if (digest !== c.body_digest || c.id !== c.body_digest)
154
+ return { ok: false, reason: `hop ${i}: body digest mismatch` };
155
+ let pk;
156
+ try {
157
+ pk = (0, pca_1.unb64u)(c.issuer);
158
+ }
159
+ catch {
160
+ return { ok: false, reason: `hop ${i}: malformed issuer key` };
161
+ }
162
+ if (i > 0) {
163
+ const parent = chain[i - 1];
164
+ if (parent === undefined)
165
+ return { ok: false, reason: `hop ${i}: missing parent` };
166
+ if (c.parent !== capHash(parent))
167
+ return { ok: false, reason: `hop ${i}: broken parent link` };
168
+ if (c.issuer !== parent.holder)
169
+ return { ok: false, reason: `hop ${i}: issuer is not the parent's bound holder` };
170
+ if (c.caveats.length < parent.caveats.length)
171
+ return { ok: false, reason: `hop ${i}: drops parent caveat(s)` };
172
+ for (let j = 0; j < parent.caveats.length; j++) {
173
+ if ((0, pca_1.hashCanonical)(c.caveats[j]) !== (0, pca_1.hashCanonical)(parent.caveats[j])) {
174
+ return { ok: false, reason: `hop ${i}: caveat ${j} altered or reordered` };
175
+ }
176
+ }
177
+ }
178
+ pks.push(pk);
179
+ msgs.push(sigMessage(c.body_digest));
180
+ }
181
+ if (!(0, bls_1.aggregateVerify)(pks, msgs, aggSig)) {
182
+ return { ok: false, reason: 'aggregate signature does not verify over all hops' };
183
+ }
184
+ return { ok: true };
185
+ }
186
+ //# sourceMappingURL=chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @atlasauth/pca-aggsig — BLS12-381 signature aggregation for Proof-Carrying Authority.
3
+ *
4
+ * A whole delegation chain's per-hop signatures, and a transparency-ledger witness quorum's
5
+ * cosignatures, collapse into ONE compact aggregate signature verified with a single pairing-product
6
+ * check. Scheme: BLS (Boneh-Lynn-Shacham) with Proof-of-Possession (draft-irtf-cfrg-bls-signature),
7
+ * minimal-pubkey-size variant (G1 keys, G2 signatures). See {@link ./bls}.
8
+ */
9
+ export { SIG_DST, POP_DST, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH, type BlsKeyPair, keyGen, publicKeyOf, keyValidate, sign, verify, aggregate, aggregatePublicKeys, aggregateVerify, fastAggregateVerify, popProve, popVerify, } from './bls';
10
+ export { BLS_SUITE, MAX_CHAIN_DEPTH, type BlsCapability, type BlsCapabilityChain, capHash, blsPublicKey, mintBlsRoot, blsAttenuate, blsDelegate, aggregateChainSignatures, verifyAggregatedChain, } from './chain';
11
+ export { type SthStatement, type BlsWitnessCosignature, cosignTreeHead, verifyWitnessCosignature, aggregateWitnessCosignatures, verifyAggregatedWitnessCosignatures, } from './witness';
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * @atlasauth/pca-aggsig — BLS12-381 signature aggregation for Proof-Carrying Authority.
4
+ *
5
+ * A whole delegation chain's per-hop signatures, and a transparency-ledger witness quorum's
6
+ * cosignatures, collapse into ONE compact aggregate signature verified with a single pairing-product
7
+ * check. Scheme: BLS (Boneh-Lynn-Shacham) with Proof-of-Possession (draft-irtf-cfrg-bls-signature),
8
+ * minimal-pubkey-size variant (G1 keys, G2 signatures). See {@link ./bls}.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.verifyAggregatedWitnessCosignatures = exports.aggregateWitnessCosignatures = exports.verifyWitnessCosignature = exports.cosignTreeHead = exports.verifyAggregatedChain = exports.aggregateChainSignatures = exports.blsDelegate = exports.blsAttenuate = exports.mintBlsRoot = exports.blsPublicKey = exports.capHash = exports.MAX_CHAIN_DEPTH = exports.BLS_SUITE = exports.popVerify = exports.popProve = exports.fastAggregateVerify = exports.aggregateVerify = exports.aggregatePublicKeys = exports.aggregate = exports.verify = exports.sign = exports.keyValidate = exports.publicKeyOf = exports.keyGen = exports.SIGNATURE_LENGTH = exports.PUBLIC_KEY_LENGTH = exports.POP_DST = exports.SIG_DST = void 0;
12
+ // Core BLS scheme + aggregation.
13
+ var bls_1 = require("./bls");
14
+ Object.defineProperty(exports, "SIG_DST", { enumerable: true, get: function () { return bls_1.SIG_DST; } });
15
+ Object.defineProperty(exports, "POP_DST", { enumerable: true, get: function () { return bls_1.POP_DST; } });
16
+ Object.defineProperty(exports, "PUBLIC_KEY_LENGTH", { enumerable: true, get: function () { return bls_1.PUBLIC_KEY_LENGTH; } });
17
+ Object.defineProperty(exports, "SIGNATURE_LENGTH", { enumerable: true, get: function () { return bls_1.SIGNATURE_LENGTH; } });
18
+ Object.defineProperty(exports, "keyGen", { enumerable: true, get: function () { return bls_1.keyGen; } });
19
+ Object.defineProperty(exports, "publicKeyOf", { enumerable: true, get: function () { return bls_1.publicKeyOf; } });
20
+ Object.defineProperty(exports, "keyValidate", { enumerable: true, get: function () { return bls_1.keyValidate; } });
21
+ Object.defineProperty(exports, "sign", { enumerable: true, get: function () { return bls_1.sign; } });
22
+ Object.defineProperty(exports, "verify", { enumerable: true, get: function () { return bls_1.verify; } });
23
+ Object.defineProperty(exports, "aggregate", { enumerable: true, get: function () { return bls_1.aggregate; } });
24
+ Object.defineProperty(exports, "aggregatePublicKeys", { enumerable: true, get: function () { return bls_1.aggregatePublicKeys; } });
25
+ Object.defineProperty(exports, "aggregateVerify", { enumerable: true, get: function () { return bls_1.aggregateVerify; } });
26
+ Object.defineProperty(exports, "fastAggregateVerify", { enumerable: true, get: function () { return bls_1.fastAggregateVerify; } });
27
+ Object.defineProperty(exports, "popProve", { enumerable: true, get: function () { return bls_1.popProve; } });
28
+ Object.defineProperty(exports, "popVerify", { enumerable: true, get: function () { return bls_1.popVerify; } });
29
+ // PCA BLS-suite capability chain.
30
+ var chain_1 = require("./chain");
31
+ Object.defineProperty(exports, "BLS_SUITE", { enumerable: true, get: function () { return chain_1.BLS_SUITE; } });
32
+ Object.defineProperty(exports, "MAX_CHAIN_DEPTH", { enumerable: true, get: function () { return chain_1.MAX_CHAIN_DEPTH; } });
33
+ Object.defineProperty(exports, "capHash", { enumerable: true, get: function () { return chain_1.capHash; } });
34
+ Object.defineProperty(exports, "blsPublicKey", { enumerable: true, get: function () { return chain_1.blsPublicKey; } });
35
+ Object.defineProperty(exports, "mintBlsRoot", { enumerable: true, get: function () { return chain_1.mintBlsRoot; } });
36
+ Object.defineProperty(exports, "blsAttenuate", { enumerable: true, get: function () { return chain_1.blsAttenuate; } });
37
+ Object.defineProperty(exports, "blsDelegate", { enumerable: true, get: function () { return chain_1.blsDelegate; } });
38
+ Object.defineProperty(exports, "aggregateChainSignatures", { enumerable: true, get: function () { return chain_1.aggregateChainSignatures; } });
39
+ Object.defineProperty(exports, "verifyAggregatedChain", { enumerable: true, get: function () { return chain_1.verifyAggregatedChain; } });
40
+ // Transparency-ledger witness cosignature aggregation.
41
+ var witness_1 = require("./witness");
42
+ Object.defineProperty(exports, "cosignTreeHead", { enumerable: true, get: function () { return witness_1.cosignTreeHead; } });
43
+ Object.defineProperty(exports, "verifyWitnessCosignature", { enumerable: true, get: function () { return witness_1.verifyWitnessCosignature; } });
44
+ Object.defineProperty(exports, "aggregateWitnessCosignatures", { enumerable: true, get: function () { return witness_1.aggregateWitnessCosignatures; } });
45
+ Object.defineProperty(exports, "verifyAggregatedWitnessCosignatures", { enumerable: true, get: function () { return witness_1.verifyAggregatedWitnessCosignatures; } });
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,iCAAiC;AACjC,6BAiBe;AAhBb,8FAAA,OAAO,OAAA;AACP,8FAAA,OAAO,OAAA;AACP,wGAAA,iBAAiB,OAAA;AACjB,uGAAA,gBAAgB,OAAA;AAEhB,6FAAA,MAAM,OAAA;AACN,kGAAA,WAAW,OAAA;AACX,kGAAA,WAAW,OAAA;AACX,2FAAA,IAAI,OAAA;AACJ,6FAAA,MAAM,OAAA;AACN,gGAAA,SAAS,OAAA;AACT,0GAAA,mBAAmB,OAAA;AACnB,sGAAA,eAAe,OAAA;AACf,0GAAA,mBAAmB,OAAA;AACnB,+FAAA,QAAQ,OAAA;AACR,gGAAA,SAAS,OAAA;AAGX,kCAAkC;AAClC,iCAYiB;AAXf,kGAAA,SAAS,OAAA;AACT,wGAAA,eAAe,OAAA;AAGf,gGAAA,OAAO,OAAA;AACP,qGAAA,YAAY,OAAA;AACZ,oGAAA,WAAW,OAAA;AACX,qGAAA,YAAY,OAAA;AACZ,oGAAA,WAAW,OAAA;AACX,iHAAA,wBAAwB,OAAA;AACxB,8GAAA,qBAAqB,OAAA;AAGvB,uDAAuD;AACvD,qCAOmB;AAJjB,yGAAA,cAAc,OAAA;AACd,mHAAA,wBAAwB,OAAA;AACxB,uHAAA,4BAA4B,OAAA;AAC5B,8HAAA,mCAAmC,OAAA"}
@@ -0,0 +1,28 @@
1
+ import { type SignedTreeHead } from '@atlasauth/pca';
2
+ import { BLS_SUITE } from './chain';
3
+ /** The tree-head statement a witness binds to — the same fields the core ledger cosigns. */
4
+ export type SthStatement = Pick<SignedTreeHead, 'size' | 'root' | 'prev_root' | 'guardian_epoch'>;
5
+ /** A BLS C2SP tlog-witness cosignature. */
6
+ export interface BlsWitnessCosignature {
7
+ /** b64u BLS12-381 G1 witness public key. */
8
+ key: string;
9
+ /** b64u BLS12-381 G2 signature over the domain-separated STH statement. */
10
+ sig: string;
11
+ suite: typeof BLS_SUITE;
12
+ }
13
+ /** A trusted witness cosigns the tree-head statement with its BLS secret key. */
14
+ export declare function cosignTreeHead(statement: SthStatement, witnessSecret: Uint8Array): BlsWitnessCosignature;
15
+ /** Verify ONE cosignature against the exact tree-head statement. Never throws. */
16
+ export declare function verifyWitnessCosignature(statement: SthStatement, cosig: BlsWitnessCosignature): boolean;
17
+ /**
18
+ * Collapse a quorum of witness cosignatures into ONE 96-byte aggregate. Throws on an empty set or a
19
+ * cosignature whose `sig` is not valid b64u.
20
+ */
21
+ export declare function aggregateWitnessCosignatures(cosigs: BlsWitnessCosignature[]): Uint8Array;
22
+ /**
23
+ * Verify an aggregate of witness cosignatures over ONE tree-head statement with a single
24
+ * FastAggregateVerify. `witnessKeys` are the b64u public keys whose cosignatures were aggregated (the
25
+ * caller supplies exactly the quorum it trusts); every key is KeyValidate'd. Never throws; returns
26
+ * `false` on an empty set, a malformed key, or a failed pairing check.
27
+ */
28
+ export declare function verifyAggregatedWitnessCosignatures(statement: SthStatement, witnessKeys: string[], aggSig: Uint8Array): boolean;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cosignTreeHead = cosignTreeHead;
4
+ exports.verifyWitnessCosignature = verifyWitnessCosignature;
5
+ exports.aggregateWitnessCosignatures = aggregateWitnessCosignatures;
6
+ exports.verifyAggregatedWitnessCosignatures = verifyAggregatedWitnessCosignatures;
7
+ const pca_1 = require("@atlasauth/pca");
8
+ const bls_1 = require("./bls");
9
+ const chain_1 = require("./chain");
10
+ /**
11
+ * BLS aggregation of transparency-ledger witness cosignatures (the C2SP tlog-witness / Sigsum model).
12
+ *
13
+ * In `@atlasauth/pca`'s ledger, a quorum of trusted witnesses each cosign the SAME tree-head statement
14
+ * — `{ size, root, prev_root, guardian_epoch }` — under their own key, turning a self-attested Signed
15
+ * Tree Head into an anti-equivocation artefact. With Ed25519 that is N independent signatures the
16
+ * monitor verifies one by one. Here each witness cosigns with the BLS12-381 PoP scheme, so
17
+ * {@link aggregateWitnessCosignatures} collapses the whole quorum into ONE 96-byte aggregate and
18
+ * {@link verifyAggregatedWitnessCosignatures} checks it with a single FastAggregateVerify (all
19
+ * witnesses signed the identical STH statement → same-message aggregation).
20
+ */
21
+ /** Domain separator — distinct from the Ed25519 ledger's `atlas-pca/sth-witness/v1`, so a BLS
22
+ * cosignature can never be confused with (or replayed against) the core witness domain. */
23
+ const STH_WITNESS_BLS_DOMAIN = 'atlas-pca/sth-witness-bls/v1\0';
24
+ /** The exact bytes a witness cosigns: domain separator followed by the canonical STH statement. */
25
+ function witnessMessage(h) {
26
+ const body = (0, pca_1.canonicalBytes)({
27
+ size: h.size,
28
+ root: h.root,
29
+ prev_root: h.prev_root,
30
+ guardian_epoch: h.guardian_epoch ?? 0,
31
+ });
32
+ const p = (0, pca_1.utf8)(STH_WITNESS_BLS_DOMAIN);
33
+ const m = new Uint8Array(p.length + body.length);
34
+ m.set(p);
35
+ m.set(body, p.length);
36
+ return m;
37
+ }
38
+ /** A trusted witness cosigns the tree-head statement with its BLS secret key. */
39
+ function cosignTreeHead(statement, witnessSecret) {
40
+ return {
41
+ key: (0, pca_1.b64u)((0, bls_1.publicKeyOf)(witnessSecret)),
42
+ sig: (0, pca_1.b64u)((0, bls_1.sign)(witnessSecret, witnessMessage(statement))),
43
+ suite: chain_1.BLS_SUITE,
44
+ };
45
+ }
46
+ /** Verify ONE cosignature against the exact tree-head statement. Never throws. */
47
+ function verifyWitnessCosignature(statement, cosig) {
48
+ try {
49
+ if (cosig === null || typeof cosig !== 'object' || cosig.suite !== chain_1.BLS_SUITE)
50
+ return false;
51
+ return (0, bls_1.fastAggregateVerify)([(0, pca_1.unb64u)(cosig.key)], witnessMessage(statement), (0, pca_1.unb64u)(cosig.sig));
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ /**
58
+ * Collapse a quorum of witness cosignatures into ONE 96-byte aggregate. Throws on an empty set or a
59
+ * cosignature whose `sig` is not valid b64u.
60
+ */
61
+ function aggregateWitnessCosignatures(cosigs) {
62
+ if (!Array.isArray(cosigs) || cosigs.length === 0)
63
+ throw new RangeError('aggregateWitnessCosignatures: empty set');
64
+ return (0, bls_1.aggregate)(cosigs.map((c) => (0, pca_1.unb64u)(c.sig)));
65
+ }
66
+ /**
67
+ * Verify an aggregate of witness cosignatures over ONE tree-head statement with a single
68
+ * FastAggregateVerify. `witnessKeys` are the b64u public keys whose cosignatures were aggregated (the
69
+ * caller supplies exactly the quorum it trusts); every key is KeyValidate'd. Never throws; returns
70
+ * `false` on an empty set, a malformed key, or a failed pairing check.
71
+ */
72
+ function verifyAggregatedWitnessCosignatures(statement, witnessKeys, aggSig) {
73
+ try {
74
+ if (!Array.isArray(witnessKeys) || witnessKeys.length === 0)
75
+ return false;
76
+ const pks = witnessKeys.map((k) => (0, pca_1.unb64u)(k));
77
+ return (0, bls_1.fastAggregateVerify)(pks, witnessMessage(statement), aggSig);
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ }
83
+ //# sourceMappingURL=witness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"witness.js","sourceRoot":"","sources":["../src/witness.ts"],"names":[],"mappings":";;AAgDA,wCAMC;AAGD,4DAOC;AAMD,oEAGC;AAQD,kFAQC;AAzFD,wCAAyF;AACzF,+BAA0E;AAC1E,mCAAoC;AAEpC;;;;;;;;;;GAUG;AAEH;4FAC4F;AAC5F,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAchE,mGAAmG;AACnG,SAAS,cAAc,CAAC,CAAe;IACrC,MAAM,IAAI,GAAG,IAAA,oBAAc,EAAC;QAC1B,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,cAAc,EAAE,CAAC,CAAC,cAAc,IAAI,CAAC;KACtC,CAAC,CAAC;IACH,MAAM,CAAC,GAAG,IAAA,UAAI,EAAC,sBAAsB,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACT,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,iFAAiF;AACjF,SAAgB,cAAc,CAAC,SAAuB,EAAE,aAAyB;IAC/E,OAAO;QACL,GAAG,EAAE,IAAA,UAAI,EAAC,IAAA,iBAAW,EAAC,aAAa,CAAC,CAAC;QACrC,GAAG,EAAE,IAAA,UAAI,EAAC,IAAA,UAAI,EAAC,aAAa,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;QACzD,KAAK,EAAE,iBAAS;KACjB,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,SAAgB,wBAAwB,CAAC,SAAuB,EAAE,KAA4B;IAC5F,IAAI,CAAC;QACH,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,iBAAS;YAAE,OAAO,KAAK,CAAC;QAC3F,OAAO,IAAA,yBAAmB,EAAC,CAAC,IAAA,YAAM,EAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,EAAE,IAAA,YAAM,EAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,4BAA4B,CAAC,MAA+B;IAC1E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,yCAAyC,CAAC,CAAC;IACnH,OAAO,IAAA,eAAS,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,YAAM,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mCAAmC,CAAC,SAAuB,EAAE,WAAqB,EAAE,MAAkB;IACpH,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1E,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,YAAM,EAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO,IAAA,yBAAmB,EAAC,GAAG,EAAE,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,35 @@
1
1
  {
2
2
  "name": "@atlasauth/pca-aggsig",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "BLS signature aggregation for PCA: collapse a delegation chain per-hop signatures and transparency-ledger witness cosignatures into one compact BLS12-381 aggregate with aggregate-verify.",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./package.json": "./package.json"
13
+ },
14
+ "dependencies": {
15
+ "@noble/curves": "^1.6.0",
16
+ "@noble/hashes": "^1.5.0",
17
+ "@atlasauth/pca": "0.1.0"
18
+ },
19
+ "devDependencies": {
20
+ "typescript": "^5.6.3",
21
+ "vitest": "^2.1.4"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.build.json",
32
+ "typecheck": "tsc -p tsconfig.json --noEmit",
33
+ "test": "vitest run"
34
+ }
6
35
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.