mod.rs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. pub mod builder;
  2. pub mod partial;
  3. use bellman::groth16;
  4. use bls12_381::Bls12;
  5. use ff::Field;
  6. use group::Group;
  7. use rand::rngs::OsRng;
  8. use std::collections::HashMap;
  9. use std::io;
  10. use self::partial::{PartialTransactionClearInput, PartialTransactionInput};
  11. use crate::crypto::{
  12. coin::Coin,
  13. create_mint_proof, create_spend_proof, load_params,
  14. merkle::CommitmentTree,
  15. note::{EncryptedNote, Note},
  16. save_params, schnorr, setup_mint_prover, setup_spend_prover, verify_mint_proof,
  17. verify_spend_proof, MintRevealedValues, SpendRevealedValues,
  18. };
  19. use crate::error::{Error, Result};
  20. use crate::impl_vec;
  21. use crate::serial::{Decodable, Encodable, VarInt};
  22. use crate::state;
  23. pub use self::builder::{
  24. TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
  25. TransactionBuilderOutputInfo,
  26. };
  27. pub struct Transaction {
  28. pub clear_inputs: Vec<TransactionClearInput>,
  29. pub inputs: Vec<TransactionInput>,
  30. pub outputs: Vec<TransactionOutput>,
  31. }
  32. pub struct TransactionClearInput {
  33. pub value: u64,
  34. pub valcom_blind: jubjub::Fr,
  35. pub signature_public: jubjub::SubgroupPoint,
  36. pub signature: schnorr::Signature,
  37. }
  38. pub struct TransactionInput {
  39. pub spend_proof: groth16::Proof<Bls12>,
  40. pub revealed: SpendRevealedValues,
  41. pub signature: schnorr::Signature,
  42. }
  43. pub struct TransactionOutput {
  44. pub mint_proof: groth16::Proof<Bls12>,
  45. pub revealed: MintRevealedValues,
  46. pub enc_note: EncryptedNote,
  47. }
  48. impl Transaction {
  49. fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
  50. let mut len = 0;
  51. len += self.clear_inputs.encode_without_signature(&mut s)?;
  52. len += self.inputs.encode_without_signature(&mut s)?;
  53. len += self.outputs.encode(s)?;
  54. Ok(len)
  55. }
  56. fn compute_value_commit(value: u64, blind: &jubjub::Fr) -> jubjub::SubgroupPoint {
  57. let value_commit = (zcash_primitives::constants::VALUE_COMMITMENT_VALUE_GENERATOR
  58. * jubjub::Fr::from(value))
  59. + (zcash_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR * blind);
  60. value_commit
  61. }
  62. pub fn verify(
  63. &self,
  64. mint_pvk: &groth16::PreparedVerifyingKey<Bls12>,
  65. spend_pvk: &groth16::PreparedVerifyingKey<Bls12>,
  66. ) -> state::VerifyResult<()> {
  67. let mut valcom_total = jubjub::SubgroupPoint::identity();
  68. for input in &self.clear_inputs {
  69. valcom_total += Self::compute_value_commit(input.value, &input.valcom_blind);
  70. }
  71. for (i, input) in self.inputs.iter().enumerate() {
  72. if !verify_spend_proof(spend_pvk, &input.spend_proof, &input.revealed) {
  73. return Err(state::VerifyFailed::SpendProof(i));
  74. }
  75. valcom_total += &input.revealed.value_commit;
  76. }
  77. for (i, output) in self.outputs.iter().enumerate() {
  78. if !verify_mint_proof(mint_pvk, &output.mint_proof, &output.revealed) {
  79. return Err(state::VerifyFailed::SpendProof(i));
  80. }
  81. valcom_total -= &output.revealed.value_commit;
  82. }
  83. if valcom_total != jubjub::SubgroupPoint::identity() {
  84. return Err(state::VerifyFailed::MissingFunds);
  85. }
  86. // Verify signatures
  87. let mut unsigned_tx_data = vec![];
  88. self.encode_without_signature(&mut unsigned_tx_data)
  89. .expect("TODO handle this");
  90. for (i, input) in self.clear_inputs.iter().enumerate() {
  91. let public = schnorr::PublicKey(input.signature_public.clone());
  92. if !public.verify(&unsigned_tx_data[..], &input.signature) {
  93. return Err(state::VerifyFailed::ClearInputSignature(i));
  94. }
  95. }
  96. for (i, input) in self.inputs.iter().enumerate() {
  97. let public = schnorr::PublicKey(input.revealed.signature_public.clone());
  98. if !public.verify(&unsigned_tx_data[..], &input.signature) {
  99. return Err(state::VerifyFailed::InputSignature(i));
  100. }
  101. }
  102. Ok(())
  103. }
  104. }
  105. impl TransactionClearInput {
  106. fn from_partial(partial: PartialTransactionClearInput, signature: schnorr::Signature) -> Self {
  107. Self {
  108. value: partial.value,
  109. valcom_blind: partial.valcom_blind,
  110. signature_public: partial.signature_public,
  111. signature,
  112. }
  113. }
  114. fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
  115. let mut len = 0;
  116. len += self.value.encode(&mut s)?;
  117. len += self.valcom_blind.encode(&mut s)?;
  118. len += self.signature_public.encode(s)?;
  119. Ok(len)
  120. }
  121. }
  122. impl TransactionInput {
  123. fn from_partial(partial: PartialTransactionInput, signature: schnorr::Signature) -> Self {
  124. Self {
  125. spend_proof: partial.spend_proof,
  126. revealed: partial.revealed,
  127. signature,
  128. }
  129. }
  130. fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
  131. let mut len = 0;
  132. len += self.spend_proof.encode(&mut s)?;
  133. len += self.revealed.encode(&mut s)?;
  134. Ok(len)
  135. }
  136. }
  137. impl Encodable for Transaction {
  138. fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
  139. let mut len = 0;
  140. len += self.clear_inputs.encode(&mut s)?;
  141. len += self.inputs.encode(&mut s)?;
  142. len += self.outputs.encode(s)?;
  143. Ok(len)
  144. }
  145. }
  146. impl Decodable for Transaction {
  147. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  148. Ok(Self {
  149. clear_inputs: Decodable::decode(&mut d)?,
  150. inputs: Decodable::decode(&mut d)?,
  151. outputs: Decodable::decode(d)?,
  152. })
  153. }
  154. }
  155. impl Encodable for TransactionClearInput {
  156. fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
  157. let mut len = 0;
  158. len += self.value.encode(&mut s)?;
  159. len += self.valcom_blind.encode(&mut s)?;
  160. len += self.signature_public.encode(&mut s)?;
  161. len += self.signature.encode(s)?;
  162. Ok(len)
  163. }
  164. }
  165. impl Decodable for TransactionClearInput {
  166. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  167. Ok(Self {
  168. value: Decodable::decode(&mut d)?,
  169. valcom_blind: Decodable::decode(&mut d)?,
  170. signature_public: Decodable::decode(&mut d)?,
  171. signature: Decodable::decode(d)?,
  172. })
  173. }
  174. }
  175. impl Encodable for TransactionInput {
  176. fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
  177. let mut len = 0;
  178. len += self.spend_proof.encode(&mut s)?;
  179. len += self.revealed.encode(&mut s)?;
  180. len += self.signature.encode(s)?;
  181. Ok(len)
  182. }
  183. }
  184. impl Decodable for TransactionInput {
  185. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  186. Ok(Self {
  187. spend_proof: Decodable::decode(&mut d)?,
  188. revealed: Decodable::decode(&mut d)?,
  189. signature: Decodable::decode(d)?,
  190. })
  191. }
  192. }
  193. impl Encodable for TransactionOutput {
  194. fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
  195. let mut len = 0;
  196. len += self.mint_proof.encode(&mut s)?;
  197. len += self.revealed.encode(&mut s)?;
  198. len += self.enc_note.encode(&mut s)?;
  199. Ok(len)
  200. }
  201. }
  202. impl Decodable for TransactionOutput {
  203. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  204. Ok(Self {
  205. mint_proof: Decodable::decode(&mut d)?,
  206. revealed: Decodable::decode(&mut d)?,
  207. enc_note: Decodable::decode(&mut d)?,
  208. })
  209. }
  210. }
  211. trait EncodableWithoutSignature {
  212. fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
  213. }
  214. macro_rules! impl_vec_without_signature {
  215. ($type: ty) => {
  216. impl EncodableWithoutSignature for Vec<$type> {
  217. #[inline]
  218. fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
  219. let mut len = 0;
  220. len += VarInt(self.len() as u64).encode(&mut s)?;
  221. for c in self.iter() {
  222. len += c.encode_without_signature(&mut s)?;
  223. }
  224. Ok(len)
  225. }
  226. }
  227. };
  228. }
  229. impl_vec_without_signature!(TransactionClearInput);
  230. impl_vec_without_signature!(TransactionInput);
  231. impl_vec!(TransactionClearInput);
  232. impl_vec!(TransactionInput);
  233. impl_vec!(TransactionOutput);