proof.rs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. use std::io;
  2. use halo2_proofs::{
  3. plonk,
  4. plonk::{Circuit, SingleVerifier},
  5. poly::commitment::Params,
  6. transcript::{Blake2bRead, Blake2bWrite},
  7. };
  8. use pasta_curves::vesta;
  9. use rand::RngCore;
  10. use crate::{
  11. crypto::types::*,
  12. util::serial::{encode_with_size, Decodable, Encodable, ReadExt, VarInt},
  13. Result,
  14. };
  15. #[derive(Debug)]
  16. pub struct VerifyingKey {
  17. pub params: Params<vesta::Affine>,
  18. pub vk: plonk::VerifyingKey<vesta::Affine>,
  19. }
  20. impl VerifyingKey {
  21. pub fn build(k: u32, c: &impl Circuit<DrkCircuitField>) -> Self {
  22. let params = Params::new(k);
  23. let vk = plonk::keygen_vk(&params, c).unwrap();
  24. VerifyingKey { params, vk }
  25. }
  26. }
  27. #[derive(Debug)]
  28. pub struct ProvingKey {
  29. pub params: Params<vesta::Affine>,
  30. pub pk: plonk::ProvingKey<vesta::Affine>,
  31. }
  32. impl ProvingKey {
  33. pub fn build(k: u32, c: &impl Circuit<DrkCircuitField>) -> Self {
  34. let params = Params::new(k);
  35. let vk = plonk::keygen_vk(&params, c).unwrap();
  36. let pk = plonk::keygen_pk(&params, vk, c).unwrap();
  37. ProvingKey { params, pk }
  38. }
  39. }
  40. #[derive(Clone, Debug)]
  41. pub struct Proof(Vec<u8>);
  42. impl AsRef<[u8]> for Proof {
  43. fn as_ref(&self) -> &[u8] {
  44. &self.0
  45. }
  46. }
  47. impl Proof {
  48. pub fn create(
  49. pk: &ProvingKey,
  50. circuits: &[impl Circuit<DrkCircuitField>],
  51. instances: &[DrkCircuitField],
  52. mut rng: impl RngCore,
  53. ) -> std::result::Result<Self, plonk::Error> {
  54. let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
  55. plonk::create_proof(
  56. &pk.params,
  57. &pk.pk,
  58. circuits,
  59. &[&[instances]],
  60. &mut rng,
  61. &mut transcript,
  62. )?;
  63. Ok(Proof(transcript.finalize()))
  64. }
  65. pub fn verify(
  66. &self,
  67. vk: &VerifyingKey,
  68. instances: &[DrkCircuitField],
  69. ) -> std::result::Result<(), plonk::Error> {
  70. let strategy = SingleVerifier::new(&vk.params);
  71. let mut transcript = Blake2bRead::init(&self.0[..]);
  72. plonk::verify_proof(&vk.params, &vk.vk, strategy, &[&[instances]], &mut transcript)
  73. }
  74. pub fn new(bytes: Vec<u8>) -> Self {
  75. Proof(bytes)
  76. }
  77. }
  78. impl Encodable for Proof {
  79. fn encode<S: io::Write>(&self, s: S) -> Result<usize> {
  80. encode_with_size(self.as_ref(), s)
  81. }
  82. }
  83. impl Decodable for Proof {
  84. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  85. let len = VarInt::decode(&mut d)?.0 as usize;
  86. let mut r = vec![0u8; len];
  87. d.read_slice(&mut r)?;
  88. Ok(Proof::new(r))
  89. }
  90. }
  91. #[cfg(test)]
  92. mod tests {
  93. use super::*;
  94. use crate::{
  95. crypto::{keypair::PublicKey, mint_proof::create_mint_proof},
  96. zk::circuit::MintContract,
  97. };
  98. use group::ff::Field;
  99. use rand::rngs::OsRng;
  100. #[test]
  101. fn test_proof_serialization() -> Result<()> {
  102. let value = 110_u64;
  103. let token_id = DrkTokenId::from(42);
  104. let value_blind = DrkValueBlind::random(&mut OsRng);
  105. let token_blind = DrkValueBlind::random(&mut OsRng);
  106. let serial = DrkSerial::random(&mut OsRng);
  107. let coin_blind = DrkCoinBlind::random(&mut OsRng);
  108. let public_key = PublicKey::random(&mut OsRng);
  109. let pk = ProvingKey::build(11, &MintContract::default());
  110. let (proof, _) = create_mint_proof(
  111. &pk,
  112. value,
  113. token_id,
  114. value_blind,
  115. token_blind,
  116. serial,
  117. coin_blind,
  118. public_key,
  119. )?;
  120. let mut buf = vec![];
  121. proof.encode(&mut buf)?;
  122. let deserialized_proof: Proof = Decodable::decode(&mut buf.as_slice())?;
  123. assert_eq!(proof.as_ref(), deserialized_proof.as_ref());
  124. Ok(())
  125. }
  126. }