tx.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. use darkfi::{crypto::Proof, Result, VerifyFailed::ProofVerifyFailed};
  2. use darkfi_sdk::{
  3. crypto::{
  4. schnorr::{SchnorrPublic, Signature},
  5. PublicKey,
  6. },
  7. pasta::pallas,
  8. tx::ContractCall,
  9. };
  10. use log::debug;
  11. use crate::{
  12. contract::{dao, example, money},
  13. note::EncryptedNote2,
  14. schema::WalletCache,
  15. util::{sign, StateRegistry, ZkContractInfo, ZkContractTable},
  16. };
  17. macro_rules! zip {
  18. ($x: expr) => ($x);
  19. ($x: expr, $($y: expr), +) => (
  20. $x.iter().zip(
  21. zip!($($y), +))
  22. )
  23. }
  24. pub struct Transaction {
  25. pub calls: Vec<ContractCall>,
  26. pub proofs: Vec<Vec<Proof>>,
  27. pub signatures: Vec<Vec<Signature>>,
  28. }
  29. impl Transaction {
  30. /// Verify ZK contracts for the entire tx
  31. /// In real code, we could parallelize this for loop
  32. /// TODO: fix use of unwrap with Result type stuff
  33. pub fn zk_verify(
  34. &self,
  35. zk_bins: &ZkContractTable,
  36. zkpub_table: &Vec<Vec<(String, Vec<pallas::Base>)>>,
  37. ) -> Result<()> {
  38. assert_eq!(
  39. self.calls.len(),
  40. self.proofs.len(),
  41. "calls.len()={} and proofs.len()={} do not match",
  42. self.calls.len(),
  43. self.proofs.len()
  44. );
  45. assert_eq!(
  46. self.calls.len(),
  47. zkpub_table.len(),
  48. "calls.len()={} and zkpub_table.len()={} do not match",
  49. self.calls.len(),
  50. zkpub_table.len()
  51. );
  52. for (call, (proofs, pubvals)) in zip!(self.calls, self.proofs, zkpub_table) {
  53. assert_eq!(
  54. proofs.len(),
  55. pubvals.len(),
  56. "proofs.len()={} and pubvals.len()={} do not match",
  57. proofs.len(),
  58. pubvals.len()
  59. );
  60. for (i, (proof, (key, public_vals))) in proofs.iter().zip(pubvals.iter()).enumerate() {
  61. match zk_bins.lookup(key).unwrap() {
  62. ZkContractInfo::Binary(info) => {
  63. let verifying_key = &info.verifying_key;
  64. let verify_result = proof.verify(verifying_key, public_vals);
  65. if verify_result.is_err() {
  66. return Err(ProofVerifyFailed(key.to_string()).into())
  67. }
  68. //assert!(verify_result.is_ok(), "verify proof[{}]='{}' failed", i, key);
  69. }
  70. ZkContractInfo::Native(info) => {
  71. let verifying_key = &info.verifying_key;
  72. let verify_result = proof.verify(verifying_key, public_vals);
  73. if verify_result.is_err() {
  74. return Err(ProofVerifyFailed(key.to_string()).into())
  75. }
  76. //assert!(verify_result.is_ok(), "verify proof[{}]='{}' failed", i, key);
  77. }
  78. };
  79. debug!(target: "demo", "zk_verify({}) passed [i={}]", key, i);
  80. }
  81. }
  82. Ok(())
  83. }
  84. pub fn verify_sigs(&self, sigpub_table: &Vec<Vec<pallas::Point>>) -> Result<()> {
  85. //let mut tx_data = Vec::new();
  86. //self.calls.encode(&mut tx_data)?;
  87. //self.proofs.encode(&mut tx_data)?;
  88. // Hash it and use the hash as the signing data
  89. let mut unsigned_tx_data = vec![0xde, 0xad, 0xbe, 0xef];
  90. for (i, (signatures, signature_public_keys)) in
  91. self.signatures.iter().zip(sigpub_table.iter()).enumerate()
  92. {
  93. for (signature_pub_key, signature) in signature_public_keys.iter().zip(signatures) {
  94. let signature_pub_key = PublicKey::from(*signature_pub_key);
  95. let verify_result = signature_pub_key.verify(&unsigned_tx_data[..], &signature);
  96. assert!(verify_result, "verify sigs[{}] failed", i);
  97. }
  98. debug!(target: "demo", "verify_sigs({}) passed", i);
  99. }
  100. Ok(())
  101. }
  102. }