Skip to content

feat(adkg-cli): implement g1 to g2 group swap for adkg output#93

Merged
azixus merged 3 commits into
mainfrom
feat/adkg-cli/dleq
Sep 9, 2025
Merged

feat(adkg-cli): implement g1 to g2 group swap for adkg output#93
azixus merged 3 commits into
mainfrom
feat/adkg-cli/dleq

Conversation

@azixus
Copy link
Copy Markdown
Contributor

@azixus azixus commented Sep 9, 2025

Mostly a bunch of wiring, the main protocol being L269-L387:

/// Pairing-based DLEQ proof that there exists an s_j s.t. P_1 = [s_j] G_1 \land P_2 = [s_j] G_2,
/// using witness s and proof \pi = P_2.
#[derive(Serialize, Deserialize)]
#[serde(bound(
serialize = "CG: PointSerializeCompressed",
deserialize = "CG: PointDeserializeCompressed"
))]
struct AdkgSwapPairingGroupMessage<CG>
where
CG: CurveGroup,
{
#[serde(with = "utils::serialize::point::base64")]
g2_sj: CG,
}
/// Using an ADKG output, swap the public keys to a different generator of the same group.
/// This protocol uses a pairing-based DLEQ proof to swap all the public keys from one group to another.
async fn pairing_swap_g1_to_g2<E, T>(
t_reconstruction: usize,
adkg_output: AdkgOutput<E::G1>,
g1: &E::G1,
g2: &E::G2,
mut transport: T,
) -> anyhow::Result<AdkgOutput<E::G2>>
where
E: Pairing,
E::G2: CurveGroup + PointSerializeCompressed + PointDeserializeCompressed,
T: Transport<Identity = PartyId>,
{
let node_pks = &adkg_output
.node_pks
.ok_or(anyhow!("cannot swap group without node pks"))?;
let sender = transport
.sender()
.ok_or(anyhow!("failed to obtain transport sender"))?;
let mut receiver = transport
.receiver_stream()
.ok_or(anyhow!("failed to obtain transport sender"))?;
// Generate the public key on G2. This also corresponds to a DLEQ proof that can be verified by
// checking that e([s] G_1, G_2) == e(G_1, [s] G_2) where [s] G_1 is the public key output by the
// ADKG, G_1, G_2 are public parameters.
let dleq_m = AdkgSwapPairingGroupMessage {
g2_sj: *g2 * adkg_output.sk,
};
let dleq_m = bson::to_vec(&dleq_m)?;
if let Err(e) = sender.send(dleq_m, Recipient::AllIncludingSelf).await {
tracing::error!(error = ?e, "Failed to send dleq group swap message")
}
// Collect at least t_reconstruction + 1 valid evals to reconstruct the swapped group public key
let mut dleq_msgs = BTreeMap::new();
loop {
let ReceivedMessage {
sender, content, ..
} = match receiver.next().await {
Some(Ok(msg)) => msg,
Some(Err(e)) => {
tracing::error!(error = ?e, "Failed to receive dleq message");
continue;
}
None => {
anyhow::bail!("Stream closed: no more dleq message to receive")
}
};
let dleq_j: AdkgSwapPairingGroupMessage<E::G2> = match bson::from_slice(&content) {
Ok(dleq_j) => dleq_j,
Err(e) => {
tracing::warn!(error = ?e, "Failed to decode dleq message");
continue;
}
};
let Some(g1_sj) = node_pks.get(sender.as_index()) else {
anyhow::bail!("adkg output's node_pks missing some ids")
};
// Verify the dleq proof with a pairing operation
if !E::multi_pairing([*g1, *g1_sj], [dleq_j.g2_sj, g2.neg()]).is_zero() {
tracing::warn!(?sender, "Failed to verify adkg swap dleq proof");
continue;
}
// Valid keys, insert.
dleq_msgs.insert(sender, dleq_j);
#[allow(clippy::int_plus_one)]
if dleq_msgs.len() >= t_reconstruction + 1 {
// Enough messages, we can interpolate the remaining public keys, and the group public key
let points: Vec<_> = dleq_msgs
.iter()
.map(|(&j, dleq_j)| (j.into(), dleq_j.g2_sj))
.collect();
let group_pk = lagrange_points_interpolate_at(&points, 0);
let node_pks = node_pks
.iter()
.enumerate()
.map(|(j, _)| {
let j_node_idx = j + 1;
if let Some(pk_j) = dleq_msgs.get(&PartyId::from(j_node_idx)) {
pk_j.g2_sj
} else {
lagrange_points_interpolate_at(&points, u64_from_usize(j_node_idx))
}
})
.collect();
let adkg_out = AdkgOutput {
sk: adkg_output.sk,
used_sessions: adkg_output.used_sessions,
node_pks: Some(node_pks),
group_pk: Some(group_pk),
};
return Ok(adkg_out);
}
}
}

@azixus azixus force-pushed the feat/htadkg branch 2 times, most recently from 5c933b5 to 36ed7e2 Compare September 9, 2025 12:22
Base automatically changed from feat/htadkg to main September 9, 2025 12:45
@azixus azixus force-pushed the feat/adkg-cli/dleq branch from 83a5519 to db37fe3 Compare September 9, 2025 12:46
@azixus azixus merged commit 50ad036 into main Sep 9, 2025
6 checks passed
@azixus azixus deleted the feat/adkg-cli/dleq branch September 9, 2025 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants