Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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 contrib/codeql/lib/policy.qll
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ predicate isNotEncodable(TypeItem t) {
/** Holds if `t` holds secret or security-sensitive material. */
predicate isSecretType(TypeItem t) {
(
t.getName().getText().regexpMatch(".*(Secret|Private|Seed|Password|Mnemonic|SkBytes).*")
t.getName().getText().regexpMatch(".*(Secret|Private|Seed|Password|Mnemonic|SkBytes|DhBytes).*")
or
// "Share" is the one keyword that "Shared" (e.g. SharedState) matches without holding a secret,
// so the guard applies to it alone, exceptions to this rule are explicitly enumerated.
Expand Down
100 changes: 68 additions & 32 deletions pkgs/pkc/bench/bls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn verify<S: BlsScheme>(bencher: Bencher) {
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [2, 5, 25, 50, 100])]
fn aggregate_pk_n<S: BlsScheme>(bencher: Bencher, n: usize) {
let pks: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i as u8)).unwrap().public_key())
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap().public_key())
.collect();
let pk_refs: Vec<_> = pks.iter().collect();
bencher
Expand All @@ -48,12 +48,12 @@ fn aggregate_pk_n<S: BlsScheme>(bencher: Bencher, n: usize) {
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [2, 10, 100])]
fn aggregate_sig_n<S: BlsScheme>(bencher: Bencher, n: usize) {
let keys: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i as u8)).unwrap())
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap())
.collect();
let sigs: Vec<_> = keys
.iter()
.enumerate()
.map(|(i, key)| key.sign(S::msg_ref(&test_msg(i as u8))))
.map(|(i, key)| key.sign(S::msg_ref(&test_msg(i))))
.collect();
let sig_refs: Vec<&BlsSignature<S>> = sigs.iter().collect();
bencher
Expand All @@ -65,9 +65,9 @@ fn aggregate_sig_n<S: BlsScheme>(bencher: Bencher, n: usize) {
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [100, 1000])]
fn verify_n_individual<S: BlsScheme>(bencher: Bencher, n: usize) {
let keys: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i as u8)).unwrap())
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap())
.collect();
let msgs: Vec<[u8; 32]> = (0..n).map(|i| test_msg(i as u8)).collect();
let msgs: Vec<[u8; 32]> = (0..n).map(test_msg).collect();
let pks: Vec<_> = keys.iter().map(BlsSecretKey::public_key).collect();
let sigs: Vec<_> = keys
.iter()
Expand All @@ -86,7 +86,7 @@ fn verify_n_individual<S: BlsScheme>(bencher: Bencher, n: usize) {
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [10, 100, 1000])]
fn fast_verify_n<S: BlsScheme>(bencher: Bencher, n: usize) {
let keys: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i as u8)).unwrap())
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap())
.collect();
let msg = test_msg(42);
let pks: Vec<_> = keys.iter().map(BlsSecretKey::public_key).collect();
Expand Down Expand Up @@ -161,33 +161,69 @@ fn recover_threshold<S: BlsScheme>(bencher: Bencher, threshold: usize) {
.bench(|| BlsSignature::<S>::recover(&subset));
}

/// Aggregate signatures over distinct messages, then verify.
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [10, 100, 1000])]
fn verify_aggregated_block<S: BlsScheme>(bencher: Bencher, n: usize)
where
S::Msg: Sync,
{
let keys: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap())
.collect();
let msgs: Vec<[u8; 32]> = (0..n).map(test_msg).collect();
let pks: Vec<_> = keys.iter().map(BlsSecretKey::public_key).collect();
let sigs: Vec<_> = keys
.iter()
.zip(&msgs)
.map(|(key, msg)| key.sign(S::msg_ref(msg)))
.collect();
let sig_refs: Vec<&BlsSignature<S>> = sigs.iter().collect();
let aggregate = BlsSignature::<S>::aggregate(&sig_refs).unwrap();
let pk_refs: Vec<_> = pks.iter().collect();
let msg_refs: Vec<&S::Msg> = msgs.iter().map(|msg| S::msg_ref(msg)).collect();

bencher
.counter(ItemsCount::new(n))
.bench(|| aggregate.verify_aggregates(&msg_refs, &pk_refs));
}

/// Public-key-weighted aggregation, one scalar multiplication per signature on
/// top of the plain sum.
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [2, 10, 100])]
fn secure_aggregate_n<S: BlsScheme>(bencher: Bencher, n: usize) {
let keys: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap())
.collect();
let msg = test_msg(42);
let pks: Vec<_> = keys.iter().map(BlsSecretKey::public_key).collect();
let sigs: Vec<_> = keys.iter().map(|key| key.sign(S::msg_ref(&msg))).collect();
let sig_refs: Vec<&BlsSignature<S>> = sigs.iter().collect();
let pk_refs: Vec<_> = pks.iter().collect();

bencher
.counter(ItemsCount::new(n))
.bench(|| BlsSignature::<S>::secure_aggregate(&sig_refs, &pk_refs));
}

/// Evaluating the master secret polynomial at a participant id, over a master
/// key of `n` coefficients.
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [2, 5, 10])]
fn derive_share_n<S: BlsScheme>(bencher: Bencher, n: usize) {
let master: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap())
.collect();
let master_refs: Vec<&BlsSecretKey<S>> = master.iter().collect();
let id = sequential_ids(1)[0];

bencher
.counter(ItemsCount::new(n))
.bench(|| BlsSecretKey::<S>::derive_share(&master_refs, &id));
}

/// IETF-only BLS operations.
mod ietf {
use super::*;

/// Aggregate signatures over distinct messages, then verify.
#[divan::bench(args = [10, 100, 1000])]
fn verify_aggregated_block(bencher: Bencher, n: usize) {
let keys: Vec<_> = (0..n)
.map(|i| BlsSecretKey::<BlsScIetf>::generate(&test_ikm(i as u8)).unwrap())
.collect();
let msgs: Vec<[u8; 32]> = (0..n).map(|i| test_msg(i as u8)).collect();
let pks: Vec<_> = keys.iter().map(BlsSecretKey::public_key).collect();
let sigs: Vec<_> = keys
.iter()
.zip(&msgs)
.map(|(key, msg)| key.sign(msg.as_slice()))
.collect();
let sig_refs: Vec<&BlsSignature<BlsScIetf>> = sigs.iter().collect();
let aggregate = BlsSignature::<BlsScIetf>::aggregate(&sig_refs).unwrap();
let pk_refs: Vec<_> = pks.iter().collect();
let msg_refs: Vec<&[u8]> = msgs.iter().map(|msg| msg.as_slice()).collect();

bencher
.counter(ItemsCount::new(n))
.bench(|| aggregate.verify_aggregates(&msg_refs, &pk_refs));
}

/// Proof of possession creation.
#[divan::bench]
fn prove_pop(bencher: Bencher) {
Expand All @@ -214,8 +250,8 @@ mod worker {
fn setup_sigs<S: BlsScheme>(n: usize) -> Vec<(BlsSignature<S>, BlsPublicKey<S>, [u8; 32])> {
(0..n)
.map(|i| {
let sk = BlsSecretKey::<S>::generate(&test_ikm(i as u8)).unwrap();
let msg = test_msg(i as u8);
let sk = BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap();
let msg = test_msg(i);
let pk = sk.public_key();
let sig = sk.sign(S::msg_ref(&msg));
(sig, pk, msg)
Expand All @@ -234,7 +270,7 @@ mod worker {
#[divan::bench(types = [BlsScChia, BlsScIetf], args = [100, 1000])]
fn aggregate_pk_n<S: BlsScheme>(bencher: Bencher, n: usize) {
let pks: Vec<BlsPublicKey<S>> = (0..n)
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i as u8)).unwrap().public_key())
.map(|i| BlsSecretKey::<S>::generate(&test_ikm(i)).unwrap().public_key())
.collect();
bencher
.counter(ItemsCount::new(n))
Expand Down
58 changes: 58 additions & 0 deletions pkgs/pkc/corpus/bls_chia_aggregate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,63 @@
],
"agg_sig": "8584ad5356fbe1e04cc94f4d1a13e4d6055380105ea70f5a76a5e8740219276287f05cfcd2c82f013af553a1a791b2e20bd19c2e5c929a5d5b1fce1de6b3093a0c2da0c2381052552651d89e2d29c5df8ce7c638eda2717d9d0dbcd03e93f86a"
}
],
"aggregate_verify": [
{
"pks": [
"8a1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"0004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222"
],
"agg_sig": "8b1bcc746cd2d0d66a4c2f266b26cb9dbea97b365e24bda8902864596535d030b8477bf392c671fb7a69a21f4ddfcf2919f34b447662aa9ff76aa2b5c3de021b6c41993e1ec5e5a513378875a84da799f350406e5ba84f6a83d90cd773f2fd28",
"accepted": true
},
{
"pks": [
"8a1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"0004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c",
"8355519968b7db86b1ceb2261e179f6cde1a6010b8588e4a1a59eae804c9eed5f3e3d433a69dabb1eb7403c9c2721116"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222",
"3333333333333333333333333333333333333333333333333333333333333333"
],
"agg_sig": "0c35b81c8be4dfda86a8e2eccec0842c45652eb5132c83d03f3365b79d089c7f3f7110186944d33115af544e97d6814a0dba5b5c3413dcebf13532764535e8cc6cd7d66247bdd58b11653d9d832dcab9d55db16693ca61b0a7109358aa0af3ca",
"accepted": true
},
{
"pks": [
"8a1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"0004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c",
"8355519968b7db86b1ceb2261e179f6cde1a6010b8588e4a1a59eae804c9eed5f3e3d433a69dabb1eb7403c9c2721116",
"184c7b6984b75a5bd6f8a8b1db3eedb7624910057d2951c6d6b39afa2d0b5b192d42f4ef531fea1bdf563e7478c0b831",
"80d3ea109332aa3911781d3f6ab88750b1ea1322c1a4c503a4a855e610950eb9a3a11c1be648e914f74eae275d57f9b9"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222",
"3333333333333333333333333333333333333333333333333333333333333333",
"4444444444444444444444444444444444444444444444444444444444444444",
"5555555555555555555555555555555555555555555555555555555555555555"
],
"agg_sig": "0262ab395c3b1a757211230962494345b9b69cf5a5d97dc92d97214f29ddae01bc27d7ba858fb9fdbe415a7929e5969b0d6b64085701d7c35ea442684c62b198da24db8b4096b5701ea932637a972fe0d31edf44558e7f8dda4c3fe8b0cbc300",
"accepted": true
},
{
"pks": [
"8a1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"0004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"1111111111111111111111111111111111111111111111111111111111111111"
],
"agg_sig": "834c7d972c285c2ec38c99d600b18b0ae68fb9266a65358920131556b71a4420f43a24bc8278ba3f697d45054aba6606015f3247c157d6cc8c42041f05bcf52a59f256201b081a96a66a3dac7cffd1f86e66f63a16f90b02a2900a3123d6006f",
"accepted": true
}
]
}
58 changes: 58 additions & 0 deletions pkgs/pkc/corpus/bls_ietf_aggregate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,63 @@
],
"agg_sig": "aefe0f3eab10e0580edfcad7b31ee019a41d41291e8528a7fc9be42bfeaf1f3751548fbbde424b3e9ce934090ce0dd3701516fe9754fbbc7a9a0e083e4d02dffb9d532432ed8c181ffc5282cc5c17d8c79c68effd51fb37f173fd2f62ff66fa7"
}
],
"aggregate_verify": [
{
"pks": [
"aa1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"8004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222"
],
"agg_sig": "a1d5a771f58b0f5dfecf3c84a7b3f9dcdf5b5469f6d59998d8c6147a3a31853832a55cf658797c82e0c4df55d374312a0708504b17d7d553424809bce93a7aac8321008cf34c73640faf644ecc643baabc633ba8c14eda8fcd41a1c5a6030672",
"accepted": true
},
{
"pks": [
"aa1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"8004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c",
"a355519968b7db86b1ceb2261e179f6cde1a6010b8588e4a1a59eae804c9eed5f3e3d433a69dabb1eb7403c9c2721116"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222",
"3333333333333333333333333333333333333333333333333333333333333333"
],
"agg_sig": "940da8906951211c25b928f228342bf434b53a2770c3ea9f754df6d6ad8792a7d612f3b1c29c4662ddd5ff59fc26b3dc02ebb2ca823a1c09da9130291c0dc7aa2cd9a05d67b4f4c4a1192831f270780e319a1a2ce7aa1a34766a3571d4aa5430",
"accepted": true
},
{
"pks": [
"aa1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"8004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c",
"a355519968b7db86b1ceb2261e179f6cde1a6010b8588e4a1a59eae804c9eed5f3e3d433a69dabb1eb7403c9c2721116",
"984c7b6984b75a5bd6f8a8b1db3eedb7624910057d2951c6d6b39afa2d0b5b192d42f4ef531fea1bdf563e7478c0b831",
"a0d3ea109332aa3911781d3f6ab88750b1ea1322c1a4c503a4a855e610950eb9a3a11c1be648e914f74eae275d57f9b9"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222",
"3333333333333333333333333333333333333333333333333333333333333333",
"4444444444444444444444444444444444444444444444444444444444444444",
"5555555555555555555555555555555555555555555555555555555555555555"
],
"agg_sig": "a6aa06a4294d03ce142e8426fc2558389ed680402f4b882db16842a2454ec960b729ae1dc406ce01eccdefcaec67844c19a8c765d21da1084c8811af9f01b25617bdf0479ad6dca3aa942a33a7f0c82fdff5093c1e5aca763f9bf6d0f26e9ad3",
"accepted": true
},
{
"pks": [
"aa1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1",
"8004066a1a5cb9cdf244e45f0a59cf579a78d90ac0bc24663565264601c1c9251c0aa3dfb9835b520e0ba0f211a6696c"
],
"msgs": [
"1111111111111111111111111111111111111111111111111111111111111111",
"1111111111111111111111111111111111111111111111111111111111111111"
],
"agg_sig": "a61c6b1abaf8a0baac5947e9b2266e72285c10eb28db3023b0ec6e00fb77b63b8d65af635b73a1c12545e99ca331a6b407def3a9e0c152c8479994ea403e5f9c9665503b4a013ce3e7178734a0274094d9389c4bb9aca6be1b7506b8e25c8fea",
"accepted": false
}
]
}
43 changes: 43 additions & 0 deletions pkgs/pkc/src/bls/blst_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@ pub(crate) fn bendian_from_scalar(scalar: &blst_scalar) -> [u8; 32] {
out
}

/// Whether `e(G1 generator, lhs_g2)` equals the product of `e(g1, g2)` over
/// the paired slices, the multi-pairing behind per-signer-message verifying.
pub(crate) fn pairings_equal_with_g1_generator_prod(lhs_g2: &G2Affine, rhs_g2: &[G2], rhs_g1: &[&G1Affine]) -> bool {
if rhs_g2.len() != rhs_g1.len() || rhs_g2.is_empty() {
return false;
}

let lhs_g2_aff = blst_p2_affine::from(*lhs_g2);
let g1_generator = blst_p1_affine::from(G1Affine::generator());
let mut lhs = blst_fp12::default();

unsafe {
blst_miller_loop(&mut lhs, &lhs_g2_aff, &g1_generator);
let mut rhs = *blst_fp12_one();
for (g2, g1) in rhs_g2.iter().zip(rhs_g1) {
let g2_aff = blst_p2_affine::from(g2.to_affine());
let g1_aff = blst_p1_affine::from(**g1);
let mut term = blst_fp12::default();
blst_miller_loop(&mut term, &g2_aff, &g1_aff);
let acc = rhs;
blst_fp12_mul(&mut rhs, &acc, &term);
}
blst_fp12_finalverify(&lhs, &rhs)
}
}

/// Pairing check `e(lhs_g2, G1) == e(rhs_g2, rhs_g1)`
pub(crate) fn pairings_equal_with_g1_generator(lhs_g2: &G2Affine, rhs_g2: &G2, rhs_g1: &G1Affine) -> bool {
let lhs_g2_aff = blst_p2_affine::from(*lhs_g2);
Expand Down Expand Up @@ -345,6 +371,12 @@ pub(crate) trait Point: Copy + Default + Add<Output = Self> {
pub struct G1(blst_p1);

impl G1 {
/// Whether the point lies in the prime-order subgroup.
#[cfg(test)]
pub(crate) fn in_subgroup(&self) -> bool {
unsafe { blst_p1_in_g1(&self.0) }
}

/// Convert to affine coordinates.
pub(crate) fn to_affine(self) -> G1Affine {
let mut aff = blst_p1_affine::default();
Expand Down Expand Up @@ -434,6 +466,12 @@ impl G2 {
Self(unsafe { *blst_p2_generator() })
}

/// Whether the point lies in the prime-order subgroup.
#[cfg(test)]
pub(crate) fn in_subgroup(&self) -> bool {
unsafe { blst_p2_in_g2(&self.0) }
}

/// Point doubling.
pub(crate) fn double(&self) -> Self {
let mut out = blst_p2::default();
Expand Down Expand Up @@ -515,6 +553,11 @@ impl G2Affine {
G2(out)
}

/// Whether the point is at infinity.
pub(crate) fn is_inf(&self) -> bool {
unsafe { blst_p2_affine_is_inf(&self.0) }
}

/// Serialize to the 96-byte compressed encoding.
pub(crate) fn compress(&self) -> [u8; 96] {
let mut out = [0u8; 96];
Expand Down
Loading
Loading