Skip to content

Commit a622df7

Browse files
committed
Add references in the doc
1 parent 903373a commit a622df7

File tree

2 files changed

+80
-31
lines changed

2 files changed

+80
-31
lines changed

crates/dkg/src/verification.rs

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -365,53 +365,82 @@ where
365365
key.verify_signature(commitment.hash.as_ref(), &signature)
366366
}
367367

368-
pub fn prove_wrong_final_key_generation<Setup>(
368+
fn verify_generation_base_hashes<Setup>(
369369
data: &BadPartialShareData<Setup>,
370370
) -> Result<(), Box<dyn std::error::Error>>
371371
where
372372
Setup: DkgSetup + DkgSetupTypes<Setup>,
373373
{
374-
verify_commitment_signature(data)?;
375-
// Verify that the generation base hashes are correct
376-
for generation in data.generations.iter() {
377-
let ok = verify_initial_commitment_hash::<Setup>(&InitialCommitment::<Setup> {
374+
for generation in &data.generations {
375+
let initial_commitment = InitialCommitment::<Setup> {
378376
hash: generation.base_hash,
379377
settings: data.settings.clone(),
380378
base_pubkeys: generation.verification_vector.clone(),
381-
});
382-
if !ok {
379+
};
380+
381+
if !verify_initial_commitment_hash::<Setup>(&initial_commitment) {
383382
return Err(Box::new(VerificationErrors::UnslashableError(format!(
384383
"Invalid generation base hash {}",
385384
generation.base_hash
386385
))));
387386
}
388387
}
388+
Ok(())
389+
}
390+
391+
fn verify_expected_key<Setup>(
392+
sorted_generation: &[BadPartialShareGeneration<Setup>],
393+
perpetrator_index: usize,
394+
key: &Setup::DkgPubkey,
395+
) -> Result<(), Box<dyn std::error::Error>>
396+
where
397+
Setup: DkgSetup + DkgSetupTypes<Setup>,
398+
{
399+
let perpetrator_id = Setup::Scalar::from_u32((perpetrator_index + 1) as u32);
400+
let expected_key = compute_pubkey_share(sorted_generation, &perpetrator_id);
401+
402+
let actual_key_point = Setup::Point::from_bytes(&key.to_bytes())
403+
.map_err(|_| VerificationErrors::SlashableError("Invalid point".to_string()))?;
404+
405+
if expected_key != actual_key_point {
406+
return Err(Box::new(VerificationErrors::SlashableError(format!(
407+
"Computed key {} does not match expected key {}",
408+
expected_key, key
409+
))));
410+
}
411+
Ok(())
412+
}
413+
414+
pub fn prove_wrong_final_key_generation<Setup>(
415+
data: &BadPartialShareData<Setup>,
416+
) -> Result<(), Box<dyn std::error::Error>>
417+
where
418+
Setup: DkgSetup + DkgSetupTypes<Setup>,
419+
{
420+
verify_commitment_signature(data)?;
421+
verify_generation_base_hashes(data)?;
389422

390423
let mut sorted_generation = data.generations.to_vec();
391424
sorted_generation.sort_by(|a, b| a.base_hash.cmp(&b.base_hash));
392425

393426
let perpetrator_index =
394427
find_perpetrator_index(&data.bad_partial.data.base_hash, &sorted_generation)?;
395428

396-
let key = match Setup::DkgPubkey::from_bytes_safe(&data.bad_partial.data.partial_pubkey) {
397-
Ok(key) => key,
398-
Err(e) => {
399-
return Err(Box::new(VerificationErrors::SlashableError(format!(
429+
let key =
430+
Setup::DkgPubkey::from_bytes_safe(&data.bad_partial.data.partial_pubkey).map_err(|e| {
431+
VerificationErrors::SlashableError(format!(
400432
"While uncompressing data.bad_partial.data.partial_pubkey {}",
401433
e
402-
))));
403-
}
404-
};
434+
))
435+
})?;
405436

406-
let sig = match Setup::DkgSignature::from_bytes_safe(&data.bad_partial.data.message_signature) {
407-
Ok(sig) => sig,
408-
Err(e) => {
409-
return Err(Box::new(VerificationErrors::SlashableError(format!(
437+
let sig = Setup::DkgSignature::from_bytes_safe(&data.bad_partial.data.message_signature)
438+
.map_err(|e| {
439+
VerificationErrors::SlashableError(format!(
410440
"While uncompressing data.bad_partial.data.message_signature {}",
411441
e
412-
))));
413-
}
414-
};
442+
))
443+
})?;
415444

416445
if !key.verify_signature(data.bad_partial.data.message_cleartext.as_bytes(), &sig) {
417446
return Err(Box::new(VerificationErrors::SlashableError(format!(
@@ -420,16 +449,7 @@ where
420449
))));
421450
}
422451

423-
let perpetrator_id = Setup::Scalar::from_u32((perpetrator_index + 1) as u32);
424-
425-
let expected_key = compute_pubkey_share(&sorted_generation, &perpetrator_id);
426-
427-
if expected_key != Setup::Point::from_bytes(&key.to_bytes()).expect("Invalid point") {
428-
return Err(Box::new(VerificationErrors::SlashableError(format!(
429-
"Computed key {} does not match expected key {}",
430-
expected_key, key,
431-
))));
432-
}
452+
verify_expected_key::<Setup>(&sorted_generation, perpetrator_index, &key)?;
433453

434454
Ok(())
435455
}

doc/dkg_verification.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,32 @@ Once all valid signatures are collected, any participant (or a subset thereof) c
301301
The circuit succeeds only if all commitments, partial keys, signatures, and the reconstructed final key are valid.
302302

303303

304+
## References for Zero-Knowledge Verification of Distributed Key Generation
305+
306+
- **Shamir’s Secret Sharing (SSS)**
307+
A method to divide a secret into multiple parts, requiring a minimum number of parts to reconstruct the original secret.
308+
[Shamir's Secret Sharing - Wikipedia](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing)
309+
310+
- **Verifiable Secret Sharing (VSS)**
311+
An extension of Shamir’s Secret Sharing that enables participants to verify the validity of their shares.
312+
[Verifiable Secret Sharing - Wikipedia](https://en.wikipedia.org/wiki/Verifiable_secret_sharing)
313+
314+
- **Zero-Knowledge Proofs (ZKPs)**
315+
Cryptographic methods enabling proof of validity without revealing underlying information.
316+
[Zero-Knowledge Proof (ZKP) — Chainlink](https://chain.link/education/zero-knowledge-proof-zkp)
317+
318+
- **Distributed Key Generation Protocols**
319+
Protocols allowing multiple participants to jointly generate a shared public/private key pair without exposing private keys.
320+
[Distributed Key Generation - Wikipedia](https://en.wikipedia.org/wiki/Distributed_key_generation)
321+
322+
- **Lagrange Interpolation**
323+
Mathematical method used in Shamir’s Secret Sharing to reconstruct secrets from polynomial interpolation.
324+
[Lagrange Polynomial - Wikipedia](https://en.wikipedia.org/wiki/Lagrange_polynomial)
325+
326+
- **Elliptic Curve Diffie–Hellman (ECDH)**
327+
Key agreement protocol for securely deriving shared keys over an insecure channel.
328+
[Elliptic-Curve Diffie–Hellman - Wikipedia](https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman)
329+
330+
- **ChaCha20-Poly1305**
331+
Authenticated encryption algorithm combining confidentiality and integrity protection.
332+
[ChaCha20-Poly1305 - Wikipedia](https://en.wikipedia.org/wiki/ChaCha20-Poly1305)

0 commit comments

Comments
 (0)