util.rs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. use lazy_static::lazy_static;
  2. use log::debug;
  3. use pasta_curves::{
  4. group::ff::{Field, PrimeField},
  5. pallas,
  6. };
  7. use rand::rngs::OsRng;
  8. use std::{any::Any, collections::HashMap, hash::Hasher};
  9. use darkfi::{
  10. crypto::{
  11. keypair::{PublicKey, SecretKey},
  12. proof::{ProvingKey, VerifyingKey},
  13. schnorr::{SchnorrPublic, SchnorrSecret, Signature},
  14. types::DrkCircuitField,
  15. Proof,
  16. },
  17. util::serial::Encodable,
  18. zk::{vm::ZkCircuit, vm_stack::empty_witnesses},
  19. zkas::decoder::ZkBinary,
  20. };
  21. // TODO: base58 encoding/ decoding
  22. lazy_static! {
  23. pub static ref XDRK_ID: pallas::Base = pallas::Base::random(&mut OsRng);
  24. }
  25. lazy_static! {
  26. pub static ref GDRK_ID: pallas::Base = pallas::Base::random(&mut OsRng);
  27. }
  28. #[derive(Eq, PartialEq)]
  29. pub struct HashableBase(pub pallas::Base);
  30. impl std::hash::Hash for HashableBase {
  31. fn hash<H: Hasher>(&self, state: &mut H) {
  32. let bytes = self.0.to_repr();
  33. bytes.hash(state);
  34. }
  35. }
  36. pub struct ZkBinaryContractInfo {
  37. pub k_param: u32,
  38. pub bincode: ZkBinary,
  39. pub proving_key: ProvingKey,
  40. pub verifying_key: VerifyingKey,
  41. }
  42. pub struct ZkNativeContractInfo {
  43. pub proving_key: ProvingKey,
  44. pub verifying_key: VerifyingKey,
  45. }
  46. pub enum ZkContractInfo {
  47. Binary(ZkBinaryContractInfo),
  48. Native(ZkNativeContractInfo),
  49. }
  50. pub struct ZkContractTable {
  51. // Key will be a hash of zk binary contract on chain
  52. table: HashMap<String, ZkContractInfo>,
  53. }
  54. impl ZkContractTable {
  55. pub fn new() -> Self {
  56. Self { table: HashMap::new() }
  57. }
  58. pub fn add_contract(&mut self, key: String, bincode: ZkBinary, k_param: u32) {
  59. let witnesses = empty_witnesses(&bincode);
  60. let circuit = ZkCircuit::new(witnesses, bincode.clone());
  61. let proving_key = ProvingKey::build(k_param, &circuit);
  62. let verifying_key = VerifyingKey::build(k_param, &circuit);
  63. let info = ZkContractInfo::Binary(ZkBinaryContractInfo {
  64. k_param,
  65. bincode,
  66. proving_key,
  67. verifying_key,
  68. });
  69. self.table.insert(key, info);
  70. }
  71. pub fn add_native(
  72. &mut self,
  73. key: String,
  74. proving_key: ProvingKey,
  75. verifying_key: VerifyingKey,
  76. ) {
  77. self.table.insert(
  78. key,
  79. ZkContractInfo::Native(ZkNativeContractInfo { proving_key, verifying_key }),
  80. );
  81. }
  82. pub fn lookup(&self, key: &String) -> Option<&ZkContractInfo> {
  83. self.table.get(key)
  84. }
  85. }
  86. pub struct Transaction {
  87. pub func_calls: Vec<FuncCall>,
  88. pub signatures: Vec<Signature>,
  89. }
  90. impl Transaction {
  91. /// Verify ZK contracts for the entire tx
  92. /// In real code, we could parallelize this for loop
  93. /// TODO: fix use of unwrap with Result type stuff
  94. pub fn zk_verify(&self, zk_bins: &ZkContractTable) {
  95. for func_call in &self.func_calls {
  96. let proofs_public_vals = &func_call.call_data.zk_public_values();
  97. assert_eq!(
  98. proofs_public_vals.len(),
  99. func_call.proofs.len(),
  100. "proof_public_vals.len()={} and func_call.proofs.len()={} do not match",
  101. proofs_public_vals.len(),
  102. func_call.proofs.len()
  103. );
  104. for (i, (proof, (key, public_vals))) in
  105. func_call.proofs.iter().zip(proofs_public_vals.iter()).enumerate()
  106. {
  107. match zk_bins.lookup(key).unwrap() {
  108. ZkContractInfo::Binary(info) => {
  109. let verifying_key = &info.verifying_key;
  110. let verify_result = proof.verify(&verifying_key, public_vals);
  111. assert!(verify_result.is_ok(), "verify proof[{}]='{}' failed", i, key);
  112. }
  113. ZkContractInfo::Native(info) => {
  114. let verifying_key = &info.verifying_key;
  115. let verify_result = proof.verify(&verifying_key, public_vals);
  116. assert!(verify_result.is_ok(), "verify proof[{}]='{}' failed", i, key);
  117. }
  118. };
  119. debug!(target: "demo", "zk_verify({}) passed [i={}]", key, i);
  120. }
  121. }
  122. }
  123. pub fn verify_sigs(&self) {
  124. let mut unsigned_tx_data = vec![];
  125. for (i, (func_call, signature)) in
  126. self.func_calls.iter().zip(self.signatures.clone()).enumerate()
  127. {
  128. func_call.encode(&mut unsigned_tx_data).expect("failed to encode data");
  129. let signature_pub_keys = func_call.call_data.signature_public_keys();
  130. for signature_pub_key in signature_pub_keys {
  131. let verify_result = signature_pub_key.verify(&unsigned_tx_data[..], &signature);
  132. assert!(verify_result, "verify sigs[{}] failed", i);
  133. }
  134. debug!(target: "demo", "verify_sigs({}) passed", i);
  135. }
  136. }
  137. }
  138. pub fn sign(signature_secrets: Vec<SecretKey>, func_calls: &Vec<FuncCall>) -> Vec<Signature> {
  139. let mut signatures = vec![];
  140. let mut unsigned_tx_data = vec![];
  141. for (_i, (signature_secret, func_call)) in
  142. signature_secrets.iter().zip(func_calls.iter()).enumerate()
  143. {
  144. func_call.encode(&mut unsigned_tx_data).expect("failed to encode data");
  145. let signature = signature_secret.sign(&unsigned_tx_data[..]);
  146. signatures.push(signature);
  147. }
  148. signatures
  149. }
  150. type ContractId = pallas::Base;
  151. type FuncId = pallas::Base;
  152. pub struct FuncCall {
  153. pub contract_id: ContractId,
  154. pub func_id: FuncId,
  155. pub call_data: Box<dyn CallDataBase + Send + Sync>,
  156. pub proofs: Vec<Proof>,
  157. }
  158. impl Encodable for FuncCall {
  159. fn encode<W: std::io::Write>(&self, mut w: W) -> std::result::Result<usize, darkfi::Error> {
  160. let mut len = 0;
  161. len += self.contract_id.encode(&mut w)?;
  162. len += self.func_id.encode(&mut w)?;
  163. len += self.proofs.encode(&mut w)?;
  164. len += self.call_data.encode_bytes(&mut w)?;
  165. Ok(len)
  166. }
  167. }
  168. pub trait CallDataBase {
  169. // Public values for verifying the proofs
  170. // Needed so we can convert internal types so they can be used in Proof::verify()
  171. fn zk_public_values(&self) -> Vec<(String, Vec<DrkCircuitField>)>;
  172. // For upcasting to CallData itself so it can be read in state_transition()
  173. fn as_any(&self) -> &dyn Any;
  174. // Public keys we will use to verify transaction signatures.
  175. fn signature_public_keys(&self) -> Vec<PublicKey>;
  176. fn encode_bytes(
  177. &self,
  178. writer: &mut dyn std::io::Write,
  179. ) -> std::result::Result<usize, darkfi::Error>;
  180. }
  181. type GenericContractState = Box<dyn Any + Send>;
  182. pub struct StateRegistry {
  183. pub states: HashMap<HashableBase, GenericContractState>,
  184. }
  185. impl StateRegistry {
  186. pub fn new() -> Self {
  187. Self { states: HashMap::new() }
  188. }
  189. pub fn register(&mut self, contract_id: ContractId, state: GenericContractState) {
  190. debug!(target: "StateRegistry::register()", "contract_id: {:?}", contract_id);
  191. self.states.insert(HashableBase(contract_id), state);
  192. }
  193. pub fn lookup_mut<'a, S: 'static>(&'a mut self, contract_id: ContractId) -> Option<&'a mut S> {
  194. self.states.get_mut(&HashableBase(contract_id)).and_then(|state| state.downcast_mut())
  195. }
  196. pub fn lookup<'a, S: 'static>(&'a self, contract_id: ContractId) -> Option<&'a S> {
  197. self.states.get(&HashableBase(contract_id)).and_then(|state| state.downcast_ref())
  198. }
  199. }
  200. pub trait UpdateBase {
  201. fn apply(self: Box<Self>, states: &mut StateRegistry);
  202. }