Repository navigation
Conversation
…s; Details: TC-2220
…text check; Details: TC-2220
…numerate fault patterns; Details: TC-2220
This was referenced Oct 30, 2026
Draft
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the S0.3 genesis distributed key generation to
tinycloud-threshold: GJKR New-DKG over owner-closed, member-signed rounds, with sealed dealings, complaints and answers, Feldman extraction, a common R5 round and R6 reconstruction, plusdkg_verify_transcript, which recomputes the outcome from the raw signed round records. The crate remains an unwired workspace member.Base:
mainatd7f88e231179ea525462a8f1582729d55735d581. Head:a672197481f5ef9e1efd662411188cba8cbf6bdb.What it does
dkg_startaccepts only an owner-authorized genesis ceremony within the genesis parameter budget (3-of-4 is refused withUnsupportedFaultBudget). It checks the member index and that the supplied recipient key matches that member's directory key before drawing any randomness or producing coefficients or dealings.DkgDealt → DkgComplained → DkgAnswered → DkgExtracting → DkgAwaitingBarrier → AfterBarrier::{Finished, Reconstruct(DkgReconstructing, R6)}. Every transition first requires the closed round's ceremony digest, round number and previous transcript link to match the state. The initial link isTH("TC-THRESHOLD-V1-DKG-START", authorized_ceremony_digest)fromdkg_initial_transcript.dkg_verify_transcripttakes the raw signed rounds (DkgTranscript), bounds the whole transcript to 4 MiB before checking signatures, and applies the same public rules as the members. It trusts no supplied outcome fields.SPEC.mdgains the S0.3 genesis DKG appendix (layouts, rule order and lifecycle);README.mdis updated.vectors/v1/dkg-genesis.jsonholds six fixed-seed transcripts with recomputed outcomes or errors, regenerated and replayed byte for byte by a test.Round equivocation compares conflicting authenticated message content from the same sender; a different signature encoding alone is not equivocation. No-abort liveness scenarios use a trusted relay that delivers every honest message. Dropped-message and equivocating-relay cases are separate failure/activation scenarios; this implementation does not provide reliable broadcast.
Commits and ownership
b8d52580test: recipient public-key derivation (seal module owner).073412batest: DKG module tests, signed owner relay scenarios, DKG checkpoint and module wiring (tests-only; no implementation).23849d71feat: crate-privateCeremonyHpkeSecretKey::public_key()(seal module owner).fd9073b8feat: DKG implementation; three typed error variants; removal of five#[cfg(test)]gates on existing crate-private helpers (Scalar::from_bytes,Scalar::to_bytes,Scalar::add,hash_g2,poly::evaluate) with no signature or body change; removal of the seal module's dead-code allowance.4f090b94test: in this PR's own new testlocal_recipient_key_and_context_are_checked_before_any_randomness(src/dkg_relay.rs, added in073412ba), the seed passed to the existing reshare-ceremony test helper changes from 12 to 11 so the reshare keeps the genesis master key and the ceremony builds; the test's assertions are unchanged. No test or fixture that existed before this PR is edited.705ff4d0fix: clippy corrections (anAfterBarriersize allowance with reason; test type alias and slice).a6721974docs: SPEC appendix, README, DKG vectors.Review notes
Scalar::from_bytesrefuses non-canonical encodings (curve.rstestscalar_canonical_boundaries_and_modular_arithmetic; DKG decoder tests assertInvalidScalarfor non-canonical pair scalars).Scalarclears its storage on drop (curve.rsimpl Zeroize/Drop for Scalar); DKG polynomial coefficients, received pairs and the candidate sum are held asScalarvalues inside the consumed states.public_key()seam derives through the HPKE library's public API and is exercised bysecret_public_key_matches_generated_recipientandlocal_recipient_key_and_context_are_checked_before_any_randomness.Checks
Run locally at
705ff4d0with the pinned 1.97.1 toolchain, isolated homes and target, two jobs (a6721974changes only SPEC, README and the generated vector file):cargo test --locked -p tinycloud-threshold --release --no-run: ok.TC_THRESHOLD_REGEN_VECTORS=1 cargo test --locked -p tinycloud-threshold --release dkg_vectors_regenerate_byte_for_byte_and_replay: ok.PROPTEST_CASES=1024 cargo test --locked -p tinycloud-threshold --release: 118 passed, 0 failed.PROPTEST_CASESsets the default case count only.within_budget_fault_patterns_finish_with_identical_outcomessets its ownProptestConfig::with_cases(12), so that property ran 12 fault-pattern ceremonies in this run, not 1024.cargo test --locked -p tinycloud-threshold --release checkpoint_2of3 -- --nocapture: the existing nine outcomes and five DKG outcomes printed.cargo clippy --locked -p tinycloud-threshold --all-targets -- -D warnings: ok.cargo fmt -p tinycloud-threshold -- --check: ok.ContextMismatchfor a recipient key outside the directory and transcript rejection for an altered member signature.Named DKG tests include:
genuine_2of3_completes_with_every_member_and_the_verifier_agreeing,genesis_3of4_is_refused_before_any_dealing,three_of_five_with_two_faulty_members_recovers_the_committed_master_key,one_recipient_bad_private_value_is_replaced_by_a_valid_answer,malformed_r2_supplies_no_complaints,conflicting_r2_content_is_equivocation_even_when_malformed,different_signature_encoding_is_not_equivocation,missing_r3_disqualifies_only_with_required_answers,malformed_r3_disqualifies_only_with_required_answers,invalid_unsolicited_answer_disqualifies_its_dealer,valid_unsolicited_answer_is_ignored,selective_r4_reaches_the_common_barrier_and_is_reconstructed,bad_missing_and_malformed_r4_are_extraction_faults,r1_equivocation_disqualifies_but_r4_equivocation_reconstructs,every_member_sends_r5_and_an_empty_barrier_finishes,missing_or_malformed_r5_counts_as_an_empty_list,corrupt_dealer_withholding_its_r6_is_recovered_and_kept,insufficient_valid_r6_values_abort_with_a_typed_error,transitions_refuse_other_ceremonies_rounds_and_histories,closed_rounds_reject_wrong_signers_cohorts_and_signatures,transcript_bound_of_4_mib_precedes_verification,within_budget_fault_patterns_finish_with_identical_outcomes,dkg_start_label_is_distinct_from_and_not_a_prefix_of_every_frozen_tag,checkpoint_2of3_dkg.Clean room
Dependencies: no change (existing
blst,sha2,zeroize,subtle,rand_core,thiserror,hpke0.12 withx25519; developmented25519-dalek,proptest,rand_chacha,serde,serde_json,hex).Provenance log
a·g2 + b·hand share checks. Feldman 1987: extraction vectorsa·g2. Shamir 1979: polynomial evaluation and interpolation.h.Details: TC-2220
Update: test additions at 82ab38c
One tests-only commit on
a6721974, changing onlysrc/dkg_relay.rs:transitions_refuse_a_foreign_ceremony_closure_on_this_history: a closed R1 from another authorized ceremony that names this ceremony's initial link is refused withInvalidRound.r2_naming_a_dealer_outside_the_cohort_supplies_no_complaintsandr3_naming_a_recipient_outside_the_cohort_is_malformed: the R2 and R3 index rules for members outside the cohort.within_budget_fault_patterns_finish_with_identical_outcomes(12 sampled cases) is replaced byevery_within_budget_fault_pattern_finishes_with_identical_outcomes_2of3and_3of5, which run every behaviour assignment of the in-tree fault model for two fixed seeds: 2 × (15 + 225) = 480 ceremonies. They cover that model only.Checks at
82ab38cb(pinned 1.97.1, isolated, two jobs): each new test fails by assertion when the rule it covers is removed from a private copy (the ceremony-digest and R2 rules were shown at the previous local commit with identical tests; the R3 rule at this head); full crate suite 122 passed, 0 failed;checkpoint_2of3printed all outcomes; clippy with-D warningsandcargo fmt -p tinycloud-threshold -- --checkpassed.Details: TC-2220