Skip to content

Commit

Permalink
MWEB: Adding 'generator', 'commitment', 'bulletproof', and 'aggsig' s…
Browse files Browse the repository at this point in the history
…ecp256k1 modules
  • Loading branch information
DavidBurkett committed Jul 2, 2023
1 parent 07d0d51 commit 8c0fcb8
Show file tree
Hide file tree
Showing 35 changed files with 6,628 additions and 1 deletion.
2 changes: 1 addition & 1 deletion configure.ac
Expand Up @@ -2055,7 +2055,7 @@ LIBS_TEMP="$LIBS"
unset LIBS
LIBS="$LIBS_TEMP"

ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig"
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig --enable-module-generator --enable-module-commitment --enable-module-bulletproof --enable-module-aggsig"
AC_CONFIG_SUBDIRS([src/secp256k1])

AC_OUTPUT
Expand Down
16 changes: 16 additions & 0 deletions src/secp256k1/Makefile.am
Expand Up @@ -228,3 +228,19 @@ endif
if ENABLE_MODULE_SCHNORRSIG
include src/modules/schnorrsig/Makefile.am.include
endif

if ENABLE_MODULE_GENERATOR
include src/modules/generator/Makefile.am.include
endif

if ENABLE_MODULE_COMMITMENT
include src/modules/commitment/Makefile.am.include
endif

if ENABLE_MODULE_BULLETPROOF
include src/modules/bulletproofs/Makefile.am.include
endif

if ENABLE_MODULE_AGGSIG
include src/modules/aggsig/Makefile.am.include
endif
40 changes: 40 additions & 0 deletions src/secp256k1/configure.ac
Expand Up @@ -156,6 +156,22 @@ AC_ARG_ENABLE(module_schnorrsig,
AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_schnorrsig], [no], [yes])])

AC_ARG_ENABLE(module_generator,
AS_HELP_STRING([--enable-module-generator],[enable NUMS generator module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_generator], [no], [yes])])

AC_ARG_ENABLE(module_commitment,
AS_HELP_STRING([--enable-module-commitment],[enable Pedersen commitments module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_commitment], [no], [yes])])

AC_ARG_ENABLE(module_bulletproof,
AS_HELP_STRING([--enable-module-bulletproof],[enable Pedersen / zero-knowledge bulletproofs module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_bulletproof], [no], [yes])])

AC_ARG_ENABLE(module_aggsig,
AS_HELP_STRING([--enable-module-aggsig],[enable Grin aggsig modules[default=no]]), [],
[SECP_SET_DEFAULT([enable_module_aggsig], [no], [yes])])

AC_ARG_ENABLE(external_default_callbacks,
AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [],
[SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])])
Expand Down Expand Up @@ -352,6 +368,22 @@ if test x"$enable_module_extrakeys" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_EXTRAKEYS, 1, [Define this symbol to enable the extrakeys 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

if test x"$enable_module_commitment" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_COMMITMENT, 1, [Define this symbol to enable the Pedersen commitment module])
fi

if test x"$enable_module_bulletproof" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_BULLETPROOF, 1, [Define this symbol to enable the Pedersen / zero knowledge bulletproof module])
fi

if test x"$enable_module_aggsig" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_AGGSIG, 1, [Define this symbol to enable the Grin Aggsig module])
fi

if test x"$enable_external_default_callbacks" = x"yes"; then
AC_DEFINE(USE_EXTERNAL_DEFAULT_CALLBACKS, 1, [Define this symbol if an external implementation of the default callbacks is used])
fi
Expand Down Expand Up @@ -391,6 +423,10 @@ AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_GENERATOR], [test x"$enable_module_generator" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_COMMITMENT], [test x"$enable_module_commitment" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_BULLETPROOF], [test x"$enable_module_bulletproof" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_AGGSIG], [test x"$enable_module_aggsig" = x"yes"])
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"])
AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"])
Expand All @@ -411,6 +447,10 @@ echo " module ecdh = $enable_module_ecdh"
echo " module recovery = $enable_module_recovery"
echo " module extrakeys = $enable_module_extrakeys"
echo " module schnorrsig = $enable_module_schnorrsig"
echo " module generator = $enable_module_generator"
echo " module commitment = $enable_module_commitment"
echo " module bulletproof = $enable_module_bulletproof"
echo " module aggsig = $enable_module_aggsig"
echo
echo " asm = $set_asm"
echo " ecmult window size = $set_ecmult_window"
Expand Down
10 changes: 10 additions & 0 deletions src/secp256k1/include/secp256k1.h
Expand Up @@ -810,6 +810,16 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
size_t n
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);

/** Tweak a private key by inverting it.
* Returns: 0 if the input was out of range. 1 otherwise.
* Args: ctx: pointer to a context object (cannot be NULL).
* In/Out: seckey: pointer to a 32-byte private key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_inv(
const secp256k1_context* ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);

/** Compute a tagged hash as defined in BIP-340.
*
* This is useful for creating a message hash and achieving domain separation
Expand Down
248 changes: 248 additions & 0 deletions src/secp256k1/include/secp256k1_aggsig.h
@@ -0,0 +1,248 @@
#ifndef _SECP256K1_AGGSIG_
# define _SECP256K1_AGGSIG_

# include "secp256k1.h"

# ifdef __cplusplus
extern "C" {
# endif

/** Opaque data structure that holds context for the aggregated signature state machine
*
* During execution of an aggregated signature this context object will contain secret
* data. It MUST be destroyed by `secp256k1_aggsig_context_destroy` to erase this data
* before freeing it. Context objects are sized based on the number of signatures to
* aggregate, and can be reused for multiple signature runs, provided that each run
* aggregates the same number of signatures.
*
* Destroying and recreating a context object is essentially just deallocating and
* reallocating memory, there is no expensive precomputation as there is with the general
* libsecp256k1 context.
*
* Once a context object is created with `secp256k1_aggsig_context_create` the workflow
* is as follows.
*
* 1. For each index controlled by the user, use `secp256k1_aggsig_generate_nonce`
* to generate a public/private nonce pair for that index. [TODO export the
* public nonce for other users]
* 2. [TODO import others' public nonces]
* 3. For each index controlled by the user, use `secp256k1_aggsig_partial_sign`
* to generate a partial signature that should be distributed to all peers.
*/
typedef struct secp256k1_aggsig_context_struct secp256k1_aggsig_context;

/** Opaque data structure that holds a partial signature
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 32 bytes in size, and can be safely copied, moved.
* and transmitted as raw bytes.
*/
typedef struct {
unsigned char data[32];
} secp256k1_aggsig_partial_signature;


/** Create an aggregated signature context object with a given size
*
* Returns: a newly created context object.
* Args: ctx: an existing context object (cannot be NULL)
* In: pubkeys: public keys for each signature (cannot be NULL)
* n_pubkeys: number of public keys/signatures to aggregate
* seed: a 32-byte seed to use for the nonce-generating RNG (cannot be NULL)
*/
SECP256K1_API secp256k1_aggsig_context* secp256k1_aggsig_context_create(
const secp256k1_context *ctx,
const secp256k1_pubkey *pubkeys,
size_t n_pubkeys,
const unsigned char *seed
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_WARN_UNUSED_RESULT;


/** Destroy an aggregated signature context object. If passed NULL, is a no-op.
*
* Args: aggctx: an existing context object
*/
SECP256K1_API void secp256k1_aggsig_context_destroy(
secp256k1_aggsig_context *aggctx
);

/** Generate a nonce pair for a single signature part in an aggregated signature
*
* Returns: 1 on success
* 0 if a nonce has already been generated for this index
* Args: ctx: an existing context object, initialized for signing (cannot be NULL)
* aggctx: an aggsig context object (cannot be NULL)
* In: index: which signature to generate a nonce for
*/
SECP256K1_API int secp256k1_aggsig_generate_nonce(
const secp256k1_context* ctx,
secp256k1_aggsig_context* aggctx,
size_t index
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;

/** Generates and exports a secure nonce, of which the public part can be shared
* and fed back for a later signature
*
* Returns: 1 on success
* Args: ctx: an existing context object, initialized for signing (cannot be NULL)
* In: seed: A random seed value
* Out: secnonce32: The secure nonce (scalar), guaranteed to be Jacobi 1
*/
SECP256K1_API int secp256k1_aggsig_export_secnonce_single(
const secp256k1_context* ctx,
unsigned char* secnonce32,
const unsigned char* seed
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_WARN_UNUSED_RESULT;

/** Generate a single-signer signature (or partial sig), without a stored context
*
* Returns: 1 on success, 0 on failure
* Args: ctx: an existing context object, initialized for signing (cannot be NULL)
* Out: sig64: the completed signature (cannot be NULL)
* In: msg32: the message to sign (cannot be NULL)
* seckey32: the secret signing key (cannot be NULL)
* secnonce32: secret nonce to use. If NULL, a nonce will be generated
* extra32: if non-NULL, add this key to s
* pubnonce_for_e: If this is non-NULL, encode this value in e instead of the derived
* pubnonce_total: If non-NULL, allow this signature to be included in combined sig
* in all cases by negating secnonce32 if the public nonce total has jacobi symbol
* -1. secnonce32 must also be provided
* pubkey_for_e: If this is non-NULL, encode this value in e
* seed: a 32-byte seed to use for the nonce-generating RNG (cannot be NULL)
*/
SECP256K1_API int secp256k1_aggsig_sign_single(
const secp256k1_context* ctx,
unsigned char *sig64,
const unsigned char *msg32,
const unsigned char *seckey32,
const unsigned char* secnonce32,
const unsigned char* extra32,
const secp256k1_pubkey *pubnonce_for_e,
const secp256k1_pubkey* pubnonce_total,
const secp256k1_pubkey* pubkey_for_e,
const unsigned char* seed)
SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(10) SECP256K1_WARN_UNUSED_RESULT;

/** Generate a single signature part in an aggregated signature
*
* Returns: 1 on success, 0 on failure
* Args: ctx: an existing context object, initialized for signing (cannot be NULL)
* aggctx: an aggsig context object (cannot be NULL)
* Out: partial: the generated signature part (cannot be NULL)
* In: msg32: the message to sign (cannot be NULL)
* seckey32: the secret signing key (cannot be NULL)
* index: the index of this signature in the aggregate signature
*/
SECP256K1_API int secp256k1_aggsig_partial_sign(
const secp256k1_context* ctx,
secp256k1_aggsig_context* aggctx,
secp256k1_aggsig_partial_signature *partial,
const unsigned char *msg32,
const unsigned char *seckey32,
size_t index
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_WARN_UNUSED_RESULT;


/** Aggregate multiple signature parts into a single aggregated signature
*
* Returns: 1 on success, 0 on failure
* Args: ctx: an existing context object, initialized for signing (cannot be NULL)
* aggctx: an aggsig context object (cannot be NULL)
* Out: sig64: the completed signature (cannot be NULL)
* In: partial: an array of partial signatures to aggregate (cannot be NULL)
* n_sigs: the number of partial signatures provided
*/
SECP256K1_API int secp256k1_aggsig_combine_signatures(
const secp256k1_context* ctx,
secp256k1_aggsig_context* aggctx,
unsigned char *sig64,
const secp256k1_aggsig_partial_signature *partial,
size_t n_sigs
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_WARN_UNUSED_RESULT;

/** Simple addition of two signatures + two public nonces into a single signature
*
* Returns: 1 on success, 0 on failure
* Args: ctx: an existing context object, initialized for signing (cannot be NULL)
* Out: sig64: the completed signature (s1+s2,n1+n2) (cannot be NULL)
* In: sig1_64: a signature (from which s1 will2be taken)
* sig2_64: another signature (from which s1 will be taken)
* pubnonce_total: the total of all public nonces, will simple become R (negated if needed)
*/

SECP256K1_API int secp256k1_aggsig_add_signatures_single(
const secp256k1_context* ctx,
unsigned char *sig64,
const unsigned char** sigs,
size_t num_sigs,
const secp256k1_pubkey* pubnonce_total
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_WARN_UNUSED_RESULT;


/** Verify a single-signer signature, without a stored context
*
* Returns: 1 on success, 0 on failure
* Args: ctx: an existing context object, initialized for signing (cannot be NULL)
* In: sig64: signature (cannot be NULL)
* msg32: the message to verify (cannot be NULL)
* pubnonce: if non-NULL, override the public nonce used to calculate e
* pubkey: the public key (cannot be NULL)
* pubkey_total: if non-NULL, encode this value in e
* extra_pubkey: if non-NULL, subtract this pubkey from sG
* is_partial: whether to ignore the jacobi symbol of the combined R, set this to 1
* to verify partial signatures that may have had their secret nonces negated
*/
SECP256K1_API int secp256k1_aggsig_verify_single(
const secp256k1_context* ctx,
const unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_pubkey *pubnonce,
const secp256k1_pubkey *pubkey,
const secp256k1_pubkey *pubkey_total,
const secp256k1_pubkey *extra_pubkey,
const int is_partial)
SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_WARN_UNUSED_RESULT;

/** Verify an aggregate signature
*
* Returns: 1 if the signature is valid, 0 if not
* Args: ctx: an existing context object (cannot be NULL)
* scratch: a scratch space (cannot be NULL)
* In: sig64: the signature to verify (cannot be NULL)
* msg32: the message that should be signed (cannot be NULL)
* pubkeys: array of public keys (cannot be NULL)
* n_keys: the number of public keys
*/
SECP256K1_API int secp256k1_aggsig_verify(
const secp256k1_context* ctx,
secp256k1_scratch_space* scratch,
const unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_pubkey *pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_WARN_UNUSED_RESULT;

/** Verify an aggregate signature, building scratch space interally beforehand
*
* Returns: 1 if the signature is valid, 0 if not
* Args: ctx: an existing context object (cannot be NULL)
* In: sig64: the signature to verify (cannot be NULL)
* msg32: the message that should be signed (cannot be NULL)
* pubkeys: array of public keys (cannot be NULL)
* n_keys: the number of public keys
*/

SECP256K1_API int secp256k1_aggsig_build_scratch_and_verify(
const secp256k1_context* ctx,
const unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_pubkey *pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_WARN_UNUSED_RESULT;

# ifdef __cplusplus
}
# endif

#endif

0 comments on commit 8c0fcb8

Please sign in to comment.