@atlasauth/pca-mpc 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +65 -2
- package/dist/beaver.d.ts +49 -0
- package/dist/beaver.js +72 -0
- package/dist/beaver.js.map +1 -0
- package/dist/compose.d.ts +21 -0
- package/dist/compose.js +33 -0
- package/dist/compose.js.map +1 -0
- package/dist/csprng.d.ts +46 -0
- package/dist/csprng.js +86 -0
- package/dist/csprng.js.map +1 -0
- package/dist/ec.d.ts +130 -0
- package/dist/ec.js +475 -0
- package/dist/ec.js.map +1 -0
- package/dist/endemic-ot.d.ts +209 -0
- package/dist/endemic-ot.js +405 -0
- package/dist/endemic-ot.js.map +1 -0
- package/dist/field.d.ts +34 -0
- package/dist/field.js +65 -0
- package/dist/field.js.map +1 -0
- package/dist/gf128.d.ts +23 -0
- package/dist/gf128.js +59 -0
- package/dist/gf128.js.map +1 -0
- package/dist/hybrid-ot.d.ts +153 -0
- package/dist/hybrid-ot.js +241 -0
- package/dist/hybrid-ot.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/kem-ot.d.ts +292 -0
- package/dist/kem-ot.js +559 -0
- package/dist/kem-ot.js.map +1 -0
- package/dist/mascot.d.ts +189 -0
- package/dist/mascot.js +322 -0
- package/dist/mascot.js.map +1 -0
- package/dist/ot.d.ts +212 -0
- package/dist/ot.js +536 -0
- package/dist/ot.js.map +1 -0
- package/dist/party.d.ts +38 -0
- package/dist/party.js +40 -0
- package/dist/party.js.map +1 -0
- package/dist/runner.d.ts +56 -0
- package/dist/runner.js +97 -0
- package/dist/runner.js.map +1 -0
- package/dist/sharing.d.ts +40 -0
- package/dist/sharing.js +97 -0
- package/dist/sharing.js.map +1 -0
- package/dist/spdz-runner.d.ts +50 -0
- package/dist/spdz-runner.js +107 -0
- package/dist/spdz-runner.js.map +1 -0
- package/dist/spdz.d.ts +136 -0
- package/dist/spdz.js +243 -0
- package/dist/spdz.js.map +1 -0
- package/dist/thermometer.d.ts +22 -0
- package/dist/thermometer.js +41 -0
- package/dist/thermometer.js.map +1 -0
- package/package.json +58 -3
package/dist/ot.js
ADDED
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Oblivious transfer — the real cryptographic root of the no-dealer offline phase.
|
|
4
|
+
*
|
|
5
|
+
* A 1-out-of-2 OT lets a RECEIVER with a choice bit `c` obtain exactly message `m_c` from a SENDER's
|
|
6
|
+
* pair `(m_0, m_1)`, such that the sender learns nothing about `c` and the receiver learns nothing
|
|
7
|
+
* about `m_{1−c}`. That single primitive is enough to multiply two parties' secret shares without a
|
|
8
|
+
* dealer (Gilboa's trick, see `mascot.ts`), which is enough to generate Beaver triples and SPDZ MACs
|
|
9
|
+
* with no trusted party. This module provides OT two ways:
|
|
10
|
+
*
|
|
11
|
+
* 1. **Base OT — MALICIOUSLY-secure Chou–Orlandi over the Ed25519 subgroup (`ec.ts`).** The core is
|
|
12
|
+
* "simplest OT": sender samples `y`, publishes `S = y·B`, holds `T = y·S`; receiver with choice `c`
|
|
13
|
+
* samples `x`, publishes `R = x·B + c·S`, derives pad `k = H(x·S)`; sender derives `k_b = H(y·R − b·T)`
|
|
14
|
+
* for `b∈{0,1}`; since `y·R = x·(y·B) + c·T`, `k_c = k` while `k_{1−c}` is `H` of a point the receiver
|
|
15
|
+
* can't compute (it would need the discrete log). **Receiver-choice privacy is information-theoretic
|
|
16
|
+
* in the transcript:** `R = x·B + c·S` with `x` uniform is a uniform subgroup element whatever `c` is
|
|
17
|
+
* — for every observed `R` there is one `x` consistent with `c=0` and one with `c=1` (`x' = x − y`),
|
|
18
|
+
* so the sender's view is identically distributed for both choices. Two additions upgrade this from
|
|
19
|
+
* semi-honest to **malicious-secure against both a cheating sender AND a cheating receiver** (docs
|
|
20
|
+
* §7.1 item a):
|
|
21
|
+
* • **the sender proves knowledge of `y` with a Schnorr NIZK on `S = y·B`** (`ec.ts`), so a sender
|
|
22
|
+
* cannot use an `S` it cannot open (e.g. one crafted to leak the receiver's choice) — the
|
|
23
|
+
* receiver verifies the proof and ABORTS before forming `R`;
|
|
24
|
+
* • **every received point is validated** (on-curve + prime-order-subgroup cofactor check +
|
|
25
|
+
* non-identity): the receiver validates `S`, the sender validates every `R_i`, so neither party
|
|
26
|
+
* can inject an off-curve / small-order / mixed-order point for a small-subgroup attack.
|
|
27
|
+
* The IKNP setup consumes this as a **random OT** (`malBaseRandomOT`): the two transferred seeds ARE
|
|
28
|
+
* the RO pads `(H(y·R), H(y·R − T))`, so there are **no sender-chosen ciphertexts** and hence no
|
|
29
|
+
* selective-failure surface — the only abort (bad `S`/proof/`R_i`) is independent of the receiver's
|
|
30
|
+
* selector, which is exactly what malicious security of the role-inverted base OTs requires. The
|
|
31
|
+
* chosen-message `baseOT` wrapper (random OT + one-time-pad + a commit-to-message check) is used by
|
|
32
|
+
* the direct OT tests; its commitment catches a sender that encrypts inconsistently with its commitment.
|
|
33
|
+
*
|
|
34
|
+
* 2. **OT extension — IKNP + the KOS consistency check (MALICIOUS-secure).** Base OT needs public-key
|
|
35
|
+
* ops per transfer; the offline phase needs hundreds of thousands of OTs. IKNP turns `κ = 128` base
|
|
36
|
+
* OTs (done once) into arbitrarily many OTs using only a hash/PRG. Roles invert for the base OTs:
|
|
37
|
+
* the extension SENDER plays base-receiver with a secret selector `s ∈ {0,1}^κ`; the extension
|
|
38
|
+
* RECEIVER plays base-sender with `κ` seed pairs. Thereafter each extension round of `m` OTs costs
|
|
39
|
+
* `κ` PRG expansions plus `~3·m` hashes. Correctness: the receiver recovers exactly `m_{c_j}` for
|
|
40
|
+
* every `j`; the sender's `s` (hidden by the base OTs) and the correlation-robust hash keep the
|
|
41
|
+
* unchosen messages hidden.
|
|
42
|
+
*
|
|
43
|
+
* Plain IKNP is only SEMI-HONEST: a cheating RECEIVER can send an extension matrix `u` that encodes
|
|
44
|
+
* *different* choice vectors in different columns, which breaks the row correlation `q_j = t_j ⊕
|
|
45
|
+
* (b_j·s)` and lets the receiver learn bits of the sender's selector `s` (and thus the unchosen
|
|
46
|
+
* messages). The **KOS correlation check** (Keller–Orsini–Scholl, "Actively Secure OT Extension
|
|
47
|
+
* with Optimal Overhead") closes exactly this: after `u` is on the wire, the parties draw public
|
|
48
|
+
* random weights `χ_j ∈ GF(2^κ)` (one per row, bound to `u` by a Fiat–Shamir hash here), the
|
|
49
|
+
* receiver reveals `x = Σ_j b_j·χ_j` and `t = Σ_j χ_j·t_j`, and the sender checks
|
|
50
|
+
* `Σ_j χ_j·q_j == t ⊕ x·s` in GF(2^κ). Honestly this always holds (`q_j = t_j ⊕ b_j·s`); a receiver
|
|
51
|
+
* who deviated in `u` satisfies it with probability ≤ `2^{-κ} = 2^{-128}`, so a deviation ABORTS.
|
|
52
|
+
* The check is run over `m + κ + SSEC` rows — the extra `κ + SSEC` random "sacrifice" OT rows mask
|
|
53
|
+
* the revealed combination (receiver privacy) and give statistical soundness. This makes the OT
|
|
54
|
+
* extension **malicious-secure**, not just semi-honest.
|
|
55
|
+
*
|
|
56
|
+
* In-process model: both parties run in one process and the functions take *both* parties' inputs and
|
|
57
|
+
* return the receiver's outputs plus an inspectable transcript (the receiver's wire message `R`, the
|
|
58
|
+
* sender's ciphertexts, the IKNP `u` matrix). That is exactly what the tests assert over: receiver
|
|
59
|
+
* correctness, sender-side choice-hiding from the transcript, and the KOS check aborting on a tampered
|
|
60
|
+
* `u`. See docs §7.1 for the remaining boundary (real async transport, constant-time, CSPRNG).
|
|
61
|
+
*/
|
|
62
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
+
exports.OtChannel = exports.BaseOtAbort = exports.MalOtAbort = exports.SSEC = exports.KAPPA = void 0;
|
|
64
|
+
exports.splitMix64 = splitMix64;
|
|
65
|
+
exports.otRandom = otRandom;
|
|
66
|
+
exports.malBaseRandomOT = malBaseRandomOT;
|
|
67
|
+
exports.baseOT = baseOT;
|
|
68
|
+
const node_crypto_1 = require("node:crypto");
|
|
69
|
+
const ec_1 = require("./ec");
|
|
70
|
+
const gf128_1 = require("./gf128");
|
|
71
|
+
const csprng_1 = require("./csprng");
|
|
72
|
+
/** IKNP security parameter (number of base OTs / width of the selector s). */
|
|
73
|
+
exports.KAPPA = 128;
|
|
74
|
+
/**
|
|
75
|
+
* KOS statistical-security parameter: the number of EXTRA random check-OT rows (beyond the `κ` that
|
|
76
|
+
* mask the revealed combination) appended to every extension round. Together `κ + SSEC` padding rows
|
|
77
|
+
* give the correlation check its receiver-privacy and statistical soundness margin.
|
|
78
|
+
*/
|
|
79
|
+
exports.SSEC = 64;
|
|
80
|
+
/** Raised when the KOS correlation check fails: a cheating OT-extension receiver is detected → ABORT. */
|
|
81
|
+
class MalOtAbort extends Error {
|
|
82
|
+
constructor(message) {
|
|
83
|
+
super(message);
|
|
84
|
+
this.name = 'MalOtAbort';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.MalOtAbort = MalOtAbort;
|
|
88
|
+
/** Seed length in bytes for base-OT messages / IKNP seeds (κ = 128 bits). */
|
|
89
|
+
const SEED_BYTES = exports.KAPPA / 8;
|
|
90
|
+
/** A raw SplitMix64 64-bit stream (deterministic). Production uses a CSPRNG with a secret seed. */
|
|
91
|
+
function splitMix64(seed) {
|
|
92
|
+
const MASK64 = (1n << 64n) - 1n;
|
|
93
|
+
let s = seed & MASK64;
|
|
94
|
+
return () => {
|
|
95
|
+
s = (s + 0x9e3779b97f4a7c15n) & MASK64;
|
|
96
|
+
let z = s;
|
|
97
|
+
z = ((z ^ (z >> 30n)) * 0xbf58476d1ce4e5b9n) & MASK64;
|
|
98
|
+
z = ((z ^ (z >> 27n)) * 0x94d049bb133111ebn) & MASK64;
|
|
99
|
+
z = (z ^ (z >> 31n)) & MASK64;
|
|
100
|
+
return z;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Build an OtRandom from a SplitMix64-style 64-bit stream (deterministic; CSPRNG in production). */
|
|
104
|
+
function otRandom(next64) {
|
|
105
|
+
return {
|
|
106
|
+
scalar() {
|
|
107
|
+
// Assemble 256 bits then reduce mod L; reject 0.
|
|
108
|
+
for (;;) {
|
|
109
|
+
let acc = 0n;
|
|
110
|
+
for (let i = 0; i < 4; i++)
|
|
111
|
+
acc = (acc << 64n) | next64();
|
|
112
|
+
const s = acc % ec_1.L;
|
|
113
|
+
if (s !== 0n)
|
|
114
|
+
return s;
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
bytes(n) {
|
|
118
|
+
const out = new Uint8Array(n);
|
|
119
|
+
let have = 0;
|
|
120
|
+
while (have < n) {
|
|
121
|
+
let v = next64();
|
|
122
|
+
for (let i = 0; i < 8 && have < n; i++) {
|
|
123
|
+
out[have++] = Number(v & 0xffn);
|
|
124
|
+
v >>= 8n;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// --------------------------------------------------------------------------------------------------
|
|
132
|
+
// Hash / PRG helpers (SHA-256 based). Deterministic; a production build uses the same constructions
|
|
133
|
+
// over a CSPRNG and a formally correlation-robust hash.
|
|
134
|
+
// --------------------------------------------------------------------------------------------------
|
|
135
|
+
function sha256(...chunks) {
|
|
136
|
+
const h = (0, node_crypto_1.createHash)('sha256');
|
|
137
|
+
for (const c of chunks)
|
|
138
|
+
h.update(c);
|
|
139
|
+
return new Uint8Array(h.digest());
|
|
140
|
+
}
|
|
141
|
+
function u32(x) {
|
|
142
|
+
const b = new Uint8Array(4);
|
|
143
|
+
b[0] = (x >>> 24) & 0xff;
|
|
144
|
+
b[1] = (x >>> 16) & 0xff;
|
|
145
|
+
b[2] = (x >>> 8) & 0xff;
|
|
146
|
+
b[3] = x & 0xff;
|
|
147
|
+
return b;
|
|
148
|
+
}
|
|
149
|
+
/** Key-derivation from a group point: H("ot-kdf" ‖ index ‖ encode(P)) → SEED_BYTES bytes. */
|
|
150
|
+
function kdfPoint(index, p) {
|
|
151
|
+
return sha256(TAG_KDF, u32(index), (0, ec_1.encodePoint)(p)).slice(0, SEED_BYTES);
|
|
152
|
+
}
|
|
153
|
+
const TAG_KDF = new TextEncoder().encode('atlas-pca-mpc/ot-kdf');
|
|
154
|
+
const TAG_PRG = new TextEncoder().encode('atlas-pca-mpc/ot-prg');
|
|
155
|
+
const TAG_CRH = new TextEncoder().encode('atlas-pca-mpc/ot-crh');
|
|
156
|
+
const TAG_KOS = new TextEncoder().encode('atlas-pca-mpc/ot-kos');
|
|
157
|
+
const TAG_COMMIT = new TextEncoder().encode('atlas-pca-mpc/ot-msg-commit');
|
|
158
|
+
/**
|
|
159
|
+
* Derive the KOS row-weights χ_j ∈ GF(2^128) for one extension round, bound to the committed `u`
|
|
160
|
+
* matrix (Fiat–Shamir). The sender and receiver both derive the SAME χ from the `u` on the wire, so a
|
|
161
|
+
* cheating receiver cannot pick `u` after seeing χ. In the real protocol χ comes from a secure
|
|
162
|
+
* coin-flip after the receiver commits to `u`; the transcript-hash here models that round and keeps the
|
|
163
|
+
* check deterministic for tests. The seed expands through a fast (non-crypto) stream — fine because χ
|
|
164
|
+
* only needs to be unpredictable-before-commit and uniform, which the hash seed provides.
|
|
165
|
+
*/
|
|
166
|
+
function kosChallenges(u, mExt) {
|
|
167
|
+
const h = (0, node_crypto_1.createHash)('sha256');
|
|
168
|
+
h.update(TAG_KOS);
|
|
169
|
+
h.update(u32(u.length));
|
|
170
|
+
const buf = new Uint8Array(SEED_BYTES);
|
|
171
|
+
for (const col of u) {
|
|
172
|
+
let v = col;
|
|
173
|
+
for (let i = 0; i < SEED_BYTES; i++) {
|
|
174
|
+
buf[i] = Number(v & 0xffn);
|
|
175
|
+
v >>= 8n;
|
|
176
|
+
}
|
|
177
|
+
h.update(buf);
|
|
178
|
+
}
|
|
179
|
+
const digest = new Uint8Array(h.digest());
|
|
180
|
+
let lo = 0n;
|
|
181
|
+
for (let i = 0; i < 8; i++)
|
|
182
|
+
lo |= BigInt(digest[i]) << BigInt(8 * i);
|
|
183
|
+
let hi = 0n;
|
|
184
|
+
for (let i = 8; i < 16; i++)
|
|
185
|
+
hi |= BigInt(digest[i]) << BigInt(8 * (i - 8));
|
|
186
|
+
const s0 = splitMix64(lo === 0n ? 1n : lo);
|
|
187
|
+
const s1 = splitMix64(hi === 0n ? 0x9e3779b97f4a7c15n : hi);
|
|
188
|
+
const chi = new Array(mExt);
|
|
189
|
+
for (let j = 0; j < mExt; j++)
|
|
190
|
+
chi[j] = (s0() << 64n) | s1();
|
|
191
|
+
return chi;
|
|
192
|
+
}
|
|
193
|
+
/** XOR into `acc` the χ_j for every SET bit `j` of the (≤ mExt-bit) column `col`, fast via 32-bit words. */
|
|
194
|
+
function accumSetBits(col, chi, acc) {
|
|
195
|
+
let v = col;
|
|
196
|
+
let base = 0;
|
|
197
|
+
while (v > 0n) {
|
|
198
|
+
let w = Number(v & 0xffffffffn) >>> 0;
|
|
199
|
+
v >>= 32n;
|
|
200
|
+
while (w !== 0) {
|
|
201
|
+
const b = w & -w; // lowest set bit
|
|
202
|
+
const j = base + (31 - Math.clz32(b));
|
|
203
|
+
acc = (0, gf128_1.gf128Add)(acc, chi[j]);
|
|
204
|
+
w ^= b;
|
|
205
|
+
}
|
|
206
|
+
base += 32;
|
|
207
|
+
}
|
|
208
|
+
return acc;
|
|
209
|
+
}
|
|
210
|
+
/** XOR two equal-length byte arrays. */
|
|
211
|
+
function xorBytes(a, b) {
|
|
212
|
+
const out = new Uint8Array(a.length);
|
|
213
|
+
for (let i = 0; i < a.length; i++)
|
|
214
|
+
out[i] = a[i] ^ b[i];
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
/** PRG: expand a seed to `nbits` bits as a bigint, from block offset `startBlock` (counter mode). */
|
|
218
|
+
function prgBits(seed, startBlock, nbits) {
|
|
219
|
+
const nBlocks = Math.ceil(nbits / 256);
|
|
220
|
+
let acc = 0n;
|
|
221
|
+
let produced = 0;
|
|
222
|
+
for (let t = 0; t < nBlocks; t++) {
|
|
223
|
+
const block = sha256(TAG_PRG, seed, u32(startBlock + t));
|
|
224
|
+
for (let i = 0; i < 32 && produced < nbits; i++) {
|
|
225
|
+
acc |= BigInt(block[i]) << BigInt(produced);
|
|
226
|
+
produced += 8;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Mask to exactly nbits.
|
|
230
|
+
return acc & ((1n << BigInt(nbits)) - 1n);
|
|
231
|
+
}
|
|
232
|
+
/** Correlation-robust hash H(j, row) → a 64-bit mask (field messages are < 2^61). */
|
|
233
|
+
function crh(j, row) {
|
|
234
|
+
const rowBytes = new Uint8Array(SEED_BYTES);
|
|
235
|
+
let v = row;
|
|
236
|
+
for (let i = 0; i < SEED_BYTES; i++) {
|
|
237
|
+
rowBytes[i] = Number(v & 0xffn);
|
|
238
|
+
v >>= 8n;
|
|
239
|
+
}
|
|
240
|
+
const d = sha256(TAG_CRH, u32(j), rowBytes);
|
|
241
|
+
let acc = 0n;
|
|
242
|
+
for (let i = 0; i < 8; i++)
|
|
243
|
+
acc |= BigInt(d[i]) << BigInt(8 * i);
|
|
244
|
+
return acc;
|
|
245
|
+
}
|
|
246
|
+
// --------------------------------------------------------------------------------------------------
|
|
247
|
+
// Base OT — MALICIOUSLY-secure Chou–Orlandi, batched (docs §7.1 item a).
|
|
248
|
+
//
|
|
249
|
+
// Two hardening layers upgrade the semi-honest "simplest OT" to malicious security against BOTH roles:
|
|
250
|
+
// • the SENDER proves knowledge of `y` with a Schnorr NIZK on `S = y·B` (`ec.ts`); the receiver
|
|
251
|
+
// verifies it and ABORTS before forming any `R`, so a sender cannot use an `S` it cannot open;
|
|
252
|
+
// • every point crossing the trust boundary is validated (on-curve + prime-order cofactor check +
|
|
253
|
+
// non-identity): the receiver validates `S` (and the proof's `U`), the sender validates every
|
|
254
|
+
// `R_i`, so neither party can inject an off-curve / small-order / mixed-order point.
|
|
255
|
+
// The core is run as a RANDOM OT (`malBaseRandomOT`): the two transferred seeds ARE the RO pads, so
|
|
256
|
+
// there are no sender-chosen ciphertexts and no selective-failure surface. The chosen-message `baseOT`
|
|
257
|
+
// wrapper then one-time-pads the messages under those pads AND sends a per-message RO commitment; the
|
|
258
|
+
// receiver recomputes the commitment on the message+pad it recovers and aborts on a mismatch — this is
|
|
259
|
+
// what catches a sender that encrypts a message inconsistent with what it committed.
|
|
260
|
+
// --------------------------------------------------------------------------------------------------
|
|
261
|
+
/** Raised when a base OT aborts: a cheating sender (bad proof / inconsistent ciphertext) is detected. */
|
|
262
|
+
class BaseOtAbort extends Error {
|
|
263
|
+
constructor(message) {
|
|
264
|
+
super(message);
|
|
265
|
+
this.name = 'BaseOtAbort';
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
exports.BaseOtAbort = BaseOtAbort;
|
|
269
|
+
/** Per-message RO commitment com_{i,b} = H(TAG ‖ i ‖ b ‖ msg ‖ pad). */
|
|
270
|
+
function otCommit(i, b, msg, pad) {
|
|
271
|
+
return sha256(TAG_COMMIT, u32(i), Uint8Array.of(b & 1), msg, pad);
|
|
272
|
+
}
|
|
273
|
+
function ctEqual(a, b) {
|
|
274
|
+
return a.length === b.length && (0, node_crypto_1.timingSafeEqual)(Buffer.from(a), Buffer.from(b));
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* The MALICIOUS-secure RANDOM base OT: `count = choices.length` 1-of-2 random OTs. The sender publishes
|
|
278
|
+
* `S = y·B` with a Schnorr proof of knowledge of `y`; the receiver validates `S` + the proof and
|
|
279
|
+
* ABORTS on failure, then forms its `R_i`; the sender validates every `R_i` and derives the pad pairs.
|
|
280
|
+
* No messages are transferred — the pads ARE the random output. `tamper` injects malicious behaviour
|
|
281
|
+
* for tests. Both parties are simulated in-process.
|
|
282
|
+
*/
|
|
283
|
+
function malBaseRandomOT(choices, rng = (0, csprng_1.secureOtRandom)(), tamper) {
|
|
284
|
+
const count = choices.length;
|
|
285
|
+
// --- Sender setup: S = y·B, T = y·S, and a Schnorr proof of knowledge of y. ---
|
|
286
|
+
const y = rng.scalar();
|
|
287
|
+
const S0 = (0, ec_1.mulBase)(y);
|
|
288
|
+
const Tpt = (0, ec_1.mul)(y, S0); // T = y·S = y²·B
|
|
289
|
+
const proof0 = (0, ec_1.schnorrProve)(y, S0, () => rng.scalar());
|
|
290
|
+
// What actually goes on the wire (a malicious sender may tamper either).
|
|
291
|
+
const S = tamper?.tamperS ? tamper.tamperS(S0) : S0;
|
|
292
|
+
const proof = tamper?.tamperProof ? tamper.tamperProof(proof0) : proof0;
|
|
293
|
+
// --- Receiver: validate the sender's point + proof BEFORE forming any R (malicious-sender guard). ---
|
|
294
|
+
(0, ec_1.assertInSubgroup)(S, 'base-OT S (received by receiver)');
|
|
295
|
+
if (!(0, ec_1.schnorrVerify)(S, proof)) {
|
|
296
|
+
throw new BaseOtAbort('base OT: sender Schnorr proof-of-knowledge of S=y·B failed; aborting');
|
|
297
|
+
}
|
|
298
|
+
// --- Receiver: choose x_i, form R_i = x_i·B (+ S if c_i=1), derive recvPad_i = H(x_i·S). ---
|
|
299
|
+
const R = [];
|
|
300
|
+
const recvPads = [];
|
|
301
|
+
for (let i = 0; i < count; i++) {
|
|
302
|
+
const x = rng.scalar();
|
|
303
|
+
const ci = choices[i] & 1;
|
|
304
|
+
const Ri = ci === 1 ? (0, ec_1.add)((0, ec_1.mulBase)(x), S) : (0, ec_1.mulBase)(x);
|
|
305
|
+
R.push(Ri);
|
|
306
|
+
recvPads.push(kdfPoint(i, (0, ec_1.mul)(x, S)));
|
|
307
|
+
}
|
|
308
|
+
// A malicious receiver may tamper the R it sends on the wire (test-injected).
|
|
309
|
+
if (tamper?.tamperR)
|
|
310
|
+
tamper.tamperR(R);
|
|
311
|
+
// --- Sender: validate every received R_i (malicious-receiver / small-subgroup guard), then derive pads. ---
|
|
312
|
+
const senderPads = [];
|
|
313
|
+
for (let i = 0; i < count; i++) {
|
|
314
|
+
(0, ec_1.assertInSubgroup)(R[i], `base-OT R_${i} (received by sender)`);
|
|
315
|
+
const yR = (0, ec_1.mul)(y, R[i]);
|
|
316
|
+
senderPads.push([kdfPoint(i, yR), kdfPoint(i, (0, ec_1.sub)(yR, Tpt))]);
|
|
317
|
+
}
|
|
318
|
+
return { S, proof, R, senderPads, recvPads };
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Run `count` MALICIOUS-secure base OTs in one batch (chosen-message, over the random OT above).
|
|
322
|
+
* `messages[i] = [m0, m1]` (SEED_BYTES each), the sender's pair; `choices[i] ∈ {0,1}` the receiver's
|
|
323
|
+
* choice. The sender one-time-pads each message under the random-OT pads and commits to each message;
|
|
324
|
+
* the receiver recovers `m_{i,c_i}` and checks the commitment, aborting (`BaseOtAbort`) on any
|
|
325
|
+
* inconsistency. Returns the receiver's recovered messages and the full transcript.
|
|
326
|
+
*/
|
|
327
|
+
function baseOT(messages, choices, rng = (0, csprng_1.secureOtRandom)(), tamper) {
|
|
328
|
+
if (messages.length !== choices.length)
|
|
329
|
+
throw new Error('baseOT: messages/choices length mismatch');
|
|
330
|
+
const count = messages.length;
|
|
331
|
+
const ro = malBaseRandomOT(choices, rng, tamper);
|
|
332
|
+
// Sender: E_{i,b} = m_{i,b} ⊕ pad_{i,b}, and commit com_{i,b} = H(i ‖ b ‖ m_{i,b} ‖ pad_{i,b}).
|
|
333
|
+
const ct = [];
|
|
334
|
+
const com = [];
|
|
335
|
+
for (let i = 0; i < count; i++) {
|
|
336
|
+
const [p0, p1] = ro.senderPads[i];
|
|
337
|
+
ct.push([xorBytes(messages[i][0], p0), xorBytes(messages[i][1], p1)]);
|
|
338
|
+
com.push([otCommit(i, 0, messages[i][0], p0), otCommit(i, 1, messages[i][1], p1)]);
|
|
339
|
+
}
|
|
340
|
+
// A malicious sender may corrupt the ciphertexts on the wire (inconsistent with the commitment).
|
|
341
|
+
if (tamper?.tamperCiphertext)
|
|
342
|
+
tamper.tamperCiphertext(ct);
|
|
343
|
+
// Receiver: decrypt the chosen ciphertext with its pad, then CHECK the commitment it can open.
|
|
344
|
+
const received = [];
|
|
345
|
+
for (let i = 0; i < count; i++) {
|
|
346
|
+
const ci = choices[i] & 1;
|
|
347
|
+
const m = xorBytes(ct[i][ci], ro.recvPads[i]);
|
|
348
|
+
const check = otCommit(i, ci, m, ro.recvPads[i]);
|
|
349
|
+
if (!ctEqual(check, com[i][ci])) {
|
|
350
|
+
throw new BaseOtAbort(`base OT (index ${i}): sender ciphertext inconsistent with its commitment; aborting`);
|
|
351
|
+
}
|
|
352
|
+
received.push(m);
|
|
353
|
+
}
|
|
354
|
+
return { received, transcript: { S: ro.S, proof: ro.proof, R: ro.R, ct, com } };
|
|
355
|
+
}
|
|
356
|
+
// --------------------------------------------------------------------------------------------------
|
|
357
|
+
// OT extension — IKNP (semi-honest), as a stateful in-process channel for one (receiver, sender) pair.
|
|
358
|
+
// --------------------------------------------------------------------------------------------------
|
|
359
|
+
/**
|
|
360
|
+
* An IKNP OT-extension channel between a fixed RECEIVER (choice bits) and SENDER (message pairs). The
|
|
361
|
+
* κ base OTs run lazily on the first `extend`; each later `extend(m)` is a cheap PRG+hash round. The
|
|
362
|
+
* channel is stateful (advances per-seed PRG counters) so many rounds compose into one amortized setup.
|
|
363
|
+
*/
|
|
364
|
+
class OtChannel {
|
|
365
|
+
rng;
|
|
366
|
+
/** Optional post-quantum (or otherwise custom) base OT for the κ setup OTs; defaults to EC `baseOT`. */
|
|
367
|
+
baseOtFn;
|
|
368
|
+
ready = false;
|
|
369
|
+
// Extension-sender state: selector s (κ bits) and the κ seeds it learned (k_i^{s_i}).
|
|
370
|
+
s = [];
|
|
371
|
+
sBits = 0n; // s packed as a κ-bit bigint (cached)
|
|
372
|
+
senderSeeds = [];
|
|
373
|
+
senderBlk = [];
|
|
374
|
+
// Extension-receiver state: κ seed pairs.
|
|
375
|
+
recvSeed0 = [];
|
|
376
|
+
recvSeed1 = [];
|
|
377
|
+
recvBlk0 = [];
|
|
378
|
+
recvBlk1 = [];
|
|
379
|
+
/** The base-OT transcript (available after setup) — exposed for inspection/tests. */
|
|
380
|
+
baseTranscript;
|
|
381
|
+
/**
|
|
382
|
+
* TEST-ONLY injection modelling a MALICIOUS extension RECEIVER: if set, it is called with the honest
|
|
383
|
+
* `u` matrix (κ columns, each `mExt` bits) just before it goes "on the wire", and may mutate it (e.g.
|
|
384
|
+
* XOR a delta into one or more columns) to encode inconsistent choices. The KOS check is computed
|
|
385
|
+
* over the tampered `u` (what the sender sees) while the receiver's revealed `(x, t)` stay honest, so
|
|
386
|
+
* a non-trivial tamper is caught — the real malicious-receiver attack that KOS defeats.
|
|
387
|
+
*/
|
|
388
|
+
tamperU;
|
|
389
|
+
round = 0;
|
|
390
|
+
/**
|
|
391
|
+
* `rng` defaults to the CSPRNG (`secureOtRandom`, `node:crypto`) — production randomness. Pass a
|
|
392
|
+
* deterministic `otRandom(splitMix64(seed))` ONLY to make a test bit-reproducible (docs §7.1 item c).
|
|
393
|
+
*/
|
|
394
|
+
constructor(rng = (0, csprng_1.secureOtRandom)(), opts) {
|
|
395
|
+
this.rng = rng;
|
|
396
|
+
this.baseOtFn = opts?.baseOtFn;
|
|
397
|
+
}
|
|
398
|
+
setup() {
|
|
399
|
+
// Extension-RECEIVER is the base-SENDER: it generates κ seed pairs.
|
|
400
|
+
const messages = [];
|
|
401
|
+
for (let i = 0; i < exports.KAPPA; i++) {
|
|
402
|
+
const k0 = this.rng.bytes(SEED_BYTES);
|
|
403
|
+
const k1 = this.rng.bytes(SEED_BYTES);
|
|
404
|
+
this.recvSeed0.push(k0);
|
|
405
|
+
this.recvSeed1.push(k1);
|
|
406
|
+
this.recvBlk0.push(0);
|
|
407
|
+
this.recvBlk1.push(0);
|
|
408
|
+
messages.push([k0, k1]);
|
|
409
|
+
}
|
|
410
|
+
// Extension-SENDER is the base-RECEIVER with selector s: it learns k_i^{s_i}.
|
|
411
|
+
this.s = Array.from({ length: exports.KAPPA }, () => {
|
|
412
|
+
const b = this.rng.bytes(1);
|
|
413
|
+
return b[0] & 1;
|
|
414
|
+
});
|
|
415
|
+
if (this.baseOtFn) {
|
|
416
|
+
// Custom (e.g. post-quantum ML-KEM) base OT: its transcript shape differs, so leave the
|
|
417
|
+
// EC-typed `baseTranscript` unset.
|
|
418
|
+
this.senderSeeds = this.baseOtFn(messages, this.s, this.rng).received;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
const base = baseOT(messages, this.s, this.rng);
|
|
422
|
+
this.senderSeeds = base.received;
|
|
423
|
+
this.baseTranscript = base.transcript;
|
|
424
|
+
}
|
|
425
|
+
this.senderBlk = new Array(exports.KAPPA).fill(0);
|
|
426
|
+
let acc = 0n;
|
|
427
|
+
for (let i = 0; i < exports.KAPPA; i++)
|
|
428
|
+
acc |= BigInt(this.s[i]) << BigInt(i);
|
|
429
|
+
this.sBits = acc;
|
|
430
|
+
this.ready = true;
|
|
431
|
+
}
|
|
432
|
+
/** Selector s as a κ-bit bigint (sender-side secret; exposed only for tests). */
|
|
433
|
+
get selector() {
|
|
434
|
+
if (!this.ready)
|
|
435
|
+
this.setup();
|
|
436
|
+
return this.sBits;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* One MALICIOUS-secure extension round: `choiceBits[j] ∈ {0,1}` (receiver), `msg0[j]/msg1[j]`
|
|
440
|
+
* field-element messages (sender). Returns the receiver's chosen messages `msg_{choiceBits[j]}[j]`
|
|
441
|
+
* for the `m` real rows. The round transparently appends `κ + SSEC` random check-OT rows and runs the
|
|
442
|
+
* **KOS correlation check** over all `m + κ + SSEC` rows; a cheating receiver (tampered `u`) is caught
|
|
443
|
+
* there and the round throws `MalOtAbort`. `uMatrix` (the receiver→sender wire message, now
|
|
444
|
+
* `mExt`-bit) is returned for tests.
|
|
445
|
+
*/
|
|
446
|
+
extend(choiceBits, msg0, msg1) {
|
|
447
|
+
if (!this.ready)
|
|
448
|
+
this.setup();
|
|
449
|
+
const m = choiceBits.length;
|
|
450
|
+
if (msg0.length !== m || msg1.length !== m)
|
|
451
|
+
throw new Error('OtChannel.extend: length mismatch');
|
|
452
|
+
if (m === 0)
|
|
453
|
+
return { received: [], uMatrix: [] };
|
|
454
|
+
const roundIdx = this.round++;
|
|
455
|
+
// --- KOS padding: append κ+SSEC random check-OT rows (no messages are transferred for them). ---
|
|
456
|
+
const pad = exports.KAPPA + exports.SSEC;
|
|
457
|
+
const mExt = m + pad;
|
|
458
|
+
const padChoice = new Array(pad);
|
|
459
|
+
for (let p = 0; p < pad; p++)
|
|
460
|
+
padChoice[p] = this.rng.bytes(1)[0] & 1;
|
|
461
|
+
// Full choice vector (real ‖ padding) as an mExt-bit bigint, and a per-row accessor for the check.
|
|
462
|
+
let bvec = 0n;
|
|
463
|
+
for (let j = 0; j < m; j++)
|
|
464
|
+
if (choiceBits[j] & 1)
|
|
465
|
+
bvec |= 1n << BigInt(j);
|
|
466
|
+
for (let p = 0; p < pad; p++)
|
|
467
|
+
if (padChoice[p] & 1)
|
|
468
|
+
bvec |= 1n << BigInt(m + p);
|
|
469
|
+
const blocks = Math.ceil(mExt / 256);
|
|
470
|
+
// Receiver forms t_i, u_i = PRG(k1) ⊕ t_i ⊕ bvec (over all mExt rows).
|
|
471
|
+
const t = new Array(exports.KAPPA);
|
|
472
|
+
const u = new Array(exports.KAPPA);
|
|
473
|
+
for (let i = 0; i < exports.KAPPA; i++) {
|
|
474
|
+
const ti = prgBits(this.recvSeed0[i], this.recvBlk0[i], mExt);
|
|
475
|
+
const gi = prgBits(this.recvSeed1[i], this.recvBlk1[i], mExt);
|
|
476
|
+
this.recvBlk0[i] += blocks;
|
|
477
|
+
this.recvBlk1[i] += blocks;
|
|
478
|
+
t[i] = ti;
|
|
479
|
+
u[i] = gi ^ ti ^ bvec;
|
|
480
|
+
}
|
|
481
|
+
// A malicious receiver may tamper the u it sends on the wire (test-injected).
|
|
482
|
+
if (this.tamperU)
|
|
483
|
+
this.tamperU(u, roundIdx);
|
|
484
|
+
// Sender computes q_i = (s_i ? u_i : 0) ⊕ PRG(k_i^{s_i}). => q_i = t_i ⊕ (s_i · bvec) if honest.
|
|
485
|
+
const q = new Array(exports.KAPPA);
|
|
486
|
+
for (let i = 0; i < exports.KAPPA; i++) {
|
|
487
|
+
const ks = prgBits(this.senderSeeds[i], this.senderBlk[i], mExt);
|
|
488
|
+
this.senderBlk[i] += blocks;
|
|
489
|
+
q[i] = (this.s[i] === 1 ? u[i] : 0n) ^ ks;
|
|
490
|
+
}
|
|
491
|
+
const sBits = this.sBits;
|
|
492
|
+
// --- KOS correlation check (GF(2^128), column-domain fold over all mExt rows). ---
|
|
493
|
+
// χ_j bound to the (possibly tampered) u on the wire. Receiver reveals x = Σ b_j·χ_j and
|
|
494
|
+
// t_comb = Σ χ_j·t_j; sender checks Σ χ_j·q_j == t_comb ⊕ x·s. Honestly q_j = t_j ⊕ b_j·s so it
|
|
495
|
+
// holds; a receiver who tampered u passes with prob ≤ 2^{-128}, else ABORT.
|
|
496
|
+
const chi = kosChallenges(u, mExt);
|
|
497
|
+
// x = Σ_{j: b_j=1} χ_j (receiver side; over real + padding choices, so real choices stay masked).
|
|
498
|
+
let x = 0n;
|
|
499
|
+
x = accumSetBits(bvec, chi, x);
|
|
500
|
+
// t_comb = Σ_i (Σ_{j: t_i has bit j} χ_j)·x^i ; q_comb likewise from q_i.
|
|
501
|
+
let tComb = 0n;
|
|
502
|
+
let qComb = 0n;
|
|
503
|
+
for (let i = 0; i < exports.KAPPA; i++) {
|
|
504
|
+
const at = accumSetBits(t[i], chi, 0n);
|
|
505
|
+
const aq = accumSetBits(q[i], chi, 0n);
|
|
506
|
+
tComb = (0, gf128_1.gf128Add)(tComb, (0, gf128_1.gf128MulByXi)(at, i));
|
|
507
|
+
qComb = (0, gf128_1.gf128Add)(qComb, (0, gf128_1.gf128MulByXi)(aq, i));
|
|
508
|
+
}
|
|
509
|
+
const expected = (0, gf128_1.gf128Add)(tComb, (0, gf128_1.gf128Mul)(x, sBits));
|
|
510
|
+
if (qComb !== expected) {
|
|
511
|
+
throw new MalOtAbort(`KOS correlation check FAILED (round ${roundIdx}): a cheating OT-extension receiver was detected; aborting`);
|
|
512
|
+
}
|
|
513
|
+
// --- Only the m real rows carry messages. Sender: y0_j = msg0_j ⊕ H(j,qrow_j), y1 ⊕ H(j,qrow⊕s). ---
|
|
514
|
+
const y0 = new Array(m);
|
|
515
|
+
const y1 = new Array(m);
|
|
516
|
+
for (let j = 0; j < m; j++) {
|
|
517
|
+
let qrow = 0n;
|
|
518
|
+
for (let i = 0; i < exports.KAPPA; i++)
|
|
519
|
+
qrow |= ((q[i] >> BigInt(j)) & 1n) << BigInt(i);
|
|
520
|
+
y0[j] = msg0[j] ^ crh(j, qrow);
|
|
521
|
+
y1[j] = msg1[j] ^ crh(j, qrow ^ sBits);
|
|
522
|
+
}
|
|
523
|
+
// Receiver: recovered_j = y_{b_j}[j] ⊕ H(j, trow_j).
|
|
524
|
+
const received = new Array(m);
|
|
525
|
+
for (let j = 0; j < m; j++) {
|
|
526
|
+
let trow = 0n;
|
|
527
|
+
for (let i = 0; i < exports.KAPPA; i++)
|
|
528
|
+
trow |= ((t[i] >> BigInt(j)) & 1n) << BigInt(i);
|
|
529
|
+
const bj = choiceBits[j] & 1;
|
|
530
|
+
received[j] = (bj === 1 ? y1[j] : y0[j]) ^ crh(j, trow);
|
|
531
|
+
}
|
|
532
|
+
return { received, uMatrix: u };
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
exports.OtChannel = OtChannel;
|
|
536
|
+
//# sourceMappingURL=ot.js.map
|
package/dist/ot.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ot.js","sourceRoot":"","sources":["../src/ot.ts"],"names":[],"mappings":"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"}
|
package/dist/party.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-stakeholder local evaluation. Each party (user, org, regulator, ...) runs ITS OWN Policy VM
|
|
3
|
+
* locally and distills the result to a tiny DECISION VECTOR — the only thing that enters the MPC.
|
|
4
|
+
* The party's policy (its envelope, risk weights, predicates, budget) never leaves its process.
|
|
5
|
+
*
|
|
6
|
+
* We reuse `@atlasauth/pca`'s `decide()` as the per-party Policy VM (read-only; we import it, we do
|
|
7
|
+
* not modify it). The three fields we extract are exactly the ones with a well-defined composition:
|
|
8
|
+
* - allow = `releaseGuardianShare` (this party admits the action at all)
|
|
9
|
+
* - t = `requiredThreshold.t` (the proof strength this party demands: 1|2|3)
|
|
10
|
+
* - rQuant = quantize(`r`) (this party's risk score, quantized to {0..Q})
|
|
11
|
+
*/
|
|
12
|
+
import { type DecideInput } from '@atlasauth/pca';
|
|
13
|
+
/** Granularity of the r-quantization. r in [0,1] maps to an integer bucket in {0..Q}. */
|
|
14
|
+
export declare const DEFAULT_Q = 100;
|
|
15
|
+
/** A stakeholder and its PRIVATE Policy-VM input (never shared with other parties). */
|
|
16
|
+
export interface PartyPolicy {
|
|
17
|
+
/** Human-readable id (e.g. "user", "org", "regulator"); for labelling only. */
|
|
18
|
+
id: string;
|
|
19
|
+
/** The party's own `@atlasauth/pca` decision input: its envelope, risk inputs, budget, etc. */
|
|
20
|
+
decideInput: DecideInput;
|
|
21
|
+
}
|
|
22
|
+
/** The small, composable decision a party contributes to the MPC. */
|
|
23
|
+
export interface DecisionVector {
|
|
24
|
+
/** 1 = this party admits the action; 0 = this party denies. */
|
|
25
|
+
allow: 0 | 1;
|
|
26
|
+
/** Proof-strength threshold this party requires. */
|
|
27
|
+
t: 1 | 2 | 3;
|
|
28
|
+
/** Risk score quantized to {0..Q}. */
|
|
29
|
+
rQuant: number;
|
|
30
|
+
}
|
|
31
|
+
/** Quantize r in [0,1] to an integer in {0..Q}. Non-finite => worst case (Q). */
|
|
32
|
+
export declare function quantizeR(r: number, Q?: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Evaluate a party's own policy to its decision vector, reusing the PCA Policy VM. Pure: `decide` is
|
|
35
|
+
* total and never throws, so this never throws. The returned vector is the party's PRIVATE input to
|
|
36
|
+
* the composition.
|
|
37
|
+
*/
|
|
38
|
+
export declare function evaluateParty(policy: PartyPolicy, Q?: number): DecisionVector;
|
package/dist/party.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Per-stakeholder local evaluation. Each party (user, org, regulator, ...) runs ITS OWN Policy VM
|
|
4
|
+
* locally and distills the result to a tiny DECISION VECTOR — the only thing that enters the MPC.
|
|
5
|
+
* The party's policy (its envelope, risk weights, predicates, budget) never leaves its process.
|
|
6
|
+
*
|
|
7
|
+
* We reuse `@atlasauth/pca`'s `decide()` as the per-party Policy VM (read-only; we import it, we do
|
|
8
|
+
* not modify it). The three fields we extract are exactly the ones with a well-defined composition:
|
|
9
|
+
* - allow = `releaseGuardianShare` (this party admits the action at all)
|
|
10
|
+
* - t = `requiredThreshold.t` (the proof strength this party demands: 1|2|3)
|
|
11
|
+
* - rQuant = quantize(`r`) (this party's risk score, quantized to {0..Q})
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.DEFAULT_Q = void 0;
|
|
15
|
+
exports.quantizeR = quantizeR;
|
|
16
|
+
exports.evaluateParty = evaluateParty;
|
|
17
|
+
const pca_1 = require("@atlasauth/pca");
|
|
18
|
+
/** Granularity of the r-quantization. r in [0,1] maps to an integer bucket in {0..Q}. */
|
|
19
|
+
exports.DEFAULT_Q = 100;
|
|
20
|
+
/** Quantize r in [0,1] to an integer in {0..Q}. Non-finite => worst case (Q). */
|
|
21
|
+
function quantizeR(r, Q = exports.DEFAULT_Q) {
|
|
22
|
+
if (!Number.isFinite(r))
|
|
23
|
+
return Q;
|
|
24
|
+
const q = Math.round(Math.max(0, Math.min(1, r)) * Q);
|
|
25
|
+
return Math.max(0, Math.min(Q, q));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Evaluate a party's own policy to its decision vector, reusing the PCA Policy VM. Pure: `decide` is
|
|
29
|
+
* total and never throws, so this never throws. The returned vector is the party's PRIVATE input to
|
|
30
|
+
* the composition.
|
|
31
|
+
*/
|
|
32
|
+
function evaluateParty(policy, Q = exports.DEFAULT_Q) {
|
|
33
|
+
const d = (0, pca_1.decide)(policy.decideInput);
|
|
34
|
+
return {
|
|
35
|
+
allow: d.releaseGuardianShare ? 1 : 0,
|
|
36
|
+
t: d.requiredThreshold.t,
|
|
37
|
+
rQuant: quantizeR(d.r, Q),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=party.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"party.js","sourceRoot":"","sources":["../src/party.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AA0BH,8BAIC;AAOD,sCAOC;AA1CD,wCAA0D;AAE1D,yFAAyF;AAC5E,QAAA,SAAS,GAAG,GAAG,CAAC;AAoB7B,iFAAiF;AACjF,SAAgB,SAAS,CAAC,CAAS,EAAE,IAAY,iBAAS;IACxD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAC,MAAmB,EAAE,IAAY,iBAAS;IACtE,MAAM,CAAC,GAAG,IAAA,YAAM,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACrC,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACxB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC1B,CAAC;AACJ,CAAC"}
|