diff --git a/CHANGELOG.md b/CHANGELOG.md
index a5fa9db3c5..b0cfa4f8f3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,13 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Added
-
- [#670](https://github.com/FuelLabs/fuel-vm/pull/670): Add DA compression functionality to `Transaction` and any types within
+- [#733](https://github.com/FuelLabs/fuel-vm/pull/733): Add LibAFL based fuzzer and update `secp256k1` version to 0.29.1.
### Changed
#### Breaking
-
- [#670](https://github.com/FuelLabs/fuel-vm/pull/670): The `predicate` field of `fuel_tx::input::Coin` is now a wrapper struct `PredicateCode`.
## [Version 0.56.0]
diff --git a/README.md b/README.md
index 9c77b1bf19..81e0693a4b 100644
--- a/README.md
+++ b/README.md
@@ -88,4 +88,4 @@ It returns `receipts` that contain result of execution. The `assert_panics` can
The `fuel-tx` provides `fuel_tx::TransactionBuilder` that simplifies the building
of custom transaction for testing purposes.
-You can check how `TransactionBuilder::script` or `TransactionBuilder::create` are used for better understanding.
\ No newline at end of file
+You can check how `TransactionBuilder::script` or `TransactionBuilder::create` are used for better understanding.
diff --git a/fuel-asm/Cargo.toml b/fuel-asm/Cargo.toml
index d1fcc9fb72..4b67bd9620 100644
--- a/fuel-asm/Cargo.toml
+++ b/fuel-asm/Cargo.toml
@@ -11,7 +11,6 @@ repository = { workspace = true }
description = "Atomic types of the FuelVM."
[dependencies]
-arbitrary = { version = "1.1", features = ["derive"], optional = true }
bitflags = { workspace = true }
fuel-types = { workspace = true, default-features = false }
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
diff --git a/fuel-asm/src/args.rs b/fuel-asm/src/args.rs
index 45c216e2a6..1998bfd7dd 100644
--- a/fuel-asm/src/args.rs
+++ b/fuel-asm/src/args.rs
@@ -11,7 +11,6 @@ crate::enum_try_from! {
#[cfg_attr(feature = "typescript", wasm_bindgen::prelude::wasm_bindgen)]
#[repr(u8)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
- #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
/// Argument list for GM (get metadata) instruction
/// The VM is the only who should match this struct, and it *MUST* always perform
/// exhaustive match so all offered variants are covered.
@@ -51,7 +50,6 @@ crate::enum_try_from! {
#[cfg_attr(feature = "typescript", wasm_bindgen::prelude::wasm_bindgen)]
#[repr(u16)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
- #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum GTFArgs {
/// Set `$rA` to `tx.type`
Type = 0x001,
diff --git a/fuel-asm/src/panic_instruction.rs b/fuel-asm/src/panic_instruction.rs
index 917661aeea..6c9ebc163c 100644
--- a/fuel-asm/src/panic_instruction.rs
+++ b/fuel-asm/src/panic_instruction.rs
@@ -11,7 +11,6 @@ use crate::{
#[cfg_attr(feature = "typescript", wasm_bindgen::prelude::wasm_bindgen)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(fuel_types::canonical::Deserialize, fuel_types::canonical::Serialize)]
-#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
/// Describe a panic reason with the instruction that generated it
pub struct PanicInstruction {
reason: PanicReason,
diff --git a/fuel-asm/src/panic_reason.rs b/fuel-asm/src/panic_reason.rs
index ff57240a22..7dae75e6ca 100644
--- a/fuel-asm/src/panic_reason.rs
+++ b/fuel-asm/src/panic_reason.rs
@@ -27,7 +27,6 @@ enum_from! {
#[cfg_attr(feature = "typescript", wasm_bindgen::prelude::wasm_bindgen)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(fuel_types::canonical::Serialize, fuel_types::canonical::Deserialize)]
- #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[repr(u8)]
#[non_exhaustive]
/// Panic reason representation for the interpreter.
diff --git a/fuel-crypto/Cargo.toml b/fuel-crypto/Cargo.toml
index 67f4b7a7cf..8b7b2e4afa 100644
--- a/fuel-crypto/Cargo.toml
+++ b/fuel-crypto/Cargo.toml
@@ -22,7 +22,7 @@ p256 = { version = "0.13", default-features = false, features = ["digest", "ecd
rand = { version = "0.8", default-features = false, optional = true }
# `rand-std` is used to further protect the blinders from side-channel attacks and won't compromise
# the deterministic arguments of the signature (key, nonce, message), as defined in the RFC-6979
-secp256k1 = { version = "0.26", default-features = false, features = ["rand-std", "recovery"], optional = true }
+secp256k1 = { version = "0.29.1", default-features = false, features = ["rand-std", "recovery"], optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
sha2 = { version = "0.10", default-features = false }
zeroize = { version = "1.5", features = ["derive"] }
@@ -41,6 +41,9 @@ serde = ["dep:serde", "fuel-types/serde"]
std = ["alloc", "coins-bip32", "secp256k1", "coins-bip39", "fuel-types/std", "lazy_static", "rand?/std_rng", "serde?/default"]
test-helpers = []
+[lints.rust]
+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
+
[[bench]]
name = "signature"
harness = false
diff --git a/fuel-crypto/benches/signature.rs b/fuel-crypto/benches/signature.rs
index 95a5e2fe14..9c7ab7b7d0 100644
--- a/fuel-crypto/benches/signature.rs
+++ b/fuel-crypto/benches/signature.rs
@@ -70,8 +70,8 @@ fn signatures(c: &mut Criterion) {
let public = PublicKey::from_secret_key(&secp, &key);
let message = fuel_crypto::Message::new(message);
- let message =
- Message::from_slice(message.as_ref()).expect("failed to create secp message");
+ let message = Message::from_digest_slice(message.as_ref())
+ .expect("failed to create secp message");
let signature = secp_signing.sign_ecdsa(&message, &key);
let recoverable = secp.sign_ecdsa_recoverable(&message, &key);
diff --git a/fuel-crypto/src/message.rs b/fuel-crypto/src/message.rs
index 8678e3b804..929ecc03ea 100644
--- a/fuel-crypto/src/message.rs
+++ b/fuel-crypto/src/message.rs
@@ -118,6 +118,6 @@ impl fmt::Display for Message {
#[cfg(feature = "std")]
impl From<&Message> for secp256k1::Message {
fn from(message: &Message) -> Self {
- secp256k1::Message::from_slice(&*message.0).expect("length always matches")
+ secp256k1::Message::from_digest_slice(&*message.0).expect("length always matches")
}
}
diff --git a/fuel-tx/Cargo.toml b/fuel-tx/Cargo.toml
index 8459f76e16..d0e8a1314f 100644
--- a/fuel-tx/Cargo.toml
+++ b/fuel-tx/Cargo.toml
@@ -59,3 +59,6 @@ alloc = ["hashbrown", "fuel-types/alloc", "itertools/use_alloc", "derivative", "
# serde is requiring alloc because its mandatory for serde_json. to avoid adding a new feature only for serde_json, we just require `alloc` here since as of the moment we don't have a use case of serde without alloc.
serde = ["alloc", "fuel-asm/serde", "fuel-crypto/serde", "fuel-merkle/serde", "serde_json", "hashbrown/serde", "bitflags/serde"]
da-compression = ["serde", "fuel-compression"]
+
+[lints.rust]
+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
diff --git a/fuel-vm/Cargo.toml b/fuel-vm/Cargo.toml
index 07155b004a..16ee3e15fd 100644
--- a/fuel-vm/Cargo.toml
+++ b/fuel-vm/Cargo.toml
@@ -85,7 +85,6 @@ std = [
"itertools/use_std",
]
alloc = ["fuel-asm/alloc", "fuel-tx/alloc", "fuel-tx/alloc"]
-arbitrary = ["fuel-asm/arbitrary"]
profile-gas = ["profile-any"]
profile-coverage = ["profile-any"]
profile-any = ["dyn-clone"] # All profiling features should depend on this
@@ -109,3 +108,6 @@ test-helpers = [
"tai64",
"fuel-crypto/test-helpers",
]
+
+[lints.rust]
+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
diff --git a/fuel-vm/fuzz/.cargo/config.toml b/fuel-vm/fuzz/.cargo/config.toml
new file mode 100644
index 0000000000..71d0799c8d
--- /dev/null
+++ b/fuel-vm/fuzz/.cargo/config.toml
@@ -0,0 +1,2 @@
+[build]
+rustflags = "--cfg fuzzing"
diff --git a/fuel-vm/fuzz/Cargo.toml b/fuel-vm/fuzz/Cargo.toml
index 83dca5fc45..29a1cf935b 100644
--- a/fuel-vm/fuzz/Cargo.toml
+++ b/fuel-vm/fuzz/Cargo.toml
@@ -3,22 +3,41 @@ name = "fuel-vm-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
-edition = "2018"
+edition = "2021"
[package.metadata]
cargo-fuzz = true
[dependencies]
-arbitrary = { version = "1.0", features = ["derive"] }
-fuel-vm = { path = "..", features = ["arbitrary"] }
-libfuzzer-sys = "0.4"
+fuel-vm = { path = "..", features = ["test-helpers"] }
+clap = { version = "4.0", features = ["derive"] }
+hex = "*"
+
+[features]
+default = ["libfuzzer"]
+libfuzzer = ["libfuzzer-sys"]
+libafl = ["libafl_libfuzzer"]
+
+[dependencies.libfuzzer-sys]
+version = "0.4"
+optional = true
+
+[dependencies.libafl_libfuzzer]
+version = "0.13"
+optional = true
# Prevent this from interfering with workspaces as this crate requires unstable features.
[workspace]
members = ["."]
+[profile.release]
+panic = 'abort'
+
+[profile.dev]
+panic = 'abort'
+
[[bin]]
-name = "grammar_aware"
-path = "fuzz_targets/grammar_aware.rs"
+name = "grammar_aware_advanced"
+path = "fuzz_targets/grammar_aware_advanced.rs"
test = false
doc = false
diff --git a/fuel-vm/fuzz/README.md b/fuel-vm/fuzz/README.md
new file mode 100644
index 0000000000..b0ffad2bad
--- /dev/null
+++ b/fuel-vm/fuzz/README.md
@@ -0,0 +1,99 @@
+# Fuzz test for the Fuel VM
+This crate provides the `grammar_aware_advanced` fuzz target which can be run with `cargo fuzz` to fuzz test the Fuel VM.
+
+General information about fuzzing Rust can be found on [appsec.guide](https://appsec.guide/docs/fuzzing/rust/cargo-fuzz/).
+
+### Installation
+The fuzzer requires nightly rust and works with rustc version `1.82.0-nightly`. To be able to run the fuzzer, the following tools must be installed.
+
+Install:
+```
+cargo install cargo-fuzz
+apt install clang pkg-config libssl-dev # for LibAFL
+rustup component add llvm-tools-preview --toolchain nightly
+```
+
+### Seeds
+
+The input to the fuzzer is a byte vector that contains script assembly, script data, and the assembly of a contract to be called. Each of these is separated by a 64-bit magic value `0x00ADBEEF5566CEAA`.
+
+While the fuzzer can be started without any seeds, it is recommended to generate seeds from compiled sway programs.
+
+#### Generate your own seeds
+
+If you want to run the fuzzer with custom input, you can run the `seed` binary against a directory of compiled sway programs.
+
+```
+cargo run --bin seed