Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions openzl-crypto/src/encryption/hybrid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,17 @@ where
}
}

#[component]
impl<K, E> Hybrid<K, E> {
type Header = E::Header where E: HeaderType;
type Ciphertext = Ciphertext<K, E> where K: EphemeralPublicKeyType, E: CiphertextType;
type EncryptionKey = EncryptionKey<K> where K: PublicKeyType;
type DecryptionKey = DecryptionKey<K> where K: SecretKeyType;
type Plaintext = E::Plaintext where E: PlaintextType;
type Randomness = Randomness<K, E> where K: EphemeralSecretKeyType, E: RandomnessType;
type DecryptedPlaintext = E::DecryptedPlaintext where E: DecryptedPlaintextType;
}

impl<K, E> HeaderType for Hybrid<K, E>
where
E: HeaderType,
Expand Down
22 changes: 4 additions & 18 deletions openzl-crypto/src/encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,8 @@ where
/// Encryption Types
///
/// This `trait` encapsulates all the types required for [`Encrypt::encrypt`].
pub trait EncryptionTypes:
CiphertextType + EncryptionKeyType + HeaderType + PlaintextType + RandomnessType
{
}

impl<T> EncryptionTypes for T where
T: CiphertextType + EncryptionKeyType + HeaderType + PlaintextType + RandomnessType
{
}
#[component]
pub type Encryption: Ciphertext + EncryptionKey + Header + Plaintext + Randomness;

/// Encryption
pub trait Encrypt<COM = ()>: EncryptionTypes {
Expand Down Expand Up @@ -203,15 +196,8 @@ where
/// Decryption Types
///
/// This `trait` encapsulates all the types required for [`Decrypt::decrypt`].
pub trait DecryptionTypes:
CiphertextType + DecryptedPlaintextType + DecryptionKeyType + HeaderType
{
}

impl<T> DecryptionTypes for T where
T: CiphertextType + DecryptedPlaintextType + DecryptionKeyType + HeaderType
{
}
#[component]
pub type Decryption: Ciphertext + DecryptedPlaintext + DecryptionKey + Header;

/// Decryption
pub trait Decrypt<COM = ()>: DecryptionTypes {
Expand Down
280 changes: 269 additions & 11 deletions openzl-derive/src/component.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,184 @@
//! `#[component]` Attribute Macro

use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote};
use syn::{
braced,
parse::{Parse, ParseStream},
parse_macro_input,
token::{Semi, Type, Unsafe},
Attribute, Ident, Result, Visibility,
punctuated::Punctuated,
Attribute, Ident, Result, Token, Type, Visibility, WhereClause,
};

/// Type Declaration
pub struct TypeDeclaration {
/// Attributes
attrs: Vec<Attribute>,

/// Visibility
vis: Visibility,

/// Unsafety
unsafety: Option<Token![unsafe]>,

/// Identifier
ident: Ident,
}

impl Parse for TypeDeclaration {
#[inline]
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let vis = Visibility::parse(input)?;
let unsafety = Option::<Token![unsafe]>::parse(input)?;
<Token![type]>::parse(input)?;
let ident = Ident::parse(input)?;
Ok(Self {
attrs,
vis,
unsafety,
ident,
})
}
}

/// Single Component Implementation
pub struct SingleComponentImpl {
///
ident: Ident,

///
body: Type,

///
where_clause: WhereClause,
}

impl Parse for SingleComponentImpl {
#[inline]
fn parse(input: ParseStream) -> Result<Self> {
todo!()
}
}

/// Component Implementation
pub struct ComponentImpl {
/// Outer Generics
outer_generics: Vec<Ident>,

/// Identifier
ident: Ident,

/// Inner Generics
inner_generics: Vec<Ident>,

/// Components
components: Punctuated<SingleComponentImpl, Token![;]>,
}

impl Parse for ComponentImpl {
#[inline]
fn parse(input: ParseStream) -> Result<Self> {
<Token![impl]>::parse(input)?;
let mut outer_generics = vec![];
if Option::<Token![<]>::parse(input)?.is_some() {
outer_generics.push(Ident::parse(input)?);
loop {
let lookahead = input.lookahead1();
if lookahead.peek(Token![,]) {
<Token![,]>::parse(input)?;
outer_generics.push(Ident::parse(input)?);
} else if lookahead.peek(Token![>]) {
<Token![>]>::parse(input)?;
break;
} else {
return Err(lookahead.error());
}
}
}
let ident = Ident::parse(input)?;
let mut inner_generics = vec![];
if !outer_generics.is_empty() {
<Token![<]>::parse(input)?;
loop {
let lookahead = input.lookahead1();
if lookahead.peek(Token![,]) {
<Token![,]>::parse(input)?;
inner_generics.push(Ident::parse(input)?);
} else if lookahead.peek(Token![>]) {
<Token![>]>::parse(input)?;
break;
} else {
return Err(lookahead.error());
}
}
}
let content;
braced!(content in input);
let components = content.parse_terminated(SingleComponentImpl::parse)?;
Ok(Self {
outer_generics,
ident,
inner_generics,
components,
})
}
}

/// Component Macro Declaration
pub enum Component {
/// Basic Type Component
Type(TypeDeclaration),

/// Extension Component
Extension {
/// Base Declaration
declaration: TypeDeclaration,

/// Type Extensions
extensions: Vec<Ident>,
},

/// Component Implementation
Impl(ComponentImpl),
}

impl Parse for Component {
#[inline]
fn parse(input: ParseStream) -> Result<Self> {
let lookahead = input.lookahead1();
if lookahead.peek(Token![impl]) {
Ok(Self::Impl(ComponentImpl::parse(input)?))
} else {
let declaration = TypeDeclaration::parse(input)?;
if Option::<Token![:]>::parse(input)?.is_some() {
let mut extensions = vec![];
extensions.push(Ident::parse(input)?);
loop {
let lookahead = input.lookahead1();
if lookahead.peek(Token![+]) {
<Token![+]>::parse(input)?;
extensions.push(Ident::parse(input)?);
} else if lookahead.peek(Token![;]) {
<Token![;]>::parse(input)?;
break;
} else {
return Err(lookahead.error());
}
}
Ok(Self::Extension {
declaration,
extensions,
})
} else {
<Token![;]>::parse(input)?;
Ok(Self::Type(declaration))
}
}
}
}

/// Component Declaration
pub struct Declaration {
/// Attributes
Expand All @@ -18,46 +188,64 @@ pub struct Declaration {
vis: Visibility,

/// Unsafety
unsafety: Option<Unsafe>,
unsafety: Option<Token![unsafe]>,

/// Identifier
ident: Ident,

/// Extension Identifiers
extensions: Vec<Ident>,
}

impl Parse for Declaration {
#[inline]
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let vis = Visibility::parse(input)?;
let unsafety = Option::<Unsafe>::parse(input)?;
let unsafety = Option::<Token![unsafe]>::parse(input)?;
Type::parse(input)?;
let ident = Ident::parse(input)?;
Semi::parse(input)?;
let mut extensions = vec![];
if Option::<Token![:]>::parse(input)?.is_some() {
extensions.push(Ident::parse(input)?);
loop {
let lookahead = input.lookahead1();
if lookahead.peek(Token![+]) {
<Token![+]>::parse(input)?;
extensions.push(Ident::parse(input)?);
} else if lookahead.peek(Token![;]) {
break;
} else {
return Err(lookahead.error());
}
}
}
<Token![;]>::parse(input)?;
Ok(Self {
attrs,
vis,
unsafety,
ident,
extensions,
})
}
}

/// Transforms `args` and `input` according to the macro definition.
/// Transforms a `declaration` component that has no extensions into the `trait` implementation.
#[inline]
pub fn transform(args: TokenStream, input: TokenStream) -> TokenStream {
let _ = args;
let Declaration {
fn transform_type(declaration: TypeDeclaration) -> TokenStream {
let TypeDeclaration {
attrs,
vis,
unsafety,
ident,
} = parse_macro_input!(input as Declaration);
} = declaration;
let trait_ident = format_ident!("{}Type", ident);
let associated_type_doc = "Component Type";
let type_alias_doc = format!(
"[`{ident}`]({trait_ident}::{ident}) Type Alias for the [`{trait_ident}`] Component",
);
TokenStream::from(quote!(
quote!(
#(#attrs)*
#vis #unsafety trait #trait_ident {
#[doc = #associated_type_doc]
Expand All @@ -77,5 +265,75 @@ pub fn transform(args: TokenStream, input: TokenStream) -> TokenStream {
}
#[doc = #type_alias_doc]
#vis type #ident<T> = <T as #trait_ident>::#ident;
)
.into()
}

/// Transforms a `declaration` component with `extensions` into the `trait` implementation.
#[inline]
fn transform_extension(declaration: TypeDeclaration, extensions: Vec<Ident>) -> TokenStream {
let TypeDeclaration {
attrs,
vis,
unsafety,
ident,
} = declaration;
let trait_ident = format_ident!("{}Types", ident);
let extensions = extensions
.into_iter()
.map(|e| format_ident!("{}Type", e))
.collect::<Vec<_>>();
quote!(
#(#attrs)*
#vis #unsafety trait #trait_ident: #(#extensions)+* {}
impl<T> #trait_ident for T
where
T: #(#extensions)+*,
{
}
)
.into()
}

///
#[inline]
fn transform_impl(implementation: ComponentImpl) -> TokenStream {
let ComponentImpl {
outer_generics,
ident,
inner_generics,
components,
} = implementation;

/*
TokenStream::from(
components
.into_iter()
.map(|component| quote!())
.collect::<TokenStream2>(),
)
*/

/*
TokenStream::from(quote!(
#(
impl<#(#outer_generics),*>
)
))
*/
todo!()
}

/// Transforms `args` and `input` according to the macro definition.
#[inline]
pub fn transform(args: TokenStream, input: TokenStream) -> TokenStream {
let _ = args;
match parse_macro_input!(input as Component) {
Component::Type(declaration) => transform_type(declaration),
Component::Extension {
declaration,
extensions,
} => transform_extension(declaration, extensions),
Component::Impl(implementation) => transform_impl(implementation),
}
}