Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
tamper_proof.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
8
12#include <cstddef>
13namespace bb {
14enum class TamperType {
15 MODIFY_SUMCHECK_UNIVARIATE, // Tamper with coefficients of a Sumcheck Round Univariate
16 MODIFY_SUMCHECK_EVAL, // Tamper with a multilinear evaluation of an entity
17 MODIFY_Z_PERM_COMMITMENT, // Tamper with the commitment to z_perm
18 MODIFY_GEMINI_WITNESS, // Tamper with a fold polynomial
19 END
20};
21
34template <typename InnerProver, typename InnerFlavor, typename ProofType>
35void tamper_with_proof(InnerProver& inner_prover, ProofType& inner_proof, TamperType type)
36{
37 using InnerFF = typename InnerFlavor::FF;
38 static constexpr size_t FIRST_WITNESS_INDEX = InnerFlavor::NUM_PRECOMPUTED_ENTITIES;
39
40 // Deserialize the transcript into the struct so that we can tamper it
41 auto num_public_inputs = inner_prover.proving_key->num_public_inputs();
42 inner_prover.transcript->deserialize_full_transcript(num_public_inputs);
43
44 switch (type) {
45
47 InnerFF random_value = InnerFF::random_element();
48 // Preserve the S_0(0) + S_0(1) = target_total_sum = 0, but the check S_0(u_0) = S_1(0) + S_1(1) would fail whp.
49 // The branching is due to the Flavor structure.
50 if constexpr (!InnerFlavor::HasZK) {
51 inner_prover.transcript->sumcheck_univariates[0].value_at(0) += random_value;
52 inner_prover.transcript->sumcheck_univariates[0].value_at(1) -= random_value;
53 } else {
54 inner_prover.transcript->zk_sumcheck_univariates[0].value_at(0) += random_value;
55 inner_prover.transcript->zk_sumcheck_univariates[0].value_at(1) -= random_value;
56 }
57 break;
58 }
59
61 // Corrupt the evaluation of the first witness. Captures that the check full_honk_purported_value =
62 // round.target_total_sum is performed in-circuit.
63 inner_prover.transcript->sumcheck_evaluations[FIRST_WITNESS_INDEX] = InnerFF::random_element();
64 break;
65
67 // Tamper with the commitment to z_perm.
68 inner_prover.transcript->z_perm_comm = inner_prover.transcript->z_perm_comm * InnerFF::random_element();
69 break;
70
72 InnerFF random_scalar = InnerFF::random_element();
73 // Tamper with the first fold commitment. In non-ZK cases, could only be captured by the pairing check.
74 inner_prover.transcript->gemini_fold_comms[0] = inner_prover.transcript->gemini_fold_comms[0] * random_scalar;
75 inner_prover.transcript->gemini_fold_evals[0] *= 0;
76 break;
77 }
78 case TamperType::END: {
79 break;
80 }
81 }
82
83 // Serialize transcript
84 // As inner_proof is extracted with export_proof, the internal values of inner_prover.transcript are reset
85 // Therefore, if we were to call export_proof without overriding num_frs_written and proof_start, the proof would
86 // be empty. This is a hack, we should probably have a better way of tampering with proofs.
87 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1411) Use std::unordered map in Transcript so that we
88 // can access/modify elements of a proof more easily
89 inner_prover.transcript->serialize_full_transcript();
90 inner_prover.transcript->proof_start = 0;
91 inner_prover.transcript->num_frs_written = InnerFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS() + num_public_inputs;
93 // Exclude the IPA points from the proof - they are added again by export_proof
94 inner_prover.transcript->num_frs_written -= IPA_PROOF_LENGTH;
95 }
96
97 // Extract the tampered proof
98 inner_proof = inner_prover.export_proof();
99}
100
106template <typename InnerProver, typename InnerFlavor, typename ProofType>
107void tamper_with_proof(ProofType& inner_proof, bool end_of_proof)
108{
109 using Commitment = typename InnerFlavor::Curve::AffineElement;
110 using FF = typename InnerFlavor::FF;
111
112 if (!end_of_proof) {
113 for (auto& val : inner_proof) {
114 if (val > 0) {
115 val += 1;
116 break;
117 }
118 }
119 } else {
120 // Manually deserialize, modify, and serialize the last commitment contained in the proof.
121 static constexpr size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<Commitment>();
122 size_t offset = inner_proof.size() - num_frs_comm;
123
124 auto element_frs = std::span{ inner_proof }.subspan(offset, num_frs_comm);
125 auto last_commitment = NativeTranscriptParams::template deserialize<Commitment>(element_frs);
126 last_commitment = last_commitment * FF(2);
127 auto last_commitment_reserialized = bb::NativeTranscriptParams::serialize(last_commitment);
128 std::copy(last_commitment_reserialized.begin(),
129 last_commitment_reserialized.end(),
130 inner_proof.begin() + static_cast<std::ptrdiff_t>(offset));
131 }
132}
133} // namespace bb
ssize_t offset
Definition engine.cpp:36
Entry point for Barretenberg command-line interface.
@ MODIFY_SUMCHECK_UNIVARIATE
typename Flavor::FF FF
void tamper_with_proof(InnerProver &inner_prover, ProofType &inner_proof, TamperType type)
Test method that provides several ways to tamper with a proof. TODO(https://github....
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static std::vector< DataType > serialize(const T &element)