@@ -267,7 +267,81 @@ SECP256K1_INLINE static void secp256k1_rangeproof_init_rng(
267267 secp256k1_rfc6979_hmac_sha256_initialize (rng , rngseed , 32 + 33 + 33 + len );
268268}
269269
270- SECP256K1_INLINE static int secp256k1_rangeproof_genrand (
270+ SECP256K1_INLINE static int secp256k1_rangeproof_genrand_sign (
271+ secp256k1_scalar * sec ,
272+ secp256k1_scalar * s ,
273+ const unsigned char * blind ,
274+ const unsigned char * message ,
275+ const size_t msg_len ,
276+ const secp256k1_rangeproof_header * header ,
277+ const uint64_t proven_value ,
278+ secp256k1_rfc6979_hmac_sha256 * rng
279+ ) {
280+ unsigned char tmp [32 ];
281+ secp256k1_scalar acc ;
282+ int overflow ;
283+ int ret ;
284+ size_t i ;
285+ size_t npub ;
286+ secp256k1_scalar_set_b32 (& acc , blind , & overflow );
287+ if (overflow ) {
288+ return 0 ;
289+ }
290+ secp256k1_scalar_negate (& acc , & acc );
291+ npub = 0 ;
292+ ret = 1 ;
293+ for (i = 0 ; i < header -> n_rings ; i ++ ) {
294+ size_t j ;
295+ if (i < header -> n_rings - 1 ) {
296+ secp256k1_rfc6979_hmac_sha256_generate (rng , tmp , 32 );
297+ do {
298+ secp256k1_rfc6979_hmac_sha256_generate (rng , tmp , 32 );
299+ secp256k1_scalar_set_b32 (& sec [i ], tmp , & overflow );
300+ } while (overflow || secp256k1_scalar_is_zero (& sec [i ]));
301+ secp256k1_scalar_add (& acc , & acc , & sec [i ]);
302+ } else {
303+ secp256k1_scalar_negate (& acc , & acc );
304+ sec [i ] = acc ;
305+ }
306+ for (j = 0 ; j < header -> rsizes [i ]; j ++ ) {
307+ secp256k1_rfc6979_hmac_sha256_generate (rng , tmp , 32 );
308+ if (message && i < header -> n_rings - 1 ) {
309+ /* encode the message side-channel */
310+ int b ;
311+ for (b = 0 ; b < 32 ; b ++ ) {
312+ if ((i * 4 + j ) * 32 + b < msg_len ) {
313+ tmp [b ] ^= message [(i * 4 + j ) * 32 + b ];
314+ }
315+ }
316+ } else if (i == header -> n_rings - 1 ) {
317+ /* encode the value in the final ring thrice, both to inform the rewinder
318+ * which indices are real and to signal to the rewinder that its nonce is
319+ * correct and it is decoding something non-random */
320+ size_t jidx = header -> rsizes [i ] - 1 ;
321+ jidx -= (proven_value >> (2 * i )) == jidx ;
322+ if (j == jidx ) {
323+ size_t k ;
324+ tmp [0 ] ^= 128 ;
325+ for (k = 0 ; k < 8 ; k ++ ) {
326+ unsigned char xor = (proven_value >> (56 - k * 8 )) & 255 ;
327+ tmp [8 + k ] ^= xor ;
328+ tmp [16 + k ] ^= xor ;
329+ tmp [24 + k ] ^= xor ;
330+ }
331+ }
332+ }
333+ secp256k1_scalar_set_b32 (& s [npub ], tmp , & overflow );
334+ ret &= !(overflow || secp256k1_scalar_is_zero (& s [npub ]));
335+ npub ++ ;
336+ }
337+ }
338+ secp256k1_rfc6979_hmac_sha256_finalize (rng );
339+ secp256k1_scalar_clear (& acc );
340+ memset (tmp , 0 , 32 );
341+ return ret ;
342+ }
343+
344+ SECP256K1_INLINE static int secp256k1_rangeproof_genrand_rewind (
271345 secp256k1_scalar * sec ,
272346 secp256k1_scalar * s ,
273347 unsigned char * message ,
@@ -301,7 +375,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_genrand(
301375 secp256k1_rfc6979_hmac_sha256_generate (rng , tmp , 32 );
302376 if (message ) {
303377 for (b = 0 ; b < 32 ; b ++ ) {
304- tmp [b ] ^= message [(i * 4 + j ) * 32 + b ];
305378 message [(i * 4 + j ) * 32 + b ] = tmp [b ];
306379 }
307380 }
@@ -326,9 +399,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
326399 secp256k1_scalar s [128 ]; /* Signatures in our proof, most forged. */
327400 secp256k1_scalar sec [32 ]; /* Blinding factors for the correct digits. */
328401 secp256k1_scalar k [32 ]; /* Nonces for our non-forged signatures. */
329- secp256k1_scalar stmp ;
330402 secp256k1_sha256 sha256_m ;
331- unsigned char prep [4096 ];
332403 unsigned char tmp [33 ];
333404 unsigned char * signs ; /* Location of sign flags in the proof. */
334405 uint64_t v ;
@@ -337,7 +408,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
337408 size_t len ; /* Number of bytes used so far. */
338409 size_t i ;
339410 size_t pub_idx ;
340- int overflow ;
341411 len = 0 ;
342412 if (* plen < 65 ) {
343413 return 0 ;
@@ -379,44 +449,15 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
379449 secp256k1_sha256_write (& sha256_m , tmp , 33 );
380450 secp256k1_sha256_write (& sha256_m , proof , len );
381451
382- memset (prep , 0 , 4096 );
383- if (message != NULL ) {
384- memcpy (prep , message , msg_len );
385- }
386- /* Note, the data corresponding to the blinding factors must be zero. */
387- if (header .rsizes [header .n_rings - 1 ] > 1 ) {
388- size_t idx ;
389- /* Value encoding sidechannel. */
390- idx = header .rsizes [header .n_rings - 1 ] - 1 ;
391- idx -= secidx [header .n_rings - 1 ] == idx ;
392- idx = ((header .n_rings - 1 ) * 4 + idx ) * 32 ;
393- for (i = 0 ; i < 8 ; i ++ ) {
394- prep [8 + i + idx ] = prep [16 + i + idx ] = prep [24 + i + idx ] = (v >> (56 - i * 8 )) & 255 ;
395- prep [i + idx ] = 0 ;
396- }
397- prep [idx ] = 128 ;
398- }
399452 secp256k1_rangeproof_init_rng (& genrand_rng , nonce , commit , proof , len , genp );
400- if (!secp256k1_rangeproof_genrand (sec , s , prep , & header , & genrand_rng )) {
453+ if (!secp256k1_rangeproof_genrand_sign (sec , s , blind , message , msg_len , & header , v , & genrand_rng )) {
401454 return 0 ;
402455 }
403- memset (prep , 0 , 4096 );
404456 for (i = 0 ; i < header .n_rings ; i ++ ) {
405457 /* Sign will overwrite the non-forged signature, move that random value into the nonce. */
406458 k [i ] = s [i * 4 + secidx [i ]];
407459 secp256k1_scalar_clear (& s [i * 4 + secidx [i ]]);
408460 }
409- /** Genrand returns the last blinding factor as -sum(rest),
410- * adding in the blinding factor for our commitment, results in the blinding factor for
411- * the commitment to the last digit that the verifier can compute for itself by subtracting
412- * all the digits in the proof from the commitment. This lets the prover skip sending the
413- * blinded value for one digit.
414- */
415- secp256k1_scalar_set_b32 (& stmp , blind , & overflow );
416- secp256k1_scalar_add (& sec [header .n_rings - 1 ], & sec [header .n_rings - 1 ], & stmp );
417- if (overflow || secp256k1_scalar_is_zero (& sec [header .n_rings - 1 ])) {
418- return 0 ;
419- }
420461 signs = & proof [len ];
421462 /* We need one sign bit for each blinded value we send. */
422463 for (i = 0 ; i < (header .n_rings + 6 ) >> 3 ; i ++ ) {
@@ -462,7 +503,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
462503 }
463504 VERIFY_CHECK (len <= * plen );
464505 * plen = len ;
465- memset (prep , 0 , 4096 );
466506 return 1 ;
467507}
468508
@@ -511,7 +551,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *
511551 memset (prep , 0 , 4096 );
512552 /* Reconstruct the provers random values. */
513553 secp256k1_rangeproof_init_rng (& genrand_rng , nonce , commit , proof , len , genp );
514- if (!secp256k1_rangeproof_genrand (sec , s_orig , prep , header , & genrand_rng )) {
554+ if (!secp256k1_rangeproof_genrand_rewind (sec , s_orig , prep , header , & genrand_rng )) {
515555 return 0 ;
516556 }
517557 * v = UINT64_MAX ;
0 commit comments