diff --git a/src/components/contracts/modules/evm/precompile/zkcard/Cargo.toml b/src/components/contracts/modules/evm/precompile/zkcard/Cargo.toml index c55465c17..7021173b9 100644 --- a/src/components/contracts/modules/evm/precompile/zkcard/Cargo.toml +++ b/src/components/contracts/modules/evm/precompile/zkcard/Cargo.toml @@ -19,10 +19,10 @@ num_enum = { version = "0.5.4", default-features = false } slices = "0.2.0" config = { path = "../../../../../config" } num = { version = "0.3", features = ["alloc"] } -starknet-curve = { git = "https://github.com/geometryresearch/proof-toolbox.git" } -barnett-smart-card-protocol = { git = "https://github.com/HarryLiIsMe/mental-poker.git", branch = "mercury-fix" } +starknet-curve = { git = "https://github.com/geometryresearch/proof-toolbox.git", branch = "fix/schnorr_affine" } +barnett-smart-card-protocol = { git = "https://github.com/FindoraNetwork/mental-poker.git", branch = "mercury-serialize-error-fix" } ark-serialize = "0.3.0" -proof-essentials = { git = "https://github.com/FindoraNetwork/proof-toolbox.git", branch = "findora" } +proof-essentials = { git = "https://github.com/HarryLiIsMe/findora-proof-toolbox.git", branch = "findora" } ark-ec = "0.3.0" rand = "0.8" ark-std = { version = "0.3.0", features = ["std"] } diff --git a/src/components/contracts/modules/evm/precompile/zkcard/src/lib.rs b/src/components/contracts/modules/evm/precompile/zkcard/src/lib.rs index 45a272214..2d77fc752 100644 --- a/src/components/contracts/modules/evm/precompile/zkcard/src/lib.rs +++ b/src/components/contracts/modules/evm/precompile/zkcard/src/lib.rs @@ -13,7 +13,7 @@ use evm_precompile_utils::{ use module_evm::precompile::{FinState, Precompile, PrecompileId, PrecompileResult}; use num::Zero; use rand::thread_rng; -use slices::u8_slice; +// use slices::u8_slice; use std::vec; use tracing::debug; @@ -56,31 +56,6 @@ type CRevealProof = ProofB; type CProof = ProofC; type CCard = Card; -/// ZkCard transfer event selector, Keccak256("Transfer(address,address,uint256)") -/// -/// event Transfer(address indexed from, address indexed to, uint256 value); -pub const TRANSFER_EVENT_SELECTOR: &[u8; 32] = - u8_slice!("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"); - -/// ZkCard approval event selector, Keccak256("Approval(address,address,uint256)") -/// -/// event Approval(address indexed owner, address indexed spender, uint256 value); -pub const APPROVAL_EVENT_SELECTOR: &[u8; 32] = - u8_slice!("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"); - -/// b"Findora" -pub const ZKCARD_NAME: &[u8; 96] = u8_slice!( - "0x00000000000000000000000000000000000000000000000000000000000000200000000000000\ - 00000000000000000000000000000000000000000000000000746696e646f7261000000000000000\ - 00000000000000000000000000000000000" -); - -/// b"FRA" -pub const ZKCARD_SYMBOL: &[u8; 96] = u8_slice!( - "0x00000000000000000000000000000000000000000000000000000000000000200000000000000\ - 00000000000000000000000000000000000000000000000000346524100000000000000000000000\ - 00000000000000000000000000000000000" -); // The gas used value is obtained according to the standard erc20 call. // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.2/contracts/token/ERC20/ERC20.sol diff --git a/src/components/contracts/modules/evm/precompile/zkcard/src/tests.rs b/src/components/contracts/modules/evm/precompile/zkcard/src/tests.rs index fb2e2c89e..4bc5f75f3 100644 --- a/src/components/contracts/modules/evm/precompile/zkcard/src/tests.rs +++ b/src/components/contracts/modules/evm/precompile/zkcard/src/tests.rs @@ -1,279 +1,90 @@ -// use crate::*; -// use baseapp::BaseApp; -// use ethereum_types::H160; -// use fp_mocks::*; - -// use evm_precompile_utils::{error, EvmDataWriter}; -// use module_evm::precompile::Precompile; -// use sha3::{Digest, Keccak256}; - -// pub const FRC20_PRECOMPILE_ADDRESS: u64 = 9; - -// #[test] -// fn selector_less_than_four_bytes() { -// let invalid_selector = vec![1u8, 2u8, 3u8]; -// assert_eq!( -// FRC20::::execute( -// &invalid_selector, -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: ALICE_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Err(PrecompileFailure::Error { -// exit_status: error("tried to parse selector out of bounds") -// }) -// ); -// } - -// #[test] -// fn no_selector_exists_but_length_is_right() { -// let invalid_selector = vec![1u8, 2u8, 3u8, 4u8]; - -// assert_eq!( -// FRC20::::execute( -// &invalid_selector, -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: ALICE_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Err(PrecompileFailure::Error { -// exit_status: error("unknown selector") -// }) -// ); -// } - -// #[test] -// fn selectors() { -// assert_eq!(Call::Name as u32, 0x06fdde03); -// assert_eq!(Call::Symbol as u32, 0x95d89b41); -// assert_eq!(Call::Decimals as u32, 0x313ce567); -// assert_eq!(Call::TotalSupply as u32, 0x18160ddd); -// assert_eq!(Call::BalanceOf as u32, 0x70a08231); -// assert_eq!(Call::Transfer as u32, 0xa9059cbb); -// assert_eq!(Call::Allowance as u32, 0xdd62ed3e); -// assert_eq!(Call::Approve as u32, 0x095ea7b3); -// assert_eq!(Call::TransferFrom as u32, 0x23b872dd); - -// assert_eq!( -// TRANSFER_EVENT_SELECTOR, -// &Keccak256::digest(b"Transfer(address,address,uint256)")[..] -// ); -// assert_eq!( -// APPROVAL_EVENT_SELECTOR, -// &Keccak256::digest(b"Approval(address,address,uint256)")[..] -// ); -// } - -// #[test] -// fn frc20_works() { -// test_mint_balance(&ALICE_ECDSA.account_id, 1000u64.into(), 1); -// test_mint_balance(&BOB_ECDSA.account_id, 1000u64.into(), 2); - -// total_supply_works(); -// balance_of_works(); -// transfer_works(); -// approve_works(); -// allowance_works(); -// transfer_from_works(); -// } - -// fn total_supply_works() { -// assert_eq!( -// FRC20::::execute( -// &EvmDataWriter::new() -// .write_selector(Call::TotalSupply) -// .build(), -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: ALICE_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Ok(PrecompileOutput { -// exit_status: ExitSucceed::Returned, -// output: EvmDataWriter::new().write(U256::from(2000u64)).build(), -// cost: GAS_TOTAL_SUPPLY, -// logs: Default::default(), -// }) -// ); -// } - -// fn balance_of_works() { -// balance_of(BOB_ECDSA.address, U256::from(1000)); -// } - -// fn balance_of(who: H160, expected_value: U256) { -// assert_eq!( -// FRC20::::execute( -// &EvmDataWriter::new() -// .write_selector(Call::BalanceOf) -// .write(Address(who)) -// .build(), -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: ALICE_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Ok(PrecompileOutput { -// exit_status: ExitSucceed::Returned, -// output: EvmDataWriter::new().write(expected_value).build(), -// cost: GAS_BALANCE_OF, -// logs: Default::default(), -// }) -// ); -// } - -// fn transfer_works() { -// assert_eq!( -// FRC20::::execute( -// &EvmDataWriter::new() -// .write_selector(Call::Transfer) -// .write(Address(BOB_ECDSA.address)) -// .write(U256::from(400)) -// .build(), -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: ALICE_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Ok(PrecompileOutput { -// exit_status: ExitSucceed::Returned, -// output: EvmDataWriter::new().write(true).build(), -// cost: GAS_TRANSFER + 1756, -// logs: LogsBuilder::new(H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS)) -// .log3( -// TRANSFER_EVENT_SELECTOR, -// ALICE_ECDSA.address, -// BOB_ECDSA.address, -// EvmDataWriter::new().write(U256::from(400)).build(), -// ) -// .build(), -// }) -// ); - -// balance_of(ALICE_ECDSA.address, U256::from(600)); - -// balance_of(BOB_ECDSA.address, U256::from(1400)); -// } - -// fn approve_works() { -// assert_eq!( -// FRC20::::execute( -// &EvmDataWriter::new() -// .write_selector(Call::Approve) -// .write(Address(BOB_ECDSA.address)) -// .write(U256::from(500)) -// .build(), -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: ALICE_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Ok(PrecompileOutput { -// exit_status: ExitSucceed::Returned, -// output: EvmDataWriter::new().write(true).build(), -// cost: GAS_APPROVE + 1756, -// logs: LogsBuilder::new(H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS)) -// .log3( -// APPROVAL_EVENT_SELECTOR, -// ALICE_ECDSA.address, -// BOB_ECDSA.address, -// EvmDataWriter::new().write(U256::from(500)).build(), -// ) -// .build(), -// }) -// ); -// } - -// fn allowance_works() { -// allowance(ALICE_ECDSA.address, BOB_ECDSA.address, U256::from(500)); -// } - -// fn allowance(owner: H160, spender: H160, expected_value: U256) { -// assert_eq!( -// FRC20::::execute( -// &EvmDataWriter::new() -// .write_selector(Call::Allowance) -// .write(Address(owner)) -// .write(Address(spender)) -// .build(), -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: ALICE_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Ok(PrecompileOutput { -// exit_status: ExitSucceed::Returned, -// output: EvmDataWriter::new().write(expected_value).build(), -// cost: GAS_ALLOWANCE, -// logs: Default::default(), -// }) -// ); -// } - -// fn transfer_from_works() { -// assert_eq!( -// FRC20::::execute( -// &EvmDataWriter::new() -// .write_selector(Call::TransferFrom) -// .write(Address(ALICE_ECDSA.address)) -// .write(Address(BOB_ECDSA.address)) -// .write(U256::from(400)) -// .build(), -// None, -// &evm::Context { -// address: H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS), -// caller: BOB_ECDSA.address, -// apparent_value: From::from(0), -// }, -// &BASE_APP.lock().unwrap().deliver_state, -// ), -// Ok(PrecompileOutput { -// exit_status: ExitSucceed::Returned, -// output: EvmDataWriter::new().write(true).build(), -// cost: GAS_TRANSFER_FROM + 1756 * 2, -// logs: LogsBuilder::new(H160::from_low_u64_be(FRC20_PRECOMPILE_ADDRESS)) -// .log3( -// TRANSFER_EVENT_SELECTOR, -// ALICE_ECDSA.address, -// BOB_ECDSA.address, -// EvmDataWriter::new().write(U256::from(400)).build(), -// ) -// .log3( -// APPROVAL_EVENT_SELECTOR, -// ALICE_ECDSA.address, -// BOB_ECDSA.address, -// EvmDataWriter::new().write(U256::from(100)).build(), -// ) -// .build(), -// }) -// ); - -// balance_of(ALICE_ECDSA.address, U256::from(200)); - -// balance_of(BOB_ECDSA.address, U256::from(1800)); - -// allowance(ALICE_ECDSA.address, BOB_ECDSA.address, U256::from(100)); -// } +use crate::*; +use baseapp::BaseApp; +use ethereum_types::H160; +use fp_mocks::*; + +use evm_precompile_utils::{error, EvmDataWriter}; +use module_evm::precompile::Precompile; +use sha3::{Digest, Keccak256}; + +pub const ZKCARD_PRECOMPILE_ADDRESS: u64 = 0x3000; + +#[test] +fn selector_less_than_four_bytes() { + let invalid_selector = vec![1u8, 2u8, 3u8]; + assert_eq!( + ZkCard::execute( + &invalid_selector, + None, + &evm::Context { + address: H160::from_low_u64_be(ZKCARD_PRECOMPILE_ADDRESS), + caller: ALICE_ECDSA.address, + apparent_value: From::from(0), + }, + &BASE_APP.lock().unwrap().deliver_state, + ), + Err(PrecompileFailure::Error { + exit_status: error("tried to parse selector out of bounds") + }) + ); +} + +#[test] +fn no_selector_exists_but_length_is_right() { + let invalid_selector = vec![1u8, 2u8, 3u8, 4u8]; + + assert_eq!( + ZkCard::execute( + &invalid_selector, + None, + &evm::Context { + address: H160::from_low_u64_be(ZKCARD_PRECOMPILE_ADDRESS), + caller: ALICE_ECDSA.address, + apparent_value: From::from(0), + }, + &BASE_APP.lock().unwrap().deliver_state, + ), + Err(PrecompileFailure::Error { + exit_status: error("unknown selector") + }) + ); +} + + +#[test] +fn selectors() { + assert_eq!(Call::VerifyKeyOwnership as u32, 0x3931f649); + assert_eq!(Call::VerifyReveal as u32, 0x9ca80d77); + assert_eq!(Call::ComputeAggregateKey as u32, 0x5b2bfec7); + assert_eq!(Call::VerifyShuffle as u32, 0x2a379865); + assert_eq!(Call::Reveal as u32, 0x6a33d652); + assert_eq!(Call::Mask as u32, 0x5a8890bc); +} + +#[test] +fn zkcard_works() { + verify_key_ownership_works(); + compute_aggregate_key_works(); + verify_shuffle_works(); + verify_reveal_works(); + reveal_works(); + mask_works(); +} + +fn verify_key_ownership_works() { +} + +fn compute_aggregate_key_works() { +} + +fn verify_shuffle_works() { +} + +fn verify_reveal_works() { +} + +fn reveal_works() { +} + +fn mask_works() { +} diff --git a/src/components/finutils/src/bins/stt/stt.rs b/src/components/finutils/src/bins/stt/stt.rs index 67cb3fe63..267ec6f70 100644 --- a/src/components/finutils/src/bins/stt/stt.rs +++ b/src/components/finutils/src/bins/stt/stt.rs @@ -42,7 +42,7 @@ const ROOT_MNEMONIC: &str = "zoo nerve assault talk depend approve mercy surge b type Name = String; type NameRef<'a> = &'a str; -#[macro_export(crate)] +#[macro_export] macro_rules! sleep_n_block { ($n_block: expr, $itv: expr) => {{ let n = $n_block as f64; diff --git a/src/components/zkcards_wasm/src/wasm.rs b/src/components/zkcards_wasm/src/wasm.rs index eda903f4d..519e06e0e 100644 --- a/src/components/zkcards_wasm/src/wasm.rs +++ b/src/components/zkcards_wasm/src/wasm.rs @@ -12,4 +12,88 @@ #![deny(missing_docs)] #![allow(clippy::needless_borrow)] +//todo: remove `unwrap` +//todo: more comments + mod zkcards; + +use crate::zkcards::{ + AggregatePublicKey, Card, CardParameters, MaskedCard, Player, ProofShuffle, + RevealedToken, Surrogate, +}; +use rand::thread_rng; +use std::collections::HashMap; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +/// create a new player with `name` and `card parameters` received from contract +pub fn new_player(pp: CardParameters, name: Vec) -> Player { + let rng = &mut thread_rng(); + Player::new(rng, &pp, &name).unwrap() +} + +#[wasm_bindgen] +/// generate a `surrogate` with `ProofKeyOwnerShip` as this player's behave +pub fn new_surrogate(player: &Player, pp: &CardParameters) -> Surrogate { + player.new_surrogate(pp) +} + +#[wasm_bindgen] +/// verify a player +pub fn verify_proof_pk(player: Surrogate, pp: &CardParameters) -> bool { + player.verify(&pp) +} + +#[wasm_bindgen] +/// Perform a shuffle operation +pub fn shuffle( + player: &Player, + pp: &CardParameters, + deck: &Vec, + joint_pk: &AggregatePublicKey, + nums_of_cards: usize, +) -> (Vec, ProofShuffle) { + player.shuffle(pp, deck, joint_pk, nums_of_cards).unwrap() +} + +#[wasm_bindgen] +/// verify shuffled deck from another player +pub fn verify_shuffle( + parameters: &CardParameters, + joint_pk: &AggregatePublicKey, + original_deck: &Vec, + shuffled_deck: &Vec, + proof_shuffle: &ProofShuffle, +) -> bool { + Player::verify_shuffle( + parameters, + joint_pk, + original_deck, + shuffled_deck, + proof_shuffle, + ) + .is_ok() +} + +#[wasm_bindgen] +/// reveal a card +pub fn compute_reveal_token( + player: &Player, + card: &MaskedCard, + pp: &CardParameters, +) -> RevealedToken { + let rng = &mut thread_rng(); + player.compute_reveal_token(rng, pp, card).unwrap() +} + +#[wasm_bindgen] +/// open a card +pub fn open_card( + parameters: &CardParameters, + reveal_tokens: &Vec, + card_mappings: &HashMap>, + card: &MaskedCard, + cards: &Vec, +) -> Vec { + Player::peek_at_card(parameters, reveal_tokens, card_mappings, card, cards).unwrap() +} diff --git a/src/components/zkcards_wasm/src/zkcards/mod.rs b/src/components/zkcards_wasm/src/zkcards/mod.rs index 38822f8db..37cfce2ec 100644 --- a/src/components/zkcards_wasm/src/zkcards/mod.rs +++ b/src/components/zkcards_wasm/src/zkcards/mod.rs @@ -2,6 +2,9 @@ mod error; mod player; mod user_card; +pub use player::*; +pub use user_card::*; + use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use barnett::discrete_log_cards; use proof_essentials::{ @@ -51,9 +54,20 @@ impl<'a> From<&'a CardParameters> for &'a discrete_log_cards::Parameters } } -pub type PlayerPublicKey = discrete_log_cards::PublicKey; -pub type PlayerSecretKey = discrete_log_cards::PlayerSecretKey; -pub type AggregatePublicKey = discrete_log_cards::PublicKey; +type PlayerSecretKey = discrete_log_cards::PlayerSecretKey; + +#[wasm_bindgen] +#[derive(Clone, Copy, Serialize, Deserialize)] +pub struct PlayerPublicKey( + #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] + pub(crate) discrete_log_cards::PublicKey, +); +#[wasm_bindgen] +#[derive(Clone, Serialize, Deserialize)] +pub struct AggregatePublicKey( + #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] + pub(crate) discrete_log_cards::PublicKey, +); #[wasm_bindgen] #[derive(Clone, Copy, Eq, Hash, PartialEq, Debug, Serialize, Deserialize)] @@ -72,6 +86,11 @@ impl From for discrete_log_cards::Card { } } +#[wasm_bindgen] +pub struct MaskedCards { + inner: Vec, +} + #[wasm_bindgen] #[derive(Clone, Copy, Eq, Hash, PartialEq, Debug, Serialize, Deserialize)] pub struct MaskedCard( @@ -167,7 +186,6 @@ impl<'a> From<&'a ProofShuffle> for &'a shuffle::proof::Proof } } -#[wasm_bindgen] //pub struct ProofMasking(chaum_pedersen_dl_equality::proof::Proof); #[derive(Clone, Copy, Eq, Hash, PartialEq, Debug, Deserialize, Serialize)] pub struct ProofRemasking( @@ -185,13 +203,12 @@ impl From for chaum_pedersen_dl_equality::proof::Proof { } } -//#[wasm_bindgen] +#[wasm_bindgen] #[derive(Serialize, Deserialize)] pub struct RevealedToken { - pub token: RevealToken, - pub proof: ProofReveal, - #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] - pub player: PlayerPublicKey, + pub(crate) token: RevealToken, + pub(crate) proof: ProofReveal, + pub(crate) player: PlayerPublicKey, } fn ark_se(a: &A, s: S) -> Result diff --git a/src/components/zkcards_wasm/src/zkcards/player.rs b/src/components/zkcards_wasm/src/zkcards/player.rs index 7bb04a341..cac39ebea 100644 --- a/src/components/zkcards_wasm/src/zkcards/player.rs +++ b/src/components/zkcards_wasm/src/zkcards/player.rs @@ -7,35 +7,34 @@ use super::{ RevealedToken, Scalar, }; use ark_std::rand::Rng; -use barnett::BarnettSmartProtocol; +use barnett::{BarnettSmartProtocol, Mask}; use proof_essentials::utils::{permutation::Permutation, rand::sample_vector}; use rand::thread_rng; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use wasm_bindgen::prelude::*; +#[wasm_bindgen] #[derive(Clone)] pub struct Player { name: Vec, sk: PlayerSecretKey, pk: PlayerPublicKey, - proof_key: ProofKeyOwnership, - cards: Vec, - opened_cards: Vec>, } +#[wasm_bindgen] #[derive(Serialize, Deserialize)] pub struct Surrogate { - pub name: Vec, - #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] - pub pk: PlayerPublicKey, - pub proof_key: ProofKeyOwnership, + pub(crate) name: Vec, + pub(crate) pk: PlayerPublicKey, + pub(crate) proof_key: ProofKeyOwnership, } impl Surrogate { pub fn verify(&self, pp: &CardParameters) -> bool { CardProtocol::verify_key_ownership( pp.into(), - &self.pk, + &self.pk.0, &self.name, &self.proof_key.into(), ) @@ -50,15 +49,10 @@ impl Player { name: &Vec, ) -> Result { let (pk, sk) = CardProtocol::player_keygen(rng, pp.into())?; - let proof_key = - CardProtocol::prove_key_ownership(rng, pp.into(), &pk, &sk, name)?; Ok(Self { name: name.clone(), sk, - pk, - proof_key: proof_key.into(), - cards: vec![], - opened_cards: vec![], + pk: PlayerPublicKey(pk), }) } @@ -67,7 +61,7 @@ impl Player { let proof_key = CardProtocol::prove_key_ownership( rng, pp.into(), - &self.pk, + &self.pk.0, &self.sk, &self.name, ) @@ -80,14 +74,6 @@ impl Player { } } - pub fn surrogate(&self) -> Surrogate { - Surrogate { - name: self.name.clone(), - pk: self.pk, - proof_key: self.proof_key, - } - } - pub fn shuffle( &self, parameters: &CardParameters, @@ -103,7 +89,7 @@ impl Player { let (shuffled_deck, shuffle_proof) = CardProtocol::shuffle_and_remask( &mut rng, parameters.into(), - joint_pk, + &joint_pk.0, &deck, &masking_factors, &permutation, @@ -118,7 +104,6 @@ impl Player { } pub fn verify_shuffle( - &self, parameters: &CardParameters, joint_pk: &AggregatePublicKey, original_deck: &Vec, @@ -135,7 +120,7 @@ impl Player { .collect::>(); CardProtocol::verify_shuffle( parameters.into(), - joint_pk, + &joint_pk.0, &original_deck, &shuffled_deck, proof_shuffle.into(), @@ -143,43 +128,30 @@ impl Player { .map_err(|e| GameErrors::CryptoError(e)) } - pub fn receive_card(&mut self, card: MaskedCard) { - self.cards.push(card); - self.opened_cards.push(None); - } - pub fn peek_at_card( - &mut self, parameters: &CardParameters, - reveal_tokens: &mut Vec, + reveal_tokens: &Vec, card_mappings: &HashMap>, card: &MaskedCard, - ) -> Result<()> { - let i = self.cards.iter().position(|&x| x == *card); - - let i = i.ok_or(GameErrors::CardNotFound)?; - - //TODO add function to create that without the proof - let rng = &mut thread_rng(); - let own_reveal_token = self.compute_reveal_token(rng, parameters, card)?; - reveal_tokens.push(RevealedToken { - token: own_reveal_token.0, - proof: own_reveal_token.1, - player: own_reveal_token.2, - }); + cards: &Vec, + ) -> Result> { + let _ = cards + .iter() + .position(|&x| x == *card) + .ok_or(GameErrors::CardNotFound)?; let raw_reveal_tokens = reveal_tokens .iter() - .map(|t| (t.token.into(), t.proof.into(), t.player)) + .map(|t| (t.token.into(), t.proof.into(), t.player.0)) .collect::>(); let unmasked_card = CardProtocol::unmask(parameters.into(), &raw_reveal_tokens, card.into())?; - let opened_card = card_mappings.get(&unmasked_card.into()); - let opened_card = opened_card.ok_or(GameErrors::InvalidCard)?; + let opened_card = card_mappings + .get(&unmasked_card.into()) + .ok_or(GameErrors::InvalidCard)?; - self.opened_cards[i] = Some(serde_json::from_slice(opened_card).unwrap()); - Ok(()) + Ok(opened_card.to_owned()) } pub fn compute_reveal_token( @@ -187,15 +159,19 @@ impl Player { rng: &mut R, pp: &CardParameters, card: &MaskedCard, - ) -> Result<(RevealToken, ProofReveal, PlayerPublicKey)> { + ) -> Result { let (reveal_token, reveal_proof) = CardProtocol::compute_reveal_token( rng, pp.into(), &self.sk, - &self.pk, + &self.pk.0, card.into(), )?; - Ok((reveal_token.into(), reveal_proof.into(), self.pk)) + Ok(RevealedToken { + token: reveal_token.into(), + proof: reveal_proof.into(), + player: self.pk, + }) } }