Implement crypto byte array newtypes in term of a shared type (#3684)

Introduces `CryptoBytes` type defined as:

```rust
pub struct CryptoBytes<const N: usize, Tag = ()>(pub [u8; N], PhantomData<fn() -> Tag>);
```

The type implements a bunch of methods and traits which are typically
expected from a byte array newtype
(NOTE: some of the methods and trait implementations IMO are a bit
redundant, but I decided to maintain them all to not change too much
stuff in this PR)

It also introduces two (generic) typical consumers of `CryptoBytes`:
`PublicBytes` and `SignatureBytes`.

```rust
pub struct PublicTag;
pub PublicBytes<const N: usize, CryptoTag> = CryptoBytes<N, (PublicTag, CryptoTag)>;

pub struct SignatureTag;
pub SignatureBytes<const N: usize, CryptoTag> = CryptoBytes<N, (SignatureTag, CryptoTag)>;
```

Both of them use a tag to differentiate the two types at a higher level.
Downstream specializations will further specialize using a dedicated
crypto tag. For example in ECDSA:


```rust
pub struct EcdsaTag;

pub type Public = PublicBytes<PUBLIC_KEY_SERIALIZED_SIZE, EcdsaTag>;
pub type Signature = PublicBytes<PUBLIC_KEY_SERIALIZED_SIZE, EcdsaTag>;
```

Overall we have a cleaner and most importantly **consistent** code for
all the types involved

All these details are opaque to the end user which can use `Public` and
`Signature` for the cryptos as before
This commit is contained in:
Davide Galassi
2024-03-19 16:47:42 +01:00
committed by GitHub
parent 5fd72a1f5e
commit 1e9fd23776
29 changed files with 492 additions and 1163 deletions
@@ -340,8 +340,8 @@ impl Statement {
Some(Proof::OnChain { .. }) | None => SignatureVerificationResult::NoSignature,
Some(Proof::Sr25519 { signature, signer }) => {
let to_sign = self.signature_material();
let signature = sp_core::sr25519::Signature(*signature);
let public = sp_core::sr25519::Public(*signer);
let signature = sp_core::sr25519::Signature::from(*signature);
let public = sp_core::sr25519::Public::from(*signer);
if signature.verify(to_sign.as_slice(), &public) {
SignatureVerificationResult::Valid(*signer)
} else {
@@ -350,8 +350,8 @@ impl Statement {
},
Some(Proof::Ed25519 { signature, signer }) => {
let to_sign = self.signature_material();
let signature = sp_core::ed25519::Signature(*signature);
let public = sp_core::ed25519::Public(*signer);
let signature = sp_core::ed25519::Signature::from(*signature);
let public = sp_core::ed25519::Public::from(*signer);
if signature.verify(to_sign.as_slice(), &public) {
SignatureVerificationResult::Valid(*signer)
} else {
@@ -360,8 +360,8 @@ impl Statement {
},
Some(Proof::Secp256k1Ecdsa { signature, signer }) => {
let to_sign = self.signature_material();
let signature = sp_core::ecdsa::Signature(*signature);
let public = sp_core::ecdsa::Public(*signer);
let signature = sp_core::ecdsa::Signature::from(*signature);
let public = sp_core::ecdsa::Public::from(*signer);
if signature.verify(to_sign.as_slice(), &public) {
let sender_hash =
<sp_runtime::traits::BlakeTwo256 as sp_core::Hasher>::hash(signer);