Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Introduce Ristretto signing #1730

Merged
merged 20 commits into from
Feb 13, 2019
Merged

Introduce Ristretto signing #1730

merged 20 commits into from
Feb 13, 2019

Conversation

gavofyork
Copy link
Member

@gavofyork gavofyork commented Feb 7, 2019

Alternative to #1706. Closes #1685.

Switch out transaction signing from Ed25519 to Schnorr/Ristretto x25519.

Included in these changes: removal of all hard-coded hashes in the node-executor test suite. Yes. That means when you change something in the runtime, you will no longer need to "update the hashes"!

@jacogr please let us know once you've managed to integrate the new signing into the JS UI.

@gavofyork gavofyork added the A0-please_review Pull request needs code review. label Feb 7, 2019
@burdges
Copy link

burdges commented Feb 8, 2019

I suppose ext_sr25519_verify permits the signature to run native, nice. I see at least three variants here:

We could pass a running hash function state through this boundary, possibly a 203 byte merlin::Transcript or possibly something else. This gives the cleanest looking code because you avoid artificial serialization. There is however a small cost to running the hash function in WASM when hashing anything large.

We could simply add a context parameter to ext_sr25519_verify so that at least adding context avoids artificial serialization, but..

Ideally, we should select some fast hash function for hashing large things anyways, probably blake2b or blake2x if we have chacha elsewhere, or maybe kangaroo12 if we want keccek everywhere. We now become free to do merlin::Transcript hashing inside WASM safe in the knowledge that we could later improve performance by adding a native call for our fast hash function.

On the other hand, alternative implementations suffer from passing a running hash function across the boundary. If they want to provide this call then they would be required to handle the precise internal state of running hash function. If this is a concern, ext_sr25519_verify could just take a 32 byte hash output and maybe a context string.

As an aside, if we had unlimited time then STROBE itself provides a perfect interface for being called across boundaries because it's literally one method that does all your normal symmetric crypto operations. In fact, merlin uses STROBE on a Keccek variant, so this remains an option for later, but I donno if STROBE's Keccek variant is the best choice for hashing large amounts of data. I'll note a full STROBE implementation has a slightly more complex internal state than a merlin::Transcript.

@burdges
Copy link

burdges commented Feb 8, 2019

In any case, artificial serialization can always be avoided by hashing data and maybe context inside WASM and calling this ext_sr25519_verify on the 32 byte output. I'm probably making a mountain out of a mole hill here.

use runtime_primitives::generic;
use runtime_primitives::{OpaqueExtrinsic, traits::BlakeTwo256};
use runtime_primitives::{
generic, traits::{Verify, BlakeTwo256, Sr25519Signature}, OpaqueExtrinsic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is Sr25519Signature being imported from traits submodule of the runtime? Moving it outside (directly imported from runtime_primitives) seems to take the build error at least a step further toward success.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed that - was just a typo.

@gavofyork
Copy link
Member Author

The usage expects AsRef for sr25519::Signature. You can either change the usage to e.g. Encode::encode it instead, or rework the Signature type itself, either introducing an appropriate AsRef in schnorrkel or just using an alternative type and converting between them as needed in sr25519.rs.

@burdges
Copy link

burdges commented Feb 8, 2019

It's fine to treat errors in deserializing a signature as signature verification errors, so sr25519::Signature could wrap just a [u8; 64].. and signatures only get checked once.

It's less ideal treat public key deserialization errors as signature verification errors because they can represent a failure elsewhere.. and sometimes you verify with the same key repeatedly.

@burdges
Copy link

burdges commented Feb 8, 2019

Just to continue that aside: You could alternatively provide only the permutation like keccak in native, except then you'd be calling across the boundary too much. And it'd break optimizations for at least some chacha implementations. You can normally call STROBE's operate only a couple times for whatever your goal is.

}
/// The Ed25519 keyring.
///
/// This is deprecated: use `ed25519::Keyring` instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something about this comment not making sense or am I reading it wrong?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also taking the next line of code into account.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means: "Don't use Keyring directly because at some point in the future we'll remove it. Instead use ed25519::Keyring"

@gavofyork gavofyork added A8-looksgood and removed A0-please_review Pull request needs code review. labels Feb 11, 2019
@gavofyork
Copy link
Member Author

(Buying myself a beer after removing the need to keep those hashes maintained.)

@kianenigma
Copy link
Contributor

while it is still open, we could also add/further discuss a new sign() to accept Rng (or anything representing entropy) as a parameter before this is even merged at the first place. Needs to be first implemented in the underlying library.

  • And remove the dependency as git = ... and replace the published version in crates.io

@gavofyork gavofyork merged commit 71fb444 into master Feb 13, 2019
@gavofyork gavofyork deleted the gav-ristretto-crypto branch February 13, 2019 09:10
@svyatonik svyatonik mentioned this pull request Feb 13, 2019
MTDK1 pushed a commit to bdevux/substrate that referenced this pull request Apr 12, 2019
* first draft of ristretto crypto module paritytech#1685

* adds better comments and code-style

* remove the last evil unwrap

* remove a mistakenly committed lockfile

* add a fresh new lockfile --will probably need a manual merge later

* fix an invalid old test vector

* Wire in ristretto

* Update comment

* Fix use.

* new Signature type api alias to be compatible with substrate

* Add new keyring, fix node executor tests

* Bump version.

* Remove all hashes.

* Update core/primitives/src/sr25519.rs

Co-Authored-By: gavofyork <github@gavwood.com>

* Revert back to Ed25519 (until JS UI is ready)

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

Successfully merging this pull request may close these issues.

6 participants