| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- /* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2023 Dyne.org foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- use darkfi::{crypto::Proof, Result, VerifyFailed::ProofVerifyFailed};
- use darkfi_sdk::{
- crypto::{
- schnorr::{SchnorrPublic, Signature},
- PublicKey,
- },
- pasta::pallas,
- tx::ContractCall,
- };
- use darkfi_serial::Encodable;
- use log::debug;
- use crate::{
- contract::{dao, example, money},
- note::EncryptedNote2,
- schema::WalletCache,
- util::{sign, StateRegistry, ZkContractInfo, ZkContractTable},
- };
- macro_rules! zip {
- ($x: expr) => ($x);
- ($x: expr, $($y: expr), +) => (
- $x.iter().zip(
- zip!($($y), +))
- )
- }
- pub struct Transaction {
- pub calls: Vec<ContractCall>,
- pub proofs: Vec<Vec<Proof>>,
- pub signatures: Vec<Vec<Signature>>,
- }
- impl Transaction {
- /// Verify ZK contracts for the entire tx
- /// In real code, we could parallelize this for loop
- /// TODO: fix use of unwrap with Result type stuff
- pub fn zk_verify(
- &self,
- zk_bins: &ZkContractTable,
- zkpub_table: &Vec<Vec<(String, Vec<pallas::Base>)>>,
- ) -> Result<()> {
- assert_eq!(
- self.calls.len(),
- self.proofs.len(),
- "calls.len()={} and proofs.len()={} do not match",
- self.calls.len(),
- self.proofs.len()
- );
- assert_eq!(
- self.calls.len(),
- zkpub_table.len(),
- "calls.len()={} and zkpub_table.len()={} do not match",
- self.calls.len(),
- zkpub_table.len()
- );
- for (call, (proofs, pubvals)) in zip!(self.calls, self.proofs, zkpub_table) {
- assert_eq!(
- proofs.len(),
- pubvals.len(),
- "proofs.len()={} and pubvals.len()={} do not match",
- proofs.len(),
- pubvals.len()
- );
- for (i, (proof, (key, public_vals))) in proofs.iter().zip(pubvals.iter()).enumerate() {
- match zk_bins.lookup(key).unwrap() {
- ZkContractInfo::Binary(info) => {
- let verifying_key = &info.verifying_key;
- let verify_result = proof.verify(verifying_key, public_vals);
- if verify_result.is_err() {
- return Err(ProofVerifyFailed(key.to_string()).into())
- }
- //assert!(verify_result.is_ok(), "verify proof[{}]='{}' failed", i, key);
- }
- ZkContractInfo::Native(info) => {
- let verifying_key = &info.verifying_key;
- let verify_result = proof.verify(verifying_key, public_vals);
- if verify_result.is_err() {
- return Err(ProofVerifyFailed(key.to_string()).into())
- }
- //assert!(verify_result.is_ok(), "verify proof[{}]='{}' failed", i, key);
- }
- };
- debug!(target: "demo", "zk_verify({}) passed [i={}]", key, i);
- }
- }
- Ok(())
- }
- pub fn verify_sigs(&self, sigpub_table: &Vec<Vec<pallas::Point>>) -> Result<()> {
- let mut tx_data = Vec::new();
- self.calls.encode(&mut tx_data)?;
- self.proofs.encode(&mut tx_data)?;
- // TODO: Hash it and use the hash as the signing data
- // let sighash = ...
- for (i, (signatures, signature_public_keys)) in
- self.signatures.iter().zip(sigpub_table.iter()).enumerate()
- {
- for (signature_pub_key, signature) in signature_public_keys.iter().zip(signatures) {
- let signature_pub_key = PublicKey::from(*signature_pub_key);
- let verify_result = signature_pub_key.verify(&tx_data[..], &signature);
- assert!(verify_result, "verify sigs[{}] failed", i);
- }
- debug!(target: "demo", "verify_sigs({}) passed", i);
- }
- Ok(())
- }
- }
|