16 Commits

Author SHA1 Message Date
Luke Parker
224cf4ea21 Update monero-oxide to the branch with the new RPC
See https://github.com/monero-oxide/monero-oxide/pull/66.

Allows us to remove the shim `simple-request 0.1` we had to define as we now
have `simple-request 0.2` in tree.
2025-09-18 19:00:10 -04:00
Luke Parker
a9b1e5293c Support webpki-roots as a fallback in simple-request 2025-09-18 18:15:24 -04:00
Luke Parker
80009ab67f Tidy unused import 2025-09-18 17:49:37 -04:00
Luke Parker
df9fda2971 Fixes from errors in cherry-picked commits 2025-09-18 17:49:32 -04:00
Luke Parker
ca8afb83a1 simple-request 0.2.0 2025-09-18 17:41:31 -04:00
Luke Parker
18a9cf2535 Have simple-request return an error upon failing to find the system's root certificates 2025-09-18 17:41:31 -04:00
Luke Parker
10c126ad92 Misc updates 2025-09-18 17:41:25 -04:00
Luke Parker
19305aebc9 Finally make modular-frost work with alloc alone
Carries the update to `frost-schnorrkel` and `bitcoin-serai`.
2025-09-18 17:06:57 -04:00
Luke Parker
be68e27551 Tweak multiexp to compile on core
On `core`, it'll use a serial implementation of no benefit other than the fact
that when `alloc` _is_ enabled, it'll use the multi-scalar multiplication
algorithms.

`schnorr-signatures` was prior tweaked to include a shim for
`SchnorrSignature::verify` which didn't use `multiexp_vartime` yet this same
premise. Now, instead of callers writing these shims, it's within `multiexp`.
2025-09-18 17:06:42 -04:00
Luke Parker
d6d96fe8ff Correct std-shims feature flagging 2025-09-18 17:06:31 -04:00
Luke Parker
95909d83a4 Expose std_shims::io on core
The `io::Write` trait is somewhat worthless, being implemented for nothing, yet
`Read` remains fully functional. This also allows using its polyfills _without_
requiring `alloc`.

Opportunity taken to make `schnorr-signatures` not require `alloc`.

This will require a version bump before being published due to newly requiring
the `alloc` feature be specified to maintain pre-existing behavior.

Enables resolving https://github.com/monero-oxide/monero-oxide/issues/48.
2025-09-18 17:06:05 -04:00
Luke Parker
3bd48974f3 Add missing alloc feature to multiexp's use of zeroize
Fixes building `multiexp` without default features, without separately
specifying `zeroize` and adding the `alloc` feature.
2025-09-18 17:05:19 -04:00
Luke Parker
29093715e3 Add impl<R: Read> Read for &mut R to std_shims
Increases parity with `std::io`.
2025-09-18 17:05:07 -04:00
Luke Parker
87b4dfc8f3 Expand std_shims::prelude to better match std::prelude 2025-09-18 17:04:54 -04:00
Luke Parker
4db78b1787 Add the ability to bound the response's size limit to simple-request 2025-09-18 17:04:41 -04:00
Luke Parker
02a5f15535 Make the MSRV lint more robust
The prior version would fail if the last entry in the final array was not
originally the last entry.
2025-09-18 17:04:10 -04:00
83 changed files with 1106 additions and 797 deletions

View File

@@ -43,7 +43,7 @@ runs:
- name: Install solc
shell: bash
run: |
cargo +1.89 install svm-rs --version =0.5.18
cargo +1.90 install svm-rs --version =0.5.19
svm install 0.8.26
svm use 0.8.26

View File

@@ -18,7 +18,7 @@ jobs:
key: rust-advisory-db
- name: Install cargo deny
run: cargo +1.89 install cargo-deny --version =0.18.3
run: cargo +1.90 install cargo-deny --version =0.18.4
- name: Run cargo deny
run: cargo deny -L error --all-features check --hide-inclusion-graph

View File

@@ -52,7 +52,7 @@ jobs:
key: rust-advisory-db
- name: Install cargo deny
run: cargo +1.89 install cargo-deny --version =0.18.3
run: cargo +1.90 install cargo-deny --version =0.18.4
- name: Run cargo deny
run: cargo deny -L error --all-features check --hide-inclusion-graph
@@ -88,8 +88,8 @@ jobs:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
- name: Verify all dependencies are in use
run: |
cargo +1.89 install cargo-machete --version =0.8.0
cargo +1.89 machete
cargo +1.90 install cargo-machete --version =0.9.1
cargo +1.90 machete
msrv:
runs-on: ubuntu-latest
@@ -98,7 +98,7 @@ jobs:
- name: Verify claimed `rust-version`
shell: bash
run: |
cargo +1.89 install cargo-msrv --version =0.18.4
cargo +1.90 install cargo-msrv --version =0.18.4
function check_msrv {
# We `cd` into the directory passed as the first argument, but will return to the
@@ -144,14 +144,15 @@ jobs:
function check_workspace {
# Get the members array from the workspace's `Cargo.toml`
cargo_toml_lines=$(cat ./Cargo.toml | wc -l)
# Keep all lines after the start of the array, then keep all lines before the next "]"
members=$(cat Cargo.toml | grep "members\ \=\ \[" -m1 -A$cargo_toml_lines | grep "]" -m1 -B$cargo_toml_lines)
# Parse out any comments, including comments post-fixed on the same line as an entry
members=$(echo "$members" | grep -Ev "^[[:space:]]+#" | grep -Ev "^[[:space:]]?$" | awk -F',' '{print $1","}')
# Prune `members = [` to `[` by replacing the first line with just `[`
# Parse out any comments, whitespace, including comments post-fixed on the same line as an entry
# We accomplish the latter by pruning all characters after the entry's ","
members=$(echo "$members" | grep -Ev "^[[:space:]]*(#|$)" | awk -F',' '{print $1","}')
# Replace the first line, which was "members = [" and is now "members = [,", with "["
members=$(echo "$members" | sed "1s/.*/\[/")
# Remove the trailing comma by replacing the last line's "," with ""
members=$(echo "$members" | sed "$(($(echo "$members" | wc -l) - 1))s/\,//")
# Correct the last line, which was malleated to "]," when pruning comments
# Correct the last line, which was malleated to "],"
members=$(echo "$members" | sed "$(echo "$members" | wc -l)s/\]\,/\]/")
# Don't check the patches
@@ -174,6 +175,9 @@ jobs:
members=$(echo "$members" | grep -v "mini\"")
members=$(echo "$members" | grep -v "tests/")
# Remove the trailing comma by replacing the last line's "," with ""
members=$(echo "$members" | sed "$(($(echo "$members" | wc -l) - 1))s/\,//")
echo $members | jq -r ".[]" | while read -r member; do
check_msrv $member
correct=$?

191
Cargo.lock generated
View File

@@ -341,7 +341,7 @@ dependencies = [
"cfg-if",
"const-hex",
"derive_more 2.0.1",
"foldhash",
"foldhash 0.1.5",
"hashbrown 0.15.5",
"indexmap 2.11.0",
"itoa",
@@ -1462,7 +1462,7 @@ dependencies = [
"serde",
"serde_json",
"simple-request",
"std-shims",
"std-shims 0.1.5",
"subtle",
"thiserror 2.0.16",
"tokio",
@@ -1928,7 +1928,7 @@ dependencies = [
"ff-group-tests",
"group",
"hex",
"std-shims",
"std-shims 0.1.5",
"subtle",
"zeroize",
]
@@ -1939,7 +1939,7 @@ version = "0.4.99"
dependencies = [
"ciphersuite 0.4.2",
"dalek-ff-group 0.5.0",
"std-shims",
"std-shims 0.1.5",
"zeroize",
]
@@ -2402,7 +2402,7 @@ dependencies = [
"cxxbridge-cmd",
"cxxbridge-flags",
"cxxbridge-macro",
"foldhash",
"foldhash 0.1.5",
"link-cplusplus",
]
@@ -2552,7 +2552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976"
dependencies = [
"data-encoding",
"syn 2.0.106",
"syn 1.0.109",
]
[[package]]
@@ -2783,7 +2783,7 @@ version = "0.6.1"
dependencies = [
"borsh",
"ciphersuite 0.4.2",
"std-shims",
"std-shims 0.1.5",
"thiserror 2.0.16",
"zeroize",
]
@@ -2795,7 +2795,7 @@ dependencies = [
"ciphersuite 0.4.2",
"dkg",
"rand_core 0.6.4",
"std-shims",
"std-shims 0.1.5",
"zeroize",
]
@@ -2821,7 +2821,7 @@ dependencies = [
"rand_chacha 0.3.1",
"rand_core 0.6.4",
"secq256k1",
"std-shims",
"std-shims 0.1.5",
"thiserror 2.0.16",
"zeroize",
]
@@ -2836,7 +2836,7 @@ dependencies = [
"dkg-recovery",
"multiexp",
"rand_core 0.6.4",
"std-shims",
"std-shims 0.1.5",
"thiserror 2.0.16",
"zeroize",
]
@@ -2922,13 +2922,13 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]]
name = "ec-divisors"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7216a2e84c7671c167c3d81eafe0d2b1f418f102#7216a2e84c7671c167c3d81eafe0d2b1f418f102"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=dc1b3dbe436aae61ec363505052d4715d38ce1df#dc1b3dbe436aae61ec363505052d4715d38ce1df"
dependencies = [
"dalek-ff-group 0.5.99",
"ff",
"group",
"rand_core 0.6.4",
"std-shims",
"std-shims 0.1.99",
"subtle",
"zeroize",
]
@@ -3043,7 +3043,7 @@ dependencies = [
"prime-field",
"rand_core 0.6.4",
"short-weierstrass",
"std-shims",
"std-shims 0.1.5",
"typenum",
"zeroize",
]
@@ -3350,6 +3350,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "foldhash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "fork-tree"
version = "3.0.0"
@@ -3546,11 +3552,11 @@ version = "0.2.0"
dependencies = [
"ciphersuite 0.4.2",
"flexible-transcript",
"group",
"modular-frost",
"rand_core 0.6.4",
"schnorr-signatures",
"schnorrkel",
"std-shims 0.1.5",
"zeroize",
]
@@ -3771,7 +3777,7 @@ dependencies = [
[[package]]
name = "generalized-bulletproofs"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7216a2e84c7671c167c3d81eafe0d2b1f418f102#7216a2e84c7671c167c3d81eafe0d2b1f418f102"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=dc1b3dbe436aae61ec363505052d4715d38ce1df#dc1b3dbe436aae61ec363505052d4715d38ce1df"
dependencies = [
"blake2 0.10.6",
"ciphersuite 0.4.99",
@@ -3779,30 +3785,30 @@ dependencies = [
"flexible-transcript",
"multiexp",
"rand_core 0.6.4",
"std-shims",
"std-shims 0.1.99",
"zeroize",
]
[[package]]
name = "generalized-bulletproofs-circuit-abstraction"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7216a2e84c7671c167c3d81eafe0d2b1f418f102#7216a2e84c7671c167c3d81eafe0d2b1f418f102"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=dc1b3dbe436aae61ec363505052d4715d38ce1df#dc1b3dbe436aae61ec363505052d4715d38ce1df"
dependencies = [
"ciphersuite 0.4.99",
"generalized-bulletproofs",
"std-shims",
"std-shims 0.1.99",
"zeroize",
]
[[package]]
name = "generalized-bulletproofs-ec-gadgets"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7216a2e84c7671c167c3d81eafe0d2b1f418f102#7216a2e84c7671c167c3d81eafe0d2b1f418f102"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=dc1b3dbe436aae61ec363505052d4715d38ce1df#dc1b3dbe436aae61ec363505052d4715d38ce1df"
dependencies = [
"ciphersuite 0.4.99",
"generalized-bulletproofs-circuit-abstraction",
"generic-array 1.2.0",
"std-shims",
"std-shims 0.1.99",
]
[[package]]
@@ -4008,10 +4014,19 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
"foldhash 0.1.5",
"serde",
]
[[package]]
name = "hashbrown"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
dependencies = [
"foldhash 0.2.0",
]
[[package]]
name = "heck"
version = "0.4.1"
@@ -4245,7 +4260,7 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite",
"socket2 0.5.8",
"socket2 0.4.10",
"tokio",
"tower-service",
"tracing",
@@ -4302,6 +4317,7 @@ dependencies = [
"tokio",
"tokio-rustls",
"tower-service",
"webpki-roots 1.0.2",
]
[[package]]
@@ -5607,7 +5623,7 @@ dependencies = [
"soketto 0.8.1",
"thiserror 1.0.69",
"url",
"webpki-roots",
"webpki-roots 0.25.4",
]
[[package]]
@@ -6098,6 +6114,7 @@ dependencies = [
"schnorr-signatures",
"serde_json",
"sha2 0.10.9",
"std-shims 0.1.5",
"subtle",
"thiserror 2.0.16",
"zeroize",
@@ -6106,7 +6123,7 @@ dependencies = [
[[package]]
name = "monero-address"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"monero-base58",
@@ -6118,36 +6135,36 @@ dependencies = [
[[package]]
name = "monero-base58"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"monero-primitives",
"std-shims",
"std-shims 0.1.99",
]
[[package]]
name = "monero-borromean"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"monero-generators",
"monero-io",
"monero-primitives",
"std-shims",
"std-shims 0.1.99",
"zeroize",
]
[[package]]
name = "monero-bulletproofs"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"monero-generators",
"monero-io",
"monero-primitives",
"rand_core 0.6.4",
"std-shims",
"std-shims 0.1.99",
"thiserror 2.0.16",
"zeroize",
]
@@ -6155,7 +6172,7 @@ dependencies = [
[[package]]
name = "monero-clsag"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"dalek-ff-group 0.5.99",
@@ -6167,16 +6184,31 @@ dependencies = [
"monero-primitives",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
"std-shims",
"std-shims 0.1.99",
"subtle",
"thiserror 2.0.16",
"zeroize",
]
[[package]]
name = "monero-daemon-rpc"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"hex",
"monero-address",
"monero-interface",
"monero-oxide",
"serde",
"serde_json",
"std-shims 0.1.99",
]
[[package]]
name = "monero-generators"
version = "0.4.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"crypto-bigint 0.5.5",
"curve25519-dalek",
@@ -6184,30 +6216,43 @@ dependencies = [
"group",
"monero-io",
"sha3 0.10.8",
"std-shims",
"std-shims 0.1.99",
"subtle",
]
[[package]]
name = "monero-interface"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"hex",
"monero-oxide",
"std-shims 0.1.99",
"thiserror 2.0.16",
"zeroize",
]
[[package]]
name = "monero-io"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"std-shims",
"std-shims 0.1.99",
"zeroize",
]
[[package]]
name = "monero-mlsag"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"monero-generators",
"monero-io",
"monero-primitives",
"std-shims",
"std-shims 0.1.99",
"thiserror 2.0.16",
"zeroize",
]
@@ -6215,7 +6260,7 @@ dependencies = [
[[package]]
name = "monero-oxide"
version = "0.1.4-alpha"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"hex-literal",
@@ -6226,47 +6271,31 @@ dependencies = [
"monero-io",
"monero-mlsag",
"monero-primitives",
"std-shims",
"std-shims 0.1.99",
"zeroize",
]
[[package]]
name = "monero-primitives"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"monero-generators",
"monero-io",
"sha3 0.10.8",
"std-shims",
"zeroize",
]
[[package]]
name = "monero-rpc"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
dependencies = [
"curve25519-dalek",
"hex",
"monero-address",
"monero-oxide",
"serde",
"serde_json",
"std-shims",
"thiserror 2.0.16",
"std-shims 0.1.99",
"zeroize",
]
[[package]]
name = "monero-simple-request-rpc"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"digest_auth",
"hex",
"monero-rpc",
"monero-daemon-rpc",
"simple-request",
"tokio",
"zeroize",
@@ -6275,22 +6304,21 @@ dependencies = [
[[package]]
name = "monero-wallet"
version = "0.1.0"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=7f37cc8f770858aa1739e0f56dbe447db86f4ba6#7f37cc8f770858aa1739e0f56dbe447db86f4ba6"
source = "git+https://github.com/monero-oxide/monero-oxide?rev=f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c#f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c"
dependencies = [
"curve25519-dalek",
"dalek-ff-group 0.5.99",
"flexible-transcript",
"hex",
"modular-frost",
"monero-address",
"monero-clsag",
"monero-interface",
"monero-oxide",
"monero-rpc",
"rand 0.8.5",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
"rand_distr",
"std-shims",
"std-shims 0.1.99",
"thiserror 2.0.16",
"zeroize",
]
@@ -6334,8 +6362,6 @@ dependencies = [
"group",
"k256",
"rand_core 0.6.4",
"rustversion",
"std-shims",
"zeroize",
]
@@ -9474,7 +9500,7 @@ dependencies = [
"multiexp",
"rand_core 0.6.4",
"sha2 0.10.9",
"std-shims",
"std-shims 0.1.5",
"zeroize",
]
@@ -9607,7 +9633,7 @@ dependencies = [
"rand_core 0.6.4",
"sha2 0.11.0-rc.2",
"short-weierstrass",
"std-shims",
"std-shims 0.1.5",
]
[[package]]
@@ -10237,15 +10263,21 @@ dependencies = [
"ciphersuite 0.4.2",
"dalek-ff-group 0.5.0",
"dkg",
"dkg-dealer",
"dkg-evrf",
"dkg-musig",
"dkg-recovery",
"embedwards25519",
"flexible-transcript",
"frost-schnorrkel",
"minimal-ed448",
"modular-frost",
"multiexp",
"prime-field",
"schnorr-signatures",
"secq256k1",
"short-weierstrass",
"std-shims 0.1.5",
]
[[package]]
@@ -11045,9 +11077,10 @@ dependencies = [
[[package]]
name = "simple-request"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"base64ct",
"futures-util",
"http-body-util",
"hyper 1.4.1",
"hyper-rustls",
@@ -11861,13 +11894,20 @@ dependencies = [
[[package]]
name = "std-shims"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"hashbrown 0.15.5",
"hashbrown 0.16.0",
"rustversion",
"spin 0.10.0",
]
[[package]]
name = "std-shims"
version = "0.1.99"
dependencies = [
"std-shims 0.1.5",
]
[[package]]
name = "strobe-rs"
version = "0.8.1"
@@ -13362,6 +13402,15 @@ version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "webpki-roots"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "which"
version = "4.4.2"

View File

@@ -14,13 +14,6 @@ members = [
"patches/option-ext",
"patches/directories-next",
# monero-oxide expects `ciphersuite`, yet the `ciphersuite` in-tree here has breaking changes
# This re-exports the in-tree `ciphersuite` _without_ changes breaking to monero-oxide
# Not included in workspace to prevent having two crates with the same name (an error)
# "patches/ciphersuite",
# Same for `dalek-ff-group`
# "patches/dalek-ff-group",
"common/std-shims",
"common/zalloc",
"common/patchable-async-sleep",
@@ -193,7 +186,7 @@ overflow-checks = true
[patch.crates-io]
# Dependencies from monero-oxide which originate from within our own tree
std-shims = { path = "common/std-shims" }
std-shims = { path = "patches/std-shims" }
simple-request = { path = "common/request" }
multiexp = { path = "crypto/multiexp" }
flexible-transcript = { path = "crypto/transcript" }

View File

@@ -1,9 +1,9 @@
[package]
name = "simple-request"
version = "0.1.0"
version = "0.2.0"
description = "A simple HTTP(S) request library"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/common/simple-request"
repository = "https://github.com/serai-dex/serai/tree/develop/common/request"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = ["http", "https", "async", "request", "ssl"]
edition = "2021"
@@ -21,6 +21,7 @@ tower-service = { version = "0.3", default-features = false }
hyper = { version = "1", default-features = false, features = ["http1", "client"] }
hyper-util = { version = "0.1", default-features = false, features = ["http1", "client-legacy", "tokio"] }
http-body-util = { version = "0.1", default-features = false }
futures-util = { version = "0.3", default-features = false, features = ["std"] }
tokio = { version = "1", default-features = false }
hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "ring", "rustls-native-certs", "native-tokio"], optional = true }
@@ -30,5 +31,6 @@ base64ct = { version = "1", features = ["alloc"], optional = true }
[features]
tls = ["hyper-rustls"]
webpki-roots = ["tls", "hyper-rustls/webpki-roots"]
basic-auth = ["zeroize", "base64ct"]
default = ["tls"]

View File

@@ -52,37 +52,47 @@ pub struct Client {
}
impl Client {
fn connector() -> Connector {
#[allow(clippy::unnecessary_wraps)]
fn connector() -> Result<Connector, Error> {
let mut res = HttpConnector::new();
res.set_keepalive(Some(core::time::Duration::from_secs(60)));
res.set_nodelay(true);
res.set_reuse_address(true);
#[cfg(feature = "tls")]
res.enforce_http(false);
#[cfg(feature = "tls")]
let res = HttpsConnectorBuilder::new()
.with_native_roots()
.expect("couldn't fetch system's SSL roots")
.https_or_http()
.enable_http1()
.wrap_connector(res);
res
let https = HttpsConnectorBuilder::new().with_native_roots();
#[cfg(all(feature = "tls", not(feature = "webpki-roots")))]
let https = https.map_err(|e| {
Error::ConnectionError(
format!("couldn't load system's SSL root certificates and webpki-roots unavilable: {e:?}")
.into(),
)
})?;
// Fallback to `webpki-roots` if present
#[cfg(all(feature = "tls", feature = "webpki-roots"))]
let https = https.unwrap_or(HttpsConnectorBuilder::new().with_webpki_roots());
#[cfg(feature = "tls")]
let res = https.https_or_http().enable_http1().wrap_connector(res);
Ok(res)
}
pub fn with_connection_pool() -> Client {
Client {
pub fn with_connection_pool() -> Result<Client, Error> {
Ok(Client {
connection: Connection::ConnectionPool(
HyperClient::builder(TokioExecutor::new())
.pool_idle_timeout(core::time::Duration::from_secs(60))
.build(Self::connector()),
.build(Self::connector()?),
),
}
})
}
pub fn without_connection_pool(host: &str) -> Result<Client, Error> {
Ok(Client {
connection: Connection::Connection {
connector: Self::connector(),
connector: Self::connector()?,
host: {
let uri: Uri = host.parse().map_err(|_| Error::InvalidUri)?;
if uri.host().is_none() {
@@ -97,7 +107,7 @@ impl Client {
pub async fn request<R: Into<Request>>(&self, request: R) -> Result<Response<'_>, Error> {
let request: Request = request.into();
let mut request = request.0;
let Request { mut request, response_size_limit } = request;
if let Some(header_host) = request.headers().get(hyper::header::HOST) {
match &self.connection {
Connection::ConnectionPool(_) => {}
@@ -149,22 +159,22 @@ impl Client {
*connection_lock = Some(requester);
}
let connection = connection_lock.as_mut().unwrap();
let connection = connection_lock.as_mut().expect("lock over the connection was poisoned");
let mut err = connection.ready().await.err();
if err.is_none() {
// Send the request
let res = connection.send_request(request).await;
if let Ok(res) = res {
return Ok(Response(res, self));
let response = connection.send_request(request).await;
if let Ok(response) = response {
return Ok(Response { response, size_limit: response_size_limit, client: self });
}
err = res.err();
err = response.err();
}
// Since this connection has been put into an error state, drop it
*connection_lock = None;
Err(Error::Hyper(err.unwrap()))?
Err(Error::Hyper(err.expect("only here if `err` is some yet no error")))?
}
};
Ok(Response(response, self))
Ok(Response { response, size_limit: response_size_limit, client: self })
}
}

View File

@@ -7,11 +7,15 @@ pub use http_body_util::Full;
use crate::Error;
#[derive(Debug)]
pub struct Request(pub(crate) hyper::Request<Full<Bytes>>);
pub struct Request {
pub(crate) request: hyper::Request<Full<Bytes>>,
pub(crate) response_size_limit: Option<usize>,
}
impl Request {
#[cfg(feature = "basic-auth")]
fn username_password_from_uri(&self) -> Result<(String, String), Error> {
if let Some(authority) = self.0.uri().authority() {
if let Some(authority) = self.request.uri().authority() {
let authority = authority.as_str();
if authority.contains('@') {
// Decode the username and password from the URI
@@ -36,9 +40,10 @@ impl Request {
let mut formatted = format!("{username}:{password}");
let mut encoded = Base64::encode_string(formatted.as_bytes());
formatted.zeroize();
self.0.headers_mut().insert(
self.request.headers_mut().insert(
hyper::header::AUTHORIZATION,
HeaderValue::from_str(&format!("Basic {encoded}")).unwrap(),
HeaderValue::from_str(&format!("Basic {encoded}"))
.expect("couldn't form header from base64-encoded string"),
);
encoded.zeroize();
}
@@ -59,9 +64,17 @@ impl Request {
pub fn with_basic_auth(&mut self) {
let _ = self.basic_auth_from_uri();
}
}
impl From<hyper::Request<Full<Bytes>>> for Request {
fn from(request: hyper::Request<Full<Bytes>>) -> Request {
Request(request)
/// Set a size limit for the response.
///
/// This may be exceeded by a single HTTP frame and accordingly isn't perfect.
pub fn set_response_size_limit(&mut self, response_size_limit: Option<usize>) {
self.response_size_limit = response_size_limit;
}
}
impl From<hyper::Request<Full<Bytes>>> for Request {
fn from(request: hyper::Request<Full<Bytes>>) -> Request {
Request { request, response_size_limit: None }
}
}

View File

@@ -1,24 +1,47 @@
use std::io;
use hyper::{
StatusCode,
header::{HeaderValue, HeaderMap},
body::{Buf, Incoming},
body::Incoming,
};
use http_body_util::BodyExt;
use futures_util::{Stream, StreamExt};
use crate::{Client, Error};
// Borrows the client so its async task lives as long as this response exists.
#[allow(dead_code)]
#[derive(Debug)]
pub struct Response<'a>(pub(crate) hyper::Response<Incoming>, pub(crate) &'a Client);
pub struct Response<'a> {
pub(crate) response: hyper::Response<Incoming>,
pub(crate) size_limit: Option<usize>,
pub(crate) client: &'a Client,
}
impl Response<'_> {
pub fn status(&self) -> StatusCode {
self.0.status()
self.response.status()
}
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
self.0.headers()
self.response.headers()
}
pub async fn body(self) -> Result<impl std::io::Read, Error> {
Ok(self.0.into_body().collect().await.map_err(Error::Hyper)?.aggregate().reader())
let mut body = self.response.into_body().into_data_stream();
let mut res: Vec<u8> = vec![];
loop {
if let Some(size_limit) = self.size_limit {
let (lower, upper) = body.size_hint();
if res.len().wrapping_add(upper.unwrap_or(lower)) > size_limit.min(usize::MAX - 1) {
Err(Error::ConnectionError("response exceeded size limit".into()))?;
}
}
let Some(part) = body.next().await else { break };
let part = part.map_err(Error::Hyper)?;
res.extend(part.as_ref());
}
Ok(io::Cursor::new(res))
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "std-shims"
version = "0.1.4"
version = "0.1.5"
description = "A series of std shims to make alloc more feasible"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/common/std-shims"
@@ -18,9 +18,10 @@ workspace = true
[dependencies]
rustversion = { version = "1", default-features = false }
spin = { version = "0.10", default-features = false, features = ["use_ticket_mutex", "once", "lazy"] }
hashbrown = { version = "0.15", default-features = false, features = ["default-hasher", "inline-more"] }
spin = { version = "0.10", default-features = false, features = ["use_ticket_mutex", "fair_mutex", "once", "lazy"] }
hashbrown = { version = "0.16", default-features = false, features = ["default-hasher", "inline-more"], optional = true }
[features]
std = []
alloc = ["hashbrown"]
std = ["alloc", "spin/std"]
default = ["std"]

View File

@@ -1,11 +1,28 @@
# std shims
# `std` shims
A crate which passes through to std when the default `std` feature is enabled,
yet provides a series of shims when it isn't.
`std-shims` is a Rust crate with two purposes:
- Expand the functionality of `core` and `alloc`
- Polyfill functionality only available on newer version of Rust
No guarantee of one-to-one parity is provided. The shims provided aim to be sufficient for the
average case.
The goal is to make supporting no-`std` environments, and older versions of
Rust, as simple as possible. For most use cases, replacing `std::` with
`std_shims::` and adding `use std_shims::prelude::*` is sufficient to take full
advantage of `std-shims`.
`HashSet` and `HashMap` are provided via `hashbrown`. Synchronization primitives are provided via
`spin` (avoiding a requirement on `critical-section`).
types are not guaranteed to be
# API Surface
`std-shims` only aims to have items _mutually available_ between `alloc` (with
extra dependencies) and `std` publicly exposed. Items exclusive to `std`, with
no shims available, will not be exported by `std-shims`.
# Dependencies
`HashSet` and `HashMap` are provided via `hashbrown`. Synchronization
primitives are provided via `spin` (avoiding a requirement on
`critical-section`). Sections of `std::io` are independently matched as
possible. `rustversion` is used to detect when to provide polyfills.
# Disclaimer
No guarantee of one-to-one parity is provided. The shims provided aim to be
sufficient for the average case. Pull requests are _welcome_.

View File

@@ -1,7 +1,7 @@
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use extern_alloc::collections::*;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use hashbrown::{HashSet, HashMap};
#[cfg(feature = "std")]
pub use std::collections::*;
#[cfg(not(feature = "std"))]
pub use alloc::collections::*;
#[cfg(not(feature = "std"))]
pub use hashbrown::{HashSet, HashMap};

View File

@@ -1,42 +1,74 @@
#[cfg(feature = "std")]
pub use std::io::*;
#[cfg(not(feature = "std"))]
mod shims {
use core::fmt::{Debug, Formatter};
use alloc::{boxed::Box, vec::Vec};
use core::fmt::{self, Debug, Display, Formatter};
#[cfg(feature = "alloc")]
use extern_alloc::{boxed::Box, vec::Vec};
use crate::error::Error as CoreError;
/// The kind of error.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum ErrorKind {
UnexpectedEof,
Other,
}
/// An error.
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
error: Box<dyn Send + Sync>,
#[cfg(feature = "alloc")]
error: Box<dyn Send + Sync + CoreError>,
}
impl Debug for Error {
fn fmt(&self, fmt: &mut Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
fmt.debug_struct("Error").field("kind", &self.kind).finish_non_exhaustive()
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
<Self as Debug>::fmt(self, f)
}
}
impl CoreError for Error {}
#[cfg(not(feature = "alloc"))]
pub trait IntoBoxSendSyncError {}
#[cfg(not(feature = "alloc"))]
impl<I> IntoBoxSendSyncError for I {}
#[cfg(feature = "alloc")]
pub trait IntoBoxSendSyncError: Into<Box<dyn Send + Sync + CoreError>> {}
#[cfg(feature = "alloc")]
impl<I: Into<Box<dyn Send + Sync + CoreError>>> IntoBoxSendSyncError for I {}
impl Error {
pub fn new<E: 'static + Send + Sync>(kind: ErrorKind, error: E) -> Error {
Error { kind, error: Box::new(error) }
/// Create a new error.
///
/// The error object itself is silently dropped when `alloc` is not enabled.
#[allow(unused)]
pub fn new<E: 'static + IntoBoxSendSyncError>(kind: ErrorKind, error: E) -> Error {
#[cfg(not(feature = "alloc"))]
let res = Error { kind };
#[cfg(feature = "alloc")]
let res = Error { kind, error: error.into() };
res
}
pub fn other<E: 'static + Send + Sync>(error: E) -> Error {
Error { kind: ErrorKind::Other, error: Box::new(error) }
/// Create a new error with `io::ErrorKind::Other` as its kind.
///
/// The error object itself is silently dropped when `alloc` is not enabled.
#[allow(unused)]
pub fn other<E: 'static + IntoBoxSendSyncError>(error: E) -> Error {
#[cfg(not(feature = "alloc"))]
let res = Error { kind: ErrorKind::Other };
#[cfg(feature = "alloc")]
let res = Error { kind: ErrorKind::Other, error: error.into() };
res
}
/// The kind of error.
pub fn kind(&self) -> ErrorKind {
self.kind
}
pub fn into_inner(self) -> Option<Box<dyn Send + Sync>> {
/// Retrieve the inner error.
#[cfg(feature = "alloc")]
pub fn into_inner(self) -> Option<Box<dyn Send + Sync + CoreError>> {
Some(self.error)
}
}
@@ -64,6 +96,12 @@ mod shims {
}
}
impl<R: Read> Read for &mut R {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
R::read(*self, buf)
}
}
pub trait BufRead: Read {
fn fill_buf(&mut self) -> Result<&[u8]>;
fn consume(&mut self, amt: usize);
@@ -88,6 +126,7 @@ mod shims {
}
}
#[cfg(feature = "alloc")]
impl Write for Vec<u8> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.extend(buf);
@@ -95,6 +134,8 @@ mod shims {
}
}
}
#[cfg(not(feature = "std"))]
pub use shims::*;
#[cfg(feature = "std")]
pub use std::io::{ErrorKind, Error, Result, Read, BufRead, Write};

View File

@@ -2,17 +2,44 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
pub extern crate alloc;
#[cfg(not(feature = "alloc"))]
pub use core::*;
#[cfg(not(feature = "alloc"))]
pub use core::{alloc, borrow, ffi, fmt, slice, str, task};
#[cfg(not(feature = "std"))]
#[rustversion::before(1.81)]
pub mod error {
use core::fmt::Debug::Display;
pub trait Error: Debug + Display {}
}
#[cfg(not(feature = "std"))]
#[rustversion::since(1.81)]
pub use core::error;
#[cfg(feature = "alloc")]
extern crate alloc as extern_alloc;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use extern_alloc::{alloc, borrow, boxed, ffi, fmt, rc, slice, str, string, task, vec, format};
#[cfg(feature = "std")]
pub use std::{alloc, borrow, boxed, error, ffi, fmt, rc, slice, str, string, task, vec, format};
pub mod sync;
pub mod collections;
pub mod io;
pub use alloc::vec;
pub use alloc::str;
pub use alloc::string;
pub mod sync;
pub mod prelude {
// Shim the `std` prelude
#[cfg(feature = "alloc")]
pub use extern_alloc::{
format, vec,
borrow::ToOwned,
boxed::Box,
vec::Vec,
string::{String, ToString},
};
// Shim `div_ceil`
#[rustversion::before(1.73)]
#[doc(hidden)]
pub trait StdShimsDivCeil {
@@ -53,6 +80,7 @@ pub mod prelude {
}
}
// Shim `io::Error::other`
#[cfg(feature = "std")]
#[rustversion::before(1.74)]
#[doc(hidden)]

View File

@@ -1,19 +1,28 @@
pub use core::sync::*;
pub use alloc::sync::*;
pub use core::sync::atomic;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use extern_alloc::sync::{Arc, Weak};
#[cfg(feature = "std")]
pub use std::sync::{Arc, Weak};
mod mutex_shim {
#[cfg(feature = "std")]
pub use std::sync::*;
#[cfg(not(feature = "std"))]
pub use spin::*;
pub use spin::{Mutex, MutexGuard};
#[cfg(feature = "std")]
pub use std::sync::{Mutex, MutexGuard};
/// A shimmed `Mutex` with an API mutual to `spin` and `std`.
#[derive(Default, Debug)]
pub struct ShimMutex<T>(Mutex<T>);
impl<T> ShimMutex<T> {
/// Construct a new `Mutex`.
pub const fn new(value: T) -> Self {
Self(Mutex::new(value))
}
/// Acquire a lock on the contents of the `Mutex`.
///
/// On no-`std` environments, this may spin until the lock is acquired. On `std` environments,
/// this may panic if the `Mutex` was poisoned.
pub fn lock(&self) -> MutexGuard<'_, T> {
#[cfg(feature = "std")]
let res = self.0.lock().unwrap();
@@ -25,10 +34,8 @@ mod mutex_shim {
}
pub use mutex_shim::{ShimMutex as Mutex, MutexGuard};
#[cfg(not(feature = "std"))]
pub use spin::Lazy as LazyLock;
#[rustversion::before(1.80)]
#[cfg(feature = "std")]
#[cfg(not(feature = "std"))]
pub use spin::Lazy as LazyLock;
#[rustversion::since(1.80)]
#[cfg(feature = "std")]

View File

@@ -7,7 +7,7 @@ use rand::{RngCore, CryptoRng, rngs::OsRng};
use blake2::{Digest, Blake2s256};
use dalek_ff_group::Ristretto;
use ciphersuite::{group::Group, *};
use ciphersuite::*;
use schnorr::SchnorrSignature;
use scale::Encode;

View File

@@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
workspace = true
[dependencies]
std-shims = { path = "../../common/std-shims", version = "0.1.4", default-features = false, optional = true }
std-shims = { path = "../../common/std-shims", version = "0.1.4", default-features = false }
zeroize = { version = "^1.5", default-features = false, features = ["derive"] }
subtle = { version = "^2.4", default-features = false }
@@ -33,7 +33,7 @@ hex = { version = "0.4", default-features = false, features = ["std"] }
ff-group-tests = { version = "0.13", path = "../ff-group-tests" }
[features]
alloc = ["std-shims", "zeroize/alloc", "digest/alloc", "ff/alloc"]
alloc = ["zeroize/alloc", "digest/alloc", "ff/alloc"]
std = [
"alloc",

View File

@@ -3,10 +3,8 @@
#![cfg_attr(not(feature = "std"), no_std)]
use core::fmt::Debug;
#[cfg(feature = "alloc")]
#[allow(unused_imports)]
use std_shims::prelude::*;
#[cfg(feature = "alloc")]
use std_shims::io::{self, Read};
use subtle::{CtOption, ConstantTimeEq, ConditionallySelectable};
@@ -112,7 +110,6 @@ pub trait GroupCanonicalEncoding: WrappedGroup {
}
/// `std::io` extensions for `GroupCanonicalEncoding.`
#[cfg(feature = "alloc")]
#[allow(non_snake_case)]
pub trait GroupIo: GroupCanonicalEncoding {
/// Read a canonical field element from something implementing `std::io::Read`.
@@ -129,8 +126,6 @@ pub trait GroupIo: GroupCanonicalEncoding {
}
/// Read a canonical point from something implementing `std::io::Read`.
#[cfg(feature = "alloc")]
#[allow(non_snake_case)]
fn read_G<R: Read>(reader: &mut R) -> io::Result<Self::G> {
let mut bytes = <Self::G as GroupEncoding>::Repr::default();
reader.read_exact(bytes.as_mut())?;

View File

@@ -21,7 +21,7 @@ zeroize = { version = "^1.5", default-features = false, features = ["zeroize_der
thiserror = { version = "2", default-features = false }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] }
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }

View File

@@ -20,7 +20,7 @@ workspace = true
zeroize = { version = "^1.5", default-features = false }
rand_core = { version = "0.6", default-features = false }
std-shims = { version = "0.1", path = "../../../common/std-shims", default-features = false }
std-shims = { version = "0.1", path = "../../../common/std-shims", default-features = false, features = ["alloc"] }
ciphersuite = { path = "../../ciphersuite", version = "^0.4.1", default-features = false }
dkg = { path = "../", version = "0.6", default-features = false }

View File

@@ -23,7 +23,7 @@ rand_core = { version = "0.6", default-features = false, features = ["alloc"] }
zeroize = { version = "^1.5", default-features = false, features = ["alloc", "zeroize_derive"] }
std-shims = { version = "0.1", path = "../../../common/std-shims", default-features = false }
std-shims = { version = "0.1", path = "../../../common/std-shims", default-features = false, features = ["alloc"] }
transcript = { package = "flexible-transcript", path = "../../transcript", version = "^0.3.2", default-features = false, features = ["recommended"] }
@@ -34,10 +34,10 @@ generic-array = { version = "1", default-features = false, features = ["alloc"]
blake2 = { version = "0.11.0-rc.2", default-features = false }
rand_chacha = { version = "0.3", default-features = false }
generalized-bulletproofs = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", default-features = false }
ec-divisors = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", default-features = false }
generalized-bulletproofs-circuit-abstraction = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", default-features = false }
generalized-bulletproofs-ec-gadgets = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", default-features = false }
generalized-bulletproofs = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", default-features = false }
ec-divisors = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", default-features = false }
generalized-bulletproofs-circuit-abstraction = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", default-features = false }
generalized-bulletproofs-ec-gadgets = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", default-features = false }
dkg = { path = "..", default-features = false }
@@ -52,7 +52,7 @@ rand = { version = "0.8", default-features = false, features = ["std"] }
ciphersuite = { path = "../../ciphersuite", default-features = false, features = ["std"] }
embedwards25519 = { path = "../../embedwards25519", default-features = false, features = ["std"] }
dalek-ff-group = { path = "../../dalek-ff-group", default-features = false, features = ["std"] }
generalized-bulletproofs = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", features = ["tests"] }
generalized-bulletproofs = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", features = ["tests"] }
dkg-recovery = { path = "../recovery" }
[features]

View File

@@ -23,7 +23,7 @@ rand_core = { version = "0.6", default-features = false }
zeroize = { version = "^1.5", default-features = false, features = ["zeroize_derive"] }
std-shims = { version = "0.1", path = "../../../common/std-shims", default-features = false }
std-shims = { version = "0.1", path = "../../../common/std-shims", default-features = false, features = ["alloc"] }
multiexp = { path = "../../multiexp", version = "0.4", default-features = false }
ciphersuite = { path = "../../ciphersuite", version = "^0.4.1", default-features = false }

View File

@@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
hex-literal = { version = "1", default-features = false }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, optional = true }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false }
zeroize = { version = "^1.5", default-features = false, features = ["zeroize_derive"] }
@@ -29,7 +29,7 @@ curve25519-dalek = { version = "4", default-features = false, features = ["legac
blake2 = { version = "0.11.0-rc.2", default-features = false }
ciphersuite = { path = "../ciphersuite", version = "0.4", default-features = false }
generalized-bulletproofs-ec-gadgets = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", default-features = false, optional = true }
generalized-bulletproofs-ec-gadgets = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", default-features = false, optional = true }
[dev-dependencies]
hex = "0.4"
@@ -39,6 +39,6 @@ rand_core = { version = "0.6", features = ["std"] }
ff-group-tests = { path = "../ff-group-tests" }
[features]
alloc = ["std-shims", "zeroize/alloc", "prime-field/alloc", "short-weierstrass/alloc", "curve25519-dalek/alloc", "blake2/alloc", "ciphersuite/alloc", "generalized-bulletproofs-ec-gadgets"]
alloc = ["zeroize/alloc", "prime-field/alloc", "short-weierstrass/alloc", "curve25519-dalek/alloc", "blake2/alloc", "ciphersuite/alloc", "generalized-bulletproofs-ec-gadgets"]
std = ["alloc", "std-shims/std", "zeroize/std", "prime-field/std", "short-weierstrass/std", "ciphersuite/std", "generalized-bulletproofs-ec-gadgets/std"]
default = ["std"]

View File

@@ -2,7 +2,6 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "alloc")]
#[allow(unused_imports)]
use std_shims::prelude::*;

View File

@@ -17,33 +17,35 @@ rustdoc-args = ["--cfg", "docsrs"]
workspace = true
[dependencies]
thiserror = { version = "2", default-features = false, features = ["std"] }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] }
rand_core = { version = "0.6", default-features = false, features = ["std"] }
rand_chacha = { version = "0.3", default-features = false, features = ["std"] }
thiserror = { version = "2", default-features = false }
zeroize = { version = "^1.5", default-features = false, features = ["std", "zeroize_derive"] }
subtle = { version = "^2.4", default-features = false, features = ["std"] }
rand_core = { version = "0.6", default-features = false, features = ["alloc"] }
rand_chacha = { version = "0.3", default-features = false }
hex = { version = "0.4", default-features = false, features = ["std"], optional = true }
zeroize = { version = "^1.5", default-features = false, features = ["alloc", "zeroize_derive"] }
subtle = { version = "^2.4", default-features = false }
transcript = { package = "flexible-transcript", path = "../transcript", version = "^0.3.2", default-features = false, features = ["std", "recommended"] }
hex = { version = "0.4", default-features = false, features = ["alloc"], optional = true }
dalek-ff-group = { path = "../dalek-ff-group", version = "0.5", default-features = false, features = ["std"], optional = true }
minimal-ed448 = { path = "../ed448", version = "0.4", default-features = false, features = ["std"], optional = true }
transcript = { package = "flexible-transcript", path = "../transcript", version = "^0.3.2", default-features = false, features = ["recommended"] }
ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["std"] }
dalek-ff-group = { path = "../dalek-ff-group", version = "0.5", default-features = false, features = ["alloc"], optional = true }
minimal-ed448 = { path = "../ed448", version = "0.4", default-features = false, features = ["alloc"], optional = true }
ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["alloc"] }
sha2 = { version = "0.10.0", default-features = false, optional = true }
elliptic-curve = { version = "0.13", default-features = false, features = ["hash2curve"], optional = true }
ciphersuite-kp256 = { path = "../ciphersuite/kp256", version = "0.4", default-features = false, features = ["std"], optional = true }
ciphersuite-kp256 = { path = "../ciphersuite/kp256", version = "0.4", default-features = false, features = ["alloc"], optional = true }
multiexp = { path = "../multiexp", version = "0.4", default-features = false, features = ["std", "batch"] }
multiexp = { path = "../multiexp", version = "0.4", default-features = false, features = ["alloc", "batch"] }
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1", default-features = false, features = ["std"] }
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1", default-features = false, features = ["alloc"] }
dkg = { path = "../dkg", version = "0.6.1", default-features = false, features = ["std"] }
dkg-recovery = { path = "../dkg/recovery", version = "0.6", default-features = false, features = ["std"], optional = true }
dkg-dealer = { path = "../dkg/dealer", version = "0.6", default-features = false, features = ["std"], optional = true }
dkg = { path = "../dkg", version = "0.6.1", default-features = false }
dkg-recovery = { path = "../dkg/recovery", version = "0.6", default-features = false, optional = true }
dkg-dealer = { path = "../dkg/dealer", version = "0.6", default-features = false, optional = true }
[dev-dependencies]
hex = "0.4"
@@ -54,6 +56,38 @@ dkg-recovery = { path = "../dkg/recovery", default-features = false, features =
dkg-dealer = { path = "../dkg/dealer", default-features = false, features = ["std"] }
[features]
std = [
"std-shims/std",
"thiserror/std",
"rand_core/std",
"rand_chacha/std",
"zeroize/std",
"subtle/std",
"hex?/std",
"transcript/std",
"dalek-ff-group?/std",
"minimal-ed448?/std",
"ciphersuite/std",
"sha2?/std",
"elliptic-curve?/std",
"ciphersuite-kp256?/std",
"multiexp/std",
"schnorr/std",
"dkg/std",
"dkg-recovery?/std",
"dkg-dealer?/std",
]
ed25519 = ["dalek-ff-group"]
ristretto = ["dalek-ff-group"]
@@ -63,3 +97,5 @@ p256 = ["sha2", "elliptic-curve", "ciphersuite-kp256"]
ed448 = ["minimal-ed448"]
tests = ["hex", "rand_core/getrandom", "dkg-dealer", "dkg-recovery"]
default = ["std"]

View File

@@ -1,5 +1,7 @@
use core::{marker::PhantomData, fmt::Debug};
use std::io::{self, Read, Write};
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::io::{self, Read, Write};
use zeroize::Zeroizing;
use rand_core::{RngCore, CryptoRng};

View File

@@ -1,5 +1,7 @@
use core::{ops::Deref, convert::AsRef};
use std::io::{self, Read};
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::io::{self, Read};
use rand_core::{RngCore, CryptoRng};

View File

@@ -1,8 +1,11 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
use core::fmt::Debug;
use std::collections::HashMap;
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::collections::HashMap;
use thiserror::Error;

View File

@@ -6,7 +6,9 @@
// Each nonce remains of the form (d, e) and made into a proper nonce with d + (e * b)
use core::ops::Deref;
use std::{
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::{
io::{self, Read, Write},
collections::HashMap,
};

View File

@@ -1,5 +1,7 @@
use core::{ops::Deref, fmt::Debug};
use std::{
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::{
io::{self, Read, Write},
collections::HashMap,
};

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std_shims::collections::HashMap;
use rand_core::{RngCore, CryptoRng};

View File

@@ -1,4 +1,4 @@
use std::io::{self, Read};
use std_shims::io::{self, Read};
use zeroize::Zeroizing;

View File

@@ -1,8 +1,8 @@
use core::ops::Deref;
use std::collections::HashMap;
use std_shims::collections::HashMap;
#[cfg(test)]
use std::str::FromStr;
use core::str::FromStr;
use zeroize::Zeroizing;

View File

@@ -17,10 +17,6 @@ rustdoc-args = ["--cfg", "docsrs"]
workspace = true
[dependencies]
rustversion = "1"
std-shims = { path = "../../common/std-shims", version = "^0.1.1", default-features = false }
zeroize = { version = "^1.5", default-features = false, features = ["zeroize_derive"] }
ff = { version = "0.13", default-features = false, features = ["bits"] }
@@ -35,8 +31,9 @@ k256 = { version = "^0.13.1", default-features = false, features = ["arithmetic"
dalek-ff-group = { path = "../dalek-ff-group" }
[features]
std = ["std-shims/std", "zeroize/std", "ff/std", "rand_core?/std"]
alloc = ["zeroize/alloc"]
std = ["alloc", "zeroize/std", "ff/std", "rand_core?/std"]
batch = ["rand_core"]
batch = ["alloc", "rand_core"]
default = ["std"]

View File

@@ -12,5 +12,6 @@ culminating in commit
[669d2dbffc1dafb82a09d9419ea182667115df06](https://github.com/serai-dex/serai/tree/669d2dbffc1dafb82a09d9419ea182667115df06).
Any subsequent changes have not undergone auditing.
This library is usable under no_std, via alloc, when the default features are
disabled.
This library is usable under no-`std` and no-`alloc`. With the `alloc` feature,
the library is fully functional. Without the `alloc` feature, the `multiexp`
function is shimmed with a serial implementation.

View File

@@ -1,4 +1,4 @@
use std_shims::vec::Vec;
use alloc::vec::Vec;
use rand_core::{RngCore, CryptoRng};

View File

@@ -2,200 +2,177 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
#[macro_use]
#[cfg(feature = "alloc")]
extern crate alloc;
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::vec::Vec;
use zeroize::Zeroize;
use ff::PrimeFieldBits;
use group::Group;
#[cfg(feature = "alloc")]
mod straus;
use straus::*;
#[cfg(feature = "alloc")]
mod pippenger;
use pippenger::*;
#[cfg(feature = "batch")]
mod batch;
#[cfg(feature = "batch")]
pub use batch::BatchVerifier;
#[cfg(test)]
#[cfg(all(test, feature = "alloc"))]
mod tests;
// Use black_box when possible
#[rustversion::since(1.66)]
use core::hint::black_box;
#[rustversion::before(1.66)]
fn black_box<T>(val: T) -> T {
val
}
#[cfg(feature = "alloc")]
mod underlying {
use super::*;
fn u8_from_bool(bit_ref: &mut bool) -> u8 {
let bit_ref = black_box(bit_ref);
use core::hint::black_box;
use alloc::{vec, vec::Vec};
let mut bit = black_box(*bit_ref);
#[allow(clippy::cast_lossless)]
let res = black_box(bit as u8);
bit.zeroize();
debug_assert!((res | 1) == 1);
pub(crate) use straus::*;
bit_ref.zeroize();
res
}
pub(crate) use pippenger::*;
// Convert scalars to `window`-sized bit groups, as needed to index a table
// This algorithm works for `window <= 8`
pub(crate) fn prep_bits<G: Group<Scalar: PrimeFieldBits>>(
pairs: &[(G::Scalar, G)],
window: u8,
) -> Vec<Vec<u8>> {
let w_usize = usize::from(window);
#[cfg(feature = "batch")]
pub use batch::BatchVerifier;
let mut groupings = vec![];
for pair in pairs {
let p = groupings.len();
let mut bits = pair.0.to_le_bits();
groupings.push(vec![0; bits.len().div_ceil(w_usize)]);
fn u8_from_bool(bit_ref: &mut bool) -> u8 {
let bit_ref = black_box(bit_ref);
for (i, mut bit) in bits.iter_mut().enumerate() {
let mut bit = u8_from_bool(&mut bit);
groupings[p][i / w_usize] |= bit << (i % w_usize);
bit.zeroize();
let mut bit = black_box(*bit_ref);
#[allow(clippy::cast_lossless)]
let res = black_box(bit as u8);
bit.zeroize();
debug_assert!((res | 1) == 1);
bit_ref.zeroize();
res
}
// Convert scalars to `window`-sized bit groups, as needed to index a table
// This algorithm works for `window <= 8`
pub(crate) fn prep_bits<G: Group<Scalar: PrimeFieldBits>>(
pairs: &[(G::Scalar, G)],
window: u8,
) -> Vec<Vec<u8>> {
let w_usize = usize::from(window);
let mut groupings = vec![];
for pair in pairs {
let p = groupings.len();
let mut bits = pair.0.to_le_bits();
groupings.push(vec![0; bits.len().div_ceil(w_usize)]);
for (i, mut bit) in bits.iter_mut().enumerate() {
let mut bit = u8_from_bool(&mut bit);
groupings[p][i / w_usize] |= bit << (i % w_usize);
bit.zeroize();
}
}
groupings
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Algorithm {
Null,
Single,
Straus(u8),
Pippenger(u8),
}
// These are 'rule of thumb's obtained via benchmarking `k256` and `curve25519-dalek`
fn algorithm(len: usize) -> Algorithm {
#[cfg(not(debug_assertions))]
if len == 0 {
Algorithm::Null
} else if len == 1 {
Algorithm::Single
} else if len < 10 {
// Straus 2 never showed a performance benefit, even with just 2 elements
Algorithm::Straus(3)
} else if len < 20 {
Algorithm::Straus(4)
} else if len < 50 {
Algorithm::Straus(5)
} else if len < 100 {
Algorithm::Pippenger(4)
} else if len < 125 {
Algorithm::Pippenger(5)
} else if len < 275 {
Algorithm::Pippenger(6)
} else if len < 400 {
Algorithm::Pippenger(7)
} else {
Algorithm::Pippenger(8)
}
#[cfg(debug_assertions)]
if len == 0 {
Algorithm::Null
} else if len == 1 {
Algorithm::Single
} else if len < 10 {
Algorithm::Straus(3)
} else if len < 80 {
Algorithm::Straus(4)
} else if len < 100 {
Algorithm::Straus(5)
} else if len < 125 {
Algorithm::Pippenger(4)
} else if len < 275 {
Algorithm::Pippenger(5)
} else if len < 475 {
Algorithm::Pippenger(6)
} else if len < 750 {
Algorithm::Pippenger(7)
} else {
Algorithm::Pippenger(8)
}
}
groupings
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Algorithm {
Null,
Single,
Straus(u8),
Pippenger(u8),
}
/*
Release (with runs 20, so all of these are off by 20x):
k256
Straus 3 is more efficient at 5 with 678µs per
Straus 4 is more efficient at 10 with 530µs per
Straus 5 is more efficient at 35 with 467µs per
Pippenger 5 is more efficient at 125 with 431µs per
Pippenger 6 is more efficient at 275 with 349µs per
Pippenger 7 is more efficient at 375 with 360µs per
dalek
Straus 3 is more efficient at 5 with 519µs per
Straus 4 is more efficient at 10 with 376µs per
Straus 5 is more efficient at 170 with 330µs per
Pippenger 5 is more efficient at 125 with 305µs per
Pippenger 6 is more efficient at 275 with 250µs per
Pippenger 7 is more efficient at 450 with 205µs per
Pippenger 8 is more efficient at 800 with 213µs per
Debug (with runs 5, so...):
k256
Straus 3 is more efficient at 5 with 2532µs per
Straus 4 is more efficient at 10 with 1930µs per
Straus 5 is more efficient at 80 with 1632µs per
Pippenger 5 is more efficient at 150 with 1441µs per
Pippenger 6 is more efficient at 300 with 1235µs per
Pippenger 7 is more efficient at 475 with 1182µs per
Pippenger 8 is more efficient at 625 with 1170µs per
dalek:
Straus 3 is more efficient at 5 with 971µs per
Straus 4 is more efficient at 10 with 782µs per
Straus 5 is more efficient at 75 with 778µs per
Straus 6 is more efficient at 165 with 867µs per
Pippenger 5 is more efficient at 125 with 677µs per
Pippenger 6 is more efficient at 250 with 655µs per
Pippenger 7 is more efficient at 475 with 500µs per
Pippenger 8 is more efficient at 875 with 499µs per
*/
fn algorithm(len: usize) -> Algorithm {
#[cfg(not(debug_assertions))]
if len == 0 {
Algorithm::Null
} else if len == 1 {
Algorithm::Single
} else if len < 10 {
// Straus 2 never showed a performance benefit, even with just 2 elements
Algorithm::Straus(3)
} else if len < 20 {
Algorithm::Straus(4)
} else if len < 50 {
Algorithm::Straus(5)
} else if len < 100 {
Algorithm::Pippenger(4)
} else if len < 125 {
Algorithm::Pippenger(5)
} else if len < 275 {
Algorithm::Pippenger(6)
} else if len < 400 {
Algorithm::Pippenger(7)
} else {
Algorithm::Pippenger(8)
/// Performs a multiexponentiation, automatically selecting the optimal algorithm based on the
/// amount of pairs.
pub fn multiexp<G: Zeroize + Group<Scalar: Zeroize + PrimeFieldBits>>(
pairs: &[(G::Scalar, G)],
) -> G {
match algorithm(pairs.len()) {
Algorithm::Null => Group::identity(),
Algorithm::Single => pairs[0].1 * pairs[0].0,
// These functions panic if called without any pairs
Algorithm::Straus(window) => straus(pairs, window),
Algorithm::Pippenger(window) => pippenger(pairs, window),
}
}
#[cfg(debug_assertions)]
if len == 0 {
Algorithm::Null
} else if len == 1 {
Algorithm::Single
} else if len < 10 {
Algorithm::Straus(3)
} else if len < 80 {
Algorithm::Straus(4)
} else if len < 100 {
Algorithm::Straus(5)
} else if len < 125 {
Algorithm::Pippenger(4)
} else if len < 275 {
Algorithm::Pippenger(5)
} else if len < 475 {
Algorithm::Pippenger(6)
} else if len < 750 {
Algorithm::Pippenger(7)
} else {
Algorithm::Pippenger(8)
/// Performs a multiexponentiation in variable time, automatically selecting the optimal algorithm
/// based on the amount of pairs.
pub fn multiexp_vartime<G: Group<Scalar: PrimeFieldBits>>(pairs: &[(G::Scalar, G)]) -> G {
match algorithm(pairs.len()) {
Algorithm::Null => Group::identity(),
Algorithm::Single => pairs[0].1 * pairs[0].0,
Algorithm::Straus(window) => straus_vartime(pairs, window),
Algorithm::Pippenger(window) => pippenger_vartime(pairs, window),
}
}
}
/// Performs a multiexponentiation, automatically selecting the optimal algorithm based on the
/// amount of pairs.
pub fn multiexp<G: Zeroize + Group<Scalar: Zeroize + PrimeFieldBits>>(
pairs: &[(G::Scalar, G)],
) -> G {
match algorithm(pairs.len()) {
Algorithm::Null => Group::identity(),
Algorithm::Single => pairs[0].1 * pairs[0].0,
// These functions panic if called without any pairs
Algorithm::Straus(window) => straus(pairs, window),
Algorithm::Pippenger(window) => pippenger(pairs, window),
#[cfg(not(feature = "alloc"))]
mod underlying {
use super::*;
/// Performs a multiexponentiation, automatically selecting the optimal algorithm based on the
/// amount of pairs.
pub fn multiexp<G: Zeroize + Group<Scalar: Zeroize + PrimeFieldBits>>(
pairs: &[(G::Scalar, G)],
) -> G {
pairs.iter().map(|(scalar, point)| *point * scalar).sum()
}
/// Performs a multiexponentiation in variable time, automatically selecting the optimal algorithm
/// based on the amount of pairs.
pub fn multiexp_vartime<G: Group<Scalar: PrimeFieldBits>>(pairs: &[(G::Scalar, G)]) -> G {
pairs.iter().map(|(scalar, point)| *point * scalar).sum()
}
}
/// Performs a multiexponentiation in variable time, automatically selecting the optimal algorithm
/// based on the amount of pairs.
pub fn multiexp_vartime<G: Group<Scalar: PrimeFieldBits>>(pairs: &[(G::Scalar, G)]) -> G {
match algorithm(pairs.len()) {
Algorithm::Null => Group::identity(),
Algorithm::Single => pairs[0].1 * pairs[0].0,
Algorithm::Straus(window) => straus_vartime(pairs, window),
Algorithm::Pippenger(window) => pippenger_vartime(pairs, window),
}
}
pub use underlying::*;

View File

@@ -1,3 +1,5 @@
use alloc::vec;
use zeroize::Zeroize;
use ff::PrimeFieldBits;

View File

@@ -1,4 +1,4 @@
use std_shims::vec::Vec;
use alloc::{vec, vec::Vec};
use zeroize::Zeroize;

View File

@@ -26,8 +26,8 @@ digest = { version = "0.11.0-rc.1", default-features = false, features = ["block
transcript = { package = "flexible-transcript", path = "../transcript", version = "^0.3.2", default-features = false, optional = true }
ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["alloc"] }
multiexp = { path = "../multiexp", version = "0.4", default-features = false, features = ["batch"] }
ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false }
multiexp = { path = "../multiexp", version = "0.4", default-features = false }
[dev-dependencies]
hex = "0.4"
@@ -40,6 +40,7 @@ dalek-ff-group = { path = "../dalek-ff-group" }
ciphersuite = { path = "../ciphersuite" }
[features]
aggregate = ["transcript"]
std = ["std-shims/std", "rand_core/std", "zeroize/std", "transcript?/std", "ciphersuite/std", "multiexp/std"]
alloc = ["zeroize/alloc", "digest/alloc", "ciphersuite/alloc", "multiexp/alloc", "multiexp/batch"]
aggregate = ["alloc", "transcript"]
std = ["alloc", "std-shims/std", "rand_core/std", "zeroize/std", "transcript?/std", "ciphersuite/std", "multiexp/std"]
default = ["std"]

View File

@@ -3,14 +3,15 @@
#![cfg_attr(not(feature = "std"), no_std)]
use core::ops::Deref;
#[cfg(not(feature = "std"))]
#[macro_use]
#[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate alloc;
use std_shims::{
vec::Vec,
io::{self, Read, Write},
};
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec;
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::io::{self, Read, Write};
#[cfg(feature = "alloc")]
use rand_core::{RngCore, CryptoRng};
use zeroize::{Zeroize, Zeroizing};
@@ -22,7 +23,9 @@ use ciphersuite::{
},
GroupIo,
};
use multiexp::{multiexp_vartime, BatchVerifier};
use multiexp::multiexp_vartime;
#[cfg(feature = "alloc")]
use multiexp::BatchVerifier;
/// Half-aggregation from <https://eprint.iacr.org/2021/350>.
#[cfg(feature = "aggregate")]
@@ -59,6 +62,7 @@ impl<C: GroupIo> SchnorrSignature<C> {
}
/// Serialize a SchnorrSignature, returning a `Vec<u8>`.
#[cfg(feature = "alloc")]
pub fn serialize(&self) -> Vec<u8> {
let mut buf = vec![];
self.write(&mut buf).unwrap();
@@ -114,6 +118,7 @@ impl<C: GroupIo> SchnorrSignature<C> {
/// This challenge must be properly crafted, which means being binding to the public key, nonce,
/// and any message. Failure to do so will let a malicious adversary to forge signatures for
/// different keys/messages.
#[cfg(feature = "alloc")]
pub fn batch_verify<R: RngCore + CryptoRng, I: Copy + Zeroize>(
&self,
rng: &mut R,

View File

@@ -17,18 +17,35 @@ rustdoc-args = ["--cfg", "docsrs"]
workspace = true
[dependencies]
rand_core = "0.6"
zeroize = "^1.5"
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] }
transcript = { package = "flexible-transcript", path = "../transcript", version = "^0.3.2", features = ["merlin"] }
rand_core = { version = "0.6", default-features = false }
zeroize = { version = "1.5", default-features = false, features = ["zeroize_derive", "alloc"] }
group = "0.13"
transcript = { package = "flexible-transcript", path = "../transcript", version = "0.3.2", default-features = false, features = ["merlin"] }
ciphersuite = { path = "../ciphersuite", version = "^0.4.1", features = ["std"] }
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1" }
frost = { path = "../frost", package = "modular-frost", version = "0.11.0", features = ["ristretto"] }
ciphersuite = { path = "../ciphersuite", version = "0.4.1", default-features = false, features = ["alloc"] }
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "0.5.1", default-features = false, features = ["alloc"] }
frost = { path = "../frost", package = "modular-frost", version = "0.11.0", default-features = false, features = ["ristretto"] }
schnorrkel = { version = "0.11" }
schnorrkel = { version = "0.11", default-features = false, features = ["alloc"] }
[dev-dependencies]
frost = { path = "../frost", package = "modular-frost", features = ["tests"] }
[features]
std = [
"std-shims/std",
"rand_core/std",
"zeroize/std",
"transcript/std",
"ciphersuite/std",
"schnorr/std",
"frost/std",
"schnorrkel/std",
]
default = ["std"]

View File

@@ -1,7 +1,10 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
use std::io::{self, Read};
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::io::{self, Read};
use rand_core::{RngCore, CryptoRng};

View File

@@ -1,6 +1,6 @@
use rand_core::OsRng;
use group::GroupEncoding;
use ciphersuite::group::GroupEncoding;
use frost::{
Participant,
tests::{key_gen, algorithm_machines, sign},

View File

@@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
hex-literal = { version = "1", default-features = false }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, optional = true }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false }
sha2 = { version = "0.11.0-rc.0", default-features = false }
k256 = { version = "0.13", default-features = false, features = ["arithmetic", "expose-field"] }
@@ -24,7 +24,7 @@ prime-field = { path = "../prime-field", default-features = false }
short-weierstrass = { path = "../short-weierstrass", default-features = false }
ciphersuite = { path = "../ciphersuite", version = "0.4", default-features = false }
generalized-bulletproofs-ec-gadgets = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", default-features = false, optional = true }
generalized-bulletproofs-ec-gadgets = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", default-features = false, optional = true }
[dev-dependencies]
hex = "0.4"
@@ -34,6 +34,6 @@ rand_core = { version = "0.6", features = ["std"] }
ff-group-tests = { path = "../ff-group-tests" }
[features]
alloc = ["std-shims", "k256/alloc", "prime-field/alloc", "short-weierstrass/alloc", "sha2/alloc", "ciphersuite/alloc", "generalized-bulletproofs-ec-gadgets"]
alloc = ["k256/alloc", "prime-field/alloc", "short-weierstrass/alloc", "sha2/alloc", "ciphersuite/alloc", "generalized-bulletproofs-ec-gadgets"]
std = ["alloc", "std-shims/std", "k256/std", "prime-field/std", "ciphersuite/std", "generalized-bulletproofs-ec-gadgets/std"]
default = ["std"]

View File

@@ -2,7 +2,6 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "alloc")]
#[allow(unused_imports)]
use std_shims::prelude::*;

View File

@@ -21,7 +21,7 @@ rand_core = { version = "0.6", default-features = false }
ff = { version = "0.13", default-features = false, features = ["bits"] }
group = { version = "0.13", default-features = false }
ec-divisors = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7216a2e84c7671c167c3d81eafe0d2b1f418f102", default-features = false, optional = true }
ec-divisors = { git = "https://github.com/monero-oxide/monero-oxide", rev = "dc1b3dbe436aae61ec363505052d4715d38ce1df", default-features = false, optional = true }
[features]
alloc = ["zeroize/alloc", "rand_core/alloc", "ff/alloc", "group/alloc", "ec-divisors"]

102
deny.toml
View File

@@ -36,77 +36,77 @@ allow = [
"MPL-2.0",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"GPL-3.0 WITH Classpath-exception-2.0",
"GPL-3.0-or-later WITH Classpath-exception-2.0",
]
exceptions = [
{ allow = ["AGPL-3.0"], name = "serai-env" },
{ allow = ["AGPL-3.0"], name = "serai-task" },
{ allow = ["AGPL-3.0-only"], name = "serai-env" },
{ allow = ["AGPL-3.0-only"], name = "serai-task" },
{ allow = ["AGPL-3.0"], name = "ethereum-schnorr-contract" },
{ allow = ["AGPL-3.0"], name = "serai-ethereum-relayer" },
{ allow = ["AGPL-3.0-only"], name = "ethereum-schnorr-contract" },
{ allow = ["AGPL-3.0-only"], name = "serai-ethereum-relayer" },
{ allow = ["AGPL-3.0"], name = "serai-message-queue" },
{ allow = ["AGPL-3.0-only"], name = "serai-message-queue" },
{ allow = ["AGPL-3.0"], name = "serai-processor-messages" },
{ allow = ["AGPL-3.0"], name = "serai-processor-primitives" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-messages" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-primitives" },
{ allow = ["AGPL-3.0"], name = "serai-processor-key-gen" },
{ allow = ["AGPL-3.0"], name = "serai-processor-frost-attempt-manager" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-key-gen" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-frost-attempt-manager" },
{ allow = ["AGPL-3.0"], name = "serai-processor-scanner" },
{ allow = ["AGPL-3.0"], name = "serai-processor-scheduler-primitives" },
{ allow = ["AGPL-3.0"], name = "serai-processor-utxo-scheduler-primitives" },
{ allow = ["AGPL-3.0"], name = "serai-processor-utxo-scheduler" },
{ allow = ["AGPL-3.0"], name = "serai-processor-transaction-chaining-scheduler" },
{ allow = ["AGPL-3.0"], name = "serai-processor-smart-contract-scheduler" },
{ allow = ["AGPL-3.0"], name = "serai-processor-signers" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-scanner" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-scheduler-primitives" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-utxo-scheduler-primitives" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-utxo-scheduler" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-transaction-chaining-scheduler" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-smart-contract-scheduler" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-signers" },
{ allow = ["AGPL-3.0"], name = "serai-bitcoin-processor" },
{ allow = ["AGPL-3.0"], name = "serai-processor-bin" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-primitives" },
{ allow = ["AGPL-3.0"], name = "serai-ethereum-test-primitives" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-deployer" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-router" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-erc20" },
{ allow = ["AGPL-3.0"], name = "serai-ethereum-processor" },
{ allow = ["AGPL-3.0"], name = "serai-monero-processor" },
{ allow = ["AGPL-3.0-only"], name = "serai-bitcoin-processor" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-bin" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-ethereum-primitives" },
{ allow = ["AGPL-3.0-only"], name = "serai-ethereum-test-primitives" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-ethereum-deployer" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-ethereum-router" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-ethereum-erc20" },
{ allow = ["AGPL-3.0-only"], name = "serai-ethereum-processor" },
{ allow = ["AGPL-3.0-only"], name = "serai-monero-processor" },
{ allow = ["AGPL-3.0"], name = "tributary-sdk" },
{ allow = ["AGPL-3.0"], name = "serai-cosign" },
{ allow = ["AGPL-3.0"], name = "serai-coordinator-substrate" },
{ allow = ["AGPL-3.0"], name = "serai-coordinator-tributary" },
{ allow = ["AGPL-3.0"], name = "serai-coordinator-p2p" },
{ allow = ["AGPL-3.0"], name = "serai-coordinator-libp2p-p2p" },
{ allow = ["AGPL-3.0"], name = "serai-coordinator" },
{ allow = ["AGPL-3.0-only"], name = "tributary-sdk" },
{ allow = ["AGPL-3.0-only"], name = "serai-cosign" },
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-substrate" },
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-tributary" },
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-p2p" },
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-libp2p-p2p" },
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator" },
{ allow = ["AGPL-3.0"], name = "serai-coins-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-dex-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-coins-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-dex-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-genesis-liquidity-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-emissions-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-genesis-liquidity-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-emissions-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-economic-security-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-economic-security-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-in-instructions-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-in-instructions-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-validator-sets-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-validator-sets-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-signals-pallet" },
{ allow = ["AGPL-3.0-only"], name = "serai-signals-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-runtime" },
{ allow = ["AGPL-3.0"], name = "serai-node" },
{ allow = ["AGPL-3.0-only"], name = "serai-runtime" },
{ allow = ["AGPL-3.0-only"], name = "serai-node" },
{ allow = ["AGPL-3.0"], name = "serai-orchestrator" },
{ allow = ["AGPL-3.0-only"], name = "serai-orchestrator" },
{ allow = ["AGPL-3.0"], name = "mini-serai" },
{ allow = ["AGPL-3.0-only"], name = "mini-serai" },
{ allow = ["AGPL-3.0"], name = "serai-docker-tests" },
{ allow = ["AGPL-3.0"], name = "serai-message-queue-tests" },
{ allow = ["AGPL-3.0"], name = "serai-processor-tests" },
{ allow = ["AGPL-3.0"], name = "serai-coordinator-tests" },
{ allow = ["AGPL-3.0"], name = "serai-full-stack-tests" },
{ allow = ["AGPL-3.0"], name = "serai-reproducible-runtime-tests" },
{ allow = ["AGPL-3.0-only"], name = "serai-docker-tests" },
{ allow = ["AGPL-3.0-only"], name = "serai-message-queue-tests" },
{ allow = ["AGPL-3.0-only"], name = "serai-processor-tests" },
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-tests" },
{ allow = ["AGPL-3.0-only"], name = "serai-full-stack-tests" },
{ allow = ["AGPL-3.0-only"], name = "serai-reproducible-runtime-tests" },
]
[[licenses.clarify]]

View File

@@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"]
workspace = true
[dependencies]
std-shims = { version = "0.1.1", path = "../../common/std-shims", default-features = false }
std-shims = { version = "0.1.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] }
thiserror = { version = "2", default-features = false }
@@ -27,12 +27,12 @@ rand_core = { version = "0.6", default-features = false }
bitcoin = { version = "0.32", default-features = false }
k256 = { version = "^0.13.1", default-features = false, features = ["arithmetic", "bits"] }
frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.11", default-features = false, features = ["secp256k1"], optional = true }
frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.11", default-features = false, features = ["secp256k1"] }
hex = { version = "0.4", default-features = false, optional = true }
serde = { version = "1", default-features = false, features = ["derive"], optional = true }
serde_json = { version = "1", default-features = false, optional = true }
simple-request = { path = "../../common/request", version = "0.1", default-features = false, features = ["tls", "basic-auth"], optional = true }
simple-request = { path = "../../common/request", version = "0.2", default-features = false, features = ["tls", "basic-auth"], optional = true }
[dev-dependencies]
secp256k1 = { version = "0.29", default-features = false, features = ["std"] }
@@ -55,7 +55,7 @@ std = [
"bitcoin/serde",
"k256/std",
"frost",
"frost/std",
"hex/std",
"serde/std",

View File

@@ -1,9 +1,27 @@
#[cfg(feature = "std")]
use core::fmt::Debug;
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::io;
use subtle::{Choice, ConstantTimeEq, ConditionallySelectable};
use zeroize::Zeroizing;
use rand_core::{RngCore, CryptoRng};
use k256::{elliptic_curve::sec1::ToEncodedPoint, ProjectivePoint};
use k256::{
elliptic_curve::{ops::Reduce, sec1::ToEncodedPoint},
U256, Scalar, ProjectivePoint,
};
use bitcoin::key::XOnlyPublicKey;
use bitcoin::{
hashes::{HashEngine, Hash, sha256::Hash as Sha256},
key::XOnlyPublicKey,
};
use frost::{
curve::{WrappedGroup, Secp256k1},
Participant, ThresholdKeys, ThresholdView, FrostError,
algorithm::{Hram as HramTrait, Algorithm, IetfSchnorr as FrostSchnorr},
};
/// Get the x coordinate of a non-infinity point.
///
@@ -21,142 +39,118 @@ pub(crate) fn x_only(key: &ProjectivePoint) -> XOnlyPublicKey {
}
/// Return if a point must be negated to have an even Y coordinate and be eligible for use.
#[cfg(feature = "std")]
pub(crate) fn needs_negation(key: &ProjectivePoint) -> Choice {
use k256::elliptic_curve::sec1::Tag;
u8::from(key.to_encoded_point(true).tag()).ct_eq(&u8::from(Tag::CompressedOddY))
}
#[cfg(feature = "std")]
mod frost_crypto {
use core::fmt::Debug;
use std_shims::{vec::Vec, io};
/// A BIP-340 compatible HRAm for use with the modular-frost Schnorr Algorithm.
///
/// If passed an odd nonce, the challenge will be negated.
///
/// If either `R` or `A` is the point at infinity, this will panic.
#[derive(Clone, Copy, Debug)]
pub struct Hram;
#[allow(non_snake_case)]
impl HramTrait<Secp256k1> for Hram {
fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar {
const TAG_HASH: Sha256 = Sha256::const_hash(b"BIP0340/challenge");
use zeroize::Zeroizing;
use rand_core::{RngCore, CryptoRng};
let mut data = Sha256::engine();
data.input(TAG_HASH.as_ref());
data.input(TAG_HASH.as_ref());
data.input(&x(R));
data.input(&x(A));
data.input(m);
use bitcoin::hashes::{HashEngine, Hash, sha256::Hash as Sha256};
use k256::{elliptic_curve::ops::Reduce, U256, Scalar};
use frost::{
curve::{WrappedGroup, Secp256k1},
Participant, ThresholdKeys, ThresholdView, FrostError,
algorithm::{Hram as HramTrait, Algorithm, IetfSchnorr as FrostSchnorr},
};
use super::*;
/// A BIP-340 compatible HRAm for use with the modular-frost Schnorr Algorithm.
///
/// If passed an odd nonce, the challenge will be negated.
///
/// If either `R` or `A` is the point at infinity, this will panic.
#[derive(Clone, Copy, Debug)]
pub struct Hram;
#[allow(non_snake_case)]
impl HramTrait<Secp256k1> for Hram {
fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar {
const TAG_HASH: Sha256 = Sha256::const_hash(b"BIP0340/challenge");
let mut data = Sha256::engine();
data.input(TAG_HASH.as_ref());
data.input(TAG_HASH.as_ref());
data.input(&x(R));
data.input(&x(A));
data.input(m);
let c = Scalar::reduce(U256::from_be_slice(Sha256::from_engine(data).as_ref()));
// If the nonce was odd, sign `r - cx` instead of `r + cx`, allowing us to negate `s` at the
// end to sign as `-r + cx`
<_>::conditional_select(&c, &-c, needs_negation(R))
}
}
/// BIP-340 Schnorr signature algorithm.
///
/// This may panic if called with nonces/a group key which are the point at infinity (which have
/// a negligible probability for a well-reasoned caller, even with malicious participants
/// present).
///
/// `verify`, `verify_share` MUST be called after `sign_share` is called. Otherwise, this library
/// MAY panic.
#[derive(Clone)]
pub struct Schnorr(FrostSchnorr<Secp256k1, Hram>);
impl Schnorr {
/// Construct a Schnorr algorithm continuing the specified transcript.
#[allow(clippy::new_without_default)]
pub fn new() -> Schnorr {
Schnorr(FrostSchnorr::ietf())
}
}
impl Algorithm<Secp256k1> for Schnorr {
type Transcript = <FrostSchnorr<Secp256k1, Hram> as Algorithm<Secp256k1>>::Transcript;
type Addendum = ();
type Signature = [u8; 64];
fn transcript(&mut self) -> &mut Self::Transcript {
self.0.transcript()
}
fn nonces(&self) -> Vec<Vec<ProjectivePoint>> {
self.0.nonces()
}
fn preprocess_addendum<R: RngCore + CryptoRng>(
&mut self,
rng: &mut R,
keys: &ThresholdKeys<Secp256k1>,
) {
self.0.preprocess_addendum(rng, keys)
}
fn read_addendum<R: io::Read>(&self, reader: &mut R) -> io::Result<Self::Addendum> {
self.0.read_addendum(reader)
}
fn process_addendum(
&mut self,
view: &ThresholdView<Secp256k1>,
i: Participant,
addendum: (),
) -> Result<(), FrostError> {
self.0.process_addendum(view, i, addendum)
}
fn sign_share(
&mut self,
params: &ThresholdView<Secp256k1>,
nonce_sums: &[Vec<<Secp256k1 as WrappedGroup>::G>],
nonces: Vec<Zeroizing<<Secp256k1 as WrappedGroup>::F>>,
msg: &[u8],
) -> <Secp256k1 as WrappedGroup>::F {
self.0.sign_share(params, nonce_sums, nonces, msg)
}
fn verify(
&self,
group_key: ProjectivePoint,
nonces: &[Vec<ProjectivePoint>],
sum: Scalar,
) -> Option<Self::Signature> {
self.0.verify(group_key, nonces, sum).map(|mut sig| {
sig.s = <_>::conditional_select(&sum, &-sum, needs_negation(&sig.R));
// Convert to a Bitcoin signature by dropping the byte for the point's sign bit
sig.serialize()[1 ..].try_into().unwrap()
})
}
fn verify_share(
&self,
verification_share: ProjectivePoint,
nonces: &[Vec<ProjectivePoint>],
share: Scalar,
) -> Result<Vec<(Scalar, ProjectivePoint)>, ()> {
self.0.verify_share(verification_share, nonces, share)
}
let c = Scalar::reduce(U256::from_be_slice(Sha256::from_engine(data).as_ref()));
// If the nonce was odd, sign `r - cx` instead of `r + cx`, allowing us to negate `s` at the
// end to sign as `-r + cx`
<_>::conditional_select(&c, &-c, needs_negation(R))
}
}
/// BIP-340 Schnorr signature algorithm.
///
/// This may panic if called with nonces/a group key which are the point at infinity (which have
/// a negligible probability for a well-reasoned caller, even with malicious participants
/// present).
///
/// `verify`, `verify_share` MUST be called after `sign_share` is called. Otherwise, this library
/// MAY panic.
#[derive(Clone)]
pub struct Schnorr(FrostSchnorr<Secp256k1, Hram>);
impl Schnorr {
/// Construct a Schnorr algorithm continuing the specified transcript.
#[allow(clippy::new_without_default)]
pub fn new() -> Schnorr {
Schnorr(FrostSchnorr::ietf())
}
}
impl Algorithm<Secp256k1> for Schnorr {
type Transcript = <FrostSchnorr<Secp256k1, Hram> as Algorithm<Secp256k1>>::Transcript;
type Addendum = ();
type Signature = [u8; 64];
fn transcript(&mut self) -> &mut Self::Transcript {
self.0.transcript()
}
fn nonces(&self) -> Vec<Vec<ProjectivePoint>> {
self.0.nonces()
}
fn preprocess_addendum<R: RngCore + CryptoRng>(
&mut self,
rng: &mut R,
keys: &ThresholdKeys<Secp256k1>,
) {
self.0.preprocess_addendum(rng, keys)
}
fn read_addendum<R: io::Read>(&self, reader: &mut R) -> io::Result<Self::Addendum> {
self.0.read_addendum(reader)
}
fn process_addendum(
&mut self,
view: &ThresholdView<Secp256k1>,
i: Participant,
addendum: (),
) -> Result<(), FrostError> {
self.0.process_addendum(view, i, addendum)
}
fn sign_share(
&mut self,
params: &ThresholdView<Secp256k1>,
nonce_sums: &[Vec<<Secp256k1 as WrappedGroup>::G>],
nonces: Vec<Zeroizing<<Secp256k1 as WrappedGroup>::F>>,
msg: &[u8],
) -> <Secp256k1 as WrappedGroup>::F {
self.0.sign_share(params, nonce_sums, nonces, msg)
}
fn verify(
&self,
group_key: ProjectivePoint,
nonces: &[Vec<ProjectivePoint>],
sum: Scalar,
) -> Option<Self::Signature> {
self.0.verify(group_key, nonces, sum).map(|mut sig| {
sig.s = <_>::conditional_select(&sum, &-sum, needs_negation(&sig.R));
// Convert to a Bitcoin signature by dropping the byte for the point's sign bit
sig.serialize()[1 ..].try_into().unwrap()
})
}
fn verify_share(
&self,
verification_share: ProjectivePoint,
nonces: &[Vec<ProjectivePoint>],
share: Scalar,
) -> Result<Vec<(Scalar, ProjectivePoint)>, ()> {
self.0.verify_share(verification_share, nonces, share)
}
}
#[cfg(feature = "std")]
pub use frost_crypto::*;

View File

@@ -2,9 +2,6 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
extern crate alloc;
/// The bitcoin Rust library.
pub use bitcoin;

View File

@@ -62,7 +62,8 @@ impl Rpc {
/// provided to this library, if the RPC has an incompatible argument layout. That is not checked
/// at time of RPC creation.
pub async fn new(url: String) -> Result<Rpc, RpcError> {
let rpc = Rpc { client: Client::with_connection_pool(), url };
let rpc =
Rpc { client: Client::with_connection_pool().map_err(|_| RpcError::ConnectionError)?, url };
// Make an RPC request to verify the node is reachable and sane
let res: String = rpc.rpc_call("help", json!([])).await?;

View File

@@ -1,36 +1,31 @@
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::{
vec::Vec,
collections::HashMap,
io::{self, Write},
io::{self, Read, Write},
};
#[cfg(feature = "std")]
use std::io::{Read, BufReader};
use k256::{
elliptic_curve::sec1::{Tag, ToEncodedPoint},
Scalar, ProjectivePoint,
};
#[cfg(feature = "std")]
use frost::{
curve::{WrappedGroup, GroupIo, Secp256k1},
ThresholdKeys,
};
use bitcoin::{
consensus::encode::serialize, key::TweakedPublicKey, OutPoint, ScriptBuf, TxOut, Transaction,
Block,
hashes::Hash,
key::TweakedPublicKey,
TapTweakHash,
consensus::encode::{Decodable, serialize},
OutPoint, ScriptBuf, TxOut, Transaction, Block,
};
#[cfg(feature = "std")]
use bitcoin::{hashes::Hash, consensus::encode::Decodable, TapTweakHash};
use crate::crypto::x_only;
#[cfg(feature = "std")]
use crate::crypto::needs_negation;
use crate::crypto::{x_only, needs_negation};
#[cfg(feature = "std")]
mod send;
#[cfg(feature = "std")]
pub use send::*;
/// Tweak keys to ensure they're usable with Bitcoin's Taproot upgrade.
@@ -42,7 +37,6 @@ pub use send::*;
/// After adding an unspendable script path, the key is negated if odd.
///
/// This has a neligible probability of returning keys whose group key is the point at infinity.
#[cfg(feature = "std")]
pub fn tweak_keys(keys: ThresholdKeys<Secp256k1>) -> ThresholdKeys<Secp256k1> {
// Adds the unspendable script path per
// https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-23
@@ -118,18 +112,23 @@ impl ReceivedOutput {
}
/// Read a ReceivedOutput from a generic satisfying Read.
#[cfg(feature = "std")]
pub fn read<R: Read>(r: &mut R) -> io::Result<ReceivedOutput> {
let offset = Secp256k1::read_F(r)?;
let output;
let outpoint;
{
let mut buf_r = BufReader::with_capacity(0, r);
output =
TxOut::consensus_decode(&mut buf_r).map_err(|_| io::Error::other("invalid TxOut"))?;
outpoint =
OutPoint::consensus_decode(&mut buf_r).map_err(|_| io::Error::other("invalid OutPoint"))?;
struct BitcoinRead<R: Read>(R);
impl<R: Read> bitcoin::io::Read for BitcoinRead<R> {
fn read(&mut self, buf: &mut [u8]) -> bitcoin::io::Result<usize> {
self
.0
.read(buf)
.map_err(|e| bitcoin::io::Error::new(bitcoin::io::ErrorKind::Other, e.to_string()))
}
}
let mut r = BitcoinRead(r);
let output = TxOut::consensus_decode(&mut r).map_err(|_| io::Error::other("invalid TxOut"))?;
let outpoint =
OutPoint::consensus_decode(&mut r).map_err(|_| io::Error::other("invalid OutPoint"))?;
Ok(ReceivedOutput { offset, output, outpoint })
}

View File

@@ -1,3 +1,5 @@
#[allow(unused_imports)]
use std_shims::prelude::*;
use std_shims::{
io::{self, Read},
collections::HashMap,

View File

@@ -19,7 +19,7 @@ workspace = true
tower = "0.5"
serde_json = { version = "1", default-features = false }
simple-request = { path = "../../../common/request", version = "0.1", default-features = false }
simple-request = { path = "../../../common/request", version = "0.2", default-features = false }
alloy-json-rpc = { version = "1", default-features = false }
alloy-transport = { version = "1", default-features = false }

View File

@@ -7,7 +7,7 @@ use std::io;
use alloy_json_rpc::{RequestPacket, ResponsePacket};
use alloy_transport::{TransportError, TransportErrorKind, TransportFut};
use simple_request::{hyper, Request, Client};
use simple_request::{hyper, Error, Request, Client};
use tower::Service;
@@ -18,8 +18,8 @@ pub struct SimpleRequest {
}
impl SimpleRequest {
pub fn new(url: String) -> Self {
Self { client: Client::with_connection_pool(), url }
pub fn new(url: String) -> Result<Self, Error> {
Ok(Self { client: Client::with_connection_pool()?, url })
}
}

View File

@@ -36,7 +36,7 @@ async fn setup_test() -> (AnvilInstance, Arc<RootProvider>, Address) {
let anvil = Anvil::new().spawn();
let provider = Arc::new(RootProvider::new(
ClientBuilder::default().transport(SimpleRequest::new(anvil.endpoint()), true),
ClientBuilder::default().transport(SimpleRequest::new(anvil.endpoint()).unwrap(), true),
));
let mut address = [0; 20];

View File

@@ -1,50 +0,0 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
# This GPG-signed message exists to confirm the SHA256 sums of Monero binaries.
#
# Please verify the signature against the key for binaryFate in the
# source code repository (/utils/gpg_keys).
#
#
## CLI
15e4d7dfc2f9261a0a452b0f8fd157c33cdbc8a896e23d883ddd13e2480a3800 monero-android-armv7-v0.18.3.4.tar.bz2
d9c9249d1408822ce36b346c6b9fb6b896cda16714d62117fb1c588a5201763c monero-android-armv8-v0.18.3.4.tar.bz2
360a551388922c8991a9ba4abaa88676b0fc7ec1fa4d0f4b5c0500847e0b946c monero-freebsd-x64-v0.18.3.4.tar.bz2
354603c56446fb0551cdd6933bce5a13590b7881e05979b7ec25d89e7e59a0e2 monero-linux-armv7-v0.18.3.4.tar.bz2
33ca2f0055529d225b61314c56370e35606b40edad61c91c859f873ed67a1ea7 monero-linux-armv8-v0.18.3.4.tar.bz2
88739a1521b9fda3154540268e416c7af016ed7857041c76ab8ed7d7674c71ca monero-linux-riscv64-v0.18.3.4.tar.bz2
51ba03928d189c1c11b5379cab17dd9ae8d2230056dc05c872d0f8dba4a87f1d monero-linux-x64-v0.18.3.4.tar.bz2
d7ca0878abff2919a0104d7ed29d9c35df9ca0ea1b6fb4ebf6c8f7607ffb9e41 monero-linux-x86-v0.18.3.4.tar.bz2
44520cb3a05c2518ca9aeae1b2e3080fe2bba1e3596d014ceff1090dfcba8ab4 monero-mac-armv8-v0.18.3.4.tar.bz2
32c449f562216d3d83154e708471236d07db7477d6b67f1936a0a85a5005f2b8 monero-mac-x64-v0.18.3.4.tar.bz2
54a66db6c892b2a0999754841f4ca68511741b88ea3ab20c7cd504a027f465f5 monero-win-x64-v0.18.3.4.zip
1a9824742aa1587023c3bddea788c115940cfd49371c78a8dd62c40113132d01 monero-win-x86-v0.18.3.4.zip
7d4845ec0a3b52404d41785da348ec33509f0a5981e8a27c5fa55b18d696e139 monero-source-v0.18.3.4.tar.bz2
#
## GUI
63349d5a7637cd0c5d1693a1a2e910a92cbb123903d57667077a36454845d7bf monero-gui-install-win-x64-v0.18.3.4.exe
2866f3a2be30e4c4113e6274cad1d6698f81c37ceebc6e8f084c57230a0f70a6 monero-gui-linux-x64-v0.18.3.4.tar.bz2
eedbf827513607a3ef579077dacd573e65892b199102effef97dff9d73138ca6 monero-gui-mac-armv8-v0.18.3.4.dmg
54eb151d7511a9f26130864e2c02f258344803b2b68311c8be29850d7faef359 monero-gui-mac-x64-v0.18.3.4.dmg
b5d42dddd722e728e480337f89038c8ea606c6507bf0c88ddf2af25050c9b751 monero-gui-win-x64-v0.18.3.4.zip
2f1d643bb2cc08e5eb334a6bfd649b0aa95ceb6178ff2f90448d5ef8d2a752a6 monero-gui-source-v0.18.3.4.tar.bz2
#
#
# ~binaryFate
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEgaxZH+nEtlxYBq/D8K9NRioL35IFAmbF8bAACgkQ8K9NRioL
35KQAQ/7BP9j0Tx+zlFs3zbVIFXzfoPbGo2/uerM4xUWX/NUoI7XDTGWV2lpcR1x
o6eqstbuHciY0Aj2MsICsdqD+1PYW0EBZlfNLMrk161c3nQMJcjCE65uIhbLkOSs
6SUakmpxkueQOE/Ug5Afaa/JBATVTxLTmqSCI7Ai9NplF+6KNauXQXNrlwO/gHcd
whYDmsqp2JyOtMpMlpOckzLgg7Oroj7B0LBf78Z13p1naUyPooBaIEXSdKm5g2HI
vPd+z1bOVIluqPBnYWUwL7EmXy08/broejHGliQ+2iY9IsmDDx6rnSe/oprNEDic
l+/w3KvPcTkBh8hJLVDyYieYdVYHqOktIPlR1dKV512CnuP1ljr/CXjJmkAkXHlg
bObMUCIM9UYqp1I+KDaArjYNbzkHK02Lu6sak49GXgEuq66m9t4isF2GdcHrbERs
cLGsnhkTO2LtnGcziOC2l9XSzL41swxe0GrkK0rdeiyDCGAlb7hllevFy7zlT90l
Jw670TyFVBs8fUFHk/tOtT0ivSDJJg8m9waBzi/46ksOvuid6p3P3a0agqu3uclj
rscSpk0JS3E/3+A/N0IaiTmUO5zSjbsCrSnxQjcfrRRtERL+6JVHFVlW+nJzYWWH
u0O7bNZSqEruR4aTEtsddLgs57I10thDR5SUONuAqbEq8EYN8OE=
=aLFR
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,50 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
# This GPG-signed message exists to confirm the SHA256 sums of Monero binaries.
#
# Please verify the signature against the key for binaryFate in the
# source code repository (/utils/gpg_keys).
#
#
## CLI
6122f0bcaca12d5badd92002338847d16032f6d52d86155c203bcb67d4fe1518 monero-android-armv7-v0.18.4.2.tar.bz2
3b248c3201f028205915403b4b2f173df0dd8bf47eeb268fd67a4661251469d3 monero-android-armv8-v0.18.4.2.tar.bz2
b4e2b7de80107a1b4613b878d8e2114244b3fb16397821d69baa72d9b0f8c8d5 monero-freebsd-x64-v0.18.4.2.tar.bz2
ecb2577499a3b0901d731e11d462d3fadcd70095f3ab0def0c27ee64dc56b061 monero-linux-armv7-v0.18.4.2.tar.bz2
a39530054dac348b219f1048a24ca629da26990f72cf9c1f6b6853e3d8c39a79 monero-linux-armv8-v0.18.4.2.tar.bz2
18492ace80bf8ef2f44aa9a99b4f20adf00fd59c675a6a496211a720088d5d1a monero-linux-riscv64-v0.18.4.2.tar.bz2
41d023f2357244ea43ee0a74796f5705ce75ce7373a5865d4959fefa13ecab06 monero-linux-x64-v0.18.4.2.tar.bz2
03e77a4836861a47430664fa703dd149a355b3b214bc400b04ed38eb064a3ef0 monero-linux-x86-v0.18.4.2.tar.bz2
9b98da6911b4769abef229c20e21f29d919b11db156965d6f139d2e1ad6625c2 monero-mac-armv8-v0.18.4.2.tar.bz2
b1b1b580320118d3b6eaa5575fdbd73cf4db90fcc025b7abf875c5e5b4e335c1 monero-mac-x64-v0.18.4.2.tar.bz2
14dd5aa11308f106183dd7834aa200e74ce6f3497103973696b556e893a4fef2 monero-win-x64-v0.18.4.2.zip
934d9dbeb06ff5610d2c96ebe34fa480e74f78eaeb3fa3e47d89b7961c9bc5e0 monero-win-x86-v0.18.4.2.zip
e9ec2062b3547db58f00102e6905621116ab7f56a331e0bc9b9e892607b87d24 monero-source-v0.18.4.2.tar.bz2
#
## GUI
9d6e87add7e3ac006ee34c13c4f629252595395f54421db768f72dc233e94ea8 monero-gui-install-win-x64-v0.18.4.2.exe
e4fcdea3f0ff27c3616a8a75545f42a4e4866ea374fa2eeaa9c87027573358ea monero-gui-linux-x64-v0.18.4.2.tar.bz2
3dfee5c5d8e000c72eb3755bf0eb03ca7c5928b69c3a241e147ad22d144e00a7 monero-gui-mac-armv8-v0.18.4.2.dmg
16abadcbd608d4f7ba20d17a297f2aa2c9066d33f6f22bf3fcdca679ab603990 monero-gui-mac-x64-v0.18.4.2.dmg
4daff8850280173d46464ba9a9de7f712228ad1ef76a1c4954531e4fd2b86d86 monero-gui-win-x64-v0.18.4.2.zip
691085e61ece6c56738431f3cfd395536ca0675214e5991e0dbfab85025e82d7 monero-gui-source-v0.18.4.2.tar.bz2
#
#
# ~binaryFate
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEgaxZH+nEtlxYBq/D8K9NRioL35IFAmitx+kACgkQ8K9NRioL
35J6cQ/7ByvGstg/a5lIYbB+Lz5bNiPozCILD9/offvC7GgOvna9rkHuofuLS+pX
qhYEMrjFjmp03XMY+i68M83qkBEZ+yU5iNDbwRuHUNMMWaaGlhnhm3nyUVtDpjjr
4xwVsee+dzi0JZhVQG7HJFURiP2Ub5Ua6bSaATDoT/aUYdhmrOnQiH2+VxogiCv3
JStDqXq6LpFjzw7UkAfxxu1PW+AQFNBzi3L0qWfzb5WWL7xuK63wXGmEkYBlvult
qt3LUhDUzMrfZ5GiiOYDEw44Y2atD4ibOYtBnllCX9CKNb0o2KKU6Qkj+CYqqtnE
uGNOt1oT09VPOtE7OUkBLVkALjef7ZXRibE7tN4wSnsrG39DP795/52L6CGJbl4n
UDnHzLCUbuvhnoAu5U+rUP5nUEDYS9ANNyj610ogNCo7YjfzLH641WSQ/UnuXKkA
RmK8xIiKoOnUeOanX99zqeXqV7gQdQMlfwLUr3pQzCI2YjdvxdRoedSEi5nX5KvO
Snf3BcCYMBemGYqVMdo95tc0Gmsw12/O8WwrBbTea+PeAXJuLaBxrLNn+RNZLfF/
UJYq2VcEwxG6vXb3cJ5lDKmRDDRI8Fxu6Amdab+6ponhM8Zy3eAynVIO952pLA7N
dtl72RsimM+sgHXP4ERYL4c6WARSHE5sAiog43dr56l3PPmM8pE=
=SoHG
-----END PGP SIGNATURE-----

View File

@@ -149,7 +149,7 @@ fn build_serai_service(prelude: &str, release: bool, features: &str, package: &s
format!(
r#"
FROM rust:1.89-slim-bookworm AS builder
FROM rust:1.90-slim-bookworm AS builder
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload

View File

@@ -10,7 +10,7 @@ fn monero_internal(
monero_binary: &str,
ports: &str,
) {
const MONERO_VERSION: &str = "0.18.3.4";
const MONERO_VERSION: &str = "0.18.4.2";
let arch = match std::env::consts::ARCH {
// We probably would run this without issues yet it's not worth needing to provide support for

View File

@@ -1,50 +0,0 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
# This GPG-signed message exists to confirm the SHA256 sums of Monero binaries.
#
# Please verify the signature against the key for binaryFate in the
# source code repository (/utils/gpg_keys).
#
#
## CLI
15e4d7dfc2f9261a0a452b0f8fd157c33cdbc8a896e23d883ddd13e2480a3800 monero-android-armv7-v0.18.3.4.tar.bz2
d9c9249d1408822ce36b346c6b9fb6b896cda16714d62117fb1c588a5201763c monero-android-armv8-v0.18.3.4.tar.bz2
360a551388922c8991a9ba4abaa88676b0fc7ec1fa4d0f4b5c0500847e0b946c monero-freebsd-x64-v0.18.3.4.tar.bz2
354603c56446fb0551cdd6933bce5a13590b7881e05979b7ec25d89e7e59a0e2 monero-linux-armv7-v0.18.3.4.tar.bz2
33ca2f0055529d225b61314c56370e35606b40edad61c91c859f873ed67a1ea7 monero-linux-armv8-v0.18.3.4.tar.bz2
88739a1521b9fda3154540268e416c7af016ed7857041c76ab8ed7d7674c71ca monero-linux-riscv64-v0.18.3.4.tar.bz2
51ba03928d189c1c11b5379cab17dd9ae8d2230056dc05c872d0f8dba4a87f1d monero-linux-x64-v0.18.3.4.tar.bz2
d7ca0878abff2919a0104d7ed29d9c35df9ca0ea1b6fb4ebf6c8f7607ffb9e41 monero-linux-x86-v0.18.3.4.tar.bz2
44520cb3a05c2518ca9aeae1b2e3080fe2bba1e3596d014ceff1090dfcba8ab4 monero-mac-armv8-v0.18.3.4.tar.bz2
32c449f562216d3d83154e708471236d07db7477d6b67f1936a0a85a5005f2b8 monero-mac-x64-v0.18.3.4.tar.bz2
54a66db6c892b2a0999754841f4ca68511741b88ea3ab20c7cd504a027f465f5 monero-win-x64-v0.18.3.4.zip
1a9824742aa1587023c3bddea788c115940cfd49371c78a8dd62c40113132d01 monero-win-x86-v0.18.3.4.zip
7d4845ec0a3b52404d41785da348ec33509f0a5981e8a27c5fa55b18d696e139 monero-source-v0.18.3.4.tar.bz2
#
## GUI
63349d5a7637cd0c5d1693a1a2e910a92cbb123903d57667077a36454845d7bf monero-gui-install-win-x64-v0.18.3.4.exe
2866f3a2be30e4c4113e6274cad1d6698f81c37ceebc6e8f084c57230a0f70a6 monero-gui-linux-x64-v0.18.3.4.tar.bz2
eedbf827513607a3ef579077dacd573e65892b199102effef97dff9d73138ca6 monero-gui-mac-armv8-v0.18.3.4.dmg
54eb151d7511a9f26130864e2c02f258344803b2b68311c8be29850d7faef359 monero-gui-mac-x64-v0.18.3.4.dmg
b5d42dddd722e728e480337f89038c8ea606c6507bf0c88ddf2af25050c9b751 monero-gui-win-x64-v0.18.3.4.zip
2f1d643bb2cc08e5eb334a6bfd649b0aa95ceb6178ff2f90448d5ef8d2a752a6 monero-gui-source-v0.18.3.4.tar.bz2
#
#
# ~binaryFate
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEgaxZH+nEtlxYBq/D8K9NRioL35IFAmbF8bAACgkQ8K9NRioL
35KQAQ/7BP9j0Tx+zlFs3zbVIFXzfoPbGo2/uerM4xUWX/NUoI7XDTGWV2lpcR1x
o6eqstbuHciY0Aj2MsICsdqD+1PYW0EBZlfNLMrk161c3nQMJcjCE65uIhbLkOSs
6SUakmpxkueQOE/Ug5Afaa/JBATVTxLTmqSCI7Ai9NplF+6KNauXQXNrlwO/gHcd
whYDmsqp2JyOtMpMlpOckzLgg7Oroj7B0LBf78Z13p1naUyPooBaIEXSdKm5g2HI
vPd+z1bOVIluqPBnYWUwL7EmXy08/broejHGliQ+2iY9IsmDDx6rnSe/oprNEDic
l+/w3KvPcTkBh8hJLVDyYieYdVYHqOktIPlR1dKV512CnuP1ljr/CXjJmkAkXHlg
bObMUCIM9UYqp1I+KDaArjYNbzkHK02Lu6sak49GXgEuq66m9t4isF2GdcHrbERs
cLGsnhkTO2LtnGcziOC2l9XSzL41swxe0GrkK0rdeiyDCGAlb7hllevFy7zlT90l
Jw670TyFVBs8fUFHk/tOtT0ivSDJJg8m9waBzi/46ksOvuid6p3P3a0agqu3uclj
rscSpk0JS3E/3+A/N0IaiTmUO5zSjbsCrSnxQjcfrRRtERL+6JVHFVlW+nJzYWWH
u0O7bNZSqEruR4aTEtsddLgs57I10thDR5SUONuAqbEq8EYN8OE=
=aLFR
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,50 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
# This GPG-signed message exists to confirm the SHA256 sums of Monero binaries.
#
# Please verify the signature against the key for binaryFate in the
# source code repository (/utils/gpg_keys).
#
#
## CLI
6122f0bcaca12d5badd92002338847d16032f6d52d86155c203bcb67d4fe1518 monero-android-armv7-v0.18.4.2.tar.bz2
3b248c3201f028205915403b4b2f173df0dd8bf47eeb268fd67a4661251469d3 monero-android-armv8-v0.18.4.2.tar.bz2
b4e2b7de80107a1b4613b878d8e2114244b3fb16397821d69baa72d9b0f8c8d5 monero-freebsd-x64-v0.18.4.2.tar.bz2
ecb2577499a3b0901d731e11d462d3fadcd70095f3ab0def0c27ee64dc56b061 monero-linux-armv7-v0.18.4.2.tar.bz2
a39530054dac348b219f1048a24ca629da26990f72cf9c1f6b6853e3d8c39a79 monero-linux-armv8-v0.18.4.2.tar.bz2
18492ace80bf8ef2f44aa9a99b4f20adf00fd59c675a6a496211a720088d5d1a monero-linux-riscv64-v0.18.4.2.tar.bz2
41d023f2357244ea43ee0a74796f5705ce75ce7373a5865d4959fefa13ecab06 monero-linux-x64-v0.18.4.2.tar.bz2
03e77a4836861a47430664fa703dd149a355b3b214bc400b04ed38eb064a3ef0 monero-linux-x86-v0.18.4.2.tar.bz2
9b98da6911b4769abef229c20e21f29d919b11db156965d6f139d2e1ad6625c2 monero-mac-armv8-v0.18.4.2.tar.bz2
b1b1b580320118d3b6eaa5575fdbd73cf4db90fcc025b7abf875c5e5b4e335c1 monero-mac-x64-v0.18.4.2.tar.bz2
14dd5aa11308f106183dd7834aa200e74ce6f3497103973696b556e893a4fef2 monero-win-x64-v0.18.4.2.zip
934d9dbeb06ff5610d2c96ebe34fa480e74f78eaeb3fa3e47d89b7961c9bc5e0 monero-win-x86-v0.18.4.2.zip
e9ec2062b3547db58f00102e6905621116ab7f56a331e0bc9b9e892607b87d24 monero-source-v0.18.4.2.tar.bz2
#
## GUI
9d6e87add7e3ac006ee34c13c4f629252595395f54421db768f72dc233e94ea8 monero-gui-install-win-x64-v0.18.4.2.exe
e4fcdea3f0ff27c3616a8a75545f42a4e4866ea374fa2eeaa9c87027573358ea monero-gui-linux-x64-v0.18.4.2.tar.bz2
3dfee5c5d8e000c72eb3755bf0eb03ca7c5928b69c3a241e147ad22d144e00a7 monero-gui-mac-armv8-v0.18.4.2.dmg
16abadcbd608d4f7ba20d17a297f2aa2c9066d33f6f22bf3fcdca679ab603990 monero-gui-mac-x64-v0.18.4.2.dmg
4daff8850280173d46464ba9a9de7f712228ad1ef76a1c4954531e4fd2b86d86 monero-gui-win-x64-v0.18.4.2.zip
691085e61ece6c56738431f3cfd395536ca0675214e5991e0dbfab85025e82d7 monero-gui-source-v0.18.4.2.tar.bz2
#
#
# ~binaryFate
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEgaxZH+nEtlxYBq/D8K9NRioL35IFAmitx+kACgkQ8K9NRioL
35J6cQ/7ByvGstg/a5lIYbB+Lz5bNiPozCILD9/offvC7GgOvna9rkHuofuLS+pX
qhYEMrjFjmp03XMY+i68M83qkBEZ+yU5iNDbwRuHUNMMWaaGlhnhm3nyUVtDpjjr
4xwVsee+dzi0JZhVQG7HJFURiP2Ub5Ua6bSaATDoT/aUYdhmrOnQiH2+VxogiCv3
JStDqXq6LpFjzw7UkAfxxu1PW+AQFNBzi3L0qWfzb5WWL7xuK63wXGmEkYBlvult
qt3LUhDUzMrfZ5GiiOYDEw44Y2atD4ibOYtBnllCX9CKNb0o2KKU6Qkj+CYqqtnE
uGNOt1oT09VPOtE7OUkBLVkALjef7ZXRibE7tN4wSnsrG39DP795/52L6CGJbl4n
UDnHzLCUbuvhnoAu5U+rUP5nUEDYS9ANNyj610ogNCo7YjfzLH641WSQ/UnuXKkA
RmK8xIiKoOnUeOanX99zqeXqV7gQdQMlfwLUr3pQzCI2YjdvxdRoedSEi5nX5KvO
Snf3BcCYMBemGYqVMdo95tc0Gmsw12/O8WwrBbTea+PeAXJuLaBxrLNn+RNZLfF/
UJYq2VcEwxG6vXb3cJ5lDKmRDDRI8Fxu6Amdab+6ponhM8Zy3eAynVIO952pLA7N
dtl72RsimM+sgHXP4ERYL4c6WARSHE5sAiog43dr56l3PPmM8pE=
=SoHG
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,23 @@
[package]
name = "simple-request"
version = "0.1.99"
description = "simple-request which patches to the latest update"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/simple-request"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = ["nostd", "no_std", "alloc", "io"]
edition = "2021"
rust-version = "1.65"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
simple-request = { path = "../../common/request" }
[features]
tls = ["simple-request/tls"]

View File

@@ -0,0 +1,18 @@
pub use simple_request::{hyper, Error, Request, Response};
#[derive(Clone, Debug)]
pub struct Client(simple_request::Client);
impl Client {
pub fn with_connection_pool() -> Client {
Self(simple_request::Client::with_connection_pool().unwrap())
}
pub fn without_connection_pool(host: &str) -> Result<Client, Error> {
simple_request::Client::without_connection_pool(host).map(Self)
}
pub async fn request<R: Into<Request>>(&self, request: R) -> Result<Response<'_>, Error> {
self.0.request(request).await
}
}

View File

@@ -0,0 +1,23 @@
[package]
name = "std-shims"
version = "0.1.99"
description = "std-shims which patches to the latest update"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/std-shims"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = ["nostd", "no_std", "alloc", "io"]
edition = "2021"
rust-version = "1.65"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
std-shims = { path = "../../common/std-shims", default-features = false, features = ["alloc"] }
[features]
std = ["std-shims/std"]

View File

@@ -0,0 +1,5 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
pub extern crate alloc;
pub use std_shims::{str, vec, string, collections, io, sync, prelude};

View File

@@ -21,7 +21,7 @@ async fn test_deployer() {
let anvil = Anvil::new().arg("--hardfork").arg(network).spawn();
let provider = Arc::new(RootProvider::new(
ClientBuilder::default().transport(SimpleRequest::new(anvil.endpoint()), true),
ClientBuilder::default().transport(SimpleRequest::new(anvil.endpoint()).unwrap(), true),
));
// Deploy the Deployer

View File

@@ -129,7 +129,7 @@ impl Test {
.spawn();
let provider = Arc::new(RootProvider::new(
ClientBuilder::default().transport(SimpleRequest::new(anvil.endpoint()), true),
ClientBuilder::default().transport(SimpleRequest::new(anvil.endpoint()).unwrap(), true),
));
let chain_id = U256::from(provider.get_chain_id().await.unwrap());

View File

@@ -61,7 +61,7 @@ async fn main() {
let db = bin::init();
let provider = Arc::new(RootProvider::new(
ClientBuilder::default().transport(SimpleRequest::new(bin::url()), true),
ClientBuilder::default().transport(SimpleRequest::new(bin::url()).unwrap(), true),
));
let chain_id = {

View File

@@ -29,8 +29,8 @@ dalek-ff-group = { path = "../../crypto/dalek-ff-group", default-features = fals
dkg = { package = "dkg-evrf", path = "../../crypto/dkg/evrf", default-features = false, features = ["std", "ed25519"] }
frost = { package = "modular-frost", path = "../../crypto/frost", default-features = false }
monero-wallet = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7f37cc8f770858aa1739e0f56dbe447db86f4ba6", default-features = false, features = ["std", "multisig"] }
monero-simple-request-rpc = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7f37cc8f770858aa1739e0f56dbe447db86f4ba6", default-features = false }
monero-wallet = { git = "https://github.com/monero-oxide/monero-oxide", rev = "f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c", default-features = false, features = ["std", "multisig"] }
monero-simple-request-rpc = { git = "https://github.com/monero-oxide/monero-oxide", rev = "f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c", default-features = false }
serai-client = { path = "../../substrate/client", default-features = false, features = ["monero"] }

View File

@@ -6,7 +6,7 @@
static ALLOCATOR: zalloc::ZeroizingAlloc<std::alloc::System> =
zalloc::ZeroizingAlloc(std::alloc::System);
use monero_simple_request_rpc::SimpleRequestRpc;
use monero_simple_request_rpc::SimpleRequestTransport;
mod primitives;
pub(crate) use crate::primitives::*;
@@ -23,7 +23,7 @@ async fn main() {
let db = bin::init();
let feed = Rpc {
rpc: loop {
match SimpleRequestRpc::new(bin::url()).await {
match SimpleRequestTransport::new(bin::url()).await {
Ok(rpc) => break rpc,
Err(e) => {
log::error!("couldn't connect to the Monero node: {e:?}");

View File

@@ -4,7 +4,8 @@ use ciphersuite::*;
use dalek_ff_group::Ed25519;
use monero_wallet::{
block::Block as MBlock, rpc::ScannableBlock as MScannableBlock, ScanError, GuaranteedScanner,
block::Block as MBlock, interface::ScannableBlock as MScannableBlock, ScanError,
GuaranteedScanner,
};
use serai_client::networks::monero::Address;

View File

@@ -1,7 +1,6 @@
use core::future::Future;
use monero_wallet::rpc::{RpcError, Rpc as RpcTrait};
use monero_simple_request_rpc::SimpleRequestRpc;
use monero_simple_request_rpc::{prelude::*, SimpleRequestTransport};
use serai_client::primitives::{ExternalNetworkId, ExternalCoin, Amount};
@@ -15,7 +14,7 @@ use crate::{
#[derive(Clone)]
pub(crate) struct Rpc {
pub(crate) rpc: SimpleRequestRpc,
pub(crate) rpc: MoneroDaemon<SimpleRequestTransport>,
}
impl ScannerFeed for Rpc {
@@ -31,21 +30,16 @@ impl ScannerFeed for Rpc {
type Block = Block;
type EphemeralError = RpcError;
type EphemeralError = InterfaceError;
fn latest_finalized_block_number(
&self,
) -> impl Send + Future<Output = Result<u64, Self::EphemeralError>> {
async move {
Ok(
self
.rpc
.get_height()
.await?
.checked_sub(1)
.expect("connected to an invalid Monero RPC")
.try_into()
.unwrap(),
u64::try_from(self.rpc.latest_block_number().await?)
.unwrap()
.saturating_sub(Self::CONFIRMATIONS - 1),
)
}
}
@@ -64,11 +58,11 @@ impl ScannerFeed for Rpc {
}
// Fetch all the timestamps within the window
let block_for_time_of = self.rpc.get_block_by_number(number.try_into().unwrap()).await?;
let block_for_time_of = self.rpc.block_by_number(number.try_into().unwrap()).await?;
let mut timestamps = vec![block_for_time_of.header.timestamp];
let mut parent = block_for_time_of.header.previous;
for _ in 1 .. BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW {
let parent_block = self.rpc.get_block(parent).await?;
let parent_block = self.rpc.block(parent).await?;
timestamps.push(parent_block.header.timestamp);
parent = parent_block.header.previous;
}
@@ -94,7 +88,7 @@ impl ScannerFeed for Rpc {
) -> impl Send
+ Future<Output = Result<<Self::Block as primitives::Block>::Header, Self::EphemeralError>>
{
async move { Ok(BlockHeader(self.rpc.get_block_by_number(number.try_into().unwrap()).await?)) }
async move { Ok(BlockHeader(self.rpc.block_by_number(number.try_into().unwrap()).await?)) }
}
#[rustfmt::skip] // It wants to improperly format the `async move` to a single line
@@ -103,7 +97,7 @@ impl ScannerFeed for Rpc {
number: u64,
) -> impl Send + Future<Output = Result<Self::Block, Self::EphemeralError>> {
async move {
Ok(Block(self.rpc.get_scannable_block_by_number(number.try_into().unwrap()).await?))
Ok(Block(self.rpc.scannable_block_by_number(number.try_into().unwrap()).await?))
}
}
@@ -128,7 +122,7 @@ impl ScannerFeed for Rpc {
}
impl TransactionPublisher<Transaction> for Rpc {
type EphemeralError = RpcError;
type EphemeralError = PublishTransactionError;
fn publish(
&self,

View File

@@ -7,7 +7,7 @@ use rand_chacha::ChaCha20Rng;
use ciphersuite::*;
use dalek_ff_group::Ed25519;
use monero_wallet::rpc::{FeeRate, RpcError};
use monero_wallet::interface::prelude::*;
use serai_client::{
primitives::{ExternalCoin, Amount},
@@ -55,7 +55,7 @@ async fn signable_transaction(
inputs: Vec<OutputFor<Rpc>>,
payments: Vec<Payment<AddressFor<Rpc>>>,
change: Option<KeyFor<Rpc>>,
) -> Result<Result<(SignableTransaction, MSignableTransaction), SendError>, RpcError> {
) -> Result<Result<(SignableTransaction, MSignableTransaction), SendError>, TransactionsError> {
assert!(inputs.len() < <Planner as TransactionPlanner<Rpc, ()>>::MAX_INPUTS);
assert!(
(payments.len() + usize::from(u8::from(change.is_some()))) <
@@ -148,7 +148,7 @@ async fn signable_transaction(
#[derive(Clone)]
pub(crate) struct Planner(pub(crate) Rpc);
impl TransactionPlanner<Rpc, ()> for Planner {
type EphemeralError = RpcError;
type EphemeralError = TransactionsError;
type SignableTransaction = SignableTransaction;
@@ -221,8 +221,9 @@ impl TransactionPlanner<Rpc, ()> for Planner {
payments: Vec<Payment<AddressFor<Rpc>>>,
change: Option<KeyFor<Rpc>>,
) -> impl Send
+ Future<Output = Result<PlannedTransaction<Rpc, Self::SignableTransaction, ()>, RpcError>>
{
+ Future<
Output = Result<PlannedTransaction<Rpc, Self::SignableTransaction, ()>, TransactionsError>,
> {
let singular_spent_output = (inputs.len() == 1).then(|| inputs[0].id());
async move {

View File

@@ -1,5 +1,5 @@
[toolchain]
channel = "1.89"
channel = "1.90"
targets = ["wasm32v1-none"]
profile = "minimal"
components = ["rust-src", "rustfmt", "clippy"]

View File

@@ -37,13 +37,13 @@ frame-system = { git = "https://github.com/serai-dex/substrate", optional = true
async-lock = "3"
simple-request = { path = "../../common/request", version = "0.1", optional = true }
simple-request = { path = "../../common/request", version = "0.2", optional = true }
bitcoin = { version = "0.32", optional = true }
ciphersuite = { path = "../../crypto/ciphersuite", optional = true }
dalek-ff-group = { path = "../../crypto/dalek-ff-group", optional = true }
monero-address = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7f37cc8f770858aa1739e0f56dbe447db86f4ba6", version = "0.1.0", default-features = false, features = ["std"], optional = true }
monero-address = { git = "https://github.com/monero-oxide/monero-oxide", rev = "f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c", version = "0.1.0", default-features = false, features = ["std"], optional = true }
[dev-dependencies]
rand_core = "0.6"

View File

@@ -158,7 +158,7 @@ impl Serai {
}
pub async fn new(url: String) -> Result<Self, SeraiError> {
let client = Client::with_connection_pool();
let client = Client::with_connection_pool().map_err(|_| SeraiError::ConnectionError)?;
let mut res = Serai { url, client, genesis: [0xfe; 32] };
res.genesis = res.block_hash(0).await?.ok_or_else(|| {
SeraiError::InvalidNode("node didn't have the first block's hash".to_string())

View File

@@ -82,7 +82,7 @@ serai-env = { path = "../../common/env" }
curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "zeroize"] }
bitcoin-serai = { path = "../../networks/bitcoin", default-features = false, features = ["std", "hazmat"] }
monero-address = { git = "https://github.com/monero-oxide/monero-oxide", rev = "7f37cc8f770858aa1739e0f56dbe447db86f4ba6", default-features = false, features = ["std"] }
monero-address = { git = "https://github.com/monero-oxide/monero-oxide", rev = "f6f4dd7dc5b7c6e057b2eac2ec4980bb7a1c707c", default-features = false, features = ["std"] }
[build-dependencies]
substrate-build-script-utils = { git = "https://github.com/serai-dex/substrate" }

View File

@@ -17,16 +17,18 @@ rustdoc-args = ["--cfg", "docsrs"]
workspace = true
[dependencies]
std-shims = { path = "../../common/std-shims", default-features = false }
flexible-transcript = { path = "../../crypto/transcript", default-features = false, features = ["recommended", "merlin"] }
multiexp = { path = "../../crypto/multiexp", default-features = false, features = ["batch"], optional = true }
multiexp = { path = "../../crypto/multiexp", default-features = false }
dalek-ff-group = { path = "../../crypto/dalek-ff-group", default-features = false }
minimal-ed448 = { path = "../../crypto/ed448", default-features = false }
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false }
schnorr-signatures = { path = "../../crypto/schnorr", default-features = false, optional = true }
schnorr-signatures = { path = "../../crypto/schnorr", default-features = false }
prime-field = { path = "../../crypto/prime-field", default-features = false }
short-weierstrass = { path = "../../crypto/short-weierstrass", default-features = false }
@@ -34,22 +36,29 @@ secq256k1 = { path = "../../crypto/secq256k1", default-features = false }
embedwards25519 = { path = "../../crypto/embedwards25519", default-features = false }
dkg = { path = "../../crypto/dkg", default-features = false, optional = true }
dkg-dealer = { path = "../../crypto/dkg/dealer", default-features = false, optional = true }
dkg-recovery = { path = "../../crypto/dkg/recovery", default-features = false, optional = true }
dkg-musig = { path = "../../crypto/dkg/musig", default-features = false, optional = true }
dkg-evrf = { path = "../../crypto/dkg/evrf", default-features = false, features = ["secp256k1", "ed25519"], optional = true }
# modular-frost = { path = "../../crypto/frost", default-features = false }
# frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false }
modular-frost = { path = "../../crypto/frost", default-features = false, optional = true }
frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false, optional = true }
bitcoin-serai = { path = "../../networks/bitcoin", default-features = false, features = ["hazmat"], optional = true }
[features]
alloc = [
"multiexp",
"std-shims/alloc",
"multiexp/alloc",
"multiexp/batch",
"dalek-ff-group/alloc",
"minimal-ed448/alloc",
"ciphersuite/alloc",
"schnorr-signatures",
"schnorr-signatures/alloc",
"prime-field/alloc",
"short-weierstrass/alloc",
@@ -57,7 +66,13 @@ alloc = [
"embedwards25519/alloc",
"dkg",
"dkg-dealer",
"dkg-recovery",
"dkg-musig",
"dkg-evrf",
"modular-frost",
"frost-schnorrkel",
"bitcoin-serai",
]

View File

@@ -1,5 +1,7 @@
#![no_std]
pub use std_shims;
pub use flexible_transcript;
pub use dalek_ff_group;
@@ -11,18 +13,21 @@ pub use prime_field;
pub use short_weierstrass;
pub use secq256k1;
pub use embedwards25519;
/*
pub use modular_frost;
pub use frost_schnorrkel;
*/
pub use schnorr_signatures;
#[cfg(feature = "alloc")]
pub mod alloc {
pub use multiexp;
pub use schnorr_signatures;
pub use dkg;
pub use dkg_dealer;
pub use dkg_recovery;
pub use dkg_musig;
pub use dkg_evrf;
pub use modular_frost;
pub use frost_schnorrkel;
pub use bitcoin_serai;
}

View File

@@ -277,7 +277,7 @@ impl Coordinator {
};
let provider = Arc::new(RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
));
if handle
@@ -417,7 +417,7 @@ impl Coordinator {
};
let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
);
let start = provider
.get_block(BlockNumberOrTag::Latest.into(), BlockTransactionsKind::Hashes)
@@ -509,7 +509,7 @@ impl Coordinator {
let (expected_number, state) = {
let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
);
let expected_number = provider
@@ -528,7 +528,7 @@ impl Coordinator {
for coordinator in others {
let rpc_url = network_rpc(coordinator.network, ops, &coordinator.network_handle);
let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
);
assert!(provider
.raw_request::<_, bool>("anvil_loadState".into(), &[&state])
@@ -605,7 +605,7 @@ impl Coordinator {
};
let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
);
let _ = provider.send_raw_transaction(tx).await.unwrap();
}
@@ -662,7 +662,7 @@ impl Coordinator {
ExternalNetworkId::Ethereum => {
/*
let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
);
let mut hash = [0; 32];
hash.copy_from_slice(tx);

View File

@@ -165,7 +165,7 @@ impl Wallet {
ethereum_serai::crypto::address(&(<Secp256k1 as WrappedGroup>::generator() * key));
let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
);
provider
@@ -319,7 +319,7 @@ impl Wallet {
let one_eth = eighteen_decimals;
let provider = Arc::new(RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()).unwrap(), true),
));
let to_as_key = PublicKey::new(