From c82c122bc244e22889ff35217fc0971643d22fbe Mon Sep 17 00:00:00 2001 From: Jules de Smit Date: Wed, 30 Sep 2020 10:37:58 +0200 Subject: [PATCH 1/2] Implement conversion from Note to StorageScalar This allows the Note to be stored in a PoseidonTree. --- src/note.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/note.rs b/src/note.rs index 0b4e1fe..bb28945 100644 --- a/src/note.rs +++ b/src/note.rs @@ -1,5 +1,6 @@ // Copyright (c) DUSK NETWORK. All rights reserved. -// Licensed under the MPL 2.0 license. See LICENSE file in the project root for details. +// Licensed under the MPL 2.0 license. See LICENSE file in the project root for +// details. use kelvin::{ByteHash, Content, Sink, Source}; use std::convert::TryFrom; @@ -13,6 +14,7 @@ use dusk_pki::{PublicSpendKey, SecretSpendKey, StealthAddress, ViewKey}; use dusk_plonk::jubjub::{dhke, GENERATOR_EXTENDED, GENERATOR_NUMS_EXTENDED}; use poseidon252::cipher::PoseidonCipher; use poseidon252::sponge::sponge::sponge_hash; +use poseidon252::StorageScalar; use crate::{ chunk_of, BlsScalar, Error, JubJubAffine, JubJubExtended, JubJubScalar, @@ -392,3 +394,15 @@ impl Content for Note { }) } } + +impl From<&Note> for StorageScalar { + fn from(value: &Note) -> Self { + StorageScalar(value.hash()) + } +} + +impl From for StorageScalar { + fn from(value: Note) -> Self { + (&value).into() + } +} From 29b5518487b14ff9e8a7cd1e224c837a8fcb3b19 Mon Sep 17 00:00:00 2001 From: Jules de Smit Date: Sat, 3 Oct 2020 12:27:36 +0200 Subject: [PATCH 2/2] Add test for note storage logic in a PoseidonTree --- Cargo.toml | 1 + tests/note_test.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 55c08d6..534d4cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ dusk-plonk = { version = "0.2.11", features = ["trace-print"] } [dev-dependencies] assert_matches = "1.3" +anyhow = "1.0.32" [profile.release] opt-level = 3 diff --git a/tests/note_test.rs b/tests/note_test.rs index 5af8da5..045fbe3 100644 --- a/tests/note_test.rs +++ b/tests/note_test.rs @@ -13,8 +13,15 @@ use phoenix_core::{Crossover, Error, Fee, Note, NoteType}; use std::io::{Read, Write}; use dusk_pki::{PublicSpendKey, SecretSpendKey}; +use dusk_plonk::bls12_381::Scalar as BlsScalar; use dusk_plonk::jubjub::Fr as JubJubScalar; +use dusk_plonk::prelude::*; +use kelvin::Blake2b; +use poseidon252::merkle_proof::merkle_opening_gadget; +use poseidon252::{PoseidonAnnotation, PoseidonTree}; + +use anyhow::Result; use assert_matches::*; #[test] @@ -199,3 +206,60 @@ fn transparent_from_fee_remainder_with_invalid_consumed() -> Result<(), Error> { Ok(()) } + +#[test] +fn note_tree_storage() -> Result<()> { + let ssk = SecretSpendKey::default(); + let psk = ssk.public_key(); + let value = 25; + + let note = Note::transparent(&psk, value); + + // Store the note in the tree + let mut tree = PoseidonTree::::new(4); + let idx = tree.push(note.into()).unwrap(); + + // Fetch the note from the tree + let branch = tree.poseidon_branch(idx).unwrap().unwrap(); + + // Now, let's see if we can make a valid merkle opening proof. + let pub_params = PublicParameters::setup(1 << 14, &mut rand::thread_rng())?; + let (ck, vk) = pub_params.trim(1 << 13)?; + + let mut prover = Prover::new(b"NoteTest"); + let hash = prover.mut_cs().add_input(note.hash()); + let root = merkle_opening_gadget( + prover.mut_cs(), + branch.clone(), + hash, + branch.root.clone(), + ); + prover.mut_cs().constrain_to_constant( + root, + BlsScalar::zero(), + -branch.root, + ); + + prover.preprocess(&ck).unwrap(); + let proof = prover.prove(&ck).unwrap(); + + let mut verifier = Verifier::new(b"NoteTest"); + let hash = verifier.mut_cs().add_input(note.hash()); + let root = merkle_opening_gadget( + verifier.mut_cs(), + branch.clone(), + hash, + branch.root.clone(), + ); + verifier.mut_cs().constrain_to_constant( + root, + BlsScalar::zero(), + -branch.root, + ); + + verifier.preprocess(&ck).unwrap(); + let pi = verifier.mut_cs().public_inputs.clone(); + verifier.verify(&proof, &vk, &pi).unwrap(); + + Ok(()) +}