Răsfoiți Sursa

improve: add mod in 'dhke' for 'mint' and 'wallet'

thesimplekid 1 an în urmă
părinte
comite
a1eae5f76c
3 a modificat fișierele cu 232 adăugiri și 207 ștergeri
  1. 7 10
      crates/cashu-sdk/src/client/mod.rs
  2. 224 196
      crates/cashu/src/dhke.rs
  3. 1 1
      crates/cashu/src/lib.rs

+ 7 - 10
crates/cashu-sdk/src/client/mod.rs

@@ -1,19 +1,16 @@
 //! Client to connet to mint
 
 use async_trait::async_trait;
-use cashu::nuts::nut00::wallet::BlindedMessages;
-use cashu::nuts::nut00::{BlindedMessage, Proof};
-use cashu::nuts::nut01::Keys;
-use cashu::nuts::nut03::RequestMintResponse;
-use cashu::nuts::nut04::PostMintResponse;
-use cashu::nuts::nut05::CheckFeesResponse;
-use cashu::nuts::nut06::{SplitRequest, SplitResponse};
+#[cfg(feature = "mint")]
+use cashu::nuts::nut00;
 #[cfg(feature = "nut07")]
-use cashu::nuts::nut07::CheckSpendableResponse;
-use cashu::nuts::nut08::MeltResponse;
+use cashu::nuts::CheckSpendableResponse;
 #[cfg(feature = "nut09")]
 use cashu::nuts::MintInfo;
-use cashu::nuts::*;
+use cashu::nuts::{
+    BlindedMessage, BlindedMessages, CheckFeesResponse, Keys, KeysetResponse, MeltResponse,
+    PostMintResponse, Proof, RequestMintResponse, SplitRequest, SplitResponse,
+};
 use cashu::{utils, Amount};
 use serde::{Deserialize, Serialize};
 use thiserror::Error;

+ 224 - 196
crates/cashu/src/dhke.rs

@@ -1,20 +1,10 @@
 //! Diffie-Hellmann key exchange
 
-use std::ops::Mul;
-
 use bitcoin::hashes::{sha256, Hash};
+#[cfg(feature = "mint")]
+pub use mint::{sign_message, verify_message};
 #[cfg(feature = "wallet")]
-use k256::ProjectivePoint;
-use k256::{Scalar, SecretKey};
-
-use crate::error;
-#[cfg(feature = "wallet")]
-use crate::nuts::nut01::{Keys, PublicKey};
-#[cfg(feature = "wallet")]
-use crate::nuts::*;
-#[cfg(feature = "wallet")]
-use crate::nuts::{BlindedSignature, Proof, Proofs};
-use crate::secret::Secret;
+pub use wallet::{blind_message, construct_proofs, unblind_message};
 
 fn hash_to_curve(message: &[u8]) -> k256::PublicKey {
     let mut msg_to_hash = message.to_vec();
@@ -35,105 +25,121 @@ fn hash_to_curve(message: &[u8]) -> k256::PublicKey {
 }
 
 #[cfg(feature = "wallet")]
-/// Blind Message Alice Step one
-pub fn blind_message(
-    secret: &[u8],
-    blinding_factor: Option<SecretKey>,
-) -> Result<(PublicKey, SecretKey), error::wallet::Error> {
-    let y = hash_to_curve(secret);
-
-    let r: SecretKey = match blinding_factor {
-        Some(sec_key) => sec_key,
-        None => SecretKey::random(&mut rand::thread_rng()),
-    };
+mod wallet {
+    use std::ops::Mul;
+
+    use k256::{ProjectivePoint, Scalar, SecretKey};
+
+    use super::hash_to_curve;
+    use crate::error;
+    use crate::nuts::{BlindedSignature, Keys, Proof, Proofs, PublicKey, *};
+    use crate::secret::Secret;
+    /// Blind Message Alice Step one
+    pub fn blind_message(
+        secret: &[u8],
+        blinding_factor: Option<SecretKey>,
+    ) -> Result<(PublicKey, SecretKey), error::wallet::Error> {
+        let y = hash_to_curve(secret);
+
+        let r: SecretKey = match blinding_factor {
+            Some(sec_key) => sec_key,
+            None => SecretKey::random(&mut rand::thread_rng()),
+        };
 
-    let b = ProjectivePoint::from(y) + ProjectivePoint::from(&r.public_key());
+        let b = ProjectivePoint::from(y) + ProjectivePoint::from(&r.public_key());
 
-    Ok((k256::PublicKey::try_from(b)?.into(), r))
-}
-
-#[cfg(feature = "wallet")]
-/// Unblind Message (Alice Step 3)
-pub fn unblind_message(
-    // C_
-    blinded_key: PublicKey,
-    r: SecretKey,
-    // A
-    mint_pubkey: PublicKey,
-) -> Result<PublicKey, error::wallet::Error> {
-    // C
-    // Unblinded message
-    let c = ProjectivePoint::from(Into::<k256::PublicKey>::into(blinded_key).as_affine())
-        - Into::<k256::PublicKey>::into(mint_pubkey)
-            .as_affine()
-            .mul(Scalar::from(r.as_scalar_primitive()));
-
-    Ok(k256::PublicKey::try_from(c)?.into())
-}
+        Ok((k256::PublicKey::try_from(b)?.into(), r))
+    }
 
-#[cfg(feature = "wallet")]
-/// Construct Proof
-pub fn construct_proofs(
-    promises: Vec<BlindedSignature>,
-    rs: Vec<nut01::SecretKey>,
-    secrets: Vec<Secret>,
-    keys: &Keys,
-) -> Result<Proofs, error::wallet::Error> {
-    let mut proofs = vec![];
-    for (i, promise) in promises.into_iter().enumerate() {
-        let blinded_c = promise.c;
-        let a: PublicKey = keys
-            .amount_key(promise.amount)
-            .ok_or(error::wallet::Error::CustomError(
-                "Could not get proofs".to_string(),
-            ))?
-            .to_owned();
-
-        let unblinded_signature = unblind_message(blinded_c, rs[i].clone().into(), a)?;
-
-        let proof = Proof {
-            id: Some(promise.id),
-            amount: promise.amount,
-            secret: secrets[i].clone(),
-            c: unblinded_signature,
-        };
+    /// Unblind Message (Alice Step 3)
+    pub fn unblind_message(
+        // C_
+        blinded_key: PublicKey,
+        r: SecretKey,
+        // A
+        mint_pubkey: PublicKey,
+    ) -> Result<PublicKey, error::wallet::Error> {
+        // C
+        // Unblinded message
+        let c = ProjectivePoint::from(Into::<k256::PublicKey>::into(blinded_key).as_affine())
+            - Into::<k256::PublicKey>::into(mint_pubkey)
+                .as_affine()
+                .mul(Scalar::from(r.as_scalar_primitive()));
 
-        proofs.push(proof);
+        Ok(k256::PublicKey::try_from(c)?.into())
     }
 
-    Ok(proofs)
-}
+    /// Construct Proof
+    pub fn construct_proofs(
+        promises: Vec<BlindedSignature>,
+        rs: Vec<nut01::SecretKey>,
+        secrets: Vec<Secret>,
+        keys: &Keys,
+    ) -> Result<Proofs, error::wallet::Error> {
+        let mut proofs = vec![];
+        for (i, promise) in promises.into_iter().enumerate() {
+            let blinded_c = promise.c;
+            let a: PublicKey = keys
+                .amount_key(promise.amount)
+                .ok_or(error::wallet::Error::CustomError(
+                    "Could not get proofs".to_string(),
+                ))?
+                .to_owned();
+
+            let unblinded_signature = unblind_message(blinded_c, rs[i].clone().into(), a)?;
+
+            let proof = Proof {
+                id: Some(promise.id),
+                amount: promise.amount,
+                secret: secrets[i].clone(),
+                c: unblinded_signature,
+            };
+
+            proofs.push(proof);
+        }
 
-#[cfg(feature = "mint")]
-/// Sign Blinded Message (Step2 bob)
-pub fn sign_message(
-    a: SecretKey,
-    blinded_message: k256::PublicKey,
-) -> Result<k256::PublicKey, error::mint::Error> {
-    Ok(k256::PublicKey::try_from(
-        blinded_message
-            .as_affine()
-            .mul(Scalar::from(a.as_scalar_primitive())),
-    )?)
+        Ok(proofs)
+    }
 }
 
 #[cfg(feature = "mint")]
-/// Verify Message
-pub fn verify_message(
-    a: SecretKey,
-    unblinded_message: k256::PublicKey,
-    msg: &Secret,
-) -> Result<(), error::mint::Error> {
-    // Y
-    let y = hash_to_curve(msg.as_bytes());
-
-    if unblinded_message
-        == k256::PublicKey::try_from(*y.as_affine() * Scalar::from(a.as_scalar_primitive()))?
-    {
-        return Ok(());
+mod mint {
+    use std::ops::Mul;
+
+    use k256::{Scalar, SecretKey};
+
+    use super::hash_to_curve;
+    use crate::error;
+    use crate::secret::Secret;
+    /// Sign Blinded Message (Step2 bob)
+    pub fn sign_message(
+        a: SecretKey,
+        blinded_message: k256::PublicKey,
+    ) -> Result<k256::PublicKey, error::mint::Error> {
+        Ok(k256::PublicKey::try_from(
+            blinded_message
+                .as_affine()
+                .mul(Scalar::from(a.as_scalar_primitive())),
+        )?)
     }
 
-    Err(error::mint::Error::TokenNotVerifed)
+    /// Verify Message
+    pub fn verify_message(
+        a: SecretKey,
+        unblinded_message: k256::PublicKey,
+        msg: &Secret,
+    ) -> Result<(), error::mint::Error> {
+        // Y
+        let y = hash_to_curve(msg.as_bytes());
+
+        if unblinded_message
+            == k256::PublicKey::try_from(*y.as_affine() * Scalar::from(a.as_scalar_primitive()))?
+        {
+            return Ok(());
+        }
+
+        Err(error::mint::Error::TokenNotVerifed)
+    }
 }
 
 #[cfg(test)]
@@ -143,129 +149,151 @@ mod tests {
 
     use super::*;
 
-    #[test]
-    fn test_hash_to_curve() {
-        let secret = "0000000000000000000000000000000000000000000000000000000000000000";
-        let sec_hex = decode(secret).unwrap();
-
-        let y = hash_to_curve(&sec_hex);
-        let expected_y = k256::PublicKey::from_sec1_bytes(
-            &hex::decode("0266687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925")
-                .unwrap(),
-        )
-        .unwrap();
-        assert_eq!(y, expected_y);
-
-        let secret = "0000000000000000000000000000000000000000000000000000000000000001";
-        let sec_hex = decode(secret).unwrap();
-        let y = hash_to_curve(&sec_hex);
-        let expected_y = k256::PublicKey::from_sec1_bytes(
-            &hex::decode("02ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5")
-                .unwrap(),
-        )
-        .unwrap();
-        assert_eq!(y, expected_y);
-    }
+    #[cfg(feature = "wallet")]
+    mod wallet_tests {
+        use k256::SecretKey;
 
-    #[test]
-    fn test_blind_message() {
-        let message = "test_message";
-        let sec = SecretKey::new(ScalarPrimitive::ONE);
+        use super::*;
+        use crate::nuts::PublicKey;
 
-        let (b, r) = blind_message(message.as_bytes(), Some(sec.clone())).unwrap();
+        #[test]
+        fn test_hash_to_curve() {
+            let secret = "0000000000000000000000000000000000000000000000000000000000000000";
+            let sec_hex = decode(secret).unwrap();
 
-        assert_eq!(
-            b,
-            k256::PublicKey::from_sec1_bytes(
-                &hex::decode("02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2")
-                    .unwrap()
+            let y = hash_to_curve(&sec_hex);
+            let expected_y = k256::PublicKey::from_sec1_bytes(
+                &hex::decode("0266687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925")
+                    .unwrap(),
             )
-            .unwrap()
-            .into()
-        );
-
-        assert_eq!(r, sec);
-    }
+            .unwrap();
+            assert_eq!(y, expected_y);
+
+            let secret = "0000000000000000000000000000000000000000000000000000000000000001";
+            let sec_hex = decode(secret).unwrap();
+            let y = hash_to_curve(&sec_hex);
+            let expected_y = k256::PublicKey::from_sec1_bytes(
+                &hex::decode("02ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5")
+                    .unwrap(),
+            )
+            .unwrap();
+            assert_eq!(y, expected_y);
+        }
 
-    #[test]
-    fn test_sign_message() {
-        let message = "test_message";
-        let sec = SecretKey::new(ScalarPrimitive::ONE);
+        #[test]
+        fn test_blind_message() {
+            let message = "test_message";
+            let sec = SecretKey::new(ScalarPrimitive::ONE);
 
-        let (blinded_message, _r) = blind_message(message.as_bytes(), Some(sec)).unwrap();
+            let (b, r) = blind_message(message.as_bytes(), Some(sec.clone())).unwrap();
 
-        // A
-        let bob_sec = SecretKey::new(ScalarPrimitive::ONE);
+            assert_eq!(
+                b,
+                k256::PublicKey::from_sec1_bytes(
+                    &hex::decode(
+                        "02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2"
+                    )
+                    .unwrap()
+                )
+                .unwrap()
+                .into()
+            );
 
-        // C_
-        let signed = sign_message(bob_sec, blinded_message.into()).unwrap();
+            assert_eq!(r, sec);
+        }
 
-        assert_eq!(
-            signed,
-            k256::PublicKey::from_sec1_bytes(
+        #[test]
+        fn test_unblind_message() {
+            let blinded_key = k256::PublicKey::from_sec1_bytes(
                 &hex::decode("02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2")
-                    .unwrap()
+                    .unwrap(),
+            )
+            .unwrap();
+
+            let r = SecretKey::new(ScalarPrimitive::ONE);
+            let a = k256::PublicKey::from_sec1_bytes(
+                &hex::decode("020000000000000000000000000000000000000000000000000000000000000001")
+                    .unwrap(),
             )
-            .unwrap()
-        );
+            .unwrap();
+
+            let unblinded = unblind_message(blinded_key.into(), r, a.into()).unwrap();
+
+            assert_eq!(
+                Into::<PublicKey>::into(
+                    k256::PublicKey::from_sec1_bytes(
+                        &hex::decode(
+                            "03c724d7e6a5443b39ac8acf11f40420adc4f99a02e7cc1b57703d9391f6d129cd"
+                        )
+                        .unwrap()
+                    )
+                    .unwrap()
+                ),
+                unblinded
+            );
+        }
     }
 
-    #[test]
-    fn test_unblind_message() {
-        let blinded_key = k256::PublicKey::from_sec1_bytes(
-            &hex::decode("02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2")
-                .unwrap(),
-        )
-        .unwrap();
-
-        let r = SecretKey::new(ScalarPrimitive::ONE);
-        let a = k256::PublicKey::from_sec1_bytes(
-            &hex::decode("020000000000000000000000000000000000000000000000000000000000000001")
-                .unwrap(),
-        )
-        .unwrap();
-
-        let unblinded = unblind_message(blinded_key.into(), r, a.into()).unwrap();
-
-        assert_eq!(
-            Into::<PublicKey>::into(
+    #[cfg(feature = "mint")]
+    mod mint_test {
+
+        use k256::SecretKey;
+
+        use super::{hash_to_curve, *};
+        use crate::secret::Secret;
+
+        #[test]
+        fn test_sign_message() {
+            use super::*;
+            let message = "test_message";
+            let sec = SecretKey::new(ScalarPrimitive::ONE);
+
+            let (blinded_message, _r) = blind_message(message.as_bytes(), Some(sec)).unwrap();
+
+            // A
+            let bob_sec = SecretKey::new(ScalarPrimitive::ONE);
+
+            // C_
+            let signed = sign_message(bob_sec, blinded_message.into()).unwrap();
+
+            assert_eq!(
+                signed,
                 k256::PublicKey::from_sec1_bytes(
                     &hex::decode(
-                        "03c724d7e6a5443b39ac8acf11f40420adc4f99a02e7cc1b57703d9391f6d129cd"
+                        "02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2"
                     )
                     .unwrap()
                 )
                 .unwrap()
-            ),
-            unblinded
-        );
-    }
+            );
+        }
 
-    #[ignore]
-    #[test]
-    fn test_blinded_dhke() {
-        // a
-        let bob_sec = SecretKey::random(&mut rand::thread_rng());
+        #[ignore]
+        #[test]
+        fn test_blinded_dhke() {
+            // a
+            let bob_sec = SecretKey::random(&mut rand::thread_rng());
 
-        // A
-        let bob_pub = bob_sec.public_key();
+            // A
+            let bob_pub = bob_sec.public_key();
 
-        // let alice_sec = SecretKey::random(&mut rand::thread_rng());
+            // let alice_sec = SecretKey::random(&mut rand::thread_rng());
 
-        let x = Secret::new();
+            let x = Secret::new();
 
-        // Y
-        let y = hash_to_curve(x.as_bytes());
+            // Y
+            let y = hash_to_curve(x.as_bytes());
 
-        // B_
-        let blinded = blind_message(&y.to_sec1_bytes(), None).unwrap();
+            // B_
+            let blinded = blind_message(&y.to_sec1_bytes(), None).unwrap();
 
-        // C_
-        let signed = sign_message(bob_sec.clone(), blinded.0.into()).unwrap();
+            // C_
+            let signed = sign_message(bob_sec.clone(), blinded.0.into()).unwrap();
 
-        // C
-        let c = unblind_message(signed.into(), blinded.1, bob_pub.into()).unwrap();
+            // C
+            let c = unblind_message(signed.into(), blinded.1, bob_pub.into()).unwrap();
 
-        assert!(verify_message(bob_sec, c.into(), &x).is_ok());
+            assert!(verify_message(bob_sec, c.into(), &x).is_ok());
+        }
     }
 }

+ 1 - 1
crates/cashu/src/lib.rs

@@ -1,5 +1,5 @@
 pub mod amount;
-#[cfg(feature = "wallet")]
+#[cfg(any(feature = "wallet", feature = "mint"))]
 pub mod dhke;
 pub mod error;
 pub mod nuts;