phoenix-circuits 0.8.0

Circuit definitions for Phoenix, a privacy-preserving ZKP-based transaction model
Documentation
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

//! Tests that verify proofs generated by the current circuit implementation
//! against the stored verifier data from the deployed transfer contract.
//!
//! These tests use the production CRS (Common Reference String) to ensure
//! compatibility with the on-chain verifier. The CRS is loaded from
//! `~/.dusk/rusk/devnet-piecrust.crs` if available, otherwise downloaded
//! from the network.

#![cfg(feature = "plonk")]

use rand::SeedableRng;
use rand::rngs::StdRng;

use dusk_plonk::prelude::{Compiler, Verifier};

use phoenix_circuits::TxCircuit;

mod common;
use common::*;

const VD_EXEC_1_2: &[u8] = include_bytes!(
    "assets/c8fed2bfcc0e0e64709586b56636fc1831be5f0227e533363e9a49b8fae5cd2f.vd"
);
const VD_EXEC_2_2: &[u8] = include_bytes!(
    "assets/98c9786a8cf36f19bcbdf97f4bc140fe402ae5f72cef3f60f24b96071c0faa73.vd"
);
const VD_EXEC_3_2: &[u8] = include_bytes!(
    "assets/1210b96327d25a0403be7b8e027cfe964370700b94ec7f47d22128ecbe7e9803.vd"
);
const VD_EXEC_4_2: &[u8] = include_bytes!(
    "assets/0095785bd378e5cd3c7427c03b6d4420966c03156bf045b556f22419252fc8bc.vd"
);

fn prove_and_verify_against_stored_vd<const I: usize>(
    input_notes_info: [InputNoteInfo<HEIGHT>; I],
    output_values: [u64; 2],
    stored_vd: &[u8],
) {
    let mut rng = StdRng::seed_from_u64(0xc0b);

    let (prover, _) = Compiler::compile::<TxCircuit<HEIGHT, I>>(&TP.pp, LABEL)
        .expect("failed to compile circuit");

    let output_notes_info = [
        create_output_note_information(
            &mut rng,
            output_values[0],
            TP.output_npk[0],
            TP.sender_blinder[0],
        ),
        create_output_note_information(
            &mut rng,
            output_values[1],
            TP.output_npk[1],
            TP.sender_blinder[1],
        ),
    ];

    let (proof, public_inputs) = prover
        .prove(
            &mut rng,
            &TxCircuit {
                input_notes_info,
                output_notes_info,
                payload_hash: TP.payload_hash,
                root: TP.root,
                deposit: TP.deposit,
                max_fee: TP.max_fee,
                sender_pk: TP.sender_pk,
                signatures: TP.signatures,
            },
        )
        .expect("failed to prove");

    let stored_verifier = Verifier::try_from_bytes(stored_vd)
        .expect("failed to deserialize stored verifier data");

    stored_verifier
        .verify(&proof, &public_inputs)
        .expect("proof failed to verify against stored verifier data");
}

#[test]
fn test_verifier_data_1_2() {
    let input_notes_info = [TP.input_notes_info[0].clone()];
    prove_and_verify_against_stored_vd(input_notes_info, [10, 5], VD_EXEC_1_2);
}

#[test]
fn test_verifier_data_2_2() {
    let input_notes_info = [
        TP.input_notes_info[0].clone(),
        TP.input_notes_info[1].clone(),
    ];
    prove_and_verify_against_stored_vd(input_notes_info, [35, 5], VD_EXEC_2_2);
}

#[test]
fn test_verifier_data_3_2() {
    let input_notes_info = [
        TP.input_notes_info[0].clone(),
        TP.input_notes_info[1].clone(),
        TP.input_notes_info[2].clone(),
    ];
    prove_and_verify_against_stored_vd(input_notes_info, [35, 30], VD_EXEC_3_2);
}

#[test]
fn test_verifier_data_4_2() {
    let input_notes_info = [
        TP.input_notes_info[0].clone(),
        TP.input_notes_info[1].clone(),
        TP.input_notes_info[2].clone(),
        TP.input_notes_info[3].clone(),
    ];
    prove_and_verify_against_stored_vd(input_notes_info, [60, 30], VD_EXEC_4_2);
}