• Davide Galassi's avatar
    Implement crypto byte array newtypes in term of a shared type (#3684) · 1e9fd237
    Davide Galassi authored
    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
    1e9fd237