Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to tapyrus-setup sign and createsig commands to sign xfield #169

Merged
merged 8 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2018"

[dependencies]
http = "0.1.17"
tapyrus = { git = "https://github.com/chaintope/rust-tapyrus", tag = "v0.4.5", features = ["use-serde", "rand"] }
tapyrus = { version = "0.4.8", features = ["use-serde", "rand"] }
secp256k1 = "0.15.3"
log = "0.4.6"
env_logger = "0.9.0"
Expand Down
32 changes: 28 additions & 4 deletions src/bin/tapyrus-signerd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ mod tests {
#[test]
fn test_load_federations() {
let pubkey = PublicKey::from_str(
"02472012cf49fca573ca1f63deafe59df842f0bbe77e9ac7e67b211bb074b72506",
"0315d137054b688717f7fe4bd22a1c886de7a07bf3beb041092fb79688306df3c9",
)
.unwrap();

Expand All @@ -215,6 +215,19 @@ mod tests {
assert_eq!(federations.len(), 2);
}

#[test]
fn test_load_federations_threshold_change() {
let pubkey = PublicKey::from_str(
"0315d137054b688717f7fe4bd22a1c886de7a07bf3beb041092fb79688306df3c9",
)
.unwrap();

let path = Path::new("tests/resources/federations_threshold_change.toml");
let federations = load_federations(&pubkey, path);

assert_eq!(federations.len(), 2);
}

#[test]
#[should_panic(expected = "Can't open federations_file. path: \"/foo/bar/no_exist_file.toml\"")]
fn test_load_federations_invalid_file_path() {
Expand All @@ -229,11 +242,11 @@ mod tests {

#[test]
#[should_panic(
expected = "federations_file: Invalid Federation at 0 height. message: The nodevss has wrong vss which has wrong number of commitments."
expected = "federations_file: Invalid Federation at 20 height. message: The nodevss has wrong vss which has wrong number of commitments."
)]
fn test_load_federations_has_invalid_federation() {
let pubkey = PublicKey::from_str(
"02472012cf49fca573ca1f63deafe59df842f0bbe77e9ac7e67b211bb074b72506",
"0315d137054b688717f7fe4bd22a1c886de7a07bf3beb041092fb79688306df3c9",
)
.unwrap();

Expand All @@ -243,7 +256,7 @@ mod tests {

#[test]
#[should_panic(
expected = "federations_file: Invalid TOML format. missing field `aggregated-public-key` for key `federation` at line 12 column 1"
expected = "federations_file: Invalid Federation at 100 height. message: No xfield in federation. Aggregated pubkey or max block size is expected"
)]
fn test_load_federations_invalid_toml_format() {
let pubkey = PublicKey::from_str(
Expand All @@ -254,4 +267,15 @@ mod tests {
let path = Path::new("tests/resources/federations_invalid_toml_format.toml");
load_federations(&pubkey, path);
}

#[test]
fn test_load_federations_has_max_block_size() {
let pubkey = PublicKey::from_str(
"0302f5584e30d2ee32e772d04ff8ee1efc90a7a91ac5b7c4025da7a42a67d06a25",
)
.unwrap();

let path = Path::new("tests/resources/federations_has_max_block_size.toml");
load_federations(&pubkey, path);
}
}
186 changes: 168 additions & 18 deletions src/cli/setup/compute_sig.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/cli/setup/create_block_vss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl<'a> CreateBlockVssCommand {
.long("threshold")
.required(true)
.takes_value(true)
.help("the minimum number of signers required to sign block"),
.help("the minimum number of signers required to sign block/xfield change"),
])
}
}
Expand Down
179 changes: 165 additions & 14 deletions src/cli/setup/sign.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/crypto/multi_party_schnorr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ impl LocalSig {
}
}

#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Signature {
pub sigma: FE,
pub v: GE,
Expand Down
171 changes: 154 additions & 17 deletions src/crypto/vss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use std::fmt;
use std::io;
use std::str::FromStr;
use tapyrus::blockdata::block::Block;
use tapyrus::blockdata::block::{Block, XField};
use tapyrus::consensus::encode::{self, *};
use tapyrus::util::prime::jacobi;
use tapyrus::{PrivateKey, PublicKey};
Expand Down Expand Up @@ -119,6 +119,32 @@
}

pub fn create_local_sig_from_shares(
_priv_shared_keys: &SharedKeys,
index: usize,
shared_block_secrets: &BidirectionalSharedSecretMap,
local_sig_for_positive: &LocalSig,
local_sig_for_negative: &LocalSig,
) -> Result<(bool, SharedKeys, LocalSig), Error> {
let shared_keys_for_positive =
Sign::verify_vss_and_construct_key(&shared_block_secrets.for_positive(), &index)?;

let shared_keys_for_negative =
Sign::verify_vss_and_construct_key(&shared_block_secrets.for_negative(), &index)?;

let y = shared_keys_for_positive
.y
.y_coor()
.expect("can not get y_coor");
let is_positive = jacobi(&Converter::to_vec(&y)) == 1;
let (shared_keys, local_sig) = if is_positive {
(shared_keys_for_positive, local_sig_for_positive)
} else {
(shared_keys_for_negative, local_sig_for_negative)
};
Ok((is_positive, shared_keys, local_sig.clone()))
}

pub fn create_local_sig_from_shares_for_block(
priv_shared_keys: &SharedKeys,
index: usize,
shared_block_secrets: &BidirectionalSharedSecretMap,
Expand All @@ -139,22 +165,47 @@
&priv_shared_keys,
block.header.signature_hash(),
);
Self::create_local_sig_from_shares(
priv_shared_keys,
index,
shared_block_secrets,
&local_sig_for_positive,
&local_sig_for_negative,
)
}

let y = shared_keys_for_positive
.y
.y_coor()
.expect("can not get y_coor");
let is_positive = jacobi(&Converter::to_vec(&y)) == 1;
let (shared_keys, local_sig) = if is_positive {
(shared_keys_for_positive, local_sig_for_positive)
} else {
(shared_keys_for_negative, local_sig_for_negative)
};
Ok((is_positive, shared_keys, local_sig))
pub fn create_local_sig_from_shares_for_xfield(
priv_shared_keys: &SharedKeys,
index: usize,
shared_block_secrets: &BidirectionalSharedSecretMap,
xfield: &XField,
) -> Result<(bool, SharedKeys, LocalSig), Error> {
let shared_keys_for_positive =
Sign::verify_vss_and_construct_key(&shared_block_secrets.for_positive(), &index)?;
let local_sig_for_positive = Sign::sign_xfield(
&shared_keys_for_positive,
&priv_shared_keys,
xfield.signature_hash()?,
);

let shared_keys_for_negative =
Sign::verify_vss_and_construct_key(&shared_block_secrets.for_negative(), &index)?;
let local_sig_for_negative = Sign::sign_xfield(
&shared_keys_for_negative,
&priv_shared_keys,
xfield.signature_hash()?,
);
Self::create_local_sig_from_shares(
priv_shared_keys,
index,
shared_block_secrets,
&local_sig_for_positive,
&local_sig_for_negative,
)
}

pub fn aggregate_and_verify_signature(
block: &Block,
hash: &[u8],
signatures: BTreeMap<SignerID, (FE, FE)>,
pubkey_list: &Vec<PublicKey>,
shared_secrets: &SharedSecretMap,
Expand Down Expand Up @@ -189,7 +240,6 @@
block_shared_keys.unwrap().2,
);
let public_key = priv_shared_keys.y;
let hash = block.header.signature_hash();
signature.verify(&hash[..], &public_key)?;
Ok(signature)
}
Expand Down Expand Up @@ -544,9 +594,13 @@
})
.collect();

let (is_positive, key, local_sig) =
Vss::create_local_sig_from_shares(&priv_shared_keys, 1, &shared_block_secrets, &block)
.expect("error occurred in Vss::create_local_sig_from_shares");
let (is_positive, key, local_sig) = Vss::create_local_sig_from_shares_for_block(
&priv_shared_keys,
1,
&shared_block_secrets,
&block,
)
.expect("error occurred in Vss::create_local_sig_from_shares");

let expected_localsig = to_local_sig(&v["expected_localsig"]).unwrap();
let expected_block_shared_keys =
Expand All @@ -557,4 +611,87 @@
assert_eq!(key.x_i, expected_block_shared_keys.1);
assert_eq!(key.y, expected_block_shared_keys.2);
}

#[test]
fn test_create_local_sig_from_shares_xfield1() {
let contents = load_test_vector("./tests/resources/vss.json").unwrap();
let v: Value =
serde_json::from_value(contents["create_local_sig_from_shares_successfully"].clone())
.unwrap();
let priv_shared_keys: SharedKeys =
serde_json::from_value(v["priv_shared_key"].clone()).unwrap();
let xfield: XField = XField::AggregatePublicKey(
PublicKey::from_str(
"025700236c2890233592fcef262f4520d22af9160e3d9705855140eb2aa06c35d3",
)
.unwrap(),
);
let shared_block_secrets = v["shared_block_secrets"]
.as_object()
.unwrap()
.iter()
.map(|(k, value)| {
(
to_signer_id(k),
(to_shared_secret(&value[0]), to_shared_secret(&value[1])),
)
})
.collect();

let (is_positive, key, local_sig) = Vss::create_local_sig_from_shares_for_xfield(

Check warning on line 641 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `local_sig`

Check warning on line 641 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `local_sig`

Check warning on line 641 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `local_sig`

Check warning on line 641 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `local_sig`
&priv_shared_keys,
1,
&shared_block_secrets,
&xfield,
)
.expect("error occurred in Vss::create_local_sig_from_shares");

let expected_localsig = to_local_sig(&v["expected_localsig"]).unwrap();

Check warning on line 649 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `expected_localsig`

Check warning on line 649 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `expected_localsig`

Check warning on line 649 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `expected_localsig`

Check warning on line 649 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `expected_localsig`
let expected_block_shared_keys =
to_block_shared_keys(&v["expected_block_shared_keys"]).unwrap();

assert_eq!(false, is_positive);
assert_eq!(key.x_i, expected_block_shared_keys.1);
assert_eq!(key.y, expected_block_shared_keys.2);
//TODO : check signature
}

#[test]
fn test_create_local_sig_from_shares_xfield2() {
let contents = load_test_vector("./tests/resources/vss.json").unwrap();
let v: Value =
serde_json::from_value(contents["create_local_sig_from_shares_successfully"].clone())
.unwrap();
let priv_shared_keys: SharedKeys =
serde_json::from_value(v["priv_shared_key"].clone()).unwrap();
let xfield: XField = XField::MaxBlockSize(100);
let shared_block_secrets = v["shared_block_secrets"]
.as_object()
.unwrap()
.iter()
.map(|(k, value)| {
(
to_signer_id(k),
(to_shared_secret(&value[0]), to_shared_secret(&value[1])),
)
})
.collect();

let (is_positive, key, local_sig) = Vss::create_local_sig_from_shares_for_xfield(

Check warning on line 680 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `local_sig`

Check warning on line 680 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `local_sig`

Check warning on line 680 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `local_sig`

Check warning on line 680 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `local_sig`
&priv_shared_keys,
1,
&shared_block_secrets,
&xfield,
)
.expect("error occurred in Vss::create_local_sig_from_shares");

let expected_localsig = to_local_sig(&v["expected_localsig"]).unwrap();

Check warning on line 688 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `expected_localsig`

Check warning on line 688 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci

unused variable: `expected_localsig`

Check warning on line 688 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `expected_localsig`

Check warning on line 688 in src/crypto/vss.rs

View workflow job for this annotation

GitHub Actions / ci (--features "dump")

unused variable: `expected_localsig`
let expected_block_shared_keys =
to_block_shared_keys(&v["expected_block_shared_keys"]).unwrap();

assert_eq!(false, is_positive);
assert_eq!(key.x_i, expected_block_shared_keys.1);
assert_eq!(key.y, expected_block_shared_keys.2);
//TODO : check signature
}
}
Loading
Loading