snarkvm_algorithms/snark/varuna/data_structures/
circuit_verifying_key.rs1use crate::{polycommit::sonic_pc, snark::varuna::ahp::indexer::*};
17use snarkvm_curves::PairingEngine;
18use snarkvm_utilities::{FromBytes, FromBytesDeserializer, ToBytes, ToBytesSerializer, into_io_error, serialize::*};
19
20use anyhow::Result;
21use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
22use std::{
23 cmp::Ordering,
24 fmt,
25 io::{self, Read, Write},
26 str::FromStr,
27 string::String,
28};
29
30#[derive(Debug, Clone, PartialEq, Eq, CanonicalSerialize)]
32pub struct CircuitVerifyingKey<E: PairingEngine> {
33 pub circuit_info: CircuitInfo,
36 pub circuit_commitments: Vec<sonic_pc::Commitment<E>>,
38 pub id: CircuitId,
39}
40
41impl<E: PairingEngine> Valid for CircuitVerifyingKey<E> {
42 fn check(&self) -> Result<(), SerializationError> {
43 self.circuit_info.check()?;
44 sonic_pc::Commitment::<E>::batch_check(self.circuit_commitments.iter())?;
45 self.id.check()
46 }
47
48 fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError>
49 where
50 Self: 'a,
51 {
52 #[cfg(not(feature = "serial"))]
53 {
54 use rayon::{iter::ParallelBridge, prelude::ParallelIterator};
55 batch.par_bridge().try_for_each(|e| e.check())?;
56 }
57 #[cfg(feature = "serial")]
58 {
59 for item in batch {
60 item.check()?;
61 }
62 }
63 Ok(())
64 }
65}
66
67impl<E: PairingEngine> CanonicalDeserialize for CircuitVerifyingKey<E> {
68 fn deserialize_with_mode<R: Read>(
69 mut reader: R,
70 compress: Compress,
71 validate: Validate,
72 ) -> Result<Self, SerializationError> {
73 let circuit_info = CircuitInfo::deserialize_with_mode(&mut reader, compress, validate)?;
75
76 let len = u64::deserialize_with_mode(&mut reader, compress, validate)?;
78
79 const MAX_CIRCUIT_COMMITMENTS: u64 = 12;
81 if len > MAX_CIRCUIT_COMMITMENTS {
82 return Err(SerializationError::InvalidData);
83 }
84
85 let mut circuit_commitments = Vec::with_capacity(len as usize);
87 for _ in 0..len {
88 circuit_commitments.push(sonic_pc::Commitment::deserialize_with_mode(&mut reader, compress, Validate::No)?);
89 }
90
91 if let Validate::Yes = validate {
92 sonic_pc::Commitment::<E>::batch_check(circuit_commitments.iter())?;
93 }
94
95 let id = CircuitId::deserialize_with_mode(&mut reader, compress, validate)?;
97
98 Ok(CircuitVerifyingKey { circuit_info, circuit_commitments, id })
99 }
100}
101
102impl<E: PairingEngine> FromBytes for CircuitVerifyingKey<E> {
103 fn read_le<R: Read>(r: R) -> io::Result<Self> {
104 Self::deserialize_compressed(r)
105 .map_err(|err| into_io_error(anyhow::Error::from(err).context("could not deserialize CircuitVerifyingKey")))
106 }
107
108 fn read_le_unchecked<R: Read>(r: R) -> io::Result<Self> {
109 Self::deserialize_compressed_unchecked(r)
110 .map_err(|err| into_io_error(anyhow::Error::from(err).context("could not deserialize CircuitVerifyingKey")))
111 }
112}
113
114impl<E: PairingEngine> ToBytes for CircuitVerifyingKey<E> {
115 fn write_le<W: Write>(&self, w: W) -> io::Result<()> {
116 self.serialize_compressed(w)
117 .map_err(|err| into_io_error(anyhow::Error::from(err).context("could not serialize CircuitVerifyingKey")))
118 }
119}
120
121impl<E: PairingEngine> CircuitVerifyingKey<E> {
122 pub fn iter(&self) -> impl Iterator<Item = &sonic_pc::Commitment<E>> {
124 self.circuit_commitments.iter()
125 }
126}
127
128impl<E: PairingEngine> FromStr for CircuitVerifyingKey<E> {
129 type Err = anyhow::Error;
130
131 #[inline]
132 fn from_str(vk_hex: &str) -> Result<Self, Self::Err> {
133 Self::from_bytes_le(&hex::decode(vk_hex)?)
134 }
135}
136
137impl<E: PairingEngine> fmt::Display for CircuitVerifyingKey<E> {
138 #[inline]
139 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140 let vk_hex = hex::encode(self.to_bytes_le().expect("Failed to convert verifying key to bytes"));
141 write!(f, "{vk_hex}")
142 }
143}
144
145impl<E: PairingEngine> Serialize for CircuitVerifyingKey<E> {
146 #[inline]
147 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
148 match serializer.is_human_readable() {
149 true => serializer.collect_str(self),
150 false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
151 }
152 }
153}
154
155impl<'de, E: PairingEngine> Deserialize<'de> for CircuitVerifyingKey<E> {
156 #[inline]
157 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
158 match deserializer.is_human_readable() {
159 true => {
160 let s: String = Deserialize::deserialize(deserializer)?;
161 FromStr::from_str(&s).map_err(de::Error::custom)
162 }
163 false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "verifying key"),
164 }
165 }
166}
167
168impl<E: PairingEngine> Ord for CircuitVerifyingKey<E> {
169 fn cmp(&self, other: &Self) -> Ordering {
170 self.id.cmp(&other.id)
171 }
172}
173
174impl<E: PairingEngine> PartialOrd for CircuitVerifyingKey<E> {
175 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
176 Some(self.cmp(other))
177 }
178}