CGGMP24 Threshold ECDSA

repository·cggmp24/m·Indexed 41 days ago

https://github.com/lfdt-lockness/cggmp21

A Rust implementation of the CGGMP24 Threshold ECDSA protocol providing secure multi-party computation (MPC) for key generation and signing. It supports both threshold (t-out-of-n) and non-threshold (n-out-of-n) configurations, HD wallet support via slip10, and no_std compatibility. Version 0.7.0-alpha.4 includes a migration path from cggmp21.

Tokens
28.7K
Snippets
88
Records
121
Agent score
100%

What's inside CGGMP24

  1. Overview of paillier-zk

    cggmp24/m
    The paillier-zk crate provides Zero-Knowledge (ZK) proofs for specific properties related to Paillier encryption. It is built on top of the fast-paillier crate. To simplify dependency management and prevent version mismatches, paillier-zk re-exports both fast-paillier and the underlying big integer implementation, allowing consumers to use them directly from this crate.
  2. Assign signer indices

    cggmp24/m

    The library uses unique indices to refer to signers. Each index is a u16 in the range $0 \le i < n$, where $n$ is the total number of parties.

    All signers must share a consistent view of these indices. A recommended approach is to use a Public Key Infrastructure (PKI) to assign indices by lexicographically sorting the signers' public keys and using their position in the sorted list as their index.

  3. Regenerate Auxiliary Data and Recover Key Shares

    cggmp24/m

    New Auxiliary Data Generation

    Because of protocol changes, old cggmp24::key_share::AuxInfo is unsupported. You must run the cggmp24::aux_info_gen() protocol. This is computationally intensive but is a one-time setup cost; use the same auxiliary data for all keys.

    Recovering Existing Key Shares

    To recover data from a serialized cggmp21::KeyShare, use the cggmp24::key_share::cggmp21_compat::ExtractCoreShare utility. It implements serde::Deserialize compatible with the old format, allowing you to extract the 'core' share. You can then combine this core with your newly generated auxiliary data to reconstruct a compatible cggmp24 key share.

  4. Understand the Key Share structure

    cggmp24/m

    A KeyShare is the output obtained from the key refresh protocol. It is used to perform signing operations and consists of two main parts:

    1. Core Share: Represented by the IncompleteKeyShare type.
    2. Auxiliary Data: Additional data required to carry out the signing process.

    Note: This implementation excludes the El-Gamal private key (which is present in the original CGGMP24 paper) because it is not required for the 3-round presigning protocol provided by this library.

  5. Understand the threshold protocol implementation

    cggmp24/m

    While the original [CGGMP24] paper defines a non-threshold protocol, this implementation extends it to support general thresholds by defining custom CGGMP24-like key generation and threshold signing protocols.

    The crate maintains both the threshold and non-threshold versions. If you choose to use the non-threshold protocol, you will be executing the original protocol as defined in the paper. Minor implementation differences (primarily typo fixes) are documented in the project's official specification.

  6. Perform Distributed Key Generation (DKG)

    cggmp24/m

    The DKG protocol allows signers to co-share a key. Participants must agree on the signer indices, a unique ExecutionId, and the threshold value t.

    1. Run Keygen: Execute cggmp24::keygen to produce an IncompleteKeyShare. This object can be serialized using serde for storage.
    2. Complete Key Share: After auxiliary-data generation is complete, use cggmp24::KeyShare::from_parts to combine the incomplete share with the aux_info.
    use cggmp24::supported_curves::Secp256k1;
    
    let eid = cggmp24::ExecutionId::new(b"execution id, unique per protocol execution");
    let i = /* signer index (0 <= i < n) */;
    let n = /* number of signers taking part in key generation */;
    let t = /* threshold */;
    
    let incomplete_key_share = cggmp24::keygen::<Secp256k1>(eid, i, n)
        .set_threshold(t)
        .start(&mut OsRng, party)
        .await?;
    
    // Later, complete the share:
    let key_share = cggmp24::KeyShare::from_parts((incomplete_key_share, aux_info)?);
  7. Use the Sync API for non-async environments

    cggmp24/m

    If you need to run protocols in a non-async environment, you can use the Sync API.

    To enable this, you must enable the state-machine feature. For every protocol, there is a companion function that returns a StateMachine. For example, to perform presignature generation synchronously, use signing::SigningBuilder::generate_presignature_sync.

  8. Configure Reliable Broadcast for CGGMP24

    cggmp24/m

    The CGGMP24 protocol requires that messages in the first round are sent over a reliable broadcast channel. To ensure this reliability, the implementation introduces an extra communication round, which increases latency.

    If your underlying transport layer is already reliable by construction (for example, if you are using a blockchain for communications), you may disable this feature to reduce latency.

    Default value: true.

  9. Import and Export keys (SPOF mode)

    cggmp24/m

    While the protocol is designed to avoid Single Points of Failure (SPOF), some use cases require importing existing keys into TSS or exporting keys from TSS.

    To use these primitives, enable the spof feature. You can then use:

    • trusted_dealer for key import.
    • key_share::reconstruct_secret_key for key export.
  10. Migrate from cggmp21 v0.6 to cggmp24 v0.7

    cggmp24/m

    Upgrading from cggmp21 to cggmp24 involves several breaking changes. To minimize friction, the migration is split into several alpha releases. You should follow the steps sequentially: v0.7.0-alpha.1 $\rightarrow$ v0.7.0-alpha.2 $\rightarrow$ v0.7.0-alpha.3 $\rightarrow$ v0.7.0-alpha.4.

    High-level Migration Workflow

    1. Update Dependencies: Update Cargo.toml to use cggmp24 and its associated crates (cggmp24-keygen, paillier-zk).
    2. Update Code References: Replace all cggmp21 tokens with cggmp24 tokens.
    3. Regenerate Auxiliary Data: Protocol changes make old cggmp24::key_share::AuxInfo incompatible. You must run cggmp24::aux_info_gen() to create new data.
    4. Handle Key Share Recovery: If you have serialized cggmp21 key shares, use cggmp24::key_share::cggmp21_compat::ExtractCoreShare to extract the core data and combine it with new auxiliary data.
    5. Update Signing Logic: The API now uses type-guards (DataToSign vs PrehashedDataToSign) to prevent insecure 'raw signing' of hashes without the original message.
    6. Update Big Integer Usage: The library has switched from rug to fast_paillier::backend::Integer (defaulting to num-bigint).
  11. Enable no_std compatibility

    cggmp24/m

    Every crate in this project is compatible with no_std environments, provided that the num-bigint backend is selected. Note that the alloc crate is still required. This configuration allows cggmp24 and cggmp24-keygen to run on platforms like wasm32-unknown-unknown.

    To enable no_std support, you must disable the default std feature and explicitly enable the no_std feature where applicable.

    cggmp24 = { version = "0.7", default-features = false, features = ["no_std", "backend-num-bigint"] }
    cggmp24-keygen = { version = "0.7", default-features = false }
    key-share = { version = "0.7", default-features = false }