proof.rs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{io, io::Cursor};
  19. use darkfi_serial::{SerialDecodable, SerialEncodable};
  20. use halo2_proofs::{
  21. pasta::{pallas, vesta},
  22. plonk,
  23. plonk::{Circuit, SingleVerifier},
  24. poly::commitment::Params,
  25. transcript::{Blake2bRead, Blake2bWrite},
  26. };
  27. use rand::RngCore;
  28. #[derive(Clone, Debug)]
  29. pub struct VerifyingKey {
  30. pub params: Params<vesta::Affine>,
  31. pub vk: plonk::VerifyingKey<vesta::Affine>,
  32. }
  33. impl VerifyingKey {
  34. pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
  35. let params = Params::new(k);
  36. let vk = plonk::keygen_vk(&params, c).unwrap();
  37. VerifyingKey { params, vk }
  38. }
  39. pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
  40. // FIXME: This can be optimized.
  41. let mut params = vec![];
  42. self.params.write(&mut params)?;
  43. let mut vk = vec![];
  44. self.vk.write(&mut vk)?;
  45. let _ = writer.write(&(params.len() as u32).to_le_bytes())?;
  46. let _ = writer.write(&params)?;
  47. let _ = writer.write(&(vk.len() as u32).to_le_bytes())?;
  48. let _ = writer.write(&vk)?;
  49. Ok(())
  50. }
  51. pub fn read<R: io::Read, ConcreteCircuit: Circuit<pallas::Base>>(
  52. reader: &mut R,
  53. ) -> io::Result<Self> {
  54. // FIXME: This can be optimized
  55. // FIXME: Don't assert
  56. // FIXME: Make sure that the size is legitimate.
  57. // The format chosen in write():
  58. // [params.len()<u32>, params..., vk.len()<u32>, vk...]
  59. let mut params_len = [0u8; 4];
  60. reader.read_exact(&mut params_len)?;
  61. let params_len = u32::from_le_bytes(params_len) as usize;
  62. let mut params_buf = vec![0u8; params_len];
  63. reader.read_exact(&mut params_buf)?;
  64. assert!(params_buf.len() == params_len);
  65. let mut vk_len = [0u8; 4];
  66. reader.read_exact(&mut vk_len)?;
  67. let vk_len = u32::from_le_bytes(vk_len) as usize;
  68. let mut vk_buf = vec![0u8; vk_len];
  69. reader.read_exact(&mut vk_buf)?;
  70. assert!(vk_buf.len() == vk_len);
  71. let mut params_c = Cursor::new(params_buf);
  72. let params: Params<vesta::Affine> = Params::read(&mut params_c)?;
  73. let mut vk_c = Cursor::new(vk_buf);
  74. let vk: plonk::VerifyingKey<vesta::Affine> =
  75. plonk::VerifyingKey::read::<Cursor<Vec<u8>>, ConcreteCircuit>(&mut vk_c, &params)?;
  76. Ok(Self { params, vk })
  77. }
  78. }
  79. #[derive(Clone, Debug)]
  80. pub struct ProvingKey {
  81. pub params: Params<vesta::Affine>,
  82. pub pk: plonk::ProvingKey<vesta::Affine>,
  83. }
  84. impl ProvingKey {
  85. pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
  86. let params = Params::new(k);
  87. let vk = plonk::keygen_vk(&params, c).unwrap();
  88. let pk = plonk::keygen_pk(&params, vk, c).unwrap();
  89. ProvingKey { params, pk }
  90. }
  91. }
  92. #[derive(Clone, Default, PartialEq, Eq, SerialEncodable, SerialDecodable)]
  93. pub struct Proof(Vec<u8>);
  94. impl AsRef<[u8]> for Proof {
  95. fn as_ref(&self) -> &[u8] {
  96. &self.0
  97. }
  98. }
  99. impl core::fmt::Debug for Proof {
  100. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  101. write!(f, "Proof({:?})", self.0)
  102. }
  103. }
  104. impl Proof {
  105. pub fn create(
  106. pk: &ProvingKey,
  107. circuits: &[impl Circuit<pallas::Base>],
  108. instances: &[pallas::Base],
  109. mut rng: impl RngCore,
  110. ) -> std::result::Result<Self, plonk::Error> {
  111. let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
  112. plonk::create_proof(
  113. &pk.params,
  114. &pk.pk,
  115. circuits,
  116. &[&[instances]],
  117. &mut rng,
  118. &mut transcript,
  119. )?;
  120. Ok(Proof(transcript.finalize()))
  121. }
  122. pub fn verify(
  123. &self,
  124. vk: &VerifyingKey,
  125. instances: &[pallas::Base],
  126. ) -> std::result::Result<(), plonk::Error> {
  127. let strategy = SingleVerifier::new(&vk.params);
  128. let mut transcript = Blake2bRead::init(&self.0[..]);
  129. plonk::verify_proof(&vk.params, &vk.vk, strategy, &[&[instances]], &mut transcript)
  130. }
  131. pub fn new(bytes: Vec<u8>) -> Self {
  132. Proof(bytes)
  133. }
  134. }