mod.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::collections::HashMap;
  19. use darkfi_sdk::{
  20. crypto::{
  21. schnorr::{SchnorrPublic, SchnorrSecret, Signature},
  22. PublicKey, SecretKey,
  23. },
  24. pasta::pallas,
  25. tx::ContractCall,
  26. };
  27. use darkfi_serial::{serialize, Encodable, SerialDecodable, SerialEncodable};
  28. use log::{debug, error};
  29. use rand::{CryptoRng, RngCore};
  30. use crate::{
  31. zk::{proof::VerifyingKey, Proof},
  32. Error, Result, VerifyFailed,
  33. };
  34. macro_rules! zip {
  35. ($x:expr) => ($x);
  36. ($x:expr, $($y:expr), +) => (
  37. $x.iter().zip(zip!($($y), +))
  38. )
  39. }
  40. // ANCHOR: transaction
  41. /// A Transaction contains an arbitrary number of `ContractCall` objects,
  42. /// along with corresponding ZK proofs and Schnorr signatures.
  43. #[derive(Debug, Clone, Eq, PartialEq, SerialEncodable, SerialDecodable)]
  44. pub struct Transaction {
  45. /// Calls executed in this transaction
  46. pub calls: Vec<ContractCall>,
  47. /// Attached ZK proofs
  48. pub proofs: Vec<Vec<Proof>>,
  49. /// Attached Schnorr signatures
  50. pub signatures: Vec<Vec<Signature>>,
  51. }
  52. // ANCHOR_END: transaction
  53. impl Transaction {
  54. /// Verify ZK proofs for the entire transaction.
  55. pub async fn verify_zkps(
  56. &self,
  57. verifying_keys: HashMap<[u8; 32], HashMap<String, VerifyingKey>>,
  58. zkp_table: Vec<Vec<(String, Vec<pallas::Base>)>>,
  59. ) -> Result<()> {
  60. // TODO: Are we sure we should assert here?
  61. assert_eq!(self.calls.len(), self.proofs.len());
  62. assert_eq!(self.calls.len(), zkp_table.len());
  63. for (call, (proofs, pubvals)) in zip!(self.calls, self.proofs, zkp_table) {
  64. assert_eq!(proofs.len(), pubvals.len());
  65. let Some(contract_map) = verifying_keys.get(&call.contract_id.to_bytes()) else {
  66. error!("Verifying keys not found for contract {}", call.contract_id);
  67. return Err(VerifyFailed::ProofVerifyFailed("VKs not found for contract".to_string()).into())
  68. };
  69. for (proof, (zk_ns, public_vals)) in proofs.iter().zip(pubvals.iter()) {
  70. if let Some(vk) = contract_map.get(zk_ns) {
  71. // We have a verifying key for this
  72. debug!("public inputs: {:#?}", public_vals);
  73. if let Err(e) = proof.verify(vk, public_vals) {
  74. error!(
  75. target: "",
  76. "Failed verifying {}::{} ZK proof: {:#?}",
  77. call.contract_id, zk_ns, e
  78. );
  79. return Err(VerifyFailed::ProofVerifyFailed(e.to_string()).into())
  80. }
  81. debug!("Successfully verified {}::{} ZK proof", call.contract_id, zk_ns);
  82. continue
  83. }
  84. let e = format!("{}:{} circuit VK nonexistent", call.contract_id, zk_ns);
  85. error!("{}", e);
  86. return Err(VerifyFailed::ProofVerifyFailed(e).into())
  87. }
  88. }
  89. Ok(())
  90. }
  91. /// Verify Schnorr signatures for the entire transaction.
  92. pub fn verify_sigs(&self, pub_table: Vec<Vec<PublicKey>>) -> Result<()> {
  93. let tx_data = self.encode_without_sigs()?;
  94. let data_hash = blake3::hash(&tx_data);
  95. debug!("tx.verify_sigs: data_hash: {:?}", data_hash.as_bytes());
  96. assert!(pub_table.len() == self.signatures.len());
  97. for (i, (sigs, pubkeys)) in self.signatures.iter().zip(pub_table.iter()).enumerate() {
  98. for (pubkey, signature) in pubkeys.iter().zip(sigs) {
  99. debug!("Verifying signature with public key: {}", pubkey);
  100. if !pubkey.verify(&data_hash.as_bytes()[..], signature) {
  101. error!("tx::verify_sigs[{}] failed to verify", i);
  102. return Err(Error::InvalidSignature)
  103. }
  104. }
  105. debug!("tx::verify_sigs[{}] passed", i);
  106. }
  107. Ok(())
  108. }
  109. /// Create Schnorr signatures for the entire transaction.
  110. pub fn create_sigs(
  111. &self,
  112. rng: &mut (impl CryptoRng + RngCore),
  113. secret_keys: &[SecretKey],
  114. ) -> Result<Vec<Signature>> {
  115. let tx_data = self.encode_without_sigs()?;
  116. let data_hash = blake3::hash(&tx_data);
  117. debug!("tx.create_sigs: data_hash: {:?}", data_hash.as_bytes());
  118. let mut sigs = vec![];
  119. for secret in secret_keys {
  120. debug!("Creating signature with public key: {}", PublicKey::from_secret(*secret));
  121. let signature = secret.sign(rng, &data_hash.as_bytes()[..]);
  122. sigs.push(signature);
  123. }
  124. Ok(sigs)
  125. }
  126. /// Encode the object into a byte vector for signing
  127. pub fn encode_without_sigs(&self) -> Result<Vec<u8>> {
  128. let mut buf = vec![];
  129. self.calls.encode(&mut buf)?;
  130. self.proofs.encode(&mut buf)?;
  131. Ok(buf)
  132. }
  133. /// Get the transaction hash
  134. pub fn hash(&self) -> blake3::Hash {
  135. blake3::hash(&serialize(self))
  136. }
  137. }