use per-signer Rho per V7 spec (#112)

* use per-signer Rho per V7 spec

* Update frost-core/src/frost.rs

* Update frost-core/src/frost.rs

Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
This commit is contained in:
Conrado Gouvea 2022-10-03 05:13:25 -03:00 committed by GitHub
parent 50f9524d4c
commit 57bf58a24e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 151 additions and 82 deletions

View File

@ -14,6 +14,7 @@ use std::{
collections::HashMap,
convert::TryFrom,
fmt::{self, Debug},
ops::Index,
};
use hex::FromHex;
@ -64,19 +65,62 @@ where
}
}
impl<C> From<&SigningPackage<C>> for Rho<C>
/// A list of binding factors and their associated identifiers.
#[derive(Clone)]
pub struct BindingFactorList<C: Ciphersuite>(Vec<(Identifier<C>, Rho<C>)>);
impl<C> BindingFactorList<C>
where
C: Ciphersuite,
{
// [`compute_binding_factor`] in the spec
/// Return iterator through all factors.
pub fn iter(&self) -> impl Iterator<Item = &(Identifier<C>, Rho<C>)> {
self.0.iter()
}
}
impl<C> Index<Identifier<C>> for BindingFactorList<C>
where
C: Ciphersuite,
{
type Output = Rho<C>;
// Get the binding factor of a participant in the list.
//
// [`compute_binding_factor`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-03.html#section-4.4
fn from(signing_package: &SigningPackage<C>) -> Rho<C> {
let preimage = signing_package.rho_preimage();
// [`binding_factor_for_participant`] in the spec
//
// [`binding_factor_for_participant`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-07.html#section-4.3
// TODO: switch from Vec to BTreeMap, as this can be made more efficient.
fn index(&self, identifier: Identifier<C>) -> &Self::Output {
for (i, factor) in self.0.iter() {
if *i == identifier {
return factor;
}
}
// The protocol should abort here, but can we do something nicer than a panic?
panic!("invalid identifier passed");
}
}
let binding_factor = C::H1(&preimage[..]);
impl<C> From<&SigningPackage<C>> for BindingFactorList<C>
where
C: Ciphersuite,
{
// [`compute_binding_factors`] in the spec
//
// [`compute_binding_factors`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-07.html#section-4.4
fn from(signing_package: &SigningPackage<C>) -> BindingFactorList<C> {
let preimages = signing_package.rho_preimages();
Rho(binding_factor)
BindingFactorList(
preimages
.iter()
.map(|(identifier, preimage)| {
let binding_factor = C::H1(preimage);
(*identifier, Rho(binding_factor))
})
.collect(),
)
}
}
@ -184,16 +228,26 @@ where
&self.message
}
/// Compute the preimage to H3 to compute rho
/// Compute the preimages to H3 to compute the per-signer rhos
// We separate this out into its own method so it can be tested
pub fn rho_preimage(&self) -> Vec<u8> {
let mut preimage = vec![];
pub fn rho_preimages(&self) -> Vec<(Identifier<C>, Vec<u8>)> {
let mut rho_input_prefix = vec![];
preimage
.extend_from_slice(&round1::encode_group_commitments(self.signing_commitments())[..]);
preimage.extend_from_slice(C::H3(self.message.as_slice()).as_ref());
rho_input_prefix.extend_from_slice(C::H3(self.message.as_slice()).as_ref());
rho_input_prefix.extend_from_slice(
C::H3(&round1::encode_group_commitments(self.signing_commitments())[..]).as_ref(),
);
preimage
self.signing_commitments()
.iter()
.map(|c| {
let mut rho_input = vec![];
rho_input.extend_from_slice(&rho_input_prefix);
rho_input.extend_from_slice(&u16::from(c.identifier).to_be_bytes());
(c.identifier, rho_input)
})
.collect()
}
}
@ -223,12 +277,11 @@ where
///
/// [`compute_group_commitment`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-03.html#section-4.4
fn try_from(signing_package: &SigningPackage<C>) -> Result<GroupCommitment<C>, &'static str> {
let rho: Rho<C> = signing_package.into();
let binding_factor_list: BindingFactorList<C> = signing_package.into();
let identity = <C::Group as Group>::identity();
let mut group_hiding_commitment = <C::Group as Group>::identity();
let mut group_binding_commitment = <C::Group as Group>::identity();
let mut group_commitment = <C::Group as Group>::identity();
// Ala the sorting of B, just always sort by identifier in ascending order
//
@ -239,13 +292,14 @@ where
if identity == commitment.binding.0 || identity == commitment.hiding.0 {
return Err("Commitment equals the identity.");
}
group_hiding_commitment = group_hiding_commitment + commitment.hiding.0;
group_binding_commitment = group_binding_commitment + commitment.binding.0;
let binding_factor = binding_factor_list[commitment.identifier].clone();
group_commitment = group_commitment
+ (commitment.hiding.0 + (commitment.binding.0 * binding_factor.0));
}
Ok(GroupCommitment(
group_hiding_commitment + group_binding_commitment * rho.0,
))
Ok(GroupCommitment(group_commitment))
}
}
@ -278,7 +332,7 @@ where
{
// Encodes the signing commitment list produced in round one as part of generating [`Rho`], the
// binding factor.
let rho: Rho<C> = signing_package.into();
let binding_factor_list: BindingFactorList<C> = signing_package.into();
// Compute the group commitment from signing commitments produced in round one.
let group_commitment = GroupCommitment::<C>::try_from(signing_package)?;
@ -302,6 +356,8 @@ where
// Compute Lagrange coefficient.
let lambda_i = derive_lagrange_coeff(&signature_share.identifier, signing_package)?;
let rho = binding_factor_list[signature_share.identifier].clone();
// Compute the commitment share.
let R_share = signing_package
.signing_commitment(&signature_share.identifier)

View File

@ -135,7 +135,8 @@ pub fn sign<C: Ciphersuite>(
) -> Result<SignatureShare<C>, &'static str> {
// Encodes the signing commitment list produced in round one as part of generating [`Rho`], the
// binding factor.
let rho: frost::Rho<C> = signing_package.into();
let binding_factor_list: frost::BindingFactorList<C> = signing_package.into();
let rho: frost::Rho<C> = binding_factor_list[key_package.identifier].clone();
// Compute the group commitment from signing commitments produced in round one.
let group_commitment = GroupCommitment::<C>::try_from(signing_package)?;

View File

@ -20,8 +20,8 @@ pub fn parse_test_vectors<C: Ciphersuite>(
Vec<u8>,
HashMap<Identifier<C>, SigningNonces<C>>,
HashMap<Identifier<C>, SigningCommitments<C>>,
Vec<u8>,
Rho<C>,
HashMap<Identifier<C>, Vec<u8>>,
HashMap<Identifier<C>, Rho<C>>,
HashMap<Identifier<C>, SignatureShare<C>>,
Vec<u8>, // Signature<C>,
) {
@ -59,18 +59,10 @@ pub fn parse_test_vectors<C: Ciphersuite>(
let round_one_outputs = &json_vectors["round_one_outputs"];
let group_binding_factor_input = Vec::<u8>::from_hex(
round_one_outputs["group_binding_factor_input"]
.as_str()
.unwrap(),
)
.unwrap();
let group_binding_factor =
Rho::<C>::from_hex(round_one_outputs["group_binding_factor"].as_str().unwrap()).unwrap();
let mut signer_nonces: HashMap<Identifier<C>, SigningNonces<C>> = HashMap::new();
let mut signer_commitments: HashMap<Identifier<C>, SigningCommitments<C>> = HashMap::new();
let mut binding_factor_inputs: HashMap<Identifier<C>, Vec<u8>> = HashMap::new();
let mut binding_factors: HashMap<Identifier<C>, Rho<C>> = HashMap::new();
for (i, signer) in round_one_outputs["signers"].as_object().unwrap().iter() {
let identifier = u16::from_str(i).unwrap().try_into().unwrap();
@ -93,6 +85,16 @@ pub fn parse_test_vectors<C: Ciphersuite>(
};
signer_commitments.insert(identifier, signing_commitments);
let binding_factor_input =
Vec::<u8>::from_hex(signer["binding_factor_input"].as_str().unwrap()).unwrap();
binding_factor_inputs.insert(identifier, binding_factor_input);
let binding_factor =
Rho::<C>::from_hex(signer["binding_factor"].as_str().unwrap()).unwrap();
binding_factors.insert(identifier, binding_factor);
}
// Round two outputs
@ -132,8 +134,8 @@ pub fn parse_test_vectors<C: Ciphersuite>(
message_bytes,
signer_nonces,
signer_commitments,
group_binding_factor_input,
group_binding_factor,
binding_factor_inputs,
binding_factors,
signature_shares,
signature_bytes,
)
@ -147,8 +149,8 @@ pub fn check_sign_with_test_vectors<C: Ciphersuite>(json_vectors: &Value) {
message_bytes,
signer_nonces,
signer_commitments,
group_binding_factor_input,
group_binding_factor,
binding_factor_inputs,
binding_factors,
signature_shares,
signature_bytes,
) = parse_test_vectors(json_vectors);
@ -195,11 +197,15 @@ pub fn check_sign_with_test_vectors<C: Ciphersuite>(json_vectors: &Value) {
let signing_package = frost::SigningPackage::new(signer_commitments_vec, message_bytes);
assert_eq!(signing_package.rho_preimage(), group_binding_factor_input);
for (identifier, input) in signing_package.rho_preimages().iter() {
assert_eq!(*input, binding_factor_inputs[identifier]);
}
let rho: frost::Rho<C> = (&signing_package).into();
let rho_list: frost::BindingFactorList<C> = (&signing_package).into();
assert_eq!(rho, group_binding_factor);
for (identifier, rho) in rho_list.iter() {
assert_eq!(*rho, binding_factors[identifier]);
}
let mut our_signature_shares: Vec<frost::round2::SignatureShare<C>> = Vec::new();

View File

@ -25,20 +25,22 @@
},
"round_one_outputs": {
"participants": "1,3",
"group_binding_factor_input": "00015c01341bd0a948e71fe1b9bf09f8b8ee258bfcf3abddee42ef74c8068e0b224584a209c6c3e812283378fb6a15e4b9a64aa9eed51f7ae405d09b56ee56bc58500003c0fc5ffaf124fa69206a9ed77bd57fa1d8ca505f6139794f82778ce15ee0be3cb6718f8139e49d08741ab9f030da29e557451eab58bc770c0c05ef4e2ff8001e678630bf982c566949d7f22d2aefb94f252c664216d332f34e2c8fdcd7045f207f854504d0daa534a5b31dbdf4183be30eb4fdba4f962d8a6b69cf20c2734043",
"group_binding_factor": "af4288aad52765341b2238007777ea2bb2d0dfb4e92423b0646d4bec426e3d0d",
"signers": {
"1": {
"hiding_nonce": "b358743151e33d84bf00c12f71808f4103957c3e2cabab7b895c436b5e70f90c",
"binding_nonce": "7bd112153b9ae1ab9b31f5e78f61f5c4ca9ee67b7ea6d1181799c409d14c350c",
"hiding_nonce_commitment": "5c01341bd0a948e71fe1b9bf09f8b8ee258bfcf3abddee42ef74c8068e0b2245",
"binding_nonce_commitment": "84a209c6c3e812283378fb6a15e4b9a64aa9eed51f7ae405d09b56ee56bc5850"
"hiding_nonce": "eb0dc12ae7b746d36e3f2de46ce3833a05b9d4af5434eeb8cafaefda76906d00",
"binding_nonce": "491e91aa9df514ef598d5e0c7c5cdd088fbde4965b96069d546c0f04f1822b03",
"hiding_nonce_commitment": "c6fe28df6a13f2ea80a911dd7a284e4b185bc8d3e3102adaf88807a5e3d3813c",
"binding_nonce_commitment": "a413722bcfc71ba044bb2846b814401e60fed6b2fc5bfb25f5a49e63474b7011",
"binding_factor_input": "678630bf982c566949d7f22d2aefb94f252c664216d332f34e2c8fdcd7045f207f854504d0daa534a5b31dbdf4183be30eb4fdba4f962d8a6b69cf20c2734043c229faa47541463641bcc7c23a4576d74e536dea0d7f7ae6e2c8461a63f4fe97599d8d83005d520a104f937ce3b8181281348fad246e1c0d89ed4cca7d522e750001",
"binding_factor": "2e81f15e28874f517b6d2023291e49000f71f998852b484aaef945000478ea05"
},
"3": {
"hiding_nonce": "22acad88478e0d0373a991092a322ebd1b9a2dad90451a976d0db3215426af0e",
"binding_nonce": "9155e3d7bcf7cd468b980c7e20b2c77cbdfbe33a1dcae031fd8bc6b1403f4b04",
"hiding_nonce_commitment": "c0fc5ffaf124fa69206a9ed77bd57fa1d8ca505f6139794f82778ce15ee0be3c",
"binding_nonce_commitment": "b6718f8139e49d08741ab9f030da29e557451eab58bc770c0c05ef4e2ff8001e"
"hiding_nonce": "abd12b8e6f255ee1e540eab029003a6e956567617720f61115f0941615892209",
"binding_nonce": "218e22625f93f262f025bd2d13c46ba722aa29fe585ceed66ff442d98fe4e509",
"hiding_nonce_commitment": "5450c4c98c3fc6bb579bded17fcdc23073d2ecfb761e3f9433cbc991e1496068",
"binding_nonce_commitment": "0ae0cf608fcba285ec1f6c84c955572c91a4fafcc1f1120f4f30b25e40fbcc0a",
"binding_factor_input": "678630bf982c566949d7f22d2aefb94f252c664216d332f34e2c8fdcd7045f207f854504d0daa534a5b31dbdf4183be30eb4fdba4f962d8a6b69cf20c2734043c229faa47541463641bcc7c23a4576d74e536dea0d7f7ae6e2c8461a63f4fe97599d8d83005d520a104f937ce3b8181281348fad246e1c0d89ed4cca7d522e750003",
"binding_factor": "240d5257c68e377c1994481081a8a4c4362b9e82e523088c30d91f8c2811890e"
}
}
},
@ -46,14 +48,14 @@
"participants": "1,3",
"signers": {
"1": {
"sig_share": "ff801b4e0839faa67f16dee4127b9f7fbcf5fd007900257b0e2bbc02cbe5e709"
"sig_share": "efae3a83437fa8cd96194aacc56a7eb841630c280da99e7764a81d1340323306"
},
"3": {
"sig_share": "afdf5481023c855bf3411a5c8a5fafa92357296a078c3b80dc168f294cb4f504"
"sig_share": "96ddc4582e45eabce46f07b9e9375f8b49d35d1510fd34ac02b1e79d6100a602"
}
}
},
"final_output": {
"sig": "deae61af10e8ee48ba492573592fba547f5debeff6bd6e2024e8673584746f5eae6070cf0a757f027358f8409dda4e29e04c276b808c60fbea414b2c179add0e"
"sig": "7ec584cef9a383afb43883b73bcaa6313afe878bd5fe75a608311b866a76ec67858cffdb71c4928a7b895165afa2dd438b366a3d1da6d323675905b1a132d908"
}
}

View File

@ -25,20 +25,22 @@
},
"round_one_outputs": {
"participants": "1,3",
"group_binding_factor_input": "000102688facca4e2540ef303734c5aee8e7cdba0bc7ab94abfe63d05ebc68dde0f4c702ae64b6f0506acc3395fecd4bc70a9eb9f8e5394264c2d2aa0c8faff857ea3058000303c21b8ee50b6478ac845c0687504db6792873f5a327ff6a3115558070b517299302f3c73c912838f707f549bf4d63432f1fbe128fa35ec8ba6eca849ebd248aa46a7a753fed12531fbcd151e1d84702927c39063e780e91c01f02bd11b60d7632bf",
"group_binding_factor": "cf7ffe4b8ad6edb6237efaa8cbfb2dfb2fd08d163b6ad9063720f14779a9e143",
"signers": {
"1": {
"hiding_nonce": "081617b24375e069b39f649d4c4ce2fba6e38b73e7c16759de0b6079a22c4c7e",
"binding_nonce": "4de5fb77d99f03a2491a83a6a4cb91ca3c82a3f34ce94cec939174f47c9f95dd",
"hiding_nonce_commitment": "02688facca4e2540ef303734c5aee8e7cdba0bc7ab94abfe63d05ebc68dde0f4c7",
"binding_nonce_commitment": "02ae64b6f0506acc3395fecd4bc70a9eb9f8e5394264c2d2aa0c8faff857ea3058"
"hiding_nonce": "33a519cf070a166f9ef41a798d03423743f3e7d0b0efd5d0d963773c4c53205e",
"binding_nonce": "307d208d0c5728f323ae374f1ebd7f14a1a49b77d9d4bc1eab222218a17765ff",
"hiding_nonce_commitment": "021e5c8b286dc859314eb1c0a2024a2077ad49b603112dd7bfaf326591d3fab332",
"binding_nonce_commitment": "039431f230cf2bd90ad556a7f3d6b5a5686efd194c863356628d7296c2a3fa5900",
"binding_factor_input": "7a753fed12531fbcd151e1d84702927c39063e780e91c01f02bd11b60d7632bf44df5a9e0d49f359549018a13a586b5ede02cadef80472f75d195b82160f43ea0001",
"binding_factor": "71f09a2c4a1fc2f7a1379102809b4ac3247837c532cc5cf0913782496c515655"
},
"3": {
"hiding_nonce": "d186ea92593f83ea83181b184d41aa93493301ac2bc5b4b1767e94d2db943e38",
"binding_nonce": "486e2ee25a3fbc8e6399d748b077a2755fde99fa85cc24fa647ea4ebf5811a15",
"hiding_nonce_commitment": "03c21b8ee50b6478ac845c0687504db6792873f5a327ff6a3115558070b5172993",
"binding_nonce_commitment": "02f3c73c912838f707f549bf4d63432f1fbe128fa35ec8ba6eca849ebd248aa46a"
"hiding_nonce": "a614eadb972dc37b88aeceb6e899903f3104742d13f379a0e014541decbea4a4",
"binding_nonce": "e509791018504c5bb87edaf0f44761cc840888507c4cd80237971d78e65f70f2",
"hiding_nonce_commitment": "0282308b1a22eb8efa13d4655f795f1cbf6525d8863ac0d60c4e164b7436d41778",
"binding_nonce_commitment": "036549bda4158ec5f76611275360a57e6ad5007d6c072462feb42c8f2a25ec94ea",
"binding_factor_input": "7a753fed12531fbcd151e1d84702927c39063e780e91c01f02bd11b60d7632bf44df5a9e0d49f359549018a13a586b5ede02cadef80472f75d195b82160f43ea0003",
"binding_factor": "57a1061da0837cc0cd7e901a1d33f46efa18af9c3e6468cca88edd2d4a16e78d"
}
}
},
@ -46,14 +48,14 @@
"participants": "1,3",
"signers": {
"1": {
"sig_share": "9e4d8865faf8c7b3193a3b35eda3d9e12118447114b1e7d5b4809ea28067f8a9"
"sig_share": "61e8b9c474df2e66ad19fd80a6e6cec1c6fe43c0a1cffd2d1c28299e93e1bbdb"
},
"3": {
"sig_share": "b7d094eab6305ae74daeed1acd31abba9ab81f638d38b72c132cb25a5dfae1fc"
"sig_share": "9651d355ca1dea2557ba1f73e38a9f4ff1f1afc565323ef27f88a9d14df8370e"
}
}
},
"final_output": {
"sig": "0342c14c77f9d4ef9b8bd64fb0d7bbfdb9f8216a44e5f7bbe6ac0f3ed5e1a57367561e1d51b129229966e92850bad5859bfee96926fad3007cd3f38639e1ffb554"
"sig": "02dfba781e17b830229ae4ed22ebe402873683d9dfd945d01762217fb3172c2a71f83a8d1a3efd188c04d41cf48a716e11b8eff38607023c1f9bb0d36fe1d9f2e9"
}
}

View File

@ -25,20 +25,22 @@
},
"round_one_outputs": {
"participants": "1,3",
"group_binding_factor_input": "00015c01341bd0a948e71fe1b9bf09f8b8ee258bfcf3abddee42ef74c8068e0b224584a209c6c3e812283378fb6a15e4b9a64aa9eed51f7ae405d09b56ee56bc58500003c0fc5ffaf124fa69206a9ed77bd57fa1d8ca505f6139794f82778ce15ee0be3cb6718f8139e49d08741ab9f030da29e557451eab58bc770c0c05ef4e2ff8001e678630bf982c566949d7f22d2aefb94f252c664216d332f34e2c8fdcd7045f207f854504d0daa534a5b31dbdf4183be30eb4fdba4f962d8a6b69cf20c2734043",
"group_binding_factor": "af4288aad52765341b2238007777ea2bb2d0dfb4e92423b0646d4bec426e3d0d",
"signers": {
"1": {
"hiding_nonce": "b358743151e33d84bf00c12f71808f4103957c3e2cabab7b895c436b5e70f90c",
"binding_nonce": "7bd112153b9ae1ab9b31f5e78f61f5c4ca9ee67b7ea6d1181799c409d14c350c",
"hiding_nonce_commitment": "5c01341bd0a948e71fe1b9bf09f8b8ee258bfcf3abddee42ef74c8068e0b2245",
"binding_nonce_commitment": "84a209c6c3e812283378fb6a15e4b9a64aa9eed51f7ae405d09b56ee56bc5850"
"hiding_nonce": "eb0dc12ae7b746d36e3f2de46ce3833a05b9d4af5434eeb8cafaefda76906d00",
"binding_nonce": "491e91aa9df514ef598d5e0c7c5cdd088fbde4965b96069d546c0f04f1822b03",
"hiding_nonce_commitment": "c6fe28df6a13f2ea80a911dd7a284e4b185bc8d3e3102adaf88807a5e3d3813c",
"binding_nonce_commitment": "a413722bcfc71ba044bb2846b814401e60fed6b2fc5bfb25f5a49e63474b7011",
"binding_factor_input": "678630bf982c566949d7f22d2aefb94f252c664216d332f34e2c8fdcd7045f207f854504d0daa534a5b31dbdf4183be30eb4fdba4f962d8a6b69cf20c2734043c229faa47541463641bcc7c23a4576d74e536dea0d7f7ae6e2c8461a63f4fe97599d8d83005d520a104f937ce3b8181281348fad246e1c0d89ed4cca7d522e750001",
"binding_factor": "2e81f15e28874f517b6d2023291e49000f71f998852b484aaef945000478ea05"
},
"3": {
"hiding_nonce": "22acad88478e0d0373a991092a322ebd1b9a2dad90451a976d0db3215426af0e",
"binding_nonce": "9155e3d7bcf7cd468b980c7e20b2c77cbdfbe33a1dcae031fd8bc6b1403f4b04",
"hiding_nonce_commitment": "c0fc5ffaf124fa69206a9ed77bd57fa1d8ca505f6139794f82778ce15ee0be3c",
"binding_nonce_commitment": "b6718f8139e49d08741ab9f030da29e557451eab58bc770c0c05ef4e2ff8001e"
"hiding_nonce": "abd12b8e6f255ee1e540eab029003a6e956567617720f61115f0941615892209",
"binding_nonce": "218e22625f93f262f025bd2d13c46ba722aa29fe585ceed66ff442d98fe4e509",
"hiding_nonce_commitment": "5450c4c98c3fc6bb579bded17fcdc23073d2ecfb761e3f9433cbc991e1496068",
"binding_nonce_commitment": "0ae0cf608fcba285ec1f6c84c955572c91a4fafcc1f1120f4f30b25e40fbcc0a",
"binding_factor_input": "678630bf982c566949d7f22d2aefb94f252c664216d332f34e2c8fdcd7045f207f854504d0daa534a5b31dbdf4183be30eb4fdba4f962d8a6b69cf20c2734043c229faa47541463641bcc7c23a4576d74e536dea0d7f7ae6e2c8461a63f4fe97599d8d83005d520a104f937ce3b8181281348fad246e1c0d89ed4cca7d522e750003",
"binding_factor": "240d5257c68e377c1994481081a8a4c4362b9e82e523088c30d91f8c2811890e"
}
}
},
@ -46,14 +48,14 @@
"participants": "1,3",
"signers": {
"1": {
"sig_share": "ff801b4e0839faa67f16dee4127b9f7fbcf5fd007900257b0e2bbc02cbe5e709"
"sig_share": "efae3a83437fa8cd96194aacc56a7eb841630c280da99e7764a81d1340323306"
},
"3": {
"sig_share": "afdf5481023c855bf3411a5c8a5fafa92357296a078c3b80dc168f294cb4f504"
"sig_share": "96ddc4582e45eabce46f07b9e9375f8b49d35d1510fd34ac02b1e79d6100a602"
}
}
},
"final_output": {
"sig": "deae61af10e8ee48ba492573592fba547f5debeff6bd6e2024e8673584746f5eae6070cf0a757f027358f8409dda4e29e04c276b808c60fbea414b2c179add0e"
"sig": "7ec584cef9a383afb43883b73bcaa6313afe878bd5fe75a608311b866a76ec67858cffdb71c4928a7b895165afa2dd438b366a3d1da6d323675905b1a132d908"
}
}