winter_air/proof/commitments.rs
1// Copyright (c) Facebook, Inc. and its affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6use alloc::vec::Vec;
7
8use crypto::Hasher;
9use utils::{
10 ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, SliceReader,
11};
12
13// COMMITMENTS
14// ================================================================================================
15/// Commitments made by the prover during commit phase of the protocol.
16///
17/// These commitments include:
18/// * Commitment to the extended execution trace, which may include commitments to one or more
19/// execution trace segments.
20/// * Commitment to the evaluations of constraint composition polynomial over LDE domain.
21/// * Commitments to the evaluations of polynomials at all FRI layers.
22///
23/// Internally, the commitments are stored as a sequence of bytes. Thus, to retrieve the
24/// commitments, [parse()](Commitments::parse) function should be used.
25#[derive(Debug, Clone, Default, Eq, PartialEq)]
26pub struct Commitments(Vec<u8>);
27
28impl Commitments {
29 // CONSTRUCTOR
30 // --------------------------------------------------------------------------------------------
31 /// Returns a new Commitments struct initialized with the provided commitments.
32 pub fn new<H: Hasher>(
33 trace_roots: Vec<H::Digest>,
34 constraint_root: H::Digest,
35 fri_roots: Vec<H::Digest>,
36 ) -> Self {
37 let mut bytes = Vec::new();
38 bytes.write_many(&trace_roots);
39 bytes.write(constraint_root);
40 bytes.write_many(&fri_roots);
41 Commitments(bytes)
42 }
43
44 // PUBLIC METHODS
45 // --------------------------------------------------------------------------------------------
46
47 /// Adds the specified commitment to the list of commitments.
48 pub fn add<H: Hasher>(&mut self, commitment: &H::Digest) {
49 commitment.write_into(&mut self.0);
50 }
51
52 // PARSING
53 // --------------------------------------------------------------------------------------------
54
55 /// Parses the serialized commitments into distinct parts.
56 ///
57 /// The parts are (in the order in which they appear in the tuple):
58 /// 1. Extended execution trace commitments.
59 /// 2. Constraint composition polynomial evaluation commitment.
60 /// 3. FRI layer commitments.
61 ///
62 /// # Errors
63 /// Returns an error if the bytes stored in self could not be parsed into the requested number
64 /// of commitments, or if there are any unconsumed bytes remaining after the parsing completes.
65 #[allow(clippy::type_complexity)]
66 pub fn parse<H: Hasher>(
67 self,
68 num_trace_segments: usize,
69 num_fri_layers: usize,
70 ) -> Result<(Vec<H::Digest>, H::Digest, Vec<H::Digest>), DeserializationError> {
71 let mut reader = SliceReader::new(&self.0);
72
73 // parse trace commitments
74 let trace_commitments = reader.read_many(num_trace_segments)?;
75
76 // parse constraint evaluation commitment:
77 let constraint_commitment = reader.read()?;
78
79 // read FRI commitments (+ 1 for remainder polynomial commitment)
80 let fri_commitments = reader.read_many(num_fri_layers + 1)?;
81
82 // make sure we consumed all available commitment bytes
83 if reader.has_more_bytes() {
84 return Err(DeserializationError::UnconsumedBytes);
85 }
86 Ok((trace_commitments, constraint_commitment, fri_commitments))
87 }
88}
89
90// SERIALIZATION
91// ================================================================================================
92
93impl Serializable for Commitments {
94 /// Serializes `self` and writes the resulting bytes into the `target`.
95 fn write_into<W: ByteWriter>(&self, target: &mut W) {
96 assert!(self.0.len() < u16::MAX as usize);
97 target.write_u16(self.0.len() as u16);
98 target.write_bytes(&self.0);
99 }
100
101 /// Returns an estimate of how many bytes are needed to represent self.
102 fn get_size_hint(&self) -> usize {
103 self.0.len() + 2
104 }
105}
106
107impl Deserializable for Commitments {
108 /// Reads commitments from the specified `source` and returns the result.
109 ///
110 /// # Errors
111 /// Returns an error of a valid Commitments struct could not be read from the specified
112 /// `source`.
113 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
114 let num_bytes = source.read_u16()? as usize;
115 let result = source.read_vec(num_bytes)?;
116 Ok(Commitments(result))
117 }
118}