Skip to content

Commit 6fede2a

Browse files
committed
rangeproof: split genrand into genrand_sign and genrang_rewind
Also eliminate `prep` array from genrand_sign
1 parent f047623 commit 6fede2a

File tree

1 file changed

+77
-37
lines changed

1 file changed

+77
-37
lines changed

src/modules/rangeproof/rangeproof_impl.h

+77-37
Original file line numberDiff line numberDiff line change
@@ -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

@@ -510,7 +550,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *
510550
memset(prep, 0, 4096);
511551
/* Reconstruct the provers random values. */
512552
secp256k1_rangeproof_init_rng(&genrand_rng, nonce, commit, proof, len, genp);
513-
if (!secp256k1_rangeproof_genrand(sec, s_orig, prep, header, &genrand_rng)) {
553+
if (!secp256k1_rangeproof_genrand_rewind(sec, s_orig, prep, header, &genrand_rng)) {
514554
return 0;
515555
}
516556
*v = UINT64_MAX;

0 commit comments

Comments
 (0)