Skip to content

Commit f7e9a85

Browse files
committed
Merge #201: rangeproof: add secp256k1_rangeproof_max_size function to estimate rangeproof size
6b6ced9 rangeproof: add more max_size tests (Jonas Nick) 34876ec rangeproof: add more static test vectors (Jonas Nick) 310e517 rangeproof: add a bunch more testing (Andrew Poelstra) f1410cb rangeproof: add secp256k1_rangeproof_max_size function to estimate rangeproof size (Andrew Poelstra) Pull request description: ACKs for top commit: real-or-random: tACK 6b6ced9 jonasnick: ACK 6b6ced9 Tree-SHA512: 421dfb0824f67f3822be729dc7f11e4654a21e32e3a6c5565e09b191ec57710b33a73c3d09c08f1d767d769f0957006ac257eabe00a2f37f88b99377644e8741
2 parents c137ddb + 6b6ced9 commit f7e9a85

File tree

3 files changed

+859
-8
lines changed

3 files changed

+859
-8
lines changed

include/secp256k1_rangeproof.h

+36
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ extern "C" {
1010

1111
#include <stdint.h>
1212

13+
/** Length of a message that can be embedded into a maximally-sized rangeproof
14+
*
15+
* It is not be possible to fit a message of this size into a non-maximally-sized
16+
* rangeproof, but it is guaranteed that any embeddable message can fit into an
17+
* array of this size. This constant is intended to be used for memory allocations
18+
* and sanity checks.
19+
*/
20+
#define SECP256K1_RANGEPROOF_MAX_MESSAGE_LEN 3968
21+
1322
/** Opaque data structure that stores a Pedersen commitment
1423
*
1524
* The exact representation of data inside is implementation defined and not
@@ -287,6 +296,33 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info(
287296
size_t plen
288297
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
289298

299+
/** Returns an upper bound on the size of a rangeproof with the given parameters
300+
*
301+
* An actual rangeproof may be smaller, for example if the actual value
302+
* is less than both the provided `max_value` and 2^`min_bits`, or if
303+
* the `exp` parameter to `secp256k1_rangeproof_sign` is set such that
304+
* the proven range is compressed. In particular this function will always
305+
* overestimate the size of single-value proofs. Also, if `min_value`
306+
* is set to 0 in the proof, the result will usually, but not always,
307+
* be 8 bytes smaller than if a nonzero value had been passed.
308+
*
309+
* The goal of this function is to provide a useful upper bound for
310+
* memory allocation or fee estimation purposes, without requiring
311+
* too many parameters be fixed in advance.
312+
*
313+
* To obtain the size of largest possible proof, set `max_value` to
314+
* `UINT64_MAX` (and `min_bits` to any valid value such as 0).
315+
*
316+
* In: ctx: pointer to a context object
317+
* max_value: the maximum value that might be passed for `value` for the proof.
318+
* min_bits: the value that will be passed as `min_bits` for the proof.
319+
*/
320+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT size_t secp256k1_rangeproof_max_size(
321+
const secp256k1_context* ctx,
322+
uint64_t max_value,
323+
int min_bits
324+
) SECP256K1_ARG_NONNULL(1);
325+
290326
# ifdef __cplusplus
291327
}
292328
# endif

src/modules/rangeproof/main_impl.h

+12
Original file line numberDiff line numberDiff line change
@@ -304,4 +304,16 @@ int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof
304304
proof, plen, min_value, &commitp, blind, nonce, exp, min_bits, value, message, msg_len, extra_commit, extra_commit_len, &genp);
305305
}
306306

307+
size_t secp256k1_rangeproof_max_size(const secp256k1_context* ctx, uint64_t max_value, int min_bits) {
308+
const int val_mantissa = max_value > 0 ? 64 - secp256k1_clz64_var(max_value) : 1;
309+
const int mantissa = min_bits > val_mantissa ? min_bits : val_mantissa;
310+
const size_t rings = (mantissa + 1) / 2;
311+
const size_t npubs = rings * 4 - 2 * (mantissa % 2);
312+
313+
VERIFY_CHECK(ctx != NULL);
314+
(void) ctx;
315+
316+
return 10 + 32 * (npubs + rings - 1) + 32 + ((rings - 1 + 7) / 8);
317+
}
318+
307319
#endif

0 commit comments

Comments
 (0)