Help with Advanced traits

Hello everyone!
I am currently working on an optimized implementation of the COLM AEAD family.
I created a working draft based on AES as the underlying block cipher but now I wanted to make it generic over the underlying block cipher, using some traits from the cipher and aead crates.
For the struct representing COLM encryption it was rather easy as you can see in the following.

Summary
/// COLM authenticated encryption with associated data.
///
/// Representation of COLM0, no intermediate tag generation. (encryption-only)
pub struct Colm0Enc<B> {
    bc: B,
}

impl<B> KeySizeUser for Colm0Enc<B>
where
    B: KeyInit,
{
    type KeySize = B::KeySize;
}

impl<B> NewAead for Colm0Enc<B>
where
    B: BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit,
{
    type KeySize = B::KeySize;

    fn new(key: &Key<Self>) -> Self {
        B::new(key).into()
    }
}

impl<B> From<B> for Colm0Enc<B>
where
    B: BlockSizeUser<BlockSize = U16> + BlockEncrypt,
{
    fn from(cipher: B) -> Self {
        Self { bc: cipher }
    }
}

However, doing the same for the struct representing COLM decryption was not that intuitive, because of the following reason: COLM decryption requires an instatiation of both the encryption AND decryption variant of the used block cipher, which was kinda hard to represent using the traits shown above. I am kinda new to working with advanced traits and the following is the best I could come up with up to now, though it still results in a cryptic error I don't understand at all:

Summary
struct BcEnc<E>
where
    E: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit,
{
    enc: E,
}

struct BcDec<D>
where
    D: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockDecrypt + KeyInit,
{
    dec: D,
}

/// COLM authenticated encryption with associated data.
///
/// Representation of COLM0, no intermediate tag generation. (decryption-only)
pub struct Colm0Dec<E, D>
where
    E: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit,
    D: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockDecrypt + KeyInit,
{
    enc: BcEnc<E>,
    dec: BcDec<D>,
}

impl<E, D> Colm0Dec<E, D>
where
    E: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit,
    D: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockDecrypt + KeyInit,
{
    pub fn new(key: &GenericArray<u8, U16>) -> Self {
        Self {
            enc: BcEnc::new(key), // <--- Error
            dec: BcDec::new(key), // <--- Error
        }
    }
}

GIving me the cryptic error message:

{unknown}
the function or associated item `new` exists for struct `colm0::BcEnc<_>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`colm0::BcEnc<_>: cipher::crypto_common::InnerInit`
which is required by `colm0::BcEnc<_>: cipher::KeyInit`
`colm0::BcEnc<_>: cipher::crypto_common::InnerUser`
which is required by `colm0::BcEnc<_>: cipher::KeyInit`
`&colm0::BcEnc<_>: cipher::crypto_common::InnerInit`
which is required by `&colm0::BcEnc<_>: cipher::KeyInit`
`&colm0::BcEnc<_>: cipher::crypto_common::InnerUser`
which is required by `&colm0::BcEnc<_>: cipher::KeyInit`
`&mut colm0::BcEnc<_>: cipher::crypto_common::InnerInit`
which is required by `&mut colm0::BcEnc<_>: cipher::KeyInit`
`&mut colm0::BcEnc<_>: cipher::crypto_common::InnerUser`
which is required by `&mut colm0::BcEnc<_>: cipher::KeyInit`rustcE0599
colm0.rs(295, 1): function or associated item `new` not found for this
colm0.rs(295, 1): doesn't satisfy `colm0::BcEnc<_>: cipher::KeyInit`
colm0.rs(295, 1): doesn't satisfy `colm0::BcEnc<_>: cipher::crypto_common::InnerInit`
colm0.rs(295, 1): doesn't satisfy `colm0::BcEnc<_>: cipher::crypto_common::InnerUser`
lib.rs(95, 1): the following traits must be implemented

If anyone could point me in the right direction I would be more than grateful. Thanks a lot in advance!

Edit:
In case someone wants to take a look at the code in its entirety here's the repo. Latest changes are on branch refactor, which was not merged into master yet since attempting the implementation of generics.

I haven't looked into what your issue is, but that's not the full error. It looks like information from an IDE popup. I recommend looking at the full error as reported by cargo build.

1 Like

Oh yes of course, sorry.
This is the build output:

error[E0599]: the function or associated item `new` exists for struct `BcEnc<_>`, but its trait bounds were not satisfied
   --> src/colm0.rs:328:25
    |
295 | / struct BcEnc<E>
296 | | where
297 | |     E: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit,
298 | | {
299 | |     enc: E,
300 | | }
    | | -
    | | |
    | | function or associated item `new` not found for this
    | | doesn't satisfy `BcEnc<_>: InnerInit`
    | |_doesn't satisfy `BcEnc<_>: InnerUser`
    |   doesn't satisfy `BcEnc<_>: KeyInit`
...
328 |               enc: BcEnc::new(key),
    |                           ^^^ function or associated item cannot be called on `BcEnc<_>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `BcEnc<_>: InnerInit`
            which is required by `BcEnc<_>: KeyInit`
            `BcEnc<_>: InnerUser`
            which is required by `BcEnc<_>: KeyInit`
            `&BcEnc<_>: InnerInit`
            which is required by `&BcEnc<_>: KeyInit`
            `&BcEnc<_>: InnerUser`
            which is required by `&BcEnc<_>: KeyInit`
            `&mut BcEnc<_>: InnerInit`
            which is required by `&mut BcEnc<_>: KeyInit`
            `&mut BcEnc<_>: InnerUser`
            which is required by `&mut BcEnc<_>: KeyInit`
note: the following traits must be implemented
   --> /home/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/crypto-common-0.1.3/src/lib.rs:95:1
    |
95  | / pub trait InnerUser {
96  | |     /// Inner type.
97  | |     type Inner;
98  | | }
    | |_^
...
189 | / pub trait InnerInit: InnerUser + Sized {
190 | |     /// Initialize value from the `inner`.
191 | |     fn inner_init(inner: Self::Inner) -> Self;
192 | | }
    | |_^

error[E0599]: the function or associated item `new` exists for struct `BcDec<_>`, but its trait bounds were not satisfied
   --> src/colm0.rs:329:25
    |
302 | / struct BcDec<D>
303 | | where
304 | |     D: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockDecrypt + KeyInit,
305 | | {
306 | |     dec: D,
307 | | }
    | | -
    | | |
    | | function or associated item `new` not found for this
    | | doesn't satisfy `BcDec<_>: InnerInit`
    | |_doesn't satisfy `BcDec<_>: InnerUser`
    |   doesn't satisfy `BcDec<_>: KeyInit`
...
329 |               dec: BcDec::new(key),
    |                           ^^^ function or associated item cannot be called on `BcDec<_>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `BcDec<_>: InnerInit`
            which is required by `BcDec<_>: KeyInit`
            `BcDec<_>: InnerUser`
            which is required by `BcDec<_>: KeyInit`
            `&BcDec<_>: InnerInit`
            which is required by `&BcDec<_>: KeyInit`
            `&BcDec<_>: InnerUser`
            which is required by `&BcDec<_>: KeyInit`
            `&mut BcDec<_>: InnerInit`
            which is required by `&mut BcDec<_>: KeyInit`
            `&mut BcDec<_>: InnerUser`
            which is required by `&mut BcDec<_>: KeyInit`
note: the following traits must be implemented
   --> /home/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/crypto-common-0.1.3/src/lib.rs:95:1
    |
95  | / pub trait InnerUser {
96  | |     /// Inner type.
97  | |     type Inner;
98  | | }
    | |_^
...
189 | / pub trait InnerInit: InnerUser + Sized {
190 | |     /// Initialize value from the `inner`.
191 | |     fn inner_init(inner: Self::Inner) -> Self;
192 | | }
    | |_^

Do you just need to implement NewAead for BcEnc<E> and BcDec<D> like you did for Colm0Enc<B>?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.