pub trait ORECipher: Sized {
    type LeftBlockType;
    type RightBlockType;
    fn init(
        k1: [u8; 16], 
        k2: [u8; 16], 
        seed: &[u8; 8]
    ) -> Result<Self, OREError>;
    fn encrypt_left<const N: usize>(
        &mut self, 
        input: &PlainText<N>
    ) -> Result<Left<Self, N>, OREError>
    where
        <Self as ORECipher>::LeftBlockType: CipherTextBlock;
    fn encrypt<const N: usize>(
        &mut self, 
        input: &PlainText<N>
    ) -> Result<CipherText<Self, N>, OREError>
    where
        <Self as ORECipher>::RightBlockType: CipherTextBlock,
        <Self as ORECipher>::LeftBlockType: CipherTextBlock;
    fn compare_raw_slices(a: &[u8], b: &[u8]) -> Option<Ordering>;
}