Merge branch 'master' into sync-7262adb4
This commit is contained in:
73
include/secp256k1_bppp.h
Normal file
73
include/secp256k1_bppp.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef SECP256K1_BPPP_H
|
||||
# define SECP256K1_BPPP_H
|
||||
|
||||
# include "secp256k1.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** Opaque structure representing a large number of NUMS generators */
|
||||
typedef struct secp256k1_bppp_generators secp256k1_bppp_generators;
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* TODO: In a followup range-proof PR, this is would still require 16 + 8 = 24 NUMS
|
||||
* points. We will later use G = H0(required for compatibility with pedersen_commitment DS)
|
||||
* in a separate commit to make review easier.
|
||||
*/
|
||||
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 at least
|
||||
* k = 33 * num_gens. Will be set to k on successful return
|
||||
*
|
||||
* TODO: For ease of review, this setting G = H0 is not included in this commit. We will
|
||||
* add it in the follow-up rangeproof PR.
|
||||
*/
|
||||
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);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
164
include/secp256k1_ecdsa_adaptor.h
Normal file
164
include/secp256k1_ecdsa_adaptor.h
Normal file
@@ -0,0 +1,164 @@
|
||||
#ifndef SECP256K1_ECDSA_ADAPTOR_H
|
||||
#define SECP256K1_ECDSA_ADAPTOR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "secp256k1.h"
|
||||
|
||||
/** This module implements single signer ECDSA adaptor signatures following
|
||||
* "One-Time Verifiably Encrypted Signatures A.K.A. Adaptor Signatures" by
|
||||
* Lloyd Fournier
|
||||
* (https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-November/002316.html
|
||||
* and https://github.com/LLFourn/one-time-VES/blob/master/main.pdf).
|
||||
*
|
||||
* WARNING! DANGER AHEAD!
|
||||
* As mentioned in Lloyd Fournier's paper, the adaptor signature leaks the
|
||||
* Elliptic-curve Diffie–Hellman (ECDH) key between the signing key and the
|
||||
* encryption key. This is not a problem for ECDSA adaptor signatures
|
||||
* themselves, but may result in a complete loss of security when they are
|
||||
* composed with other schemes. More specifically, let us refer to the
|
||||
* signer's public key as X = x*G, and to the encryption key as Y = y*G.
|
||||
* Given X, Y and the adaptor signature, it is trivial to compute Y^x = X^y.
|
||||
*
|
||||
* A defense is to not reuse the signing key of ECDSA adaptor signatures in
|
||||
* protocols that rely on the hardness of the CDH problem, e.g., Diffie-Hellman
|
||||
* key exchange and ElGamal encryption. In general, it is a well-established
|
||||
* cryptographic practice to seperate keys for different purposes whenever
|
||||
* possible.
|
||||
*/
|
||||
|
||||
/** A pointer to a function to deterministically generate a nonce.
|
||||
*
|
||||
* Same as secp256k1_nonce_function_hardened with the exception of using the
|
||||
* compressed 33-byte encoding for the pubkey argument.
|
||||
*
|
||||
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
|
||||
* return an error.
|
||||
* Out: nonce32: pointer to a 32-byte array to be filled by the function
|
||||
* In: msg32: the 32-byte message hash being verified
|
||||
* key32: pointer to a 32-byte secret key
|
||||
* pk33: the 33-byte serialized pubkey corresponding to key32
|
||||
* algo: pointer to an array describing the signature algorithm
|
||||
* algolen: the length of the algo array
|
||||
* data: arbitrary data pointer that is passed through
|
||||
*
|
||||
* Except for test cases, this function should compute some cryptographic hash of
|
||||
* the message, the key, the pubkey, the algorithm description, and data.
|
||||
*/
|
||||
typedef int (*secp256k1_nonce_function_hardened_ecdsa_adaptor)(
|
||||
unsigned char *nonce32,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *key32,
|
||||
const unsigned char *pk33,
|
||||
const unsigned char *algo,
|
||||
size_t algolen,
|
||||
void *data
|
||||
);
|
||||
|
||||
/** A modified BIP-340 nonce generation function. If a data pointer is passed, it is
|
||||
* assumed to be a pointer to 32 bytes of auxiliary random data as defined in BIP-340.
|
||||
* The hash will be tagged with algo after removing all terminating null bytes.
|
||||
*/
|
||||
SECP256K1_API const secp256k1_nonce_function_hardened_ecdsa_adaptor secp256k1_nonce_function_ecdsa_adaptor;
|
||||
|
||||
/** Encrypted Signing
|
||||
*
|
||||
* Creates an adaptor signature, which includes a proof to verify the adaptor
|
||||
* signature.
|
||||
* WARNING: Make sure you have read and understood the WARNING at the top of
|
||||
* this file and applied the suggested countermeasures.
|
||||
*
|
||||
* Returns: 1 on success, 0 on failure
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: adaptor_sig162: pointer to 162 byte to store the returned signature
|
||||
* In: seckey32: pointer to 32 byte secret key that will be used for
|
||||
* signing
|
||||
* enckey: pointer to the encryption public key
|
||||
* msg32: pointer to the 32-byte message hash to sign
|
||||
* noncefp: pointer to a nonce generation function. If NULL,
|
||||
* secp256k1_nonce_function_ecdsa_adaptor is used
|
||||
* ndata: pointer to arbitrary data used by the nonce generation
|
||||
* function (can be NULL). If it is non-NULL and
|
||||
* secp256k1_nonce_function_ecdsa_adaptor is used, then
|
||||
* ndata must be a pointer to 32-byte auxiliary randomness
|
||||
* as per BIP-340.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_adaptor_encrypt(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *adaptor_sig162,
|
||||
unsigned char *seckey32,
|
||||
const secp256k1_pubkey *enckey,
|
||||
const unsigned char *msg32,
|
||||
secp256k1_nonce_function_hardened_ecdsa_adaptor noncefp,
|
||||
void *ndata
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Encryption Verification
|
||||
*
|
||||
* Verifies that the adaptor decryption key can be extracted from the adaptor signature
|
||||
* and the completed ECDSA signature.
|
||||
*
|
||||
* Returns: 1 on success, 0 on failure
|
||||
* Args: ctx: pointer to a context object
|
||||
* In: adaptor_sig162: pointer to 162-byte signature to verify
|
||||
* pubkey: pointer to the public key corresponding to the secret key
|
||||
* used for signing
|
||||
* msg32: pointer to the 32-byte message hash being verified
|
||||
* enckey: pointer to the adaptor encryption public key
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_adaptor_verify(
|
||||
const secp256k1_context *ctx,
|
||||
const unsigned char *adaptor_sig162,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_pubkey *enckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Signature Decryption
|
||||
*
|
||||
* Derives an ECDSA signature from an adaptor signature and an adaptor decryption key.
|
||||
*
|
||||
* Returns: 1 on success, 0 on failure
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: sig: pointer to the ECDSA signature to create
|
||||
* In: deckey32: pointer to 32-byte decryption secret key for the adaptor
|
||||
* encryption public key
|
||||
* adaptor_sig162: pointer to 162-byte adaptor sig
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_adaptor_decrypt(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *deckey32,
|
||||
const unsigned char *adaptor_sig162
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Decryption Key Recovery
|
||||
*
|
||||
* Extracts the adaptor decryption key from the complete signature and the adaptor
|
||||
* signature.
|
||||
*
|
||||
* Returns: 1 on success, 0 on failure
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: deckey32: pointer to 32-byte adaptor decryption key for the adaptor
|
||||
* encryption public key
|
||||
* In: sig: pointer to ECDSA signature to recover the adaptor decryption
|
||||
* key from
|
||||
* adaptor_sig162: pointer to adaptor signature to recover the adaptor
|
||||
* decryption key from
|
||||
* enckey: pointer to the adaptor encryption public key
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_adaptor_recover(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *deckey32,
|
||||
const secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *adaptor_sig162,
|
||||
const secp256k1_pubkey *enckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_ECDSA_ADAPTOR_H */
|
||||
234
include/secp256k1_ecdsa_s2c.h
Normal file
234
include/secp256k1_ecdsa_s2c.h
Normal file
@@ -0,0 +1,234 @@
|
||||
#ifndef SECP256K1_ECDSA_S2C_H
|
||||
#define SECP256K1_ECDSA_S2C_H
|
||||
|
||||
#include "secp256k1.h"
|
||||
|
||||
/** This module implements the sign-to-contract scheme for ECDSA signatures, as
|
||||
* well as the "ECDSA Anti-Exfil Protocol" that is based on sign-to-contract
|
||||
* and is specified further down. The sign-to-contract scheme allows creating a
|
||||
* signature that also commits to some data. This works by offsetting the public
|
||||
* nonce point of the signature R by hash(R, data)*G where G is the secp256k1
|
||||
* group generator.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Data structure that holds a sign-to-contract ("s2c") opening information.
|
||||
* Sign-to-contract allows a signer to commit to some data as part of a signature. It
|
||||
* can be used as an Out-argument in certain signing functions.
|
||||
*
|
||||
* 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 64 bytes in size, and can be safely copied/moved.
|
||||
* If you need to convert to a format suitable for storage, transmission, or
|
||||
* comparison, use secp256k1_ecdsa_s2c_opening_serialize and secp256k1_ecdsa_s2c_opening_parse.
|
||||
*/
|
||||
typedef struct secp256k1_ecdsa_s2c_opening {
|
||||
unsigned char data[64];
|
||||
} secp256k1_ecdsa_s2c_opening;
|
||||
|
||||
/** Parse a sign-to-contract opening.
|
||||
*
|
||||
* Returns: 1 if the opening could be parsed
|
||||
* 0 if the opening could not be parsed
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: opening: pointer to an opening object. If 1 is returned, it is set to a
|
||||
* parsed version of input. If not, its value is unspecified.
|
||||
* In: input33: pointer to 33-byte array with a serialized opening
|
||||
*
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_s2c_opening_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_s2c_opening *opening,
|
||||
const unsigned char *input33
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a sign-to-contract opening into a byte sequence.
|
||||
*
|
||||
* Returns: 1 if the opening was successfully serialized.
|
||||
* 0 if the opening could not be serialized
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: output33: pointer to a 33-byte array to place the serialized opening in
|
||||
* In: opening: pointer to an initialized `secp256k1_ecdsa_s2c_opening`
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_s2c_opening_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output33,
|
||||
const secp256k1_ecdsa_s2c_opening *opening
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Same as secp256k1_ecdsa_sign, but s2c_data32 is committed to inside the nonce
|
||||
*
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, or the private key was invalid.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
|
||||
* s2c_opening: if non-NULL, pointer to an secp256k1_ecdsa_s2c_opening structure to populate
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* s2c_data32: pointer to a 32-byte data to commit to in the nonce (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_s2c_sign(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
secp256k1_ecdsa_s2c_opening *s2c_opening,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *seckey,
|
||||
const unsigned char *s2c_data32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
|
||||
|
||||
/** Verify a sign-to-contract commitment.
|
||||
*
|
||||
* Returns: 1: the signature contains a commitment to data32 (though it does
|
||||
* not necessarily need to be a valid siganture!)
|
||||
* 0: incorrect opening
|
||||
* Args: ctx: pointer to a context object
|
||||
* In: sig: the signature containing the sign-to-contract commitment (cannot be NULL)
|
||||
* data32: the 32-byte data that was committed to (cannot be NULL)
|
||||
* opening: pointer to the opening created during signing (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_s2c_verify_commit(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *data32,
|
||||
const secp256k1_ecdsa_s2c_opening *opening
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
|
||||
/** ECDSA Anti-Exfil Protocol
|
||||
*
|
||||
* The ecdsa_anti_exfil_* functions can be used to prevent a signing device from
|
||||
* exfiltrating the secret signing keys through biased signature nonces. The general
|
||||
* idea is that a host provides additional randomness to the signing device client
|
||||
* and the client commits to the randomness in the nonce using sign-to-contract.
|
||||
*
|
||||
* The following scheme is described by Stepan Snigirev here:
|
||||
* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-February/017655.html
|
||||
* and by Pieter Wuille (as "Scheme 6") here:
|
||||
* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-March/017667.html
|
||||
*
|
||||
* In order to ensure the host cannot trick the signing device into revealing its
|
||||
* keys, or the signing device to bias the nonce despite the host's contributions,
|
||||
* the host and client must engage in a commit-reveal protocol as follows:
|
||||
* 1. The host draws randomness `rho` and computes a sha256 commitment to it using
|
||||
* `secp256k1_ecdsa_anti_exfil_host_commit`. It sends this to the signing device.
|
||||
* 2. The signing device computes a public nonce `R` using the host's commitment
|
||||
* as auxiliary randomness, using `secp256k1_ecdsa_anti_exfil_signer_commit`.
|
||||
* The signing device sends the resulting `R` to the host as a s2c_opening.
|
||||
*
|
||||
* If, at any point from this step onward, the hardware device fails, it is
|
||||
* okay to restart the protocol using **exactly the same `rho`** and checking
|
||||
* that the hardware device proposes **exactly the same** `R`. Otherwise, the
|
||||
* hardware device may be selectively aborting and thereby biasing the set of
|
||||
* nonces that are used in actual signatures.
|
||||
*
|
||||
* It takes many (>100) such aborts before there is a plausible attack, given
|
||||
* current knowledge in 2020. However such aborts accumulate even across a total
|
||||
* replacement of all relevant devices (but not across replacement of the actual
|
||||
* signing keys with new independently random ones).
|
||||
*
|
||||
* In case the hardware device cannot be made to sign with the given `rho`, `R`
|
||||
* pair, wallet authors should alert the user and present a very scary message
|
||||
* implying that if this happens more than even a few times, say 20 or more times
|
||||
* EVER, they should change hardware vendors and perhaps sweep their coins.
|
||||
*
|
||||
* 3. The host replies with `rho` generated in step 1.
|
||||
* 4. The device signs with `secp256k1_anti_exfil_sign`, using `rho` as `host_data32`,
|
||||
* and sends the signature to the host.
|
||||
* 5. The host verifies that the signature's public nonce matches the opening from
|
||||
* step 2 and its original randomness `rho`, using `secp256k1_anti_exfil_host_verify`.
|
||||
*
|
||||
* Rationale:
|
||||
* - The reason for having a host commitment is to allow the signing device to
|
||||
* deterministically derive a unique nonce even if the host restarts the protocol
|
||||
* using the same message and keys. Otherwise the signer might reuse the original
|
||||
* nonce in two iterations of the protocol with different `rho`, which leaks the
|
||||
* the secret key.
|
||||
* - The signer does not need to check that the host commitment matches the host's
|
||||
* claimed `rho`. Instead it re-derives the commitment (and its original `R`) from
|
||||
* the provided `rho`. If this differs from the original commitment, the result
|
||||
* will be an invalid `s2c_opening`, but since `R` was unique there is no risk to
|
||||
* the signer's secret keys. Because of this, the signing device does not need to
|
||||
* maintain any state about the progress of the protocol.
|
||||
*/
|
||||
|
||||
/** Create the initial host commitment to `rho`. Part of the ECDSA Anti-Exfil Protocol.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: pointer to a context object (cannot be NULL)
|
||||
* Out: rand_commitment32: pointer to 32-byte array to store the returned commitment (cannot be NULL)
|
||||
* In: rand32: the 32-byte randomness to commit to (cannot be NULL). It must come from
|
||||
* a cryptographically secure RNG. As per the protocol, this value must not
|
||||
* be revealed to the client until after the host has received the client
|
||||
* commitment.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_anti_exfil_host_commit(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *rand_commitment32,
|
||||
const unsigned char *rand32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Compute signer's original nonce. Part of the ECDSA Anti-Exfil Protocol.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: s2c_opening: pointer to an s2c_opening where the signer's public nonce will be
|
||||
* placed. (cannot be NULL)
|
||||
* In: msg32: the 32-byte message hash to be signed (cannot be NULL)
|
||||
* seckey32: the 32-byte secret key used for signing (cannot be NULL)
|
||||
* rand_commitment32: the 32-byte randomness commitment from the host (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_anti_exfil_signer_commit(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_s2c_opening *s2c_opening,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *seckey32,
|
||||
const unsigned char *rand_commitment32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Same as secp256k1_ecdsa_sign, but commits to host randomness in the nonce. Part of the
|
||||
* ECDSA Anti-Exfil Protocol.
|
||||
*
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, or the private key was invalid.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* host_data32: pointer to 32-byte host-provided randomness (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_anti_exfil_sign(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *seckey,
|
||||
const unsigned char *host_data32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Verify a signature was correctly constructed using the ECDSA Anti-Exfil Protocol.
|
||||
*
|
||||
* Returns: 1: the signature is valid and contains a commitment to host_data32
|
||||
* 0: incorrect opening
|
||||
* Args: ctx: pointer to a context object
|
||||
* In: sig: the signature produced by the signer (cannot be NULL)
|
||||
* msghash32: the 32-byte message hash being verified (cannot be NULL)
|
||||
* pubkey: pointer to the signer's public key (cannot be NULL)
|
||||
* host_data32: the 32-byte data provided by the host (cannot be NULL)
|
||||
* opening: the s2c opening provided by the signer (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_anti_exfil_host_verify(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const unsigned char *host_data32,
|
||||
const secp256k1_ecdsa_s2c_opening *opening
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_ECDSA_S2C_H */
|
||||
241
include/secp256k1_generator.h
Normal file
241
include/secp256k1_generator.h
Normal file
@@ -0,0 +1,241 @@
|
||||
#ifndef SECP256K1_GENERATOR_H
|
||||
# define SECP256K1_GENERATOR_H
|
||||
|
||||
# include "secp256k1.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** Opaque data structure that stores a base point
|
||||
*
|
||||
* 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 64 bytes in size, and can be safely copied/moved.
|
||||
* If you need to convert to a format suitable for storage, transmission, or
|
||||
* comparison, use secp256k1_generator_serialize and secp256k1_generator_parse.
|
||||
*/
|
||||
typedef struct secp256k1_generator {
|
||||
unsigned char data[64];
|
||||
} secp256k1_generator;
|
||||
|
||||
/**
|
||||
* Static constant generator 'h' maintained for historical reasons.
|
||||
*/
|
||||
SECP256K1_API const secp256k1_generator *secp256k1_generator_h;
|
||||
|
||||
/** Parse a 33-byte generator byte sequence into a generator object.
|
||||
*
|
||||
* Returns: 1 if input contains a valid generator.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: gen: pointer to the output generator object
|
||||
* In: input: pointer to a 33-byte serialized generator
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_generator *gen,
|
||||
const unsigned char *input
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a 33-byte generator into a serialized byte sequence.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: output: pointer to a 33-byte byte array
|
||||
* In: gen: pointer to a generator object
|
||||
*/
|
||||
SECP256K1_API int secp256k1_generator_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
const secp256k1_generator *gen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Generate a generator for the curve.
|
||||
*
|
||||
* Returns: 0 in the highly unlikely case the seed is not acceptable,
|
||||
* 1 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: gen: pointer to a the new generator object
|
||||
* In: seed32: 32-byte seed
|
||||
*
|
||||
* If successful a valid generator will be placed in gen. The produced
|
||||
* generators are distributed uniformly over the curve, and will not have a
|
||||
* known discrete logarithm with respect to any other generator produced,
|
||||
* or to the base generator G.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_generator *gen,
|
||||
const unsigned char *seed32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Generate a blinded generator for the curve.
|
||||
*
|
||||
* Returns: 0 in the highly unlikely case the seed is not acceptable or when
|
||||
* blind is out of range. 1 otherwise.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: gen: pointer to a generator object
|
||||
* In: seed32: 32-byte seed
|
||||
* blind32: 32-byte secret value to blind the generator with.
|
||||
*
|
||||
* The result is equivalent to first calling secp256k1_generator_generate,
|
||||
* converting the result to a public key, calling secp256k1_ec_pubkey_tweak_add,
|
||||
* and then converting back to generator form.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate_blinded(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_generator *gen,
|
||||
const unsigned char *seed32,
|
||||
const unsigned char *blind32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Opaque data structure that stores a Pedersen commitment
|
||||
*
|
||||
* 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 64 bytes in size, and can be safely copied/moved.
|
||||
* If you need to convert to a format suitable for storage, transmission, or
|
||||
* comparison, use secp256k1_pedersen_commitment_serialize and
|
||||
* secp256k1_pedersen_commitment_parse.
|
||||
*/
|
||||
typedef struct secp256k1_pedersen_commitment {
|
||||
unsigned char data[64];
|
||||
} secp256k1_pedersen_commitment;
|
||||
|
||||
/** Parse a 33-byte commitment into a commitment object.
|
||||
*
|
||||
* Returns: 1 if input contains a valid commitment.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: commit: pointer to the output commitment object
|
||||
* In: input: pointer to a 33-byte serialized commitment key
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commitment_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pedersen_commitment *commit,
|
||||
const unsigned char *input
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a commitment object into a serialized byte sequence.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: output: pointer to a 33-byte byte array
|
||||
* In: commit: pointer to a secp256k1_pedersen_commitment containing an
|
||||
* initialized commitment
|
||||
*/
|
||||
SECP256K1_API int secp256k1_pedersen_commitment_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
const secp256k1_pedersen_commitment *commit
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Generate a pedersen commitment.
|
||||
* Returns 1: Commitment successfully created.
|
||||
* 0: Error. The blinding factor is larger than the group order
|
||||
* (probability for random 32 byte number < 2^-127) or results in the
|
||||
* point at infinity. Retry with a different factor.
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* blind: pointer to a 32-byte blinding factor (cannot be NULL)
|
||||
* value: unsigned 64-bit integer value to commit to.
|
||||
* gen: additional generator 'h'
|
||||
* Out: commit: pointer to the commitment (cannot be NULL)
|
||||
*
|
||||
* Blinding factors can be generated and verified in the same way as secp256k1 private keys for ECDSA.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pedersen_commitment *commit,
|
||||
const unsigned char *blind,
|
||||
uint64_t value,
|
||||
const secp256k1_generator *gen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Computes the sum of multiple positive and negative blinding factors.
|
||||
* Returns 1: Sum successfully computed.
|
||||
* 0: Error. A blinding factor is larger than the group order
|
||||
* (probability for random 32 byte number < 2^-127). Retry with
|
||||
* different factors.
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* blinds: pointer to pointers to 32-byte character arrays for blinding factors. (cannot be NULL)
|
||||
* n: number of factors pointed to by blinds.
|
||||
* npositive: how many of the initial factors should be treated with a positive sign.
|
||||
* Out: blind_out: pointer to a 32-byte array for the sum (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *blind_out,
|
||||
const unsigned char * const *blinds,
|
||||
size_t n,
|
||||
size_t npositive
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Verify a tally of pedersen commitments
|
||||
* Returns 1: commitments successfully sum to zero.
|
||||
* 0: Commitments do not sum to zero or other error.
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* commits: pointer to array of pointers to the commitments. (cannot be NULL if pcnt is non-zero)
|
||||
* pcnt: number of commitments pointed to by commits.
|
||||
* ncommits: pointer to array of pointers to the negative commitments. (cannot be NULL if ncnt is non-zero)
|
||||
* ncnt: number of commitments pointed to by ncommits.
|
||||
*
|
||||
* This computes sum(commit[0..pcnt)) - sum(ncommit[0..ncnt)) == 0.
|
||||
*
|
||||
* A pedersen commitment is xG + vA where G and A are generators for the secp256k1 group and x is a blinding factor,
|
||||
* while v is the committed value. For a collection of commitments to sum to zero, for each distinct generator
|
||||
* A all blinding factors and all values must sum to zero.
|
||||
*
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_pedersen_commitment * const *commits,
|
||||
size_t pcnt,
|
||||
const secp256k1_pedersen_commitment * const *ncommits,
|
||||
size_t ncnt
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Sets the final Pedersen blinding factor correctly when the generators themselves
|
||||
* have blinding factors.
|
||||
*
|
||||
* Consider a generator of the form A' = A + rG, where A is the "real" generator
|
||||
* but A' is the generator provided to verifiers. Then a Pedersen commitment
|
||||
* P = vA' + r'G really has the form vA + (vr + r')G. To get all these (vr + r')
|
||||
* to sum to zero for multiple commitments, we take three arrays consisting of
|
||||
* the `v`s, `r`s, and `r'`s, respectively called `value`s, `generator_blind`s
|
||||
* and `blinding_factor`s, and sum them.
|
||||
*
|
||||
* The function then subtracts the sum of all (vr + r') from the last element
|
||||
* of the `blinding_factor` array, setting the total sum to zero.
|
||||
*
|
||||
* Returns 1: Blinding factor successfully computed.
|
||||
* 0: Error. A blinding_factor or generator_blind are larger than the group
|
||||
* order (probability for random 32 byte number < 2^-127). Retry with
|
||||
* different values.
|
||||
*
|
||||
* In: ctx: pointer to a context object
|
||||
* value: array of asset values, `v` in the above paragraph.
|
||||
* May not be NULL unless `n_total` is 0.
|
||||
* generator_blind: array of asset blinding factors, `r` in the above paragraph
|
||||
* May not be NULL unless `n_total` is 0.
|
||||
* n_total: Total size of the above arrays
|
||||
* n_inputs: How many of the initial array elements represent commitments that
|
||||
* will be negated in the final sum
|
||||
* In/Out: blinding_factor: array of commitment blinding factors, `r'` in the above paragraph
|
||||
* May not be NULL unless `n_total` is 0.
|
||||
* the last value will be modified to get the total sum to zero.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generator_blind_sum(
|
||||
const secp256k1_context *ctx,
|
||||
const uint64_t *value,
|
||||
const unsigned char * const *generator_blind,
|
||||
unsigned char * const *blinding_factor,
|
||||
size_t n_total,
|
||||
size_t n_inputs
|
||||
);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@ extern "C" {
|
||||
* v1.0.0. You can find an example demonstrating the musig module in
|
||||
* examples/musig.c.
|
||||
*
|
||||
* The module also supports BIP 341 ("Taproot") public key tweaking.
|
||||
* The module also supports BIP 341 ("Taproot") public key tweaking and adaptor signatures.
|
||||
*
|
||||
* It is recommended to read the documentation in this include file carefully.
|
||||
* Further notes on API usage can be found in doc/musig.md
|
||||
@@ -462,6 +462,11 @@ SECP256K1_API int secp256k1_musig_nonce_agg(
|
||||
/** Takes the aggregate nonce and creates a session that is required for signing
|
||||
* and verification of partial signatures.
|
||||
*
|
||||
* If the adaptor argument is non-NULL, then the output of
|
||||
* musig_partial_sig_agg will be a pre-signature which is not a valid Schnorr
|
||||
* signature. In order to create a valid signature, the pre-signature and the
|
||||
* secret adaptor must be provided to `musig_adapt`.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: session: pointer to a struct to store the session
|
||||
@@ -470,13 +475,17 @@ SECP256K1_API int secp256k1_musig_nonce_agg(
|
||||
* msg32: the 32-byte message to sign
|
||||
* keyagg_cache: pointer to the keyagg_cache that was used to create the
|
||||
* aggregate (and potentially tweaked) pubkey
|
||||
* adaptor: optional pointer to an adaptor point encoded as a public
|
||||
* key if this signing session is part of an adaptor
|
||||
* signature protocol (can be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_process(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_session *session,
|
||||
const secp256k1_musig_aggnonce *aggnonce,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const secp256k1_pubkey *adaptor
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Produces a partial signature
|
||||
@@ -534,7 +543,8 @@ SECP256K1_API int secp256k1_musig_partial_sign(
|
||||
* before aggregating it with `musig_nonce_agg` and using the result to
|
||||
* create the `session` with `musig_nonce_process`.
|
||||
*
|
||||
* It is not required to call this function in regular MuSig sessions, because
|
||||
* This function is essential when using protocols with adaptor signatures.
|
||||
* Without adaptor signatures, it is not required to call this function in regular MuSig sessions, because
|
||||
* if any partial signature does not verify, the final signature will not
|
||||
* verify either, so the problem will be caught. However, this function
|
||||
* provides the ability to identify which specific partial signature fails
|
||||
@@ -581,6 +591,77 @@ SECP256K1_API int secp256k1_musig_partial_sig_agg(
|
||||
size_t n_sigs
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Extracts the nonce_parity bit from a session
|
||||
*
|
||||
* This is used for adaptor signatures.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: nonce_parity: pointer to an integer that indicates the parity
|
||||
* of the aggregate public nonce. Used for adaptor
|
||||
* signatures.
|
||||
* In: session: pointer to the session that was created with
|
||||
* musig_nonce_process
|
||||
*/
|
||||
SECP256K1_API int secp256k1_musig_nonce_parity(
|
||||
const secp256k1_context *ctx,
|
||||
int *nonce_parity,
|
||||
const secp256k1_musig_session *session
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Creates a signature from a pre-signature and an adaptor.
|
||||
*
|
||||
* If the sec_adaptor32 argument is incorrect, the output signature will be
|
||||
* invalid. This function does not verify the signature.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, or pre_sig64 or sec_adaptor32 contain
|
||||
* invalid (overflowing) values. 1 otherwise (which does NOT mean the
|
||||
* signature or the adaptor are valid!)
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: sig64: 64-byte signature. This pointer may point to the same
|
||||
* memory area as `pre_sig`.
|
||||
* In: pre_sig64: 64-byte pre-signature
|
||||
* sec_adaptor32: 32-byte secret adaptor to add to the pre-signature
|
||||
* nonce_parity: the output of `musig_nonce_parity` called with the
|
||||
* session used for producing the pre-signature
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_adapt(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *pre_sig64,
|
||||
const unsigned char *sec_adaptor32,
|
||||
int nonce_parity
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Extracts a secret adaptor from a MuSig pre-signature and corresponding
|
||||
* signature
|
||||
*
|
||||
* This function will not fail unless given grossly invalid data; if it is
|
||||
* merely given signatures that do not verify, the returned value will be
|
||||
* nonsense. It is therefore important that all data be verified at earlier
|
||||
* steps of any protocol that uses this function. In particular, this includes
|
||||
* verifying all partial signatures that were aggregated into pre_sig64.
|
||||
*
|
||||
* Returns: 0 if the arguments are NULL, or sig64 or pre_sig64 contain
|
||||
* grossly invalid (overflowing) values. 1 otherwise (which does NOT
|
||||
* mean the signatures or the adaptor are valid!)
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out:sec_adaptor32: 32-byte secret adaptor
|
||||
* In: sig64: complete, valid 64-byte signature
|
||||
* pre_sig64: the pre-signature corresponding to sig64, i.e., the
|
||||
* aggregate of partial signatures without the secret
|
||||
* adaptor
|
||||
* nonce_parity: the output of `musig_nonce_parity` called with the
|
||||
* session used for producing sig64
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_adaptor(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sec_adaptor32,
|
||||
const unsigned char *sig64,
|
||||
const unsigned char *pre_sig64,
|
||||
int nonce_parity
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
217
include/secp256k1_rangeproof.h
Normal file
217
include/secp256k1_rangeproof.h
Normal file
@@ -0,0 +1,217 @@
|
||||
#ifndef SECP256K1_RANGEPROOF_H
|
||||
# define SECP256K1_RANGEPROOF_H
|
||||
|
||||
# include "secp256k1.h"
|
||||
# include "secp256k1_generator.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** This module implements a variant of Back-Maxwell range proofs as described
|
||||
* in the Confidential Assets paper (https://blockstream.com/bitcoin17-final41.pdf).
|
||||
* The construction is based on Borromean ring signatures.
|
||||
* (https://nt4tn.net/papers/borromean_draft_0.01_34241bb.pdf)
|
||||
*
|
||||
* This implementation differs from the variant in the paper mainly in that it
|
||||
* omits an optimization that saves one scalar per ring. This optimization complicates
|
||||
* the protocol and security analysis, as it requires differentiating cases where
|
||||
* the i-th bit v_i = 0 versus otherwise, and makes calculating response points R_i less
|
||||
* straightforward. The implemented version uses Borromean ring signatures in
|
||||
* an unmodified way.
|
||||
*
|
||||
* Another difference is that the implementation omits the last ring's commitment
|
||||
* from the proof, which is recovered by the verifier by subtracting all other digit
|
||||
* commitments from the total, reducing proof size by one group element.
|
||||
*
|
||||
* Furthermore, in the implementation every hash calculation includes a message
|
||||
* m=SHA256(C||H||header||C_0||...||C_(n-2)||extra_commit), binding the commitment C,
|
||||
* generator H, proof header, the n-1 explicit digit commitments, and any extra data.
|
||||
* This prevents an attack that would compromise non-malleability. In the paper's
|
||||
* version of the protocol, a prover could pick distinct indices i, j and a scalar y,
|
||||
* and modify digit commitments in the original proof by setting C'_i = C_i + yG and
|
||||
* C'_j = C_j - yG, obtaining a different valid proof for the same commitment and
|
||||
* witness.
|
||||
*
|
||||
* In the current implementation, up to 3968 bytes of message data can be
|
||||
* embedded and recovered within maximally-sized proofs. The implemented embedding
|
||||
* method using the forged parts of ring signatures could also be applied to the
|
||||
* construction in the paper, but is not mentioned there. Message embedding is used
|
||||
* in Confidential Assets to transmit values and blinding factors of the corresponding
|
||||
* commitments. This is possible because randomness is generated by seeding HMAC-DRBG
|
||||
* with the shared ECDH key, allowing the receiver to rewind the proof using the same
|
||||
* random values the sender used.
|
||||
*/
|
||||
|
||||
/** Length of a message that can be embedded into a maximally-sized rangeproof
|
||||
*
|
||||
* It is not be possible to fit a message of this size into a non-maximally-sized
|
||||
* rangeproof, but it is guaranteed that any embeddable message can fit into an
|
||||
* array of this size. This constant is intended to be used for memory allocations
|
||||
* and sanity checks.
|
||||
*/
|
||||
#define SECP256K1_RANGEPROOF_MAX_MESSAGE_LEN 3968
|
||||
|
||||
/** Verify a proof that a committed value is within a range.
|
||||
* Returns 1: Value is within the range [0..2^64), the specifically proven range is in the min/max value outputs.
|
||||
* 0: Proof failed or other error.
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* commit: the commitment being proved. (cannot be NULL)
|
||||
* proof: pointer to character array with the proof. (cannot be NULL)
|
||||
* plen: length of proof in bytes.
|
||||
* extra_commit: additional data covered in rangeproof signature
|
||||
* extra_commit_len: length of extra_commit byte array (0 if NULL)
|
||||
* gen: additional generator 'h'
|
||||
* Out: min_value: pointer to a unsigned int64 which will be updated with the minimum value that commit could have. (cannot be NULL)
|
||||
* max_value: pointer to a unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_verify(
|
||||
const secp256k1_context *ctx,
|
||||
uint64_t *min_value,
|
||||
uint64_t *max_value,
|
||||
const secp256k1_pedersen_commitment *commit,
|
||||
const unsigned char *proof,
|
||||
size_t plen,
|
||||
const unsigned char *extra_commit,
|
||||
size_t extra_commit_len,
|
||||
const secp256k1_generator *gen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(9);
|
||||
|
||||
/** Verify a range proof proof and rewind the proof to recover information sent by its author.
|
||||
* Returns 1: Value is within the range [0..2^64), the specifically proven range is in the min/max value outputs, and the value and blinding were recovered.
|
||||
* 0: Proof failed, rewind failed, or other error.
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* commit: the commitment being proved. (cannot be NULL)
|
||||
* proof: pointer to character array with the proof. (cannot be NULL)
|
||||
* plen: length of proof in bytes.
|
||||
* nonce: 32-byte secret nonce used by the prover (cannot be NULL)
|
||||
* extra_commit: additional data covered in rangeproof signature
|
||||
* extra_commit_len: length of extra_commit byte array (0 if NULL)
|
||||
* gen: additional generator 'h'
|
||||
* In/Out: blind_out: storage for the 32-byte blinding factor used for the commitment
|
||||
* value_out: pointer to an unsigned int64 which has the exact value of the commitment.
|
||||
* message_out: pointer to a 4096 byte character array to receive message data from the proof author.
|
||||
* outlen: length of message data written to message_out. This is generally not equal to the
|
||||
* msg_len used by the signer. However, for all i with msg_len <= i < outlen, it is
|
||||
* guaranteed that message_out[i] == 0.
|
||||
* min_value: pointer to an unsigned int64 which will be updated with the minimum value that commit could have. (cannot be NULL)
|
||||
* max_value: pointer to an unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *blind_out,
|
||||
uint64_t *value_out,
|
||||
unsigned char *message_out,
|
||||
size_t *outlen,
|
||||
const unsigned char *nonce,
|
||||
uint64_t *min_value,
|
||||
uint64_t *max_value,
|
||||
const secp256k1_pedersen_commitment *commit,
|
||||
const unsigned char *proof,
|
||||
size_t plen,
|
||||
const unsigned char *extra_commit,
|
||||
size_t extra_commit_len,
|
||||
const secp256k1_generator *gen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(9) SECP256K1_ARG_NONNULL(10) SECP256K1_ARG_NONNULL(14);
|
||||
|
||||
/** Author a proof that a committed value is within a range.
|
||||
* Returns 1: Proof successfully created.
|
||||
* 0: Error
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* proof: pointer to array to receive the proof, can be up to 5134 bytes. (cannot be NULL)
|
||||
* min_value: constructs a proof where the verifer can tell the minimum value is at least the specified amount.
|
||||
* commit: the commitment being proved.
|
||||
* blind: 32-byte blinding factor used by commit. The blinding factor may be all-zeros as long as min_bits is set to 3 or greater.
|
||||
* This is a side-effect of the underlying crypto, not a deliberate API choice, but it may be useful when balancing CT transactions.
|
||||
* nonce: 32-byte secret nonce used to initialize the proof (value can be reverse-engineered out of the proof if this secret is known.)
|
||||
* exp: Base-10 exponent. Digits below above will be made public, but the proof will be made smaller. Allowed range is -1 to 18.
|
||||
* (-1 is a special case that makes the value public. 0 is the most private.)
|
||||
* min_bits: Number of bits of the value to keep private. (0 = auto/minimal, - 64).
|
||||
* value: Actual value of the commitment.
|
||||
* message: pointer to a byte array of data to be embedded in the rangeproof that can be recovered by rewinding the proof
|
||||
* msg_len: size of the message to be embedded in the rangeproof
|
||||
* extra_commit: additional data to be covered in rangeproof signature
|
||||
* extra_commit_len: length of extra_commit byte array (0 if NULL)
|
||||
* gen: additional generator 'h'
|
||||
* In/out: plen: point to an integer with the size of the proof buffer and the size of the constructed proof.
|
||||
*
|
||||
* If min_value or exp is non-zero then the value must be on the range [0, 2^63) to prevent the proof range from spanning past 2^64.
|
||||
*
|
||||
* If exp is -1 the value is revealed by the proof (e.g. it proves that the proof is a blinding of a specific value, without revealing the blinding key.)
|
||||
*
|
||||
* This can randomly fail with probability around one in 2^100. If this happens, buy a lottery ticket and retry with a different nonce or blinding.
|
||||
*
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *proof,
|
||||
size_t *plen,
|
||||
uint64_t min_value,
|
||||
const secp256k1_pedersen_commitment *commit,
|
||||
const unsigned char *blind,
|
||||
const unsigned char *nonce,
|
||||
int exp,
|
||||
int min_bits,
|
||||
uint64_t value,
|
||||
const unsigned char *message,
|
||||
size_t msg_len,
|
||||
const unsigned char *extra_commit,
|
||||
size_t extra_commit_len,
|
||||
const secp256k1_generator *gen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(15);
|
||||
|
||||
/** Extract some basic information from a range-proof.
|
||||
* Returns 1: Information successfully extracted.
|
||||
* 0: Decode failed.
|
||||
* In: ctx: pointer to a context object
|
||||
* proof: pointer to character array with the proof.
|
||||
* plen: length of proof in bytes.
|
||||
* Out: exp: Exponent used in the proof (-1 means the value isn't private).
|
||||
* mantissa: Number of bits covered by the proof.
|
||||
* min_value: pointer to an unsigned int64 which will be updated with the minimum value that commit could have. (cannot be NULL)
|
||||
* max_value: pointer to an unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info(
|
||||
const secp256k1_context *ctx,
|
||||
int *exp,
|
||||
int *mantissa,
|
||||
uint64_t *min_value,
|
||||
uint64_t *max_value,
|
||||
const unsigned char *proof,
|
||||
size_t plen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Returns an upper bound on the size of a rangeproof with the given parameters
|
||||
*
|
||||
* An actual rangeproof may be smaller, for example if the actual value
|
||||
* is less than both the provided `max_value` and 2^`min_bits`, or if
|
||||
* the `exp` parameter to `secp256k1_rangeproof_sign` is set such that
|
||||
* the proven range is compressed. In particular this function will always
|
||||
* overestimate the size of single-value proofs. Also, if `min_value`
|
||||
* is set to 0 in the proof, the result will usually, but not always,
|
||||
* be 8 bytes smaller than if a nonzero value had been passed.
|
||||
*
|
||||
* The goal of this function is to provide a useful upper bound for
|
||||
* memory allocation or fee estimation purposes, without requiring
|
||||
* too many parameters be fixed in advance.
|
||||
*
|
||||
* To obtain the size of largest possible proof, set `max_value` to
|
||||
* `UINT64_MAX` (and `min_bits` to any valid value such as 0).
|
||||
*
|
||||
* In: ctx: pointer to a context object
|
||||
* max_value: the maximum value that might be passed for `value` for the proof.
|
||||
* min_bits: the value that will be passed as `min_bits` for the proof.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT size_t secp256k1_rangeproof_max_size(
|
||||
const secp256k1_context *ctx,
|
||||
uint64_t max_value,
|
||||
int min_bits
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
107
include/secp256k1_schnorrsig_halfagg.h
Normal file
107
include/secp256k1_schnorrsig_halfagg.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef SECP256K1_SCHNORRSIG_HALFAGG_H
|
||||
#define SECP256K1_SCHNORRSIG_HALFAGG_H
|
||||
|
||||
#include "secp256k1.h"
|
||||
#include "secp256k1_extrakeys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** Incrementally (Half-)Aggregate a sequence of Schnorr
|
||||
* signatures to an existing half-aggregate signature.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* In/Out: aggsig: pointer to the serialized aggregate signature
|
||||
* that is input. The first 32*(n_before+1) of this
|
||||
* array should hold the input aggsig. It will be
|
||||
* overwritten by the new serialized aggregate signature.
|
||||
* It should be large enough for that, see aggsig_len.
|
||||
* aggsig_len: size of aggsig array in bytes.
|
||||
* Should be large enough to hold the new
|
||||
* serialized aggregate signature, i.e.,
|
||||
* should satisfy aggsig_size >= 32*(n_before+n_new+1).
|
||||
* It will be overwritten to be the exact size of the
|
||||
* resulting aggsig.
|
||||
* In: all_pubkeys: Array of (n_before + n_new) many x-only public keys,
|
||||
* including both the ones for the already aggregated signature
|
||||
* and the ones for the signatures that should be added.
|
||||
* Can only be NULL if n_before + n_new is 0.
|
||||
* all_msgs32: Array of (n_before + n_new) many 32-byte messages,
|
||||
* including both the ones for the already aggregated signature
|
||||
* and the ones for the signatures that should be added.
|
||||
* Can only be NULL if n_before + n_new is 0.
|
||||
* new_sigs64: Array of n_new many 64-byte signatures, containing the new
|
||||
* signatures that should be added. Can only be NULL if n_new is 0.
|
||||
* n_before: Number of signatures that have already been aggregated
|
||||
* in the input aggregate signature.
|
||||
* n_new: Number of signatures that should now be added
|
||||
* to the aggregate signature.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorrsig_inc_aggregate(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *aggsig,
|
||||
size_t *aggsig_len,
|
||||
const secp256k1_xonly_pubkey* all_pubkeys,
|
||||
const unsigned char *all_msgs32,
|
||||
const unsigned char *new_sigs64,
|
||||
size_t n_before,
|
||||
size_t n_new
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** (Half-)Aggregate a sequence of Schnorr signatures.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* Out: aggsig: pointer to an array of aggsig_len many bytes to
|
||||
* store the serialized aggregate signature.
|
||||
* In/Out: aggsig_len: size of the aggsig array that is passed in bytes;
|
||||
* will be overwritten to be the exact size of aggsig.
|
||||
* In: pubkeys: Array of n many x-only public keys.
|
||||
* Can only be NULL if n is 0.
|
||||
* msgs32: Array of n many 32-byte messages.
|
||||
* Can only be NULL if n is 0.
|
||||
* sigs64: Array of n many 64-byte signatures.
|
||||
* Can only be NULL if n is 0.
|
||||
* n: number of signatures to be aggregated.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorrsig_aggregate(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *aggsig,
|
||||
size_t *aggsig_len,
|
||||
const secp256k1_xonly_pubkey *pubkeys,
|
||||
const unsigned char *msgs32,
|
||||
const unsigned char *sigs64,
|
||||
size_t n
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Verify a (Half-)aggregate Schnorr signature.
|
||||
*
|
||||
* Returns: 1: correct signature.
|
||||
* 0: incorrect signature.
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* In: pubkeys: Array of n many x-only public keys. Can only be NULL if n is 0.
|
||||
* msgs32: Array of n many 32-byte messages. Can only be NULL if n is 0.
|
||||
* n: number of signatures to that have been aggregated.
|
||||
* aggsig: Pointer to an array of aggsig_size many bytes
|
||||
* containing the serialized aggregate
|
||||
* signature to be verified.
|
||||
* aggsig_len: Size of the aggregate signature in bytes.
|
||||
* Should be aggsig_len = 32*(n+1)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_aggverify(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_xonly_pubkey *pubkeys,
|
||||
const unsigned char *msgs32,
|
||||
size_t n,
|
||||
const unsigned char *aggsig,
|
||||
size_t aggsig_len
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_SCHNORRSIG_HALFAGG_H */
|
||||
269
include/secp256k1_surjectionproof.h
Normal file
269
include/secp256k1_surjectionproof.h
Normal file
@@ -0,0 +1,269 @@
|
||||
#ifndef SECP256K1_SURJECTIONPROOF_H
|
||||
#define SECP256K1_SURJECTIONPROOF_H
|
||||
|
||||
#include "secp256k1.h"
|
||||
#include "secp256k1_rangeproof.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Maximum number of inputs that may be given in a surjection proof */
|
||||
#define SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS 256
|
||||
|
||||
/** Maximum number of inputs that may be used in a surjection proof */
|
||||
#define SECP256K1_SURJECTIONPROOF_MAX_USED_INPUTS 256
|
||||
|
||||
/** Number of bytes a serialized surjection proof requires given the
|
||||
* number of inputs and the number of used inputs.
|
||||
*/
|
||||
#define SECP256K1_SURJECTIONPROOF_SERIALIZATION_BYTES(n_inputs, n_used_inputs) \
|
||||
(2 + (n_inputs + 7)/8 + 32 * (1 + (n_used_inputs)))
|
||||
|
||||
/** Maximum number of bytes a serialized surjection proof requires. */
|
||||
#define SECP256K1_SURJECTIONPROOF_SERIALIZATION_BYTES_MAX \
|
||||
SECP256K1_SURJECTIONPROOF_SERIALIZATION_BYTES(SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS, SECP256K1_SURJECTIONPROOF_MAX_USED_INPUTS)
|
||||
|
||||
/** Opaque data structure that holds a parsed surjection proof
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
* guaranteed to be portable between different platforms or versions. Nor is
|
||||
* it guaranteed to have any particular size, nor that identical proofs
|
||||
* will have identical representation. (That is, memcmp may return nonzero
|
||||
* even for identical proofs.)
|
||||
*
|
||||
* To obtain these properties, instead use secp256k1_surjectionproof_parse
|
||||
* and secp256k1_surjectionproof_serialize to encode/decode proofs into a
|
||||
* well-defined format.
|
||||
*
|
||||
* The representation is exposed to allow creation of these objects on the
|
||||
* stack; please *do not* use these internals directly.
|
||||
*/
|
||||
typedef struct secp256k1_surjectionproof {
|
||||
#ifdef VERIFY
|
||||
/** Mark whether this proof has gone through `secp256k1_surjectionproof_initialize` */
|
||||
int initialized;
|
||||
#endif
|
||||
/** Total number of input asset tags */
|
||||
size_t n_inputs;
|
||||
/** Bitmap of which input tags are used in the surjection proof */
|
||||
unsigned char used_inputs[SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS / 8];
|
||||
/** Borromean signature: e0, scalars */
|
||||
unsigned char data[32 * (1 + SECP256K1_SURJECTIONPROOF_MAX_USED_INPUTS)];
|
||||
} secp256k1_surjectionproof;
|
||||
|
||||
#ifndef USE_REDUCED_SURJECTION_PROOF_SIZE
|
||||
/** Parse a surjection proof
|
||||
*
|
||||
* Returns: 1 when the proof could be parsed, 0 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: proof: pointer to a proof object
|
||||
* In: input: pointer to the array to parse
|
||||
* inputlen: length of the array pointed to by input
|
||||
*
|
||||
* The proof must consist of:
|
||||
* - A 2-byte little-endian total input count `n`
|
||||
* - A ceil(n/8)-byte bitmap indicating which inputs are used.
|
||||
* - A big-endian 32-byte borromean signature e0 value
|
||||
* - `m` big-endian 32-byte borromean signature s values, where `m`
|
||||
* is the number of set bits in the bitmap
|
||||
*/
|
||||
SECP256K1_API int secp256k1_surjectionproof_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_surjectionproof *proof,
|
||||
const unsigned char *input,
|
||||
size_t inputlen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
#endif
|
||||
|
||||
/** Serialize a surjection proof
|
||||
*
|
||||
* Returns: 1 if enough space was available to serialize, 0 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: output: pointer to an array to store the serialization
|
||||
* In/Out: outputlen: pointer to an integer which is initially set to the size
|
||||
* of output, and is overwritten with the written size.
|
||||
* In: proof: pointer to an initialized proof object
|
||||
*
|
||||
* See secp256k1_surjectionproof_parse for details about the encoding.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_surjectionproof_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
size_t *outputlen,
|
||||
const secp256k1_surjectionproof *proof
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Data structure that holds a fixed asset tag.
|
||||
*
|
||||
* This data type is *not* opaque. It will always be 32 bytes of whatever
|
||||
* data the API user wants to use as an asset tag. Its contents have no
|
||||
* semantic meaning to libsecp whatsoever.
|
||||
*/
|
||||
typedef struct secp256k1_fixed_asset_tag {
|
||||
unsigned char data[32];
|
||||
} secp256k1_fixed_asset_tag;
|
||||
|
||||
/** Returns the total number of inputs a proof expects to be over.
|
||||
*
|
||||
* Returns: the number of inputs for the given proof
|
||||
* In: ctx: pointer to a context object
|
||||
* proof: pointer to a proof object
|
||||
*/
|
||||
SECP256K1_API size_t secp256k1_surjectionproof_n_total_inputs(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_surjectionproof *proof
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Returns the actual number of inputs that a proof uses
|
||||
*
|
||||
* Returns: the number of inputs for the given proof
|
||||
* In: ctx: pointer to a context object
|
||||
* proof: pointer to a proof object
|
||||
*/
|
||||
SECP256K1_API size_t secp256k1_surjectionproof_n_used_inputs(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_surjectionproof *proof
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Returns the total size this proof would take, in bytes, when serialized
|
||||
*
|
||||
* Returns: the total size
|
||||
* In: ctx: pointer to a context object
|
||||
* proof: pointer to a proof object
|
||||
*/
|
||||
SECP256K1_API size_t secp256k1_surjectionproof_serialized_size(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_surjectionproof *proof
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Surjection proof initialization function; decides on inputs to use
|
||||
* To be used to initialize stack-allocated secp256k1_surjectionproof struct
|
||||
* Returns 0: inputs could not be selected
|
||||
* n: inputs were selected after n iterations of random selection
|
||||
*
|
||||
* In: ctx: pointer to a context object
|
||||
* fixed_input_tags: fixed input tags `A_i` for all inputs. (If the fixed tag is not known,
|
||||
* e.g. in a coinjoin with others' inputs, an ephemeral tag can be given;
|
||||
* this won't match the output tag but might be used in the anonymity set.)
|
||||
* n_input_tags: the number of entries in the fixed_input_tags array
|
||||
* n_input_tags_to_use: the number of inputs to select randomly to put in the anonymity set
|
||||
* Must be <= SECP256K1_SURJECTIONPROOF_MAX_USED_INPUTS
|
||||
* fixed_output_tag: fixed output tag
|
||||
* max_n_iterations: the maximum number of iterations to do before giving up. Because the
|
||||
* maximum number of inputs (SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS) is
|
||||
* limited to 256 the probability of giving up is smaller than
|
||||
* (255/256)^(n_input_tags_to_use*max_n_iterations).
|
||||
*
|
||||
* random_seed32: random seed to be used for input selection
|
||||
* Out: proof: The proof whose bitvector will be initialized. In case of failure,
|
||||
* the state of the proof is undefined.
|
||||
* input_index: The index of the actual input that is secretly mapped to the output
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_initialize(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_surjectionproof *proof,
|
||||
size_t *input_index,
|
||||
const secp256k1_fixed_asset_tag *fixed_input_tags,
|
||||
const size_t n_input_tags,
|
||||
const size_t n_input_tags_to_use,
|
||||
const secp256k1_fixed_asset_tag *fixed_output_tag,
|
||||
const size_t n_max_iterations,
|
||||
const unsigned char *random_seed32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7);
|
||||
|
||||
|
||||
/** Surjection proof allocation and initialization function; decides on inputs to use
|
||||
* Returns 0: inputs could not be selected, or malloc failure
|
||||
* n: inputs were selected after n iterations of random selection
|
||||
*
|
||||
* In: ctx: pointer to a context object
|
||||
* proof_out_p: pointer to a pointer to `secp256k1_surjectionproof*`.
|
||||
* The newly-allocated struct pointer will be saved here.
|
||||
* fixed_input_tags: fixed input tags `A_i` for all inputs. (If the fixed tag is not known,
|
||||
* e.g. in a coinjoin with others' inputs, an ephemeral tag can be given;
|
||||
* this won't match the output tag but might be used in the anonymity set.)
|
||||
* n_input_tags: the number of entries in the fixed_input_tags array
|
||||
* n_input_tags_to_use: the number of inputs to select randomly to put in the anonymity set
|
||||
* fixed_output_tag: fixed output tag
|
||||
* max_n_iterations: the maximum number of iterations to do before giving up. Because the
|
||||
* maximum number of inputs (SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS) is
|
||||
* limited to 256 the probability of giving up is smaller than
|
||||
* (255/256)^(n_input_tags_to_use*max_n_iterations).
|
||||
*
|
||||
* random_seed32: random seed to be used for input selection
|
||||
* Out: proof_out_p: pointer to newly-allocated proof whose bitvector will be initialized.
|
||||
* In case of failure, the pointer will be NULL.
|
||||
* input_index: The index of the actual input that is secretly mapped to the output
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_allocate_initialized(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_surjectionproof **proof_out_p,
|
||||
size_t *input_index,
|
||||
const secp256k1_fixed_asset_tag *fixed_input_tags,
|
||||
const size_t n_input_tags,
|
||||
const size_t n_input_tags_to_use,
|
||||
const secp256k1_fixed_asset_tag *fixed_output_tag,
|
||||
const size_t n_max_iterations,
|
||||
const unsigned char *random_seed32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7);
|
||||
|
||||
/** Surjection proof destroy function
|
||||
* deallocates the struct that was allocated with secp256k1_surjectionproof_allocate_initialized
|
||||
*
|
||||
* In: proof: pointer to secp256k1_surjectionproof struct
|
||||
*/
|
||||
SECP256K1_API void secp256k1_surjectionproof_destroy(
|
||||
secp256k1_surjectionproof *proof
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** Surjection proof generation function
|
||||
* Returns 0: proof could not be created
|
||||
* 1: proof was successfully created
|
||||
*
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* ephemeral_input_tags: the ephemeral asset tag of all inputs
|
||||
* n_ephemeral_input_tags: the number of entries in the ephemeral_input_tags array
|
||||
* ephemeral_output_tag: the ephemeral asset tag of the output
|
||||
* input_index: the index of the input that actually maps to the output
|
||||
* input_blinding_key: the blinding key of the input
|
||||
* output_blinding_key: the blinding key of the output
|
||||
* In/Out: proof: The produced surjection proof. Must have already gone through `secp256k1_surjectionproof_initialize`
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_generate(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_surjectionproof *proof,
|
||||
const secp256k1_generator *ephemeral_input_tags,
|
||||
size_t n_ephemeral_input_tags,
|
||||
const secp256k1_generator *ephemeral_output_tag,
|
||||
size_t input_index,
|
||||
const unsigned char *input_blinding_key,
|
||||
const unsigned char *output_blinding_key
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8);
|
||||
|
||||
|
||||
#ifndef USE_REDUCED_SURJECTION_PROOF_SIZE
|
||||
/** Surjection proof verification function
|
||||
* Returns 0: proof was invalid
|
||||
* 1: proof was valid
|
||||
*
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* proof: proof to be verified
|
||||
* ephemeral_input_tags: the ephemeral asset tag of all inputs
|
||||
* n_ephemeral_input_tags: the number of entries in the ephemeral_input_tags array
|
||||
* ephemeral_output_tag: the ephemeral asset tag of the output
|
||||
*/
|
||||
SECP256K1_API int secp256k1_surjectionproof_verify(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_surjectionproof *proof,
|
||||
const secp256k1_generator *ephemeral_input_tags,
|
||||
size_t n_ephemeral_input_tags,
|
||||
const secp256k1_generator *ephemeral_output_tag
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
148
include/secp256k1_whitelist.h
Normal file
148
include/secp256k1_whitelist.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/**********************************************************************
|
||||
* Copyright (c) 2016 Andrew Poelstra *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef SECP256K1_WHITELIST_H
|
||||
#define SECP256K1_WHITELIST_H
|
||||
|
||||
#include "secp256k1.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SECP256K1_WHITELIST_MAX_N_KEYS 255
|
||||
|
||||
/** Opaque data structure that holds a parsed whitelist proof
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
* guaranteed to be portable between different platforms or versions. Nor is
|
||||
* it guaranteed to have any particular size, nor that identical signatures
|
||||
* will have identical representation. (That is, memcmp may return nonzero
|
||||
* even for identical signatures.)
|
||||
*
|
||||
* To obtain these properties, instead use secp256k1_whitelist_signature_parse
|
||||
* and secp256k1_whitelist_signature_serialize to encode/decode signatures
|
||||
* into a well-defined format.
|
||||
*
|
||||
* The representation is exposed to allow creation of these objects on the
|
||||
* stack; please *do not* use these internals directly. To learn the number
|
||||
* of keys for a signature, use `secp256k1_whitelist_signature_n_keys`.
|
||||
*/
|
||||
typedef struct secp256k1_whitelist_signature {
|
||||
size_t n_keys;
|
||||
/* e0, scalars */
|
||||
unsigned char data[32 * (1 + SECP256K1_WHITELIST_MAX_N_KEYS)];
|
||||
} secp256k1_whitelist_signature;
|
||||
|
||||
/** Parse a whitelist signature
|
||||
*
|
||||
* Returns: 1 when the signature could be parsed, 0 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: sig: pointer to a signature object
|
||||
* In: input: pointer to the array to parse
|
||||
* input_len: the length of the above array
|
||||
*
|
||||
* The signature must consist of a 1-byte n_keys value, followed by a 32-byte
|
||||
* big endian e0 value, followed by n_keys many 32-byte big endian s values.
|
||||
* If n_keys falls outside of [0..SECP256K1_WHITELIST_MAX_N_KEYS] the encoding
|
||||
* is invalid.
|
||||
*
|
||||
* The total length of the input array must therefore be 33 + 32 * n_keys.
|
||||
* If the length `input_len` does not match this value, parsing will fail.
|
||||
*
|
||||
* After the call, sig will always be initialized. If parsing failed or any
|
||||
* scalar values overflow or are zero, the resulting sig value is guaranteed
|
||||
* to fail validation for any set of keys.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_whitelist_signature_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_whitelist_signature *sig,
|
||||
const unsigned char *input,
|
||||
size_t input_len
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Returns the number of keys a signature expects to have.
|
||||
*
|
||||
* Returns: the number of keys for the given signature
|
||||
* In: sig: pointer to a signature object
|
||||
*/
|
||||
SECP256K1_API size_t secp256k1_whitelist_signature_n_keys(
|
||||
const secp256k1_whitelist_signature *sig
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** Serialize a whitelist signature
|
||||
*
|
||||
* Returns: 1
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: output64: pointer to an array to store the serialization
|
||||
* In/Out: output_len: length of the above array, updated with the actual serialized length
|
||||
* In: sig: pointer to an initialized signature object
|
||||
*
|
||||
* See secp256k1_whitelist_signature_parse for details about the encoding.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_whitelist_signature_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
size_t *output_len,
|
||||
const secp256k1_whitelist_signature *sig
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Compute a whitelist signature
|
||||
* Returns 1: signature was successfully created
|
||||
* 0: signature was not successfully created
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* online_pubkeys: list of all online pubkeys
|
||||
* offline_pubkeys: list of all offline pubkeys
|
||||
* n_keys: the number of entries in each of the above two arrays
|
||||
* sub_pubkey: the key to be whitelisted
|
||||
* online_seckey: the secret key to the signer's online pubkey
|
||||
* summed_seckey: the secret key to the sum of (whitelisted key, signer's offline pubkey)
|
||||
* index: the signer's index in the lists of keys
|
||||
* Out: sig: The produced signature.
|
||||
*
|
||||
* The signatures are of the list of all passed pubkeys in the order
|
||||
* ( whitelist, online_1, offline_1, online_2, offline_2, ... )
|
||||
* The verification key list consists of
|
||||
* online_i + H(offline_i + whitelist)(offline_i + whitelist)
|
||||
* for each public key pair (offline_i, offline_i). Here H means sha256 of the
|
||||
* compressed serialization of the key.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_whitelist_sign(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_whitelist_signature *sig,
|
||||
const secp256k1_pubkey *online_pubkeys,
|
||||
const secp256k1_pubkey *offline_pubkeys,
|
||||
const size_t n_keys,
|
||||
const secp256k1_pubkey *sub_pubkey,
|
||||
const unsigned char *online_seckey,
|
||||
const unsigned char *summed_seckeyx,
|
||||
const size_t index
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8);
|
||||
|
||||
/** Verify a whitelist signature
|
||||
* Returns 1: signature is valid
|
||||
* 0: signature is not valid
|
||||
* In: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* sig: the signature to be verified
|
||||
* online_pubkeys: list of all online pubkeys
|
||||
* offline_pubkeys: list of all offline pubkeys
|
||||
* n_keys: the number of entries in each of the above two arrays
|
||||
* sub_pubkey: the key to be whitelisted
|
||||
*/
|
||||
SECP256K1_API int secp256k1_whitelist_verify(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_whitelist_signature *sig,
|
||||
const secp256k1_pubkey *online_pubkeys,
|
||||
const secp256k1_pubkey *offline_pubkeys,
|
||||
const size_t n_keys,
|
||||
const secp256k1_pubkey *sub_pubkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user