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