-
Notifications
You must be signed in to change notification settings - Fork 169
test: Integrate Fuzzing into Jellyfish #784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
I'm highly supportive on this effort. I'd say add fuzzing in CI as well (maybe as a weekly cron job as it runs for a very long time). |
|
okay, i fixed the rayon iterator issue in CI. but wasm32 target build will fail. I feel like including wdyt? |
That's a good idea. We don't mean to export it. Also don't forget to update the nix env |
|
Yeah I think adding as a crate was a "oh my god I will do anything to make this work" type of decision. Let me swap that out and get CI, then @0xkato and I will keep adding tests |
|
CI fixed. @0xkato to take over adding tests, I will circle back |
| if let Ok(input) = ExtensionAttackInput::arbitrary(&mut u) { | ||
| let forged_val = F::from(input.forged_val); | ||
| let attack_pos = input.attack_pos; | ||
| let forged_pos = attack_pos * 3 + 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of using hardcoded value, let's either add explanatory code doc on top of this whole function or name const arity = 3
especially explain the digest_leaf computation on H(0 || pos || val) where 0 is leaf_node_domain_separator... to help readers understand why +2
| let squeezed = RescueCRHF::<F>::sponge_no_padding(&data, 1).unwrap(); | ||
| let val = squeezed[0]; | ||
|
|
||
| let elems = vec![val; attack_pos as usize + 1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we:
- construct this leaves vector with
Vec::with_capacity(next_multiple_of(attack_pos, arity)) - only mutate the
attack_posto be theval - add some sanity check on the constructed
mt'sheight,num_leavesetc.
| if let Some(random_lookup) = (0..input.elems.len()) | ||
| .into_iter() | ||
| .collect::<Vec<_>>() | ||
| .choose(&mut thread_rng()) | ||
| .cloned() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this an overly-complicated way of doing rng.gen_range(0..len)?
| .cloned() | ||
| { | ||
| let commitment = mt.commitment(); | ||
| if let jf_merkle_tree::LookupResult::Ok(elem, proof) = mt.lookup(random_lookup as u64) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q1: i can't think of a reason why the result here won't be LookupResult::Ok, we didn't prune it or explicitly forget it.
Q2: putting it behind if let indicate that we want to skip the failure cases? should we panic in those case instead. I think we should ? to panic.
|
|
||
| #[derive(Arbitrary, Debug)] | ||
| struct MerkleTreeArbitraryInput { | ||
| // height: usize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not?
| if let Some(random_lookup) = (0..input_elems_len) | ||
| .into_iter() | ||
| .collect::<Vec<_>>() | ||
| .choose(&mut rand::rng()) | ||
| .cloned() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, why not rand::rng().random_rang()?
| return; | ||
| } | ||
|
|
||
| let elems: Vec<Fr254> = input.elems.iter().map(|x| Fr254::from(*x)).collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
importing ark_std::UniformRand, then you can invoke Fr254::rand(&mut rng) which will produce a uniform field element (256bits) rather than converting from a single limb u64.
we can use arbitrary input's as seed to a SeedableRng which is further used to generate a random field element if Arbtrary doesn't work well with Fr::rand() api.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so what are we testing here? just universal tree construction? or maybe this is just WIP?
Howdy gents.
Tobias and I have had some initial luck with getting libFuzzer integrated and want to spend some time looking at this further (i.e. a more comprehensive test harness, etc). We wanted to solicit your feedback as this would be a lot of work, and if there's no hope of it ever merging we might consider some other approaches.