From 1d196e58c7c5a23cac72927f170a9311c927234c Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 1 Feb 2023 16:07:15 +0300 Subject: [PATCH 01/11] helper for transmute added --- mithril-stm/src/multi_sig.rs | 53 ++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 29cec451c1e..8cb4860e9d7 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -206,7 +206,7 @@ impl VerificationKeyPoP { }; let result = unsafe { let g1_p = *blst_p1_affine_generator(); - let mvk_p = std::mem::transmute::<&BlstVk, &blst_p2_affine>(&self.vk.0); + let mvk_p = vk_to_p2_affine(&self.vk); let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); let mut k2_p = blst_p1_affine::default(); @@ -308,7 +308,7 @@ impl From<&SigningKey> for ProofOfPossession { use blst::blst_sk_to_pk_in_g1; let k1 = sk.0.sign(POP, &[], &[]); let k2 = unsafe { - let sk_scalar = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); + let sk_scalar = sk_to_scalar(sk); let mut out = blst_p1::default(); blst_sk_to_pk_in_g1(&mut out, sk_scalar); @@ -416,7 +416,7 @@ impl Signature { let mut projective_p2 = blst_p2::default(); blst_p2_from_affine( &mut projective_p2, - &std::mem::transmute::(vk.0), + vk_to_p2_affine(vk), ); projective_p2 }) @@ -428,7 +428,7 @@ impl Signature { let mut projective_p1 = blst_p1::default(); blst_p1_from_affine( &mut projective_p1, - &std::mem::transmute::(sig), + &sig_to_p1_affine(sig), ); projective_p1 }) @@ -440,12 +440,12 @@ impl Signature { let aggr_vk: BlstVk = unsafe { let mut affine_p2 = blst_p2_affine::default(); blst_p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars.as_slice(), 128)); - std::mem::transmute::(affine_p2) + p2_affine_to_vk(affine_p2) }; let aggr_sig: BlstSig = unsafe { let mut affine_p1 = blst_p1_affine::default(); blst_p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars.as_slice(), 128)); - std::mem::transmute::(affine_p1) + p1_affine_to_sig(affine_p1) }; Ok((VerificationKey(aggr_vk), Signature(aggr_sig))) @@ -521,6 +521,47 @@ impl Ord for Signature { } } + + +// --------------------------------------------------------------------- +// Transmute helpers +// --------------------------------------------------------------------- + +pub fn vk_to_p2_affine(vk: &VerificationKey) -> &'static blst_p2_affine { + unsafe { + let result = std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk.0); + return result; + }; +} + +pub fn p2_affine_to_vk(affine_p2: blst_p2_affine) -> BlstVk { + unsafe { + let result = std::mem::transmute::(affine_p2); + return result; + }; +} + +pub fn p1_affine_to_sig(affine_p1: blst_p1_affine) -> BlstSig { + unsafe { + let result = std::mem::transmute::(affine_p1); + return result; + }; +} + +pub fn sig_to_p1_affine(sig: BlstSig) -> blst_p1_affine { + unsafe { + let result = std::mem::transmute::(sig); + return result; + }; +} + +pub fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { + unsafe { + let result = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); + return result; + }; +} + // --------------------------------------------------------------------- // Serde implementation // --------------------------------------------------------------------- From 267ce8b8ba12d9e017502d1b7cfd5fe31f079b90 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 1 Feb 2023 16:29:03 +0300 Subject: [PATCH 02/11] clippy errors corrected --- mithril-stm/src/multi_sig.rs | 41 ++++++++---------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 8cb4860e9d7..39f82f4bbb5 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -414,10 +414,7 @@ impl Signature { .iter() .map(|vk| unsafe { let mut projective_p2 = blst_p2::default(); - blst_p2_from_affine( - &mut projective_p2, - vk_to_p2_affine(vk), - ); + blst_p2_from_affine(&mut projective_p2, vk_to_p2_affine(vk)); projective_p2 }) .collect(); @@ -426,10 +423,7 @@ impl Signature { .iter() .map(|&sig| unsafe { let mut projective_p1 = blst_p1::default(); - blst_p1_from_affine( - &mut projective_p1, - &sig_to_p1_affine(sig), - ); + blst_p1_from_affine(&mut projective_p1, &sig_to_p1_affine(sig)); projective_p1 }) .collect(); @@ -521,45 +515,28 @@ impl Ord for Signature { } } - - // --------------------------------------------------------------------- // Transmute helpers // --------------------------------------------------------------------- pub fn vk_to_p2_affine(vk: &VerificationKey) -> &'static blst_p2_affine { - unsafe { - let result = std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk.0); - return result; - }; + unsafe { std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk.0) } } pub fn p2_affine_to_vk(affine_p2: blst_p2_affine) -> BlstVk { - unsafe { - let result = std::mem::transmute::(affine_p2); - return result; - }; + unsafe { std::mem::transmute::(affine_p2) } } pub fn p1_affine_to_sig(affine_p1: blst_p1_affine) -> BlstSig { - unsafe { - let result = std::mem::transmute::(affine_p1); - return result; - }; + unsafe { std::mem::transmute::(affine_p1) } } -pub fn sig_to_p1_affine(sig: BlstSig) -> blst_p1_affine { - unsafe { - let result = std::mem::transmute::(sig); - return result; - }; +pub fn sig_to_p1_affine(sig: BlstSig) -> blst_p1_affine { + unsafe { std::mem::transmute::(sig) } } -pub fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { - unsafe { - let result = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); - return result; - }; +pub fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { + unsafe { std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0) } } // --------------------------------------------------------------------- From ffec0f017b888267ac37695643edceccbeb104b6 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 1 Feb 2023 16:37:43 +0300 Subject: [PATCH 03/11] herlpers made private --- mithril-stm/src/multi_sig.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 39f82f4bbb5..e4d5d7d5c7c 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -519,23 +519,23 @@ impl Ord for Signature { // Transmute helpers // --------------------------------------------------------------------- -pub fn vk_to_p2_affine(vk: &VerificationKey) -> &'static blst_p2_affine { +fn vk_to_p2_affine(vk: &VerificationKey) -> &'static blst_p2_affine { unsafe { std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk.0) } } -pub fn p2_affine_to_vk(affine_p2: blst_p2_affine) -> BlstVk { +fn p2_affine_to_vk(affine_p2: blst_p2_affine) -> BlstVk { unsafe { std::mem::transmute::(affine_p2) } } -pub fn p1_affine_to_sig(affine_p1: blst_p1_affine) -> BlstSig { +fn p1_affine_to_sig(affine_p1: blst_p1_affine) -> BlstSig { unsafe { std::mem::transmute::(affine_p1) } } -pub fn sig_to_p1_affine(sig: BlstSig) -> blst_p1_affine { +fn sig_to_p1_affine(sig: BlstSig) -> blst_p1_affine { unsafe { std::mem::transmute::(sig) } } -pub fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { +fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { unsafe { std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0) } } From 4b7959e22df2e5d2678fad2c11cd74bea41654f5 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 2 Feb 2023 14:58:57 +0300 Subject: [PATCH 04/11] helpers for unsafe code --- mithril-stm/src/multi_sig.rs | 96 +++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 28 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index e4d5d7d5c7c..49ed9feb5ac 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -13,9 +13,10 @@ use blst::min_sig::{ Signature as BlstSig, }; use blst::{ - blst_p1, blst_p1_affine, blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, - blst_p1_uncompress, blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, - blst_scalar, p1_affines, p2_affines, + blst_fp12, blst_fp12_finalverify, blst_p1, blst_p1_affine, blst_p1_affine_generator, + blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, blst_p1_uncompress, blst_p2, + blst_p2_affine, blst_p2_affine_generator, blst_p2_from_affine, blst_p2_to_affine, blst_scalar, + blst_sk_to_pk_in_g1, p1_affines, p2_affines, BLST_ERROR, }; use rand_core::{CryptoRng, RngCore}; @@ -200,21 +201,17 @@ impl VerificationKeyPoP { // If we are really looking for performance improvements, we can combine the // two final exponentiations (for verifying k1 and k2) into a single one. pub fn check(&self) -> Result<(), MultiSignatureError> { - use blst::{ - blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, - BLST_ERROR, - }; - let result = unsafe { - let g1_p = *blst_p1_affine_generator(); + let result = { + let g1_p = generate_p1_affine(); let mvk_p = vk_to_p2_affine(&self.vk); let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); let mut k2_p = blst_p1_affine::default(); - blst_p1_to_affine(&mut k2_p, &self.pop.k2); - let g2_p = *blst_p2_affine_generator(); + p1_to_affine(&mut k2_p, &self.pop.k2); + let g2_p = generate_p2_affine(); let ml_rhs = blst_fp12::miller_loop(&g2_p, &k2_p); - blst_fp12_finalverify(&ml_lhs, &ml_rhs) + final_verify(ml_lhs, ml_rhs) }; if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false) @@ -269,9 +266,9 @@ impl ProofOfPossession { pub fn to_bytes(self) -> [u8; 96] { let mut pop_bytes = [0u8; 96]; pop_bytes[..48].copy_from_slice(&self.k1.to_bytes()); - let k2_bytes = unsafe { + let k2_bytes = { let mut bytes = [0u8; 48]; - blst_p1_compress(bytes.as_mut_ptr(), &self.k2); + compress_p1(&mut bytes, &self.k2); bytes }; pop_bytes[48..].copy_from_slice(&k2_bytes); @@ -288,11 +285,11 @@ impl ProofOfPossession { } }; - let k2 = unsafe { + let k2 = { let mut point = blst_p1_affine::default(); let mut out = blst_p1::default(); - blst_p1_uncompress(&mut point, bytes[48..].as_ptr()); - blst_p1_from_affine(&mut out, &point); + uncompress_p1(&mut point, bytes[48..96].as_ptr()); + p1_from_affine(&mut out, &point); out }; @@ -305,13 +302,12 @@ impl From<&SigningKey> for ProofOfPossession { /// `k1 = H_G1(b"PoP" || mvk)` and `k2 = g1 * sk` where `H_G1` hashes into /// `G1` and `g1` is the generator in `G1`. fn from(sk: &SigningKey) -> Self { - use blst::blst_sk_to_pk_in_g1; let k1 = sk.0.sign(POP, &[], &[]); - let k2 = unsafe { + let k2 = { let sk_scalar = sk_to_scalar(sk); let mut out = blst_p1::default(); - blst_sk_to_pk_in_g1(&mut out, sk_scalar); + sk_to_pk_in_g1(&mut out, sk_scalar); out }; @@ -412,18 +408,18 @@ impl Signature { let transmuted_vks: Vec = vks .iter() - .map(|vk| unsafe { + .map(|vk| { let mut projective_p2 = blst_p2::default(); - blst_p2_from_affine(&mut projective_p2, vk_to_p2_affine(vk)); + p2_from_affine(&mut projective_p2, vk_to_p2_affine(vk)); projective_p2 }) .collect(); let transmuted_sigs: Vec = signatures .iter() - .map(|&sig| unsafe { + .map(|&sig| { let mut projective_p1 = blst_p1::default(); - blst_p1_from_affine(&mut projective_p1, &sig_to_p1_affine(sig)); + p1_from_affine(&mut projective_p1, &sig_to_p1_affine(sig)); projective_p1 }) .collect(); @@ -431,14 +427,14 @@ impl Signature { let grouped_vks = p2_affines::from(transmuted_vks.as_slice()); let grouped_sigs = p1_affines::from(transmuted_sigs.as_slice()); - let aggr_vk: BlstVk = unsafe { + let aggr_vk: BlstVk = { let mut affine_p2 = blst_p2_affine::default(); - blst_p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars.as_slice(), 128)); + p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars.as_slice(), 128)); p2_affine_to_vk(affine_p2) }; - let aggr_sig: BlstSig = unsafe { + let aggr_sig: BlstSig = { let mut affine_p1 = blst_p1_affine::default(); - blst_p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars.as_slice(), 128)); + p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars.as_slice(), 128)); p1_affine_to_sig(affine_p1) }; @@ -515,6 +511,50 @@ impl Ord for Signature { } } +// --------------------------------------------------------------------- +// Unsafe helpers +// --------------------------------------------------------------------- + +fn generate_p1_affine() -> blst_p1_affine { + unsafe { *blst_p1_affine_generator() } +} + +fn compress_p1(bytes: &mut [u8; 48], k2: *const blst_p1) { + unsafe { blst_p1_compress(bytes.as_mut_ptr(), k2) } +} + +fn uncompress_p1(point: *mut blst_p1_affine, bytes: *const u8) -> BLST_ERROR { + unsafe { blst_p1_uncompress(point, bytes) } +} + +fn p1_from_affine(out: *mut blst_p1, point: *const blst_p1_affine) { + unsafe { blst_p1_from_affine(out, point) } +} + +fn p1_to_affine(k2_p: *mut blst_p1_affine, k2: *const blst_p1) { + unsafe { blst_p1_to_affine(k2_p, k2) } +} + +fn generate_p2_affine() -> blst_p2_affine { + unsafe { *blst_p2_affine_generator() } +} + +fn p2_from_affine(out: *mut blst_p2, point: *const blst_p2_affine) { + unsafe { blst_p2_from_affine(out, point) } +} + +fn p2_to_affine(out_: *mut blst_p2_affine, in_: *const blst_p2) { + unsafe { blst_p2_to_affine(out_, in_) } +} + +fn sk_to_pk_in_g1(out: *mut blst_p1, sk_scalar: *const blst_scalar) { + unsafe { blst_sk_to_pk_in_g1(out, sk_scalar) } +} + +fn final_verify(ml_lhs: blst_fp12, ml_rhs: blst_fp12) -> bool { + unsafe { blst_fp12_finalverify(&ml_lhs, &ml_rhs) } +} + // --------------------------------------------------------------------- // Transmute helpers // --------------------------------------------------------------------- From cb148d79fb6cacd9d11b37a4f58a4e3a9f76d3ac Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Mon, 6 Feb 2023 20:13:02 +0300 Subject: [PATCH 05/11] unsafe code grouped in functions --- mithril-stm/src/multi_sig.rs | 188 ++++++++++++++++------------------- 1 file changed, 85 insertions(+), 103 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 49ed9feb5ac..868f27bd6b7 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -13,10 +13,9 @@ use blst::min_sig::{ Signature as BlstSig, }; use blst::{ - blst_fp12, blst_fp12_finalverify, blst_p1, blst_p1_affine, blst_p1_affine_generator, - blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, blst_p1_uncompress, blst_p2, - blst_p2_affine, blst_p2_affine_generator, blst_p2_from_affine, blst_p2_to_affine, blst_scalar, - blst_sk_to_pk_in_g1, p1_affines, p2_affines, BLST_ERROR, + blst_p1, blst_p1_affine, blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, + blst_p1_uncompress, blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, + blst_scalar, p1_affines, p2_affines, BLST_ERROR, }; use rand_core::{CryptoRng, RngCore}; @@ -201,18 +200,11 @@ impl VerificationKeyPoP { // If we are really looking for performance improvements, we can combine the // two final exponentiations (for verifying k1 and k2) into a single one. pub fn check(&self) -> Result<(), MultiSignatureError> { - let result = { - let g1_p = generate_p1_affine(); - let mvk_p = vk_to_p2_affine(&self.vk); - let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); - - let mut k2_p = blst_p1_affine::default(); - p1_to_affine(&mut k2_p, &self.pop.k2); - let g2_p = generate_p2_affine(); - let ml_rhs = blst_fp12::miller_loop(&g2_p, &k2_p); - - final_verify(ml_lhs, ml_rhs) - }; + // use blst::{ + // blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, + // BLST_ERROR, + // }; + let result = verify_miller_loop(self.vk, self.pop.k2); if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false) == BLST_ERROR::BLST_SUCCESS @@ -266,11 +258,10 @@ impl ProofOfPossession { pub fn to_bytes(self) -> [u8; 96] { let mut pop_bytes = [0u8; 96]; pop_bytes[..48].copy_from_slice(&self.k1.to_bytes()); - let k2_bytes = { - let mut bytes = [0u8; 48]; - compress_p1(&mut bytes, &self.k2); - bytes - }; + + let mut k2_bytes = [0u8; 48]; + compress_p1(&mut k2_bytes, &self.k2); + pop_bytes[48..].copy_from_slice(&k2_bytes); pop_bytes } @@ -285,13 +276,7 @@ impl ProofOfPossession { } }; - let k2 = { - let mut point = blst_p1_affine::default(); - let mut out = blst_p1::default(); - uncompress_p1(&mut point, bytes[48..96].as_ptr()); - p1_from_affine(&mut out, &point); - out - }; + let k2 = uncompress_p1(bytes[48..96].as_ptr()); Ok(Self { k1, k2 }) } @@ -303,13 +288,7 @@ impl From<&SigningKey> for ProofOfPossession { /// `G1` and `g1` is the generator in `G1`. fn from(sk: &SigningKey) -> Self { let k1 = sk.0.sign(POP, &[], &[]); - let k2 = { - let sk_scalar = sk_to_scalar(sk); - - let mut out = blst_p1::default(); - sk_to_pk_in_g1(&mut out, sk_scalar); - out - }; + let k2 = sk_to_pk_in_g1(sk); Self { k1, k2 } } @@ -406,37 +385,15 @@ impl Signature { scalars.extend_from_slice(hasher.finalize().as_slice()); } - let transmuted_vks: Vec = vks - .iter() - .map(|vk| { - let mut projective_p2 = blst_p2::default(); - p2_from_affine(&mut projective_p2, vk_to_p2_affine(vk)); - projective_p2 - }) - .collect(); - - let transmuted_sigs: Vec = signatures - .iter() - .map(|&sig| { - let mut projective_p1 = blst_p1::default(); - p1_from_affine(&mut projective_p1, &sig_to_p1_affine(sig)); - projective_p1 - }) - .collect(); + let transmuted_vks: Vec = vks.iter().map(p2_from_affine).collect(); + + let transmuted_sigs: Vec = signatures.iter().map(|&sig| sig_to_p1(sig)).collect(); let grouped_vks = p2_affines::from(transmuted_vks.as_slice()); let grouped_sigs = p1_affines::from(transmuted_sigs.as_slice()); - let aggr_vk: BlstVk = { - let mut affine_p2 = blst_p2_affine::default(); - p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars.as_slice(), 128)); - p2_affine_to_vk(affine_p2) - }; - let aggr_sig: BlstSig = { - let mut affine_p1 = blst_p1_affine::default(); - p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars.as_slice(), 128)); - p1_affine_to_sig(affine_p1) - }; + let aggr_vk: BlstVk = p2_affine_to_vk(grouped_vks, scalars.as_slice()); + let aggr_sig: BlstSig = p1_affine_to_sig(grouped_sigs, scalars.as_slice()); Ok((VerificationKey(aggr_vk), Signature(aggr_sig))) } @@ -492,8 +449,8 @@ impl<'a> Sum<&'a Self> for Signature { let signatures: Vec<&BlstSig> = iter.map(|x| &x.0).collect(); assert!(!signatures.is_empty(), "One cannot add an empty vector"); let aggregate = AggregateSignature::aggregate(&signatures, false) - .expect("An MspSig is always a valid signature. This function only fails if signatures is empty or if the signatures are invalid, none of which can happen.") - .to_signature(); + .expect("An MspSig is always a valid signature. This function only fails if signatures is empty or if the signatures are invalid, none of which can happen.") + .to_signature(); Self(aggregate) } @@ -511,48 +468,77 @@ impl Ord for Signature { } } -// --------------------------------------------------------------------- -// Unsafe helpers -// --------------------------------------------------------------------- +fn verify_miller_loop(vk: VerificationKey, k2: blst_p1) -> bool { + use blst::{ + blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, + }; + unsafe { + let g1_p = *blst_p1_affine_generator(); + let mvk_p = vk_to_p2_affine(&vk); + let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); + + let mut k2_p = blst_p1_affine::default(); + blst_p1_to_affine(&mut k2_p, &k2); + let g2_p = *blst_p2_affine_generator(); + let ml_rhs = blst_fp12::miller_loop(&g2_p, &k2_p); -fn generate_p1_affine() -> blst_p1_affine { - unsafe { *blst_p1_affine_generator() } + blst_fp12_finalverify(&ml_lhs, &ml_rhs) + } } fn compress_p1(bytes: &mut [u8; 48], k2: *const blst_p1) { unsafe { blst_p1_compress(bytes.as_mut_ptr(), k2) } } -fn uncompress_p1(point: *mut blst_p1_affine, bytes: *const u8) -> BLST_ERROR { - unsafe { blst_p1_uncompress(point, bytes) } -} - -fn p1_from_affine(out: *mut blst_p1, point: *const blst_p1_affine) { - unsafe { blst_p1_from_affine(out, point) } -} - -fn p1_to_affine(k2_p: *mut blst_p1_affine, k2: *const blst_p1) { - unsafe { blst_p1_to_affine(k2_p, k2) } +fn uncompress_p1(bytes: *const u8) -> blst_p1 { + unsafe { + let mut point = blst_p1_affine::default(); + let mut out = blst_p1::default(); + blst_p1_uncompress(&mut point, bytes); + blst_p1_from_affine(&mut out, &point); + out + } } -fn generate_p2_affine() -> blst_p2_affine { - unsafe { *blst_p2_affine_generator() } -} +fn sk_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { + use blst::blst_sk_to_pk_in_g1; -fn p2_from_affine(out: *mut blst_p2, point: *const blst_p2_affine) { - unsafe { blst_p2_from_affine(out, point) } + unsafe { + let sk_scalar = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); + let mut out = blst_p1::default(); + blst_sk_to_pk_in_g1(&mut out, sk_scalar); + out + } } -fn p2_to_affine(out_: *mut blst_p2_affine, in_: *const blst_p2) { - unsafe { blst_p2_to_affine(out_, in_) } +fn p2_from_affine(vk: &VerificationKey) -> blst_p2 { + unsafe { + let mut projective_p2 = blst_p2::default(); + blst_p2_from_affine( + &mut projective_p2, + &std::mem::transmute::(vk.0), + ); + projective_p2 + } } -fn sk_to_pk_in_g1(out: *mut blst_p1, sk_scalar: *const blst_scalar) { - unsafe { blst_sk_to_pk_in_g1(out, sk_scalar) } +fn sig_to_p1(sig: BlstSig) -> blst_p1 { + unsafe { + let mut projective_p1 = blst_p1::default(); + blst_p1_from_affine( + &mut projective_p1, + &std::mem::transmute::(sig), + ); + projective_p1 + } } -fn final_verify(ml_lhs: blst_fp12, ml_rhs: blst_fp12) -> bool { - unsafe { blst_fp12_finalverify(&ml_lhs, &ml_rhs) } +fn p2_affine_to_vk(grouped_vks: p2_affines, scalars: &[u8]) -> BlstVk { + unsafe { + let mut affine_p2 = blst_p2_affine::default(); + blst_p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars, 128)); + std::mem::transmute::(affine_p2) + } } // --------------------------------------------------------------------- @@ -563,21 +549,17 @@ fn vk_to_p2_affine(vk: &VerificationKey) -> &'static blst_p2_affine { unsafe { std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk.0) } } -fn p2_affine_to_vk(affine_p2: blst_p2_affine) -> BlstVk { - unsafe { std::mem::transmute::(affine_p2) } -} - -fn p1_affine_to_sig(affine_p1: blst_p1_affine) -> BlstSig { - unsafe { std::mem::transmute::(affine_p1) } -} - -fn sig_to_p1_affine(sig: BlstSig) -> blst_p1_affine { - unsafe { std::mem::transmute::(sig) } +fn p1_affine_to_sig(grouped_sigs: p1_affines, scalars: &[u8]) -> BlstSig { + unsafe { + let mut affine_p1 = blst_p1_affine::default(); + blst_p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars, 128)); + std::mem::transmute::(affine_p1) + } } -fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { - unsafe { std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0) } -} +// fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { +// unsafe { std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0) } +// } // --------------------------------------------------------------------- // Serde implementation From 1c914fdd009097030e1c5bc90224f461b17dabbd Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 7 Feb 2023 14:30:08 +0300 Subject: [PATCH 06/11] error corrections --- mithril-stm/src/multi_sig.rs | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 868f27bd6b7..38ef459a29e 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -204,7 +204,7 @@ impl VerificationKeyPoP { // blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, // BLST_ERROR, // }; - let result = verify_miller_loop(self.vk, self.pop.k2); + let result = verify_miller_loop(self.vk.0, self.pop.k2); if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false) == BLST_ERROR::BLST_SUCCESS @@ -288,7 +288,7 @@ impl From<&SigningKey> for ProofOfPossession { /// `G1` and `g1` is the generator in `G1`. fn from(sk: &SigningKey) -> Self { let k1 = sk.0.sign(POP, &[], &[]); - let k2 = sk_to_pk_in_g1(sk); + let k2 = scalar_to_pk_in_g1(sk); Self { k1, k2 } } @@ -385,7 +385,7 @@ impl Signature { scalars.extend_from_slice(hasher.finalize().as_slice()); } - let transmuted_vks: Vec = vks.iter().map(p2_from_affine).collect(); + let transmuted_vks: Vec = vks.iter().map(vk_from_p2_affine).collect(); let transmuted_sigs: Vec = signatures.iter().map(|&sig| sig_to_p1(sig)).collect(); @@ -468,13 +468,17 @@ impl Ord for Signature { } } -fn verify_miller_loop(vk: VerificationKey, k2: blst_p1) -> bool { +// --------------------------------------------------------------------- +// Unsafe helpers +// --------------------------------------------------------------------- + +fn verify_miller_loop(vk: BlstVk, k2: blst_p1) -> bool { use blst::{ blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, }; unsafe { let g1_p = *blst_p1_affine_generator(); - let mvk_p = vk_to_p2_affine(&vk); + let mvk_p = std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk); let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); let mut k2_p = blst_p1_affine::default(); @@ -500,9 +504,8 @@ fn uncompress_p1(bytes: *const u8) -> blst_p1 { } } -fn sk_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { +fn scalar_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { use blst::blst_sk_to_pk_in_g1; - unsafe { let sk_scalar = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); let mut out = blst_p1::default(); @@ -511,7 +514,7 @@ fn sk_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { } } -fn p2_from_affine(vk: &VerificationKey) -> blst_p2 { +fn vk_from_p2_affine(vk: &VerificationKey) -> blst_p2 { unsafe { let mut projective_p2 = blst_p2::default(); blst_p2_from_affine( @@ -541,14 +544,6 @@ fn p2_affine_to_vk(grouped_vks: p2_affines, scalars: &[u8]) -> BlstVk { } } -// --------------------------------------------------------------------- -// Transmute helpers -// --------------------------------------------------------------------- - -fn vk_to_p2_affine(vk: &VerificationKey) -> &'static blst_p2_affine { - unsafe { std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk.0) } -} - fn p1_affine_to_sig(grouped_sigs: p1_affines, scalars: &[u8]) -> BlstSig { unsafe { let mut affine_p1 = blst_p1_affine::default(); @@ -557,10 +552,6 @@ fn p1_affine_to_sig(grouped_sigs: p1_affines, scalars: &[u8]) -> BlstSig { } } -// fn sk_to_scalar(sk: &SigningKey) -> &blst_scalar { -// unsafe { std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0) } -// } - // --------------------------------------------------------------------- // Serde implementation // --------------------------------------------------------------------- From bbc23f95b553d83fe2dcde1886c7e2bc0d6f6fcf Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 7 Feb 2023 16:43:37 +0300 Subject: [PATCH 07/11] references and pointers corrected --- mithril-stm/src/multi_sig.rs | 37 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 38ef459a29e..bde4d59a8c6 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -204,7 +204,7 @@ impl VerificationKeyPoP { // blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, // BLST_ERROR, // }; - let result = verify_miller_loop(self.vk.0, self.pop.k2); + let result = verify_miller_loop(&self.vk.0, &self.pop.k2); if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false) == BLST_ERROR::BLST_SUCCESS @@ -259,10 +259,9 @@ impl ProofOfPossession { let mut pop_bytes = [0u8; 96]; pop_bytes[..48].copy_from_slice(&self.k1.to_bytes()); - let mut k2_bytes = [0u8; 48]; - compress_p1(&mut k2_bytes, &self.k2); + let k2_bytes = compress_p1(&self.k2); - pop_bytes[48..].copy_from_slice(&k2_bytes); + pop_bytes[48..].copy_from_slice(k2_bytes.as_slice()); pop_bytes } @@ -276,7 +275,7 @@ impl ProofOfPossession { } }; - let k2 = uncompress_p1(bytes[48..96].as_ptr()); + let k2 = uncompress_p1(&bytes[48..96]); Ok(Self { k1, k2 }) } @@ -387,13 +386,13 @@ impl Signature { let transmuted_vks: Vec = vks.iter().map(vk_from_p2_affine).collect(); - let transmuted_sigs: Vec = signatures.iter().map(|&sig| sig_to_p1(sig)).collect(); + let transmuted_sigs: Vec = signatures.iter().map(sig_to_p1).collect(); let grouped_vks = p2_affines::from(transmuted_vks.as_slice()); let grouped_sigs = p1_affines::from(transmuted_sigs.as_slice()); - let aggr_vk: BlstVk = p2_affine_to_vk(grouped_vks, scalars.as_slice()); - let aggr_sig: BlstSig = p1_affine_to_sig(grouped_sigs, scalars.as_slice()); + let aggr_vk: BlstVk = p2_affine_to_vk(&grouped_vks, scalars.as_slice()); + let aggr_sig: BlstSig = p1_affine_to_sig(&grouped_sigs, scalars.as_slice()); Ok((VerificationKey(aggr_vk), Signature(aggr_sig))) } @@ -472,17 +471,17 @@ impl Ord for Signature { // Unsafe helpers // --------------------------------------------------------------------- -fn verify_miller_loop(vk: BlstVk, k2: blst_p1) -> bool { +fn verify_miller_loop(vk: &BlstVk, k2: &blst_p1) -> bool { use blst::{ blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, }; unsafe { let g1_p = *blst_p1_affine_generator(); - let mvk_p = std::mem::transmute::<&BlstVk, &blst_p2_affine>(&vk); + let mvk_p = std::mem::transmute::<&BlstVk, &blst_p2_affine>(vk); let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); let mut k2_p = blst_p1_affine::default(); - blst_p1_to_affine(&mut k2_p, &k2); + blst_p1_to_affine(&mut k2_p, k2); let g2_p = *blst_p2_affine_generator(); let ml_rhs = blst_fp12::miller_loop(&g2_p, &k2_p); @@ -490,15 +489,17 @@ fn verify_miller_loop(vk: BlstVk, k2: blst_p1) -> bool { } } -fn compress_p1(bytes: &mut [u8; 48], k2: *const blst_p1) { +fn compress_p1(k2: &blst_p1) -> [u8; 48] { + let mut bytes = [0u8; 48]; unsafe { blst_p1_compress(bytes.as_mut_ptr(), k2) } + bytes } -fn uncompress_p1(bytes: *const u8) -> blst_p1 { +fn uncompress_p1(bytes: &[u8]) -> blst_p1 { unsafe { let mut point = blst_p1_affine::default(); let mut out = blst_p1::default(); - blst_p1_uncompress(&mut point, bytes); + blst_p1_uncompress(&mut point, bytes.as_ptr()); blst_p1_from_affine(&mut out, &point); out } @@ -525,18 +526,18 @@ fn vk_from_p2_affine(vk: &VerificationKey) -> blst_p2 { } } -fn sig_to_p1(sig: BlstSig) -> blst_p1 { +fn sig_to_p1(sig: &BlstSig) -> blst_p1 { unsafe { let mut projective_p1 = blst_p1::default(); blst_p1_from_affine( &mut projective_p1, - &std::mem::transmute::(sig), + &std::mem::transmute::(*sig), ); projective_p1 } } -fn p2_affine_to_vk(grouped_vks: p2_affines, scalars: &[u8]) -> BlstVk { +fn p2_affine_to_vk(grouped_vks: &p2_affines, scalars: &[u8]) -> BlstVk { unsafe { let mut affine_p2 = blst_p2_affine::default(); blst_p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars, 128)); @@ -544,7 +545,7 @@ fn p2_affine_to_vk(grouped_vks: p2_affines, scalars: &[u8]) -> BlstVk { } } -fn p1_affine_to_sig(grouped_sigs: p1_affines, scalars: &[u8]) -> BlstSig { +fn p1_affine_to_sig(grouped_sigs: &p1_affines, scalars: &[u8]) -> BlstSig { unsafe { let mut affine_p1 = blst_p1_affine::default(); blst_p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars, 128)); From 9d25947c8ca18cc3d8efdc198495d496eb7f6c38 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 7 Feb 2023 17:47:34 +0300 Subject: [PATCH 08/11] mod for unsafe helpers --- mithril-stm/src/multi_sig.rs | 177 ++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 87 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index bde4d59a8c6..7b3a0861826 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -5,6 +5,7 @@ use crate::error::{blst_err_to_mithril, MultiSignatureError}; use crate::stm::Index; use blake2::{digest::consts::U16, Blake2b, Blake2b512, Digest}; +use unsafe_helpers::*; // We use `min_sig` resulting in signatures of 48 bytes and public keys of // 96. We can switch that around if desired by using `min_vk`. @@ -26,7 +27,6 @@ use std::{ hash::{Hash, Hasher}, iter::Sum, }; - /// String used to generate the proofs of possession. const POP: &[u8] = b"PoP"; @@ -467,92 +467,6 @@ impl Ord for Signature { } } -// --------------------------------------------------------------------- -// Unsafe helpers -// --------------------------------------------------------------------- - -fn verify_miller_loop(vk: &BlstVk, k2: &blst_p1) -> bool { - use blst::{ - blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, - }; - unsafe { - let g1_p = *blst_p1_affine_generator(); - let mvk_p = std::mem::transmute::<&BlstVk, &blst_p2_affine>(vk); - let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); - - let mut k2_p = blst_p1_affine::default(); - blst_p1_to_affine(&mut k2_p, k2); - let g2_p = *blst_p2_affine_generator(); - let ml_rhs = blst_fp12::miller_loop(&g2_p, &k2_p); - - blst_fp12_finalverify(&ml_lhs, &ml_rhs) - } -} - -fn compress_p1(k2: &blst_p1) -> [u8; 48] { - let mut bytes = [0u8; 48]; - unsafe { blst_p1_compress(bytes.as_mut_ptr(), k2) } - bytes -} - -fn uncompress_p1(bytes: &[u8]) -> blst_p1 { - unsafe { - let mut point = blst_p1_affine::default(); - let mut out = blst_p1::default(); - blst_p1_uncompress(&mut point, bytes.as_ptr()); - blst_p1_from_affine(&mut out, &point); - out - } -} - -fn scalar_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { - use blst::blst_sk_to_pk_in_g1; - unsafe { - let sk_scalar = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); - let mut out = blst_p1::default(); - blst_sk_to_pk_in_g1(&mut out, sk_scalar); - out - } -} - -fn vk_from_p2_affine(vk: &VerificationKey) -> blst_p2 { - unsafe { - let mut projective_p2 = blst_p2::default(); - blst_p2_from_affine( - &mut projective_p2, - &std::mem::transmute::(vk.0), - ); - projective_p2 - } -} - -fn sig_to_p1(sig: &BlstSig) -> blst_p1 { - unsafe { - let mut projective_p1 = blst_p1::default(); - blst_p1_from_affine( - &mut projective_p1, - &std::mem::transmute::(*sig), - ); - projective_p1 - } -} - -fn p2_affine_to_vk(grouped_vks: &p2_affines, scalars: &[u8]) -> BlstVk { - unsafe { - let mut affine_p2 = blst_p2_affine::default(); - blst_p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars, 128)); - std::mem::transmute::(affine_p2) - } -} - -fn p1_affine_to_sig(grouped_sigs: &p1_affines, scalars: &[u8]) -> BlstSig { - unsafe { - let mut affine_p1 = blst_p1_affine::default(); - blst_p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars, 128)); - std::mem::transmute::(affine_p1) - } -} - // --------------------------------------------------------------------- // Serde implementation // --------------------------------------------------------------------- @@ -621,6 +535,95 @@ impl_serde!(VerificationKey, VerificationKeyVisitor, 96); impl_serde!(ProofOfPossession, ProofOfPossessionVisitor, 96); impl_serde!(Signature, SignatureVisitor, 48); +// --------------------------------------------------------------------- +// Unsafe helpers +// --------------------------------------------------------------------- +mod unsafe_helpers { + use super::*; + use blst::{ + blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, + blst_sk_to_pk_in_g1, + }; + + pub(crate) fn verify_miller_loop(vk: &BlstVk, k2: &blst_p1) -> bool { + unsafe { + let g1_p = *blst_p1_affine_generator(); + let mvk_p = std::mem::transmute::<&BlstVk, &blst_p2_affine>(vk); + let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); + + let mut k2_p = blst_p1_affine::default(); + blst_p1_to_affine(&mut k2_p, k2); + let g2_p = *blst_p2_affine_generator(); + let ml_rhs = blst_fp12::miller_loop(&g2_p, &k2_p); + + blst_fp12_finalverify(&ml_lhs, &ml_rhs) + } + } + + pub(crate) fn compress_p1(k2: &blst_p1) -> [u8; 48] { + let mut bytes = [0u8; 48]; + unsafe { blst_p1_compress(bytes.as_mut_ptr(), k2) } + bytes + } + + pub(crate) fn uncompress_p1(bytes: &[u8]) -> blst_p1 { + unsafe { + let mut point = blst_p1_affine::default(); + let mut out = blst_p1::default(); + blst_p1_uncompress(&mut point, bytes.as_ptr()); + blst_p1_from_affine(&mut out, &point); + out + } + } + + pub(crate) fn scalar_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { + unsafe { + let sk_scalar = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); + let mut out = blst_p1::default(); + blst_sk_to_pk_in_g1(&mut out, sk_scalar); + out + } + } + + pub(crate) fn vk_from_p2_affine(vk: &VerificationKey) -> blst_p2 { + unsafe { + let mut projective_p2 = blst_p2::default(); + blst_p2_from_affine( + &mut projective_p2, + &std::mem::transmute::(vk.0), + ); + projective_p2 + } + } + + pub(crate) fn sig_to_p1(sig: &BlstSig) -> blst_p1 { + unsafe { + let mut projective_p1 = blst_p1::default(); + blst_p1_from_affine( + &mut projective_p1, + &std::mem::transmute::(*sig), + ); + projective_p1 + } + } + + pub(crate) fn p2_affine_to_vk(grouped_vks: &p2_affines, scalars: &[u8]) -> BlstVk { + unsafe { + let mut affine_p2 = blst_p2_affine::default(); + blst_p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars, 128)); + std::mem::transmute::(affine_p2) + } + } + + pub(crate) fn p1_affine_to_sig(grouped_sigs: &p1_affines, scalars: &[u8]) -> BlstSig { + unsafe { + let mut affine_p1 = blst_p1_affine::default(); + blst_p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars, 128)); + std::mem::transmute::(affine_p1) + } + } +} + #[cfg(test)] mod tests { use super::*; From 77801f025c3793ad1d4e0f6e9bceccab028f0a88 Mon Sep 17 00:00:00 2001 From: curiecrypt <36852463+curiecrypt@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:19:24 +0300 Subject: [PATCH 09/11] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: IƱigo Querejeta Azurmendi <31273774+iquerejeta@users.noreply.github.com> --- mithril-stm/src/multi_sig.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 7b3a0861826..11c629661d7 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -204,7 +204,7 @@ impl VerificationKeyPoP { // blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, // BLST_ERROR, // }; - let result = verify_miller_loop(&self.vk.0, &self.pop.k2); + let result = verify_pairing(&self.vk, &self.pop); if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false) == BLST_ERROR::BLST_SUCCESS @@ -259,9 +259,7 @@ impl ProofOfPossession { let mut pop_bytes = [0u8; 96]; pop_bytes[..48].copy_from_slice(&self.k1.to_bytes()); - let k2_bytes = compress_p1(&self.k2); - - pop_bytes[48..].copy_from_slice(k2_bytes.as_slice()); + pop_bytes[48..].copy_from_slice(compress_p1(&self.k2)[..]); pop_bytes } @@ -391,8 +389,8 @@ impl Signature { let grouped_vks = p2_affines::from(transmuted_vks.as_slice()); let grouped_sigs = p1_affines::from(transmuted_sigs.as_slice()); - let aggr_vk: BlstVk = p2_affine_to_vk(&grouped_vks, scalars.as_slice()); - let aggr_sig: BlstSig = p1_affine_to_sig(&grouped_sigs, scalars.as_slice()); + let aggr_vk: BlstVk = p2_affine_to_vk(&grouped_vks, &scalars); + let aggr_sig: BlstSig = p1_affine_to_sig(&grouped_sigs, &scalars); Ok((VerificationKey(aggr_vk), Signature(aggr_sig))) } @@ -545,11 +543,11 @@ mod unsafe_helpers { blst_sk_to_pk_in_g1, }; - pub(crate) fn verify_miller_loop(vk: &BlstVk, k2: &blst_p1) -> bool { + pub(crate) fn verify_pairing(vk: & VerificationKey, pop: & ProofOfPossession) -> bool { unsafe { let g1_p = *blst_p1_affine_generator(); - let mvk_p = std::mem::transmute::<&BlstVk, &blst_p2_affine>(vk); - let ml_lhs = blst_fp12::miller_loop(mvk_p, &g1_p); + let mvk_p = std::mem::transmute::(vk.0); + let ml_lhs = blst_fp12::miller_loop(&mvk_p, &g1_p); let mut k2_p = blst_p1_affine::default(); blst_p1_to_affine(&mut k2_p, k2); @@ -578,9 +576,9 @@ mod unsafe_helpers { pub(crate) fn scalar_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { unsafe { - let sk_scalar = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); + let sk_scalar = std::mem::transmute::(sk.0); let mut out = blst_p1::default(); - blst_sk_to_pk_in_g1(&mut out, sk_scalar); + blst_sk_to_pk_in_g1(&mut out, &sk_scalar); out } } From 5612aae340068dde9972bdf75f6d02ad13172706 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 14 Feb 2023 18:41:40 +0300 Subject: [PATCH 10/11] comments resolved --- mithril-stm/src/multi_sig.rs | 58 +++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index 11c629661d7..f4ff974a16e 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -13,11 +13,10 @@ use blst::min_sig::{ AggregatePublicKey, AggregateSignature, PublicKey as BlstVk, SecretKey as BlstSk, Signature as BlstSig, }; -use blst::{ - blst_p1, blst_p1_affine, blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, - blst_p1_uncompress, blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, - blst_scalar, p1_affines, p2_affines, BLST_ERROR, -}; +use blst::{blst_p1, blst_p2, p1_affines, p2_affines, BLST_ERROR}; +// blst_p1_affine, blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, +// blst_p1_uncompress, blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, +// blst_scalar, p1_affines, p2_affines, BLST_ERROR, use rand_core::{CryptoRng, RngCore}; use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; @@ -200,10 +199,6 @@ impl VerificationKeyPoP { // If we are really looking for performance improvements, we can combine the // two final exponentiations (for verifying k1 and k2) into a single one. pub fn check(&self) -> Result<(), MultiSignatureError> { - // use blst::{ - // blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, - // BLST_ERROR, - // }; let result = verify_pairing(&self.vk, &self.pop); if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false) @@ -259,7 +254,7 @@ impl ProofOfPossession { let mut pop_bytes = [0u8; 96]; pop_bytes[..48].copy_from_slice(&self.k1.to_bytes()); - pop_bytes[48..].copy_from_slice(compress_p1(&self.k2)[..]); + pop_bytes[48..].copy_from_slice(&compress_p1(&self.k2)[..]); pop_bytes } @@ -273,7 +268,7 @@ impl ProofOfPossession { } }; - let k2 = uncompress_p1(&bytes[48..96]); + let k2 = uncompress_p1(&bytes[48..96])?; Ok(Self { k1, k2 }) } @@ -389,8 +384,8 @@ impl Signature { let grouped_vks = p2_affines::from(transmuted_vks.as_slice()); let grouped_sigs = p1_affines::from(transmuted_sigs.as_slice()); - let aggr_vk: BlstVk = p2_affine_to_vk(&grouped_vks, &scalars); - let aggr_sig: BlstSig = p1_affine_to_sig(&grouped_sigs, &scalars); + let aggr_vk: BlstVk = p2_affine_to_vk(&grouped_vks.mult(&scalars, 128)); + let aggr_sig: BlstSig = p1_affine_to_sig(&grouped_sigs.mult(&scalars, 128)); Ok((VerificationKey(aggr_vk), Signature(aggr_sig))) } @@ -538,19 +533,22 @@ impl_serde!(Signature, SignatureVisitor, 48); // --------------------------------------------------------------------- mod unsafe_helpers { use super::*; + use crate::error::MultiSignatureError::SerializationError; use blst::{ - blst_fp12, blst_fp12_finalverify, blst_p1_affine_generator, blst_p2_affine_generator, - blst_sk_to_pk_in_g1, + blst_fp12, blst_fp12_finalverify, blst_p1_affine, blst_p1_affine_generator, + blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, blst_p1_uncompress, + blst_p2_affine, blst_p2_affine_generator, blst_p2_from_affine, blst_p2_to_affine, + blst_scalar, blst_sk_to_pk_in_g1, }; - pub(crate) fn verify_pairing(vk: & VerificationKey, pop: & ProofOfPossession) -> bool { + pub(crate) fn verify_pairing(vk: &VerificationKey, pop: &ProofOfPossession) -> bool { unsafe { let g1_p = *blst_p1_affine_generator(); let mvk_p = std::mem::transmute::(vk.0); let ml_lhs = blst_fp12::miller_loop(&mvk_p, &g1_p); let mut k2_p = blst_p1_affine::default(); - blst_p1_to_affine(&mut k2_p, k2); + blst_p1_to_affine(&mut k2_p, &pop.k2); let g2_p = *blst_p2_affine_generator(); let ml_rhs = blst_fp12::miller_loop(&g2_p, &k2_p); @@ -564,19 +562,23 @@ mod unsafe_helpers { bytes } - pub(crate) fn uncompress_p1(bytes: &[u8]) -> blst_p1 { + pub(crate) fn uncompress_p1(bytes: &[u8]) -> Result { unsafe { - let mut point = blst_p1_affine::default(); - let mut out = blst_p1::default(); - blst_p1_uncompress(&mut point, bytes.as_ptr()); - blst_p1_from_affine(&mut out, &point); - out + if bytes.len() == 48 { + let mut point = blst_p1_affine::default(); + let mut out = blst_p1::default(); + blst_p1_uncompress(&mut point, bytes.as_ptr()); + blst_p1_from_affine(&mut out, &point); + Ok(out) + } else { + Err(SerializationError) + } } } pub(crate) fn scalar_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { unsafe { - let sk_scalar = std::mem::transmute::(sk.0); + let sk_scalar = std::mem::transmute::(sk.0.clone()); let mut out = blst_p1::default(); blst_sk_to_pk_in_g1(&mut out, &sk_scalar); out @@ -605,18 +607,18 @@ mod unsafe_helpers { } } - pub(crate) fn p2_affine_to_vk(grouped_vks: &p2_affines, scalars: &[u8]) -> BlstVk { + pub(crate) fn p2_affine_to_vk(grouped_vks: &blst_p2) -> BlstVk { unsafe { let mut affine_p2 = blst_p2_affine::default(); - blst_p2_to_affine(&mut affine_p2, &grouped_vks.mult(scalars, 128)); + blst_p2_to_affine(&mut affine_p2, grouped_vks); std::mem::transmute::(affine_p2) } } - pub(crate) fn p1_affine_to_sig(grouped_sigs: &p1_affines, scalars: &[u8]) -> BlstSig { + pub(crate) fn p1_affine_to_sig(grouped_sigs: &blst_p1) -> BlstSig { unsafe { let mut affine_p1 = blst_p1_affine::default(); - blst_p1_to_affine(&mut affine_p1, &grouped_sigs.mult(scalars, 128)); + blst_p1_to_affine(&mut affine_p1, grouped_sigs); std::mem::transmute::(affine_p1) } } From c83d6bd6d002935f17db6188489c98955adb5ba1 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 15 Feb 2023 18:37:31 +0300 Subject: [PATCH 11/11] final revisions for unsafe helpers --- mithril-stm/src/multi_sig.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mithril-stm/src/multi_sig.rs b/mithril-stm/src/multi_sig.rs index f4ff974a16e..3cc8ade4aad 100644 --- a/mithril-stm/src/multi_sig.rs +++ b/mithril-stm/src/multi_sig.rs @@ -14,9 +14,6 @@ use blst::min_sig::{ Signature as BlstSig, }; use blst::{blst_p1, blst_p2, p1_affines, p2_affines, BLST_ERROR}; -// blst_p1_affine, blst_p1_compress, blst_p1_from_affine, blst_p1_to_affine, -// blst_p1_uncompress, blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, -// blst_scalar, p1_affines, p2_affines, BLST_ERROR, use rand_core::{CryptoRng, RngCore}; use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; @@ -209,6 +206,7 @@ impl VerificationKeyPoP { } Ok(()) } + /// Convert to a 144 byte string. /// /// # Layout @@ -531,6 +529,7 @@ impl_serde!(Signature, SignatureVisitor, 48); // --------------------------------------------------------------------- // Unsafe helpers // --------------------------------------------------------------------- + mod unsafe_helpers { use super::*; use crate::error::MultiSignatureError::SerializationError; @@ -541,6 +540,7 @@ mod unsafe_helpers { blst_scalar, blst_sk_to_pk_in_g1, }; + /// Check manually if the pairing `e(g1,mvk) = e(k2,g2)` holds. pub(crate) fn verify_pairing(vk: &VerificationKey, pop: &ProofOfPossession) -> bool { unsafe { let g1_p = *blst_p1_affine_generator(); @@ -578,9 +578,9 @@ mod unsafe_helpers { pub(crate) fn scalar_to_pk_in_g1(sk: &SigningKey) -> blst_p1 { unsafe { - let sk_scalar = std::mem::transmute::(sk.0.clone()); + let sk_scalar = std::mem::transmute::<&BlstSk, &blst_scalar>(&sk.0); let mut out = blst_p1::default(); - blst_sk_to_pk_in_g1(&mut out, &sk_scalar); + blst_sk_to_pk_in_g1(&mut out, sk_scalar); out } }