Skip to content

Commit 3771ad3

Browse files
committed
rangeproof: split genrand into genrand_sign and genrang_rewind
Also eliminate `prep` array from genrand_sign
1 parent 1233fbe commit 3771ad3

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
@@ -275,7 +275,81 @@ SECP256K1_INLINE static void secp256k1_rangeproof_init_rng(
275275
secp256k1_rfc6979_hmac_sha256_initialize(rng, rngseed, 32 + 33 + 33 + len);
276276
}
277277

278-
SECP256K1_INLINE static int secp256k1_rangeproof_genrand(
278+
SECP256K1_INLINE static int secp256k1_rangeproof_genrand_sign(
279+
secp256k1_scalar *sec,
280+
secp256k1_scalar *s,
281+
const unsigned char* blind,
282+
const unsigned char* message,
283+
const size_t msg_len,
284+
const secp256k1_rangeproof_header* header,
285+
const uint64_t proven_value,
286+
secp256k1_rfc6979_hmac_sha256* rng
287+
) {
288+
unsigned char tmp[32];
289+
secp256k1_scalar acc;
290+
int overflow;
291+
int ret;
292+
size_t i;
293+
size_t npub;
294+
secp256k1_scalar_set_b32(&acc, blind, &overflow);
295+
if (overflow) {
296+
return 0;
297+
}
298+
secp256k1_scalar_negate(&acc, &acc);
299+
npub = 0;
300+
ret = 1;
301+
for (i = 0; i < header->n_rings; i++) {
302+
size_t j;
303+
if (i < header->n_rings - 1) {
304+
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
305+
do {
306+
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
307+
secp256k1_scalar_set_b32(&sec[i], tmp, &overflow);
308+
} while (overflow || secp256k1_scalar_is_zero(&sec[i]));
309+
secp256k1_scalar_add(&acc, &acc, &sec[i]);
310+
} else {
311+
secp256k1_scalar_negate(&acc, &acc);
312+
sec[i] = acc;
313+
}
314+
for (j = 0; j < header->rsizes[i]; j++) {
315+
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
316+
if (message && i < header->n_rings - 1) {
317+
/* encode the message side-channel */
318+
int b;
319+
for (b = 0; b < 32; b++) {
320+
if ((i * 4 + j) * 32 + b < msg_len) {
321+
tmp[b] ^= message[(i * 4 + j) * 32 + b];
322+
}
323+
}
324+
} else if (i == header->n_rings - 1) {
325+
/* encode the value in the final ring thrice, both to inform the rewinder
326+
* which indices are real and to signal to the rewinder that its nonce is
327+
* correct and it is decoding something non-random */
328+
size_t jidx = header->rsizes[i] - 1;
329+
jidx -= (proven_value >> (2 * i)) == jidx;
330+
if (j == jidx) {
331+
size_t k;
332+
tmp[0] ^= 128;
333+
for (k = 0; k < 8; k++) {
334+
unsigned char xor = (proven_value >> (56 - k * 8)) & 255;
335+
tmp[8 + k] ^= xor;
336+
tmp[16 + k] ^= xor;
337+
tmp[24 + k] ^= xor;
338+
}
339+
}
340+
}
341+
secp256k1_scalar_set_b32(&s[npub], tmp, &overflow);
342+
ret &= !(overflow || secp256k1_scalar_is_zero(&s[npub]));
343+
npub++;
344+
}
345+
}
346+
secp256k1_rfc6979_hmac_sha256_finalize(rng);
347+
secp256k1_scalar_clear(&acc);
348+
memset(tmp, 0, 32);
349+
return ret;
350+
}
351+
352+
SECP256K1_INLINE static int secp256k1_rangeproof_genrand_rewind(
279353
secp256k1_scalar *sec,
280354
secp256k1_scalar *s,
281355
unsigned char *message,
@@ -309,7 +383,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_genrand(
309383
secp256k1_rfc6979_hmac_sha256_generate(rng, tmp, 32);
310384
if (message) {
311385
for (b = 0; b < 32; b++) {
312-
tmp[b] ^= message[(i * 4 + j) * 32 + b];
313386
message[(i * 4 + j) * 32 + b] = tmp[b];
314387
}
315388
}
@@ -334,9 +407,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
334407
secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */
335408
secp256k1_scalar sec[32]; /* Blinding factors for the correct digits. */
336409
secp256k1_scalar k[32]; /* Nonces for our non-forged signatures. */
337-
secp256k1_scalar stmp;
338410
secp256k1_sha256 sha256_m;
339-
unsigned char prep[4096];
340411
unsigned char tmp[33];
341412
unsigned char *signs; /* Location of sign flags in the proof. */
342413
uint64_t v;
@@ -345,7 +416,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
345416
size_t len; /* Number of bytes used so far. */
346417
size_t i;
347418
size_t pub_idx;
348-
int overflow;
349419
len = 0;
350420
if (*plen < 65) {
351421
return 0;
@@ -387,44 +457,15 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
387457
secp256k1_sha256_write(&sha256_m, tmp, 33);
388458
secp256k1_sha256_write(&sha256_m, proof, len);
389459

390-
memset(prep, 0, 4096);
391-
if (message != NULL) {
392-
memcpy(prep, message, msg_len);
393-
}
394-
/* Note, the data corresponding to the blinding factors must be zero. */
395-
if (header.rsizes[header.n_rings - 1] > 1) {
396-
size_t idx;
397-
/* Value encoding sidechannel. */
398-
idx = header.rsizes[header.n_rings - 1] - 1;
399-
idx -= secidx[header.n_rings - 1] == idx;
400-
idx = ((header.n_rings - 1) * 4 + idx) * 32;
401-
for (i = 0; i < 8; i++) {
402-
prep[8 + i + idx] = prep[16 + i + idx] = prep[24 + i + idx] = (v >> (56 - i * 8)) & 255;
403-
prep[i + idx] = 0;
404-
}
405-
prep[idx] = 128;
406-
}
407460
secp256k1_rangeproof_init_rng(&genrand_rng, nonce, commit, proof, len, genp);
408-
if (!secp256k1_rangeproof_genrand(sec, s, prep, &header, &genrand_rng)) {
461+
if (!secp256k1_rangeproof_genrand_sign(sec, s, blind, message, msg_len, &header, v, &genrand_rng)) {
409462
return 0;
410463
}
411-
memset(prep, 0, 4096);
412464
for (i = 0; i < header.n_rings; i++) {
413465
/* Sign will overwrite the non-forged signature, move that random value into the nonce. */
414466
k[i] = s[i * 4 + secidx[i]];
415467
secp256k1_scalar_clear(&s[i * 4 + secidx[i]]);
416468
}
417-
/** Genrand returns the last blinding factor as -sum(rest),
418-
* adding in the blinding factor for our commitment, results in the blinding factor for
419-
* the commitment to the last digit that the verifier can compute for itself by subtracting
420-
* all the digits in the proof from the commitment. This lets the prover skip sending the
421-
* blinded value for one digit.
422-
*/
423-
secp256k1_scalar_set_b32(&stmp, blind, &overflow);
424-
secp256k1_scalar_add(&sec[header.n_rings - 1], &sec[header.n_rings - 1], &stmp);
425-
if (overflow || secp256k1_scalar_is_zero(&sec[header.n_rings - 1])) {
426-
return 0;
427-
}
428469
signs = &proof[len];
429470
/* We need one sign bit for each blinded value we send. */
430471
for (i = 0; i < (header.n_rings + 6) >> 3; i++) {
@@ -470,7 +511,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
470511
}
471512
VERIFY_CHECK(len <= *plen);
472513
*plen = len;
473-
memset(prep, 0, 4096);
474514
return 1;
475515
}
476516

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

0 commit comments

Comments
 (0)