Selaa lähdekoodia

More code generation

Ian Goldberg 5 kuukautta sitten
vanhempi
commit
66c9c45a54
2 muutettua tiedostoa jossa 62 lisäystä ja 19 poistoa
  1. 60 19
      cmzcred_derive/src/lib.rs
  2. 2 0
      src/lib.rs

+ 60 - 19
cmzcred_derive/src/lib.rs

@@ -405,6 +405,7 @@ impl Parse for ProtoSpec {
 enum StructField {
     Scalar(Ident),
     Point(Ident),
+    EncPoint(Ident),
 }
 
 // Convenience functions to create StructField items
@@ -415,6 +416,9 @@ impl StructField {
     pub fn point(s: &str) -> Self {
         Self::Point(Ident::new(s, Span::call_site().into()))
     }
+    pub fn encpoint(s: &str) -> Self {
+        Self::EncPoint(Ident::new(s, Span::call_site().into()))
+    }
 }
 
 // A list of StructField items
@@ -430,11 +434,15 @@ impl StructFieldList {
     pub fn push_point(&mut self, s: &str) {
         self.fields.push(StructField::point(s));
     }
+    pub fn push_encpoint(&mut self, s: &str) {
+        self.fields.push(StructField::encpoint(s));
+    }
     /// Output an iterator consisting of the field names
     pub fn field_iter<'a>(&'a self) -> impl Iterator<Item = &'a Ident> {
         self.fields.iter().map(|f| match f {
             StructField::Scalar(id) => id,
             StructField::Point(id) => id,
+            StructField::EncPoint(id) => id,
         })
     }
     /// Output a ToTokens of the fields as they would appear in a struct
@@ -449,6 +457,10 @@ impl StructFieldList {
                 #[serde_as(as = "SerdePoint")]
                 pub #id: Point,
             },
+            StructField::EncPoint(id) => quote! {
+                #[serde_as(as = "(SerdePoint, SerdePoint)")]
+                pub #id: (Point, Point),
+            },
         });
         quote! { #(#decls)* }
     }
@@ -539,15 +551,52 @@ fn protocol_macro(
                 cred_hide_joint = true;
             }
 
-            /* For each Hide and Joint attribute (for CMZ): Compute an
-               exponential El Gamal encryption (of the attribute) E_attr =
-               (r_attr*B, attr*B + r_attr*D) for random r_attr.  Include E_attr
-               in the Request, and attr, r_attr, and E_attr in the CliProof.
-               Hide attributes will be passed into prepare on the client side;
-               Joint attributes (client contribution) will be generated randomly
-               by prepare on the client side, and (issuer contribution) by
-               handle on the issuer side.
-            */
+            if !use_muCMZ && (spec == IssueSpec::Hide || spec == IssueSpec::Joint) {
+                /* For each Hide and Joint attribute (for CMZ): Compute an
+                   exponential El Gamal encryption (of the attribute) E_attr =
+                   (r_attr*B, attr*B + r_attr*D) for random r_attr.  Include E_attr
+                   in the Request, attr in the ClientState, and attr,
+                   r_attr, and E_attr in the CliProof.  Hide attributes
+                   will be passed into prepare on the client side; Joint
+                   attributes (client contribution) will be generated
+                   randomly by prepare on the client side, and (issuer
+                   contribution) by handle on the issuer side.
+                */
+                let enc_attr = format_ident!("E_{}", scoped_attr);
+                let r_attr = format_ident!("r_{}", scoped_attr);
+                request_fields.push_encpoint(&enc_attr.to_string());
+                clientstate_fields.push_scalar(&scoped_attr.to_string());
+                if spec == IssueSpec::Hide {
+                    prepare_code = quote! {
+                        #prepare_code
+                        let #scoped_attr =
+                        #iss_cred_id.#attr.ok_or(CMZError::HideAttrMissing(#cred_str,
+                        #attr_str))?;
+                    };
+                } else {
+                    prepare_code = quote! {
+                        #prepare_code
+                        let #scoped_attr = <Scalar as ff::Field>::random(&mut *rng);
+                    };
+                    reply_fields.push_scalar(&scoped_attr.to_string());
+                    handle_code_pre_fill = quote! {
+                        #handle_code_pre_fill
+                        let #scoped_attr = <Scalar as ff::Field>::random(&mut *rng);
+                    };
+                    finalize_code = quote! {
+                        #finalize_code
+                        let #scoped_attr = self.#scoped_attr + reply.#scoped_attr;
+                        #iss_cred_id.#attr = Some(#scoped_attr);
+                    };
+                }
+                prepare_code = quote! {
+                    #prepare_code
+                    let #r_attr = <Scalar as ff::Field>::random(&mut *rng);
+                    let #enc_attr = (bp.mulB(&#r_attr),
+                        bp.mulB(&#scoped_attr) +
+                        #r_attr * D);
+                };
+            }
 
             /* For all Hide and Joint attributes of a single credential to be
                isued (for CMZ): the issuer chooses a random b, computes
@@ -611,9 +660,8 @@ fn protocol_macro(
                 }
             }
 
-            /* For each Set and Joint attribute: the issuer's value will be set
-              by fill_creds (for Set) or by handle (for Joint).  Include the
-              value in Reply.
+            /* For each Set attribute: the issuer's value will be set
+              by fill_creds.  Include the value in Reply.
             */
             if spec == IssueSpec::Set {
                 reply_fields.push_scalar(&scoped_attr.to_string());
@@ -629,13 +677,6 @@ fn protocol_macro(
                     #iss_cred_id.#attr = Some(#scoped_attr);
                 }
             }
-            if spec == IssueSpec::Joint {
-                reply_fields.push_scalar(&scoped_attr.to_string());
-                handle_code_post_auth = quote! {
-                    #handle_code_post_auth
-                    let #scoped_attr = <Scalar as ff::Field>::random(&mut *rng);
-                };
-            }
         }
         any_hide_joint |= cred_hide_joint;
     }

+ 2 - 0
src/lib.rs

@@ -382,6 +382,8 @@ macro_rules! CMZ {
 /// functions generated by the CMZProtocol family of macros
 #[derive(Error, Debug)]
 pub enum CMZError {
+    #[error("Hide attribute {1} of credential {0} was not passed to prepare")]
+    HideAttrMissing(&'static str, &'static str),
     #[error("Reveal attribute {1} of credential {0} was not passed to prepare")]
     RevealAttrMissing(&'static str, &'static str),
     #[error("Implicit attribute {1} of credential {0} was not passed to prepare")]