@atlasauth/pca-mpc 0.2.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 +81 -3
- package/dist/beaver.js +4 -0
- package/dist/beaver.js.map +1 -1
- package/dist/compose.d.ts +9 -2
- package/dist/compose.js +24 -1
- package/dist/compose.js.map +1 -1
- package/dist/ec.d.ts +6 -3
- package/dist/ec.js +27 -9
- package/dist/ec.js.map +1 -1
- package/dist/enc.d.ts +46 -0
- package/dist/enc.js +88 -0
- package/dist/enc.js.map +1 -0
- package/dist/endemic-ot.js +24 -1
- package/dist/endemic-ot.js.map +1 -1
- package/dist/hybrid-ot.js +3 -0
- package/dist/hybrid-ot.js.map +1 -1
- package/dist/kem-ot.js +2 -0
- package/dist/kem-ot.js.map +1 -1
- package/dist/mascot.d.ts +81 -30
- package/dist/mascot.js +232 -113
- package/dist/mascot.js.map +1 -1
- package/dist/net/certs.d.ts +14 -0
- package/dist/net/certs.js +30 -0
- package/dist/net/certs.js.map +1 -0
- package/dist/net/faults.d.ts +49 -0
- package/dist/net/faults.js +222 -0
- package/dist/net/faults.js.map +1 -0
- package/dist/net/forensics.d.ts +81 -0
- package/dist/net/forensics.js +181 -0
- package/dist/net/forensics.js.map +1 -0
- package/dist/net/gadget.d.ts +44 -0
- package/dist/net/gadget.js +102 -0
- package/dist/net/gadget.js.map +1 -0
- package/dist/net/index.d.ts +11 -0
- package/dist/net/index.js +28 -0
- package/dist/net/index.js.map +1 -0
- package/dist/net/launch-local.d.ts +53 -0
- package/dist/net/launch-local.js +190 -0
- package/dist/net/launch-local.js.map +1 -0
- package/dist/net/launch-support.d.ts +6 -0
- package/dist/net/launch-support.js +65 -0
- package/dist/net/launch-support.js.map +1 -0
- package/dist/net/mesh.d.ts +135 -0
- package/dist/net/mesh.js +491 -0
- package/dist/net/mesh.js.map +1 -0
- package/dist/net/offline-net.d.ts +58 -0
- package/dist/net/offline-net.js +485 -0
- package/dist/net/offline-net.js.map +1 -0
- package/dist/net/ot-net.d.ts +42 -0
- package/dist/net/ot-net.js +219 -0
- package/dist/net/ot-net.js.map +1 -0
- package/dist/net/pa.d.ts +65 -0
- package/dist/net/pa.js +118 -0
- package/dist/net/pa.js.map +1 -0
- package/dist/net/party-main.d.ts +48 -0
- package/dist/net/party-main.js +146 -0
- package/dist/net/party-main.js.map +1 -0
- package/dist/net/prep.d.ts +40 -0
- package/dist/net/prep.js +12 -0
- package/dist/net/prep.js.map +1 -0
- package/dist/net/protocol.d.ts +126 -0
- package/dist/net/protocol.js +655 -0
- package/dist/net/protocol.js.map +1 -0
- package/dist/net/wire.d.ts +89 -0
- package/dist/net/wire.js +242 -0
- package/dist/net/wire.js.map +1 -0
- package/dist/ot.d.ts +176 -17
- package/dist/ot.js +479 -252
- package/dist/ot.js.map +1 -1
- package/dist/otx.d.ts +76 -0
- package/dist/otx.js +238 -0
- package/dist/otx.js.map +1 -0
- package/dist/runner.d.ts +1 -1
- package/dist/runner.js +6 -1
- package/dist/runner.js.map +1 -1
- package/dist/sharing.d.ts +2 -0
- package/dist/sharing.js +7 -4
- package/dist/sharing.js.map +1 -1
- package/dist/spdz-runner.d.ts +20 -3
- package/dist/spdz-runner.js +21 -3
- package/dist/spdz-runner.js.map +1 -1
- package/dist/spdz.d.ts +96 -22
- package/dist/spdz.js +196 -47
- package/dist/spdz.js.map +1 -1
- package/package.json +15 -6
package/dist/ot.d.ts
CHANGED
|
@@ -47,7 +47,14 @@
|
|
|
47
47
|
* random weights `χ_j ∈ GF(2^κ)` (one per row, bound to `u` by a Fiat–Shamir hash here), the
|
|
48
48
|
* receiver reveals `x = Σ_j b_j·χ_j` and `t = Σ_j χ_j·t_j`, and the sender checks
|
|
49
49
|
* `Σ_j χ_j·q_j == t ⊕ x·s` in GF(2^κ). Honestly this always holds (`q_j = t_j ⊕ b_j·s`); a receiver
|
|
50
|
-
* who deviated in `u`
|
|
50
|
+
* who deviated in `u` is caught, so a deviation ABORTS. The honest statement of the bound is the KOS
|
|
51
|
+
* STATISTICAL parameter `s = SSEC = 128`, NOT `2^{-κ}`: a receiver that deviates in a few columns passes by
|
|
52
|
+
* guessing the matching bits of the selector `s`, and the 2015 proof (ePrint 2015/546) was additionally shown
|
|
53
|
+
* to rest on an incorrect lemma (Roy, CRYPTO 2022). Roy's attacks give the receiver success
|
|
54
|
+
* about `2^{-s}` with `s` extra rows, and the KOS proof is still open (Roy leaves a sound proof to future work), so
|
|
55
|
+
* this module sets `s = SSEC = 128` extra rows (was 64): the best KNOWN attack then succeeds with probability about
|
|
56
|
+
* `2^{-128}`. That is an argument from the attack analysis, NOT a proof; we did not implement SoftSpokenOT's own
|
|
57
|
+
* (different, small-field VOLE) consistency check, whose parameters we could not verify from the paper.
|
|
51
58
|
* The check is run over `m + κ + SSEC` rows — the extra `κ + SSEC` random "sacrifice" OT rows mask
|
|
52
59
|
* the revealed combination (receiver privacy) and give statistical soundness. This makes the OT
|
|
53
60
|
* extension **malicious-secure**, not just semi-honest.
|
|
@@ -64,9 +71,12 @@ export declare const KAPPA = 128;
|
|
|
64
71
|
/**
|
|
65
72
|
* KOS statistical-security parameter: the number of EXTRA random check-OT rows (beyond the `κ` that
|
|
66
73
|
* mask the revealed combination) appended to every extension round. Together `κ + SSEC` padding rows
|
|
67
|
-
* give the correlation check its receiver-privacy and statistical soundness margin.
|
|
74
|
+
* give the correlation check its receiver-privacy and statistical soundness margin. Roy (CRYPTO 2022, ePrint
|
|
75
|
+
* 2022/192) shows the KOS proof is flawed and that the attacks succeed with probability about 2^-s for `s` extra
|
|
76
|
+
* rows; `s = 128` (raised from 64, a WIRE CHANGE: the matrix has 64 more rows per round) makes the best known attack
|
|
77
|
+
* about 2^-128. Not a proof.
|
|
68
78
|
*/
|
|
69
|
-
export declare const SSEC =
|
|
79
|
+
export declare const SSEC = 128;
|
|
70
80
|
/** Raised when the KOS correlation check fails: a cheating OT-extension receiver is detected → ABORT. */
|
|
71
81
|
export declare class MalOtAbort extends Error {
|
|
72
82
|
constructor(message: string);
|
|
@@ -82,6 +92,47 @@ export interface OtRandom {
|
|
|
82
92
|
export declare function splitMix64(seed: bigint): () => bigint;
|
|
83
93
|
/** Build an OtRandom from a SplitMix64-style 64-bit stream (deterministic; CSPRNG in production). */
|
|
84
94
|
export declare function otRandom(next64: () => bigint): OtRandom;
|
|
95
|
+
/**
|
|
96
|
+
* Session binding of one base OT: who runs it, in which session and round. It is folded into the sender's
|
|
97
|
+
* Schnorr challenge AND into every pad, so neither a proof nor a pad carries over to another session,
|
|
98
|
+
* party pair or round. `senderIndex` is the base-OT SENDER (the party that publishes S).
|
|
99
|
+
*/
|
|
100
|
+
export interface BaseOtBinding {
|
|
101
|
+
/** 8..64 bytes, unique per session (the network runner uses its session id). */
|
|
102
|
+
sessionId: Uint8Array;
|
|
103
|
+
senderIndex: number;
|
|
104
|
+
receiverIndex: number;
|
|
105
|
+
/** Non-empty label of the protocol round / use, at most 64 bytes. */
|
|
106
|
+
round: string;
|
|
107
|
+
}
|
|
108
|
+
/** Canonical, length-prefixed encoding of a binding (the Schnorr context and part of every KDF input). */
|
|
109
|
+
export declare function bindingBytes(b: BaseOtBinding): Uint8Array;
|
|
110
|
+
/** A fresh binding for an in-process OT (both roles simulated): random session id from `rng`. */
|
|
111
|
+
export declare function randomBinding(rng: OtRandom, round: string, senderIndex?: number, receiverIndex?: number): BaseOtBinding;
|
|
112
|
+
/**
|
|
113
|
+
* Hash of the WHOLE base-OT transcript: binding, the sender's S and every receiver point R_i, in order.
|
|
114
|
+
* Every pad is derived under this hash, so changing the session, S or ANY R_j changes EVERY key.
|
|
115
|
+
*/
|
|
116
|
+
export declare function baseOtTranscriptHash(binding: BaseOtBinding, S: Point, R: readonly Point[]): Uint8Array;
|
|
117
|
+
/**
|
|
118
|
+
* Key derivation from a group point, Chou–Orlandi / Simplest-OT style but over the full transcript:
|
|
119
|
+
* `H("ot-kdf" ‖ H(transcript) ‖ index ‖ R_i ‖ P)` → SEED_BYTES bytes.
|
|
120
|
+
*/
|
|
121
|
+
export declare function baseOtKdf(transcriptHash: Uint8Array, index: number, Ri: Point, p: Point): Uint8Array;
|
|
122
|
+
/**
|
|
123
|
+
* Derive the KOS row-weights χ_j ∈ GF(2^128) for one extension round (Fiat–Shamir). The sender and
|
|
124
|
+
* receiver both derive the SAME χ from the FULL `u` matrix on the wire, so a cheating receiver cannot
|
|
125
|
+
* pick `u` after seeing χ. In the real protocol χ comes from a secure coin-flip after the receiver
|
|
126
|
+
* commits to `u`; the transcript hash here models that round.
|
|
127
|
+
*
|
|
128
|
+
* The weights are the output of SHAKE256 (an extendable-output function, `node:crypto`) over
|
|
129
|
+
* `TAG ‖ channel binding ‖ round ‖ mExt ‖ every bit of every column of u`, 16 bytes per row — a vetted
|
|
130
|
+
* XOF seeded by the whole transcript, not a fast non-cryptographic stream. (An earlier version expanded a
|
|
131
|
+
* 128-bit digest with SplitMix64, and hashed only the low 128 bits of each column; both are gone.)
|
|
132
|
+
*/
|
|
133
|
+
export declare function kosChallenges(binding: Uint8Array, round: number, u: bigint[], mExt: number): bigint[];
|
|
134
|
+
/** The same weights as little-endian u32 words (4 per row), the form the typed kernels consume. */
|
|
135
|
+
export declare function kosChiWords(binding: Uint8Array, round: number, u: bigint[], mExt: number, colBytesList?: Uint8Array[]): Uint32Array;
|
|
85
136
|
/** Raised when a base OT aborts: a cheating sender (bad proof / inconsistent ciphertext) is detected. */
|
|
86
137
|
export declare class BaseOtAbort extends Error {
|
|
87
138
|
constructor(message: string);
|
|
@@ -149,7 +200,36 @@ export interface MalRandomOtResult {
|
|
|
149
200
|
* No messages are transferred — the pads ARE the random output. `tamper` injects malicious behaviour
|
|
150
201
|
* for tests. Both parties are simulated in-process.
|
|
151
202
|
*/
|
|
152
|
-
export declare function malBaseRandomOT(choices: number[], rng?: OtRandom, tamper?: BaseOtTamper): MalRandomOtResult;
|
|
203
|
+
export declare function malBaseRandomOT(choices: number[], rng?: OtRandom, tamper?: BaseOtTamper, binding?: BaseOtBinding): MalRandomOtResult;
|
|
204
|
+
/** SENDER step 1: S = y·B, T = y·S, and a Schnorr proof of knowledge of y. `y`/`T` stay sender-local. */
|
|
205
|
+
export declare function malBaseOtSenderSetup(rng: OtRandom, binding: BaseOtBinding): {
|
|
206
|
+
y: bigint;
|
|
207
|
+
T: Point;
|
|
208
|
+
S: Point;
|
|
209
|
+
proof: SchnorrProof;
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* RECEIVER step: validate the sender's point + proof BEFORE forming any R (malicious-sender guard), then
|
|
213
|
+
* choose x_i, form R_i = x_i·B (+ S if c_i=1) and derive recvPad_i = H(x_i·S). Throws `BaseOtAbort`/
|
|
214
|
+
* `PointValidationError` on a bad S or proof.
|
|
215
|
+
*/
|
|
216
|
+
export declare function malBaseOtReceiverRespond(S: Point, proof: SchnorrProof, choices: number[], rng: OtRandom, binding: BaseOtBinding): {
|
|
217
|
+
R: Point[];
|
|
218
|
+
recvPads: Uint8Array[];
|
|
219
|
+
};
|
|
220
|
+
/** SENDER step 2: validate every received R_i (malicious-receiver / small-subgroup guard), derive both pads. */
|
|
221
|
+
export declare function malBaseOtSenderDerive(y: bigint, T: Point, R: Point[], S: Point, binding: BaseOtBinding): Array<[Uint8Array, Uint8Array]>;
|
|
222
|
+
/** SENDER step 3 (chosen-message wrapper): one-time-pad each message under its pad and commit to it. */
|
|
223
|
+
export declare function baseOtSenderEncrypt(messages: Array<[Uint8Array, Uint8Array]>, senderPads: Array<[Uint8Array, Uint8Array]>): {
|
|
224
|
+
ct: Array<[Uint8Array, Uint8Array]>;
|
|
225
|
+
com: Array<[Uint8Array, Uint8Array]>;
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* RECEIVER step 3: decrypt the chosen ciphertext with its pad, then CHECK the commitment it can open;
|
|
229
|
+
* `BaseOtAbort` on any inconsistency (a cheating sender). Every ciphertext/commitment must have the shape
|
|
230
|
+
* the receiver expects (equal-length byte strings of at most the pad width).
|
|
231
|
+
*/
|
|
232
|
+
export declare function baseOtReceiverDecrypt(choices: number[], recvPads: Uint8Array[], ct: Array<[Uint8Array, Uint8Array]>, com: Array<[Uint8Array, Uint8Array]>): Uint8Array[];
|
|
153
233
|
/**
|
|
154
234
|
* Run `count` MALICIOUS-secure base OTs in one batch (chosen-message, over the random OT above).
|
|
155
235
|
* `messages[i] = [m0, m1]` (SEED_BYTES each), the sender's pair; `choices[i] ∈ {0,1}` the receiver's
|
|
@@ -157,25 +237,99 @@ export declare function malBaseRandomOT(choices: number[], rng?: OtRandom, tampe
|
|
|
157
237
|
* the receiver recovers `m_{i,c_i}` and checks the commitment, aborting (`BaseOtAbort`) on any
|
|
158
238
|
* inconsistency. Returns the receiver's recovered messages and the full transcript.
|
|
159
239
|
*/
|
|
160
|
-
export declare function baseOT(messages: Array<[Uint8Array, Uint8Array]>, choices: number[], rng?: OtRandom, tamper?: BaseOtTamper): BaseOtResult;
|
|
240
|
+
export declare function baseOT(messages: Array<[Uint8Array, Uint8Array]>, choices: number[], rng?: OtRandom, tamper?: BaseOtTamper, binding?: BaseOtBinding): BaseOtResult;
|
|
241
|
+
/** One extension round's receiver -> sender message: the u matrix and the KOS-revealed (x, t) pair. */
|
|
242
|
+
export interface ExtRoundMsg {
|
|
243
|
+
/** KAPPA columns of `mExt = m + KAPPA + SSEC` bits each. */
|
|
244
|
+
u: bigint[];
|
|
245
|
+
/** x = Σ_j b_j·χ_j in GF(2^128). */
|
|
246
|
+
x: bigint;
|
|
247
|
+
/** t = Σ_i x^i·(Σ_j t_i[j]·χ_j). */
|
|
248
|
+
tComb: bigint;
|
|
249
|
+
}
|
|
250
|
+
/** The receiver's private state between sending `ExtRoundMsg` and receiving the sender's ciphertexts. */
|
|
251
|
+
export interface ExtPending {
|
|
252
|
+
m: number;
|
|
253
|
+
choiceBits: number[];
|
|
254
|
+
/** The receiver's `t` matrix: COLS columns of `W` u32 words, concatenated. */
|
|
255
|
+
t: Uint32Array;
|
|
256
|
+
W: number;
|
|
257
|
+
/** Channel-global index of this round's first row (R4-12 hash tweak). */
|
|
258
|
+
rowOffset: number;
|
|
259
|
+
}
|
|
161
260
|
/**
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
|
|
261
|
+
* The OT-extension RECEIVER (holds the choice bits). In the base OT it is the SENDER: it draws κ seed pairs
|
|
262
|
+
* and offers them; after the base OT it expands them with the PRG.
|
|
263
|
+
*/
|
|
264
|
+
export declare class OtExtReceiver {
|
|
265
|
+
private readonly rng;
|
|
266
|
+
private readonly kosBinding;
|
|
267
|
+
private seed0;
|
|
268
|
+
private seed1;
|
|
269
|
+
private blk0;
|
|
270
|
+
private blk1;
|
|
271
|
+
private round;
|
|
272
|
+
/** Rows hashed in earlier rounds (R4-12 global tweak offset); advanced by m per round, in step with the sender. */
|
|
273
|
+
private rowsDone;
|
|
274
|
+
private readonly tweakDomain;
|
|
275
|
+
ready: boolean;
|
|
276
|
+
/**
|
|
277
|
+
* TEST-ONLY: called with the honest `u` matrix just before it goes on the wire; may mutate it (a malicious
|
|
278
|
+
* receiver encoding inconsistent choices). The KOS values are computed over the tampered `u`.
|
|
279
|
+
*/
|
|
280
|
+
tamperU?: (u: bigint[], round: number) => void;
|
|
281
|
+
constructor(rng: OtRandom, kosBinding: Uint8Array);
|
|
282
|
+
/** Base-OT messages: the κ seed pairs this party offers as the base-OT sender. */
|
|
283
|
+
makeSeeds(): Array<[Uint8Array, Uint8Array]>;
|
|
284
|
+
/** Round start: form u and the KOS pair for `choiceBits` (the real rows); returns the wire message + pending state. */
|
|
285
|
+
begin(choiceBits: number[]): {
|
|
286
|
+
msg: ExtRoundMsg;
|
|
287
|
+
pending: ExtPending;
|
|
288
|
+
};
|
|
289
|
+
/** Round end: recover the chosen messages from the sender's ciphertexts. */
|
|
290
|
+
finish(pending: ExtPending, y0: bigint[], y1: bigint[]): bigint[];
|
|
291
|
+
}
|
|
292
|
+
/** The OT-extension SENDER (holds the message pairs). In the base OT it is the RECEIVER with selector `s`. */
|
|
293
|
+
export declare class OtExtSender {
|
|
294
|
+
private readonly rng;
|
|
295
|
+
private readonly kosBinding;
|
|
296
|
+
private s;
|
|
297
|
+
private sBits;
|
|
298
|
+
private seeds;
|
|
299
|
+
private blk;
|
|
300
|
+
private round;
|
|
301
|
+
private rowsDone;
|
|
302
|
+
private readonly tweakDomain;
|
|
303
|
+
ready: boolean;
|
|
304
|
+
constructor(rng: OtRandom, kosBinding: Uint8Array);
|
|
305
|
+
/** Draw the secret selector s ∈ {0,1}^κ (the base-OT choice bits). */
|
|
306
|
+
makeSelector(): number[];
|
|
307
|
+
/** Install the κ seeds learned from the base OT. */
|
|
308
|
+
setSeeds(seeds: Uint8Array[]): void;
|
|
309
|
+
get selector(): bigint;
|
|
310
|
+
/**
|
|
311
|
+
* Verify the receiver's round message (structure + KOS correlation check) and return the ciphertexts for
|
|
312
|
+
* the `m` real rows. A cheating receiver is caught here: `MalOtAbort`.
|
|
313
|
+
*/
|
|
314
|
+
respond(msg: ExtRoundMsg, msg0: bigint[], msg1: bigint[]): {
|
|
315
|
+
y0: bigint[];
|
|
316
|
+
y1: bigint[];
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* An IKNP/KOS OT-extension channel between a fixed RECEIVER (choice bits) and SENDER (message pairs), both
|
|
321
|
+
* simulated in-process. The κ base OTs run lazily on the first `extend`; each later `extend(m)` is a cheap
|
|
322
|
+
* PRG+hash round. The channel is stateful (advances per-seed PRG counters) so many rounds compose into one
|
|
323
|
+
* amortized setup. The two roles are the standalone `OtExtReceiver` / `OtExtSender` (used over the network).
|
|
165
324
|
*/
|
|
166
325
|
export declare class OtChannel {
|
|
167
326
|
private readonly rng;
|
|
168
327
|
/** Optional post-quantum (or otherwise custom) base OT for the κ setup OTs; defaults to EC `baseOT`. */
|
|
169
328
|
private readonly baseOtFn?;
|
|
329
|
+
private readonly bindingOpt?;
|
|
330
|
+
private recv?;
|
|
331
|
+
private send?;
|
|
170
332
|
private ready;
|
|
171
|
-
private s;
|
|
172
|
-
private sBits;
|
|
173
|
-
private senderSeeds;
|
|
174
|
-
private senderBlk;
|
|
175
|
-
private recvSeed0;
|
|
176
|
-
private recvSeed1;
|
|
177
|
-
private recvBlk0;
|
|
178
|
-
private recvBlk1;
|
|
179
333
|
/** The base-OT transcript (available after setup) — exposed for inspection/tests. */
|
|
180
334
|
baseTranscript?: BaseOtTranscript;
|
|
181
335
|
/**
|
|
@@ -186,13 +340,18 @@ export declare class OtChannel {
|
|
|
186
340
|
* a non-trivial tamper is caught — the real malicious-receiver attack that KOS defeats.
|
|
187
341
|
*/
|
|
188
342
|
tamperU?: (u: bigint[], round: number) => void;
|
|
189
|
-
private round;
|
|
190
343
|
/**
|
|
191
344
|
* `rng` defaults to the CSPRNG (`secureOtRandom`, `node:crypto`) — production randomness. Pass a
|
|
192
345
|
* deterministic `otRandom(splitMix64(seed))` ONLY to make a test bit-reproducible (docs §7.1 item c).
|
|
193
346
|
*/
|
|
194
347
|
constructor(rng?: OtRandom, opts?: {
|
|
195
348
|
baseOtFn?: BaseOtFn;
|
|
349
|
+
/**
|
|
350
|
+
* Session binding of this channel (both parties must agree on it). `senderIndex` is the EXTENSION
|
|
351
|
+
* RECEIVER (it plays base-OT sender), `receiverIndex` the extension sender. Omitted for an in-process
|
|
352
|
+
* channel: a fresh random session id is drawn from `rng`.
|
|
353
|
+
*/
|
|
354
|
+
binding?: Omit<BaseOtBinding, 'round'>;
|
|
196
355
|
});
|
|
197
356
|
private setup;
|
|
198
357
|
/** Selector s as a κ-bit bigint (sender-side secret; exposed only for tests). */
|