1use std::{io, io::Cursor};
19
20#[cfg(feature = "async-serial")]
21use darkfi_serial::async_trait;
22
23use darkfi_sdk::pasta::{pallas, vesta};
24use darkfi_serial::{SerialDecodable, SerialEncodable};
25use halo2_proofs::{
26 helpers::SerdeFormat,
27 plonk,
28 plonk::{Circuit, SingleVerifier},
29 poly::commitment::Params,
30 transcript::{Blake2bRead, Blake2bWrite},
31};
32use rand::RngCore;
33
34#[derive(Clone, Debug)]
35pub struct VerifyingKey {
36 pub params: Params<vesta::Affine>,
37 pub vk: plonk::VerifyingKey<vesta::Affine>,
38}
39
40impl VerifyingKey {
41 pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
42 let params = Params::new(k);
43 let vk = plonk::keygen_vk(¶ms, c).unwrap();
44 VerifyingKey { params, vk }
45 }
46
47 pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
48 let mut params = vec![];
49 self.params.write(&mut params)?;
50
51 let mut vk = vec![];
52 self.vk.write(&mut vk, SerdeFormat::RawBytes)?;
53
54 let _ = writer.write(&(params.len() as u32).to_le_bytes())?;
55 let _ = writer.write(¶ms)?;
56 let _ = writer.write(&(vk.len() as u32).to_le_bytes())?;
57 let _ = writer.write(&vk)?;
58
59 Ok(())
60 }
61
62 pub fn read<R: io::Read, ConcreteCircuit: Circuit<pallas::Base>>(
63 reader: &mut R,
64 circuit: ConcreteCircuit,
65 ) -> io::Result<Self> {
66 let mut params_len = [0u8; 4];
70 reader.read_exact(&mut params_len)?;
71 let params_len = u32::from_le_bytes(params_len) as usize;
72
73 let mut params_buf = vec![0u8; params_len];
74 reader.read_exact(&mut params_buf)?;
75
76 assert!(params_buf.len() == params_len);
77
78 let mut vk_len = [0u8; 4];
79 reader.read_exact(&mut vk_len)?;
80 let vk_len = u32::from_le_bytes(vk_len) as usize;
81
82 let mut vk_buf = vec![0u8; vk_len];
83 reader.read_exact(&mut vk_buf)?;
84
85 assert!(vk_buf.len() == vk_len);
86
87 let mut params_c = Cursor::new(params_buf);
88 let params: Params<vesta::Affine> = Params::read(&mut params_c)?;
89
90 let mut vk_c = Cursor::new(vk_buf);
91 let vk: plonk::VerifyingKey<vesta::Affine> =
92 plonk::VerifyingKey::read::<Cursor<Vec<u8>>, ConcreteCircuit>(
93 &mut vk_c,
94 SerdeFormat::RawBytes,
95 circuit.params(),
96 )?;
97
98 Ok(Self { params, vk })
99 }
100}
101
102#[derive(Clone, Debug)]
103pub struct ProvingKey {
104 pub params: Params<vesta::Affine>,
105 pub pk: plonk::ProvingKey<vesta::Affine>,
106}
107
108impl ProvingKey {
109 pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
110 let params = Params::new(k);
111 let vk = plonk::keygen_vk(¶ms, c).unwrap();
112 let pk = plonk::keygen_pk(¶ms, vk, c).unwrap();
113 ProvingKey { params, pk }
114 }
115
116 pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
117 let mut params = vec![];
118 self.params.write(&mut params)?;
119
120 let mut pk = vec![];
121 self.pk.write(&mut pk, SerdeFormat::RawBytes)?;
122
123 let _ = writer.write(&(params.len() as u32).to_le_bytes())?;
124 let _ = writer.write(¶ms)?;
125 let _ = writer.write(&(pk.len() as u32).to_le_bytes())?;
126 let _ = writer.write(&pk)?;
127
128 Ok(())
129 }
130
131 pub fn read<R: io::Read, ConcreteCircuit: Circuit<pallas::Base>>(
132 reader: &mut R,
133 circuit: ConcreteCircuit,
134 ) -> io::Result<Self> {
135 let mut params_len = [0u8; 4];
136 reader.read_exact(&mut params_len)?;
137 let params_len = u32::from_le_bytes(params_len) as usize;
138
139 let mut params_buf = vec![0u8; params_len];
140 reader.read_exact(&mut params_buf)?;
141
142 assert!(params_buf.len() == params_len);
143
144 let mut pk_len = [0u8; 4];
145 reader.read_exact(&mut pk_len)?;
146 let pk_len = u32::from_le_bytes(pk_len) as usize;
147
148 let mut pk_buf = vec![0u8; pk_len];
149 reader.read_exact(&mut pk_buf)?;
150
151 assert!(pk_buf.len() == pk_len);
152
153 let mut params_c = Cursor::new(params_buf);
154 let params: Params<vesta::Affine> = Params::read(&mut params_c)?;
155
156 let mut pk_c = Cursor::new(pk_buf);
157 let pk: plonk::ProvingKey<vesta::Affine> =
158 plonk::ProvingKey::read::<Cursor<Vec<u8>>, ConcreteCircuit>(
159 &mut pk_c,
160 SerdeFormat::RawBytes,
161 circuit.params(),
162 )?;
163
164 Ok(Self { params, pk })
165 }
166}
167
168#[derive(Clone, Default, PartialEq, Eq, SerialEncodable, SerialDecodable)]
169pub struct Proof(Vec<u8>);
170
171impl AsRef<[u8]> for Proof {
172 fn as_ref(&self) -> &[u8] {
173 &self.0
174 }
175}
176
177impl core::fmt::Debug for Proof {
178 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
179 write!(f, "Proof({:?})", self.0)
180 }
181}
182
183impl Proof {
184 pub fn create(
185 pk: &ProvingKey,
186 circuits: &[impl Circuit<pallas::Base>],
187 instances: &[pallas::Base],
188 mut rng: impl RngCore,
189 ) -> std::result::Result<Self, plonk::Error> {
190 let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
191 plonk::create_proof(
192 &pk.params,
193 &pk.pk,
194 circuits,
195 &[&[instances]],
196 &mut rng,
197 &mut transcript,
198 )?;
199
200 Ok(Proof(transcript.finalize()))
201 }
202
203 pub fn verify(
204 &self,
205 vk: &VerifyingKey,
206 instances: &[pallas::Base],
207 ) -> std::result::Result<(), plonk::Error> {
208 let strategy = SingleVerifier::new(&vk.params);
209 let mut transcript = Blake2bRead::init(&self.0[..]);
210
211 plonk::verify_proof(&vk.params, &vk.vk, strategy, &[&[instances]], &mut transcript)
212 }
213
214 pub fn new(bytes: Vec<u8>) -> Self {
215 Proof(bytes)
216 }
217}