-
Notifications
You must be signed in to change notification settings - Fork 87
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
Refactor Storage Signature #738
Conversation
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.
It looks like you have a commit related to the release, that is not on dev
somehow? Maybe you can check with @eike-hass what's going on.
Maybe I missed the conversation, but why is Signature
an enum? I think we can just make the signature a wrapper around bytes.
Edit: Looks like @eike-hass force-pushed dev
(?), so you should get rid of 38069e8ba0eb5427eabfff3e100ecd7ab88be7b7
here.
pub fn data(&self) -> &[u8] { | ||
&self.data | ||
/// Consumes the signature and returns it as bytes | ||
pub fn as_bytes(self) -> Vec<u8> { |
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.
Not sure why clippy's wrong_self_convention
isn't triggered here, this should be called into_bytes
. Not sure about the JS method you're binding to, but I would probably go with toBytes
.
/// A digital signature. | ||
#[derive(Clone, Deserialize, Serialize)] | ||
pub enum Signature { | ||
Ed25519(Vec<u8>), |
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.
Do we need this to be an enum? I think we can just use pub struct Signature(Vec<u8>)
.
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.
We can, but if we want to add support to something else latter on, we would have to change it.
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.
We could also use Vec<u8>
/UInt8Array
(or a newtype wrapper) for now since we only support those types of signatures then refactor it when we need to support something more exotic?
Edit: or use SignatureValue
. Really not sure on which design is best, just that the previous design with public key was wrong.
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.
I assume any signature can be represented as bytes, and what type of signature it is, is clear from context, e.g. when calling key_sign
with a KeyLocation
that contains a certain MethodType
. So having to do the additional match seems unnecessary, unless the Storage
implementation is simply wrong and returns something else. It's maybe slightly safer, but I don't really see a major advantage.
At least judging by RemoteSign
, I think it's better not to use SignatureValue
, so we don't accidentally return that signature value, but have to first encode it as base58 and then return an instance of SignatureValue
.
identity.rs/identity-account-storage/src/crypto/remote.rs
Lines 53 to 56 in 1271d95
let message: Vec<u8> = data.to_jcs()?; | |
let signature: Vec<u8> = RemoteSign::sign(&message, remote_key).await?; | |
let signature: String = encode_b58(&signature); | |
Ok(SignatureValue::Signature(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.
I assume any signature can be represented as bytes
I'm not sure that's a strong assumption. For instance the BBS+ Signatures 2020 spec requires a nonce value used to derive the proof as well, so it's probable that we will need more than just the signature/proof bytes in the future. One could argue that the I think I misunderstood nonce
could be predetermined and passed to the sign
function but that just moves the problem to the signing interface not being general enough to handle it.nonce
as something passed to the signature algorithm: I think it's just something similar to a random challenge added to the data to show it's not replayed. This would strengthen the argument for just using Vec<u8>
rather than an enum for now.
At least judging by RemoteSign, I think it's better not to use SignatureValue,
I agree, SignatureValue
does not seem fully appropriate for this as it would require Storage
implementers to also implement the signature schemes such as JCSEd25519Signature2020
and handle encoding rather than just the raw key signing.
I'm fine using just Vec<u8>
or a similar new-type wrapper, until we need to refactor it to handle a new method type, if we cannot come to a consensus on what a future-proof design looks like now.
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 has a bunch of release changes, this may have to be rebased to remove them since I think dev
was force-pushed.
Edit: merge from dev should solve this now, since the commits will be squashed anyway.
Should we consider using SignatureValue
from identity-core
to avoid the new type altogether or does the SignatureValue::None
variant make it unusable in this context?
Edit: SignatureValue
was decided to be inappropriate for this.
Edit: missed @PhilippGackstatter previous review, sorry for the duplication.
/// A digital signature. | ||
#[derive(Clone, Deserialize, Serialize)] | ||
pub enum Signature { | ||
Ed25519(Vec<u8>), |
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.
I think this design is good for forwards-compatibility. Should we mark the enum as non_exhaustive
so we can add variants without causing a breaking change?
/// Consumes the signature and returns it as bytes | ||
pub fn as_bytes(self) -> Vec<u8> { | ||
match self { | ||
Signature::Ed25519(bytes) => bytes, | ||
} |
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.
Not too sure about the name, as_*
usually doesn't consume self
. Maybe into_bytes
would be more appropriate? It's unclear whether all variants will be able to satisfy this though...
73d29a9
to
297f6e0
Compare
297f6e0
to
24de838
Compare
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.
Looks good to me!
// Returns a copy of the signature as a vec of bytes. | ||
#[wasm_bindgen(js_name = asBytes)] | ||
pub fn as_bytes(&self) -> Vec<u8> { | ||
self.0.as_bytes().to_vec() |
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.
// Returns a copy of the signature as a vec of bytes. | |
#[wasm_bindgen(js_name = asBytes)] | |
pub fn as_bytes(&self) -> Vec<u8> { | |
self.0.as_bytes().to_vec() | |
// Returns a copy of the signature as a `UInt8Array`. | |
#[wasm_bindgen(js_name = asBytes)] | |
pub fn as_bytes(&self) -> Vec<u8> { | |
self.0.as_bytes().to_vec() |
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.
Oh, maybe change the PR title to fit the changelog better. Something like "Refactor Storage
Signature
".
Edit: and add the Wasm
label, it affects the bindings too.
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.
Looks good to me, thanks for the changes!
/// Returns a copy of the signature as a `UInt8Array`. | ||
#[wasm_bindgen(js_name = asBytes)] | ||
pub fn as_bytes(&self) -> Vec<u8> { | ||
self.0.as_bytes().to_vec() |
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.
Nit: I still think this should be toBytes
in JS, mostly due to the Rust naming convention reasoning of "to" representing a conversion. But since I'm not familiar with JS naming conventions in that detail, I'll leave it up to you.
Description of change
Change
account-core
Signature
to new type struct, removing unusedPublicKey
. RemoveSerialize/Deserialize
forKey
andbindings-derive
featureLinks to any relevant issues
#669
fixes #722
Type of change
How the change has been tested
All existing tests and examples have been run
Change checklist