mina_tree/proofs/
prover.rs

1use std::{borrow::Cow, str::FromStr};
2
3use super::{util::extract_bulletproof, ProverProof};
4use kimchi::{
5    poly_commitment::PolyComm,
6    proof::{PointEvaluations, ProofEvaluations, ProverCommitments, RecursionChallenge},
7};
8use mina_curves::pasta::{Fp, Fq, Pallas};
9use mina_p2p_messages::{bigint::BigInt, v2::PicklesProofProofsVerified2ReprStableV2};
10use once_cell::sync::Lazy;
11use poly_commitment::{commitment::CommitmentCurve, ipa::OpeningProof};
12
13fn get_challenge_polynomial_commitments_padding() -> (BigInt, BigInt) {
14    static PADDING: Lazy<(BigInt, BigInt)> = Lazy::new(|| {
15        let first = Fp::from_str(
16            "8063668238751197448664615329057427953229339439010717262869116690340613895496",
17        )
18        .unwrap();
19        let second = Fp::from_str(
20            "2694491010813221541025626495812026140144933943906714931997499229912601205355",
21        )
22        .unwrap();
23
24        (first.into(), second.into())
25    });
26
27    PADDING.clone()
28}
29
30pub fn make_padded_proof_from_p2p(
31    PicklesProofProofsVerified2ReprStableV2 {
32        statement,
33        prev_evals: _, // unused
34        proof,
35    }: &PicklesProofProofsVerified2ReprStableV2,
36) -> anyhow::Result<ProverProof<Fq>> {
37    let of_coord = |(a, b): &(BigInt, BigInt)| -> anyhow::Result<_> {
38        Ok(Pallas::of_coordinates(a.to_field()?, b.to_field()?))
39    };
40
41    let make_poly = |poly: &(BigInt, BigInt)| -> anyhow::Result<_> {
42        Ok(PolyComm {
43            chunks: vec![of_coord(poly)?],
44        })
45    };
46
47    let w_comm: [PolyComm<Pallas>; 15] =
48        crate::try_array_into_with(&proof.commitments.w_comm, make_poly)?;
49    let z_comm: PolyComm<Pallas> = make_poly(&proof.commitments.z_comm)?;
50    let t_comm: PolyComm<Pallas> = {
51        let chunks = proof
52            .commitments
53            .t_comm
54            .iter()
55            .map(of_coord)
56            .collect::<Result<_, _>>()?;
57        PolyComm { chunks }
58    };
59
60    let bulletproof = &proof.bulletproof;
61
62    let lr = &bulletproof.lr;
63    let lr: Vec<(Pallas, Pallas)> = lr
64        .iter()
65        .map(|(a, b)| Ok((of_coord(a)?, of_coord(b)?)))
66        .collect::<anyhow::Result<_>>()?;
67
68    let delta: Pallas = of_coord(&bulletproof.delta)?;
69    let z1: Fq = bulletproof.z_1.to_field()?;
70    let z2: Fq = bulletproof.z_2.to_field()?;
71
72    let sg: Pallas = of_coord(&bulletproof.challenge_polynomial_commitment)?;
73
74    let evals = &proof.evaluations;
75
76    let to_pt_eval = |(first, second): &(BigInt, BigInt)| -> anyhow::Result<_> {
77        Ok(PointEvaluations {
78            zeta: vec![first.to_field::<Fq>()?],
79            zeta_omega: vec![second.to_field::<Fq>()?],
80        })
81    };
82
83    let evals: ProofEvaluations<PointEvaluations<Vec<Fq>>> = ProofEvaluations {
84        w: crate::try_array_into_with(&evals.w, to_pt_eval)?,
85        z: to_pt_eval(&evals.z)?,
86        s: crate::try_array_into_with(&evals.s, to_pt_eval)?,
87        generic_selector: to_pt_eval(&evals.generic_selector)?,
88        poseidon_selector: to_pt_eval(&evals.poseidon_selector)?,
89        coefficients: crate::try_array_into_with(&evals.coefficients, to_pt_eval)?,
90        complete_add_selector: to_pt_eval(&evals.complete_add_selector)?,
91        mul_selector: to_pt_eval(&evals.mul_selector)?,
92        emul_selector: to_pt_eval(&evals.emul_selector)?,
93        endomul_scalar_selector: to_pt_eval(&evals.endomul_scalar_selector)?,
94        range_check0_selector: None,
95        range_check1_selector: None,
96        foreign_field_add_selector: None,
97        foreign_field_mul_selector: None,
98        xor_selector: None,
99        rot_selector: None,
100        lookup_aggregation: None,
101        lookup_table: None,
102        lookup_sorted: [None, None, None, None, None],
103        runtime_lookup_table: None,
104        runtime_lookup_table_selector: None,
105        xor_lookup_selector: None,
106        lookup_gate_lookup_selector: None,
107        range_check_lookup_selector: None,
108        foreign_field_mul_lookup_selector: None,
109        public: None,
110    };
111
112    let ft_eval1: Fq = proof.ft_eval1.to_field()?;
113
114    let old_bulletproof_challenges = &statement
115        .proof_state
116        .messages_for_next_wrap_proof
117        .old_bulletproof_challenges;
118    let old_bulletproof_challenges: Vec<[Fq; 15]> = extract_bulletproof(&[
119        old_bulletproof_challenges.0[0].0.clone(),
120        old_bulletproof_challenges.0[1].0.clone(),
121    ]);
122
123    let make_poly = |poly: &(BigInt, BigInt)| -> anyhow::Result<_> {
124        let point = of_coord(poly)?;
125        Ok(PolyComm {
126            chunks: vec![point],
127        })
128    };
129
130    let mut challenge_polynomial_commitments = Cow::Borrowed(
131        &statement
132            .messages_for_next_step_proof
133            .challenge_polynomial_commitments,
134    );
135
136    // Prepend padding:
137    // <https://github.com/MinaProtocol/mina/blob/bfd1009abdbee78979ff0343cc73a3480e862f58/src/lib/pickles/verify.ml#L361C1-L364C51>
138    while challenge_polynomial_commitments.len() < 2 {
139        let padding = get_challenge_polynomial_commitments_padding();
140        challenge_polynomial_commitments
141            .to_mut()
142            .push_front(padding);
143    }
144
145    let challenge_polynomial_commitments: Vec<PolyComm<Pallas>> = challenge_polynomial_commitments
146        .iter()
147        .map(make_poly)
148        .collect::<Result<_, _>>()?;
149
150    // Or pad with `Wrap_hack.pad_accumulator`
151    assert_eq!(old_bulletproof_challenges.len(), 2);
152    assert_eq!(challenge_polynomial_commitments.len(), 2);
153    let prev_challenges: Vec<RecursionChallenge<Pallas>> = old_bulletproof_challenges
154        .iter()
155        .zip(challenge_polynomial_commitments)
156        .map(|(chals, comm)| RecursionChallenge::new(chals.to_vec(), comm))
157        .collect();
158
159    Ok(ProverProof::<Fq> {
160        commitments: ProverCommitments {
161            w_comm,
162            z_comm,
163            t_comm,
164            lookup: None,
165        },
166        proof: OpeningProof {
167            lr,
168            delta,
169            z1,
170            z2,
171            sg,
172        },
173        evals,
174        ft_eval1,
175        prev_challenges,
176    })
177}