mina_tree/proofs/
prover.rs

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