@@ -160,4 +160,68 @@ static void secp256k1_bppp_rangeproof_prove_round1_impl(
160160 }
161161}
162162
163+
164+ /* Round 2 of the proof. Computes the reciprocals of the digits.
165+ * Serialized as 33 byte compressed point.
166+ * Always succeeds.
167+ */
168+ static void secp256k1_bppp_rangeproof_prove_round2_impl (
169+ secp256k1_bppp_rangeproof_prover_context * prover_ctx ,
170+ const secp256k1_bppp_generators * gens ,
171+ const secp256k1_ge * asset_genp ,
172+ unsigned char * output ,
173+ secp256k1_sha256 * transcript ,
174+ const size_t num_digits ,
175+ const size_t digit_base ,
176+ const unsigned char * nonce
177+ ) {
178+ size_t i ;
179+ size_t g_offset = digit_base > num_digits ? digit_base : num_digits ;
180+ secp256k1_gej r_commj ;
181+ secp256k1_scalar q_inv ;
182+
183+ /* We need only one value in this round, ignore the second value. */
184+ secp256k1_scalar_chacha20 (& prover_ctx -> b_r , & prover_ctx -> b_r , nonce , 4 );
185+
186+ /* Commit to the vector d in gens */
187+ secp256k1_ecmult_const (& r_commj , asset_genp , & prover_ctx -> b_r , 256 );
188+ for (i = 0 ; i < num_digits ; i ++ ) {
189+ secp256k1_gej resj ;
190+ secp256k1_ge r_comm ;
191+ secp256k1_scalar_add (& prover_ctx -> r [i ], & prover_ctx -> d [i ], & prover_ctx -> e );
192+ secp256k1_scalar_inverse (& prover_ctx -> r [i ], & prover_ctx -> r [i ]); /* r_i cannot be zero as it added by random value `e`*/
193+ secp256k1_ecmult_const (& resj , & gens -> gens [i ], & prover_ctx -> r [i ], 256 );
194+ secp256k1_ge_set_gej (& r_comm , & r_commj );
195+ secp256k1_gej_add_ge (& r_commj , & resj , & r_comm ); /* r_comm cannot be zero */
196+ }
197+
198+ {
199+ secp256k1_ge r_comm ;
200+ /* All r values are non-zero(computed by inverse), rcommj must be non-zero */
201+ VERIFY_CHECK (secp256k1_gej_is_infinity (& r_commj ) == 0 );
202+ secp256k1_ge_set_gej_var (& r_comm , & r_commj );
203+ secp256k1_fe_normalize_var (& r_comm .x );
204+ secp256k1_fe_normalize_var (& r_comm .y );
205+ secp256k1_bppp_serialize_pt (& output [0 ], & r_comm );
206+
207+ secp256k1_sha256_write (transcript , output , 33 );
208+ secp256k1_bppp_challenge_scalar (& prover_ctx -> q_sqrt , transcript , 0 );
209+ secp256k1_bppp_challenge_scalar (& prover_ctx -> x , transcript , 1 );
210+ secp256k1_bppp_challenge_scalar (& prover_ctx -> y , transcript , 2 );
211+ secp256k1_scalar_sqr (& prover_ctx -> q , & prover_ctx -> q_sqrt );
212+ }
213+ /* Pre-compute powers of q and q_inv. We will need them in future rounds. */
214+ secp256k1_bppp_rangeproof_powers_of_q (prover_ctx -> q_pows , & prover_ctx -> q , g_offset );
215+ secp256k1_scalar_inverse_var (& q_inv , & prover_ctx -> q ); /* q cannot be zero */
216+ secp256k1_bppp_rangeproof_powers_of_q (prover_ctx -> q_inv_pows , & q_inv , g_offset );
217+ /* Compute the values of alpha_m = (x/(e+i)*q_inv[i]) */
218+ for (i = 0 ; i < digit_base ; i ++ ) {
219+ secp256k1_scalar_set_int (& prover_ctx -> alpha_m [i ], i ); /* digit base is less than 2^32, can directly set*/
220+ secp256k1_scalar_add (& prover_ctx -> alpha_m [i ], & prover_ctx -> alpha_m [i ], & prover_ctx -> e );
221+ secp256k1_scalar_inverse_var (& prover_ctx -> alpha_m [i ], & prover_ctx -> alpha_m [i ]);
222+ secp256k1_scalar_mul (& prover_ctx -> alpha_m [i ], & prover_ctx -> alpha_m [i ], & prover_ctx -> x );
223+ secp256k1_scalar_mul (& prover_ctx -> alpha_m [i ], & prover_ctx -> alpha_m [i ], & prover_ctx -> q_inv_pows [i ]);
224+ }
225+ }
226+
163227#endif
0 commit comments