浏览代码

prepare() and handle() now take a session id as an additional argument

Ian Goldberg 3 月之前
父节点
当前提交
2cc1771ea8
共有 5 个文件被更改,包括 59 次插入15 次删除
  1. 6 0
      README.md
  2. 27 6
      cmzcred_derive/src/lib.rs
  3. 1 1
      tests/basic.rs
  4. 5 2
      tests/submodule.rs
  5. 20 6
      tests/wallet.rs

+ 6 - 0
README.md

@@ -201,12 +201,17 @@ the following signature:
 ```rust
     pub fn prepare(
         rng: &mut impl RngCore,
+        session_id: &[u8],
         W: &Wallet,
         I: &Item,
         N: Wallet,
     ) -> Result<(Request, ClientState), CMZError>
 ```
 
+The `session_id` parameter is a session identifier.  It can be any
+sequence of bytes, but the value passed here to `prepare` and below to
+`handle` must be the same.
+
 You should treat the `Request` and `ClientState` structs as opaque, but
 they are currently not, and have `Debug` implemented, so if you wanted,
 you could look inside with `println!("{:#?}", request)` or similar.
@@ -222,6 +227,7 @@ the following signature:
 ```rust
     pub fn handle<F,A>(
         rng: &mut impl RngCore,
+        session_id: &[u8],
         request: Request,
         fill_creds: F,
         authorize: A,

+ 27 - 6
cmzcred_derive/src/lib.rs

@@ -638,6 +638,7 @@ fn protocol_macro(
     let B_ident = format_ident!("B_generator");
     let d_ident = format_ident!("d_privkey");
     let D_ident = format_ident!("D_pubkey");
+    let iss_proof_sessid_ident = format_ident!("iss_proof_sessid");
 
     prepare_code = quote! {
         #prepare_code
@@ -669,6 +670,10 @@ fn protocol_macro(
         iss_proof_const_points.push(B_ident.clone());
     }
 
+    // Stash the issue proof session id in prepare so that it can be
+    // used in finalize
+    clientstate_fields.push_bytevec(&iss_proof_sessid_ident);
+
     for iss_cred in proto_spec.issue_creds.iter() {
         // Are there any Hide or Joint attributes in this particular
         // credential to be issued?
@@ -1280,7 +1285,7 @@ fn protocol_macro(
             };
             // If prove returns Err here, there's an actual bug.
             let #iss_proof_ident = issuer_proof::prove(&iss_proof_params,
-                &iss_proof_witness, rng).unwrap();
+                &iss_proof_witness, &iss_proof_sessid, rng).unwrap();
         };
         let cli_iss_params_fields = iss_proof_pub_points
             .iter()
@@ -1292,7 +1297,7 @@ fn protocol_macro(
                 #(#cli_iss_params_fields,)*
             };
             if issuer_proof::verify(&iss_proof_params,
-                &reply.#iss_proof_ident).is_err() {
+                &reply.#iss_proof_ident, &self.iss_proof_sessid).is_err() {
                 return Err((CMZError::IssProofFailed, self));
             }
         };
@@ -1555,7 +1560,7 @@ fn protocol_macro(
         };
         // If prove returns Err here, there's an actual bug.
         let #cli_proof_ident = client_proof::prove(&cli_proof_params,
-            &cli_proof_witness, rng).unwrap();
+            &cli_proof_witness, &cli_proof_sessid, rng).unwrap();
     };
     let iss_cli_params_fields = cli_proof_pub_points
         .iter()
@@ -1568,7 +1573,7 @@ fn protocol_macro(
             #(#iss_cli_params_fields,)*
         };
         if client_proof::verify(&cli_proof_params,
-            &request.#cli_proof_ident).is_err() {
+            &request.#cli_proof_ident, &cli_proof_sessid).is_err() {
             return Err(CMZError::CliProofFailed);
         }
     };
@@ -1820,9 +1825,16 @@ fn protocol_macro(
         let csf = clientstate_fields.field_iter();
         quote! {
             pub fn prepare(rng: &mut (impl CryptoRng + RngCore),
+                session_id: &[u8],
                 #(#client_show_args)* #(#client_issue_args)* #client_params_arg)
                     -> Result<(Request, ClientState),CMZError> {
                 let bp = cmz_basepoints::<Point>();
+                let mut cli_proof_sessid: Vec<u8> = Vec::new();
+                cli_proof_sessid.extend(b"cli_");
+                cli_proof_sessid.extend(session_id);
+                let mut iss_proof_sessid: Vec<u8> = Vec::new();
+                iss_proof_sessid.extend(b"iss_");
+                iss_proof_sessid.extend(session_id);
                 #prepare_code
                 Ok((Request{#(#reqf,)*}, ClientState{#(#csf,)*}))
             }
@@ -1954,6 +1966,7 @@ fn protocol_macro(
 
         quote! {
             pub fn handle<F,A>(rng: &mut (impl CryptoRng + RngCore),
+                session_id: &[u8],
                 request: Request, fill_creds: F, authorize: A)
                 -> #rettype
             where
@@ -1963,6 +1976,12 @@ fn protocol_macro(
                     Result<(),CMZError>
             {
                 let bp = cmz_basepoints::<Point>();
+                let mut cli_proof_sessid: Vec<u8> = Vec::new();
+                cli_proof_sessid.extend(b"cli_");
+                cli_proof_sessid.extend(session_id);
+                let mut iss_proof_sessid: Vec<u8> = Vec::new();
+                iss_proof_sessid.extend(b"iss_");
+                iss_proof_sessid.extend(session_id);
                 #(#cred_decls)*
                 #handle_code_pre_fill
                 #fill_creds_assign fill_creds(#(#fill_creds_params)*)?;
@@ -2009,8 +2028,10 @@ fn protocol_macro(
 
         quote! {
             impl ClientState {
-                pub fn finalize(self, reply: Reply)
-                    -> #rettype {
+                pub fn finalize(
+                    self,
+                    reply: Reply,
+                ) -> #rettype {
                     let bp = cmz_basepoints::<Point>();
                     #(#cred_decls)*
                     #finalize_code

+ 1 - 1
tests/basic.rs

@@ -46,7 +46,7 @@ fn test_basic() {
     basic_cred.attr1 = Some(Scalar::ZERO);
     basic_cred.attr2 = Some(Scalar::ONE);
 
-    let (req, state) = basic_proto::prepare(&mut rng, &basic_cred).unwrap();
+    let (req, state) = basic_proto::prepare(&mut rng, b"test_basic", &basic_cred).unwrap();
     println!("{req:#?}");
     println!("{state:#?}");
 }

+ 5 - 2
tests/submodule.rs

@@ -41,10 +41,11 @@ pub mod submod {
         basic_iss.x = Some(Scalar::ZERO);
         basic_iss.y = Some(Scalar::ONE);
         basic_iss.z = Some(Scalar::ONE);
-        let (ireq, istate) = issue_proto::prepare(&mut rng, basic_iss).unwrap();
+        let (ireq, istate) = issue_proto::prepare(&mut rng, b"issue_proto", basic_iss).unwrap();
 
         let (ireply, _) = issue_proto::handle(
             &mut rng,
+            b"issue_proto",
             ireq,
             |N: &mut Basic| {
                 N.set_privkey(&privkey);
@@ -62,10 +63,12 @@ pub mod submod {
         basic_new.y = Some(2u128.into());
         basic_new.z = Some(3u128.into());
 
-        let (req, state) = basic_proto::prepare(&mut rng, &basic_cred, basic_new).unwrap();
+        let (req, state) =
+            basic_proto::prepare(&mut rng, b"basic_proto", &basic_cred, basic_new).unwrap();
 
         let (reply, _) = basic_proto::handle(
             &mut rng,
+            b"basic_proto",
             req,
             |A: &mut Basic, N: &mut Basic| {
                 A.set_privkey(&privkey);

+ 20 - 6
tests/wallet.rs

@@ -54,9 +54,11 @@ macro_rules! protos_def {
                 privkey: &CMZPrivkey<G>,
                 public: &CMZPubkey<G>,
             ) -> Result<Item, CMZError> {
-                let (request, state) = $item_issue::prepare(&mut *rng, Item::using_pubkey(public))?;
+                let (request, state) =
+                    $item_issue::prepare(&mut *rng, b"issue_item", Item::using_pubkey(public))?;
                 let (reply, _) = $item_issue::handle(
                     &mut *rng,
+                    b"issue_item",
                     request,
                     |I: &mut Item| {
                         I.set_privkey(privkey);
@@ -82,10 +84,14 @@ macro_rules! protos_def {
                 privkey: &CMZPrivkey<G>,
                 public: &CMZPubkey<G>,
             ) -> Result<Wallet, CMZError> {
-                let (request, state) =
-                    $wallet_issue::prepare(&mut *rng, Wallet::using_pubkey(public))?;
+                let (request, state) = $wallet_issue::prepare(
+                    &mut *rng,
+                    b"issue_wallet",
+                    Wallet::using_pubkey(public),
+                )?;
                 let (reply, _) = $wallet_issue::handle(
                     &mut *rng,
+                    b"issue_wallet",
                     request,
                     |W: &mut Wallet| {
                         W.set_privkey(privkey);
@@ -134,13 +140,14 @@ macro_rules! protos_def {
             let mut N = Wallet::using_pubkey(&wallet_pub);
             N.balance = Some(initial_wallet.balance.unwrap() - ebook_item.price.unwrap());
             let (request, state) =
-                $wallet_spend::prepare(&mut rng, &initial_wallet, &ebook_item, N)?;
+                $wallet_spend::prepare(&mut rng, b"test_wallet", &initial_wallet, &ebook_item, N)?;
             let reqbytes = request.as_bytes();
 
             // issuer actions
             let recvreq = $wallet_spend::Request::try_from(&reqbytes[..]).unwrap();
             let (reply, (_W_issuer, _I_issuer, _N_issuer)) = $wallet_spend::handle(
                 &mut rng,
+                b"test_wallet",
                 recvreq,
                 |W: &mut Wallet, I: &mut Item, N: &mut Wallet| {
                     W.set_privkey(&wallet_priv);
@@ -170,8 +177,14 @@ macro_rules! protos_def {
             N_fee.balance =
                 Some(W_issued.balance.unwrap() - album_item.price.unwrap() - params.fee);
 
-            let (request_fee, state_fee) =
-                $wallet_spend_with_fee::prepare(&mut rng, &W_issued, &album_item, N_fee, &params)?;
+            let (request_fee, state_fee) = $wallet_spend_with_fee::prepare(
+                &mut rng,
+                b"test_wallet_fee",
+                &W_issued,
+                &album_item,
+                N_fee,
+                &params,
+            )?;
             let reqbytes_fee = request_fee.as_bytes();
 
             // issuer actions
@@ -179,6 +192,7 @@ macro_rules! protos_def {
             let (reply_fee, (_W_fee_issuer, _I_fee_isser, _N_fee_issuer)) =
                 $wallet_spend_with_fee::handle(
                     &mut rng,
+                    b"test_wallet_fee",
                     recvreq_fee,
                     |W: &mut Wallet, I: &mut Item, N: &mut Wallet| {
                         W.set_privkey(&wallet_priv);