-
Notifications
You must be signed in to change notification settings - Fork 66
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
Allow Transcript::new labels to come from non-rust code without leakage, UB, etc. #44
Conversation
Merlin requires `'static` protocol labels, which normally originate in Rust code for various reasons, ala session type. Yet, the label passwd to new could reasonably originate outside Rust code, due to protocols being designed to be composed. paritytech/schnorrkel-js#12 (comment)
Alternatives:
t.append_message(b"externally defined label", external_label);
let _: &'static str = Box::leak(String::from("hello world").into_boxed_str()); |
Transcript::new
labels to come from non-rust code without leakage, UB, etc.
Transcript::new
labels to come from non-rust code without leakage, UB, etc.
Internally, merlin does 1 for I now think 2 cannot work in practice because someone will invoke the leaking code repeatedly. |
(2) shouldn't be an issue if the user can't create new labels. See my previous message as edited. Leak a single string containing all labels and refer to its slices. |
Note: because Merlin includes metadata in the transcript, passing an empty label into the transcript and then later adding a label is not the same as initializing a transcript with that label, by design. The Merlin API is designed so that the parts which should be fixed statically (protocol framing and names) are You should not create a transcript with an empty protocol label. The protocol label does domain separation for your construction. If you want to do additional domain separation, you can append further messages after creating the transcript, and this works fine without having to change any lifetimes. |
There is no meaningful Yes, a As I noted elsewhere, a |
Given that this exists in safe Rust, what exactly is the API meant to defend against?
Your definition of "runtime" works for pure-rust but is fairly short-sighted w.r.t. dynamic languages. The protocol label may not vary after some point in time T but is not known at compile-time. If a goal of Merlin is to avoid users hand-rolling their own (potentially broken) domain separation then it seems counter-intuitive to raise the barrier to entry for certain valid use-cases. |
Is this strictly necessary? Pun not intended |
We ran into trouble using merlin with dynamic langauges: paritytech/schnorrkel-js#12 dalek-cryptography/merlin#44 We only benefit minimally if at all from using merlin here anyways, so just remove it entirely. Also merlin is not likely to adapt anything else we noticed as convenient: dalek-cryptography/merlin#37
We'll use |
We ran into trouble using merlin with dynamic langauges: paritytech/schnorrkel-js#12 dalek-cryptography/merlin#44 This is the easiest solution.
For what it's worth, I am also finding this design choice regrettable and not usable even within Rust itself. I am trying to export the proof verifier from the bulletproofs library inside our smart contract language, Move, which is implemented in Rust. By requiring I cannot use Will probably have to fork and change this. PS: I cannot "use |
I've always just told people to unsafe cast to static but I'm always calling merlin directly.. you maybe more nervous if you propagate that static through however many subcrates are in bulletrpoofs.. If you maintain a fork then maybe you'll find some other warts more visible from how academics think about transcripts and it could find more adoption than merlin. |
Hey Jeff, If by cast to static you mean the Box-based approach I outlined above, then that would almost work, but not for us: we are not yet ready to use unsafe in our repo 😔 |
You do not need allocation. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=36046949c84b41372cc658cd4bb36f2c although If you're using a dependency that missuses the memory safety boundary then don't be so surprised by using unsafe. It sounds like those bulletproofs provers are miss-using one of the good parts merlin interface though, which makes this unsafety worse. |
Solution without For future reference, in case link breaks:
Not sure I follow your last claim: there's no misuse in each user
The problem, on our side, will be that we will need to provide a public-facing API that can verify any range proof |
Yes. I meant it's good As non-Rust languages exists, it's also bad or worse that merlin tries to prevent you from passing labels this with this silliness, but these mistakes do not cancel out. It'd all be far simpler to just say throughout the merlin documentation that domain separation depends upon your label choices so labels should come from your own code and not be abstracted. |
Merlin requires
'static
protocol labels, which normally originate in Rust code for various reasons, ala session type. Yet, the label passwd toTranscript::new
could reasonably originate outside Rust code when protocols are designed to be composed.paritytech/schnorrkel-js#12 (comment)