proof.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. use std::io;
  2. // TODO: Alias vesta::Affine to something
  3. use halo2::{
  4. plonk,
  5. plonk::Circuit,
  6. poly::commitment::Params,
  7. transcript::{Blake2bRead, Blake2bWrite},
  8. };
  9. use pasta_curves::vesta;
  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. pubinputs: &[DrkCircuitField],
  52. ) -> std::result::Result<Self, plonk::Error> {
  53. let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
  54. plonk::create_proof(&pk.params, &pk.pk, circuits, &[&[pubinputs]], &mut transcript)?;
  55. Ok(Proof(transcript.finalize()))
  56. }
  57. pub fn verify(
  58. &self,
  59. vk: &VerifyingKey,
  60. pubinputs: &[DrkCircuitField],
  61. ) -> std::result::Result<(), plonk::Error> {
  62. let msm = vk.params.empty_msm();
  63. let mut transcript = Blake2bRead::init(&self.0[..]);
  64. let guard = plonk::verify_proof(&vk.params, &vk.vk, msm, &[&[pubinputs]], &mut transcript)?;
  65. let msm = guard.clone().use_challenges();
  66. if msm.eval() {
  67. Ok(())
  68. } else {
  69. Err(plonk::Error::ConstraintSystemFailure)
  70. }
  71. }
  72. pub fn new(bytes: Vec<u8>) -> Self {
  73. Proof(bytes)
  74. }
  75. }
  76. impl Encodable for Proof {
  77. fn encode<S: io::Write>(&self, s: S) -> Result<usize> {
  78. encode_with_size(self.as_ref(), s)
  79. }
  80. }
  81. impl Decodable for Proof {
  82. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  83. let len = VarInt::decode(&mut d)?.0 as usize;
  84. let mut r = vec![0u8; len];
  85. d.read_slice(&mut r)?;
  86. Ok(Proof::new(r))
  87. }
  88. }
  89. #[cfg(test)]
  90. mod tests {
  91. use super::*;
  92. use crate::{
  93. crypto::{keypair::PublicKey, mint_proof::create_mint_proof},
  94. zk::circuit::MintContract,
  95. };
  96. use halo2::arithmetic::Field;
  97. use rand::rngs::OsRng;
  98. #[test]
  99. fn test_proof_serialization() -> Result<()> {
  100. let value = 110_u64;
  101. let token_id = DrkTokenId::from(42);
  102. let value_blind = DrkValueBlind::random(&mut OsRng);
  103. let token_blind = DrkValueBlind::random(&mut OsRng);
  104. let serial = DrkSerial::random(&mut OsRng);
  105. let coin_blind = DrkCoinBlind::random(&mut OsRng);
  106. let public_key = PublicKey::random(&mut OsRng);
  107. let pk = ProvingKey::build(11, MintContract::default());
  108. let (proof, _) = create_mint_proof(
  109. &pk,
  110. value,
  111. token_id,
  112. value_blind,
  113. token_blind,
  114. serial,
  115. coin_blind,
  116. public_key,
  117. )?;
  118. let mut buf = vec![];
  119. proof.encode(&mut buf)?;
  120. let deserialized_proof: Proof = Decodable::decode(&mut buf.as_slice())?;
  121. assert_eq!(proof.as_ref(), deserialized_proof.as_ref());
  122. Ok(())
  123. }
  124. }