From 26ebfb811d8612551ff7ddc8d7223c8d592b6292 Mon Sep 17 00:00:00 2001 From: Cassandra Heart Date: Fri, 5 Jul 2024 02:16:04 -0500 Subject: [PATCH] v1.4.21 --- Cargo.lock | 198 ++++++++++++++++++++++++++- crates/bls48581/Cargo.toml | 10 +- crates/bls48581/benches/bench_bls.rs | 20 +++ crates/bls48581/src/lib.rs | 130 ++++++++---------- node/config/p2p.go | 2 + node/config/version.go | 4 +- node/crypto/channel/feldman_test.go | 2 +- node/p2p/blossomsub.go | 19 ++- 8 files changed, 299 insertions(+), 86 deletions(-) create mode 100644 crates/bls48581/benches/bench_bls.rs diff --git a/Cargo.lock b/Cargo.lock index d7c2a8f..d8ac732 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,17 @@ dependencies = [ "nom", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -143,6 +154,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "block-buffer" version = "0.7.3" @@ -168,7 +185,9 @@ dependencies = [ name = "bls48581" version = "0.1.0" dependencies = [ + "criterion 0.4.0", "hex 0.4.3", + "rand", "serde_json", "uniffi", ] @@ -268,6 +287,18 @@ dependencies = [ "half", ] +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "bitflags", + "clap_lex 0.2.4", + "indexmap", + "textwrap", +] + [[package]] name = "clap" version = "4.5.4" @@ -286,7 +317,7 @@ checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", - "clap_lex", + "clap_lex 0.7.0", "strsim", ] @@ -302,6 +333,15 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "clap_lex" version = "0.7.0" @@ -312,7 +352,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" name = "classgroup" version = "0.1.0" dependencies = [ - "criterion", + "criterion 0.5.1", "libc", "num-traits", ] @@ -323,6 +363,32 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "criterion" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +dependencies = [ + "anes", + "atty", + "cast", + "ciborium", + "clap 3.2.25", + "criterion-plot", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + [[package]] name = "criterion" version = "0.5.1" @@ -332,7 +398,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap", + "clap 4.5.4", "criterion-plot", "is-terminal", "itertools", @@ -429,6 +495,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "glob" version = "0.3.1" @@ -456,6 +533,12 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "heck" version = "0.4.1" @@ -468,6 +551,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -486,13 +578,23 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "is-terminal" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys", ] @@ -527,6 +629,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.155" @@ -610,6 +718,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + [[package]] name = "paste" version = "1.0.15" @@ -650,6 +764,12 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.85" @@ -668,6 +788,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.10.0" @@ -833,6 +983,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + [[package]] name = "thiserror" version = "1.0.61" @@ -901,7 +1057,7 @@ checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f" dependencies = [ "anyhow", "camino", - "clap", + "clap 4.5.4", "uniffi_bindgen", "uniffi_build", "uniffi_core", @@ -918,7 +1074,7 @@ dependencies = [ "askama", "camino", "cargo_metadata", - "clap", + "clap 4.5.4", "fs-err", "glob", "goblin", @@ -1037,7 +1193,7 @@ version = "0.1.0" dependencies = [ "bit-vec", "classgroup", - "criterion", + "criterion 0.5.1", "hex 0.3.2", "num-traits", "sha2", @@ -1060,6 +1216,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -1133,6 +1295,22 @@ dependencies = [ "nom", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.8" @@ -1142,6 +1320,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/crates/bls48581/Cargo.toml b/crates/bls48581/Cargo.toml index 7c5a13f..e0664c9 100644 --- a/crates/bls48581/Cargo.toml +++ b/crates/bls48581/Cargo.toml @@ -12,5 +12,13 @@ hex = "0.4.3" serde_json = "1.0.117" uniffi = { version= "0.25", features = ["cli"]} +[dev-dependencies] +criterion = { version = "0.4", features = ["html_reports"] } +rand = "0.8.5" + [build-dependencies] -uniffi = { version = "0.25", features = [ "build" ] } \ No newline at end of file +uniffi = { version = "0.25", features = [ "build" ] } + +[[bench]] +name = "bench_bls" +harness = false \ No newline at end of file diff --git a/crates/bls48581/benches/bench_bls.rs b/crates/bls48581/benches/bench_bls.rs new file mode 100644 index 0000000..147acda --- /dev/null +++ b/crates/bls48581/benches/bench_bls.rs @@ -0,0 +1,20 @@ +use rand::Rng; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + +fn criterion_benchmark(c: &mut Criterion) { + bls48581::init(); + let mut bytes = vec![0u8; 65536]; + rand::thread_rng().fill(&mut bytes[..]); + + let mut group = c.benchmark_group("commit"); + group.sample_size(10); + group.bench_function("commit 16", |b| b.iter(|| black_box(bls48581::commit_raw(&bytes, 16)))); + group.bench_function("commit 128", |b| b.iter(|| black_box(bls48581::commit_raw(&bytes, 128)))); + group.bench_function("commit 256", |b| b.iter(|| black_box(bls48581::commit_raw(&bytes, 256)))); + group.bench_function("commit 1024", |b| b.iter(|| black_box(bls48581::commit_raw(&bytes, 1024)))); + group.bench_function("commit 65536", |b| b.iter(|| black_box(bls48581::commit_raw(&bytes, 65536)))); + group.finish(); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); \ No newline at end of file diff --git a/crates/bls48581/src/lib.rs b/crates/bls48581/src/lib.rs index ea0a3ef..4644c39 100644 --- a/crates/bls48581/src/lib.rs +++ b/crates/bls48581/src/lib.rs @@ -49,35 +49,18 @@ fn recurse_fft( fft_width: u64, inverse: bool, ) { + let M = &big::BIG::new_ints(&rom::CURVE_ORDER); let roots = if inverse { &bls::singleton().ReverseRootsOfUnityBLS48581[&fft_width] } else { &bls::singleton().RootsOfUnityBLS48581[&fft_width] }; - if out.len() <= 16 { - let l = out.len() as u64; - for i in 0..l { - let mut last = big::BIG::modmul( - &values[offset as usize], - &roots[0], - &big::BIG::new_ints(&rom::CURVE_ORDER), - ); - - for j in 1..l { - let mid = big::BIG::modmul( - &values[(offset + j * stride) as usize], - &roots[((i * j) % l) as usize * roots_stride as usize], - &big::BIG::new_ints(&rom::CURVE_ORDER), - ); - last = big::BIG::modadd( - &last, - &mid, - &big::BIG::new_ints(&rom::CURVE_ORDER), - ); - } - out[i as usize] = last; - } + if out.len() == 1 { + // optimization: we're working in bls48-581, the first roots of unity + // value is always 1 no matter the fft width, so we can skip the + // multiplication: + out[0] = values[offset as usize].clone(); return; } @@ -107,26 +90,26 @@ fn recurse_fft( // cha cha now, y'all for i in 0..half { - let mul = big::BIG::modmul( - &out[(i + half) as usize], - &roots[(i * roots_stride) as usize], - &big::BIG::new_ints(&rom::CURVE_ORDER), - ); - let mul_add = big::BIG::modadd( - &out[i as usize], - &mul, - &big::BIG::new_ints(&rom::CURVE_ORDER), - ); - out[(i + half) as usize] = big::BIG::modadd( - &out[i as usize], - &big::BIG::modneg(&mul, &big::BIG::new_ints(&rom::CURVE_ORDER)), - &big::BIG::new_ints(&rom::CURVE_ORDER), - ); - out[i as usize] = mul_add; + let mul = big::BIG::modmul( + &out[(i + half) as usize], + &roots[(i * roots_stride) as usize], + &big::BIG::new_ints(&rom::CURVE_ORDER), + ); + let mul_add = big::BIG::modadd( + &out[i as usize], + &mul, + &big::BIG::new_ints(&rom::CURVE_ORDER), + ); + out[(i + half) as usize] = big::BIG::modadd( + &out[i as usize], + &big::BIG::modneg(&mul, &big::BIG::new_ints(&rom::CURVE_ORDER)), + &big::BIG::new_ints(&rom::CURVE_ORDER), + ); + out[i as usize] = mul_add; } } -fn fft( +pub fn fft( values: &[big::BIG], fft_width: u64, inverse: bool, @@ -183,21 +166,8 @@ fn recurse_fft_g1( &bls::singleton().RootsOfUnityBLS48581[&fft_width] }; - if out.len() <= 16 { - let l = out.len() as u64; - for i in 0..l { - let mut last = ecp::ECP::mul(&values[offset as usize].clone(), &roots[0]); - - for j in 1..l { - let mid = ecp::ECP::mul( - &values[(offset + j * stride) as usize].clone(), - &roots[((i * j) % l) as usize * roots_stride as usize], - ); - &last.add(&mid); - } - - out[i as usize] = last.clone(); - } + if out.len() == 1 { + out[0] = values[offset as usize].clone(); return; } @@ -227,7 +197,9 @@ fn recurse_fft_g1( // cha cha now, y'all for i in 0..half { - let mul = out[(i + half) as usize].clone().mul(&roots[(i * roots_stride) as usize].clone()); + let mul = out[(i + half) as usize].clone().mul( + &roots[(i * roots_stride) as usize].clone(), + ); let mut mul_add = out[i as usize].clone(); mul_add.add(&mul.clone()); out[(i + half) as usize] = out[i as usize].clone(); @@ -236,7 +208,7 @@ fn recurse_fft_g1( } } -fn fft_g1( +pub fn fft_g1( values: &[ecp::ECP], fft_width: u64, inverse: bool, @@ -291,7 +263,7 @@ fn bytes_to_polynomial( let size = bytes.len() / 64; let trunc_last = bytes.len() % 64 > 0; - let mut poly = Vec::new(); + let mut poly = Vec::with_capacity(size + (if trunc_last { 1 } else { 0 })); for i in 0..size { let scalar = big::BIG::frombytes(&bytes[i * 64..(i + 1) * 64]); @@ -306,8 +278,8 @@ fn bytes_to_polynomial( return poly; } -fn point_linear_combination( - points: &Vec<&ecp::ECP>, +pub fn point_linear_combination( + points: &[ecp::ECP], scalars: &Vec, ) -> Result> { if points.len() != scalars.len() { @@ -318,14 +290,7 @@ fn point_linear_combination( ).into()); } - let mut result = ecp::ECP::new(); - - for (i, point) in points.iter().enumerate() { - let c = point.clone(); - let p = c.mul(&scalars[i]); - - &result.add(&p); - } + let result = ecp::ECP::muln(points.len(), points, scalars.as_slice()); Ok(result) } @@ -362,7 +327,7 @@ pub fn commit_raw( poly.push(big::BIG::new()); } match point_linear_combination( - &bls::singleton().FFTBLS48581[&poly_size].iter().collect(), + &bls::singleton().FFTBLS48581[&poly_size], &poly, ) { Ok(commit) => { @@ -440,7 +405,7 @@ pub fn prove_raw( } match point_linear_combination( - &bls::singleton().CeremonyBLS48581G1[..(poly_size as usize - 1)].iter().collect(), + &bls::singleton().CeremonyBLS48581G1[..(poly_size as usize - 1)], &out, ) { Ok(proof) => { @@ -483,4 +448,29 @@ pub fn verify_raw( pub fn init() { bls::singleton(); +} + +#[cfg(test)] +mod tests { + use ecp::ECP; + + use super::*; + + #[test] + fn fft_matches_fft_g1_when_raised() { + init(); + let mut rand = rand::RAND::new(); + let mut v = vec![big::BIG::new(); 16]; + let mut vp = vec![ECP::new(); 16]; + for i in 0..16 { + v[i] = big::BIG::random(&mut rand); + vp[i] = ECP::generator().mul(&v[i]); + } + let scalars = fft(v.as_slice(), 16, false).unwrap(); + let points = fft_g1(vp.as_slice(), 16, false).unwrap(); + for (i, s) in scalars.iter().enumerate() { + let sp = ECP::generator().mul(&s); + assert!(points[i].equals(&sp)); + } + } } \ No newline at end of file diff --git a/node/config/p2p.go b/node/config/p2p.go index 2493c58..e048de7 100644 --- a/node/config/p2p.go +++ b/node/config/p2p.go @@ -38,4 +38,6 @@ type P2PConfig struct { TraceLogFile string `yaml:"traceLogFile"` MinPeers int `yaml:"minPeers"` Network uint8 `yaml:"network"` + LowWatermarkConnections uint `yaml:"lowWatermarkConnections"` + HighWatermarkConnections uint `yaml:"highWatermarkConnections"` } diff --git a/node/config/version.go b/node/config/version.go index 92ef409..c3a1199 100644 --- a/node/config/version.go +++ b/node/config/version.go @@ -14,7 +14,7 @@ func GetMinimumVersion() []byte { } func GetVersion() []byte { - return []byte{0x01, 0x04, 0x14} + return []byte{0x01, 0x04, 0x15} } func GetVersionString() string { @@ -36,5 +36,5 @@ func FormatVersion(version []byte) string { } func GetPatchNumber() byte { - return 0x01 + return 0x00 } diff --git a/node/crypto/channel/feldman_test.go b/node/crypto/channel/feldman_test.go index bdd9e4b..a8c5f7a 100644 --- a/node/crypto/channel/feldman_test.go +++ b/node/crypto/channel/feldman_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves" - "source.quilibrium.com/quilibrium/monorepo/node/crypto" + crypto "source.quilibrium.com/quilibrium/monorepo/node/crypto/channel" ) func TestFeldman(t *testing.T) { diff --git a/node/p2p/blossomsub.go b/node/p2p/blossomsub.go index b129b2a..b409e0b 100644 --- a/node/p2p/blossomsub.go +++ b/node/p2p/blossomsub.go @@ -23,6 +23,7 @@ import ( "github.com/libp2p/go-libp2p/p2p/discovery/routing" "github.com/libp2p/go-libp2p/p2p/discovery/util" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" + "github.com/libp2p/go-libp2p/p2p/net/connmgr" "github.com/mr-tron/base58" "github.com/multiformats/go-multiaddr" "github.com/pkg/errors" @@ -150,6 +151,19 @@ func NewBlossomSub( opts = append(opts, libp2p.Peerstore(ps)) + if p2pConfig.LowWatermarkConnections != 0 && + p2pConfig.HighWatermarkConnections != 0 { + cm, err := connmgr.NewConnManager( + int(p2pConfig.LowWatermarkConnections), + int(p2pConfig.HighWatermarkConnections), + connmgr.WithEmergencyTrim(true), + ) + if err != nil { + panic(err) + } + opts = append(opts, libp2p.ConnectionManager(cm)) + } + bs := &BlossomSub{ ctx: ctx, logger: logger, @@ -189,11 +203,6 @@ func NewBlossomSub( } blossomOpts := []blossomsub.Option{} - if isBootstrapPeer { - blossomOpts = append(blossomOpts, - blossomsub.WithPeerExchange(true), - ) - } if tracer != nil { blossomOpts = append(blossomOpts, blossomsub.WithEventTracer(tracer))