Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: bulletproofs: use one large ecmult_multi instead of two smaller ones #216

Draft
wants to merge 35 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
87373f5
MOVE ONLY: move Pedersen commitment stuff to generator module from ra…
apoelstra Aug 27, 2022
0a60069
Revert "Remove unused scalar_sqr"
apoelstra Jul 12, 2022
6162d57
generator: cleanups in Pedersen/generator code
apoelstra Jul 12, 2022
048f9f8
bulletproofs: add new empty module
apoelstra Aug 27, 2022
48563c8
bulletproofs: add API functionality to generate a large set of genera…
apoelstra Nov 12, 2020
17417d4
Add utilities from uncompressed Bulletproofs PR
sanket1729 Nov 22, 2022
420353d
Add utilities for log2
sanket1729 Jan 31, 2023
412f8f6
Add utility functions required in norm argument
sanket1729 Oct 26, 2022
8638f0e
Add internal BP++ commit API
sanket1729 Oct 26, 2022
d914545
Add bulletproofs++ norm argument prove API
sanket1729 Oct 26, 2022
d381748
Add norm argument verify API
sanket1729 Oct 26, 2022
6e5932d
Add testcases for bulletproofs++ norm arugment
sanket1729 Oct 26, 2022
aac50de
ci: add bulletproofs
jonasnick Jan 20, 2023
aca625f
norm arg: add tests for zero length and zero vectors
jonasnick Jan 26, 2023
a0cb1c6
norm arg: add verification vectors
jonasnick Jan 31, 2023
9504285
transcript: add tests
jonasnick Jan 31, 2023
94f77ff
Rename buletproof_pp* to bppp*
sanket1729 Feb 6, 2023
9c76877
Prepare of bulletproofs++ rangeproof implementation
sanket1729 Nov 8, 2022
20b6b26
Add transcript module
sanket1729 Nov 15, 2022
d293ae0
Use generic FS transcrpit in norm argument
sanket1729 Dec 1, 2022
34d641b
Update generator serialization to have h0 = G
sanket1729 Dec 1, 2022
6d46f87
Add BP++ round 1
sanket1729 Dec 1, 2022
f8d775c
BP++ prover round 2
sanket1729 Dec 1, 2022
1e1fc2e
BP++ prover round 3
sanket1729 Dec 1, 2022
e6ca68b
Prover round 4: Norm proof argument
sanket1729 Dec 1, 2022
ec9a56e
BP++ verifier
sanket1729 Dec 1, 2022
326978c
Expose BP++ Apis
sanket1729 Dec 1, 2022
60a448c
Add benchmarks
sanket1729 Dec 1, 2022
da6288c
Add rangeproof unit tests
sanket1729 Dec 1, 2022
c0da897
Add simple breaking test case
sanket1729 Jan 19, 2023
8874315
fixup! compilation
jonasnick Feb 7, 2023
5336791
fixup! fix tests by plugging memory leaks
jonasnick Feb 11, 2023
9700ede
fixup! improve generators test
jonasnick Feb 11, 2023
d4b3a8e
bppp: avoid benchmarking verification of same proof over and over
jonasnick Feb 11, 2023
f109aa0
make one ecmult_multi out of two
jonasnick Feb 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ env:
WHITELIST: no
MUSIG: no
ECDSAADAPTOR: no
BPPP: no
### test options
SECP256K1_TEST_ITERS:
BENCH: yes
Expand Down Expand Up @@ -72,12 +73,12 @@ task:
<< : *LINUX_CONTAINER
matrix: &ENV_MATRIX
- env: {WIDEMUL: int64, RECOVERY: yes}
- env: {WIDEMUL: int64, ECDH: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes}
- env: {WIDEMUL: int64, ECDH: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes, BPPP: yes}
- env: {WIDEMUL: int128}
- env: {WIDEMUL: int128, RECOVERY: yes, SCHNORRSIG: yes}
- env: {WIDEMUL: int128, ECDH: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes}
- env: {WIDEMUL: int128, ECDH: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes, BPPP: yes}
- env: {WIDEMUL: int128, ASM: x86_64}
- env: { RECOVERY: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes}
- env: { RECOVERY: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes, BPPP: yes}
- env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETEST: no, BENCH: no}
- env: {CPPFLAGS: -DDETERMINISTIC}
- env: {CFLAGS: -O0, CTIMETEST: no}
Expand Down Expand Up @@ -108,6 +109,7 @@ task:
GENERATOR: yes
MUSIG: yes
ECDSAADAPTOR: yes
BPPP: yes
matrix:
- env:
CC: i686-linux-gnu-gcc
Expand Down Expand Up @@ -165,6 +167,7 @@ task:
GENERATOR: yes
MUSIG: yes
ECDSAADAPTOR: yes
BPPP: yes
CTIMETEST: no
<< : *MERGE_BASE
test_script:
Expand Down Expand Up @@ -259,6 +262,7 @@ task:
GENERATOR: yes
MUSIG: yes
ECDSAADAPTOR: yes
BPPP: yes
CTIMETEST: no
matrix:
- name: "Valgrind (memcheck)"
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
bench
bench_bppp
bench_ecmult
bench_generator
bench_rangeproof
bench_internal
bench_whitelist
tests
example_musig
exhaustive_tests
precompute_ecmult_gen
precompute_ecmult
Expand Down Expand Up @@ -66,4 +69,4 @@ src/stamp-h1
libsecp256k1.pc
contrib/gh-pr-create.sh

musig_example
musig_example
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ clean-precomp:

EXTRA_DIST = autogen.sh SECURITY.md

if ENABLE_MODULE_BPPP
include src/modules/bppp/Makefile.am.include
endif

if ENABLE_MODULE_ECDH
include src/modules/ecdh/Makefile.am.include
endif
Expand Down
5 changes: 5 additions & 0 deletions ci/cirrus.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ valgrind --version || true
--with-ecmult-gen-precision="$ECMULTGENPRECISION" \
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
--enable-module-ecdsa-s2c="$ECDSA_S2C" \
--enable-module-bppp="$BPPP" \
--enable-module-rangeproof="$RANGEPROOF" --enable-module-whitelist="$WHITELIST" --enable-module-generator="$GENERATOR" \
--enable-module-schnorrsig="$SCHNORRSIG" --enable-module-musig="$MUSIG" --enable-module-ecdsa-adaptor="$ECDSAADAPTOR" \
--enable-module-schnorrsig="$SCHNORRSIG" \
Expand Down Expand Up @@ -51,6 +52,10 @@ then
$EXEC ./bench_ecmult
$EXEC ./bench_internal
$EXEC ./bench
if [ "$BPPP" = "yes" ]
then
$EXEC ./bench_bppp
fi
} >> bench.log 2>&1
fi

Expand Down
15 changes: 15 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ AC_ARG_ENABLE(examples,
AS_HELP_STRING([--enable-examples],[compile the examples [default=no]]), [],
[SECP_SET_DEFAULT([enable_examples], [no], [yes])])

AC_ARG_ENABLE(module_bppp,
AS_HELP_STRING([--enable-module-bppp],[enable Bulletproofs++ module (experimental)]),
[],
[SECP_SET_DEFAULT([enable_module_bppp], [no], [yes])])

AC_ARG_ENABLE(module_ecdh,
AS_HELP_STRING([--enable-module-ecdh],[enable ECDH module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_ecdh], [no], [yes])])
Expand Down Expand Up @@ -417,6 +422,11 @@ if test x"$enable_module_rangeproof" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_RANGEPROOF, 1, [Define this symbol to enable the Pedersen / zero knowledge range proof module])
fi

if test x"$enable_module_bppp" = x"yes"; then
enable_module_generator=yes
AC_DEFINE(ENABLE_MODULE_BPPP, 1, [Define this symbol to enable the Bulletproofs++ module])
fi

if test x"$enable_module_generator" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_GENERATOR, 1, [Define this symbol to enable the NUMS generator module])
fi
Expand Down Expand Up @@ -460,6 +470,9 @@ else
# module (which automatically enables the module dependencies) we want to
# print an error for the dependent module, not the module dependency. Hence,
# we first test dependent modules.
if test x"$enable_module_bppp" = x"yes"; then
AC_MSG_ERROR([Bulletproofs++ module is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_whitelist" = x"yes"; then
AC_MSG_ERROR([Key whitelisting module is experimental. Use --enable-experimental to allow.])
fi
Expand Down Expand Up @@ -502,6 +515,7 @@ AM_CONDITIONAL([USE_TESTS], [test x"$enable_tests" != x"no"])
AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$enable_exhaustive_tests" != x"no"])
AM_CONDITIONAL([USE_EXAMPLES], [test x"$enable_examples" != x"no"])
AM_CONDITIONAL([USE_BENCHMARK], [test x"$enable_benchmark" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_BPPP], [test x"$enable_module_bppp" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_MUSIG], [test x"$enable_module_musig" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"])
Expand Down Expand Up @@ -541,6 +555,7 @@ echo " module whitelist = $enable_module_whitelist"
echo " module musig = $enable_module_musig"
echo " module ecdsa-s2c = $enable_module_ecdsa_s2c"
echo " module ecdsa-adaptor = $enable_module_ecdsa_adaptor"
echo " module bppp = $enable_module_bppp"
echo
echo " asm = $set_asm"
echo " ecmult window size = $set_ecmult_window"
Expand Down
163 changes: 163 additions & 0 deletions include/secp256k1_bppp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#ifndef _SECP256K1_BPPP_
# define _SECP256K1_BPPP_

# include "secp256k1.h"

# ifdef __cplusplus
extern "C" {
# endif

#include <stdint.h>

#include "include/secp256k1_generator.h"

/** Opaque structure representing a large number of NUMS generators */
typedef struct secp256k1_bppp_generators secp256k1_bppp_generators;

/** Opaque structure representing a prover context used in bulletproofs++ prover */
typedef struct secp256k1_bppp_rangeproof_prover_context secp256k1_bppp_rangeproof_prover_context;

/** Allocates and initializes a list of NUMS generators.
* Returns a list of generators, or calls the error callback if the allocation fails.
* Args: ctx: pointer to a context object
* n: number of NUMS generators to produce.
*/
SECP256K1_API secp256k1_bppp_generators *secp256k1_bppp_generators_create(
const secp256k1_context* ctx,
size_t n
) SECP256K1_ARG_NONNULL(1);

/** Allocates a list of generators from a static array
* Returns a list of generators or NULL in case of failure.
* Args: ctx: pointer to a context object
* In: data: data that came from `secp256k1_bppp_generators_serialize`
* data_len: the length of the `data` buffer
*/
SECP256K1_API secp256k1_bppp_generators* secp256k1_bppp_generators_parse(
const secp256k1_context* ctx,
const unsigned char* data,
size_t data_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);

/** Serializes a list of generators to an array
* Returns 1 on success, 0 if the provided array was not large enough
* Args: ctx: pointer to a context object
* gen: pointer to the generator set to be serialized
* Out: data: pointer to buffer into which the generators will be serialized
* In/Out: data_len: the length of the `data` buffer. Should be initially set to at
* least 33 times the number of generators plus one(33 * (num_gens - 1)).
* Upon success, data_len will be set to the (33 * (num_gens - 1)).
*/
SECP256K1_API int secp256k1_bppp_generators_serialize(
const secp256k1_context* ctx,
const secp256k1_bppp_generators* gen,
unsigned char* data,
size_t *data_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

/** Destroys a list of NUMS generators, freeing allocated memory
* Args: ctx: pointer to a context object
* gen: pointer to the generator set to be destroyed
* (can be NULL, in which case this function is a no-op)
*/
SECP256K1_API void secp256k1_bppp_generators_destroy(
const secp256k1_context* ctx,
secp256k1_bppp_generators* gen
) SECP256K1_ARG_NONNULL(1);

/** Returns the serialized size of an bulletproofs++ proof of a given number
* of bits and the base. Both base and n_bits must be a power of two. The number
* of digits required to represent number of bits in the given base must also be
* a power of two. Specifically, all of n_bits, base and num_digits = (n_bits / log2(base))
* must all be a power of two.
* Args: ctx: pointer to a context object
* Out: len: 0 if the parameters and num_digits (n_bits/log2(base)) are not a power of two
* length of the serialized proof otherwise
* In: n_bits: number of bits to prove (max 64, should usually be 64)
* base: base representation to be used in proof construction (max 256, recommended 16)
*/
SECP256K1_API size_t secp256k1_bppp_rangeproof_proof_length(
const secp256k1_context* ctx,
size_t n_bits,
size_t base
) SECP256K1_ARG_NONNULL(1);

/** Produces a Bulletproofs++ rangeproof. Returns 1 on success, 0 on failure.
* Proof creation can only fail if the arguments are invalid. The documentation
* below specifies the constraints on inputs and arguments under which this API
* can fail.
* Args: ctx: pointer to a context object
* scratch: pointer to a scratch space
* gens: pointer to the generator set to use, which must have exactly
* `n = max(num_digits, base) + 7` generators, where num_digits is the number.
* asset_gen: pointer to the asset generator for the Pedersen/CT commitment
* Out: proof: pointer to a byte array to output the proof into
* In/Out: plen: pointer to the size of the above array; will be set to the actual size of
* the serialized proof. To learn this value in advance, to allocate a sufficient
* buffer, call `secp256k1_bppp_rangeproof_proof_length`
* In: n_bits: size of range being proven, in bits. Must be a power of two,
* and at most 64.
* base: base representation to be used in proof construction. Must be a power of two,
* value: value committed in the Pedersen commitment. Must be less
* than 2^n_bits.
* min_value: minimum value of the range being proven. Must be less than value
* commit: the Pedersen commitment being proven
* blind: blinding factor for the Pedersen commitment. Must be a 32 byte
* valid scalar within secp curve order.
* nonce: seed for the RNG used to generate random data during proving
* extra_commit: arbitrary extra data that the proof commits to (may be NULL if extra_commit_len is 0)
* extra_commit_len: length of the arbitrary extra data.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_bppp_rangeproof_prove(
const secp256k1_context* ctx,
secp256k1_scratch_space *scratch,
const secp256k1_bppp_generators* gens,
const secp256k1_generator* asset_gen,
unsigned char* proof,
size_t* plen,
const size_t n_bits,
const size_t base,
const uint64_t value,
const uint64_t min_value,
const secp256k1_pedersen_commitment* commit,
const unsigned char* blind,
const unsigned char* nonce,
const unsigned char* extra_commit,
size_t extra_commit_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(11) SECP256K1_ARG_NONNULL(12) SECP256K1_ARG_NONNULL(13);

/** Verifies an Bulletproofs++ rangeproof. Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object
* scratch: pointer to a scratch space
* gens: pointer to the generator set to use, which must have at least 2*n_bits generators
* asset_gen: pointer to the asset generator for the CT commitment
* In: proof: pointer to a byte array containing the serialized proof
* plen: length of the serialized proof
* n_bits: size of range being proven, in bits. Must be a power of two,
* and at most 64.
* base: base representation to be used in proof construction. Must be a power of two,
* min_value: minimum value of the range being proven
* commit: the Pedersen commitment being proven
* extra_commit: arbitrary extra data that the proof commits to (may be NULL if extra_commit_len is 0)
* extra_commit_len: length of the arbitrary extra data
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_bppp_rangeproof_verify(
const secp256k1_context* ctx,
secp256k1_scratch_space *scratch,
const secp256k1_bppp_generators* gens,
const secp256k1_generator* asset_gen,
const unsigned char* proof,
const size_t plen,
const uint64_t n_bits,
const uint64_t base,
const uint64_t min_value,
const secp256k1_pedersen_commitment* commit,
const unsigned char* extra_commit,
size_t extra_commit_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(10);

# ifdef __cplusplus
}
# endif

#endif
Loading