Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Signing context may not be selected at runtime. #12

Open
wilfred-centrality opened this issue Jul 2, 2019 · 11 comments
Open

Signing context may not be selected at runtime. #12

wilfred-centrality opened this issue Jul 2, 2019 · 11 comments

Comments

@wilfred-centrality
Copy link

In an ideal world there would be sign and verify methods able to take a signing context from JS at runtime.

We've been scratching our heads over the current situation. The context is fixed to substrate, and the requirement seems to be that any signing context is defined at build time. Besides forking this repo and publishing a package with the signing contexts cennznet needs, are there any other methods that might work for us?

The underlying cause of the issue is a static lifetime requirement on the signing context that comes from the merlin crate, which is used by w3f's schnorrkel.

@Mischala
Copy link

Mischala commented Jul 2, 2019

I have run into this issue when creating a wrapper for Schnorrkel in Python.
In that too, it is impossible to change the signing context, which kinda ruins this library's use as a multipurpose solution.

@burdges
Copy link

burdges commented Jul 2, 2019

Interesting, we could submit a pull request to merlin, not sure if they'd accept it, but hey.. dalek-cryptography/merlin#44

It's not afaik necessarily undefined behavior for foreign code to pass rust a &'static [u8], just even less safe than the normal FFI boundary. We all know merlin consumes its instantly, and even as a &'a [u8], so passing a reference works and can even live long enough.

Rust's Box<[u8]>: 'static and ditto Vec<u8> but you can only obtain the &'static [u8] safely with leak::<'static>, so you could reallocate the context temporarily and either (a) you initialize only a few signing contexts on startup, which risks memory leaks, (b) you depend upon leak being a wrapper around into_raw(), or (c) you write leak yourself using into_raw. I think (c) is preferable, but maybe just passing the reference is acceptable too.

You could maybe manage some static mut UGLY: HashSet<&'static [u8]> = HashSet::new() that you populate with Box::leak, but ugh..

We could make signing_transcript call Transcript::new("") and then append_label, which avoids the problem without altering merlin.

There is a separate concern that merlin/strobe might not be the fastest hashing library, which sucks if people call SingingContext::bytes. I never quite got around to doing the benchmarks, but we always supported any hash function with an XoF, which currently means Shake128, but Blake2x works too if anyone implements it RustCrypto/hashes#83

Anyways..

There are a bunch of breaking changes in schnorrkel now, so we should resolve this hashing question before the schnorrkel audit finishes and substrate updates.

burdges added a commit to burdges/merlin that referenced this issue Jul 2, 2019
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)
@burdges
Copy link

burdges commented Jul 2, 2019

We cannot expect merlin to be changed, so we should take another route, either abusing leaking, using empty labels, or just dumping or forking merlin. I like both merlin and strobe, but we cannot reject dynamic langues, so..

We should benchmark merlin vs. shake128 for our use case I think. And thanks for bringing this up in a timely fashion!

@wilfred-centrality
Copy link
Author

No worries, and thanks. Let me know if there's anything we can do in the meantime. Somewhat time critical for us as well so hoping for speedy resolution.

burdges added a commit to w3f/bls that referenced this issue Jul 3, 2019
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
@burdges
Copy link

burdges commented Jul 3, 2019

I've taken the meaningless labels approach while adding our own domain separation in w3f/schnorrkel@fa0a6f7 We should still benchmark merlin vs shake128 though. I also removed merlin from our bls crate where it added nothing.

burdges added a commit to w3f/schnorrkel that referenced this issue Jul 3, 2019
We ran into trouble using merlin with dynamic langauges:
paritytech/schnorrkel-js#12
dalek-cryptography/merlin#44
This is the easiest solution.
@wilfred-centrality
Copy link
Author

Wonderful news, in that case we're close to a solution. The verify methods still have a static lifetime requirement, for example: https://github.com/w3f/schnorrkel/blob/fee6fdf0b5fd087d9531825c7165abe29f2fe21d/src/sign.rs#L213

@wilfred-centrality
Copy link
Author

Please review w3f/schnorrkel#40

wilfred-centrality added a commit to wilfred-centrality/schnorrkel that referenced this issue Jul 8, 2019
@burdges
Copy link

burdges commented Jul 8, 2019

Merged. We require 0.6.1 now since I got overzealous and yanked 0.6.0

@burdges
Copy link

burdges commented Jul 8, 2019

We've an audit starting this week, so expect a breaking 0.7 before August.

@wilfred-centrality
Copy link
Author

wilfred-centrality commented Jul 8, 2019 via email

@wilfred-centrality
Copy link
Author

Please review #13

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants