Skip to content
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

Merged
merged 2 commits into from
Mar 24, 2022
Merged

Refactor Storage Signature #738

merged 2 commits into from
Mar 24, 2022

Conversation

HenriqueNogara
Copy link
Contributor

@HenriqueNogara HenriqueNogara commented Mar 21, 2022

Description of change

Change account-core Signature to new type struct, removing unused PublicKey. Remove Serialize/Deserialize for Key and bindings-derive feature

Links to any relevant issues

#669

fixes #722

Type of change

  • Bug fix (a non-breaking change which fixes an issue)
  • Enhancement (a non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Fix

How the change has been tested

All existing tests and examples have been run

Change checklist

  • I have followed the contribution guidelines for this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@HenriqueNogara HenriqueNogara added Enhancement New feature or improvement to an existing feature Breaking change A change to the API that requires a major release. Part of "Changed" section in changelog Rust Related to the core Rust code. Becomes part of the Rust changelog. labels Mar 21, 2022
@HenriqueNogara HenriqueNogara marked this pull request as ready for review March 21, 2022 14:47
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a 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> {
Copy link
Contributor

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>),
Copy link
Contributor

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>).

Copy link
Contributor Author

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.

Copy link
Contributor

@cycraig cycraig Mar 21, 2022

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.

Copy link
Contributor

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.

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))

Copy link
Contributor

@cycraig cycraig Mar 21, 2022

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 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. I think I misunderstood 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.

Copy link
Contributor

@cycraig cycraig left a 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.

Comment on lines 7 to 10
/// A digital signature.
#[derive(Clone, Deserialize, Serialize)]
pub enum Signature {
Ed25519(Vec<u8>),
Copy link
Contributor

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?

Comment on lines 14 to 18
/// Consumes the signature and returns it as bytes
pub fn as_bytes(self) -> Vec<u8> {
match self {
Signature::Ed25519(bytes) => bytes,
}
Copy link
Contributor

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...

Copy link
Contributor

@cycraig cycraig left a 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!

Comment on lines 21 to 24
// 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()
Copy link
Contributor

@cycraig cycraig Mar 23, 2022

Choose a reason for hiding this comment

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

Suggested change
// 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()

Copy link
Contributor

@cycraig cycraig left a 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.

@HenriqueNogara HenriqueNogara changed the title Chore/refactor signature Refactor Storage Signature Mar 23, 2022
@HenriqueNogara HenriqueNogara added the Wasm Related to Wasm bindings. Becomes part of the Wasm changelog label Mar 23, 2022
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a 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!

Comment on lines +21 to +24
/// 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()
Copy link
Contributor

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.

@HenriqueNogara HenriqueNogara merged commit c484b26 into dev Mar 24, 2022
@HenriqueNogara HenriqueNogara deleted the chore/refactor-signature branch March 24, 2022 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Breaking change A change to the API that requires a major release. Part of "Changed" section in changelog Enhancement New feature or improvement to an existing feature Rust Related to the core Rust code. Becomes part of the Rust changelog. Wasm Related to Wasm bindings. Becomes part of the Wasm changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Task] Refactor Account Signature
3 participants