Browse Source

Add more commands

Cesar Rodas 1 month ago
parent
commit
18f7297d1b

+ 6 - 0
crates/cashu/src/secret.rs

@@ -44,6 +44,12 @@ impl Secret {
         Self(secret.into())
     }
 
+    /// Creates a new [`Secret`] from bytes
+    pub fn from_bytes(bytes: Vec<u8>) -> Self {
+        let secret = hex::encode(bytes);
+        Self(secret)
+    }
+
     /// Create secret value
     /// Generate a new random secret as the recommended 32 byte hex
     pub fn generate() -> Self {

+ 18 - 3
crates/cdk-signatory/src/proto/client.rs

@@ -5,7 +5,8 @@ use cdk_common::error::Error;
 use cdk_common::mint::MintKeySetInfo;
 use cdk_common::signatory::{KeysetIdentifier, Signatory};
 use cdk_common::{
-    BlindSignature, BlindedMessage, CurrencyUnit, Id, KeySet, KeysResponse, KeysetResponse, Proof,
+    dhke, BlindSignature, BlindedMessage, CurrencyUnit, Id, KeySet, KeysResponse, KeysetResponse,
+    Proof,
 };
 
 use crate::proto::signatory_client::SignatoryClient;
@@ -36,9 +37,23 @@ impl Signatory for RemoteSigner {
             .map_err(|e| Error::Custom(e.to_string()))?
     }
 
-    async fn verify_proof(&self, _proof: Proof) -> Result<(), Error> {
-        todo!()
+    async fn verify_proof(&self, request: Proof) -> Result<(), Error> {
+        let req: super::Proof = request.into();
+        let result: super::Success = self
+            .client
+            .clone()
+            .verify_proof(req)
+            .await
+            .map(|response| response.into_inner())
+            .map_err(|e| Error::Custom(e.to_string()))?;
+
+        if result.success {
+            Ok(())
+        } else {
+            Err(dhke::Error::TokenNotVerified)?
+        }
     }
+
     async fn keyset(&self, _keyset_id: Id) -> Result<Option<KeySet>, Error> {
         todo!()
     }

+ 57 - 0
crates/cdk-signatory/src/proto/mod.rs

@@ -1,3 +1,4 @@
+use cdk_common::secret::Secret;
 use cdk_common::{HTLCWitness, P2PKWitness};
 use tonic::Status;
 
@@ -6,6 +7,62 @@ tonic::include_proto!("cdk_signatory");
 pub mod client;
 pub mod server;
 
+impl From<cdk_common::ProofDleq> for ProofDleq {
+    fn from(value: cdk_common::ProofDleq) -> Self {
+        ProofDleq {
+            e: value.e.as_secret_bytes().to_vec(),
+            s: value.s.as_secret_bytes().to_vec(),
+            r: value.r.as_secret_bytes().to_vec(),
+        }
+    }
+}
+
+impl TryInto<cdk_common::ProofDleq> for ProofDleq {
+    type Error = Status;
+
+    fn try_into(self) -> Result<cdk_common::ProofDleq, Self::Error> {
+        Ok(cdk_common::ProofDleq {
+            e: cdk_common::SecretKey::from_slice(&self.e)
+                .map_err(|e| Status::from_error(Box::new(e)))?,
+            s: cdk_common::SecretKey::from_slice(&self.s)
+                .map_err(|e| Status::from_error(Box::new(e)))?,
+            r: cdk_common::SecretKey::from_slice(&self.r)
+                .map_err(|e| Status::from_error(Box::new(e)))?,
+        })
+    }
+}
+
+impl From<cdk_common::Proof> for Proof {
+    fn from(value: cdk_common::Proof) -> Self {
+        Proof {
+            amount: value.amount.into(),
+            keyset_id: value.keyset_id.to_string(),
+            secret: value.secret.to_bytes(),
+            c: value.c.to_bytes().to_vec(),
+            witness: value.witness.map(|w| w.into()),
+            dleq: value.dleq.map(|dleq| dleq.into()),
+        }
+    }
+}
+
+impl TryInto<cdk_common::Proof> for Proof {
+    type Error = Status;
+    fn try_into(self) -> Result<cdk_common::Proof, Self::Error> {
+        Ok(cdk_common::Proof {
+            amount: self.amount.into(),
+            keyset_id: self
+                .keyset_id
+                .parse()
+                .map_err(|e| Status::from_error(Box::new(e)))?,
+            secret: Secret::from_bytes(self.secret),
+            c: cdk_common::PublicKey::from_slice(&self.c)
+                .map_err(|e| Status::from_error(Box::new(e)))?,
+            witness: self.witness.map(|w| w.try_into()).transpose()?,
+            dleq: self.dleq.map(|x| x.try_into()).transpose()?,
+        })
+    }
+}
+
 impl From<cdk_common::BlindedMessage> for BlindedMessage {
     fn from(value: cdk_common::BlindedMessage) -> Self {
         BlindedMessage {

+ 17 - 0
crates/cdk-signatory/src/proto/server.rs

@@ -1,5 +1,6 @@
 use std::net::SocketAddr;
 
+use cdk_common::dhke;
 use cdk_common::signatory::Signatory as _;
 use tonic::transport::{Error, Server};
 use tonic::{Request, Response, Status};
@@ -23,6 +24,22 @@ impl signatory_server::Signatory for CdkSignatory {
             .map_err(|e| Status::from_error(Box::new(e)))?;
         Ok(Response::new(blind_signature.into()))
     }
+
+    async fn verify_proof(
+        &self,
+        request: Request<proto::Proof>,
+    ) -> Result<Response<proto::Success>, Status> {
+        println!("Got a request: {:?}", request);
+        let result = match self.0.verify_proof(request.into_inner().try_into()?).await {
+            Ok(()) => proto::Success { success: true },
+            Err(cdk_common::error::Error::DHKE(dhke::Error::TokenNotVerified)) => {
+                proto::Success { success: false }
+            }
+            Err(err) => return Err(Status::from_error(Box::new(err))),
+        };
+
+        Ok(Response::new(result))
+    }
 }
 
 /// Runs the signatory server

+ 20 - 0
crates/cdk-signatory/src/proto/signatory.proto

@@ -4,9 +4,29 @@ package cdk_signatory;
 
 service Signatory {
   rpc BlindSign (BlindedMessage) returns (BlindSignature);
+  rpc VerifyProof (Proof) returns (Success);
 }
 
 
+message Success {
+    bool success  = 1;
+}
+
+message Proof {
+    uint64 amount = 1;
+    string keyset_id = 2;
+    bytes secret = 3;
+    bytes C = 4;
+    optional Witness witness = 5;
+    optional ProofDLEQ dleq = 6;
+}
+
+message ProofDLEQ {
+    bytes e = 1;
+    bytes s = 2;
+    bytes r = 3;
+}
+
 message BlindSignature {
     uint64 amount = 1;
     string keyset_id = 2;