mhpow B2: O-17, B4's lottery rule adopted with its fake-winner budget; B4's answers to B-T1 to B-T8
B4 (requirements.md on mhpow-b4a9e933a9a, README 5b on masterb67b89cf8) answered B-T3 in shape: trial id in chi, W = H('W', chi || tau), winners verified in full, spot checks as the pre-filter. B2 adopts it as O-17 and states the budget B4 asked for (B4-OB-LOT-1): the pre-filter does not price a fake winner, which keeps one labelling and re-rolls the red sink, (log2 N + 1)/p calls against 2N/p for a real winner, so an attacker with 1e-6 of the network makes 1.34 fakes per real block at N = 2^24, each costing every validator it reaches a full labelling (figures section 6). B4 5b's sentence that R1's bound prices the fake is corrected here. New row B-N4 to the node lane with B6. B-T4, B-T6, B-T7, B-T8 answered; B-T1, B-T2, B-T5 stay BLOCKED. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
757c729661
commit
840ef38549
4 changed files with 65 additions and 16 deletions
|
|
@ -15,7 +15,8 @@ registry until the panel reads it; this lane writes no PASS. The status words in
|
|||
| The spec | `docs/spec/01-lottery-hash.md` on master bc6bfa75e: 1.0 (the frozen object), 1.6, 1.10, 1.12, 1.13.3 | the dataset policy digest in full, the epoch, day and era clocks |
|
||||
| The signing pair | `igneum-pow/tests/composition.rs` at class-v6 755c2dbcf | epoch seed af89be5d..., era edc4fa84..., day 20730, program id 0x2a1d6caab4c24564 |
|
||||
| The B1 lane's encoding pins (R15-05, a4490b2dfe9114a55, 10:2x UK) | unkeyed BLAKE2b-256, `lambda = 256`, one ASCII role byte per query kind, u64 LE integers, raw-label leaves, path bit `j` = bit `j - 1` of the leaf index (LSB at the root), no path sharing, the graph from `'G' || graph_seed || u64 v || u64 ctr` by rejection sampling (DRSample from ABH17 Algorithm 1) | adopted here whole; B1 owns the primitive and its fixtures |
|
||||
| Figures | `tools/mhpow/b2/b2_figures.py` (sha256 7b8664ea44b770c9f6af246898aa576f3f0a63e65e7bf50a0b278c5727a1ee8b) | output `figures.txt` (sha256 27bb414c8534a438fdeae98cba2d4b9ece9c21d0487aa872673b0da465d9702a), run on build-9 under `/srv/builds/b2/b2-run.pid`: `python3 tools/mhpow/b2/b2_figures.py > docs/analysis/mhpow/b2/figures.txt` |
|
||||
| The B4 theory lane's answers (a46974623d72b032c) | `docs/analysis/mhpow/b4/requirements.md` (branch mhpow-b4 6d9c14596) and `docs/analysis/mhpow/b4/README.md` section 5b (build/master 80b127484) | the B-T rows of section 4 and the lottery rule of O-17 |
|
||||
| Figures | `tools/mhpow/b2/b2_figures.py` (sha256 742b64d9c2f3f8bad0524c9cdf38ac3aeff0c33bb14e000eb17b278053d79103) | output `figures.txt` (sha256 90e0f3932e2d915b7b1bcc958d5a2a74ccba55c2a3a37e71f53390b42bb7a022), run on build-9 under `/srv/builds/b2/b2-run.pid`: `python3 tools/mhpow/b2/b2_figures.py > docs/analysis/mhpow/b2/figures.txt` |
|
||||
|
||||
## 1. What the paper proves, and what it does not
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ The oracle and the domain separation:
|
|||
| Merkle node | `tau_x = H('M', chi || tau_x0 || tau_x1)`; leaves are the raw labels, node `w` at leaf index `w - 1`; root `tau = tau_empty`; a reveal is the label and `n` siblings | section 4.1, Appendix C, salt `chi` |
|
||||
| Challenge | `c_i = int_le(H('C', chi || u64 i || tau)) mod N`, `i = 1 .. k`; open node `c_i + 1` and each parent, each with its own path | `c_i = H(chi, i, tau) mod N` |
|
||||
| Graph | DRSample, indeg 2, its draws from `H('G', graph_seed || u64 v || u64 ctr)` by rejection sampling; `graph_seed` a 32-byte public consensus constant, never `chi` | Fact 8; section 1.2 (the graph fixed a priori) |
|
||||
| Lottery value | NONE in this draft (O-07) | the paper has none |
|
||||
| Lottery value | `W = int_le(H('W', chi || tau)) <= target`, the winner verified IN FULL (O-17, B4's rule; the naive spot-check-only forms FAIL, O-07) | the paper has none |
|
||||
|
||||
Every query is fixed width once the role and the node are known, which keeps Theorem 5's parse unique (the extractor reads the
|
||||
`h`-th parent at a fixed offset after `chi` and `v`). The role byte keeps the query families disjoint (B1's note: without it the challenge query `H(chi, i, tau)` has the shape of
|
||||
|
|
@ -127,30 +128,33 @@ parameter choice (B3, B4) fill them. They are not conformance vectors; the B1 la
|
|||
| O-14 | Rejected trials and cancellation: a trial in flight when the template changes | the instance binds the parent set, so a new block on the network stales every trial in flight; the honest trial takes `O(N)` sequential rounds (Definition 5, item 1) | not a soundness matter; it is a feasibility bound: `N x t_seq <= rho x T_block`, with `T_block` 1 s on the devnet (spec 1.12) and `rho` the stale fraction the chain accepts. The bound caps `N`, and a small `N` fits one instance in SRAM, which is the B5 question | BLOCKED B-N2 (the node lane: `T_block` and `rho` on devnet-4) and B3 (`t_seq` measured, never assumed) |
|
||||
| O-15 | The frozen class stays the chain's binding: the dataset policy 70a6c703 and the signing id 2a1d6caab4c24564 | the instance carries `dataset_policy` (all 32 bytes), `program_id`, `epoch_seed`, `epoch_start_daa`, `era_seed`, `day_index` and `state_root`; the verifier recomputes each from the chain and the header and rejects a mismatch, so no certificate carries across a class object, a policy or an epoch | by construction plus O-01, O-03. Two facts for the node lane: the policy digest sits outside the consensus digest until the class v6 floor is set (f0 manifest), so the instance is the only place a certificate binds it today; and the day rule differs between `bind.rs` (the interim `timestamp_ms / 86,400,000`) and spec 1.12 (DAA seconds) | ANSWERED by construction, conditional on B-N1 and B-N3 |
|
||||
| O-16 | The epoch-seed lead and the day-pack: no precomputation across trials | the labelling needs `chi`, which needs the template's parents; the 600 DAA-second epoch-seed lead and the day key (known before the day) give no label in advance. Static per-day work (the v6 dataset) stays amortisable by design; the instance removes it from the MHPoW part only | O-03 | ANSWERED |
|
||||
| O-17 | The lottery rule (B4-OB-LOT-1, this lane's row): B4's replacement for O-07, and the cost of a fake winner that passes the spot checks | trial id in `chi`; `W = H('W', chi || tau) <= target`; a winner is verified IN FULL (the verifier recomputes all `N` labels and the root, so `tau` is unique per `chi` and one draw costs one labelling); the `k` spot checks stay as the header pre-filter. The pre-filter does NOT price a fake: the prover keeps one honest labelling and re-rolls the red sink until `W` passes, about `(log2 N + 1) / p` calls a fake against `2N / p` for a real winner, and the fake passes the spot checks with `(1 - 1/N)^k`. Every validator it reaches then pays one full labelling (`2N` calls, `N` sequential steps) to reject it. An attacker with share `s` of the honest network's oracle calls makes `s x 2N / (log2 N + 1)` fakes per real block: 1.34 at `s = 10^-6`, 134 at `10^-4`, 13,400 at `10^-2` (`N = 2^24`, figures section 6 (a)). Per fake the attacker pays `(log2 N + 1) D / (2N)` of one validator's rejection cost (`D` labellings per block interval network-wide): 0.745 at `D = 10^6`, 74.5 at `10^8` (section 6 (b)), and every node the fake reaches pays it again | B4 README 5b says R1's theorem prices a spot-check-passing fake at the cmc bound. It does not: Theorem 7 is paid once per trace, and one trace yields fakes at the re-roll price (O-07, B1's fixture A6). The rule's soundness per draw is B4 Lemma C (NOT RUN) with AS15 per fully verified labelling | the rule ADOPTED as the draft binding (work version 1); the fake-winner budget is the open part: BLOCKED B-N4 and B4-OB-LOT-4 (B6) |
|
||||
|
||||
## 4. The BLOCKED questions, with their owners
|
||||
|
||||
| Id | Owner | The exact question |
|
||||
|---|---|---|
|
||||
| B-T1 | B4 theory lane (to be named) | For DRSample sampled from a fixed public seed at `N = 2^20` to `2^24`, what is the probability that the sampled graph is not `(c3 N / log N, c4 N)`-depth-robust, with the constants written out? Is a per-era re-seed from the era seed admissible, given that a party able to bias the era seed could search for a weak graph? |
|
||||
| B-T2 | B4 | The values of `c3` and `c4` (Fact 8, from ABH17 or ABP17) for the sampled DRSample at the chosen `N`, proved, so that Corollary 3's bound and `k = 2 lambda log N / c3` become numbers. Without them every certificate size and every lower bound in this README is a sensitivity row. |
|
||||
| B-T3 | B4 | The lottery. Give a lottery value `W` (or prove none exists) such that the expected number of distinct accepted pairs (`chi`, certificate) with `W` under the target, output by an adversary of cumulative memory `C`, is at most `C` divided by a constant fraction of Corollary 3's bound, with sampled verification of polylog cost. Known: any `W` that depends on labels the verifier samples can be re-rolled through an unchallenged node at the cost of that node's descendants (O-07 (a)); any `W` of `chi` alone is screened for free (O-07 (b)). Candidates for the panel: a succinct proof of the full labelling (a unique output, so Alwen and Serbinenko's bound per trial applies, at a prover cost the paper's own section 1 calls non-egalitarian); or a construction that is not MTP. |
|
||||
| B-T4 | B4 | The adaptive-input version of Corollary 3: the adversary chooses `chi` among at most `q` candidates after querying `H`. State the loss in the bad-event sum. |
|
||||
| B-T5 | B4 | The multi-instance version: producing accepted certificates for `m` distinct inputs costs at least `m (lambda/4)(c3 c4 / 2) N^2 / log N` except with what probability, and how the `q` and `t` terms scale with `m`. |
|
||||
| B-T6 | B4 | The label width `lambda` for an adversary of `q = 2^64` to `2^96` queries: either `lambda >= 8 log2 q + 4` under Lemma 3 as stated (516 to 772 bits, so an XOF in place of BLAKE2b's 512-bit maximum), or a tighter statement of Theorem 6 with the charge `lambda - 2 log2 q - log2 indeg` per pebble at `lambda = 256`. |
|
||||
| B-T7 | B4 | Confirm that no step in Theorems 4 to 7 or Lemmas 2 to 4 uses a coincidence between a label query and a Merkle or challenge query that the role byte would remove (the role byte only splits the domain; the check is that the extractor's hint and parse still hold). |
|
||||
| B-T8 | B4 with the adversary lane | The translation from cumulative memory to energy and bandwidth (the plan's R2, R3), including the full-SRAM design at the `N` that O-14 allows. |
|
||||
| B-T1 | B4 theory lane a46974623d72b032c | STILL BLOCKED (B4-B01: ABH17 not fetched by B4; B1 holds the archived ABH17, eprint 2017/443, sha256 f8e08d36...). For DRSample sampled from a fixed public seed at `N = 2^20` to `2^24`, what is the probability that the sampled graph is not `(c3 N / log N, c4 N)`-depth-robust, with the constants written out? Is a per-era re-seed from the era seed admissible, given that a party able to bias the era seed could search for a weak graph? |
|
||||
| B-T2 | B4 | STILL BLOCKED (B4-B03). The values of `c3` and `c4` (Fact 8, from ABH17 or ABP17) for the sampled DRSample at the chosen `N`, proved, so that Corollary 3's bound and `k = 2 lambda log N / c3` become numbers. Without them every certificate size and every lower bound in this README is a sensitivity row. |
|
||||
| B-T3 | B4 | ANSWERED IN SHAPE by B4 Lemma C (NOT RUN): no `W` with polylog sampled verification meets the bound inside MTP; the replacement is full verification of winners, adopted here as O-17, whose fake-winner budget stays open. The lottery. Give a lottery value `W` (or prove none exists) such that the expected number of distinct accepted pairs (`chi`, certificate) with `W` under the target, output by an adversary of cumulative memory `C`, is at most `C` divided by a constant fraction of Corollary 3's bound, with sampled verification of polylog cost. Known: any `W` that depends on labels the verifier samples can be re-rolled through an unchallenged node at the cost of that node's descendants (O-07 (a)); any `W` of `chi` alone is screened for free (O-07 (b)). Candidates for the panel: a succinct proof of the full labelling (a unique output, so Alwen and Serbinenko's bound per trial applies, at a prover cost the paper's own section 1 calls non-egalitarian); or a construction that is not MTP. |
|
||||
| B-T4 | B4 | ANSWERED AS A LOSS by B4 (NOT RUN): MISCOLOR becomes `q N 2^-lambda`; the other bad events are already unions over the trace. The adaptive-input version of Corollary 3: the adversary chooses `chi` among at most `q` candidates after querying `H`. State the loss in the bad-event sum. |
|
||||
| B-T5 | B4 | STILL BLOCKED (B4-OB-LOT-3; the union-graph route, MISCOLOR `J N 2^-lambda`, proof not written). The multi-instance version: producing accepted certificates for `m` distinct inputs costs at least `m (lambda/4)(c3 c4 / 2) N^2 / log N` except with what probability, and how the `q` and `t` terms scale with `m`. |
|
||||
| B-T6 | B4 | ANSWERED AS A CONSTRAINT by B4: `w >= 8 log2 q + 4`, or R2 Theorem 3.3's `w > 20 log2 q` (1,280 bits at `q = 2^64`); labels of 1 KiB or more meet both, through an XOF or R16's permutation. The instance's `label_bytes` field carries it; `chi` and every fixture move with it. The label width `lambda` for an adversary of `q = 2^64` to `2^96` queries: either `lambda >= 8 log2 q + 4` under Lemma 3 as stated (516 to 772 bits, so an XOF in place of BLAKE2b's 512-bit maximum), or a tighter statement of Theorem 6 with the charge `lambda - 2 log2 q - log2 indeg` per pebble at `lambda = 256`. |
|
||||
| B-T7 | B4 | ANSWERED BY READING by B4 (not a proof audit): the role byte only shifts offsets, and Theorem 4's Merkle trace needs exactly that form separation. Confirm that no step in Theorems 4 to 7 or Lemmas 2 to 4 uses a coincidence between a label query and a Merkle or challenge query that the role byte would remove (the role byte only splits the domain; the check is that the extractor's hint and parse still hold). |
|
||||
| B-T8 | B4 with the adversary lane | ANSWERED by B4 README sections 5, 7, 8 and its Q5: the window `log2 N x M_SRAM / C <= N b <= b rho / t_seq` may be empty for DRSample. The translation from cumulative memory to energy and bandwidth (the plan's R2, R3), including the full-SRAM design at the `N` that O-14 allows. |
|
||||
| B-N1 | node lane a283f5f0d364ceef0 | Which day rule is live on devnet-4 (`bind.rs`'s timestamp day or spec 1.12's DAA day), and the rule the verifier uses to recompute `epoch_seed`, `epoch_start_daa`, `era_seed`, `program_id` and the policy digest from a header and the chain. |
|
||||
| B-N2 | node lane | The block interval on devnet-4, the timestamp acceptance window (past median and future bound), and the stale fraction the chain accepts, so O-14's bound on `N x t_seq` is a number. |
|
||||
| B-N4 | node lane with B6 | O-17's fake-winner budget at the network's scale: does a block that fails full verification cost its sender (peer score, ban, a relay rule of full verification before forwarding), and what full verifications per second per node can the chain absorb before the 1.34-fakes-per-block attacker at `s = 10^-6` (`N = 2^24`) stalls validation? |
|
||||
| B-N3 | node lane | The 32 bytes of the state stream root the class v6 dataset is keyed on for the signing pair (epoch af89be5d, era edc4fa84, day 20730), and whether that root is in the header's past by the epoch boundary. |
|
||||
|
||||
## 5. What this means for Track B
|
||||
|
||||
1. The input binding is complete for reuse: no certificate carries across a template, a trial, an epoch, a day, an era, a network
|
||||
or a class object (O-01 to O-04, O-15, O-16).
|
||||
2. The economic binding is not: the reference construction has no lottery, and the two direct ways to add one either buy about a
|
||||
million draws per labelling at `N = 2^24` or screen trials for free (O-07). Until B-T3 is answered, an MTP certificate per
|
||||
block adds memory work per block, never per lottery trial, and cannot move the 1.5x ratio.
|
||||
2. The economic binding is not in the paper: the reference construction has no lottery, and the two direct ways to add one either
|
||||
buy about a million draws per labelling at `N = 2^24` or screen trials for free (O-07). B4's rule (O-17: full verification of
|
||||
winners) restores one labelling per draw, at a price: a fake winner costs about a millionth of a real one and costs every
|
||||
validator a full labelling, so the rule is adopted as the draft and its denial-of-service budget is the open row (B-N4).
|
||||
3. Binding the template forces each trial to finish inside a fraction of the block interval (O-14), which caps `N` and pushes the
|
||||
instance toward a size that fits in SRAM. B3 and B5 own that collision; it is recorded here because the binding causes it.
|
||||
4. Even granted a lottery, the proved bound sits a factor `4 log N / (c3 c4)` under the honest prover's cumulative memory with
|
||||
|
|
|
|||
|
|
@ -94,3 +94,25 @@ log2_N k honest_calls_per_trial reroll_calls_per_draw amortisation pass_probabil
|
|||
20 9000 2097152 21 9.99e+04 0.991454
|
||||
24 2000 33554432 25 1.34e+06 0.999881
|
||||
24 9000 33554432 25 1.34e+06 0.999464
|
||||
|
||||
== 6. O-17: the fake-winner budget under B4's rule (trial id in chi, W = H(lot, chi, tau), winners verified in full,
|
||||
the k spot checks as the header pre-filter). A fake winner keeps ONE honest labelling and re-rolls the red sink until
|
||||
W <= target: about (log2 N + 1) / p calls per fake once the labelling exists; it passes the spot checks with (1 - 1/N)^k;
|
||||
every validator it reaches recomputes the labelling in full (2N calls, N sequential label steps) before rejecting it.
|
||||
A real winner costs 2N / p calls. p = 1 / D, D = labellings per block interval network-wide.
|
||||
(a) fakes per real block for an attacker holding share s of the honest network's oracle calls: s * 2N / (log2 N + 1)
|
||||
log2_N share fakes_per_real_block
|
||||
20 1e-06 0.0999
|
||||
20 0.0001 9.99
|
||||
20 0.01 999
|
||||
24 1e-06 1.34
|
||||
24 0.0001 134
|
||||
24 0.01 1.34e+04
|
||||
(b) attacker calls per fake / one validator's calls to reject it: (log2 N + 1) D / (2N)
|
||||
log2_N D attacker_over_validator
|
||||
20 10000 0.1
|
||||
20 1e+06 10
|
||||
20 1e+08 1e+03
|
||||
24 10000 0.00745
|
||||
24 1e+06 0.745
|
||||
24 1e+08 74.5
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@
|
|||
"status": "NOT RUN",
|
||||
"method": "model",
|
||||
"evidence": "docs/analysis/mhpow/b2/README.md",
|
||||
"note": "POW-05: obligations O-06 to O-11 and O-16 (grinding, chosen instance, amortisation, partial evaluation, precomputation); O-07 records two FAIL rules and B-T3 the open question. POW-06: O-11's certificate sizes as functions of DRSample's unproved constant c3 (13.6 to 194.9 MiB at lambda 256), a sensitivity table only; the verifier budget is B6's.",
|
||||
"note": "POW-05: obligations O-06 to O-11 and O-16 (grinding, chosen instance, amortisation, partial evaluation, precomputation); O-07 records two FAIL rules (B1's fixture A6 executes the first); O-17 adopts B4's full-verification rule with its fake-winner budget open (B-N4). POW-06: O-11's certificate sizes as functions of DRSample's unproved constant c3 (13.6 to 194.9 MiB at lambda 256), a sensitivity table only; the verifier budget is B6's.",
|
||||
"claim_impact": "none: no public figure moves; Track B's construction is not adopted and nothing activates",
|
||||
"in_progress": true
|
||||
}
|
||||
],
|
||||
"map_cell_requested": {
|
||||
"model:mhpow-b2-binding": {
|
||||
"command": "python3 tools/mhpow/b2/b2_figures.py > docs/analysis/mhpow/b2/figures.txt (a build box under a pid file; byte-identical output, sha256 27bb414c...)",
|
||||
"command": "python3 tools/mhpow/b2/b2_figures.py > docs/analysis/mhpow/b2/figures.txt (a build box under a pid file; byte-identical output, sha256 90e0f393...)",
|
||||
"box_class": "build box, CPU only (build-9)",
|
||||
"fixtures": [],
|
||||
"cases": [
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ Sections:
|
|||
3. Lemma 3's precondition lambda/4 >= 2 log2 q + log2 indeg and the per-pebble charge lambda - 2 log2 q - log2 indeg
|
||||
(the extractor's bound before the paper rounds it to lambda/4);
|
||||
4. Corollary 2's challenge count and the certificate size, as functions of DRSample's unproved constant c3;
|
||||
5. the lottery re-roll counter-example (obligation O-07): honest oracle calls per trial against the re-roll's.
|
||||
5. the lottery re-roll counter-example (obligation O-07): honest oracle calls per trial against the re-roll's;
|
||||
6. O-17, the fake-winner budget under B4's full-verification rule (B4-OB-LOT-1).
|
||||
|
||||
Nothing here is a measurement. Every row is arithmetic on the paper's statements (eprint 2025/1456, the copy with
|
||||
sha256 13c3646e7d85c1aa58a92914582caab5798d90cf2a3cad33e58d81d49c1d31db) and on the draft layout.
|
||||
|
|
@ -213,12 +214,34 @@ def section5():
|
|||
print(f"{ln}\t{k}\t{honest}\t{reroll}\t{honest / reroll:.3g}\t{p:.6f}")
|
||||
|
||||
|
||||
def section6():
|
||||
print()
|
||||
print("== 6. O-17: the fake-winner budget under B4's rule (trial id in chi, W = H(lot, chi, tau), winners verified in full,")
|
||||
print(" the k spot checks as the header pre-filter). A fake winner keeps ONE honest labelling and re-rolls the red sink until")
|
||||
print(" W <= target: about (log2 N + 1) / p calls per fake once the labelling exists; it passes the spot checks with (1 - 1/N)^k;")
|
||||
print(" every validator it reaches recomputes the labelling in full (2N calls, N sequential label steps) before rejecting it.")
|
||||
print(" A real winner costs 2N / p calls. p = 1 / D, D = labellings per block interval network-wide.")
|
||||
print(" (a) fakes per real block for an attacker holding share s of the honest network's oracle calls: s * 2N / (log2 N + 1)")
|
||||
print("log2_N\tshare\tfakes_per_real_block")
|
||||
for ln in (20, 24):
|
||||
n = 2 ** ln
|
||||
for share in (1e-6, 1e-4, 1e-2):
|
||||
print(f"{ln}\t{share:g}\t{share * 2 * n / (ln + 1):.3g}")
|
||||
print(" (b) attacker calls per fake / one validator's calls to reject it: (log2 N + 1) D / (2N)")
|
||||
print("log2_N\tD\tattacker_over_validator")
|
||||
for ln in (20, 24):
|
||||
n = 2 ** ln
|
||||
for d in (1e4, 1e6, 1e8):
|
||||
print(f"{ln}\t{d:g}\t{(ln + 1) * d / (2 * n):.3g}")
|
||||
|
||||
|
||||
def main():
|
||||
total = section1()
|
||||
section2(total)
|
||||
section3()
|
||||
section4()
|
||||
section5()
|
||||
section6()
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue