From 61bbef03fce594fd92097324d7097d541cecad38 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Mon, 14 Oct 2024 17:13:47 +0800 Subject: [PATCH 01/10] rm submodule --- .gitmodules | 3 --- Utils/Sources/blst | 1 - 2 files changed, 4 deletions(-) delete mode 160000 Utils/Sources/blst diff --git a/.gitmodules b/.gitmodules index 8dd5769d..5cdb516b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "JAMTests/jamtestvectors"] path = JAMTests/jamtestvectors url = https://github.com/AcalaNetwork/jamtestvectors.git -[submodule "blst"] - path = Utils/Sources/blst - url = https://github.com/supranational/blst.git diff --git a/Utils/Sources/blst b/Utils/Sources/blst deleted file mode 160000 index e99f7db0..00000000 --- a/Utils/Sources/blst +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e99f7db0db413e2efefcfd077a4e335766f39c27 From bec4e14661db47b433a251dc915cd80d2124c8c4 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Wed, 16 Oct 2024 11:44:34 +0800 Subject: [PATCH 02/10] new ffi --- .github/workflows/ci.yml | 22 +- .../Blockchain/Types/State+Genesis.swift | 2 +- .../bandersnatch/Cargo.lock => Cargo.lock | 522 ++++++++++++-- Cargo.toml | 6 + Makefile | 10 +- Utils/Package.swift | 4 +- Utils/Sources/Utils/Crypto/BLS.swift | 285 +++++--- Utils/Sources/Utils/Crypto/Bandersnatch.swift | 101 +-- Utils/Sources/Utils/Crypto/FFIUtils.swift | 78 ++ Utils/Sources/bls/Cargo.toml | 18 + Utils/Sources/bls/bindings.h | 61 ++ Utils/Sources/bls/build.rs | 14 + Utils/Sources/bls/cbindgen.toml | 12 + Utils/Sources/bls/src/bls.rs | 32 + Utils/Sources/bls/src/ffi.rs | 283 ++++++++ Utils/Sources/bls/src/lib.rs | 4 + Utils/Sources/erasure-coding/Cargo.lock | 674 ------------------ Utils/Sources/module.modulemap | 6 +- scripts/bandersnatch.sh | 17 - scripts/blst.sh | 17 - scripts/build-rust-libs.sh | 15 + scripts/erasure-coding.sh | 17 - 22 files changed, 1196 insertions(+), 1004 deletions(-) rename Utils/Sources/bandersnatch/Cargo.lock => Cargo.lock (66%) create mode 100644 Cargo.toml create mode 100644 Utils/Sources/Utils/Crypto/FFIUtils.swift create mode 100644 Utils/Sources/bls/Cargo.toml create mode 100644 Utils/Sources/bls/bindings.h create mode 100644 Utils/Sources/bls/build.rs create mode 100644 Utils/Sources/bls/cbindgen.toml create mode 100644 Utils/Sources/bls/src/bls.rs create mode 100644 Utils/Sources/bls/src/ffi.rs create mode 100644 Utils/Sources/bls/src/lib.rs delete mode 100644 Utils/Sources/erasure-coding/Cargo.lock delete mode 100755 scripts/bandersnatch.sh delete mode 100755 scripts/blst.sh create mode 100755 scripts/build-rust-libs.sh delete mode 100755 scripts/erasure-coding.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 725143b4..c1ba4c58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,10 +34,6 @@ jobs: - uses: awalsh128/cache-apt-pkgs-action@latest with: packages: librocksdb-dev libzstd-dev libbz2-dev liblz4-dev - - name: Get blst submodule commit hash - id: blst-commit-hash - run: | - echo "commit-hash=$(git submodule status Utils/Sources/blst/ | cut -c2-41)" >> $GITHUB_OUTPUT - name: Cache SPM uses: actions/cache@v4 with: @@ -53,15 +49,8 @@ jobs: ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ - Utils/Sources/bandersnatch/target/ + target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Cache blst static lib - uses: actions/cache@v4 - with: - path: .lib/libblst.a - key: ${{ runner.os }}-libs-blst-${{ steps.blst-commit-hash.outputs.commit-hash }} - restore-keys: | - ${{ runner.os }}-libs-blst - name: Cache bandersnatch_vrfs static lib uses: actions/cache@v4 with: @@ -69,6 +58,13 @@ jobs: key: ${{ runner.os }}-libs-libbandersnatch-${{ hashFiles('Utils/Sources/bandersnatch/**') }} restore-keys: | ${{ runner.os }}-libs-libbandersnatch + - name: Cache bls static lib + uses: actions/cache@v4 + with: + path: .lib/libbls.a + key: ${{ runner.os }}-libs-libbls-${{ hashFiles('Utils/Sources/bls/**') }} + restore-keys: | + ${{ runner.os }}-libs-libbls - name: Cache erasure-coding static lib uses: actions/cache@v4 with: @@ -83,7 +79,7 @@ jobs: with: components: rustfmt - name: Check rust format - run: cargo +nightly fmt --all --manifest-path Utils/Sources/bandersnatch/Cargo.toml -- --check + run: cargo +nightly fmt --all -- --check - name: Build run: make build - name: Test diff --git a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift index df08f188..0d23da39 100644 --- a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift +++ b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift @@ -11,7 +11,7 @@ extension State { devKeys.append(ValidatorKey( bandersnatch: keySet.bandersnatch.data, ed25519: keySet.ed25519.data, - bls: Data144(), // TODO: figure out BLS pub key size + bls: Data144(), metadata: Data128() )) } diff --git a/Utils/Sources/bandersnatch/Cargo.lock b/Cargo.lock similarity index 66% rename from Utils/Sources/bandersnatch/Cargo.lock rename to Cargo.lock index 6358e635..eb3e55ef 100644 --- a/Utils/Sources/bandersnatch/Cargo.lock +++ b/Cargo.lock @@ -50,7 +50,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -60,7 +60,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ark-bls12-377" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb00293ba84f51ce3bd026bd0de55899c4e68f0a39a5728cebae3a73ffdc0a4f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", ] [[package]] @@ -230,27 +241,50 @@ dependencies = [ "sha3", ] +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bandersnatch-vrfs" version = "0.1.0" dependencies = [ "ark-ec-vrfs", - "cbindgen", + "cbindgen 0.27.0", "hex-literal", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" @@ -266,6 +300,17 @@ dependencies = [ "digest", ] +[[package]] +name = "blake2b_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -275,29 +320,80 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bls" +version = "0.1.0" +dependencies = [ + "cbindgen 0.27.0", + "hex-literal", + "w3f-bls", +] + +[[package]] +name = "bounded-collections" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca548b6163b872067dc5eb82fd130c56881435e30367d2073594a3d9744120dd" +dependencies = [ + "log", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytemuck" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" + [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "cbindgen" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" +dependencies = [ + "clap 3.2.25", + "heck", + "indexmap 1.9.3", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 1.0.109", + "tempfile", + "toml 0.5.11", +] + [[package]] name = "cbindgen" version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb" dependencies = [ - "clap", + "clap 4.5.20", "heck", - "indexmap", + "indexmap 2.6.0", "log", "proc-macro2", "quote", "serde", "serde_json", - "syn 2.0.72", + "syn 2.0.79", "tempfile", - "toml", + "toml 0.8.19", ] [[package]] @@ -308,23 +404,47 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.19" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex 0.2.4", + "indexmap 1.9.3", + "strsim 0.10.0", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", - "clap_lex", - "strsim", + "clap_lex 0.7.2", + "strsim 0.11.1", +] + +[[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]] @@ -354,11 +474,23 @@ dependencies = [ "rayon", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "constcat" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08" + [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -409,6 +541,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "digest" version = "0.10.7" @@ -420,6 +563,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "ec" +version = "0.1.0" +dependencies = [ + "cbindgen 0.24.5", + "erasure-coding", + "hex", + "serde", + "serde_json", +] + [[package]] name = "either" version = "1.13.0" @@ -432,6 +586,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erasure-coding" +version = "0.1.0" +source = "git+https://github.com/paritytech/erasure-coding?rev=512e774#512e77472beb877fe0881a857623d54d97b82bc4" +dependencies = [ + "blake2b_simd", + "bounded-collections", + "parity-scale-codec", + "reed-solomon-simd", + "thiserror", +] + [[package]] name = "errno" version = "0.3.9" @@ -439,14 +605,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fflonk" @@ -462,6 +628,12 @@ dependencies = [ "rayon", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "generic-array" version = "0.14.7" @@ -493,6 +665,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.13.2" @@ -514,12 +692,48 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hex-literal" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.6.0" @@ -562,9 +776,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "linux-raw-sys" @@ -626,9 +840,39 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "paste" @@ -638,24 +882,36 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -710,6 +966,23 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "readme-rustdocifier" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ad765b21a08b1a8e5cdce052719188a23772bcbefb3c439f0baaf62c56ceac" + +[[package]] +name = "reed-solomon-simd" +version = "2.2.1" +source = "git+https://github.com/ordian/reed-solomon-simd?branch=simd-feature#2e7136fc19f599d7f11f86d51c356482d71ef980" +dependencies = [ + "bytemuck", + "fixedbitset", + "once_cell", + "readme-rustdocifier", +] + [[package]] name = "ring" version = "0.1.0" @@ -730,24 +1003,24 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -756,6 +1029,30 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "scale-info" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "semver" version = "1.0.23" @@ -764,29 +1061,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -824,6 +1121,12 @@ dependencies = [ "keccak", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -849,9 +1152,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -860,14 +1163,59 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[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.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", ] [[package]] @@ -897,7 +1245,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -912,9 +1260,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "utf8parse" @@ -928,12 +1276,66 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "w3f-bls" +version = "0.1.5" +source = "git+https://github.com/w3f/bls?rev=c19bbe8#c19bbe843593236246cb6d084673d3b15b9c0b76" +dependencies = [ + "ark-bls12-377", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-serialize-derive", + "arrayref", + "constcat", + "digest", + "rand", + "rand_chacha", + "rand_core", + "sha2", + "sha3", + "thiserror", + "zeroize", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[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" @@ -943,6 +1345,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1022,6 +1433,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] @@ -1033,7 +1445,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1053,5 +1465,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..0a64d192 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = [ + "Utils/Sources/bandersnatch", + "Utils/Sources/bls", + "Utils/Sources/erasure-coding", +] diff --git a/Makefile b/Makefile index 47972aab..088b34d3 100644 --- a/Makefile +++ b/Makefile @@ -8,16 +8,16 @@ default: build githooks: .git/hooks/pre-commit .PHONY: deps -deps: .lib/libblst.a .lib/libbandersnatch_vrfs.a .lib/libec.a .lib/libmsquic.a +deps: .lib/libbls.a .lib/libbandersnatch_vrfs.a .lib/libec.a .lib/libmsquic.a -.lib/libblst.a: - ./scripts/blst.sh +.lib/libbls.a: $(wildcard Utils/Sources/bls/src/*) + ./scripts/build-rust-libs.sh .lib/libbandersnatch_vrfs.a: $(wildcard Utils/Sources/bandersnatch/src/*) - ./scripts/bandersnatch.sh + ./scripts/build-rust-libs.sh .lib/libec.a: $(wildcard Utils/Sources/erasure-coding/src/*) - ./scripts/erasure-coding.sh + ./scripts/build-rust-libs.sh .lib/libmsquic.a: ./scripts/external-libs.sh diff --git a/Utils/Package.swift b/Utils/Package.swift index 795f590a..3856854b 100644 --- a/Utils/Package.swift +++ b/Utils/Package.swift @@ -36,7 +36,7 @@ let package = Package( .product(name: "Crypto", package: "swift-crypto"), .product(name: "Atomics", package: "swift-atomics"), .product(name: "Numerics", package: "swift-numerics"), - "blst", + "bls", "bandersnatch_vrfs", "erasure_coding", "SHA3IUF", @@ -54,7 +54,7 @@ let package = Package( publicHeadersPath: "." ), .systemLibrary( - name: "blst", + name: "bls", path: "Sources" ), .systemLibrary( diff --git a/Utils/Sources/Utils/Crypto/BLS.swift b/Utils/Sources/Utils/Crypto/BLS.swift index 0a595fc9..b1afe851 100644 --- a/Utils/Sources/Utils/Crypto/BLS.swift +++ b/Utils/Sources/Utils/Crypto/BLS.swift @@ -1,88 +1,101 @@ -import blst +import bls import Foundation +import TracingUtils + +private let logger = Logger(label: "BLS") -/// A wrapper to blst C library. -/// -/// `blst_p1` for public keys, and `blst_p2` for signatures public enum BLS: KeyType { public enum Error: Swift.Error { - case blstError(BLST_ERROR) + case createSecretFailed(Int) + case createPublicKeyFailed(Int) + case createMessageFailed(Int) + case createSignatureFailed(Int) + case keypairSignFailed(Int) + case signatureVerifyFailed(Int) + case aggregateSigsFailed(Int) + case aggregatedVerifyFailed(Int) } public final class SecretKey: SecretKeyProtocol, @unchecked Sendable { - private var sk: blst_scalar - + fileprivate let keyPairPtr: SendableOpaquePointer public let publicKey: PublicKey - /// Initiate a BLS secret key with IKM. - /// IKM MUST be infeasible to guess, e.g., generated by a trusted source of randomness. - /// IKM MUST be at least 32 bytes long, but it MAY be longer. - public init(from ikm: Data32) throws { - sk = blst_scalar() + public init(from seed: Data32) throws(Error) { + var ptr: OpaquePointer! - // avoid capture self - withUnsafeMutablePointer(to: &sk) { sk in - ikm.data.withUnsafeBytes { ptr in - blst_keygen(sk, ptr.baseAddress, ikm.data.count, nil, 0) - } + try FFIUtils.call(seed.data) { ptrs in + keypair_new(ptrs[0].ptr, ptrs[0].count, &ptr) + } onErr: { err throws(Error) in + throw .createSecretFailed(err) } - var pk = blst_p1() - blst_sk_to_pk_in_g1(&pk, &sk) - - publicKey = PublicKey(pk: &pk) + keyPairPtr = ptr.asSendable + publicKey = try PublicKey(keyPair: ptr) } - public func sign(message: Data) -> Data96 { - var msgHash = blst_p2() - - message.withUnsafeBytes { ptr in - blst_hash_to_g2(&msgHash, ptr.baseAddress, ptr.count, nil, 0, nil, 0) - } + deinit { + keypair_free(keyPairPtr.value) + } - var sig = blst_p2() - blst_sign_pk_in_g1(&sig, &msgHash, &sk) + public func sign(message: Data) throws(Error) -> Data96 { + var output = Data(repeating: 0, count: 96) - var sigBytes = Data(repeating: 0, count: 96) - sigBytes.withUnsafeMutableBytes { ptr in - blst_p2_compress(ptr.baseAddress, &sig) + try FFIUtils.call(message, out: &output) { ptrs, out_buf in + keypair_sign( + keyPairPtr.value, + ptrs[0].ptr, + ptrs[0].count, + out_buf.ptr, + out_buf.count + ) + } onErr: { err throws(Error) in + throw .keypairSignFailed(err) } - return Data96(sigBytes)! + return Data96(Data(output))! } } public final class PublicKey: PublicKeyProtocol, @unchecked Sendable { - // this is immutable after initialization but C API requires it to be mutable - fileprivate var pk = blst_p1_affine() - public let data: Data48 + fileprivate let ptr: SendableOpaquePointer + public let data: Data144 + + public init(data: Data144) throws(Error) { + var ptr: OpaquePointer! + try FFIUtils.call(data.data) { ptrs in + public_new_from_data(ptrs[0].ptr, ptrs[0].count, &ptr) + } onErr: { err throws(Error) in + throw .createPublicKeyFailed(err) + } + self.ptr = ptr.asSendable + self.data = data + } - fileprivate init(pk: inout blst_p1) { - var data = Data(repeating: 0, count: 48) + fileprivate init(keyPair: OpaquePointer) throws(Error) { + var ptr: OpaquePointer! + try FFIUtils.call { _ in + public_new_from_keypair(keyPair, &ptr) + } onErr: { err throws(Error) in + throw .createPublicKeyFailed(err) + } - data.withUnsafeMutableBytes { ptr in - blst_p1_compress(ptr.baseAddress, &pk) + var data = Data(repeating: 0, count: 144) + FFIUtils.call(out: &data) { _, out_buf in + public_serialize(ptr, out_buf.ptr, out_buf.count) } - blst_p1_to_affine(&self.pk, &pk) - self.data = Data48(data)! + self.ptr = ptr.asSendable + self.data = Data144(data)! } - public init(from data: Data48) throws { - self.data = data - - try data.data.withUnsafeBytes { ptr in - let result = blst_p1_uncompress(&pk, ptr.baseAddress) - guard result == BLST_SUCCESS else { - throw Error.blstError(result) - } - } + deinit { + public_free(ptr.value) } public convenience init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - let data = try container.decode(Data48.self) - try self.init(from: data) + let data = try container.decode(Data144.self) + try self.init(data: data) } public func encode(to encoder: Encoder) throws { @@ -102,92 +115,140 @@ public enum BLS: KeyType { data.description } - public func verify(signature: Data96, message: Data) -> Bool { - var sig = blst_p2_affine() - - let res = signature.data.withUnsafeBytes { ptr in - blst_p2_uncompress(&sig, ptr.baseAddress) - } - - guard res == BLST_SUCCESS else { - return false - } - - let verifyResult = message.withUnsafeBytes { ptr in - blst_core_verify_pk_in_g1( - &pk, &sig, true, ptr.baseAddress, ptr.count, nil, 0, nil, 0 + public func verify(signature: Data96, message: Data) throws(Error) -> Bool { + var output = Data(repeating: 0, count: 1) + + try FFIUtils.call(signature.data, message, out: &output) { ptrs, out_buf in + public_verify( + ptr.value, + ptrs[0].ptr, + ptrs[0].count, + ptrs[1].ptr, + ptrs[1].count, + out_buf.ptr, + out_buf.count ) + } onErr: { err throws(Error) in + throw .signatureVerifyFailed(err) } - return verifyResult == BLST_SUCCESS + return output[0] == 1 } } public static func aggregateVerify( - signature: Data96, messages: [Data], publicKeys: [PublicKey] - ) -> Bool { + signatures: [Data96], messages: [Data], publicKeys: [PublicKey] + ) throws(Error) -> Bool { if messages.count != publicKeys.count { return false } - let size = blst_pairing_sizeof() - let ctx = OpaquePointer(malloc(size)) - defer { free(UnsafeMutableRawPointer(ctx)) } + var msgPtrs: [OpaquePointer?] = [] + var keyPtrs: [OpaquePointer?] = [] + var sigPtrs: [OpaquePointer?] = [] - blst_pairing_init(ctx, true, nil, 0) - - var sig = blst_p2_affine() - let sigResult = blst_p2_uncompress(&sig, [UInt8](signature.data)) - guard sigResult == BLST_SUCCESS else { - return false + defer { + for msgPtr in msgPtrs { + message_free(msgPtr) + } + for sigPtr in sigPtrs { + signature_free(sigPtr) + } + // do not free public keys here as they're owned externally } - var first = true - for (key, message) in zip(publicKeys, messages) { - let res = message.withUnsafeBytes { ptr in - if first { - blst_pairing_aggregate_pk_in_g1( - ctx, &key.pk, &sig, ptr.baseAddress, ptr.count, nil, 0 - ) - } else { - blst_pairing_aggregate_pk_in_g1( - ctx, &key.pk, nil, ptr.baseAddress, ptr.count, nil, 0 - ) - } + for msg in messages { + var msgPtr: OpaquePointer? + try FFIUtils.call(msg) { ptrs in + message_new_from_bytes( + ptrs[0].ptr, + ptrs[0].count, + &msgPtr + ) + } onErr: { err throws(Error) in + throw .createMessageFailed(err) } - guard res == BLST_SUCCESS else { - return false + msgPtrs.append(msgPtr) + } + for signature in signatures { + var sigPtr: OpaquePointer? + try FFIUtils.call(signature.data) { ptrs in + signature_new_from_bytes( + ptrs[0].ptr, + ptrs[0].count, + &sigPtr + ) + } onErr: { err throws(Error) in + throw .createSignatureFailed(err) } + sigPtrs.append(sigPtr) + } - first = false + keyPtrs = publicKeys.map(\.ptr.value) + + var output = Data(repeating: 0, count: 1) + + try FFIUtils.call(out: &output) { _, out_buf in + msgPtrs.withUnsafeBufferPointer { msgPtrs in + keyPtrs.withUnsafeBufferPointer { keyPtrs in + sigPtrs.withUnsafeBufferPointer { sigPtrs in + aggeregated_verify( + sigPtrs.baseAddress, + UInt(sigPtrs.count), + msgPtrs.baseAddress, + UInt(msgPtrs.count), + keyPtrs.baseAddress, + UInt(keyPtrs.count), + out_buf.ptr, + out_buf.count + ) + } + } + } + } onErr: { err throws(Error) in + throw .aggregatedVerifyFailed(err) } - blst_pairing_commit(ctx) - return blst_pairing_finalverify(ctx, nil) + return output[0] == 1 } + // TODO: maybe we don't need this method public static func aggregateSignatures(signatures: [Data96]) throws -> Data96 { - var aggregate = blst_p2() + let sigPtrs: [OpaquePointer?] = [] + defer { + for sigPtr in sigPtrs { + signature_free(sigPtr) + } + } for signature in signatures { - var sig = blst_p2_affine() - try signature.data.withUnsafeBytes { ptr in - let sigResult = blst_p2_uncompress(&sig, ptr.baseAddress) - guard sigResult == BLST_SUCCESS else { - throw Error.blstError(sigResult) - } - } - // silance the memory overlapping accessing warning - // as this is supported by the C API - withUnsafeMutablePointer(to: &aggregate) { ptr in - blst_p2_add_or_double_affine(ptr, ptr, &sig) + var sigPtr: OpaquePointer? + try FFIUtils.call(signature.data) { ptrs in + signature_new_from_bytes( + ptrs[0].ptr, + ptrs[0].count, + &sigPtr + ) + } onErr: { err throws(Error) in + throw .createSignatureFailed(err) } } - var sigCompressed = Data(repeating: 0, count: 96) - sigCompressed.withUnsafeMutableBytes { ptr in - blst_p2_compress(ptr.baseAddress, &aggregate) + var output = Data(repeating: 0, count: 96) + + try FFIUtils.call(out: &output) { _, out_buf in + sigPtrs.withUnsafeBufferPointer { sigPtrs in + aggregate_signatures( + sigPtrs.baseAddress, + UInt(sigPtrs.count), + out_buf.ptr, + out_buf.count + ) + } + } onErr: { err throws(Error) in + throw .aggregateSigsFailed(err) } - return Data96(sigCompressed)! + + return Data96(Data(output))! } } diff --git a/Utils/Sources/Utils/Crypto/Bandersnatch.swift b/Utils/Sources/Utils/Crypto/Bandersnatch.swift index 7ab216dc..337f5148 100644 --- a/Utils/Sources/Utils/Crypto/Bandersnatch.swift +++ b/Utils/Sources/Utils/Crypto/Bandersnatch.swift @@ -4,81 +4,6 @@ import TracingUtils private let logger = Logger(label: "Bandersnatch") -private func _call( - data: [Data], - out: inout Data?, - fn: ([(ptr: UnsafeRawPointer, count: UInt)], (ptr: UnsafeMutableRawPointer, count: UInt)?) -> Int, - onErr: (Int) throws(E) -> Void -) throws(E) { - func helper(data: ArraySlice, ptr: [(ptr: UnsafeRawPointer, count: UInt)]) -> Int { - if data.isEmpty { - if var outData = out { - let res = outData.withUnsafeMutableBytes { (bufferPtr: UnsafeMutableRawBufferPointer) -> Int in - guard let bufferAddress = bufferPtr.baseAddress else { - fatalError("unreachable: bufferPtr.baseAddress is nil") - } - return fn(ptr, (ptr: bufferAddress, count: UInt(bufferPtr.count))) - } - out = outData - return res - } - return fn(ptr, nil) - } - let rest = data.dropFirst() - let first = data.first! - return first.withUnsafeBytes { (bufferPtr: UnsafeRawBufferPointer) -> Int in - guard let bufferAddress = bufferPtr.baseAddress else { - fatalError("unreachable: bufferPtr.baseAddress is nil") - } - return helper(data: rest, ptr: ptr + [(bufferAddress, UInt(bufferPtr.count))]) - } - } - - let ret = helper(data: data[...], ptr: []) - - if ret != 0 { - try onErr(ret) - } -} - -private func call( - _ data: Data..., - fn: ([(ptr: UnsafeRawPointer, count: UInt)]) -> Int, - onErr: (Int) throws(E) -> Void -) throws(E) { - var out: Data? - try _call(data: data, out: &out, fn: { ptrs, _ in fn(ptrs) }, onErr: onErr) -} - -private func call( - _ data: Data..., - fn: ([(ptr: UnsafeRawPointer, count: UInt)]) -> Int -) { - var out: Data? - _call(data: data, out: &out, fn: { ptrs, _ in fn(ptrs) }, onErr: { err in fatalError("unreachable: \(err)") }) -} - -private func call( - _ data: Data..., - out: inout Data, - fn: ([(ptr: UnsafeRawPointer, count: UInt)], (ptr: UnsafeMutableRawPointer, count: UInt)) -> Int, - onErr: (Int) throws(E) -> Void -) throws(E) { - var out2: Data? = out - try _call(data: data, out: &out2, fn: { ptrs, out_buf in fn(ptrs, out_buf!) }, onErr: onErr) - out = out2! -} - -private func call( - _ data: Data..., - out: inout Data, - fn: ([(ptr: UnsafeRawPointer, count: UInt)], (ptr: UnsafeMutableRawPointer, count: UInt)) -> Int -) { - var out2: Data? = out - _call(data: data, out: &out2, fn: { ptrs, out_buf in fn(ptrs, out_buf!) }, onErr: { err in fatalError("unreachable: \(err)") }) - out = out2! -} - public enum Bandersnatch: KeyType { public enum Error: Swift.Error { case createSecretFailed(Int) @@ -100,7 +25,7 @@ public enum Bandersnatch: KeyType { public init(from seed: Data32) throws(Error) { var ptr: OpaquePointer! - try call(seed.data) { ptrs in + try FFIUtils.call(seed.data) { ptrs in secret_new(ptrs[0].ptr, ptrs[0].count, &ptr) } onErr: { err throws(Error) in throw .createSecretFailed(err) @@ -125,7 +50,7 @@ public enum Bandersnatch: KeyType { var output = Data(repeating: 0, count: 96) - try call(vrfInputData, auxData, out: &output) { ptrs, out_buf in + try FFIUtils.call(vrfInputData, auxData, out: &output) { ptrs, out_buf in prover_ietf_vrf_sign( ptr.value, ptrs[0].ptr, @@ -147,7 +72,7 @@ public enum Bandersnatch: KeyType { var output = Data(repeating: 0, count: 32) - try call(vrfInputData, out: &output) { ptrs, out_buf in + try FFIUtils.call(vrfInputData, out: &output) { ptrs, out_buf in secret_output( ptr.value, ptrs[0].ptr, @@ -169,7 +94,7 @@ public enum Bandersnatch: KeyType { public init(data: Data32) throws(Error) { var ptr: OpaquePointer! - try call(data.data) { ptrs in + try FFIUtils.call(data.data) { ptrs in public_new_from_data(ptrs[0].ptr, ptrs[0].count, &ptr) } onErr: { err throws(Error) in throw .createPublicKeyFailed(err) @@ -180,14 +105,14 @@ public enum Bandersnatch: KeyType { fileprivate init(secretKey: OpaquePointer) throws(Error) { var ptr: OpaquePointer! - try call { _ in + try FFIUtils.call { _ in public_new_from_secret(secretKey, &ptr) } onErr: { err throws(Error) in throw .createRingContextFailed(err) } var data = Data(repeating: 0, count: 32) - call(out: &data) { _, out_buf in + FFIUtils.call(out: &data) { _, out_buf in public_serialize_compressed(ptr, out_buf.ptr, out_buf.count) } @@ -242,7 +167,7 @@ public enum Bandersnatch: KeyType { var output = Data(repeating: 0, count: 32) - try call(vrfInputData, auxData, signature.data, out: &output) { ptrs, out_buf in + try FFIUtils.call(vrfInputData, auxData, signature.data, out: &output) { ptrs, out_buf in verifier_ietf_vrf_verify( ptr.value, ptrs[0].ptr, @@ -267,7 +192,7 @@ public enum Bandersnatch: KeyType { public init(size: UInt) throws(Error) { var ptr: OpaquePointer! - try call { _ in + try FFIUtils.call { _ in ring_context_new(size, &ptr) } onErr: { err throws(Error) in throw .createRingContextFailed(err) @@ -306,7 +231,7 @@ public enum Bandersnatch: KeyType { var output = Data(repeating: 0, count: 784) - try call(vrfInputData, auxData, out: &output) { ptrs, out_buf in + try FFIUtils.call(vrfInputData, auxData, out: &output) { ptrs, out_buf in ringPtrs.withUnsafeBufferPointer { ringPtrs in prover_ring_vrf_sign( secret.ptr.value, @@ -338,7 +263,7 @@ public enum Bandersnatch: KeyType { let ringPtrs = ring.map { $0?.ptr.value as OpaquePointer? } var ptr: OpaquePointer! - try call { _ in + try FFIUtils.call { _ in ringPtrs.withUnsafeBufferPointer { ringPtrs in ring_commitment_new_from_ring( ringPtrs.baseAddress, @@ -353,7 +278,7 @@ public enum Bandersnatch: KeyType { } var out = Data(repeating: 0, count: 144) - try call(out: &out) { _, out_buf in + try FFIUtils.call(out: &out) { _, out_buf in ring_commitment_serialize(ptr, out_buf.ptr, out_buf.count) } onErr: { err throws(Error) in throw .serializeRingCommitmentFailed(err) @@ -365,7 +290,7 @@ public enum Bandersnatch: KeyType { public init(data: Data144) throws(Error) { var ptr: OpaquePointer! - try call(data.data) { ptrs in + try FFIUtils.call(data.data) { ptrs in ring_commitment_new_from_data(ptrs[0].ptr, ptrs[0].count, &ptr) } onErr: { err throws(Error) in throw .createRingCommitmentFailed(err) @@ -405,7 +330,7 @@ public enum Bandersnatch: KeyType { var output = Data(repeating: 0, count: 32) - try call(vrfInputData, auxData, signature.data, out: &output) { ptrs, out_buf in + try FFIUtils.call(vrfInputData, auxData, signature.data, out: &output) { ptrs, out_buf in verifier_ring_vrf_verify( ctx.ptr.value, commitment.ptr.value, diff --git a/Utils/Sources/Utils/Crypto/FFIUtils.swift b/Utils/Sources/Utils/Crypto/FFIUtils.swift new file mode 100644 index 00000000..6a58edc2 --- /dev/null +++ b/Utils/Sources/Utils/Crypto/FFIUtils.swift @@ -0,0 +1,78 @@ +import Foundation + +enum FFIUtils { + private static func _call( + data: [Data], + out: inout Data?, + fn: ([(ptr: UnsafeRawPointer, count: UInt)], (ptr: UnsafeMutableRawPointer, count: UInt)?) -> Int, + onErr: (Int) throws(E) -> Void + ) throws(E) { + func helper(data: ArraySlice, ptr: [(ptr: UnsafeRawPointer, count: UInt)]) -> Int { + if data.isEmpty { + if var outData = out { + let res = outData.withUnsafeMutableBytes { (bufferPtr: UnsafeMutableRawBufferPointer) -> Int in + guard let bufferAddress = bufferPtr.baseAddress else { + fatalError("unreachable: bufferPtr.baseAddress is nil") + } + return fn(ptr, (ptr: bufferAddress, count: UInt(bufferPtr.count))) + } + out = outData + return res + } + return fn(ptr, nil) + } + let rest = data.dropFirst() + let first = data.first! + return first.withUnsafeBytes { (bufferPtr: UnsafeRawBufferPointer) -> Int in + guard let bufferAddress = bufferPtr.baseAddress else { + fatalError("unreachable: bufferPtr.baseAddress is nil") + } + return helper(data: rest, ptr: ptr + [(bufferAddress, UInt(bufferPtr.count))]) + } + } + + let ret = helper(data: data[...], ptr: []) + + if ret != 0 { + try onErr(ret) + } + } + + static func call( + _ data: Data..., + fn: ([(ptr: UnsafeRawPointer, count: UInt)]) -> Int, + onErr: (Int) throws(E) -> Void + ) throws(E) { + var out: Data? + try _call(data: data, out: &out, fn: { ptrs, _ in fn(ptrs) }, onErr: onErr) + } + + static func call( + _ data: Data..., + fn: ([(ptr: UnsafeRawPointer, count: UInt)]) -> Int + ) { + var out: Data? + _call(data: data, out: &out, fn: { ptrs, _ in fn(ptrs) }, onErr: { err in fatalError("unreachable: \(err)") }) + } + + static func call( + _ data: Data..., + out: inout Data, + fn: ([(ptr: UnsafeRawPointer, count: UInt)], (ptr: UnsafeMutableRawPointer, count: UInt)) -> Int, + onErr: (Int) throws(E) -> Void + ) throws(E) { + var out2: Data? = out + try _call(data: data, out: &out2, fn: { ptrs, out_buf in fn(ptrs, out_buf!) }, onErr: onErr) + out = out2! + } + + static func call( + _ data: Data..., + out: inout Data, + fn: ([(ptr: UnsafeRawPointer, count: UInt)], (ptr: UnsafeMutableRawPointer, count: UInt)) -> Int + ) { + var out2: Data? = out + _call(data: data, out: &out2, fn: { ptrs, out_buf in fn(ptrs, out_buf!) }, onErr: { err in fatalError("unreachable: \(err)") }) + out = out2! + } +} diff --git a/Utils/Sources/bls/Cargo.toml b/Utils/Sources/bls/Cargo.toml new file mode 100644 index 00000000..e7f8be07 --- /dev/null +++ b/Utils/Sources/bls/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "bls" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["staticlib"] + +[build-dependencies] +cbindgen = "0.27.0" + +[dependencies] +w3f-bls = { git = "https://github.com/w3f/bls", rev = "c19bbe8", features = [ + "experimental", +] } + +[dev-dependencies] +hex-literal = "0.4.1" diff --git a/Utils/Sources/bls/bindings.h b/Utils/Sources/bls/bindings.h new file mode 100644 index 00000000..82b27083 --- /dev/null +++ b/Utils/Sources/bls/bindings.h @@ -0,0 +1,61 @@ +/* Warning, this file is auto generated by cbindgen. Don't modify this manually. */ + +#include +#include +#include +#include + +typedef struct KeyPair KeyPair; +typedef struct Public Public; +typedef struct Secret Secret; +typedef struct Sig Sig; +typedef struct Message Message; + + +intptr_t keypair_new(const uint8_t *seed, uintptr_t seed_len, KeyPair **out_ptr); + +void keypair_free(KeyPair *keypair); + +intptr_t keypair_sign(KeyPair *key_pair, + const uint8_t *msg_data, + uintptr_t msg_data_len, + uint8_t *out, + uintptr_t out_len); + +intptr_t public_new_from_keypair(const KeyPair *key_pair, Public **out_ptr); + +intptr_t public_new_from_data(const uint8_t *data, uintptr_t len, Public **out_ptr); + +intptr_t public_serialize(const Public *public_, uint8_t *out, uintptr_t out_len); + +void public_free(Public *public_); + +intptr_t public_verify(const Public *public_, + const uint8_t *signature, + uintptr_t signature_len, + const uint8_t *msg_data, + uintptr_t msg_data_len, + uint8_t *out, + uintptr_t out_len); + +intptr_t message_new_from_bytes(const uint8_t *msg_data, uintptr_t msg_data_len, Message **out_ptr); + +void message_free(Message *msg); + +intptr_t signature_new_from_bytes(const uint8_t *bytes, uintptr_t len, Sig **out_ptr); + +void signature_free(Sig *sigs); + +intptr_t aggeregated_verify(const Sig *const *signatures, + uintptr_t signatures_len, + const Message *const *msgs, + uintptr_t msgs_len, + const Public *const *publickeys, + uintptr_t publickeys_len, + uint8_t *out, + uintptr_t out_len); + +intptr_t aggregate_signatures(const Sig *const *sigs_raw, + uintptr_t sigs_len, + uint8_t *out, + uintptr_t out_len); diff --git a/Utils/Sources/bls/build.rs b/Utils/Sources/bls/build.rs new file mode 100644 index 00000000..7ec4f969 --- /dev/null +++ b/Utils/Sources/bls/build.rs @@ -0,0 +1,14 @@ +extern crate cbindgen; + +fn main() { + let crate_dir = "./"; + + let config = cbindgen::Config::from_file("cbindgen.toml").unwrap(); + + cbindgen::Builder::new() + .with_crate(crate_dir) + .with_config(config) + .generate() + .expect("Unable to generate bindings") + .write_to_file("bindings.h"); +} diff --git a/Utils/Sources/bls/cbindgen.toml b/Utils/Sources/bls/cbindgen.toml new file mode 100644 index 00000000..499a7a0b --- /dev/null +++ b/Utils/Sources/bls/cbindgen.toml @@ -0,0 +1,12 @@ +language = "C" + +after_includes = """ + +typedef struct KeyPair KeyPair; +typedef struct Public Public; +typedef struct Secret Secret; +typedef struct Sig Sig; +typedef struct Message Message; +""" + +autogen_warning = "/* Warning, this file is auto generated by cbindgen. Don't modify this manually. */" diff --git a/Utils/Sources/bls/src/bls.rs b/Utils/Sources/bls/src/bls.rs new file mode 100644 index 00000000..9a73ffa6 --- /dev/null +++ b/Utils/Sources/bls/src/bls.rs @@ -0,0 +1,32 @@ +use w3f_bls::{ + distinct::DistinctMessages, Keypair, Message, PublicKey, SerializableToBytes, Signature, + Signed, ZBLS, +}; + +pub fn key_pair_sign( + key_pair: &mut Keypair, + msg: &Message, + out_buf: &mut [u8], +) -> Result<(), ()> { + let sig = key_pair.sign(msg); + let sig_bytes = sig.to_bytes(); + out_buf.copy_from_slice(&sig_bytes); + Ok(()) +} + +pub fn signature_verify( + sig: &Signature, + msg: &Message, + pub_key: &PublicKey, + out_buf: &mut [u8], +) -> Result<(), ()> { + let res = sig.verify(msg, pub_key); + out_buf[0] = if res { 1 } else { 0 }; + Ok(()) +} + +pub fn aggregated_verify(dms: &DistinctMessages, out_buf: &mut [u8]) -> Result<(), ()> { + let res = dms.verify(); + out_buf[0] = if res { 1 } else { 0 }; + Ok(()) +} diff --git a/Utils/Sources/bls/src/ffi.rs b/Utils/Sources/bls/src/ffi.rs new file mode 100644 index 00000000..45a2b0db --- /dev/null +++ b/Utils/Sources/bls/src/ffi.rs @@ -0,0 +1,283 @@ +use w3f_bls::{ + distinct::DistinctMessages, Keypair, Message, PublicKey, SecretKey, SerializableToBytes, + Signature, Signed, ZBLS, +}; + +use crate::bls::{aggregated_verify, key_pair_sign, signature_verify}; + +/// cbindgen:ignore +pub type KeyPair = Keypair; +/// cbindgen:ignore +pub type Public = PublicKey; +/// cbindgen:ignore +pub type Secret = SecretKey; +/// cbindgen:ignore +pub type Sig = Signature; + +#[no_mangle] +pub extern "C" fn keypair_new( + seed: *const u8, + seed_len: usize, + out_ptr: *mut *mut KeyPair, +) -> isize { + if seed.is_null() || out_ptr.is_null() { + return 1; + } + let seed_bytes = unsafe { std::slice::from_raw_parts(seed, seed_len) }; + let secret = SecretKey::::from_seed(seed_bytes); + let keypair = Box::new(Keypair { + public: secret.into_public(), + secret, + }); + unsafe { + *out_ptr = Box::into_raw(keypair); + } + 0 +} + +#[no_mangle] +pub extern "C" fn keypair_free(keypair: *mut KeyPair) { + if !keypair.is_null() { + unsafe { + drop(Box::from_raw(keypair)); + } + } +} + +#[no_mangle] +pub extern "C" fn keypair_sign( + key_pair: *mut KeyPair, + msg_data: *const u8, + msg_data_len: usize, + out: *mut u8, + out_len: usize, +) -> isize { + if key_pair.is_null() || msg_data.is_null() || out.is_null() { + return 1; + } + if out_len < 96 { + return 2; + } + let key_pair: &mut Keypair = unsafe { &mut *key_pair }; + let msg_data_slice = unsafe { std::slice::from_raw_parts(msg_data, msg_data_len) }; + let msg = Message::from(msg_data_slice); + let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; + match key_pair_sign(key_pair, &msg, out_slice) { + Ok(_) => 0, + Err(_) => 3, + } +} + +#[no_mangle] +pub extern "C" fn public_new_from_keypair( + key_pair: *const KeyPair, + out_ptr: *mut *mut Public, +) -> isize { + if key_pair.is_null() || out_ptr.is_null() { + return 1; + } + let key_pair: &KeyPair = unsafe { &*key_pair }; + let public = Box::new(key_pair.public); + unsafe { + *out_ptr = Box::into_raw(public); + } + 0 +} + +#[no_mangle] +pub extern "C" fn public_new_from_data( + data: *const u8, + len: usize, + out_ptr: *mut *mut Public, +) -> isize { + if data.is_null() || out_ptr.is_null() { + return 1; + } + let data_slice = unsafe { std::slice::from_raw_parts(data, len) }; + let public = match Public::from_bytes(data_slice) { + Ok(public) => Box::new(public), + Err(_) => return 2, + }; + unsafe { *out_ptr = Box::into_raw(public) }; + 0 +} + +#[no_mangle] +pub extern "C" fn public_serialize(public: *const Public, out: *mut u8, out_len: usize) -> isize { + if public.is_null() || out.is_null() { + return 1; + } + if out_len < 144 { + return 2; + } + let public: &Public = unsafe { &*public }; + let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; + out_slice.copy_from_slice(&public.to_bytes()); + 0 +} + +#[no_mangle] +pub extern "C" fn public_free(public: *mut Public) { + if !public.is_null() { + unsafe { + drop(Box::from_raw(public)); + } + } +} + +#[no_mangle] +pub extern "C" fn public_verify( + public: *const Public, + signature: *const u8, + signature_len: usize, + msg_data: *const u8, + msg_data_len: usize, + out: *mut u8, + out_len: usize, +) -> isize { + if public.is_null() || signature.is_null() || msg_data.is_null() || out.is_null() { + return 1; + } + let public: &Public = unsafe { &*public }; + let signature_slice = unsafe { std::slice::from_raw_parts(signature, signature_len) }; + let sig = match Signature::from_bytes(signature_slice) { + Ok(sig) => Box::new(sig), + Err(_) => return 2, + }; + let msg_data_slice = unsafe { std::slice::from_raw_parts(msg_data, msg_data_len) }; + let msg = Message::from(msg_data_slice); + let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; + match signature_verify(&sig, &msg, &public, out_slice) { + Ok(_) => 0, + Err(_) => 3, + } +} + +#[no_mangle] +pub extern "C" fn message_new_from_bytes( + msg_data: *const u8, + msg_data_len: usize, + out_ptr: *mut *mut Message, +) -> isize { + if msg_data.is_null() || out_ptr.is_null() { + return 1; + } + if msg_data_len < 96 { + return 2; + } + let msg_data_slice = unsafe { std::slice::from_raw_parts(msg_data, msg_data_len) }; + let msg = Message::from(msg_data_slice); + unsafe { *out_ptr = Box::into_raw(Box::new(msg)) }; + 0 +} + +#[no_mangle] +pub extern "C" fn message_free(msg: *mut Message) { + if !msg.is_null() { + unsafe { + drop(Box::from_raw(msg)); + } + } +} + +#[no_mangle] +pub extern "C" fn signature_new_from_bytes( + bytes: *const u8, + len: usize, + out_ptr: *mut *mut Sig, +) -> isize { + if bytes.is_null() || out_ptr.is_null() { + return 1; + } + if len < 96 { + return 2; + } + let bytes_slice = unsafe { std::slice::from_raw_parts(bytes, len) }; + let sig = match Signature::from_bytes(bytes_slice) { + Ok(sig) => Box::new(sig), + Err(_) => return 3, + }; + unsafe { *out_ptr = Box::into_raw(sig) }; + 0 +} + +#[no_mangle] +pub extern "C" fn signature_free(sigs: *mut Sig) { + if !sigs.is_null() { + unsafe { + drop(Box::from_raw(sigs)); + } + } +} + +#[no_mangle] +pub extern "C" fn aggeregated_verify( + signatures: *const *const Sig, + signatures_len: usize, + msgs: *const *const Message, + msgs_len: usize, + publickeys: *const *const Public, + publickeys_len: usize, + out: *mut u8, + out_len: usize, +) -> isize { + if signatures.is_null() || msgs.is_null() || publickeys.is_null() || out.is_null() { + return 1; + } + if out_len < 1 { + return 2; + } + let signatures_slice = unsafe { std::slice::from_raw_parts(signatures, signatures_len) }; + let msgs_slice = unsafe { std::slice::from_raw_parts(msgs, msgs_len) }; + let publickeys_slice = unsafe { std::slice::from_raw_parts(publickeys, publickeys_len) }; + + let mut dms = DistinctMessages::::new(); + for &sig_ptr in signatures_slice.iter() { + let sig = unsafe { &*sig_ptr }; + dms.add_signature(sig); + } + let aggregated_signature = <&DistinctMessages as Signed>::signature(&&dms); + + let mut dms = DistinctMessages::::new(); + for (&message_ptr, &publickey_ptr) in msgs_slice.iter().zip(publickeys_slice.iter()) { + let message = unsafe { (*message_ptr).clone() }; + let publickey = unsafe { *publickey_ptr }; + dms = match dms.add_message_n_publickey(message, publickey) { + Ok(dms) => dms, + Err(_) => return 3, // AttackViaDuplicateMessages + } + } + dms.add_signature(&aggregated_signature); + let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; + match aggregated_verify(&dms, out_slice) { + Ok(_) => 0, + Err(_) => 4, + } +} + +#[no_mangle] +pub extern "C" fn aggregate_signatures( + sigs_raw: *const *const Sig, + sigs_len: usize, + out: *mut u8, + out_len: usize, +) -> isize { + if sigs_raw.is_null() || out.is_null() { + return 1; + } + if out_len < 96 { + return 2; + } + + let sigs_slice = unsafe { std::slice::from_raw_parts(sigs_raw, sigs_len) }; + let mut dms = DistinctMessages::::new(); + for &sig_ptr in sigs_slice.iter() { + let sig = unsafe { &*sig_ptr }; + dms.add_signature(sig); + } + let signature = <&DistinctMessages as Signed>::signature(&&dms); + + let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; + out_slice.copy_from_slice(&signature.to_bytes()); + 0 +} diff --git a/Utils/Sources/bls/src/lib.rs b/Utils/Sources/bls/src/lib.rs new file mode 100644 index 00000000..6ca1d918 --- /dev/null +++ b/Utils/Sources/bls/src/lib.rs @@ -0,0 +1,4 @@ +mod bls; + +pub mod ffi; +pub use ffi::*; diff --git a/Utils/Sources/erasure-coding/Cargo.lock b/Utils/Sources/erasure-coding/Cargo.lock deleted file mode 100644 index c474d7e3..00000000 --- a/Utils/Sources/erasure-coding/Cargo.lock +++ /dev/null @@ -1,674 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "arrayref" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "blake2b_simd" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - -[[package]] -name = "bounded-collections" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca548b6163b872067dc5eb82fd130c56881435e30367d2073594a3d9744120dd" -dependencies = [ - "log", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "bytemuck" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" - -[[package]] -name = "cbindgen" -version = "0.24.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" -dependencies = [ - "clap", - "heck", - "indexmap 1.9.3", - "log", - "proc-macro2", - "quote", - "serde", - "serde_json", - "syn 1.0.109", - "tempfile", - "toml", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_lex", - "indexmap 1.9.3", - "strsim", - "termcolor", - "textwrap", -] - -[[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 = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.72", -] - -[[package]] -name = "ec" -version = "0.1.0" -dependencies = [ - "cbindgen", - "erasure-coding", - "hex", - "serde", - "serde_json", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erasure-coding" -version = "0.1.0" -source = "git+https://github.com/paritytech/erasure-coding?rev=512e774#512e77472beb877fe0881a857623d54d97b82bc4" -dependencies = [ - "blake2b_simd", - "bounded-collections", - "parity-scale-codec", - "reed-solomon-simd", - "thiserror", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "readme-rustdocifier" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ad765b21a08b1a8e5cdce052719188a23772bcbefb3c439f0baaf62c56ceac" - -[[package]] -name = "reed-solomon-simd" -version = "2.2.1" -source = "git+https://github.com/ordian/reed-solomon-simd?branch=simd-feature#2e7136fc19f599d7f11f86d51c356482d71ef980" -dependencies = [ - "bytemuck", - "fixedbitset", - "once_cell", - "readme-rustdocifier", -] - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "scale-info" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" -dependencies = [ - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.205" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.205" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.72", -] - -[[package]] -name = "serde_json" -version = "1.0.122" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" -dependencies = [ - "cfg-if", - "fastrand", - "once_cell", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[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.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.72", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.3.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[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.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] diff --git a/Utils/Sources/module.modulemap b/Utils/Sources/module.modulemap index 58070834..698fcb1f 100644 --- a/Utils/Sources/module.modulemap +++ b/Utils/Sources/module.modulemap @@ -1,6 +1,6 @@ -module blst { - header "blst/bindings/blst.h" - link "blst" +module bls { + header "bls/bindings.h" + link "bls" } module bandersnatch_vrfs { diff --git a/scripts/bandersnatch.sh b/scripts/bandersnatch.sh deleted file mode 100755 index 6a8967b3..00000000 --- a/scripts/bandersnatch.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -e - - -# Setup bandersnatch vrf c binding -CWD=$(pwd) - -mkdir -p .lib - -cd Utils/Sources/bandersnatch || { echo "directory not found"; exit 1; } - -cargo build --release --lib - -cp target/release/libbandersnatch_vrfs.a ${CWD}/.lib - -echo "Setup bandersnatch successfully." diff --git a/scripts/blst.sh b/scripts/blst.sh deleted file mode 100755 index 675968fe..00000000 --- a/scripts/blst.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -e - - -# Setup blst C module -CWD=$(pwd) - -mkdir -p .lib - -cd Utils/Sources/blst || { echo "Submodule directory not found"; exit 1; } - -./build.sh || { echo "Build blst library failed"; exit 1; } - -cp libblst.a ${CWD}/.lib - -echo "Setup blst successfully." diff --git a/scripts/build-rust-libs.sh b/scripts/build-rust-libs.sh new file mode 100755 index 00000000..94dbd6ca --- /dev/null +++ b/scripts/build-rust-libs.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -e + +# Setup rust libs c binding +CWD=$(pwd) + +mkdir -p .lib + +cargo build --release --lib + +cd ${CWD} +cp target/release/*.a .lib + +echo "Setup rust libs c binding successfully." diff --git a/scripts/erasure-coding.sh b/scripts/erasure-coding.sh deleted file mode 100755 index 7f81e958..00000000 --- a/scripts/erasure-coding.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -e - - -# Setup erasure-coding c binding -CWD=$(pwd) - -mkdir -p .lib - -cd Utils/Sources/erasure-coding || { echo "directory not found"; exit 1; } - -cargo build --release --lib - -cp target/release/libec.a ${CWD}/.lib - -echo "Setup erasure-coding successfully." From b31ce478ee2e23b8892984efcc249d01d6ec9fe8 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Wed, 16 Oct 2024 12:23:16 +0800 Subject: [PATCH 03/10] fix build --- Utils/Sources/Utils/Crypto/BLS.swift | 4 ++-- Utils/Sources/bls/bindings.h | 4 ++-- Utils/Sources/bls/src/ffi.rs | 9 ++++++--- Utils/Tests/UtilsTests/Crypto/BLSTests.swift | 20 ++++++++++---------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Utils/Sources/Utils/Crypto/BLS.swift b/Utils/Sources/Utils/Crypto/BLS.swift index b1afe851..1e0fcc87 100644 --- a/Utils/Sources/Utils/Crypto/BLS.swift +++ b/Utils/Sources/Utils/Crypto/BLS.swift @@ -63,7 +63,7 @@ public enum BLS: KeyType { public init(data: Data144) throws(Error) { var ptr: OpaquePointer! try FFIUtils.call(data.data) { ptrs in - public_new_from_data(ptrs[0].ptr, ptrs[0].count, &ptr) + public_new_from_bytes(ptrs[0].ptr, ptrs[0].count, &ptr) } onErr: { err throws(Error) in throw .createPublicKeyFailed(err) } @@ -89,7 +89,7 @@ public enum BLS: KeyType { } deinit { - public_free(ptr.value) + bls_public_free(ptr.value) } public convenience init(from decoder: Decoder) throws { diff --git a/Utils/Sources/bls/bindings.h b/Utils/Sources/bls/bindings.h index 82b27083..5cdfa627 100644 --- a/Utils/Sources/bls/bindings.h +++ b/Utils/Sources/bls/bindings.h @@ -24,11 +24,11 @@ intptr_t keypair_sign(KeyPair *key_pair, intptr_t public_new_from_keypair(const KeyPair *key_pair, Public **out_ptr); -intptr_t public_new_from_data(const uint8_t *data, uintptr_t len, Public **out_ptr); +intptr_t public_new_from_bytes(const uint8_t *data, uintptr_t len, Public **out_ptr); intptr_t public_serialize(const Public *public_, uint8_t *out, uintptr_t out_len); -void public_free(Public *public_); +void bls_public_free(Public *public_); intptr_t public_verify(const Public *public_, const uint8_t *signature, diff --git a/Utils/Sources/bls/src/ffi.rs b/Utils/Sources/bls/src/ffi.rs index 45a2b0db..d8fa612b 100644 --- a/Utils/Sources/bls/src/ffi.rs +++ b/Utils/Sources/bls/src/ffi.rs @@ -85,7 +85,7 @@ pub extern "C" fn public_new_from_keypair( } #[no_mangle] -pub extern "C" fn public_new_from_data( +pub extern "C" fn public_new_from_bytes( data: *const u8, len: usize, out_ptr: *mut *mut Public, @@ -111,13 +111,16 @@ pub extern "C" fn public_serialize(public: *const Public, out: *mut u8, out_len: return 2; } let public: &Public = unsafe { &*public }; + let res = public.to_bytes(); + println!("res: {:?}, len: {}", res, res.len()); let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; - out_slice.copy_from_slice(&public.to_bytes()); + out_slice.copy_from_slice(&res); + // out_slice.copy_from_slice(&public.to_bytes()); 0 } #[no_mangle] -pub extern "C" fn public_free(public: *mut Public) { +pub extern "C" fn bls_public_free(public: *mut Public) { if !public.is_null() { unsafe { drop(Box::from_raw(public)); diff --git a/Utils/Tests/UtilsTests/Crypto/BLSTests.swift b/Utils/Tests/UtilsTests/Crypto/BLSTests.swift index b2d38eb5..5e9ab7b7 100644 --- a/Utils/Tests/UtilsTests/Crypto/BLSTests.swift +++ b/Utils/Tests/UtilsTests/Crypto/BLSTests.swift @@ -8,44 +8,44 @@ import Testing let bls = try BLS.SecretKey(from: Data32()) let publicKey1 = bls.publicKey let message1 = Data("test1".utf8) - let signature1 = bls.sign(message: message1) + let signature1 = try bls.sign(message: message1) #expect( - publicKey1.verify(signature: signature1, message: message1) + try publicKey1.verify(signature: signature1, message: message1) ) let invalidMessage = Data("testUnknown".utf8) #expect( - !publicKey1.verify(signature: signature1, message: invalidMessage) + try !publicKey1.verify(signature: signature1, message: invalidMessage) ) var invalidSignature = signature1.data invalidSignature.replaceSubrange(0 ... 1, with: [2, 3]) #expect( - !publicKey1.verify(signature: Data96(invalidSignature)!, message: message1) + try !publicKey1.verify(signature: Data96(invalidSignature)!, message: message1) ) let bls2 = try BLS.SecretKey(from: Data32.random()) let publicKey2 = bls2.publicKey let message2 = Data("test2".utf8) - let signature2 = bls2.sign(message: message2) + let signature2 = try bls2.sign(message: message2) #expect( - publicKey2.verify(signature: signature2, message: message2) + try publicKey2.verify(signature: signature2, message: message2) ) let aggSig = try BLS.aggregateSignatures(signatures: [signature1, signature2]) #expect( - BLS.aggregateVerify( - signature: aggSig, messages: [message1, message2], + try BLS.aggregateVerify( + signatures: [aggSig], messages: [message1, message2], publicKeys: [publicKey1, publicKey2] ) ) #expect( - !BLS.aggregateVerify( - signature: aggSig, messages: [message1, message2], + try !BLS.aggregateVerify( + signatures: [aggSig], messages: [message1, message2], publicKeys: [publicKey2, publicKey1] ) ) From 5d262c9860d39a1bb8cad84f03bf514413ece780 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Thu, 17 Oct 2024 08:42:58 +0800 Subject: [PATCH 04/10] use correct pub key schema --- Cargo.lock | 1 + Utils/Sources/Utils/Crypto/BLS.swift | 148 +++++++++---------- Utils/Sources/bls/Cargo.toml | 1 + Utils/Sources/bls/bindings.h | 14 +- Utils/Sources/bls/src/bls.rs | 19 ++- Utils/Sources/bls/src/ffi.rs | 144 +++++++++--------- Utils/Tests/UtilsTests/Crypto/BLSTests.swift | 30 +++- 7 files changed, 181 insertions(+), 176 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb3e55ef..30ff81fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,6 +326,7 @@ version = "0.1.0" dependencies = [ "cbindgen 0.27.0", "hex-literal", + "sha2", "w3f-bls", ] diff --git a/Utils/Sources/Utils/Crypto/BLS.swift b/Utils/Sources/Utils/Crypto/BLS.swift index 1e0fcc87..21d9fb7a 100644 --- a/Utils/Sources/Utils/Crypto/BLS.swift +++ b/Utils/Sources/Utils/Crypto/BLS.swift @@ -37,8 +37,8 @@ public enum BLS: KeyType { keypair_free(keyPairPtr.value) } - public func sign(message: Data) throws(Error) -> Data96 { - var output = Data(repeating: 0, count: 96) + public func sign(message: Data) throws(Error) -> Data { + var output = Data(repeating: 0, count: 160) try FFIUtils.call(message, out: &output) { ptrs, out_buf in keypair_sign( @@ -52,7 +52,7 @@ public enum BLS: KeyType { throw .keypairSignFailed(err) } - return Data96(Data(output))! + return Data(output) } } @@ -115,10 +115,10 @@ public enum BLS: KeyType { data.description } - public func verify(signature: Data96, message: Data) throws(Error) -> Bool { + public func verify(signature: Data, message: Data) throws(Error) -> Bool { var output = Data(repeating: 0, count: 1) - try FFIUtils.call(signature.data, message, out: &output) { ptrs, out_buf in + try FFIUtils.call(signature, message, out: &output) { ptrs, out_buf in public_verify( ptr.value, ptrs[0].ptr, @@ -129,7 +129,9 @@ public enum BLS: KeyType { out_buf.count ) } onErr: { err throws(Error) in - throw .signatureVerifyFailed(err) + if err != 2 { + throw .signatureVerifyFailed(err) + } } return output[0] == 1 @@ -137,42 +139,39 @@ public enum BLS: KeyType { } public static func aggregateVerify( - signatures: [Data96], messages: [Data], publicKeys: [PublicKey] + message: Data, signatures: [Data], publicKeys: [PublicKey] ) throws(Error) -> Bool { - if messages.count != publicKeys.count { + if signatures.count != publicKeys.count { return false } - var msgPtrs: [OpaquePointer?] = [] var keyPtrs: [OpaquePointer?] = [] var sigPtrs: [OpaquePointer?] = [] + var msgPtr: OpaquePointer? defer { - for msgPtr in msgPtrs { + if let msgPtr { message_free(msgPtr) } for sigPtr in sigPtrs { signature_free(sigPtr) } - // do not free public keys here as they're owned externally } - for msg in messages { - var msgPtr: OpaquePointer? - try FFIUtils.call(msg) { ptrs in - message_new_from_bytes( - ptrs[0].ptr, - ptrs[0].count, - &msgPtr - ) - } onErr: { err throws(Error) in - throw .createMessageFailed(err) - } - msgPtrs.append(msgPtr) + // single message + try FFIUtils.call(message) { ptrs in + message_new_from_bytes( + ptrs[0].ptr, + ptrs[0].count, + &msgPtr + ) + } onErr: { err throws(Error) in + throw .createMessageFailed(err) } + for signature in signatures { var sigPtr: OpaquePointer? - try FFIUtils.call(signature.data) { ptrs in + try FFIUtils.call(signature) { ptrs in signature_new_from_bytes( ptrs[0].ptr, ptrs[0].count, @@ -189,20 +188,17 @@ public enum BLS: KeyType { var output = Data(repeating: 0, count: 1) try FFIUtils.call(out: &output) { _, out_buf in - msgPtrs.withUnsafeBufferPointer { msgPtrs in - keyPtrs.withUnsafeBufferPointer { keyPtrs in - sigPtrs.withUnsafeBufferPointer { sigPtrs in - aggeregated_verify( - sigPtrs.baseAddress, - UInt(sigPtrs.count), - msgPtrs.baseAddress, - UInt(msgPtrs.count), - keyPtrs.baseAddress, - UInt(keyPtrs.count), - out_buf.ptr, - out_buf.count - ) - } + keyPtrs.withUnsafeBufferPointer { keyPtrs in + sigPtrs.withUnsafeBufferPointer { sigPtrs in + aggeregated_verify( + msgPtr, + sigPtrs.baseAddress!, + UInt(sigPtrs.count), + keyPtrs.baseAddress!, + UInt(keyPtrs.count), + out_buf.ptr, + out_buf.count + ) } } } onErr: { err throws(Error) in @@ -213,42 +209,42 @@ public enum BLS: KeyType { } // TODO: maybe we don't need this method - public static func aggregateSignatures(signatures: [Data96]) throws -> Data96 { - let sigPtrs: [OpaquePointer?] = [] - defer { - for sigPtr in sigPtrs { - signature_free(sigPtr) - } - } - - for signature in signatures { - var sigPtr: OpaquePointer? - try FFIUtils.call(signature.data) { ptrs in - signature_new_from_bytes( - ptrs[0].ptr, - ptrs[0].count, - &sigPtr - ) - } onErr: { err throws(Error) in - throw .createSignatureFailed(err) - } - } - - var output = Data(repeating: 0, count: 96) - - try FFIUtils.call(out: &output) { _, out_buf in - sigPtrs.withUnsafeBufferPointer { sigPtrs in - aggregate_signatures( - sigPtrs.baseAddress, - UInt(sigPtrs.count), - out_buf.ptr, - out_buf.count - ) - } - } onErr: { err throws(Error) in - throw .aggregateSigsFailed(err) - } - - return Data96(Data(output))! - } + // public static func aggregateSignatures(signatures: [Data96]) throws -> Data96 { + // let sigPtrs: [OpaquePointer?] = [] + // defer { + // for sigPtr in sigPtrs { + // signature_free(sigPtr) + // } + // } + + // for signature in signatures { + // var sigPtr: OpaquePointer? + // try FFIUtils.call(signature.data) { ptrs in + // signature_new_from_bytes( + // ptrs[0].ptr, + // ptrs[0].count, + // &sigPtr + // ) + // } onErr: { err throws(Error) in + // throw .createSignatureFailed(err) + // } + // } + + // var output = Data(repeating: 0, count: 96) + + // try FFIUtils.call(out: &output) { _, out_buf in + // sigPtrs.withUnsafeBufferPointer { sigPtrs in + // aggregate_signatures( + // sigPtrs.baseAddress, + // UInt(sigPtrs.count), + // out_buf.ptr, + // out_buf.count + // ) + // } + // } onErr: { err throws(Error) in + // throw .aggregateSigsFailed(err) + // } + + // return Data96(Data(output))! + // } } diff --git a/Utils/Sources/bls/Cargo.toml b/Utils/Sources/bls/Cargo.toml index e7f8be07..cfb8169a 100644 --- a/Utils/Sources/bls/Cargo.toml +++ b/Utils/Sources/bls/Cargo.toml @@ -13,6 +13,7 @@ cbindgen = "0.27.0" w3f-bls = { git = "https://github.com/w3f/bls", rev = "c19bbe8", features = [ "experimental", ] } +sha2 = { version = "0.10", default-features = false } [dev-dependencies] hex-literal = "0.4.1" diff --git a/Utils/Sources/bls/bindings.h b/Utils/Sources/bls/bindings.h index 5cdfa627..4a4cf636 100644 --- a/Utils/Sources/bls/bindings.h +++ b/Utils/Sources/bls/bindings.h @@ -22,10 +22,10 @@ intptr_t keypair_sign(KeyPair *key_pair, uint8_t *out, uintptr_t out_len); -intptr_t public_new_from_keypair(const KeyPair *key_pair, Public **out_ptr); - intptr_t public_new_from_bytes(const uint8_t *data, uintptr_t len, Public **out_ptr); +intptr_t public_new_from_keypair(const KeyPair *key_pair, Public **out_ptr); + intptr_t public_serialize(const Public *public_, uint8_t *out, uintptr_t out_len); void bls_public_free(Public *public_); @@ -46,16 +46,10 @@ intptr_t signature_new_from_bytes(const uint8_t *bytes, uintptr_t len, Sig **out void signature_free(Sig *sigs); -intptr_t aggeregated_verify(const Sig *const *signatures, +intptr_t aggeregated_verify(const Message *msg, + const Sig *const *signatures, uintptr_t signatures_len, - const Message *const *msgs, - uintptr_t msgs_len, const Public *const *publickeys, uintptr_t publickeys_len, uint8_t *out, uintptr_t out_len); - -intptr_t aggregate_signatures(const Sig *const *sigs_raw, - uintptr_t sigs_len, - uint8_t *out, - uintptr_t out_len); diff --git a/Utils/Sources/bls/src/bls.rs b/Utils/Sources/bls/src/bls.rs index 9a73ffa6..75404fc8 100644 --- a/Utils/Sources/bls/src/bls.rs +++ b/Utils/Sources/bls/src/bls.rs @@ -1,6 +1,7 @@ +use sha2::Sha256; use w3f_bls::{ - distinct::DistinctMessages, Keypair, Message, PublicKey, SerializableToBytes, Signature, - Signed, ZBLS, + single_pop_aggregator::SignatureAggregatorAssumingPoP, DoublePublicKey, DoublePublicKeyScheme, + DoubleSignature, Keypair, Message, SerializableToBytes, ZBLS, }; pub fn key_pair_sign( @@ -8,16 +9,16 @@ pub fn key_pair_sign( msg: &Message, out_buf: &mut [u8], ) -> Result<(), ()> { - let sig = key_pair.sign(msg); + let sig = DoublePublicKeyScheme::sign(key_pair, msg); let sig_bytes = sig.to_bytes(); out_buf.copy_from_slice(&sig_bytes); Ok(()) } pub fn signature_verify( - sig: &Signature, + sig: &DoubleSignature, msg: &Message, - pub_key: &PublicKey, + pub_key: &DoublePublicKey, out_buf: &mut [u8], ) -> Result<(), ()> { let res = sig.verify(msg, pub_key); @@ -25,8 +26,12 @@ pub fn signature_verify( Ok(()) } -pub fn aggregated_verify(dms: &DistinctMessages, out_buf: &mut [u8]) -> Result<(), ()> { - let res = dms.verify(); +pub fn aggregated_verify( + aggregator: SignatureAggregatorAssumingPoP, + out_buf: &mut [u8], +) -> Result<(), ()> { + // TODO: check using `verify` or `verify_using_aggregated_auxiliary_public_keys` + let res = aggregator.verify_using_aggregated_auxiliary_public_keys::(); out_buf[0] = if res { 1 } else { 0 }; Ok(()) } diff --git a/Utils/Sources/bls/src/ffi.rs b/Utils/Sources/bls/src/ffi.rs index d8fa612b..447fde0d 100644 --- a/Utils/Sources/bls/src/ffi.rs +++ b/Utils/Sources/bls/src/ffi.rs @@ -1,6 +1,7 @@ use w3f_bls::{ - distinct::DistinctMessages, Keypair, Message, PublicKey, SecretKey, SerializableToBytes, - Signature, Signed, ZBLS, + single_pop_aggregator::SignatureAggregatorAssumingPoP, DoublePublicKey, DoublePublicKeyScheme, + DoubleSignature, EngineBLS, Keypair, Message, PublicKey, PublicKeyInSignatureGroup, SecretKey, + SerializableToBytes, Signature, ZBLS, }; use crate::bls::{aggregated_verify, key_pair_sign, signature_verify}; @@ -8,11 +9,11 @@ use crate::bls::{aggregated_verify, key_pair_sign, signature_verify}; /// cbindgen:ignore pub type KeyPair = Keypair; /// cbindgen:ignore -pub type Public = PublicKey; +pub type Public = DoublePublicKey; /// cbindgen:ignore pub type Secret = SecretKey; /// cbindgen:ignore -pub type Sig = Signature; +pub type Sig = DoubleSignature; #[no_mangle] pub extern "C" fn keypair_new( @@ -55,7 +56,7 @@ pub extern "C" fn keypair_sign( if key_pair.is_null() || msg_data.is_null() || out.is_null() { return 1; } - if out_len < 96 { + if out_len < ZBLS::SIGNATURE_SERIALIZED_SIZE { return 2; } let key_pair: &mut Keypair = unsafe { &mut *key_pair }; @@ -68,22 +69,6 @@ pub extern "C" fn keypair_sign( } } -#[no_mangle] -pub extern "C" fn public_new_from_keypair( - key_pair: *const KeyPair, - out_ptr: *mut *mut Public, -) -> isize { - if key_pair.is_null() || out_ptr.is_null() { - return 1; - } - let key_pair: &KeyPair = unsafe { &*key_pair }; - let public = Box::new(key_pair.public); - unsafe { - *out_ptr = Box::into_raw(public); - } - 0 -} - #[no_mangle] pub extern "C" fn public_new_from_bytes( data: *const u8, @@ -102,20 +87,34 @@ pub extern "C" fn public_new_from_bytes( 0 } +#[no_mangle] +pub extern "C" fn public_new_from_keypair( + key_pair: *const KeyPair, + out_ptr: *mut *mut Public, +) -> isize { + if key_pair.is_null() || out_ptr.is_null() { + return 1; + } + let key_pair: &KeyPair = unsafe { &*key_pair }; + let public = Box::new(key_pair.into_double_public_key()); + unsafe { + *out_ptr = Box::into_raw(public); + } + 0 +} + #[no_mangle] pub extern "C" fn public_serialize(public: *const Public, out: *mut u8, out_len: usize) -> isize { if public.is_null() || out.is_null() { return 1; } - if out_len < 144 { + if out_len < ZBLS::PUBLICKEY_SERIALIZED_SIZE { return 2; } let public: &Public = unsafe { &*public }; let res = public.to_bytes(); - println!("res: {:?}, len: {}", res, res.len()); let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; out_slice.copy_from_slice(&res); - // out_slice.copy_from_slice(&public.to_bytes()); 0 } @@ -143,7 +142,7 @@ pub extern "C" fn public_verify( } let public: &Public = unsafe { &*public }; let signature_slice = unsafe { std::slice::from_raw_parts(signature, signature_len) }; - let sig = match Signature::from_bytes(signature_slice) { + let sig = match DoubleSignature::from_bytes(signature_slice) { Ok(sig) => Box::new(sig), Err(_) => return 2, }; @@ -165,9 +164,6 @@ pub extern "C" fn message_new_from_bytes( if msg_data.is_null() || out_ptr.is_null() { return 1; } - if msg_data_len < 96 { - return 2; - } let msg_data_slice = unsafe { std::slice::from_raw_parts(msg_data, msg_data_len) }; let msg = Message::from(msg_data_slice); unsafe { *out_ptr = Box::into_raw(Box::new(msg)) }; @@ -192,11 +188,11 @@ pub extern "C" fn signature_new_from_bytes( if bytes.is_null() || out_ptr.is_null() { return 1; } - if len < 96 { + if len < ZBLS::SIGNATURE_SERIALIZED_SIZE { return 2; } let bytes_slice = unsafe { std::slice::from_raw_parts(bytes, len) }; - let sig = match Signature::from_bytes(bytes_slice) { + let sig = match DoubleSignature::from_bytes(bytes_slice) { Ok(sig) => Box::new(sig), Err(_) => return 3, }; @@ -215,72 +211,70 @@ pub extern "C" fn signature_free(sigs: *mut Sig) { #[no_mangle] pub extern "C" fn aggeregated_verify( + msg: *const Message, signatures: *const *const Sig, signatures_len: usize, - msgs: *const *const Message, - msgs_len: usize, publickeys: *const *const Public, publickeys_len: usize, out: *mut u8, out_len: usize, ) -> isize { - if signatures.is_null() || msgs.is_null() || publickeys.is_null() || out.is_null() { + if signatures.is_null() || msg.is_null() || publickeys.is_null() || out.is_null() { return 1; } if out_len < 1 { return 2; } + + let message = unsafe { &*msg }; let signatures_slice = unsafe { std::slice::from_raw_parts(signatures, signatures_len) }; - let msgs_slice = unsafe { std::slice::from_raw_parts(msgs, msgs_len) }; let publickeys_slice = unsafe { std::slice::from_raw_parts(publickeys, publickeys_len) }; - let mut dms = DistinctMessages::::new(); - for &sig_ptr in signatures_slice.iter() { - let sig = unsafe { &*sig_ptr }; - dms.add_signature(sig); - } - let aggregated_signature = <&DistinctMessages as Signed>::signature(&&dms); + // TODO: check if this is the correct way to aggregate + // TODO: do pop here, DoubleSignature has the stuff needed - let mut dms = DistinctMessages::::new(); - for (&message_ptr, &publickey_ptr) in msgs_slice.iter().zip(publickeys_slice.iter()) { - let message = unsafe { (*message_ptr).clone() }; - let publickey = unsafe { *publickey_ptr }; - dms = match dms.add_message_n_publickey(message, publickey) { - Ok(dms) => dms, - Err(_) => return 3, // AttackViaDuplicateMessages - } + let mut aggregator = SignatureAggregatorAssumingPoP::::new(message.clone()); + for &sig in signatures_slice { + let sig = unsafe { &*sig }; + aggregator.add_signature(&Signature::(sig.0)); } - dms.add_signature(&aggregated_signature); + for &public_key in publickeys_slice { + let public_key = unsafe { &*public_key }; + // aggregated_public_key.0 += public_key.1; + aggregator.add_publickey(&PublicKey::(public_key.1)); + aggregator.add_auxiliary_public_key(&PublicKeyInSignatureGroup::(public_key.0)); + } + let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; - match aggregated_verify(&dms, out_slice) { + match aggregated_verify(aggregator, out_slice) { Ok(_) => 0, - Err(_) => 4, + Err(_) => 3, } } -#[no_mangle] -pub extern "C" fn aggregate_signatures( - sigs_raw: *const *const Sig, - sigs_len: usize, - out: *mut u8, - out_len: usize, -) -> isize { - if sigs_raw.is_null() || out.is_null() { - return 1; - } - if out_len < 96 { - return 2; - } +// #[no_mangle] +// pub extern "C" fn aggregate_signatures( +// sigs_raw: *const *const Sig, +// sigs_len: usize, +// out: *mut u8, +// out_len: usize, +// ) -> isize { +// if sigs_raw.is_null() || out.is_null() { +// return 1; +// } +// if out_len < 96 { +// return 2; +// } - let sigs_slice = unsafe { std::slice::from_raw_parts(sigs_raw, sigs_len) }; - let mut dms = DistinctMessages::::new(); - for &sig_ptr in sigs_slice.iter() { - let sig = unsafe { &*sig_ptr }; - dms.add_signature(sig); - } - let signature = <&DistinctMessages as Signed>::signature(&&dms); +// let sigs_slice = unsafe { std::slice::from_raw_parts(sigs_raw, sigs_len) }; +// let mut dms = DistinctMessages::::new(); +// for &sig_ptr in sigs_slice.iter() { +// let sig = unsafe { &*sig_ptr }; +// dms.add_signature(sig); +// } +// let signature = <&DistinctMessages as Signed>::signature(&&dms); - let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; - out_slice.copy_from_slice(&signature.to_bytes()); - 0 -} +// let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; +// out_slice.copy_from_slice(&signature.to_bytes()); +// 0 +// } diff --git a/Utils/Tests/UtilsTests/Crypto/BLSTests.swift b/Utils/Tests/UtilsTests/Crypto/BLSTests.swift index 5e9ab7b7..764283d2 100644 --- a/Utils/Tests/UtilsTests/Crypto/BLSTests.swift +++ b/Utils/Tests/UtilsTests/Crypto/BLSTests.swift @@ -7,8 +7,10 @@ import Testing @Test func BLSSignatureWorks() throws { let bls = try BLS.SecretKey(from: Data32()) let publicKey1 = bls.publicKey + #expect(publicKey1.data.data.count == 144) let message1 = Data("test1".utf8) let signature1 = try bls.sign(message: message1) + #expect(signature1.count == 160) #expect( try publicKey1.verify(signature: signature1, message: message1) @@ -19,10 +21,10 @@ import Testing try !publicKey1.verify(signature: signature1, message: invalidMessage) ) - var invalidSignature = signature1.data + var invalidSignature = signature1 invalidSignature.replaceSubrange(0 ... 1, with: [2, 3]) #expect( - try !publicKey1.verify(signature: Data96(invalidSignature)!, message: message1) + try !publicKey1.verify(signature: invalidSignature, message: message1) ) let bls2 = try BLS.SecretKey(from: Data32.random()) @@ -34,19 +36,31 @@ import Testing try publicKey2.verify(signature: signature2, message: message2) ) - let aggSig = try BLS.aggregateSignatures(signatures: [signature1, signature2]) - #expect( try BLS.aggregateVerify( - signatures: [aggSig], messages: [message1, message2], - publicKeys: [publicKey1, publicKey2] + message: message1, + signatures: [signature1], + publicKeys: [publicKey1] ) ) #expect( try !BLS.aggregateVerify( - signatures: [aggSig], messages: [message1, message2], - publicKeys: [publicKey2, publicKey1] + message: message2, + signatures: [signature1], + publicKeys: [publicKey1] + ) + ) + + let bls3 = try BLS.SecretKey(from: Data32.random()) + let publicKey3 = bls3.publicKey + let signature3 = try bls3.sign(message: message1) + + #expect( + try BLS.aggregateVerify( + message: message1, + signatures: [signature1, signature3], + publicKeys: [publicKey1, publicKey3] ) ) } From 60e4357c0f3c69860ca2a1fdd2c97590af6d87c6 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Thu, 17 Oct 2024 10:30:04 +0800 Subject: [PATCH 05/10] remove extra comments --- Utils/Sources/Utils/Crypto/BLS.swift | 41 ---------------------------- Utils/Sources/bls/src/ffi.rs | 31 --------------------- 2 files changed, 72 deletions(-) diff --git a/Utils/Sources/Utils/Crypto/BLS.swift b/Utils/Sources/Utils/Crypto/BLS.swift index 21d9fb7a..50c0900d 100644 --- a/Utils/Sources/Utils/Crypto/BLS.swift +++ b/Utils/Sources/Utils/Crypto/BLS.swift @@ -158,7 +158,6 @@ public enum BLS: KeyType { } } - // single message try FFIUtils.call(message) { ptrs in message_new_from_bytes( ptrs[0].ptr, @@ -207,44 +206,4 @@ public enum BLS: KeyType { return output[0] == 1 } - - // TODO: maybe we don't need this method - // public static func aggregateSignatures(signatures: [Data96]) throws -> Data96 { - // let sigPtrs: [OpaquePointer?] = [] - // defer { - // for sigPtr in sigPtrs { - // signature_free(sigPtr) - // } - // } - - // for signature in signatures { - // var sigPtr: OpaquePointer? - // try FFIUtils.call(signature.data) { ptrs in - // signature_new_from_bytes( - // ptrs[0].ptr, - // ptrs[0].count, - // &sigPtr - // ) - // } onErr: { err throws(Error) in - // throw .createSignatureFailed(err) - // } - // } - - // var output = Data(repeating: 0, count: 96) - - // try FFIUtils.call(out: &output) { _, out_buf in - // sigPtrs.withUnsafeBufferPointer { sigPtrs in - // aggregate_signatures( - // sigPtrs.baseAddress, - // UInt(sigPtrs.count), - // out_buf.ptr, - // out_buf.count - // ) - // } - // } onErr: { err throws(Error) in - // throw .aggregateSigsFailed(err) - // } - - // return Data96(Data(output))! - // } } diff --git a/Utils/Sources/bls/src/ffi.rs b/Utils/Sources/bls/src/ffi.rs index 447fde0d..7fabce2a 100644 --- a/Utils/Sources/bls/src/ffi.rs +++ b/Utils/Sources/bls/src/ffi.rs @@ -230,9 +230,6 @@ pub extern "C" fn aggeregated_verify( let signatures_slice = unsafe { std::slice::from_raw_parts(signatures, signatures_len) }; let publickeys_slice = unsafe { std::slice::from_raw_parts(publickeys, publickeys_len) }; - // TODO: check if this is the correct way to aggregate - // TODO: do pop here, DoubleSignature has the stuff needed - let mut aggregator = SignatureAggregatorAssumingPoP::::new(message.clone()); for &sig in signatures_slice { let sig = unsafe { &*sig }; @@ -240,7 +237,6 @@ pub extern "C" fn aggeregated_verify( } for &public_key in publickeys_slice { let public_key = unsafe { &*public_key }; - // aggregated_public_key.0 += public_key.1; aggregator.add_publickey(&PublicKey::(public_key.1)); aggregator.add_auxiliary_public_key(&PublicKeyInSignatureGroup::(public_key.0)); } @@ -251,30 +247,3 @@ pub extern "C" fn aggeregated_verify( Err(_) => 3, } } - -// #[no_mangle] -// pub extern "C" fn aggregate_signatures( -// sigs_raw: *const *const Sig, -// sigs_len: usize, -// out: *mut u8, -// out_len: usize, -// ) -> isize { -// if sigs_raw.is_null() || out.is_null() { -// return 1; -// } -// if out_len < 96 { -// return 2; -// } - -// let sigs_slice = unsafe { std::slice::from_raw_parts(sigs_raw, sigs_len) }; -// let mut dms = DistinctMessages::::new(); -// for &sig_ptr in sigs_slice.iter() { -// let sig = unsafe { &*sig_ptr }; -// dms.add_signature(sig); -// } -// let signature = <&DistinctMessages as Signed>::signature(&&dms); - -// let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; -// out_slice.copy_from_slice(&signature.to_bytes()); -// 0 -// } From 6dcaef160e1e8709fc1a70e287cf2082127165d9 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Thu, 17 Oct 2024 11:29:04 +0800 Subject: [PATCH 06/10] use tinybls and test common seeds --- Cargo.lock | 1 + Utils/Sources/bls/Cargo.toml | 4 ++ Utils/Sources/bls/src/bls.rs | 12 +++--- Utils/Sources/bls/src/ffi.rs | 30 ++++++------- .../Crypto/JamTestnetSeedTests.swift | 42 +++++++++++++++++++ 5 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift diff --git a/Cargo.lock b/Cargo.lock index 30ff81fd..fdb43a58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,6 +324,7 @@ dependencies = [ name = "bls" version = "0.1.0" dependencies = [ + "ark-bls12-381", "cbindgen 0.27.0", "hex-literal", "sha2", diff --git a/Utils/Sources/bls/Cargo.toml b/Utils/Sources/bls/Cargo.toml index cfb8169a..cc8209fa 100644 --- a/Utils/Sources/bls/Cargo.toml +++ b/Utils/Sources/bls/Cargo.toml @@ -14,6 +14,10 @@ w3f-bls = { git = "https://github.com/w3f/bls", rev = "c19bbe8", features = [ "experimental", ] } sha2 = { version = "0.10", default-features = false } +ark-bls12-381 = { version = "0.4.0", default-features = false, features = [ + "curve", +] } + [dev-dependencies] hex-literal = "0.4.1" diff --git a/Utils/Sources/bls/src/bls.rs b/Utils/Sources/bls/src/bls.rs index 75404fc8..75824b2d 100644 --- a/Utils/Sources/bls/src/bls.rs +++ b/Utils/Sources/bls/src/bls.rs @@ -1,11 +1,13 @@ use sha2::Sha256; use w3f_bls::{ single_pop_aggregator::SignatureAggregatorAssumingPoP, DoublePublicKey, DoublePublicKeyScheme, - DoubleSignature, Keypair, Message, SerializableToBytes, ZBLS, + DoubleSignature, Keypair, Message, SerializableToBytes, TinyBLS, }; +pub type Engine = TinyBLS; + pub fn key_pair_sign( - key_pair: &mut Keypair, + key_pair: &mut Keypair, msg: &Message, out_buf: &mut [u8], ) -> Result<(), ()> { @@ -16,9 +18,9 @@ pub fn key_pair_sign( } pub fn signature_verify( - sig: &DoubleSignature, + sig: &DoubleSignature, msg: &Message, - pub_key: &DoublePublicKey, + pub_key: &DoublePublicKey, out_buf: &mut [u8], ) -> Result<(), ()> { let res = sig.verify(msg, pub_key); @@ -27,7 +29,7 @@ pub fn signature_verify( } pub fn aggregated_verify( - aggregator: SignatureAggregatorAssumingPoP, + aggregator: SignatureAggregatorAssumingPoP, out_buf: &mut [u8], ) -> Result<(), ()> { // TODO: check using `verify` or `verify_using_aggregated_auxiliary_public_keys` diff --git a/Utils/Sources/bls/src/ffi.rs b/Utils/Sources/bls/src/ffi.rs index 7fabce2a..973516d1 100644 --- a/Utils/Sources/bls/src/ffi.rs +++ b/Utils/Sources/bls/src/ffi.rs @@ -1,19 +1,19 @@ use w3f_bls::{ single_pop_aggregator::SignatureAggregatorAssumingPoP, DoublePublicKey, DoublePublicKeyScheme, DoubleSignature, EngineBLS, Keypair, Message, PublicKey, PublicKeyInSignatureGroup, SecretKey, - SerializableToBytes, Signature, ZBLS, + SerializableToBytes, Signature, }; -use crate::bls::{aggregated_verify, key_pair_sign, signature_verify}; +use crate::bls::{aggregated_verify, key_pair_sign, signature_verify, Engine}; /// cbindgen:ignore -pub type KeyPair = Keypair; +pub type KeyPair = Keypair; /// cbindgen:ignore -pub type Public = DoublePublicKey; +pub type Public = DoublePublicKey; /// cbindgen:ignore -pub type Secret = SecretKey; +pub type Secret = SecretKey; /// cbindgen:ignore -pub type Sig = DoubleSignature; +pub type Sig = DoubleSignature; #[no_mangle] pub extern "C" fn keypair_new( @@ -25,7 +25,7 @@ pub extern "C" fn keypair_new( return 1; } let seed_bytes = unsafe { std::slice::from_raw_parts(seed, seed_len) }; - let secret = SecretKey::::from_seed(seed_bytes); + let secret = SecretKey::::from_seed(seed_bytes); let keypair = Box::new(Keypair { public: secret.into_public(), secret, @@ -56,10 +56,10 @@ pub extern "C" fn keypair_sign( if key_pair.is_null() || msg_data.is_null() || out.is_null() { return 1; } - if out_len < ZBLS::SIGNATURE_SERIALIZED_SIZE { + if out_len < Engine::SIGNATURE_SERIALIZED_SIZE { return 2; } - let key_pair: &mut Keypair = unsafe { &mut *key_pair }; + let key_pair: &mut Keypair = unsafe { &mut *key_pair }; let msg_data_slice = unsafe { std::slice::from_raw_parts(msg_data, msg_data_len) }; let msg = Message::from(msg_data_slice); let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; @@ -108,7 +108,7 @@ pub extern "C" fn public_serialize(public: *const Public, out: *mut u8, out_len: if public.is_null() || out.is_null() { return 1; } - if out_len < ZBLS::PUBLICKEY_SERIALIZED_SIZE { + if out_len < Engine::PUBLICKEY_SERIALIZED_SIZE { return 2; } let public: &Public = unsafe { &*public }; @@ -188,7 +188,7 @@ pub extern "C" fn signature_new_from_bytes( if bytes.is_null() || out_ptr.is_null() { return 1; } - if len < ZBLS::SIGNATURE_SERIALIZED_SIZE { + if len < Engine::SIGNATURE_SERIALIZED_SIZE { return 2; } let bytes_slice = unsafe { std::slice::from_raw_parts(bytes, len) }; @@ -230,15 +230,15 @@ pub extern "C" fn aggeregated_verify( let signatures_slice = unsafe { std::slice::from_raw_parts(signatures, signatures_len) }; let publickeys_slice = unsafe { std::slice::from_raw_parts(publickeys, publickeys_len) }; - let mut aggregator = SignatureAggregatorAssumingPoP::::new(message.clone()); + let mut aggregator = SignatureAggregatorAssumingPoP::::new(message.clone()); for &sig in signatures_slice { let sig = unsafe { &*sig }; - aggregator.add_signature(&Signature::(sig.0)); + aggregator.add_signature(&Signature::(sig.0)); } for &public_key in publickeys_slice { let public_key = unsafe { &*public_key }; - aggregator.add_publickey(&PublicKey::(public_key.1)); - aggregator.add_auxiliary_public_key(&PublicKeyInSignatureGroup::(public_key.0)); + aggregator.add_publickey(&PublicKey::(public_key.1)); + aggregator.add_auxiliary_public_key(&PublicKeyInSignatureGroup::(public_key.0)); } let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; diff --git a/Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift b/Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift new file mode 100644 index 00000000..213b375a --- /dev/null +++ b/Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift @@ -0,0 +1,42 @@ +import Foundation +import Testing + +@testable import Utils + +struct JamTestnetSeedTests { + @Test func alice() throws { + let seed = Data32(fromHexString: "0000000000000000000000000000000000000000000000000000000000000000")! + let bandersnatch = try Bandersnatch.SecretKey(from: seed) + let ed25519 = try Ed25519.SecretKey(from: seed) + let bls = try BLS.SecretKey(from: seed) + #expect(bandersnatch.publicKey.data.toHexString() == "5e465beb01dbafe160ce8216047f2155dd0569f058afd52dcea601025a8d161d") + #expect(ed25519.publicKey.data.toHexString() == "3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29") + #expect(bls.publicKey.data + .toHexString() == + "b27150a1f1cd24bccc792ba7ba4220a1e8c36636e35a969d1d14b4c89bce7d1d463474fb186114a89dd70e88506fefc9830756c27a7845bec1cb6ee31e07211afd0dde34f0dc5d89231993cd323973faa23d84d521fd574e840b8617c75d1a1d0102aa3c71999137001a77464ced6bb2885c460be760c709009e26395716a52c8c52e6e23906a455b4264e7d0c75466e") + } + + @Test func bob() throws { + let seed = Data32(fromHexString: "0000000000000000000000000000000000000000000000000000000000000001")! + let bandersnatch = try Bandersnatch.SecretKey(from: seed) + let ed25519 = try Ed25519.SecretKey(from: seed) + let bls = try BLS.SecretKey(from: seed) + #expect(bandersnatch.publicKey.data.toHexString() == "1565283e47871f63e863b3c78dc82c9a62ad3040027a7996c827e2461cbf1571") + #expect(ed25519.publicKey.data.toHexString() == "4cb5abf6ad79fbf5abbccafcc269d85cd2651ed4b885b5869f241aedf0a5ba29") + #expect(bls.publicKey.data + .toHexString() == + "8b8a096ada14a51df7e2067007bf6c24d7568d88bf89816c1287ba2784b4188c3536d70b1a1cbc8ab438056e457e2aa0ab48d30d6279373652d19269f7260624d0965c3dc00ed944d1b6ff6db06bb73dc1314164e9fed6020108487897ac3a9814eca841aedc47f504a848513166ffe39f89c9f3e7c6729dc99207f863a10bda142d5a24ba42b90d99d6d6df3fa6d780") + } + + @Test func charlie() throws { + let seed = Data32(fromHexString: "0000000000000000000000000000000000000000000000000000000000000002")! + let bandersnatch = try Bandersnatch.SecretKey(from: seed) + let ed25519 = try Ed25519.SecretKey(from: seed) + let bls = try BLS.SecretKey(from: seed) + #expect(bandersnatch.publicKey.data.toHexString() == "699a8fcb24649d8f159a5bd11916cb9541dc5360690c06935ecdf3b6d06cce01") + #expect(ed25519.publicKey.data.toHexString() == "7422b9887598068e32c4448a949adb290d0f4e35b9e01b0ee5f1a1e600fe2674") + #expect(bls.publicKey.data + .toHexString() == + "93377fa4dddd7cf95dddef8edfe9ff310ba4d8dffa57e34f2774ad2a6adb16e8ebca12e037dcaf5d762d8eaa9b9cb40498b771e65d8364b1af4cbf51b41525df62b78d8507218c14d9af1eeb96bec770646b9f2b887518b3248f8d8d526874231255aa247b7e252c0802be0a91cc659a0f4b679487345ab8a5f5d67b53319d6ad7d946b9976be4deab9e9a7f2486ecb1") + } +} From cf0ac8cfb9eeda287bef5b6e8286ce70a0d0192f Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Thu, 17 Oct 2024 11:37:18 +0800 Subject: [PATCH 07/10] upgrade lint and fix --- Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift b/Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift index 213b375a..ec074694 100644 --- a/Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift +++ b/Utils/Tests/UtilsTests/Crypto/JamTestnetSeedTests.swift @@ -13,6 +13,7 @@ struct JamTestnetSeedTests { #expect(ed25519.publicKey.data.toHexString() == "3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29") #expect(bls.publicKey.data .toHexString() == + // swiftlint:disable:next line_length "b27150a1f1cd24bccc792ba7ba4220a1e8c36636e35a969d1d14b4c89bce7d1d463474fb186114a89dd70e88506fefc9830756c27a7845bec1cb6ee31e07211afd0dde34f0dc5d89231993cd323973faa23d84d521fd574e840b8617c75d1a1d0102aa3c71999137001a77464ced6bb2885c460be760c709009e26395716a52c8c52e6e23906a455b4264e7d0c75466e") } @@ -25,6 +26,7 @@ struct JamTestnetSeedTests { #expect(ed25519.publicKey.data.toHexString() == "4cb5abf6ad79fbf5abbccafcc269d85cd2651ed4b885b5869f241aedf0a5ba29") #expect(bls.publicKey.data .toHexString() == + // swiftlint:disable:next line_length "8b8a096ada14a51df7e2067007bf6c24d7568d88bf89816c1287ba2784b4188c3536d70b1a1cbc8ab438056e457e2aa0ab48d30d6279373652d19269f7260624d0965c3dc00ed944d1b6ff6db06bb73dc1314164e9fed6020108487897ac3a9814eca841aedc47f504a848513166ffe39f89c9f3e7c6729dc99207f863a10bda142d5a24ba42b90d99d6d6df3fa6d780") } @@ -37,6 +39,7 @@ struct JamTestnetSeedTests { #expect(ed25519.publicKey.data.toHexString() == "7422b9887598068e32c4448a949adb290d0f4e35b9e01b0ee5f1a1e600fe2674") #expect(bls.publicKey.data .toHexString() == + // swiftlint:disable:next line_length "93377fa4dddd7cf95dddef8edfe9ff310ba4d8dffa57e34f2774ad2a6adb16e8ebca12e037dcaf5d762d8eaa9b9cb40498b771e65d8364b1af4cbf51b41525df62b78d8507218c14d9af1eeb96bec770646b9f2b887518b3248f8d8d526874231255aa247b7e252c0802be0a91cc659a0f4b679487345ab8a5f5d67b53319d6ad7d946b9976be4deab9e9a7f2486ecb1") } } From 070080fd44a8eb6a61f8296425ef322b3fc89898 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Thu, 17 Oct 2024 13:55:46 +0800 Subject: [PATCH 08/10] fix --- .../Blockchain/Types/State+Genesis.swift | 2 +- Utils/Sources/Utils/Crypto/BLS.swift | 43 ++++++++----------- Utils/Sources/Utils/Crypto/Bandersnatch.swift | 16 +++---- Utils/Sources/Utils/SafePointer.swift | 5 +++ Utils/Sources/bls/bindings.h | 10 +++-- Utils/Sources/bls/src/bls.rs | 27 +----------- Utils/Sources/bls/src/ffi.rs | 41 ++++++++---------- Utils/Tests/UtilsTests/Crypto/BLSTests.swift | 5 ++- 8 files changed, 58 insertions(+), 91 deletions(-) create mode 100644 Utils/Sources/Utils/SafePointer.swift diff --git a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift index 0d23da39..9b296cc5 100644 --- a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift +++ b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift @@ -11,7 +11,7 @@ extension State { devKeys.append(ValidatorKey( bandersnatch: keySet.bandersnatch.data, ed25519: keySet.ed25519.data, - bls: Data144(), + bls: keySet.bls.data, metadata: Data128() )) } diff --git a/Utils/Sources/Utils/Crypto/BLS.swift b/Utils/Sources/Utils/Crypto/BLS.swift index 50c0900d..422dc0c3 100644 --- a/Utils/Sources/Utils/Crypto/BLS.swift +++ b/Utils/Sources/Utils/Crypto/BLS.swift @@ -16,8 +16,8 @@ public enum BLS: KeyType { case aggregatedVerifyFailed(Int) } - public final class SecretKey: SecretKeyProtocol, @unchecked Sendable { - fileprivate let keyPairPtr: SendableOpaquePointer + public final class SecretKey: SecretKeyProtocol, Sendable { + fileprivate let keyPairPtr: SafePointer public let publicKey: PublicKey public init(from seed: Data32) throws(Error) { @@ -29,20 +29,17 @@ public enum BLS: KeyType { throw .createSecretFailed(err) } - keyPairPtr = ptr.asSendable - publicKey = try PublicKey(keyPair: ptr) - } - - deinit { - keypair_free(keyPairPtr.value) + // use SafePointer to ensure keypair is freed even `try PublicKey` throws + keyPairPtr = SafePointer(ptr: ptr.asSendable, free: keypair_free) + publicKey = try PublicKey(keyPair: keyPairPtr.ptr.value) } public func sign(message: Data) throws(Error) -> Data { - var output = Data(repeating: 0, count: 160) + var output = Data(repeating: 0, count: Int(BLS_SIGNATURE_SERIALIZED_SIZE)) try FFIUtils.call(message, out: &output) { ptrs, out_buf in keypair_sign( - keyPairPtr.value, + keyPairPtr.ptr.value, ptrs[0].ptr, ptrs[0].count, out_buf.ptr, @@ -56,7 +53,7 @@ public enum BLS: KeyType { } } - public final class PublicKey: PublicKeyProtocol, @unchecked Sendable { + public final class PublicKey: PublicKeyProtocol, Sendable { fileprivate let ptr: SendableOpaquePointer public let data: Data144 @@ -79,7 +76,7 @@ public enum BLS: KeyType { throw .createPublicKeyFailed(err) } - var data = Data(repeating: 0, count: 144) + var data = Data(repeating: 0, count: Int(BLS_PUBLICKEY_SERIALIZED_SIZE)) FFIUtils.call(out: &data) { _, out_buf in public_serialize(ptr, out_buf.ptr, out_buf.count) } @@ -116,25 +113,20 @@ public enum BLS: KeyType { } public func verify(signature: Data, message: Data) throws(Error) -> Bool { - var output = Data(repeating: 0, count: 1) + var output = false - try FFIUtils.call(signature, message, out: &output) { ptrs, out_buf in + FFIUtils.call(signature, message) { ptrs in public_verify( ptr.value, ptrs[0].ptr, ptrs[0].count, ptrs[1].ptr, ptrs[1].count, - out_buf.ptr, - out_buf.count + &output ) - } onErr: { err throws(Error) in - if err != 2 { - throw .signatureVerifyFailed(err) - } } - return output[0] == 1 + return output } } @@ -184,9 +176,9 @@ public enum BLS: KeyType { keyPtrs = publicKeys.map(\.ptr.value) - var output = Data(repeating: 0, count: 1) + var output = false - try FFIUtils.call(out: &output) { _, out_buf in + try FFIUtils.call { _ in keyPtrs.withUnsafeBufferPointer { keyPtrs in sigPtrs.withUnsafeBufferPointer { sigPtrs in aggeregated_verify( @@ -195,8 +187,7 @@ public enum BLS: KeyType { UInt(sigPtrs.count), keyPtrs.baseAddress!, UInt(keyPtrs.count), - out_buf.ptr, - out_buf.count + &output ) } } @@ -204,6 +195,6 @@ public enum BLS: KeyType { throw .aggregatedVerifyFailed(err) } - return output[0] == 1 + return output } } diff --git a/Utils/Sources/Utils/Crypto/Bandersnatch.swift b/Utils/Sources/Utils/Crypto/Bandersnatch.swift index 337f5148..7b95e0ab 100644 --- a/Utils/Sources/Utils/Crypto/Bandersnatch.swift +++ b/Utils/Sources/Utils/Crypto/Bandersnatch.swift @@ -19,7 +19,7 @@ public enum Bandersnatch: KeyType { } public final class SecretKey: SecretKeyProtocol, Sendable { - fileprivate let ptr: SendableOpaquePointer + fileprivate let ptr: SafePointer public let publicKey: PublicKey public init(from seed: Data32) throws(Error) { @@ -31,12 +31,8 @@ public enum Bandersnatch: KeyType { throw .createSecretFailed(err) } - self.ptr = ptr.asSendable - publicKey = try PublicKey(secretKey: ptr) - } - - deinit { - secret_free(ptr.value) + self.ptr = SafePointer(ptr: ptr.asSendable, free: secret_free) + publicKey = try PublicKey(secretKey: self.ptr.ptr.value) } /// Non-Anonymous VRF signature. @@ -52,7 +48,7 @@ public enum Bandersnatch: KeyType { try FFIUtils.call(vrfInputData, auxData, out: &output) { ptrs, out_buf in prover_ietf_vrf_sign( - ptr.value, + ptr.ptr.value, ptrs[0].ptr, ptrs[0].count, ptrs[1].ptr, @@ -74,7 +70,7 @@ public enum Bandersnatch: KeyType { try FFIUtils.call(vrfInputData, out: &output) { ptrs, out_buf in secret_output( - ptr.value, + ptr.ptr.value, ptrs[0].ptr, ptrs[0].count, out_buf.ptr, @@ -234,7 +230,7 @@ public enum Bandersnatch: KeyType { try FFIUtils.call(vrfInputData, auxData, out: &output) { ptrs, out_buf in ringPtrs.withUnsafeBufferPointer { ringPtrs in prover_ring_vrf_sign( - secret.ptr.value, + secret.ptr.ptr.value, ringPtrs.baseAddress, UInt(ringPtrs.count), proverIdx, diff --git a/Utils/Sources/Utils/SafePointer.swift b/Utils/Sources/Utils/SafePointer.swift new file mode 100644 index 00000000..369ab63f --- /dev/null +++ b/Utils/Sources/Utils/SafePointer.swift @@ -0,0 +1,5 @@ +public struct SafePointer: ~Copyable, Sendable { + let ptr: SendableOpaquePointer + let free: @Sendable (_ ptr: OpaquePointer) -> Void + deinit { free(ptr.value) } +} diff --git a/Utils/Sources/bls/bindings.h b/Utils/Sources/bls/bindings.h index 4a4cf636..331a0b2b 100644 --- a/Utils/Sources/bls/bindings.h +++ b/Utils/Sources/bls/bindings.h @@ -12,6 +12,10 @@ typedef struct Sig Sig; typedef struct Message Message; +extern const uintptr_t BLS_PUBLICKEY_SERIALIZED_SIZE; + +extern const uintptr_t BLS_SIGNATURE_SERIALIZED_SIZE; + intptr_t keypair_new(const uint8_t *seed, uintptr_t seed_len, KeyPair **out_ptr); void keypair_free(KeyPair *keypair); @@ -35,8 +39,7 @@ intptr_t public_verify(const Public *public_, uintptr_t signature_len, const uint8_t *msg_data, uintptr_t msg_data_len, - uint8_t *out, - uintptr_t out_len); + bool *out); intptr_t message_new_from_bytes(const uint8_t *msg_data, uintptr_t msg_data_len, Message **out_ptr); @@ -51,5 +54,4 @@ intptr_t aggeregated_verify(const Message *msg, uintptr_t signatures_len, const Public *const *publickeys, uintptr_t publickeys_len, - uint8_t *out, - uintptr_t out_len); + bool *out); diff --git a/Utils/Sources/bls/src/bls.rs b/Utils/Sources/bls/src/bls.rs index 75824b2d..7c5bf0ee 100644 --- a/Utils/Sources/bls/src/bls.rs +++ b/Utils/Sources/bls/src/bls.rs @@ -1,8 +1,4 @@ -use sha2::Sha256; -use w3f_bls::{ - single_pop_aggregator::SignatureAggregatorAssumingPoP, DoublePublicKey, DoublePublicKeyScheme, - DoubleSignature, Keypair, Message, SerializableToBytes, TinyBLS, -}; +use w3f_bls::{DoublePublicKeyScheme, Keypair, Message, SerializableToBytes, TinyBLS}; pub type Engine = TinyBLS; @@ -16,24 +12,3 @@ pub fn key_pair_sign( out_buf.copy_from_slice(&sig_bytes); Ok(()) } - -pub fn signature_verify( - sig: &DoubleSignature, - msg: &Message, - pub_key: &DoublePublicKey, - out_buf: &mut [u8], -) -> Result<(), ()> { - let res = sig.verify(msg, pub_key); - out_buf[0] = if res { 1 } else { 0 }; - Ok(()) -} - -pub fn aggregated_verify( - aggregator: SignatureAggregatorAssumingPoP, - out_buf: &mut [u8], -) -> Result<(), ()> { - // TODO: check using `verify` or `verify_using_aggregated_auxiliary_public_keys` - let res = aggregator.verify_using_aggregated_auxiliary_public_keys::(); - out_buf[0] = if res { 1 } else { 0 }; - Ok(()) -} diff --git a/Utils/Sources/bls/src/ffi.rs b/Utils/Sources/bls/src/ffi.rs index 973516d1..da82cb47 100644 --- a/Utils/Sources/bls/src/ffi.rs +++ b/Utils/Sources/bls/src/ffi.rs @@ -1,10 +1,11 @@ +use sha2::Sha256; use w3f_bls::{ single_pop_aggregator::SignatureAggregatorAssumingPoP, DoublePublicKey, DoublePublicKeyScheme, - DoubleSignature, EngineBLS, Keypair, Message, PublicKey, PublicKeyInSignatureGroup, SecretKey, + DoubleSignature, Keypair, Message, PublicKey, PublicKeyInSignatureGroup, SecretKey, SerializableToBytes, Signature, }; -use crate::bls::{aggregated_verify, key_pair_sign, signature_verify, Engine}; +use crate::bls::{key_pair_sign, Engine}; /// cbindgen:ignore pub type KeyPair = Keypair; @@ -15,6 +16,11 @@ pub type Secret = SecretKey; /// cbindgen:ignore pub type Sig = DoubleSignature; +#[no_mangle] +pub static BLS_PUBLICKEY_SERIALIZED_SIZE: usize = Public::SERIALIZED_BYTES_SIZE; +#[no_mangle] +pub static BLS_SIGNATURE_SERIALIZED_SIZE: usize = Sig::SERIALIZED_BYTES_SIZE; + #[no_mangle] pub extern "C" fn keypair_new( seed: *const u8, @@ -56,7 +62,7 @@ pub extern "C" fn keypair_sign( if key_pair.is_null() || msg_data.is_null() || out.is_null() { return 1; } - if out_len < Engine::SIGNATURE_SERIALIZED_SIZE { + if out_len < Sig::SERIALIZED_BYTES_SIZE { return 2; } let key_pair: &mut Keypair = unsafe { &mut *key_pair }; @@ -108,7 +114,7 @@ pub extern "C" fn public_serialize(public: *const Public, out: *mut u8, out_len: if public.is_null() || out.is_null() { return 1; } - if out_len < Engine::PUBLICKEY_SERIALIZED_SIZE { + if out_len < Public::SERIALIZED_BYTES_SIZE { return 2; } let public: &Public = unsafe { &*public }; @@ -134,8 +140,7 @@ pub extern "C" fn public_verify( signature_len: usize, msg_data: *const u8, msg_data_len: usize, - out: *mut u8, - out_len: usize, + out: *mut bool, ) -> isize { if public.is_null() || signature.is_null() || msg_data.is_null() || out.is_null() { return 1; @@ -148,11 +153,9 @@ pub extern "C" fn public_verify( }; let msg_data_slice = unsafe { std::slice::from_raw_parts(msg_data, msg_data_len) }; let msg = Message::from(msg_data_slice); - let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; - match signature_verify(&sig, &msg, &public, out_slice) { - Ok(_) => 0, - Err(_) => 3, - } + let res = sig.verify(&msg, &public); + unsafe { *out = res }; + 0 } #[no_mangle] @@ -188,7 +191,7 @@ pub extern "C" fn signature_new_from_bytes( if bytes.is_null() || out_ptr.is_null() { return 1; } - if len < Engine::SIGNATURE_SERIALIZED_SIZE { + if len < Sig::SERIALIZED_BYTES_SIZE { return 2; } let bytes_slice = unsafe { std::slice::from_raw_parts(bytes, len) }; @@ -216,15 +219,11 @@ pub extern "C" fn aggeregated_verify( signatures_len: usize, publickeys: *const *const Public, publickeys_len: usize, - out: *mut u8, - out_len: usize, + out: *mut bool, ) -> isize { if signatures.is_null() || msg.is_null() || publickeys.is_null() || out.is_null() { return 1; } - if out_len < 1 { - return 2; - } let message = unsafe { &*msg }; let signatures_slice = unsafe { std::slice::from_raw_parts(signatures, signatures_len) }; @@ -241,9 +240,7 @@ pub extern "C" fn aggeregated_verify( aggregator.add_auxiliary_public_key(&PublicKeyInSignatureGroup::(public_key.0)); } - let out_slice = unsafe { std::slice::from_raw_parts_mut(out, out_len) }; - match aggregated_verify(aggregator, out_slice) { - Ok(_) => 0, - Err(_) => 3, - } + let res = aggregator.verify_using_aggregated_auxiliary_public_keys::(); + unsafe { *out = res }; + 0 } diff --git a/Utils/Tests/UtilsTests/Crypto/BLSTests.swift b/Utils/Tests/UtilsTests/Crypto/BLSTests.swift index 764283d2..7c7b8b06 100644 --- a/Utils/Tests/UtilsTests/Crypto/BLSTests.swift +++ b/Utils/Tests/UtilsTests/Crypto/BLSTests.swift @@ -1,3 +1,4 @@ +import bls import Foundation import Testing @@ -7,10 +8,10 @@ import Testing @Test func BLSSignatureWorks() throws { let bls = try BLS.SecretKey(from: Data32()) let publicKey1 = bls.publicKey - #expect(publicKey1.data.data.count == 144) + #expect(publicKey1.data.data.count == Int(BLS_PUBLICKEY_SERIALIZED_SIZE)) let message1 = Data("test1".utf8) let signature1 = try bls.sign(message: message1) - #expect(signature1.count == 160) + #expect(signature1.count == Int(BLS_SIGNATURE_SERIALIZED_SIZE)) #expect( try publicKey1.verify(signature: signature1, message: message1) From 3bd538b2367ea88880ba22757682efde357da007 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Thu, 17 Oct 2024 14:37:11 +0800 Subject: [PATCH 09/10] fix --- Utils/Sources/Utils/Crypto/BLS.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Utils/Sources/Utils/Crypto/BLS.swift b/Utils/Sources/Utils/Crypto/BLS.swift index 422dc0c3..893636d7 100644 --- a/Utils/Sources/Utils/Crypto/BLS.swift +++ b/Utils/Sources/Utils/Crypto/BLS.swift @@ -115,7 +115,7 @@ public enum BLS: KeyType { public func verify(signature: Data, message: Data) throws(Error) -> Bool { var output = false - FFIUtils.call(signature, message) { ptrs in + try FFIUtils.call(signature, message) { ptrs in public_verify( ptr.value, ptrs[0].ptr, @@ -124,6 +124,9 @@ public enum BLS: KeyType { ptrs[1].count, &output ) + } onErr: { err throws(Error) in + // no need to throw here, but still need to catch errors + logger.debug("PublicKey.verify failed: \(err)") } return output From e508112ddb87a2de3c9bd78bfdb4fe8771b09123 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Fri, 18 Oct 2024 08:49:27 +0800 Subject: [PATCH 10/10] fix --- Utils/Sources/Utils/Crypto/BLS.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utils/Sources/Utils/Crypto/BLS.swift b/Utils/Sources/Utils/Crypto/BLS.swift index 893636d7..9e10d5d3 100644 --- a/Utils/Sources/Utils/Crypto/BLS.swift +++ b/Utils/Sources/Utils/Crypto/BLS.swift @@ -49,7 +49,7 @@ public enum BLS: KeyType { throw .keypairSignFailed(err) } - return Data(output) + return output } } @@ -195,7 +195,7 @@ public enum BLS: KeyType { } } } onErr: { err throws(Error) in - throw .aggregatedVerifyFailed(err) + logger.debug("aggregateVerify failed: \(err)") } return output