proof.rs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2025 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. #[cfg(feature = "async-serial")]
  20. use darkfi_serial::async_trait;
  21. use darkfi_sdk::pasta::{pallas, vesta};
  22. use darkfi_serial::{SerialDecodable, SerialEncodable};
  23. use halo2_proofs::{
  24. helpers::SerdeFormat,
  25. plonk,
  26. plonk::{Circuit, SingleVerifier},
  27. poly::commitment::Params,
  28. transcript::{Blake2bRead, Blake2bWrite},
  29. };
  30. use rand::RngCore;
  31. #[derive(Clone, Debug)]
  32. pub struct VerifyingKey {
  33. pub params: Params<vesta::Affine>,
  34. pub vk: plonk::VerifyingKey<vesta::Affine>,
  35. }
  36. impl VerifyingKey {
  37. pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
  38. let params = Params::new(k);
  39. let vk = plonk::keygen_vk(&params, c).unwrap();
  40. VerifyingKey { params, vk }
  41. }
  42. pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
  43. let mut params = vec![];
  44. self.params.write(&mut params)?;
  45. let mut vk = vec![];
  46. self.vk.write(&mut vk, SerdeFormat::RawBytes)?;
  47. let _ = writer.write(&(params.len() as u32).to_le_bytes())?;
  48. let _ = writer.write(&params)?;
  49. let _ = writer.write(&(vk.len() as u32).to_le_bytes())?;
  50. let _ = writer.write(&vk)?;
  51. Ok(())
  52. }
  53. pub fn read<R: io::Read, ConcreteCircuit: Circuit<pallas::Base>>(
  54. reader: &mut R,
  55. circuit: ConcreteCircuit,
  56. ) -> io::Result<Self> {
  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>(
  76. &mut vk_c,
  77. SerdeFormat::RawBytes,
  78. circuit.params(),
  79. )?;
  80. Ok(Self { params, vk })
  81. }
  82. }
  83. #[derive(Clone, Debug)]
  84. pub struct ProvingKey {
  85. pub params: Params<vesta::Affine>,
  86. pub pk: plonk::ProvingKey<vesta::Affine>,
  87. }
  88. impl ProvingKey {
  89. pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
  90. let params = Params::new(k);
  91. let vk = plonk::keygen_vk(&params, c).unwrap();
  92. let pk = plonk::keygen_pk(&params, vk, c).unwrap();
  93. ProvingKey { params, pk }
  94. }
  95. pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
  96. let mut params = vec![];
  97. self.params.write(&mut params)?;
  98. let mut pk = vec![];
  99. self.pk.write(&mut pk, SerdeFormat::RawBytes)?;
  100. let _ = writer.write(&(params.len() as u32).to_le_bytes())?;
  101. let _ = writer.write(&params)?;
  102. let _ = writer.write(&(pk.len() as u32).to_le_bytes())?;
  103. let _ = writer.write(&pk)?;
  104. Ok(())
  105. }
  106. pub fn read<R: io::Read, ConcreteCircuit: Circuit<pallas::Base>>(
  107. reader: &mut R,
  108. circuit: ConcreteCircuit,
  109. ) -> io::Result<Self> {
  110. let mut params_len = [0u8; 4];
  111. reader.read_exact(&mut params_len)?;
  112. let params_len = u32::from_le_bytes(params_len) as usize;
  113. let mut params_buf = vec![0u8; params_len];
  114. reader.read_exact(&mut params_buf)?;
  115. assert!(params_buf.len() == params_len);
  116. let mut pk_len = [0u8; 4];
  117. reader.read_exact(&mut pk_len)?;
  118. let pk_len = u32::from_le_bytes(pk_len) as usize;
  119. let mut pk_buf = vec![0u8; pk_len];
  120. reader.read_exact(&mut pk_buf)?;
  121. assert!(pk_buf.len() == pk_len);
  122. let mut params_c = Cursor::new(params_buf);
  123. let params: Params<vesta::Affine> = Params::read(&mut params_c)?;
  124. let mut pk_c = Cursor::new(pk_buf);
  125. let pk: plonk::ProvingKey<vesta::Affine> =
  126. plonk::ProvingKey::read::<Cursor<Vec<u8>>, ConcreteCircuit>(
  127. &mut pk_c,
  128. SerdeFormat::RawBytes,
  129. circuit.params(),
  130. )?;
  131. Ok(Self { params, pk })
  132. }
  133. }
  134. #[derive(Clone, Default, PartialEq, Eq, SerialEncodable, SerialDecodable)]
  135. pub struct Proof(Vec<u8>);
  136. impl AsRef<[u8]> for Proof {
  137. fn as_ref(&self) -> &[u8] {
  138. &self.0
  139. }
  140. }
  141. impl core::fmt::Debug for Proof {
  142. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  143. write!(f, "Proof({:?})", self.0)
  144. }
  145. }
  146. impl Proof {
  147. pub fn create(
  148. pk: &ProvingKey,
  149. circuits: &[impl Circuit<pallas::Base>],
  150. instances: &[pallas::Base],
  151. mut rng: impl RngCore,
  152. ) -> std::result::Result<Self, plonk::Error> {
  153. let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
  154. plonk::create_proof(
  155. &pk.params,
  156. &pk.pk,
  157. circuits,
  158. &[&[instances]],
  159. &mut rng,
  160. &mut transcript,
  161. )?;
  162. Ok(Proof(transcript.finalize()))
  163. }
  164. pub fn verify(
  165. &self,
  166. vk: &VerifyingKey,
  167. instances: &[pallas::Base],
  168. ) -> std::result::Result<(), plonk::Error> {
  169. let strategy = SingleVerifier::new(&vk.params);
  170. let mut transcript = Blake2bRead::init(&self.0[..]);
  171. plonk::verify_proof(&vk.params, &vk.vk, strategy, &[&[instances]], &mut transcript)
  172. }
  173. pub fn new(bytes: Vec<u8>) -> Self {
  174. Proof(bytes)
  175. }
  176. }