L0 Bytecode / CGGMP24
CGGMP24 L0 bytecode
CGGMP24 L0 bytecode combines a Paillier/ZK micro-alphabet with the KD1 presign-freeze and a generic ECDSA signing witness chain. The trace records Paillier auxiliary state, encrypted-share checks, MtA finalization, transcript sealing, and witness chain verification at publication time.
S_beta = (Sigma, L, W_beta, R_beta, Q_beta); op_beta(C, roots, S_beta) -> (root, S_beta', effects)Intuition: CGGMP24 produces a standard ECDSA signature among parties who never reconstruct the private key. Paillier encryption carries the multiplicative steps (MtA), and a zero-knowledge proof gates each step so an output is accepted into the computation only after its proof checks. The instruction list below splits the protocol into an offline presign phase (frozen one-shot) and an online signing phase: each evaluation instruction is paired with the proof check that admits it, and any failed check routes to an abort that poisons the presign session.
Each instruction shows descriptors for locality, phase, and stage. The uppercase badges state what the step does to state; locality remains the security-relevant descriptor for local, p2p, frontier, and evidence movement.
01aux_i := paillier_aux_keygen(C, party_i)- Create local Paillier auxiliary material for the KD1 lane.
- Bind modulus descriptor, auxiliary key state, and proof state to the witness store.
- Start the share_rand path before transcript sealing.
02ct_i := Enc_pk(share_i; rho_i)- Encrypt a local secret share for MtA, inversion, or EC-multiply lowering.
- Commit ciphertext handle and randomness witness state.
- Feed encryption proof checks and peer affine evaluation.
03ct_eval := affine_eval(ct_i, peer_share, masks)- Evaluate the Paillier affine relation used by MtA.
- Create the distributed wait point for peer-side contribution.
- Bind nonce-related MtA state into the transcript order.
04share_out := DecLocal(sk_pail_i, ct_eval)- Complete the local decryption side of the Paillier relation.
- Store decryption share and local witness material.
- Feed multiplication, inversion, or EC-multiply finalization.
05ok_mod := VerifyModulusProof(N_i, proof_mod_i)- Validate Paillier modulus evidence.
- Attach proof state to CGGMP witness evidence.
- Route proof failure into terminal reject evidence.
06ok_enc := VerifyEncProof(ct_i, proof_enc_i, bind)- Validate ciphertext well-formedness.
- Bind encryption proof to the operation and peer context.
- Gate MtA evaluation on checked encrypted shares.
07ok_aff := VerifyAffineGProof(ct_eval, proof_aff_i, bind)- Validate the affine/gadget relation used by share multiplication.
- Commit proof evidence for the MtA transcript.
- Gate mta_finalize on checked affine output.
08mul_frag := finalize_mta(dec_share, masks, transcript_roots)- Assemble the additive multiplication relation.
- Commit the CGGMP share_mul terminal root.
- Feed paillier_transcript_seal for KD1 presign evidence.
09inv_frag := finalize_inverse(dec_share, inv_state, transcript_roots)- Assemble the inversion relation for KD1 offline material.
- Commit the share_inv terminal root.
- Feed paillier_transcript_seal with inversion witness state.
10seal_root := H_CGGMP24(bind, args, cggmp_trace_input_roots, out_cid)- Seal the KD1 freeze transcript under the CGGMP24/BackendPaillier profile.
- Commit BackendMicroTrace with backend CGGMP24/BackendPaillier.
- Bind Paillier transcript evidence to the presign output CID.
11r1 := dsg_msg_r1_broadcast(C, presign inputs)- Create a suspendable pending frontier.
- Bind nonce commitment traffic into the ECDSA witness context.
- Feed PresignFreeze witness requirements.
12r2 := dsg_msg_r2_peer(C, r1, receiver state)- Create a per-peer pending frontier.
- Bind receiver RVOLE material into transcript order.
- Contribute to PresignFreeze witness root.
13r3 := dsg_msg_r3_peer(C, r2, sender check)- Create a per-peer pending frontier.
- Attach sender-side RVOLE check material.
- Close the interactive presign-freeze round set.
14presign_witness := normalize(input_roots, prior_transcript_roots)- Commit EcdsaWitnessSiteKind::PresignFreeze trace.
- Store local EcdsaWitnessStore under ecdsa-witness handle.
- Provide witness requirement for later partial signing.
15z := bind(message_hash, presign_cid, keyshare_context)- Bind challenge and presign material.
- Prepare partial-signature input roots.
- Connect KD1/AFF3 signing to the common ECDSA witness vocabulary.
16nonce := nonce_ref(rx_cid, r_point_cid)- Materialize nonce reference when the flow needs it.
- Bind R point and x-coordinate roots.
- Feed the partial signature output value.
17part_sig := PartSigKd1 | PartSigAff3(presign_cid, nonce_cid, signing shares)- Commit partial signature value.
- Commit consumed_presign marker.
- Create EcdsaWitnessSiteKind::PartialSign witness.
18bind_ok := check(part_sig, message_hash, presign_cid, signer_context)- Validate that the partial signature is bound to the selected message and presign material.
- Commit the final-sign witness check before aggregation.
- Close the signer-local ECDSA partial-signature evidence chain.
19sig_local := combine(sign_input_cid, s_cid, nonce_cid, witness_chain)- Verify prior ECDSA witness chain.
- Commit Finalize witness for signature-local material.
- Prepare publication-time witness verification.
20publish_ok := require_dkls23_dsg_publish_witnesses(sig_local_cid)- Verify final ECDSA witness before publication.
- Materialize public signature bytes through shared publication code.
- Expose portable evidence for external signature verification.
Witness shape
The Paillier/ZK layer provides the MtA, inversion, encryption, proof-check, and transcript-seal substrate. The ECDSA signing witness layer groups the signing path into three regions: presign freeze, partial sign, and finalize. Pending frontiers exist for round-message stages; presign normalization, partial-sign binding, signature combination, and verification readiness remain local witness stages.
Publication verifies the full witness chain before public signature bytes are materialized, keeping the Paillier/ECDSA evidence chain linked to the external signature artifact.
Effects
The bytecode commits presign values, part-signature values, final signature-local material, backend microtraces, and local ECDSA witness stores. Public signature material leaves the boundary only after the witness chain is verified at publish time.
Presign handle lifecycle
The CGGMP24 path introduces a presign handle that separates the offline Paillier/MtA phase from the online signing step. The handle moves through: Pending → Frozen (after paillierTranscriptSeal) → Reserved → Consumed or Poisoned. Reuse of a consumed presign handle is a protocol violation: it would leak the masked nonce scalar. AdvanceStep atomically reserves and then consumes the handle, and any double-consume poisons the presign session.
The freeze phase is visible in the session lifecycle. A DomainManifest can require a minimum batch of frozen presign handles before a signing epoch opens, so capacity and replay-safety are managed at the epoch level rather than per-operation. Operators observe the presign pool depth through the operational-risk plane without touching the underlying Paillier material.
ZK proof gating
Paillier MtA involves encrypted-share operations that must be ZK-verified before their outputs are accepted into the share_mul computation. The bytecode gates each evaluation stage on the corresponding proof check: pail_enc_share is gated by zk_enc_check, pail_affine_eval is gated by zk_aff_g_check, and pail_dec_local proceeds only after the encrypted input is verified clean.
Proof failures route to an explicit abort. A failed zk_mod_check, zk_enc_check, or zk_aff_g_check routes to commitAbort, which poisons the presign session, records the failing proof stage as a reason code, and closes the operation. The reject path is disjoint from the success path; bad proof input always takes the abort route.