Skip to content

Commit 05a618b

Browse files
committed
rangeproof: split genrand into genrand_sign and genrang_rewind
Also eliminate `prep` array from genrand_sign
1 parent 1e5c300 commit 05a618b

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
@@ -281,7 +281,81 @@ SECP256K1_INLINE static void secp256k1_rangeproof_init_rng(
281281
secp256k1_rfc6979_hmac_sha256_initialize(rng, rngseed, 32 + 33 + 33 + len);
282282
}
283283

284-
SECP256K1_INLINE static int secp256k1_rangeproof_genrand(
284+
SECP256K1_INLINE static int secp256k1_rangeproof_genrand_sign(
285+
secp256k1_scalar *sec,
286+
secp256k1_scalar *s,
287+
const unsigned char* blind,
288+
const unsigned char* message,
289+
const size_t msg_len,
290+
const secp256k1_rangeproof_header* header,
291+
const uint64_t proven_value,
292+
secp256k1_rfc6979_hmac_sha256* rng
293+
) {
294+
unsigned char tmp[32];
295+
secp256k1_scalar acc;
296+
int overflow;
297+
int ret;
298+
size_t i;
299+
size_t npub;
300+
secp256k1_scalar_set_b32(&acc, blind, &overflow);
301+
if (overflow) {
302+
return 0;
303+
}
304+
secp256k1_scalar_negate(&acc, &acc);
305+
npub = 0;
306+
ret = 1;
307+
for (i = 0; i < header->n_rings; i++) {
308+
size_t j;
309+
if (i < header->n_rings - 1) {
310+
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
311+
do {
312+
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
313+
secp256k1_scalar_set_b32(&sec[i], tmp, &overflow);
314+
} while (overflow || secp256k1_scalar_is_zero(&sec[i]));
315+
secp256k1_scalar_add(&acc, &acc, &sec[i]);
316+
} else {
317+
secp256k1_scalar_negate(&acc, &acc);
318+
sec[i] = acc;
319+
}
320+
for (j = 0; j < header->rsizes[i]; j++) {
321+
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
322+
if (message && i < header->n_rings - 1) {
323+
/* encode the message side-channel */
324+
int b;
325+
for (b = 0; b < 32; b++) {
326+
if ((i * 4 + j) * 32 + b < msg_len) {
327+
tmp[b] ^= message[(i * 4 + j) * 32 + b];
328+
}
329+
}
330+
} else if (i == header->n_rings - 1) {
331+
/* encode the value in the final ring thrice, both to inform the rewinder
332+
* which indices are real and to signal to the rewinder that its nonce is
333+
* correct and it is decoding something non-random */
334+
size_t jidx = header->rsizes[i] - 1;
335+
jidx -= (proven_value >> (2 * i)) == jidx;
336+
if (j == jidx) {
337+
size_t k;
338+
tmp[0] ^= 128;
339+
for (k = 0; k < 8; k++) {
340+
unsigned char xor = (proven_value >> (56 - k * 8)) & 255;
341+
tmp[8 + k] ^= xor;
342+
tmp[16 + k] ^= xor;
343+
tmp[24 + k] ^= xor;
344+
}
345+
}
346+
}
347+
secp256k1_scalar_set_b32(&s[npub], tmp, &overflow);
348+
ret &= !(overflow || secp256k1_scalar_is_zero(&s[npub]));
349+
npub++;
350+
}
351+
}
352+
secp256k1_rfc6979_hmac_sha256_finalize(rng);
353+
secp256k1_scalar_clear(&acc);
354+
memset(tmp, 0, 32);
355+
return ret;
356+
}
357+
358+
SECP256K1_INLINE static int secp256k1_rangeproof_genrand_rewind(
285359
secp256k1_scalar *sec,
286360
secp256k1_scalar *s,
287361
unsigned char *message,
@@ -315,7 +389,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_genrand(
315389
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
316390
if (message) {
317391
for (b = 0; b < 32; b++) {
318-
tmp[b] ^= message[(i * 4 + j) * 32 + b];
319392
message[(i * 4 + j) * 32 + b] = tmp[b];
320393
}
321394
}
@@ -340,9 +413,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
340413
secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */
341414
secp256k1_scalar sec[32]; /* Blinding factors for the correct digits. */
342415
secp256k1_scalar k[32]; /* Nonces for our non-forged signatures. */
343-
secp256k1_scalar stmp;
344416
secp256k1_sha256 sha256_m;
345-
unsigned char prep[4096];
346417
unsigned char tmp[33];
347418
unsigned char *signs; /* Location of sign flags in the proof. */
348419
uint64_t v;
@@ -351,7 +422,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
351422
size_t len; /* Number of bytes used so far. */
352423
size_t i;
353424
size_t pub_idx;
354-
int overflow;
355425
len = 0;
356426
if (*plen < 65) {
357427
return 0;
@@ -390,44 +460,15 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
390460
secp256k1_sha256_write(&sha256_m, tmp, 33);
391461
secp256k1_sha256_write(&sha256_m, proof, len);
392462

393-
memset(prep, 0, 4096);
394-
if (message != NULL) {
395-
memcpy(prep, message, msg_len);
396-
}
397-
/* Note, the data corresponding to the blinding factors must be zero. */
398-
if (header.rsizes[header.n_rings - 1] > 1) {
399-
size_t idx;
400-
/* Value encoding sidechannel. */
401-
idx = header.rsizes[header.n_rings - 1] - 1;
402-
idx -= secidx[header.n_rings - 1] == idx;
403-
idx = ((header.n_rings - 1) * 4 + idx) * 32;
404-
for (i = 0; i < 8; i++) {
405-
prep[8 + i + idx] = prep[16 + i + idx] = prep[24 + i + idx] = (v >> (56 - i * 8)) & 255;
406-
prep[i + idx] = 0;
407-
}
408-
prep[idx] = 128;
409-
}
410463
secp256k1_rangeproof_init_rng(&genrand_rng, nonce, commit, proof, len, genp);
411-
if (!secp256k1_rangeproof_genrand(sec, s, prep, &header, &genrand_rng)) {
464+
if (!secp256k1_rangeproof_genrand_sign(sec, s, blind, message, msg_len, &header, v, &genrand_rng)) {
412465
return 0;
413466
}
414-
memset(prep, 0, 4096);
415467
for (i = 0; i < header.n_rings; i++) {
416468
/* Sign will overwrite the non-forged signature, move that random value into the nonce. */
417469
k[i] = s[i * 4 + secidx[i]];
418470
secp256k1_scalar_clear(&s[i * 4 + secidx[i]]);
419471
}
420-
/** Genrand returns the last blinding factor as -sum(rest),
421-
* adding in the blinding factor for our commitment, results in the blinding factor for
422-
* the commitment to the last digit that the verifier can compute for itself by subtracting
423-
* all the digits in the proof from the commitment. This lets the prover skip sending the
424-
* blinded value for one digit.
425-
*/
426-
secp256k1_scalar_set_b32(&stmp, blind, &overflow);
427-
secp256k1_scalar_add(&sec[header.n_rings - 1], &sec[header.n_rings - 1], &stmp);
428-
if (overflow || secp256k1_scalar_is_zero(&sec[header.n_rings - 1])) {
429-
return 0;
430-
}
431472
signs = &proof[len];
432473
/* We need one sign bit for each blinded value we send. */
433474
for (i = 0; i < (header.n_rings + 6) >> 3; i++) {
@@ -473,7 +514,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
473514
}
474515
VERIFY_CHECK(len <= *plen);
475516
*plen = len;
476-
memset(prep, 0, 4096);
477517
return 1;
478518
}
479519

@@ -521,7 +561,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *
521561
memset(prep, 0, 4096);
522562
/* Reconstruct the provers random values. */
523563
secp256k1_rangeproof_init_rng(&genrand_rng, nonce, commit, proof, len, genp);
524-
if (!secp256k1_rangeproof_genrand(sec, s_orig, prep, header, &genrand_rng)) {
564+
if (!secp256k1_rangeproof_genrand_rewind(sec, s_orig, prep, header, &genrand_rng)) {
525565
return 0;
526566
}
527567
*v = UINT64_MAX;

0 commit comments

Comments
 (0)