-
Notifications
You must be signed in to change notification settings - Fork 224
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
Add crypto provider #1214
Add crypto provider #1214
Conversation
It might make more sense to put this in the Then downstream crates like This keeps the core cryptographic functionality in one crate, instead of spread out. |
@@ -51,14 +52,14 @@ tendermint-proto = { version = "0.25.0", default-features = false, path = "../pr | |||
time = { version = "0.3", default-features = false, features = ["macros", "parsing"] } | |||
zeroize = { version = "1.1", default-features = false, features = ["zeroize_derive", "alloc"] } | |||
flex-error = { version = "0.4.4", default-features = false } | |||
k256 = { version = "0.11", optional = true, default-features = false, features = ["ecdsa", "sha256"] } | |||
k256 = { version = "0.11", default-features = false, features = ["ecdsa", "sha256"] } |
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.
Having this one optional depends on whether CryptoProvider
will be under a feature flag.
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.
As I understand it now, we lock the signature type in CryptoProvider
to the one defined by k256
. If we cannot abstract this associated type to less specific rust-crypto bounds ("must be fixed array of 256 bits"?) and still keep it usable in generic code, then k256
should become a hard dependency. But I thought dependency management was the whole purpose of this rework.
Moved it on 100fc53 |
Codecov Report
@@ Coverage Diff @@
## main #1214 +/- ##
=======================================
- Coverage 64.2% 64.1% -0.2%
=======================================
Files 244 245 +1
Lines 21364 21401 +37
=======================================
- Hits 13734 13731 -3
- Misses 7630 7670 +40
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
The new API looks good in general, will review once more when undrafted. |
I'll add this, and un-draft it :) |
tendermint/src/host_functions.rs
Outdated
@@ -0,0 +1,134 @@ | |||
use crate::signature::Verifier; |
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.
As a general thought, "host functions" that contains only a CryptoProvider
trait still feels like YAGNI to me.
I would personally suggest putting it under a crypto
module (which should probably have been created a long time ago, with all of the existing cryptography code in the tendermint
crate factored into it).
The trait itself looks OK, aside from the commented out part. However, it isn't terribly useful unless the existing cryptography in the crate(s) is changed to use it. And that's where this sort of change might get a bit onerous: you either need to add a generic type parameter with a default, or a generic type parameter with feature-gated type aliases. I'd probably suggest the latter. |
Please check it out here: ComposableFi/near-rs#16 |
Is this PR meant to start a piecemeal introduction of the larger set of changes first submitted in #1138?
I think a ready-to-use implementation of the crypto functions, using widely adopted pure Rust dependencies, should be provided in the tendermint crate for those users who don't need to bother with the alternatives. In the interests of dependency management, it needs to be feature-gated. |
Can you please be more specific on how to make if feature-gated friendly? |
Cribbing from #1138 again, you could have a generic #[cfg(feature = "rust-crypto")]
pub type ProdCommitValidator = CommitValidator<RustCryptoProvider>; But perhaps it's work for a follow-up PR. I will look into ComposableFi/near-rs#16 and the fork of tendermint-rs used in Hyperspace. |
@mzabaluev gave my first shot on feature gating this. Would def appreciate some guidance :) |
#[cfg(feature = "rust-crypto")] | ||
type RustCryptoProvider: CryptoProvider; | ||
|
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.
Feature-gating trait members is not a good idea, I think.
Perhaps I did not explain the idea more carefully. It's OK to work the abstract CryptoProvider
generics wherever needed without feature-gating. So you could have:
// Kill the CommitValidator trait, its methods become inherent methods of the struct:
pub struct CommitValidator<C> {
// ...
}
impl<C: CryptoProvider> CommitValidator<C> {
// The API that belonged to CommitValidator trait goes here
}
/// The batteries-included validator, for when you don't mind the dependencies on
/// the full rust-crypto stack.
#[cfg(feature = "rust-crypto")]
pub type ProdCommitValidator = CommitValidator<RustCryptoProvider>;
@thanethomson I think all those traits having a single empty ProdFoo
implementation don't carry much weight in the current design, since all the logic is provided in the default trait method bodies. So it's fair to replace them with generic types parameterized around the crypto provider, like in the example above.
9afc8bf
to
63a2d0e
Compare
@mzabaluev any comments? |
tendermint/src/crypto.rs
Outdated
trait DefaultHostFunctions: CryptoProvider { | ||
fn sha2_256(preimage: &[u8]) -> [u8; 32]; | ||
fn ed25519_verify(sig: &[u8], msg: &[u8], pub_key: &[u8]) -> Result<(), ()>; | ||
fn secp256k1_verify(sig: &[u8], message: &[u8], public: &[u8]) -> Result<(), ()>; | ||
} |
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.
The purpose of this trait is not clear. Is it meant to be a "god trait" for all future functions that could be host-provided? Now, it only adds the crypto methods that I think could well be defined in CryptoProvider
itself, because the implementation is tightly coupled with the associated type definitions there.
I agree with @tony-iqlusion that this umbrella trait is not necessarily needed until we realise a clear purpose for it.
tendermint/src/crypto.rs
Outdated
// type Ed25519Signer: Signer<ed25519::Signature>; | ||
// type Ed25519Verifier: Verifier<ed25519::Signature>; |
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.
This should be removed, to be added later when/if needed.
@@ -51,14 +52,14 @@ tendermint-proto = { version = "0.25.0", default-features = false, path = "../pr | |||
time = { version = "0.3", default-features = false, features = ["macros", "parsing"] } | |||
zeroize = { version = "1.1", default-features = false, features = ["zeroize_derive", "alloc"] } | |||
flex-error = { version = "0.4.4", default-features = false } | |||
k256 = { version = "0.11", optional = true, default-features = false, features = ["ecdsa", "sha256"] } | |||
k256 = { version = "0.11", default-features = false, features = ["ecdsa", "sha256"] } |
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.
As I understand it now, we lock the signature type in CryptoProvider
to the one defined by k256
. If we cannot abstract this associated type to less specific rust-crypto bounds ("must be fixed array of 256 bits"?) and still keep it usable in generic code, then k256
should become a hard dependency. But I thought dependency management was the whole purpose of this rework.
I think the functionality abstracted by |
Here's my crack at it: #1238 |
Superseded by #1238 |
Draft definition of the
CryptoProvider
trait defined in #1213 + an actual instance of the traitfor a
HostFunction*
implementation