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: _, 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_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 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 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}