@atlasauth/pca-ratchet 0.3.0 → 0.4.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/README.md +4 -3
- package/dist/accumulator.d.ts +24 -0
- package/dist/accumulator.js +128 -50
- package/dist/accumulator.js.map +1 -1
- package/dist/adapters.d.ts +17 -1
- package/dist/adapters.js +37 -3
- package/dist/adapters.js.map +1 -1
- package/dist/binding.d.ts +87 -0
- package/dist/binding.js +115 -0
- package/dist/binding.js.map +1 -0
- package/dist/group.d.ts +8 -2
- package/dist/group.js +21 -5
- package/dist/group.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/ratchet.d.ts +9 -0
- package/dist/ratchet.js +17 -2
- package/dist/ratchet.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The PCA Capability Ratchet: two cryptographic primitives that replace bookkeeping in Proof-Carrying Authority with math.
|
|
4
4
|
|
|
5
|
-
1. **Puncturable forward-secure capability keys.** A GGM puncturable-PRF tree of one-time Ed25519 leaf keys under a Merkle-root commitment. Signing at a leaf
|
|
5
|
+
1. **Puncturable forward-secure capability keys.** A GGM puncturable-PRF tree of one-time Ed25519 leaf keys under a Merkle-root commitment. Signing at a leaf punctures it, so once the state has been erased a spent action cannot be re-signed by an adversary who obtains only the new state. A copy of the state taken BEFORE the signing can sign the same leaf again (nothing in a stateless verifier marks the second signature invalid): use `verifyLeafSignatureOnce` with a spent-leaf store for one-time use at the verifier. Adapters round risk up, so a nonzero risk never costs zero units.
|
|
6
6
|
2. **Homomorphic risk accumulator.** Pedersen commitments on ristretto255 plus a zero-knowledge range proof that the committed total risk stays at or under a budget ceiling, without revealing individual risks.
|
|
7
7
|
|
|
8
8
|
Small adapters map a PCActn `counter` to a leaf index and core risk scores to accumulator units.
|
|
@@ -46,11 +46,12 @@ verifyBudget(sum, 500, proof); // false
|
|
|
46
46
|
|
|
47
47
|
- Ratchet: `deriveRatchetRoot`, `signAtLeaf`, `verifyLeafSignature`, `availableLeaves`, `isLeafAvailable`, `RatchetError`, `MAX_RATCHET_DEPTH`.
|
|
48
48
|
- Accumulator: `commitRisk`, `addCommitments`, `openCommitment`, `proveBudget`, `verifyBudget`, `AccumulatorError`, `N_BITS`.
|
|
49
|
-
- Adapters: `counterToLeafIndex`, `leafIndexToCounter`, `leafIndexForAction`, `riskToUnits
|
|
49
|
+
- Adapters: `counterToLeafIndex`, `leafIndexToCounter`, `leafIndexForAction`, `riskToUnits` (rounds UP: a nonzero risk is never 0 units), `RiskQuantizer` (carries the sub-unit remainder so the running total is `ceil(true sum)`), `budgetCeilingUnits` (floors), `RISK_SCALE`.
|
|
50
|
+
- Verifier-side bindings (red-team RT-11): `leafNullifier`, `verifyLeafSignatureOnce` with a `SpentLeafStore` (`memorySpentLeafStore`, or implement over a shared store) returns `ok` / `replay` / `equivocation` (same leaf, different message: evidence of a holder that kept an old state) / `invalid` / `store-error`. `issueRiskCommitment`, `verifyRiskAttestation`, `verifyAttestedBudget`: the party that computes the risk commits to it and signs `(actionDigest, commitment)`, so a prover cannot commit 0 for a 1.0-risk action or move a commitment to another action.
|
|
50
51
|
|
|
51
52
|
## Status
|
|
52
53
|
|
|
53
|
-
Experimental. The cryptography here (GGM tree, Pedersen commitments, bit-decomposition range proof) is original and has **not**
|
|
54
|
+
Experimental. The cryptography here (GGM tree, Pedersen commitments, bit-decomposition range proof) is original and has been self-audited in tests (see the security audit in the PCA docs) but **not** independently audited; do not rely on it as the sole control for high-value actions. One-time-use is enforced by the key material only for an honest holder of the `RatchetState`; a verifier that wants it against a dishonest holder must use `verifyLeafSignatureOnce` with a spent-leaf store (Ed25519 here is deterministic, so a second signature does NOT reveal the key: reuse is detected by the verifier, not punished cryptographically, and the store must be shared and durable across the verifier fleet). Without a store, if a state is copied or restored from an old backup, spent leaves are available again, so persist the latest state atomically. `RatchetSignature` now carries a `nullifier` and `verifyLeafSignature` requires it (breaking: signatures made by earlier versions no longer verify). Commitments are only bound to the real action when issued through the attestation helpers; `verifyBoundedBudget` alone proves a property of whatever the prover committed. `verifyBudget` alone constrains only the SUM: use `proveRiskRange` per commitment and `verifyBoundedBudget` so a "negative" risk cannot cancel real risk.
|
|
54
55
|
|
|
55
56
|
## License
|
|
56
57
|
|
package/dist/accumulator.d.ts
CHANGED
|
@@ -57,17 +57,41 @@ export declare function commitRisk(risk: RiskUnits, blinding?: bigint): RiskComm
|
|
|
57
57
|
export declare function addCommitments(commitments: readonly string[]): string;
|
|
58
58
|
/** Check that `commitment` opens to (`risk`, `blinding`). Never throws; malformed input is false. */
|
|
59
59
|
export declare function openCommitment(commitment: string, risk: RiskUnits, blinding: bigint): boolean;
|
|
60
|
+
/** Largest ceiling the N_BITS range proof can express: a slack is proven in [0, 2^N_BITS). */
|
|
61
|
+
export declare const MAX_PROVABLE_CEILING: bigint;
|
|
60
62
|
/**
|
|
61
63
|
* Prove that the committed aggregate satisfies Σrisk ≤ bMax, in zero knowledge over the individual
|
|
62
64
|
* risks. `risks`/`blindings` are the same per-action values used to build the commitments whose sum
|
|
63
65
|
* is passed to {@link verifyBudget}. If the aggregate is over budget (or the slack does not fit in
|
|
64
66
|
* N_BITS), the returned proof is well-formed but will be REJECTED by the verifier — soundness lives
|
|
65
67
|
* in verification, not in the prover trusting its own inputs.
|
|
68
|
+
*
|
|
69
|
+
* SCOPE: the proof is about the committed VALUE of the sum. It does not by itself show that each addend was a
|
|
70
|
+
* non-negative amount: pair it with {@link proveRiskRange} / {@link verifyBoundedBudget}, otherwise a prover can
|
|
71
|
+
* offset real risk with a commitment to a "negative" value (a field element near L).
|
|
66
72
|
*/
|
|
67
73
|
export declare function proveBudget(risks: readonly RiskUnits[], blindings: readonly bigint[], bMax: RiskUnits): BudgetProof;
|
|
68
74
|
/**
|
|
69
75
|
* Verify a budget proof against the commitment sum and ceiling. Returns true only if every bit
|
|
70
76
|
* commitment opens to 0/1 and they aggregate to the slack commitment bMax·G − commitmentSum — i.e.
|
|
71
77
|
* Σrisk ≤ bMax. Learns nothing about the individual risks. Never throws; malformed input is false.
|
|
78
|
+
* Scalars and points must be canonical (a proof is not malleable). Ceilings above 2^N_BITS - 1 are clamped.
|
|
72
79
|
*/
|
|
73
80
|
export declare function verifyBudget(commitmentSum: string, bMax: RiskUnits, proof: BudgetProof): boolean;
|
|
81
|
+
/** A proof that a single risk commitment opens to a value in [0, 2^N_BITS). Same shape as a {@link BudgetProof}. */
|
|
82
|
+
export type RiskRangeProof = BudgetProof;
|
|
83
|
+
/**
|
|
84
|
+
* Prove that the commitment `commitRisk(risk, blinding)` holds a value in [0, 2^N_BITS). Each action's
|
|
85
|
+
* commitment needs one of these: the budget proof alone only constrains the SUM, and since a commitment is just a
|
|
86
|
+
* group element, a prover could otherwise include one that commits to a value near the group order (a
|
|
87
|
+
* "negative" risk) to cancel real risk. With every addend range-proved, the integers add without wrapping.
|
|
88
|
+
*/
|
|
89
|
+
export declare function proveRiskRange(risk: RiskUnits, blinding: bigint): RiskRangeProof;
|
|
90
|
+
/** Verify {@link proveRiskRange} for `commitment`. Never throws; malformed input is false. */
|
|
91
|
+
export declare function verifyRiskRange(commitment: string, proof: RiskRangeProof): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* The sound end-to-end check for a budget over a set of per-action commitments: every commitment must carry a
|
|
94
|
+
* valid range proof, and the budget proof must verify for their homomorphic sum. Accepting implies
|
|
95
|
+
* Σ(committed risks), as integers, ≤ min(bMax, 2^N_BITS − 1). Never throws.
|
|
96
|
+
*/
|
|
97
|
+
export declare function verifyBoundedBudget(commitments: readonly string[], rangeProofs: readonly RiskRangeProof[], bMax: RiskUnits, budgetProof: BudgetProof): boolean;
|
package/dist/accumulator.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AccumulatorError = exports.N_BITS = void 0;
|
|
3
|
+
exports.MAX_PROVABLE_CEILING = exports.AccumulatorError = exports.N_BITS = void 0;
|
|
4
4
|
exports.commitRisk = commitRisk;
|
|
5
5
|
exports.addCommitments = addCommitments;
|
|
6
6
|
exports.openCommitment = openCommitment;
|
|
7
7
|
exports.proveBudget = proveBudget;
|
|
8
8
|
exports.verifyBudget = verifyBudget;
|
|
9
|
+
exports.proveRiskRange = proveRiskRange;
|
|
10
|
+
exports.verifyRiskRange = verifyRiskRange;
|
|
11
|
+
exports.verifyBoundedBudget = verifyBoundedBudget;
|
|
9
12
|
const group_1 = require("./group");
|
|
10
13
|
/**
|
|
11
14
|
* Mechanism 2 — Homomorphic risk accumulator with a zero-knowledge spend ceiling.
|
|
@@ -73,8 +76,20 @@ function openCommitment(commitment, risk, blinding) {
|
|
|
73
76
|
}
|
|
74
77
|
// ---- range proof ----------------------------------------------------------------------
|
|
75
78
|
const CTX_DOMAIN = (0, group_1.utf8)('atlas-pca-ratchet/budget/ctx/v1');
|
|
79
|
+
const RISK_CTX_DOMAIN = (0, group_1.utf8)('atlas-pca-ratchet/risk-range/ctx/v1');
|
|
76
80
|
const OR_DOMAIN = (0, group_1.utf8)('atlas-pca-ratchet/budget/bit-or/v1');
|
|
77
81
|
const AGG_DOMAIN = (0, group_1.utf8)('atlas-pca-ratchet/budget/agg/v1');
|
|
82
|
+
/** Largest ceiling the N_BITS range proof can express: a slack is proven in [0, 2^N_BITS). */
|
|
83
|
+
exports.MAX_PROVABLE_CEILING = (1n << BigInt(exports.N_BITS)) - 1n;
|
|
84
|
+
/**
|
|
85
|
+
* The ceiling actually proven. A ceiling above 2^N_BITS - 1 is clamped to it: "sum <= 2^N_BITS - 1" is a
|
|
86
|
+
* strictly stronger statement than "sum <= bMax", so a verifier is never weakened, and an honest prover whose
|
|
87
|
+
* total fits in N_BITS is never refused (before the clamp, a ceiling >= 2^N_BITS made every small total
|
|
88
|
+
* unprovable because the slack no longer fit the range).
|
|
89
|
+
*/
|
|
90
|
+
function effectiveCeiling(bMaxUnits) {
|
|
91
|
+
return bMaxUnits > exports.MAX_PROVABLE_CEILING ? exports.MAX_PROVABLE_CEILING : bMaxUnits;
|
|
92
|
+
}
|
|
78
93
|
/** The transcript context that binds every challenge to the exact public statement. */
|
|
79
94
|
function contextHash(n, bMaxUnits, commitmentSum, bitCommitments) {
|
|
80
95
|
const parts = [
|
|
@@ -88,6 +103,13 @@ function contextHash(n, bMaxUnits, commitmentSum, bitCommitments) {
|
|
|
88
103
|
// Reuse hashToScalar's length-prefixed framing, then serialize the scalar back to 32 bytes.
|
|
89
104
|
return (0, group_1.numberToBytesLE)((0, group_1.hashToScalar)(parts), 32);
|
|
90
105
|
}
|
|
106
|
+
/** Context for the per-commitment range proof (a different domain, so it cannot be replayed as a budget proof). */
|
|
107
|
+
function riskContextHash(n, commitment, bitCommitments) {
|
|
108
|
+
const parts = [RISK_CTX_DOMAIN, Uint8Array.of(n & 0xff), commitment.toRawBytes()];
|
|
109
|
+
for (const B of bitCommitments)
|
|
110
|
+
parts.push(B.toRawBytes());
|
|
111
|
+
return (0, group_1.numberToBytesLE)((0, group_1.hashToScalar)(parts), 32);
|
|
112
|
+
}
|
|
91
113
|
/** Prove bit commitment `B` (= b·G + s·H) opens to 0 or 1, knowing bit `b` and blinding `s`. */
|
|
92
114
|
function proveBit(ctx, index, B, b, s) {
|
|
93
115
|
const P0 = B; // commitment to 0 under H => B = s·H
|
|
@@ -139,29 +161,14 @@ function verifySchnorr(ctx, D, proof) {
|
|
|
139
161
|
return (0, group_1.mul)(group_1.H, z).equals((0, group_1.add)(a, (0, group_1.mul)(D, e)));
|
|
140
162
|
}
|
|
141
163
|
/**
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* N_BITS
|
|
146
|
-
* in verification, not in the prover trusting its own inputs.
|
|
164
|
+
* Shared range-proof core. Proves that the point `V = value·G + gamma·H` (known to both sides) commits to a
|
|
165
|
+
* value in [0, 2^N_BITS): bit-decompose, commit to each bit, prove each is 0/1 (OR-proof), and prove by a
|
|
166
|
+
* Schnorr proof that Σ 2^i·B_i − V is a pure multiple of H (so the bits aggregate to the committed value).
|
|
167
|
+
* `value` is taken modulo 2^N_BITS: an out-of-range value yields a well-formed proof that the verifier rejects.
|
|
147
168
|
*/
|
|
148
|
-
function
|
|
149
|
-
if (risks.length !== blindings.length) {
|
|
150
|
-
throw new AccumulatorError('length_mismatch', 'risks and blindings must have equal length');
|
|
151
|
-
}
|
|
152
|
-
const bMaxUnits = asUnits(bMax);
|
|
153
|
-
let sumRisk = 0n;
|
|
154
|
-
let sumBlind = 0n;
|
|
155
|
-
for (let i = 0; i < risks.length; i++) {
|
|
156
|
-
sumRisk += asUnits(risks[i] ?? 0n);
|
|
157
|
-
sumBlind = (0, group_1.scalarAdd)(sumBlind, blindings[i] ?? 0n);
|
|
158
|
-
}
|
|
159
|
-
// Commitment sum (= what the verifier is given) and the slack commitment V = bMax·G − C_sum.
|
|
160
|
-
const cSum = (0, group_1.add)((0, group_1.mul)(group_1.G, (0, group_1.mod)(sumRisk)), (0, group_1.mul)(group_1.H, sumBlind));
|
|
161
|
-
const gamma = (0, group_1.mod)(-sumBlind); // blinding of V
|
|
162
|
-
const v = bMaxUnits - sumRisk; // slack (may be negative if over budget)
|
|
169
|
+
function rangeProve(makeCtx, V, value, gamma) {
|
|
163
170
|
const mask = (1n << BigInt(exports.N_BITS)) - 1n;
|
|
164
|
-
const vMasked =
|
|
171
|
+
const vMasked = value & mask; // low N_BITS bits (correct two's-complement low bits even if value < 0)
|
|
165
172
|
const bitCommitments = [];
|
|
166
173
|
const bitBlindings = [];
|
|
167
174
|
const bits = [];
|
|
@@ -172,13 +179,13 @@ function proveBudget(risks, blindings, bMax) {
|
|
|
172
179
|
bitBlindings.push(s);
|
|
173
180
|
bitCommitments.push((0, group_1.add)((0, group_1.mul)(group_1.G, bit), (0, group_1.mul)(group_1.H, s)));
|
|
174
181
|
}
|
|
175
|
-
const ctx =
|
|
182
|
+
const ctx = makeCtx(bitCommitments);
|
|
176
183
|
const or = [];
|
|
177
184
|
for (let i = 0; i < exports.N_BITS; i++) {
|
|
178
185
|
or.push(proveBit(ctx, i, bitCommitments[i], bits[i], bitBlindings[i]));
|
|
179
186
|
}
|
|
180
|
-
// Aggregation: Σ 2^i·B_i =
|
|
181
|
-
//
|
|
187
|
+
// Aggregation: Σ 2^i·B_i = v'·G + sStar·H. When v' = value (in range), D = Σ2^i·B_i − V = (sStar − gamma)·H,
|
|
188
|
+
// a pure H-multiple whose dlog the prover knows.
|
|
182
189
|
let sStar = 0n;
|
|
183
190
|
let aggPoint = (0, group_1.mul)(group_1.G, 0n);
|
|
184
191
|
for (let i = 0; i < exports.N_BITS; i++) {
|
|
@@ -186,43 +193,114 @@ function proveBudget(risks, blindings, bMax) {
|
|
|
186
193
|
sStar = (0, group_1.scalarAdd)(sStar, (0, group_1.scalarMul)(w, bitBlindings[i]));
|
|
187
194
|
aggPoint = (0, group_1.add)(aggPoint, (0, group_1.mul)(bitCommitments[i], w));
|
|
188
195
|
}
|
|
189
|
-
const V = (0, group_1.sub)((0, group_1.mul)(group_1.G, (0, group_1.mod)(bMaxUnits)), cSum);
|
|
190
196
|
const D = (0, group_1.sub)(aggPoint, V);
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
197
|
+
const agg = proveSchnorr(ctx, D, (0, group_1.scalarSub)(sStar, gamma));
|
|
198
|
+
return { bitCommitments, or, agg };
|
|
199
|
+
}
|
|
200
|
+
function rangeVerify(makeCtx, V, proof) {
|
|
201
|
+
if (proof === null || typeof proof !== 'object')
|
|
202
|
+
return false;
|
|
203
|
+
const { n, bitCommitments, or, agg } = proof;
|
|
204
|
+
if (n !== exports.N_BITS || !Array.isArray(bitCommitments) || !Array.isArray(or))
|
|
205
|
+
return false;
|
|
206
|
+
if (bitCommitments.length !== exports.N_BITS || or.length !== exports.N_BITS)
|
|
207
|
+
return false;
|
|
208
|
+
if (agg === null || typeof agg !== 'object')
|
|
209
|
+
return false;
|
|
210
|
+
const B = bitCommitments.map(group_1.decodePoint);
|
|
211
|
+
const ctx = makeCtx(B);
|
|
212
|
+
for (let i = 0; i < exports.N_BITS; i++) {
|
|
213
|
+
if (!verifyBit(ctx, i, B[i], or[i]))
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
let aggPoint = (0, group_1.mul)(group_1.G, 0n);
|
|
217
|
+
for (let i = 0; i < exports.N_BITS; i++)
|
|
218
|
+
aggPoint = (0, group_1.add)(aggPoint, (0, group_1.mul)(B[i], 1n << BigInt(i)));
|
|
219
|
+
return verifySchnorr(ctx, (0, group_1.sub)(aggPoint, V), agg);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Prove that the committed aggregate satisfies Σrisk ≤ bMax, in zero knowledge over the individual
|
|
223
|
+
* risks. `risks`/`blindings` are the same per-action values used to build the commitments whose sum
|
|
224
|
+
* is passed to {@link verifyBudget}. If the aggregate is over budget (or the slack does not fit in
|
|
225
|
+
* N_BITS), the returned proof is well-formed but will be REJECTED by the verifier — soundness lives
|
|
226
|
+
* in verification, not in the prover trusting its own inputs.
|
|
227
|
+
*
|
|
228
|
+
* SCOPE: the proof is about the committed VALUE of the sum. It does not by itself show that each addend was a
|
|
229
|
+
* non-negative amount: pair it with {@link proveRiskRange} / {@link verifyBoundedBudget}, otherwise a prover can
|
|
230
|
+
* offset real risk with a commitment to a "negative" value (a field element near L).
|
|
231
|
+
*/
|
|
232
|
+
function proveBudget(risks, blindings, bMax) {
|
|
233
|
+
if (risks.length !== blindings.length) {
|
|
234
|
+
throw new AccumulatorError('length_mismatch', 'risks and blindings must have equal length');
|
|
235
|
+
}
|
|
236
|
+
const ceiling = effectiveCeiling(asUnits(bMax));
|
|
237
|
+
let sumRisk = 0n;
|
|
238
|
+
let sumBlind = 0n;
|
|
239
|
+
for (let i = 0; i < risks.length; i++) {
|
|
240
|
+
sumRisk += asUnits(risks[i] ?? 0n);
|
|
241
|
+
sumBlind = (0, group_1.scalarAdd)(sumBlind, blindings[i] ?? 0n);
|
|
242
|
+
}
|
|
243
|
+
// Commitment sum (= what the verifier is given) and the slack commitment V = bMax·G − C_sum.
|
|
244
|
+
const cSum = (0, group_1.add)((0, group_1.mul)(group_1.G, (0, group_1.mod)(sumRisk)), (0, group_1.mul)(group_1.H, sumBlind));
|
|
245
|
+
const V = (0, group_1.sub)((0, group_1.mul)(group_1.G, (0, group_1.mod)(ceiling)), cSum);
|
|
246
|
+
const slack = ceiling - sumRisk; // may be negative if over budget
|
|
247
|
+
const r = rangeProve((bits) => contextHash(exports.N_BITS, ceiling, cSum, bits), V, slack, (0, group_1.mod)(-sumBlind));
|
|
248
|
+
return { n: exports.N_BITS, bitCommitments: r.bitCommitments.map(group_1.encodePoint), or: r.or, agg: r.agg };
|
|
194
249
|
}
|
|
195
250
|
/**
|
|
196
251
|
* Verify a budget proof against the commitment sum and ceiling. Returns true only if every bit
|
|
197
252
|
* commitment opens to 0/1 and they aggregate to the slack commitment bMax·G − commitmentSum — i.e.
|
|
198
253
|
* Σrisk ≤ bMax. Learns nothing about the individual risks. Never throws; malformed input is false.
|
|
254
|
+
* Scalars and points must be canonical (a proof is not malleable). Ceilings above 2^N_BITS - 1 are clamped.
|
|
199
255
|
*/
|
|
200
256
|
function verifyBudget(commitmentSum, bMax, proof) {
|
|
201
257
|
try {
|
|
202
|
-
|
|
203
|
-
return false;
|
|
204
|
-
const { n, bitCommitments, or, agg } = proof;
|
|
205
|
-
if (n !== exports.N_BITS || !Array.isArray(bitCommitments) || !Array.isArray(or))
|
|
206
|
-
return false;
|
|
207
|
-
if (bitCommitments.length !== exports.N_BITS || or.length !== exports.N_BITS)
|
|
208
|
-
return false;
|
|
209
|
-
if (agg === null || typeof agg !== 'object')
|
|
210
|
-
return false;
|
|
211
|
-
const bMaxUnits = asUnits(bMax);
|
|
258
|
+
const ceiling = effectiveCeiling(asUnits(bMax));
|
|
212
259
|
const cSum = (0, group_1.decodePoint)(commitmentSum);
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
260
|
+
const V = (0, group_1.sub)((0, group_1.mul)(group_1.G, (0, group_1.mod)(ceiling)), cSum);
|
|
261
|
+
return rangeVerify((bits) => contextHash(exports.N_BITS, ceiling, cSum, bits), V, proof);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Prove that the commitment `commitRisk(risk, blinding)` holds a value in [0, 2^N_BITS). Each action's
|
|
269
|
+
* commitment needs one of these: the budget proof alone only constrains the SUM, and since a commitment is just a
|
|
270
|
+
* group element, a prover could otherwise include one that commits to a value near the group order (a
|
|
271
|
+
* "negative" risk) to cancel real risk. With every addend range-proved, the integers add without wrapping.
|
|
272
|
+
*/
|
|
273
|
+
function proveRiskRange(risk, blinding) {
|
|
274
|
+
const v = asUnits(risk);
|
|
275
|
+
const b = (0, group_1.mod)(blinding);
|
|
276
|
+
const C = (0, group_1.add)((0, group_1.mul)(group_1.G, (0, group_1.mod)(v)), (0, group_1.mul)(group_1.H, b));
|
|
277
|
+
const r = rangeProve((bits) => riskContextHash(exports.N_BITS, C, bits), C, v, b);
|
|
278
|
+
return { n: exports.N_BITS, bitCommitments: r.bitCommitments.map(group_1.encodePoint), or: r.or, agg: r.agg };
|
|
279
|
+
}
|
|
280
|
+
/** Verify {@link proveRiskRange} for `commitment`. Never throws; malformed input is false. */
|
|
281
|
+
function verifyRiskRange(commitment, proof) {
|
|
282
|
+
try {
|
|
283
|
+
const C = (0, group_1.decodePoint)(commitment);
|
|
284
|
+
return rangeVerify((bits) => riskContextHash(exports.N_BITS, C, bits), C, proof);
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* The sound end-to-end check for a budget over a set of per-action commitments: every commitment must carry a
|
|
292
|
+
* valid range proof, and the budget proof must verify for their homomorphic sum. Accepting implies
|
|
293
|
+
* Σ(committed risks), as integers, ≤ min(bMax, 2^N_BITS − 1). Never throws.
|
|
294
|
+
*/
|
|
295
|
+
function verifyBoundedBudget(commitments, rangeProofs, bMax, budgetProof) {
|
|
296
|
+
try {
|
|
297
|
+
if (!Array.isArray(commitments) || !Array.isArray(rangeProofs) || commitments.length !== rangeProofs.length)
|
|
298
|
+
return false;
|
|
299
|
+
for (let i = 0; i < commitments.length; i++) {
|
|
300
|
+
if (!verifyRiskRange(commitments[i], rangeProofs[i]))
|
|
217
301
|
return false;
|
|
218
302
|
}
|
|
219
|
-
|
|
220
|
-
for (let i = 0; i < exports.N_BITS; i++) {
|
|
221
|
-
aggPoint = (0, group_1.add)(aggPoint, (0, group_1.mul)(B[i], 1n << BigInt(i)));
|
|
222
|
-
}
|
|
223
|
-
const V = (0, group_1.sub)((0, group_1.mul)(group_1.G, (0, group_1.mod)(bMaxUnits)), cSum);
|
|
224
|
-
const D = (0, group_1.sub)(aggPoint, V);
|
|
225
|
-
return verifySchnorr(ctx, D, agg);
|
|
303
|
+
return verifyBudget(addCommitments(commitments), bMax, budgetProof);
|
|
226
304
|
}
|
|
227
305
|
catch {
|
|
228
306
|
return false;
|
package/dist/accumulator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accumulator.js","sourceRoot":"","sources":["../src/accumulator.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accumulator.js","sourceRoot":"","sources":["../src/accumulator.ts"],"names":[],"mappings":"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"}
|
package/dist/adapters.d.ts
CHANGED
|
@@ -23,8 +23,24 @@ export declare function leafIndexForAction(actn: Pick<PCActn, 'counter'>, depth:
|
|
|
23
23
|
* the integer units the Pedersen accumulator commits to. 1000 = millirisk resolution.
|
|
24
24
|
*/
|
|
25
25
|
export declare const RISK_SCALE = 1000;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Quantize a core risk score (any finite r ≥ 0) to non-negative integer accumulator units, ROUNDING UP
|
|
28
|
+
* (a nonzero risk is never 0 units; a sum of quantized risks never under-counts the true sum — RT-11).
|
|
29
|
+
* A value within float noise of an exact unit (e.g. 0.3 * 1000) keeps that unit. Each action may
|
|
30
|
+
* over-count by < 1 unit; use {@link RiskQuantizer} to carry the remainder instead.
|
|
31
|
+
*/
|
|
27
32
|
export declare function riskToUnits(r: number): RiskUnits;
|
|
33
|
+
/**
|
|
34
|
+
* Carry-forward quantizer: emits per-action integer units such that the running total of emitted
|
|
35
|
+
* units is ALWAYS `ceil(Σ true risk * SCALE)` (never below the true cumulative sum, over by < 1 unit
|
|
36
|
+
* in total instead of per action). Stateful; one instance per budget stream.
|
|
37
|
+
*/
|
|
38
|
+
export declare class RiskQuantizer {
|
|
39
|
+
private nano;
|
|
40
|
+
private emitted;
|
|
41
|
+
next(r: number): bigint;
|
|
42
|
+
get totalUnits(): bigint;
|
|
43
|
+
}
|
|
28
44
|
/**
|
|
29
45
|
* The accumulator's budget ceiling in integer units, derived from a RiskPolicy. This is exactly the
|
|
30
46
|
* core cumulative-risk safety bound Σrisk ≤ bMax/κ (`safetyBound`), quantized — so the zero-knowledge
|
package/dist/adapters.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RISK_SCALE = void 0;
|
|
3
|
+
exports.RiskQuantizer = exports.RISK_SCALE = void 0;
|
|
4
4
|
exports.counterToLeafIndex = counterToLeafIndex;
|
|
5
5
|
exports.leafIndexToCounter = leafIndexToCounter;
|
|
6
6
|
exports.leafIndexForAction = leafIndexForAction;
|
|
@@ -53,13 +53,47 @@ function leafIndexForAction(actn, depth) {
|
|
|
53
53
|
* the integer units the Pedersen accumulator commits to. 1000 = millirisk resolution.
|
|
54
54
|
*/
|
|
55
55
|
exports.RISK_SCALE = 1000;
|
|
56
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Quantize a core risk score (any finite r ≥ 0) to non-negative integer accumulator units, ROUNDING UP
|
|
58
|
+
* (a nonzero risk is never 0 units; a sum of quantized risks never under-counts the true sum — RT-11).
|
|
59
|
+
* A value within float noise of an exact unit (e.g. 0.3 * 1000) keeps that unit. Each action may
|
|
60
|
+
* over-count by < 1 unit; use {@link RiskQuantizer} to carry the remainder instead.
|
|
61
|
+
*/
|
|
57
62
|
function riskToUnits(r) {
|
|
58
63
|
if (!Number.isFinite(r) || r < 0) {
|
|
59
64
|
throw new accumulator_1.AccumulatorError('invalid_value', 'risk must be a finite number >= 0');
|
|
60
65
|
}
|
|
61
|
-
|
|
66
|
+
const v = r * exports.RISK_SCALE;
|
|
67
|
+
const nearest = Math.round(v);
|
|
68
|
+
if (Math.abs(v - nearest) <= 1e-9 * Math.max(1, v))
|
|
69
|
+
return BigInt(nearest);
|
|
70
|
+
return BigInt(Math.ceil(v));
|
|
71
|
+
}
|
|
72
|
+
const NANO = 1000000n;
|
|
73
|
+
/**
|
|
74
|
+
* Carry-forward quantizer: emits per-action integer units such that the running total of emitted
|
|
75
|
+
* units is ALWAYS `ceil(Σ true risk * SCALE)` (never below the true cumulative sum, over by < 1 unit
|
|
76
|
+
* in total instead of per action). Stateful; one instance per budget stream.
|
|
77
|
+
*/
|
|
78
|
+
class RiskQuantizer {
|
|
79
|
+
nano = 0n;
|
|
80
|
+
emitted = 0n;
|
|
81
|
+
next(r) {
|
|
82
|
+
if (!Number.isFinite(r) || r < 0) {
|
|
83
|
+
throw new accumulator_1.AccumulatorError('invalid_value', 'risk must be a finite number >= 0');
|
|
84
|
+
}
|
|
85
|
+
// r * SCALE in millionths of a unit, rounded UP so the total can only over-approximate.
|
|
86
|
+
this.nano += BigInt(Math.ceil(r * exports.RISK_SCALE * 1e6 - 1e-3));
|
|
87
|
+
const total = (this.nano + NANO - 1n) / NANO;
|
|
88
|
+
const out = total - this.emitted;
|
|
89
|
+
this.emitted = total;
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
get totalUnits() {
|
|
93
|
+
return this.emitted;
|
|
94
|
+
}
|
|
62
95
|
}
|
|
96
|
+
exports.RiskQuantizer = RiskQuantizer;
|
|
63
97
|
/**
|
|
64
98
|
* The accumulator's budget ceiling in integer units, derived from a RiskPolicy. This is exactly the
|
|
65
99
|
* core cumulative-risk safety bound Σrisk ≤ bMax/κ (`safetyBound`), quantized — so the zero-knowledge
|
package/dist/adapters.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":";;;AAqBA,gDAWC;AAGD,gDAKC;AAGD,gDAEC;
|
|
1
|
+
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type BudgetProof, type RiskRangeProof, type RiskUnits } from './accumulator';
|
|
2
|
+
import { type RatchetSignature } from './ratchet';
|
|
3
|
+
/**
|
|
4
|
+
* Verifier-side bindings that the stateless primitives cannot give on their own (red-team RT-11):
|
|
5
|
+
*
|
|
6
|
+
* 1. {@link verifyLeafSignatureOnce}: a spent-leaf store so a SECOND signature at the same leaf is
|
|
7
|
+
* detected (replay) and a different message at the same leaf is flagged as equivocation, with
|
|
8
|
+
* both signed digests as evidence. Ed25519 is deterministic and the ratchet holds no
|
|
9
|
+
* verifier-extractable secret, so this is DETECTION by the verifier, not key extraction.
|
|
10
|
+
* 2. {@link issueRiskCommitment} / {@link verifyAttestedBudget}: the risk commitment is created
|
|
11
|
+
* by the party that COMPUTES the risk (a risk authority) and signed together with the action
|
|
12
|
+
* digest, so a prover cannot commit 0 for a 1.0-risk action or move a commitment between actions.
|
|
13
|
+
*/
|
|
14
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
15
|
+
/** Atomic first-claim store keyed by leaf nullifier. */
|
|
16
|
+
export interface SpentLeafStore {
|
|
17
|
+
/**
|
|
18
|
+
* Atomically record `record` under `nullifier` if absent. Resolve `{ first: true }` on first claim,
|
|
19
|
+
* else `{ first: false, record }` with the record stored earlier.
|
|
20
|
+
*/
|
|
21
|
+
claim(nullifier: string, record: string): MaybePromise<{
|
|
22
|
+
first: true;
|
|
23
|
+
} | {
|
|
24
|
+
first: false;
|
|
25
|
+
record: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
/** In-process {@link SpentLeafStore}. Per process: use a shared store for a verifier fleet. */
|
|
29
|
+
export declare function memorySpentLeafStore(): SpentLeafStore;
|
|
30
|
+
export type LeafUseResult = {
|
|
31
|
+
ok: true;
|
|
32
|
+
} | {
|
|
33
|
+
ok: false;
|
|
34
|
+
reason: 'invalid';
|
|
35
|
+
} | {
|
|
36
|
+
ok: false;
|
|
37
|
+
reason: 'replay';
|
|
38
|
+
nullifier: string;
|
|
39
|
+
} | {
|
|
40
|
+
ok: false;
|
|
41
|
+
reason: 'equivocation';
|
|
42
|
+
nullifier: string;
|
|
43
|
+
firstMessageDigest: string;
|
|
44
|
+
secondMessageDigest: string;
|
|
45
|
+
} | {
|
|
46
|
+
ok: false;
|
|
47
|
+
reason: 'store-error';
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Verify a leaf signature AND enforce one-time use at the verifier: the first valid signature at a
|
|
51
|
+
* leaf is accepted and its message digest recorded; any later signature at that leaf is refused as
|
|
52
|
+
* `replay` (same message) or `equivocation` (different message, the evidence of a holder that kept an
|
|
53
|
+
* old state). Fail closed: a store that throws denies.
|
|
54
|
+
*/
|
|
55
|
+
export declare function verifyLeafSignatureOnce(rootCommitment: string, leafIndex: number, message: Uint8Array, signature: RatchetSignature, store: SpentLeafStore): Promise<LeafUseResult>;
|
|
56
|
+
/** A risk authority's signature binding a commitment to one action. */
|
|
57
|
+
export interface RiskAttestation {
|
|
58
|
+
/** The action (e.g. `pcactnDigest`) this commitment is for. */
|
|
59
|
+
actionDigest: string;
|
|
60
|
+
/** b64u Ed25519 signature by the risk authority over (domain, actionDigest, commitment). */
|
|
61
|
+
sig: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* RISK AUTHORITY side: commit to the risk it computed for `actionDigest`, prove the range, and sign
|
|
65
|
+
* (actionDigest, commitment). Hand `blinding` privately to the prover (needed for the budget proof);
|
|
66
|
+
* publish `commitment`, `rangeProof`, `attestation`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function issueRiskCommitment(risk: RiskUnits, actionDigest: string, authoritySecretKey: Uint8Array): {
|
|
69
|
+
commitment: string;
|
|
70
|
+
blinding: bigint;
|
|
71
|
+
rangeProof: RiskRangeProof;
|
|
72
|
+
attestation: RiskAttestation;
|
|
73
|
+
};
|
|
74
|
+
/** Verify one attestation against the risk authority's public key (b64u). Never throws. */
|
|
75
|
+
export declare function verifyRiskAttestation(commitment: string, attestation: RiskAttestation, authorityPublicKey: string): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Sound end-to-end budget check over ATTESTED commitments. For the verifier's own list of action
|
|
78
|
+
* digests (in order), every item must carry a valid authority attestation for exactly that digest and
|
|
79
|
+
* commitment, then {@link verifyBoundedBudget} must hold. Accepting implies the authority-computed
|
|
80
|
+
* risks of exactly these actions sum, as integers, to at most `bMax`. Never throws.
|
|
81
|
+
*/
|
|
82
|
+
export declare function verifyAttestedBudget(items: readonly {
|
|
83
|
+
commitment: string;
|
|
84
|
+
rangeProof: RiskRangeProof;
|
|
85
|
+
attestation: RiskAttestation;
|
|
86
|
+
}[], expectedActionDigests: readonly string[], authorityPublicKey: string, bMax: RiskUnits, budgetProof: BudgetProof): boolean;
|
|
87
|
+
export {};
|
package/dist/binding.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.memorySpentLeafStore = memorySpentLeafStore;
|
|
4
|
+
exports.verifyLeafSignatureOnce = verifyLeafSignatureOnce;
|
|
5
|
+
exports.issueRiskCommitment = issueRiskCommitment;
|
|
6
|
+
exports.verifyRiskAttestation = verifyRiskAttestation;
|
|
7
|
+
exports.verifyAttestedBudget = verifyAttestedBudget;
|
|
8
|
+
const ed25519_1 = require("@noble/curves/ed25519");
|
|
9
|
+
const pca_1 = require("@atlasauth/pca");
|
|
10
|
+
const accumulator_1 = require("./accumulator");
|
|
11
|
+
const ratchet_1 = require("./ratchet");
|
|
12
|
+
const group_1 = require("./group");
|
|
13
|
+
/** In-process {@link SpentLeafStore}. Per process: use a shared store for a verifier fleet. */
|
|
14
|
+
function memorySpentLeafStore() {
|
|
15
|
+
const seen = new Map();
|
|
16
|
+
return {
|
|
17
|
+
claim(nullifier, record) {
|
|
18
|
+
const prev = seen.get(nullifier);
|
|
19
|
+
if (prev !== undefined)
|
|
20
|
+
return { first: false, record: prev };
|
|
21
|
+
seen.set(nullifier, record);
|
|
22
|
+
return { first: true };
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function messageDigest(leafIndex, message) {
|
|
27
|
+
return (0, pca_1.b64u)((0, pca_1.sha256)(message)) + '@' + String(leafIndex);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Verify a leaf signature AND enforce one-time use at the verifier: the first valid signature at a
|
|
31
|
+
* leaf is accepted and its message digest recorded; any later signature at that leaf is refused as
|
|
32
|
+
* `replay` (same message) or `equivocation` (different message, the evidence of a holder that kept an
|
|
33
|
+
* old state). Fail closed: a store that throws denies.
|
|
34
|
+
*/
|
|
35
|
+
async function verifyLeafSignatureOnce(rootCommitment, leafIndex, message, signature, store) {
|
|
36
|
+
if (!(0, ratchet_1.verifyLeafSignature)(rootCommitment, leafIndex, message, signature))
|
|
37
|
+
return { ok: false, reason: 'invalid' };
|
|
38
|
+
const nullifier = (0, ratchet_1.leafNullifier)(rootCommitment, leafIndex);
|
|
39
|
+
const mine = messageDigest(leafIndex, message);
|
|
40
|
+
try {
|
|
41
|
+
const r = await store.claim(nullifier, mine);
|
|
42
|
+
if (r.first)
|
|
43
|
+
return { ok: true };
|
|
44
|
+
if (r.record === mine)
|
|
45
|
+
return { ok: false, reason: 'replay', nullifier };
|
|
46
|
+
return { ok: false, reason: 'equivocation', nullifier, firstMessageDigest: r.record, secondMessageDigest: mine };
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return { ok: false, reason: 'store-error' };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ---- (2) action-bound risk commitments -------------------------------------------------
|
|
53
|
+
const ATTEST_DOMAIN = (0, group_1.utf8)('atlas-pca-ratchet/risk-attestation/v1\0');
|
|
54
|
+
function attestMessage(actionDigest, commitment) {
|
|
55
|
+
const a = (0, group_1.utf8)(actionDigest);
|
|
56
|
+
const c = (0, group_1.utf8)(commitment);
|
|
57
|
+
const out = new Uint8Array(ATTEST_DOMAIN.length + 4 + a.length + 4 + c.length);
|
|
58
|
+
const dv = new DataView(out.buffer);
|
|
59
|
+
out.set(ATTEST_DOMAIN, 0);
|
|
60
|
+
let o = ATTEST_DOMAIN.length;
|
|
61
|
+
dv.setUint32(o, a.length, false);
|
|
62
|
+
out.set(a, o + 4);
|
|
63
|
+
o += 4 + a.length;
|
|
64
|
+
dv.setUint32(o, c.length, false);
|
|
65
|
+
out.set(c, o + 4);
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* RISK AUTHORITY side: commit to the risk it computed for `actionDigest`, prove the range, and sign
|
|
70
|
+
* (actionDigest, commitment). Hand `blinding` privately to the prover (needed for the budget proof);
|
|
71
|
+
* publish `commitment`, `rangeProof`, `attestation`.
|
|
72
|
+
*/
|
|
73
|
+
function issueRiskCommitment(risk, actionDigest, authoritySecretKey) {
|
|
74
|
+
const { commitment, blinding } = (0, accumulator_1.commitRisk)(risk);
|
|
75
|
+
const rangeProof = (0, accumulator_1.proveRiskRange)(risk, blinding);
|
|
76
|
+
const sig = (0, pca_1.b64u)(ed25519_1.ed25519.sign(attestMessage(actionDigest, commitment), authoritySecretKey));
|
|
77
|
+
return { commitment, blinding, rangeProof, attestation: { actionDigest, sig } };
|
|
78
|
+
}
|
|
79
|
+
/** Verify one attestation against the risk authority's public key (b64u). Never throws. */
|
|
80
|
+
function verifyRiskAttestation(commitment, attestation, authorityPublicKey) {
|
|
81
|
+
try {
|
|
82
|
+
if (attestation === null || typeof attestation !== 'object')
|
|
83
|
+
return false;
|
|
84
|
+
if (typeof attestation.actionDigest !== 'string' || typeof attestation.sig !== 'string')
|
|
85
|
+
return false;
|
|
86
|
+
return (0, pca_1.verifyB64u)(authorityPublicKey, attestMessage(attestation.actionDigest, commitment), attestation.sig);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Sound end-to-end budget check over ATTESTED commitments. For the verifier's own list of action
|
|
94
|
+
* digests (in order), every item must carry a valid authority attestation for exactly that digest and
|
|
95
|
+
* commitment, then {@link verifyBoundedBudget} must hold. Accepting implies the authority-computed
|
|
96
|
+
* risks of exactly these actions sum, as integers, to at most `bMax`. Never throws.
|
|
97
|
+
*/
|
|
98
|
+
function verifyAttestedBudget(items, expectedActionDigests, authorityPublicKey, bMax, budgetProof) {
|
|
99
|
+
try {
|
|
100
|
+
if (!Array.isArray(items) || !Array.isArray(expectedActionDigests) || items.length !== expectedActionDigests.length)
|
|
101
|
+
return false;
|
|
102
|
+
for (let i = 0; i < items.length; i++) {
|
|
103
|
+
const it = items[i];
|
|
104
|
+
if (it.attestation?.actionDigest !== expectedActionDigests[i])
|
|
105
|
+
return false;
|
|
106
|
+
if (!verifyRiskAttestation(it.commitment, it.attestation, authorityPublicKey))
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return (0, accumulator_1.verifyBoundedBudget)(items.map((i) => i.commitment), items.map((i) => i.rangeProof), bMax, budgetProof);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"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"}
|
package/dist/group.d.ts
CHANGED
|
@@ -34,7 +34,9 @@ export declare function scalarSub(a: bigint, b: bigint): bigint;
|
|
|
34
34
|
export declare function scalarMul(a: bigint, b: bigint): bigint;
|
|
35
35
|
/**
|
|
36
36
|
* Scalar multiplication `k·P` that tolerates k ≡ 0 (mod L) by returning the identity —
|
|
37
|
-
* @noble's `multiply` rejects 0 and values ≥ L, so we reduce first
|
|
37
|
+
* @noble's `multiply` rejects 0 and values ≥ L, so we reduce first. The multiplication is ALWAYS performed
|
|
38
|
+
* (by 1 when k ≡ 0) and the identity is selected afterwards, so the cost of the call does not reveal whether a
|
|
39
|
+
* secret scalar (a risk value, a bit of the slack) is zero.
|
|
38
40
|
*/
|
|
39
41
|
export declare function mul(P: Point, k: bigint): Point;
|
|
40
42
|
export declare function add(a: Point, b: Point): Point;
|
|
@@ -44,9 +46,13 @@ export declare function randScalar(): bigint;
|
|
|
44
46
|
export declare function numberToBytesLE(n: bigint, len: number): Uint8Array;
|
|
45
47
|
export declare function bytesToNumberLE(b: Uint8Array): bigint;
|
|
46
48
|
export declare function encodePoint(P: Point): string;
|
|
47
|
-
/** Decode a wire point; throws on a non-canonical / invalid ristretto encoding. */
|
|
49
|
+
/** Decode a wire point; throws on non-canonical base64url, a length other than 32 bytes, or a non-canonical / invalid ristretto encoding. */
|
|
48
50
|
export declare function decodePoint(s: string): Point;
|
|
49
51
|
export declare function encodeScalar(k: bigint): string;
|
|
52
|
+
/**
|
|
53
|
+
* Decode a wire scalar. Strict: canonical base64url, exactly 32 bytes, value < L. (Reducing instead would make
|
|
54
|
+
* every proof malleable: s and s + L, ~16 encodings of each scalar, would all verify.) Throws otherwise.
|
|
55
|
+
*/
|
|
50
56
|
export declare function decodeScalar(s: string): bigint;
|
|
51
57
|
/**
|
|
52
58
|
* Length-prefixed concatenation so distinct part sequences can never collide (each part is
|
package/dist/group.js
CHANGED
|
@@ -50,11 +50,14 @@ function scalarMul(a, b) {
|
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Scalar multiplication `k·P` that tolerates k ≡ 0 (mod L) by returning the identity —
|
|
53
|
-
* @noble's `multiply` rejects 0 and values ≥ L, so we reduce first
|
|
53
|
+
* @noble's `multiply` rejects 0 and values ≥ L, so we reduce first. The multiplication is ALWAYS performed
|
|
54
|
+
* (by 1 when k ≡ 0) and the identity is selected afterwards, so the cost of the call does not reveal whether a
|
|
55
|
+
* secret scalar (a risk value, a bit of the slack) is zero.
|
|
54
56
|
*/
|
|
55
57
|
function mul(P, k) {
|
|
56
58
|
const s = mod(k);
|
|
57
|
-
|
|
59
|
+
const r = P.multiply(s === 0n ? 1n : s);
|
|
60
|
+
return s === 0n ? exports.ZERO : r;
|
|
58
61
|
}
|
|
59
62
|
function add(a, b) {
|
|
60
63
|
return a.add(b);
|
|
@@ -95,15 +98,28 @@ function bytesToNumberLE(b) {
|
|
|
95
98
|
function encodePoint(P) {
|
|
96
99
|
return (0, pca_1.b64u)(P.toRawBytes());
|
|
97
100
|
}
|
|
98
|
-
/** Decode a wire point; throws on a non-canonical / invalid ristretto encoding. */
|
|
101
|
+
/** Decode a wire point; throws on non-canonical base64url, a length other than 32 bytes, or a non-canonical / invalid ristretto encoding. */
|
|
99
102
|
function decodePoint(s) {
|
|
100
|
-
|
|
103
|
+
const bytes = (0, pca_1.decodeB64uStrict)(s, 32);
|
|
104
|
+
if (bytes === null)
|
|
105
|
+
throw new RangeError('decodePoint: not a canonical 32-byte base64url string');
|
|
106
|
+
return ed25519_1.RistrettoPoint.fromHex(bytes);
|
|
101
107
|
}
|
|
102
108
|
function encodeScalar(k) {
|
|
103
109
|
return (0, pca_1.b64u)(numberToBytesLE(mod(k), 32));
|
|
104
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Decode a wire scalar. Strict: canonical base64url, exactly 32 bytes, value < L. (Reducing instead would make
|
|
113
|
+
* every proof malleable: s and s + L, ~16 encodings of each scalar, would all verify.) Throws otherwise.
|
|
114
|
+
*/
|
|
105
115
|
function decodeScalar(s) {
|
|
106
|
-
|
|
116
|
+
const bytes = (0, pca_1.decodeB64uStrict)(s, 32);
|
|
117
|
+
if (bytes === null)
|
|
118
|
+
throw new RangeError('decodeScalar: not a canonical 32-byte base64url string');
|
|
119
|
+
const v = bytesToNumberLE(bytes);
|
|
120
|
+
if (v >= exports.L)
|
|
121
|
+
throw new RangeError('decodeScalar: non-canonical scalar (>= L)');
|
|
122
|
+
return v;
|
|
107
123
|
}
|
|
108
124
|
// ---- Fiat-Shamir transcript -----------------------------------------------------------
|
|
109
125
|
/**
|
package/dist/group.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.js","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":";;;AA0CA,kBAGC;AAED,8BAEC;AAED,8BAEC;AAED,8BAEC;
|
|
1
|
+
{"version":3,"file":"group.js","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* adapters.ts binds both to the @atlasauth/pca core (PCActn.counter, RiskPolicy budget) without
|
|
15
15
|
* modifying it.
|
|
16
16
|
*/
|
|
17
|
-
export { type RatchetErrorCode, type RatchetSignature, type RatchetState, RatchetError, deriveRatchetRoot, signAtLeaf, verifyLeafSignature, availableLeaves, isLeafAvailable, } from './ratchet';
|
|
17
|
+
export { type RatchetErrorCode, type RatchetSignature, type RatchetState, RatchetError, deriveRatchetRoot, signAtLeaf, verifyLeafSignature, leafNullifier, availableLeaves, isLeafAvailable, } from './ratchet';
|
|
18
18
|
export { MAX_RATCHET_DEPTH } from './ggm';
|
|
19
|
-
export { type AccumulatorErrorCode, type RiskUnits, type RiskCommitment, type BitOrProof, type SchnorrProof, type BudgetProof, N_BITS, AccumulatorError, commitRisk, addCommitments, openCommitment, proveBudget, verifyBudget, } from './accumulator';
|
|
20
|
-
export { RISK_SCALE, counterToLeafIndex, leafIndexToCounter, leafIndexForAction, riskToUnits, budgetCeilingUnits, } from './adapters';
|
|
19
|
+
export { type AccumulatorErrorCode, type RiskUnits, type RiskCommitment, type BitOrProof, type SchnorrProof, type BudgetProof, N_BITS, MAX_PROVABLE_CEILING, type RiskRangeProof, AccumulatorError, commitRisk, addCommitments, openCommitment, proveBudget, verifyBudget, proveRiskRange, verifyRiskRange, verifyBoundedBudget, } from './accumulator';
|
|
20
|
+
export { RISK_SCALE, counterToLeafIndex, leafIndexToCounter, leafIndexForAction, riskToUnits, RiskQuantizer, budgetCeilingUnits, } from './adapters';
|
|
21
|
+
export { type SpentLeafStore, type LeafUseResult, type RiskAttestation, memorySpentLeafStore, verifyLeafSignatureOnce, issueRiskCommitment, verifyRiskAttestation, verifyAttestedBudget, } from './binding';
|
package/dist/index.js
CHANGED
|
@@ -16,29 +16,41 @@
|
|
|
16
16
|
* modifying it.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.budgetCeilingUnits = exports.riskToUnits = exports.leafIndexForAction = exports.leafIndexToCounter = exports.counterToLeafIndex = exports.RISK_SCALE = exports.verifyBudget = exports.proveBudget = exports.openCommitment = exports.addCommitments = exports.commitRisk = exports.AccumulatorError = exports.N_BITS = exports.MAX_RATCHET_DEPTH = exports.isLeafAvailable = exports.availableLeaves = exports.verifyLeafSignature = exports.signAtLeaf = exports.deriveRatchetRoot = exports.RatchetError = void 0;
|
|
19
|
+
exports.verifyAttestedBudget = exports.verifyRiskAttestation = exports.issueRiskCommitment = exports.verifyLeafSignatureOnce = exports.memorySpentLeafStore = exports.budgetCeilingUnits = exports.RiskQuantizer = exports.riskToUnits = exports.leafIndexForAction = exports.leafIndexToCounter = exports.counterToLeafIndex = exports.RISK_SCALE = exports.verifyBoundedBudget = exports.verifyRiskRange = exports.proveRiskRange = exports.verifyBudget = exports.proveBudget = exports.openCommitment = exports.addCommitments = exports.commitRisk = exports.AccumulatorError = exports.MAX_PROVABLE_CEILING = exports.N_BITS = exports.MAX_RATCHET_DEPTH = exports.isLeafAvailable = exports.availableLeaves = exports.leafNullifier = exports.verifyLeafSignature = exports.signAtLeaf = exports.deriveRatchetRoot = exports.RatchetError = void 0;
|
|
20
20
|
var ratchet_1 = require("./ratchet");
|
|
21
21
|
Object.defineProperty(exports, "RatchetError", { enumerable: true, get: function () { return ratchet_1.RatchetError; } });
|
|
22
22
|
Object.defineProperty(exports, "deriveRatchetRoot", { enumerable: true, get: function () { return ratchet_1.deriveRatchetRoot; } });
|
|
23
23
|
Object.defineProperty(exports, "signAtLeaf", { enumerable: true, get: function () { return ratchet_1.signAtLeaf; } });
|
|
24
24
|
Object.defineProperty(exports, "verifyLeafSignature", { enumerable: true, get: function () { return ratchet_1.verifyLeafSignature; } });
|
|
25
|
+
Object.defineProperty(exports, "leafNullifier", { enumerable: true, get: function () { return ratchet_1.leafNullifier; } });
|
|
25
26
|
Object.defineProperty(exports, "availableLeaves", { enumerable: true, get: function () { return ratchet_1.availableLeaves; } });
|
|
26
27
|
Object.defineProperty(exports, "isLeafAvailable", { enumerable: true, get: function () { return ratchet_1.isLeafAvailable; } });
|
|
27
28
|
var ggm_1 = require("./ggm");
|
|
28
29
|
Object.defineProperty(exports, "MAX_RATCHET_DEPTH", { enumerable: true, get: function () { return ggm_1.MAX_RATCHET_DEPTH; } });
|
|
29
30
|
var accumulator_1 = require("./accumulator");
|
|
30
31
|
Object.defineProperty(exports, "N_BITS", { enumerable: true, get: function () { return accumulator_1.N_BITS; } });
|
|
32
|
+
Object.defineProperty(exports, "MAX_PROVABLE_CEILING", { enumerable: true, get: function () { return accumulator_1.MAX_PROVABLE_CEILING; } });
|
|
31
33
|
Object.defineProperty(exports, "AccumulatorError", { enumerable: true, get: function () { return accumulator_1.AccumulatorError; } });
|
|
32
34
|
Object.defineProperty(exports, "commitRisk", { enumerable: true, get: function () { return accumulator_1.commitRisk; } });
|
|
33
35
|
Object.defineProperty(exports, "addCommitments", { enumerable: true, get: function () { return accumulator_1.addCommitments; } });
|
|
34
36
|
Object.defineProperty(exports, "openCommitment", { enumerable: true, get: function () { return accumulator_1.openCommitment; } });
|
|
35
37
|
Object.defineProperty(exports, "proveBudget", { enumerable: true, get: function () { return accumulator_1.proveBudget; } });
|
|
36
38
|
Object.defineProperty(exports, "verifyBudget", { enumerable: true, get: function () { return accumulator_1.verifyBudget; } });
|
|
39
|
+
Object.defineProperty(exports, "proveRiskRange", { enumerable: true, get: function () { return accumulator_1.proveRiskRange; } });
|
|
40
|
+
Object.defineProperty(exports, "verifyRiskRange", { enumerable: true, get: function () { return accumulator_1.verifyRiskRange; } });
|
|
41
|
+
Object.defineProperty(exports, "verifyBoundedBudget", { enumerable: true, get: function () { return accumulator_1.verifyBoundedBudget; } });
|
|
37
42
|
var adapters_1 = require("./adapters");
|
|
38
43
|
Object.defineProperty(exports, "RISK_SCALE", { enumerable: true, get: function () { return adapters_1.RISK_SCALE; } });
|
|
39
44
|
Object.defineProperty(exports, "counterToLeafIndex", { enumerable: true, get: function () { return adapters_1.counterToLeafIndex; } });
|
|
40
45
|
Object.defineProperty(exports, "leafIndexToCounter", { enumerable: true, get: function () { return adapters_1.leafIndexToCounter; } });
|
|
41
46
|
Object.defineProperty(exports, "leafIndexForAction", { enumerable: true, get: function () { return adapters_1.leafIndexForAction; } });
|
|
42
47
|
Object.defineProperty(exports, "riskToUnits", { enumerable: true, get: function () { return adapters_1.riskToUnits; } });
|
|
48
|
+
Object.defineProperty(exports, "RiskQuantizer", { enumerable: true, get: function () { return adapters_1.RiskQuantizer; } });
|
|
43
49
|
Object.defineProperty(exports, "budgetCeilingUnits", { enumerable: true, get: function () { return adapters_1.budgetCeilingUnits; } });
|
|
50
|
+
var binding_1 = require("./binding");
|
|
51
|
+
Object.defineProperty(exports, "memorySpentLeafStore", { enumerable: true, get: function () { return binding_1.memorySpentLeafStore; } });
|
|
52
|
+
Object.defineProperty(exports, "verifyLeafSignatureOnce", { enumerable: true, get: function () { return binding_1.verifyLeafSignatureOnce; } });
|
|
53
|
+
Object.defineProperty(exports, "issueRiskCommitment", { enumerable: true, get: function () { return binding_1.issueRiskCommitment; } });
|
|
54
|
+
Object.defineProperty(exports, "verifyRiskAttestation", { enumerable: true, get: function () { return binding_1.verifyRiskAttestation; } });
|
|
55
|
+
Object.defineProperty(exports, "verifyAttestedBudget", { enumerable: true, get: function () { return binding_1.verifyAttestedBudget; } });
|
|
44
56
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,qCAWmB;AAPjB,uGAAA,YAAY,OAAA;AACZ,4GAAA,iBAAiB,OAAA;AACjB,qGAAA,UAAU,OAAA;AACV,8GAAA,mBAAmB,OAAA;AACnB,wGAAA,aAAa,OAAA;AACb,0GAAA,eAAe,OAAA;AACf,0GAAA,eAAe,OAAA;AAGjB,6BAA0C;AAAjC,wGAAA,iBAAiB,OAAA;AAE1B,6CAmBuB;AAZrB,qGAAA,MAAM,OAAA;AACN,mHAAA,oBAAoB,OAAA;AAEpB,+GAAA,gBAAgB,OAAA;AAChB,yGAAA,UAAU,OAAA;AACV,6GAAA,cAAc,OAAA;AACd,6GAAA,cAAc,OAAA;AACd,0GAAA,WAAW,OAAA;AACX,2GAAA,YAAY,OAAA;AACZ,6GAAA,cAAc,OAAA;AACd,8GAAA,eAAe,OAAA;AACf,kHAAA,mBAAmB,OAAA;AAGrB,uCAQoB;AAPlB,sGAAA,UAAU,OAAA;AACV,8GAAA,kBAAkB,OAAA;AAClB,8GAAA,kBAAkB,OAAA;AAClB,8GAAA,kBAAkB,OAAA;AAClB,uGAAA,WAAW,OAAA;AACX,yGAAA,aAAa,OAAA;AACb,8GAAA,kBAAkB,OAAA;AAGpB,qCASmB;AALjB,+GAAA,oBAAoB,OAAA;AACpB,kHAAA,uBAAuB,OAAA;AACvB,8GAAA,mBAAmB,OAAA;AACnB,gHAAA,qBAAqB,OAAA;AACrB,+GAAA,oBAAoB,OAAA"}
|
package/dist/ratchet.d.ts
CHANGED
|
@@ -23,6 +23,13 @@ export interface RatchetSignature {
|
|
|
23
23
|
leafPubKey: string;
|
|
24
24
|
/** Merkle inclusion proof that `leafPubKey` is the leaf at this index under the root commitment. */
|
|
25
25
|
merklePath: InclusionProof;
|
|
26
|
+
/**
|
|
27
|
+
* b64u nullifier of the spent leaf: `H(domain ‖ rootCommitment ‖ leafIndex)`. A verifier recomputes it
|
|
28
|
+
* ({@link leafNullifier}) and records it in a {@link SpentLeafStore} (see `verifyLeafSignatureOnce`)
|
|
29
|
+
* so a second signature at the same leaf is DETECTED (RT-11). The ratchet alone cannot stop a
|
|
30
|
+
* holder who kept the old state; only a verifier-side spent set can.
|
|
31
|
+
*/
|
|
32
|
+
nullifier: string;
|
|
26
33
|
}
|
|
27
34
|
/**
|
|
28
35
|
* The live ratchet. `leafPubKeys` are public (safe to retain; needed to build Merkle proofs).
|
|
@@ -36,6 +43,8 @@ export interface RatchetState {
|
|
|
36
43
|
readonly leafPubKeys: readonly string[];
|
|
37
44
|
readonly covering: ReadonlyMap<string, CoverNode>;
|
|
38
45
|
}
|
|
46
|
+
/** The per-leaf nullifier a verifier records to detect leaf reuse: `b64u(sha256(domain ‖ lp(root) ‖ index))`. */
|
|
47
|
+
export declare function leafNullifier(rootCommitment: string, leafIndex: number): string;
|
|
39
48
|
/**
|
|
40
49
|
* Build a ratchet from a root `seed` (≥ 32 bytes of entropy) and tree `depth`. Returns the public
|
|
41
50
|
* `rootCommitment` (a Merkle root over all 2^depth leaf public keys) and the live `state`.
|
package/dist/ratchet.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RatchetError = void 0;
|
|
4
|
+
exports.leafNullifier = leafNullifier;
|
|
4
5
|
exports.deriveRatchetRoot = deriveRatchetRoot;
|
|
5
6
|
exports.signAtLeaf = signAtLeaf;
|
|
6
7
|
exports.verifyLeafSignature = verifyLeafSignature;
|
|
@@ -9,6 +10,7 @@ exports.isLeafAvailable = isLeafAvailable;
|
|
|
9
10
|
const ed25519_1 = require("@noble/curves/ed25519");
|
|
10
11
|
const pca_1 = require("@atlasauth/pca");
|
|
11
12
|
const ggm_1 = require("./ggm");
|
|
13
|
+
const pca_2 = require("@atlasauth/pca");
|
|
12
14
|
const group_1 = require("./group");
|
|
13
15
|
class RatchetError extends Error {
|
|
14
16
|
code;
|
|
@@ -19,6 +21,17 @@ class RatchetError extends Error {
|
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
exports.RatchetError = RatchetError;
|
|
24
|
+
const NULLIFIER_DOMAIN = (0, group_1.utf8)('atlas-pca-ratchet/nullifier/v1\0');
|
|
25
|
+
/** The per-leaf nullifier a verifier records to detect leaf reuse: `b64u(sha256(domain ‖ lp(root) ‖ index))`. */
|
|
26
|
+
function leafNullifier(rootCommitment, leafIndex) {
|
|
27
|
+
const root = (0, group_1.utf8)(rootCommitment);
|
|
28
|
+
const out = new Uint8Array(NULLIFIER_DOMAIN.length + 4 + root.length + 8);
|
|
29
|
+
out.set(NULLIFIER_DOMAIN, 0);
|
|
30
|
+
new DataView(out.buffer).setUint32(NULLIFIER_DOMAIN.length, root.length, false);
|
|
31
|
+
out.set(root, NULLIFIER_DOMAIN.length + 4);
|
|
32
|
+
new DataView(out.buffer).setBigUint64(NULLIFIER_DOMAIN.length + 4 + root.length, BigInt(leafIndex), false);
|
|
33
|
+
return (0, pca_1.b64u)((0, pca_2.sha256)(out));
|
|
34
|
+
}
|
|
22
35
|
const SIG_DOMAIN = (0, group_1.utf8)('atlas-pca-ratchet/leaf-sig/v1\0');
|
|
23
36
|
/** Domain-separated signed message: binds the leaf index so a signature cannot be lifted elsewhere. */
|
|
24
37
|
function leafSigMessage(leafIndex, message) {
|
|
@@ -87,7 +100,7 @@ function signAtLeaf(state, leafIndex, message) {
|
|
|
87
100
|
covering.set((0, ggm_1.coverKey)(sib.level, sib.nodeIndex), sib);
|
|
88
101
|
}
|
|
89
102
|
return {
|
|
90
|
-
signature: { edSig, leafPubKey, merklePath },
|
|
103
|
+
signature: { edSig, leafPubKey, merklePath, nullifier: leafNullifier(state.rootCommitment, leafIndex) },
|
|
91
104
|
newState: { ...state, covering },
|
|
92
105
|
};
|
|
93
106
|
}
|
|
@@ -100,7 +113,9 @@ function verifyLeafSignature(rootCommitment, leafIndex, message, signature) {
|
|
|
100
113
|
try {
|
|
101
114
|
if (signature === null || typeof signature !== 'object')
|
|
102
115
|
return false;
|
|
103
|
-
const { edSig, leafPubKey, merklePath } = signature;
|
|
116
|
+
const { edSig, leafPubKey, merklePath, nullifier } = signature;
|
|
117
|
+
if (typeof nullifier !== 'string' || nullifier !== leafNullifier(rootCommitment, leafIndex))
|
|
118
|
+
return false;
|
|
104
119
|
if (typeof edSig !== 'string' || typeof leafPubKey !== 'string' || merklePath === null || typeof merklePath !== 'object') {
|
|
105
120
|
return false;
|
|
106
121
|
}
|
package/dist/ratchet.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ratchet.js","sourceRoot":"","sources":["../src/ratchet.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ratchet.js","sourceRoot":"","sources":["../src/ratchet.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlasauth/pca-ratchet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "PCA Capability Ratchet: puncturable forward-secure capability keys (cryptographic one-time-use — a spent action can never be re-signed) plus a homomorphic Pedersen risk accumulator for zero-knowledge proof of the Sigma-risk <= budget ceiling across a delegation chain.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"forward secrecy",
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@noble/curves": "^1.6.0",
|
|
36
36
|
"@noble/hashes": "^1.5.0",
|
|
37
|
-
"@atlasauth/pca": "0.
|
|
37
|
+
"@atlasauth/pca": "0.4.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
+
"fast-check": "^3.23.1",
|
|
40
41
|
"typescript": "^5.6.3",
|
|
41
42
|
"vitest": "^2.1.4"
|
|
42
43
|
},
|