convert redpallas keys into even-Y format (#280)

* convert redpallas keys into even-Y format

* clarify docs
This commit is contained in:
Conrado Gouvea 2024-08-13 11:35:22 -03:00 committed by GitHub
parent 0782761505
commit 4503c10790
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 120 additions and 20 deletions

31
Cargo.lock generated
View File

@ -416,7 +416,7 @@ dependencies = [
"itertools",
"message-io",
"rand",
"reddsa",
"reddsa 0.5.1 (git+https://github.com/ZcashFoundation/reddsa.git?rev=4d8c4bb337231e6e89117334d7c61dada589a953)",
"reqwest",
"serde_json",
"server",
@ -579,7 +579,7 @@ dependencies = [
"itertools",
"pipe",
"rand",
"reddsa",
"reddsa 0.5.1 (git+https://github.com/ZcashFoundation/reddsa.git?rev=4d8c4bb337231e6e89117334d7c61dada589a953)",
"serde_json",
"thiserror",
]
@ -1415,7 +1415,7 @@ dependencies = [
"hex",
"message-io",
"rand",
"reddsa",
"reddsa 0.5.1 (git+https://github.com/ZcashFoundation/reddsa.git?rev=4d8c4bb337231e6e89117334d7c61dada589a953)",
"reqwest",
"serde_json",
"server",
@ -1597,6 +1597,24 @@ dependencies = [
"zeroize",
]
[[package]]
name = "reddsa"
version = "0.5.1"
source = "git+https://github.com/ZcashFoundation/reddsa.git?rev=56a31af7099b95737031ef6cf251939ed99627c0#56a31af7099b95737031ef6cf251939ed99627c0"
dependencies = [
"blake2b_simd",
"byteorder",
"frost-rerandomized",
"group",
"hex",
"jubjub",
"pasta_curves",
"rand_core",
"serde",
"thiserror",
"zeroize",
]
[[package]]
name = "redox_syscall"
version = "0.5.3"
@ -1935,7 +1953,7 @@ dependencies = [
"frost-ed25519",
"frost-rerandomized",
"rand",
"reddsa",
"reddsa 0.5.1 (git+https://github.com/ZcashFoundation/reddsa.git?rev=4d8c4bb337231e6e89117334d7c61dada589a953)",
"regex",
"reqwest",
"serde",
@ -2152,7 +2170,7 @@ dependencies = [
"hex",
"participant",
"rand",
"reddsa",
"reddsa 0.5.1 (git+https://github.com/ZcashFoundation/reddsa.git?rev=4d8c4bb337231e6e89117334d7c61dada589a953)",
"serde_json",
"server",
"tokio",
@ -2433,10 +2451,11 @@ dependencies = [
"exitcode",
"frost-core",
"frost-ed25519",
"frost-rerandomized",
"hex",
"itertools",
"rand",
"reddsa",
"reddsa 0.5.1 (git+https://github.com/ZcashFoundation/reddsa.git?rev=56a31af7099b95737031ef6cf251939ed99627c0)",
"serde_json",
"thiserror",
]

View File

@ -1,12 +1,45 @@
use frost_core::keys::{KeyPackage, PublicKeyPackage};
use frost_core::{self as frost, Ciphersuite};
use rand::thread_rng;
use reddsa::frost::redpallas::keys::EvenY;
use std::collections::BTreeMap;
use std::io::{BufRead, Write};
use crate::inputs::{read_round1_package, read_round2_package, request_inputs};
pub fn cli<C: Ciphersuite + 'static>(
// The redpallas ciphersuite, when used for generating Orchard spending key
// signatures, requires ensuring public key have an even Y coordinate. Since the
// code uses generics, this trait is used to convert if needed depending on the
// ciphersuite.
//
// If you are adding a new ciphersuite to this tool which does note require
// this, just implement it and the default implementation (which does nothing)
// will suffice. See below.
pub trait MaybeIntoEvenY: Ciphersuite {
fn into_even_y(
key_packages: (KeyPackage<Self>, PublicKeyPackage<Self>),
) -> (KeyPackage<Self>, PublicKeyPackage<Self>) {
key_packages
}
}
// A ciphersuite that does not need the conversion.
impl MaybeIntoEvenY for frost_ed25519::Ed25519Sha512 {}
impl MaybeIntoEvenY for reddsa::frost::redpallas::PallasBlake2b512 {
fn into_even_y(
(key_package, public_key_package): (KeyPackage<Self>, PublicKeyPackage<Self>),
) -> (KeyPackage<Self>, PublicKeyPackage<Self>) {
let is_even = public_key_package.has_even_y();
(
key_package.into_even_y(Some(is_even)),
public_key_package.into_even_y(Some(is_even)),
)
}
}
pub fn cli<C: Ciphersuite + 'static + MaybeIntoEvenY>(
reader: &mut impl BufRead,
logger: &mut impl Write,
) -> Result<(), Box<dyn std::error::Error>> {
@ -75,11 +108,11 @@ pub fn cli<C: Ciphersuite + 'static>(
writeln!(logger, "=== DKG FINISHED ===")?;
let (key_package, public_key_package) = frost::keys::dkg::part3(
let (key_package, public_key_package) = MaybeIntoEvenY::into_even_y(frost::keys::dkg::part3(
&round2_secret_package,
&received_round1_packages,
&received_round2_packages,
)?;
)?);
writeln!(
logger,

View File

@ -1,6 +1,6 @@
use frost_core::{self as frost, Ciphersuite};
use dkg::cli::cli;
use dkg::cli::{cli, MaybeIntoEvenY};
use std::collections::HashMap;
use std::io::{BufRead, Write};
@ -35,7 +35,7 @@ fn check_dkg() {
}
#[allow(clippy::needless_range_loop)]
fn check_dkg_for_ciphersuite<C: Ciphersuite + 'static>() {
fn check_dkg_for_ciphersuite<C: Ciphersuite + 'static + MaybeIntoEvenY>() {
let mut input_writers = Vec::new();
let mut output_readers = Vec::new();
let mut join_handles = Vec::new();

View File

@ -7,8 +7,9 @@ edition = "2021"
[dependencies]
frost-core = { version = "2.0.0-rc.0", features = ["serde"] }
frost-rerandomized = { version = "2.0.0-rc.0", features = ["serde"] }
frost-ed25519 = { version = "2.0.0-rc.0", features = ["serde"] }
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "4d8c4bb337231e6e89117334d7c61dada589a953", features = ["frost"] }
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "56a31af7099b95737031ef6cf251939ed99627c0", features = ["frost"] }
clap = { version = "4.5.13", features = ["derive"] }
thiserror = "1.0"
rand = "0.8"

View File

@ -1,14 +1,61 @@
use frost_core::keys::IdentifierList;
use frost_core::Ciphersuite;
use rand::thread_rng;
use std::collections::BTreeMap;
use std::io::{BufRead, Write};
use frost_core::keys::{IdentifierList, PublicKeyPackage, SecretShare};
use frost_core::{Ciphersuite, Identifier};
use reddsa::frost::redpallas::keys::EvenY;
use crate::args::Args;
use crate::inputs::{print_values, request_inputs};
use crate::trusted_dealer_keygen::{split_secret, trusted_dealer_keygen};
// Currently this uses the Default Identifiers
pub fn cli<C: Ciphersuite + 'static>(
// The redpallas ciphersuite, when used for generating Orchard spending key
// signatures, requires ensuring public key have an even Y coordinate. Since the
// code uses generics, this trait is used to convert if needed depending on the
// ciphersuite.
//
// If you are adding a new ciphersuite to this tool which does note require
// this, just implement it and the default implementation (which does nothing)
// will suffice. See below.
pub trait MaybeIntoEvenY: Ciphersuite {
fn into_even_y(
secret_shares_and_public_key_package: (
BTreeMap<Identifier<Self>, SecretShare<Self>>,
PublicKeyPackage<Self>,
),
) -> (
BTreeMap<Identifier<Self>, SecretShare<Self>>,
PublicKeyPackage<Self>,
) {
secret_shares_and_public_key_package
}
}
// A ciphersuite that does not need the conversion.
impl MaybeIntoEvenY for frost_ed25519::Ed25519Sha512 {}
impl MaybeIntoEvenY for reddsa::frost::redpallas::PallasBlake2b512 {
fn into_even_y(
(secret_shares, public_key_package): (
BTreeMap<Identifier<Self>, SecretShare<Self>>,
PublicKeyPackage<Self>,
),
) -> (
BTreeMap<Identifier<Self>, SecretShare<Self>>,
PublicKeyPackage<Self>,
) {
let is_even = public_key_package.has_even_y();
let public_key_package = public_key_package.into_even_y(Some(is_even));
let secret_shares = secret_shares
.iter()
.map(|(i, s)| (*i, s.clone().into_even_y(Some(is_even))))
.collect();
(secret_shares, public_key_package)
}
}
pub fn cli<C: Ciphersuite + 'static + MaybeIntoEvenY>(
args: &Args,
input: &mut impl BufRead,
logger: &mut impl Write,
@ -17,13 +64,13 @@ pub fn cli<C: Ciphersuite + 'static>(
let mut rng = thread_rng();
let keygen = if config.secret.is_empty() {
trusted_dealer_keygen(&config, IdentifierList::<C>::Default, &mut rng)
let shares_and_package = if config.secret.is_empty() {
trusted_dealer_keygen(&config, IdentifierList::<C>::Default, &mut rng)?
} else {
split_secret(&config, IdentifierList::<C>::Default, &mut rng)
split_secret(&config, IdentifierList::<C>::Default, &mut rng)?
};
let (shares, pubkeys) = keygen?;
let (shares, pubkeys) = MaybeIntoEvenY::into_even_y(shares_and_package);
print_values(args, &shares, &pubkeys, logger)?;