view release on metacpan or search on metacpan
libsecp256k1/CHANGELOG.md view on Meta::CPAN
- The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake).
- This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB).
#### ABI Compatibility
The ABI is backward compatible with versions 0.4.x and 0.3.x.
## [0.4.1] - 2023-12-21
#### Changed
- The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one.
- Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is...
#### ABI Compatibility
The ABI is backward compatible with versions 0.4.0 and 0.3.x.
## [0.4.0] - 2023-09-04
#### Added
- New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them.
ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See:
- Header file `include/secp256k1_ellswift.h` which defines the new API.
libsecp256k1/CHANGELOG.md view on Meta::CPAN
- Increased minimum required CMake version to 3.13. CMake builds remain experimental.
#### ABI Compatibility
The ABI is compatible with version 0.3.0.
## [0.3.0] - 2023-03-08
#### Added
- Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported.
- Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory.
- Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as par...
#### Fixed
- Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now wil...
#### Changed
- Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.)
- Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to ...
#### Removed
- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported b...
libsecp256k1/CMakeLists.txt view on Meta::CPAN
message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
message(" ecmult gen table size ............... ${SECP256K1_ECMULT_GEN_KB} KiB")
message("Optional features:")
message(" assembly ............................ ${SECP256K1_ASM}")
message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}")
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}")
endif()
message("Optional binaries:")
message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}")
message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}")
set(tests_status "${SECP256K1_BUILD_TESTS}")
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
set(tests_status OFF)
endif()
message(" tests ............................... ${tests_status}")
message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}")
message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}")
message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}")
message("")
if(CMAKE_CROSSCOMPILING)
libsecp256k1/Makefile.am view on Meta::CPAN
bench_internal_SOURCES = src/bench_internal.c
bench_internal_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
bench_internal_CPPFLAGS = $(SECP_CONFIG_DEFINES)
bench_ecmult_SOURCES = src/bench_ecmult.c
bench_ecmult_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
bench_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES)
endif
TESTS =
if USE_TESTS
TESTS += noverify_tests
noinst_PROGRAMS += noverify_tests
noverify_tests_SOURCES = src/tests.c
noverify_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
noverify_tests_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
noverify_tests_LDFLAGS = -static
if !ENABLE_COVERAGE
TESTS += tests
noinst_PROGRAMS += tests
tests_SOURCES = $(noverify_tests_SOURCES)
tests_CPPFLAGS = $(noverify_tests_CPPFLAGS) -DVERIFY
tests_LDADD = $(noverify_tests_LDADD)
tests_LDFLAGS = $(noverify_tests_LDFLAGS)
endif
endif
if USE_CTIME_TESTS
noinst_PROGRAMS += ctime_tests
ctime_tests_SOURCES = src/ctime_tests.c
ctime_tests_LDADD = libsecp256k1.la
ctime_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
endif
libsecp256k1/contrib/lax_der_privatekey_parsing.c view on Meta::CPAN
/* sequence element 0: version number (=1) */
if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) {
return 0;
}
privkey += 3;
/* sequence element 1: octet string, up to 32 bytes */
if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) {
return 0;
}
if (privkey[1]) memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]);
if (!secp256k1_ec_seckey_verify(ctx, out32)) {
memset(out32, 0, 32);
return 0;
}
return 1;
}
int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
secp256k1_pubkey pubkey;
size_t pubkeylen = 0;
if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) {
libsecp256k1/doc/ellswift.md view on Meta::CPAN
We wish to avoid the need for callers to deal with this special case.
This is implemented in `secp256k1_ellswift_xswiftec_frac_var` (which decodes to an x-coordinate represented as a fraction), and
in `secp256k1_ellswift_xswiftec_var` (which outputs the actual x-coordinate).
## 3. The encoding function
To implement $F_u^{-1}(x)$, the function to find the set of inverses $t$ for which $F_u(t) = x$, we have to reverse the process:
* Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$
* Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$
* For each of the found $t$ values, verify that $F_u(t) = x.$
* Return the remaining $t$ values.
The function $P_u^{-1}$, which finds $t$ given $(X, Y) \in S_u$, is significantly simpler than $P_u:$
$$
P_u^{-1}(X, Y) = \left\\{\begin{array}{ll}
Yu\sqrt{-3} - X & a = 0 \\
\dfrac{Y-Y_0(u)}{X-X_0(u)} & a \neq 0 \land X \neq X_0(u) \\
\dfrac{-X_0(u)}{h(u)Y_0(u)} & a \neq 0 \land X = X_0(u) \land Y = Y_0(u)
\end{array}\right.
$$
The third step above, verifying that $F_u(t) = x$, is necessary because for the $(X, Y)$ values found through the $x_1$ and $x_2$ expressions,
it is possible that decoding through $\psi_u(X, Y)$ yields a valid $x_3$ on the curve, which would take precedence over the
$x_1$ or $x_2$ decoding. These $(X, Y)$ solutions must be rejected.
Since we know that exactly one or exactly three out of $\\{x_1, x_2, x_3\\}$ are valid x-coordinates for any $t$,
the case where either $x_1$ or $x_2$ is valid and in addition also $x_3$ is valid must mean that all three are valid.
This means that instead of checking whether $x_3$ is on the curve, it is also possible to check whether the other one out of
$x_1$ and $x_2$ is on the curve. This is significantly simpler, as it turns out.
Observe that $\psi_u$ guarantees that $x_1 + x_2 = -u.$ So given either $x = x_1$ or $x = x_2$, the other one of the two can be computed as
$-u - x.$ Thus, when encoding $x$ through the $x_1$ or $x_2$ expressions, one can simply check whether $g(-u-x)$ is a square,
libsecp256k1/doc/musig.md view on Meta::CPAN
This is covered by `examples/musig.c`.
Essentially, the protocol proceeds in the following steps:
1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key with `secp256k1_keypair_pub`.
2. Call `secp256k1_musig_pubkey_agg` with the pubkeys of all participants.
3. Optionally add a (Taproot) tweak with `secp256k1_musig_pubkey_xonly_tweak_add` and a plain tweak with `secp256k1_musig_pubkey_ec_tweak_add`.
4. Generate a pair of secret and public nonce with `secp256k1_musig_nonce_gen` and send the public nonce to the other signers.
5. Someone (not necessarily the signer) aggregates the public nonces with `secp256k1_musig_nonce_agg` and sends it to the signers.
6. Process the aggregate nonce with `secp256k1_musig_nonce_process`.
7. Create a partial signature with `secp256k1_musig_partial_sign`.
8. Verify the partial signatures (optional in some scenarios) with `secp256k1_musig_partial_sig_verify`.
9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using `secp256k1_musig_partial_sig_agg`.
The aggregate signature can be verified with `secp256k1_schnorrsig_verify`.
Steps 1 through 5 above can occur before or after the signers are aware of the message to be signed.
Whenever possible, it is recommended to generate the nonces only after the message is known.
This provides enhanced defense-in-depth measures, protecting against potential API misuse in certain scenarios.
However, it does require two rounds of communication during the signing process.
The alternative, generating the nonces in a pre-processing step before the message is known, eliminates these additional protective measures but allows for non-interactive signing.
Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5).
## Verification
A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7.
libsecp256k1/doc/release-process.md view on Meta::CPAN
./autogen.sh && ./configure --prefix=$dir && make clean && make install && ls -RlAh $dir
gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=$dir/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"$dir/lib" && ./ecdsa
```
3. Check installation with CMake:
```shell
dir=$(mktemp -d)
build=$(mktemp -d)
cmake -B $build -DCMAKE_INSTALL_PREFIX=$dir && cmake --build $build && cmake --install $build && ls -RlAh $dir
gcc -o ecdsa examples/ecdsa.c -I $dir/include -L $dir/lib*/ -l secp256k1 -Wl,-rpath,"$dir/lib",-rpath,"$dir/lib64" && ./ecdsa
```
4. Use the [`check-abi.sh`](/tools/check-abi.sh) tool to verify that there are no unexpected ABI incompatibilities and that the version number and the release notes accurately reflect all potential ABI changes. To run this tool, the `abi-dumper` and ...
```shell
tools/check-abi.sh
```
## Regular release
1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that
* finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) by
* adding a section for the release (make sure that the version number is a link to a diff between the previous and new version),
* removing the `[Unreleased]` section header,
libsecp256k1/examples/ecdh.c view on Meta::CPAN
assert(return_val);
/*** Key Generation ***/
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
printf("Failed to generate randomness\n");
return 1;
}
/* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Public key creation using a valid context with a verified secret key should never fail */
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey1, seckey1);
assert(return_val);
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey2, seckey2);
assert(return_val);
libsecp256k1/examples/ecdsa.c view on Meta::CPAN
assert(return_val);
/*** Key Generation ***/
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 1;
}
/* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Public key creation using a valid context with a verified secret key should never fail */
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey, seckey);
assert(return_val);
/* Serialize the pubkey in a compressed form(33 bytes). Should always return 1. */
len = sizeof(compressed_pubkey);
libsecp256k1/examples/ecdsa.c view on Meta::CPAN
return 1;
}
/* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) {
printf("Failed parsing the public key\n");
return 1;
}
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
is_signature_valid = secp256k1_ecdsa_verify(ctx, &sig, msg_hash, &pubkey);
printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
printf("Secret Key: ");
print_hex(seckey, sizeof(seckey));
printf("Public Key: ");
print_hex(compressed_pubkey, sizeof(compressed_pubkey));
printf("Signature: ");
print_hex(serialized_signature, sizeof(serialized_signature));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* Bonus example: if all we need is signature verification (and no key
generation or signing), we don't need to use a context created via
secp256k1_context_create(). We can simply use the static (i.e., global)
context secp256k1_context_static. See its description in
include/secp256k1.h for details. */
is_signature_valid2 = secp256k1_ecdsa_verify(secp256k1_context_static,
&sig, msg_hash, &pubkey);
assert(is_signature_valid2 == is_signature_valid);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
libsecp256k1/examples/ellswift.c view on Meta::CPAN
assert(return_val);
/*** Generate secret keys ***/
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
printf("Failed to generate randomness\n");
return 1;
}
/* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Generate ElligatorSwift public keys. This should never fail with valid context and
verified secret keys. Note that providing additional randomness (fourth parameter) is
optional, but recommended. */
if (!fill_random(auxrand1, sizeof(auxrand1)) || !fill_random(auxrand2, sizeof(auxrand2))) {
printf("Failed to generate randomness\n");
return 1;
libsecp256k1/examples/musig.c view on Meta::CPAN
/* Xonly tweaking which, for example, allows creating Taproot commitments */
if (!secp256k1_musig_pubkey_xonly_tweak_add(ctx, &output_pk, cache, xonly_tweak)) {
return 0;
}
/* Note that if we wouldn't care about signing, we can arrive at the same
* output_pk by providing the untweaked public key to
* `secp256k1_xonly_pubkey_tweak_add` (after converting it to an xonly pubkey
* if necessary with `secp256k1_xonly_pubkey_from_pubkey`). */
/* Now we convert the output_pk to an xonly pubkey to allow to later verify
* the Schnorr signature against it. For this purpose we can ignore the
* `pk_parity` output argument; we would need it if we would have to open
* the Taproot commitment. */
if (!secp256k1_xonly_pubkey_from_pubkey(ctx, agg_pk, NULL, &output_pk)) {
return 0;
}
return 1;
}
/* Sign a message hash with the given key pairs and store the result in sig */
libsecp256k1/examples/musig.c view on Meta::CPAN
* create a secnonce). If you do, you effectively reuse the nonce and
* leak the secret key. */
if (!secp256k1_musig_partial_sign(ctx, &signer[i].partial_sig, &signer_secrets[i].secnonce, &signer_secrets[i].keypair, cache, &session)) {
return 0;
}
partial_sigs[i] = &signer[i].partial_sig;
}
/* Communication round 2: Every signer sends their partial signature to the
* coordinator, who verifies the partial signatures and aggregates them. */
for (i = 0; i < N_SIGNERS; i++) {
/* To check whether signing was successful, it suffices to either verify
* the aggregate signature with the aggregate public key using
* secp256k1_schnorrsig_verify, or verify all partial signatures of all
* signers individually. Verifying the aggregate signature is cheaper but
* verifying the individual partial signatures has the advantage that it
* can be used to determine which of the partial signatures are invalid
* (if any), i.e., which of the partial signatures cause the aggregate
* signature to be invalid and thus the protocol run to fail. It's also
* fine to first verify the aggregate sig, and only verify the individual
* sigs if it does not work.
*/
if (!secp256k1_musig_partial_sig_verify(ctx, &signer[i].partial_sig, &signer[i].pubnonce, &signer[i].pubkey, cache, &session)) {
return 0;
}
}
return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS);
}
int main(void) {
secp256k1_context* ctx;
int i;
struct signer_secrets signer_secrets[N_SIGNERS];
libsecp256k1/examples/musig.c view on Meta::CPAN
printf("ok\n");
printf("Signing message.........");
fflush(stdout);
if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Verifying signature.....");
fflush(stdout);
if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite secret key material with zeros.
*
libsecp256k1/examples/schnorr.c view on Meta::CPAN
* that the probability of this occurring is negligible with a properly
* functioning random number generator. */
if (!secp256k1_keypair_create(ctx, &keypair, seckey)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Extract the X-only public key from the keypair. We pass NULL for
* `pk_parity` as the parity isn't needed for signing or verification.
* `secp256k1_keypair_xonly_pub` supports returning the parity for
* other use cases such as tests or verifying Taproot tweaks.
* This should never fail with a valid context and public key. */
return_val = secp256k1_keypair_xonly_pub(ctx, &pubkey, NULL, &keypair);
assert(return_val);
/* Serialize the public key. Should always return 1 for a valid public key. */
return_val = secp256k1_xonly_pubkey_serialize(ctx, serialized_pubkey, &pubkey);
assert(return_val);
/*** Signing ***/
libsecp256k1/examples/schnorr.c view on Meta::CPAN
if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) {
printf("Failed parsing the public key\n");
return 1;
}
/* Compute the tagged hash on the received messages using the same tag as the signer. */
return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg));
assert(return_val);
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
is_signature_valid = secp256k1_schnorrsig_verify(ctx, signature, msg_hash, 32, &pubkey);
printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
printf("Secret Key: ");
print_hex(seckey, sizeof(seckey));
printf("Public Key: ");
print_hex(serialized_pubkey, sizeof(serialized_pubkey));
printf("Signature: ");
print_hex(signature, sizeof(signature));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* Bonus example: if all we need is signature verification (and no key
generation or signing), we don't need to use a context created via
secp256k1_context_create(). We can simply use the static (i.e., global)
context secp256k1_context_static. See its description in
include/secp256k1.h for details. */
is_signature_valid2 = secp256k1_schnorrsig_verify(secp256k1_context_static,
signature, msg_hash, 32, &pubkey);
assert(is_signature_valid2 == is_signature_valid);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
libsecp256k1/include/secp256k1.h view on Meta::CPAN
* Args: ctx: pointer to a context object
* In: sig: the signature being verified.
* msghash32: the 32-byte message hash being verified.
* The verifier must make sure to apply a cryptographic
* hash function to the message by itself and not accept an
* msghash32 value directly. Otherwise, it would be easy to
* create a "valid" signature without knowledge of the
* secret key. See also
* https://bitcoin.stackexchange.com/a/81116/35586 for more
* background on this topic.
* pubkey: pointer to an initialized public key to verify with.
*
* To avoid accepting malleable signatures, only ECDSA signatures in lower-S
* form are accepted.
*
* If you need to accept ECDSA signatures from sources that do not obey this
* rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to
* verification, but be aware that doing so results in malleable signatures.
*
* For details, see the comments for that function.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
const secp256k1_context *ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msghash32,
const secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Convert a signature to a normalized lower-S form.
*
* Returns: 1 if sigin was not normalized, 0 if it already was.
* Args: ctx: pointer to a context object
libsecp256k1/include/secp256k1.h view on Meta::CPAN
* message, given a single initial signature, but without knowing the key. This
* is done by negating the S value modulo the order of the curve, 'flipping'
* the sign of the random point R which is not included in the signature.
*
* Forgery of the same message isn't universally problematic, but in systems
* where message malleability or uniqueness of signatures is important this can
* cause issues. This forgery can be blocked by all verifiers forcing signers
* to use a normalized form.
*
* The lower-S form reduces the size of signatures slightly on average when
* variable length encodings (such as DER) are used and is cheap to verify,
* making it a good choice. Security of always using lower-S is assured because
* anyone can trivially modify a signature after the fact to enforce this
* property anyway.
*
* The lower S value is always between 0x1 and
* 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
* inclusive.
*
* No other forms of ECDSA malleability are known and none seem likely, but
* there is no formal proof that ECDSA, even with this additional restriction,
* is free of other malleability. Commonly used serialization schemes will also
* accept various non-unique encodings, so care should be taken when this
* property is required for an application.
*
* The secp256k1_ecdsa_sign function will by default create signatures in the
* lower-S form, and secp256k1_ecdsa_verify will not accept others. In case
* signatures come from a system that cannot enforce this property,
* secp256k1_ecdsa_signature_normalize must be called before verification.
*/
SECP256K1_API int secp256k1_ecdsa_signature_normalize(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sigout,
const secp256k1_ecdsa_signature *sigin
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function.
libsecp256k1/include/secp256k1.h view on Meta::CPAN
* probability of choosing a 32-byte string uniformly at random which is an
* invalid secret key is negligible. However, if it does happen it should
* be assumed that the randomness source is severely broken and there should
* be no retry.
*
* Returns: 1: secret key is valid
* 0: secret key is invalid
* Args: ctx: pointer to a context object.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
const secp256k1_context *ctx,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Compute the public key for a secret key.
*
* Returns: 1: secret was valid, public key stores.
* 0: secret was invalid, try again.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: pubkey: pointer to the created public key.
libsecp256k1/include/secp256k1.h view on Meta::CPAN
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Negates a secret key in place.
*
* Returns: 0 if the given secret key is invalid according to
* secp256k1_ec_seckey_verify. 1 otherwise
* Args: ctx: pointer to a context object
* In/Out: seckey: pointer to the 32-byte secret key to be negated. If the
* secret key is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0 and
* seckey will be set to some unspecified value.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
libsecp256k1/include/secp256k1.h view on Meta::CPAN
secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Tweak a secret key by adding tweak to it.
*
* Returns: 0 if the arguments are invalid or the resulting secret key would be
* invalid (only when the tweak is the negation of the secret key). 1
* otherwise.
* Args: ctx: pointer to a context object.
* In/Out: seckey: pointer to a 32-byte secret key. If the secret key is
* invalid according to secp256k1_ec_seckey_verify, this
* function returns 0. seckey will be set to some unspecified
* value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in
libsecp256k1/include/secp256k1.h view on Meta::CPAN
/** Tweak a public key by adding tweak times the generator to it.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object.
* In/Out: pubkey: pointer to a public key object. pubkey will be set to an
* invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Tweak a secret key by multiplying it by a tweak.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object.
* In/Out: seckey: pointer to a 32-byte secret key. If the secret key is
* invalid according to secp256k1_ec_seckey_verify, this
* function returns 0. seckey will be set to some unspecified
* value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in
libsecp256k1/include/secp256k1.h view on Meta::CPAN
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_mul instead");
/** Tweak a public key by multiplying it by a tweak value.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object.
* In/Out: pubkey: pointer to a public key object. pubkey will be set to an
* invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Randomizes the context to provide enhanced protection against side-channel leakage.
libsecp256k1/include/secp256k1_extrakeys.h view on Meta::CPAN
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
*
* Args: ctx: pointer to a context object.
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0.
* In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to.
* tweak32: pointer to a 32-byte tweak, which must be valid
* according to secp256k1_ec_seckey_verify or 32 zero
* bytes. For uniformly random 32-byte tweaks, the chance of
* being invalid is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
const secp256k1_xonly_pubkey *internal_pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Checks that a tweaked pubkey is the result of calling
* secp256k1_xonly_pubkey_tweak_add with internal_pubkey and tweak32.
*
* The tweaked pubkey is represented by its 32-byte x-only serialization and
* its pk_parity, which can both be obtained by converting the result of
* tweak_add to a secp256k1_xonly_pubkey.
*
* Note that this alone does _not_ verify that the tweaked pubkey is a
* commitment. If the tweak is not chosen in a specific way, the tweaked pubkey
* can easily be the result of a different internal_pubkey and tweak.
*
* Returns: 0 if the arguments are invalid or the tweaked pubkey is not the
* result of tweaking the internal_pubkey with tweak32. 1 otherwise.
* Args: ctx: pointer to a context object.
* In: tweaked_pubkey32: pointer to a serialized xonly_pubkey.
* tweaked_pk_parity: the parity of the tweaked pubkey (whose serialization
* is passed in as tweaked_pubkey32). This must match the
* pk_parity value that is returned when calling
libsecp256k1/include/secp256k1_extrakeys.h view on Meta::CPAN
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(
const secp256k1_context *ctx,
const unsigned char *tweaked_pubkey32,
int tweaked_pk_parity,
const secp256k1_xonly_pubkey *internal_pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Compute the keypair for a valid secret key.
*
* See the documentation of `secp256k1_ec_seckey_verify` for more information
* about the validity of secret keys.
*
* Returns: 1: secret key is valid
* 0: secret key is invalid
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: keypair: pointer to the created keypair.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
const secp256k1_context *ctx,
libsecp256k1/include/secp256k1_extrakeys.h view on Meta::CPAN
* secp256k1_xonly_pubkey_tweak_add.
*
* Returns: 0 if the arguments are invalid or the resulting keypair would be
* invalid (only when the tweak is the negation of the keypair's
* secret key). 1 otherwise.
*
* Args: ctx: pointer to a context object.
* In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to
* an invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
const secp256k1_context *ctx,
secp256k1_keypair *keypair,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
#ifdef __cplusplus
libsecp256k1/include/secp256k1_musig.h view on Meta::CPAN
* which ensures the same `agg_pk` result for the same multiset of pubkeys.
* This is useful to do before `pubkey_agg`, such that the order of pubkeys
* does not affect the aggregate public key.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: agg_pk: the MuSig-aggregated x-only public key. If you do not need it,
* this arg can be NULL.
* keyagg_cache: if non-NULL, pointer to a musig_keyagg_cache struct that
* is required for signing (or observing the signing session
* and verifying partial signatures).
* In: pubkeys: input array of pointers to public keys to aggregate. The order
* is important; a different order will result in a different
* aggregate public key.
* n_pubkeys: length of pubkeys array. Must be greater than 0.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_agg(
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *agg_pk,
secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_pubkey * const *pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(4);
/** Obtain the aggregate public key from a keyagg_cache.
*
* This is only useful if you need the non-xonly public key, in particular for
* plain (non-xonly) tweaking or batch-verifying multiple key aggregations
* (not implemented).
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: agg_pk: the MuSig-aggregated public key.
* In: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_get(
const secp256k1_context *ctx,
libsecp256k1/include/secp256k1_musig.h view on Meta::CPAN
* signature for it, use `secp256k1_ec_pubkey_tweak_add` instead.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
* In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes
* `secp256k1_ec_seckey_verify` and is not equal to the
* secret key corresponding to the public key represented
* by keyagg_cache or its negation. For uniformly random
* 32-byte arrays the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_ec_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *tweak32
libsecp256k1/include/secp256k1_musig.h view on Meta::CPAN
* signature for it, use `secp256k1_xonly_pubkey_tweak_add` instead.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
* In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes
* `secp256k1_ec_seckey_verify` and is not equal to the
* secret key corresponding to the public key represented
* by keyagg_cache or its negation. For uniformly random
* 32-byte arrays the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_xonly_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *tweak32
libsecp256k1/include/secp256k1_musig.h view on Meta::CPAN
* secnonce that is all zeros. This is a best effort attempt to protect against nonce
* reuse. However, this is of course easily defeated if the secnonce has been
* copied (or serialized). Remember that nonce reuse will leak the secret key!
*
* For signing to succeed, the secnonce provided to this function must have
* been generated for the provided keypair. This means that when signing for a
* keypair consisting of a seckey and pubkey, the secnonce must have been
* created by calling musig_nonce_gen with that pubkey. Otherwise, the
* illegal_callback is called.
*
* This function does not verify the output partial signature, deviating from
* the BIP 327 specification. It is recommended to verify the output partial
* signature with `secp256k1_musig_partial_sig_verify` to prevent random or
* adversarially provoked computation errors.
*
* Returns: 0 if the arguments are invalid or the provided secnonce has already
* been used for signing, 1 otherwise
* Args: ctx: pointer to a context object
* Out: partial_sig: pointer to struct to store the partial signature
* In/Out: secnonce: pointer to the secnonce struct created in
* musig_nonce_gen that has been never used in a
* partial_sign call before and has been created for the
* keypair
libsecp256k1/include/secp256k1_musig.h view on Meta::CPAN
secp256k1_musig_partial_sig *partial_sig,
secp256k1_musig_secnonce *secnonce,
const secp256k1_keypair *keypair,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Verifies an individual signer's partial signature
*
* The signature is verified for a specific signing session. In order to avoid
* accidentally verifying a signature from a different or non-existing signing
* session, you must ensure the following:
* 1. The `keyagg_cache` argument is identical to the one used to create the
* `session` with `musig_nonce_process`.
* 2. The `pubkey` argument must be identical to the one sent by the signer
* before aggregating it with `musig_pubkey_agg` to create the
* `keyagg_cache`.
* 3. The `pubnonce` argument must be identical to the one sent by the signer
* 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
* 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
* verification.
*
* Returns: 0 if the arguments are invalid or the partial signature does not
* verify, 1 otherwise
* Args ctx: pointer to a context object
* In: partial_sig: pointer to partial signature to verify, sent by
* the signer associated with `pubnonce` and `pubkey`
* pubnonce: public nonce of the signer in the signing session
* pubkey: public key of the signer in the signing session
* keyagg_cache: pointer to the keyagg_cache that was output when the
* aggregate public key for this signing session
* session: pointer to the session that was created with
* `musig_nonce_process`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
const secp256k1_context *ctx,
const secp256k1_musig_partial_sig *partial_sig,
const secp256k1_musig_pubnonce *pubnonce,
const secp256k1_pubkey *pubkey,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Aggregates partial signatures
*
libsecp256k1/include/secp256k1_schnorrsig.h view on Meta::CPAN
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\
NULL,\
NULL\
}
/** Create a Schnorr signature.
*
* Does _not_ strictly follow BIP-340 because it does not verify the resulting
* signature. Instead, you can manually use secp256k1_schnorrsig_verify and
* abort if it fails.
*
* This function only signs 32-byte messages. If you have messages of a
* different size (or the same size but without a context-specific tag
* prefix), it is recommended to create a 32-byte message hash with
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows
* providing an context-specific tag for domain separation. This prevents
* signatures from being valid in multiple contexts by accident.
*
* Returns 1 on success, 0 on failure.
libsecp256k1/include/secp256k1_schnorrsig.h view on Meta::CPAN
size_t msglen,
const secp256k1_keypair *keypair,
secp256k1_schnorrsig_extraparams *extraparams
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
/** Verify a Schnorr signature.
*
* Returns: 1: correct signature
* 0: incorrect signature
* Args: ctx: pointer to a context object.
* In: sig64: pointer to the 64-byte signature to verify.
* msg: the message being verified. Can only be NULL if msglen is 0.
* msglen: length of the message
* pubkey: pointer to an x-only public key to verify with
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
const secp256k1_context *ctx,
const unsigned char *sig64,
const unsigned char *msg,
size_t msglen,
const secp256k1_xonly_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
#ifdef __cplusplus
}
#endif
libsecp256k1/sage/group_prover.sage view on Meta::CPAN
# This code supports verifying group implementations which have branches
# or conditional statements (like cmovs), by allowing each execution path
# to independently set assumptions on input or intermediary variables.
#
# The general approach is:
# * A constraint is a tuple of two sets of symbolic expressions:
# the first of which are required to evaluate to zero, the second of which
# are required to evaluate to nonzero.
# - A constraint is said to be conflicting if any of its nonzero expressions
# is in the ideal with basis the zero expressions (in other words: when the
# zero expressions imply that one of the nonzero expressions are zero).
libsecp256k1/sage/group_prover.sage view on Meta::CPAN
if not ok:
return (False, "FAIL, %s fails%s" % (str(msg), describe))
res, expl = prove_nonzero(R, require.nonzero, assume)
if not res:
return (False, "FAIL, %s fails%s" % (str(expl), describe))
return (True, "OK%s" % describe)
def concrete_verify(c):
for k in c.zero:
if k != 0:
return (False, c.zero[k])
for k in c.nonzero:
if k == 0:
return (False, c.nonzero[k])
return (True, None)
libsecp256k1/sage/weierstrass_prover.sage view on Meta::CPAN
def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p):
"""Verify an implementation of addition of Jacobian points on a Weierstrass curve, by executing and validating the result for every possible addition in a prime field"""
F = Integers(p)
print("Formula %s on Z%i:" % (name, p))
points = []
for x in range(0, p):
for y in range(0, p):
point = affinepoint(F(x), F(y))
r, e = concrete_verify(on_weierstrass_curve(A, B, point))
if r:
points.append(point)
ret = True
for za in range(1, p):
for zb in range(1, p):
for pa in points:
for pb in points:
for ia in range(2):
for ib in range(2):
pA = jacobianpoint(pa.x * F(za)^2, pa.y * F(za)^3, F(za), ia)
pB = jacobianpoint(pb.x * F(zb)^2, pb.y * F(zb)^3, F(zb), ib)
for branch in range(0, branches):
assumeAssert, assumeBranch, pC = formula(branch, pA, pB)
pC.X = F(pC.X)
pC.Y = F(pC.Y)
pC.Z = F(pC.Z)
pC.Infinity = F(pC.Infinity)
r, e = concrete_verify(assumeAssert + assumeBranch)
if r:
match = False
for key in laws_jacobian_weierstrass:
assumeLaw, require = laws_jacobian_weierstrass[key](A, B, pa, pb, pA, pB, pC)
r, e = concrete_verify(assumeLaw)
if r:
if match:
print(" multiple branches for (%s,%s,%s,%s) + (%s,%s,%s,%s)" % (pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity))
else:
match = True
r, e = concrete_verify(require)
if not r:
ret = False
print(" failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e))
print()
return ret
def check_symbolic_function(R, assumeAssert, assumeBranch, f, A, B, pa, pb, pA, pB, pC):
assumeLaw, require = f(A, B, pa, pb, pA, pB, pC)
libsecp256k1/src/CMakeLists.txt view on Meta::CPAN
if(SECP256K1_BUILD_BENCHMARK)
add_executable(bench bench.c)
target_link_libraries(bench secp256k1)
add_executable(bench_internal bench_internal.c)
target_link_libraries(bench_internal secp256k1_precomputed secp256k1_asm)
add_executable(bench_ecmult bench_ecmult.c)
target_link_libraries(bench_ecmult secp256k1_precomputed secp256k1_asm)
endif()
if(SECP256K1_BUILD_TESTS)
add_executable(noverify_tests tests.c)
target_link_libraries(noverify_tests secp256k1_precomputed secp256k1_asm)
add_test(NAME secp256k1_noverify_tests COMMAND noverify_tests)
if(NOT CMAKE_BUILD_TYPE STREQUAL "Coverage")
add_executable(tests tests.c)
target_compile_definitions(tests PRIVATE VERIFY)
target_link_libraries(tests secp256k1_precomputed secp256k1_asm)
add_test(NAME secp256k1_tests COMMAND tests)
endif()
endif()
if(SECP256K1_BUILD_EXHAUSTIVE_TESTS)
# Note: do not include secp256k1_precomputed in exhaustive_tests (it uses runtime-generated tables).
libsecp256k1/src/bench.c view on Meta::CPAN
#endif
printf("\n");
printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters);
printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n");
printf("\n");
printf("Usage: ./bench [args]\n");
printf("By default, all benchmarks will be run.\n");
printf("args:\n");
printf(" help : display this help and exit\n");
printf(" ecdsa : all ECDSA algorithms--sign, verify, recovery (if enabled)\n");
printf(" ecdsa_sign : ECDSA siging algorithm\n");
printf(" ecdsa_verify : ECDSA verification algorithm\n");
printf(" ec : all EC public key algorithms (keygen)\n");
printf(" ec_keygen : EC public key generation\n");
#ifdef ENABLE_MODULE_RECOVERY
printf(" ecdsa_recover : ECDSA public key recovery algorithm\n");
#endif
#ifdef ENABLE_MODULE_ECDH
printf(" ecdh : ECDH key exchange algorithm\n");
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG
printf(" schnorrsig : all Schnorr signature algorithms (sign, verify)\n");
printf(" schnorrsig_sign : Schnorr sigining algorithm\n");
printf(" schnorrsig_verify : Schnorr verification algorithm\n");
#endif
#ifdef ENABLE_MODULE_ELLSWIFT
printf(" ellswift : all ElligatorSwift benchmarks (encode, decode, keygen, ecdh)\n");
printf(" ellswift_encode : ElligatorSwift encoding\n");
printf(" ellswift_decode : ElligatorSwift decoding\n");
printf(" ellswift_keygen : ElligatorSwift key generation\n");
printf(" ellswift_ecdh : ECDH on ElligatorSwift keys\n");
#endif
libsecp256k1/src/bench.c view on Meta::CPAN
typedef struct {
secp256k1_context *ctx;
unsigned char msg[32];
unsigned char key[32];
unsigned char sig[72];
size_t siglen;
unsigned char pubkey[33];
size_t pubkeylen;
} bench_data;
static void bench_verify(void* arg, int iters) {
int i;
bench_data* data = (bench_data*)arg;
for (i = 0; i < iters; i++) {
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1);
CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0));
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
}
}
static void bench_sign_setup(void* arg) {
int i;
bench_data *data = (bench_data*)arg;
libsecp256k1/src/bench.c view on Meta::CPAN
int i;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
bench_data data;
int d = argc == 1;
int default_iters = 20000;
int iters = get_iters(default_iters);
/* Check for invalid user arguments */
char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover",
"ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign", "ec",
"keygen", "ec_keygen", "ellswift", "encode", "ellswift_encode", "decode",
"ellswift_decode", "ellswift_keygen", "ellswift_ecdh"};
size_t valid_args_size = sizeof(valid_args)/sizeof(valid_args[0]);
int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size);
if (argc > 1) {
if (have_flag(argc, argv, "-h")
|| have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) {
help(default_iters);
libsecp256k1/src/bench.c view on Meta::CPAN
#ifndef ENABLE_MODULE_RECOVERY
if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) {
fprintf(stderr, "./bench: Public key recovery module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n");
return 1;
}
#endif
#ifndef ENABLE_MODULE_SCHNORRSIG
if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) {
fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n");
return 1;
}
#endif
#ifndef ENABLE_MODULE_ELLSWIFT
if (have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "ellswift_encode") || have_flag(argc, argv, "ellswift_decode") ||
have_flag(argc, argv, "encode") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_keygen") ||
have_flag(argc, argv, "ellswift_ecdh")) {
libsecp256k1/src/bench.c view on Meta::CPAN
data.key[i] = 33 + i;
}
data.siglen = 72;
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
data.pubkeylen = 33;
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
print_output_table_header_row();
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "ecdsa_verify")) run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "ecdsa_sign")) run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "ec") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ec_keygen")) run_benchmark("ec_keygen", bench_keygen_run, bench_keygen_setup, NULL, &data, 10, iters);
secp256k1_context_destroy(data.ctx);
#ifdef ENABLE_MODULE_ECDH
/* ECDH benchmarks */
run_ecdh_bench(iters, argc, argv);
#endif
libsecp256k1/src/ctime_tests.c view on Meta::CPAN
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL);
SECP256K1_CHECKMEM_DEFINE(&recoverable_signature, sizeof(recoverable_signature));
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret);
CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature));
CHECK(recid >= 0 && recid <= 3);
#endif
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ec_seckey_verify(ctx, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ec_seckey_negate(ctx, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(msg, 32);
libsecp256k1/src/ecdsa.h view on Meta::CPAN
#define SECP256K1_ECDSA_H
#include <stddef.h>
#include "scalar.h"
#include "group.h"
#include "ecmult.h"
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size);
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s);
static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message);
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid);
#endif /* SECP256K1_ECDSA_H */
libsecp256k1/src/ecdsa_impl.h view on Meta::CPAN
sig[1] = 4 + lenS + lenR;
sig[2] = 0x02;
sig[3] = lenR;
memcpy(sig+4, rp, lenR);
sig[4+lenR] = 0x02;
sig[5+lenR] = lenS;
memcpy(sig+lenR+6, sp, lenS);
return 1;
}
static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) {
unsigned char c[32];
secp256k1_scalar sn, u1, u2;
#if !defined(EXHAUSTIVE_TEST_ORDER)
secp256k1_fe xr;
#endif
secp256k1_gej pubkeyj;
secp256k1_gej pr;
if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) {
return 0;
libsecp256k1/src/ecmult_const_impl.h view on Meta::CPAN
* The input point (n/d, y) also has Jacobian coordinates:
*
* (n/d, y, 1)
* = (n/d * v^2, y * v^3, v)
* = (n/d * d*g, y * sqrt(d^3*g^3), v)
* = (n/d * d*g, sqrt(y^2 * d^3*g^3), v)
* = (n*g, sqrt(g/d^3 * d^3*g^3), v)
* = (n*g, sqrt(g^4), v)
* = (n*g, g^2, v)
*
* It is easy to verify that both (n*g, g^2, v) and its negation (n*g, -g^2, v) have affine X
* coordinate n/d, and this holds even when the square root function doesn't have a
* deterministic sign. We choose the (n*g, g^2, v) version.
*
* Now switch to the effective affine curve using phi_v, where the input point has coordinates
* (n*g, g^2). Compute (X, Y, Z) = q * (n*g, g^2) there.
*
* Back on secp256k1, that means q * (n*g, g^2, v) = (X, Y, v*Z). This last point has affine X
* coordinate X / (v^2*Z^2) = X / (d*g*Z^2). Determining the affine Y coordinate would involve
* a square root, but as long as we only care about the resulting X coordinate, no square root
* is needed anywhere in this computation.
libsecp256k1/src/ecmult_impl.h view on Meta::CPAN
secp256k1_ge_set_xy(&pre_a[i], &ai.x, &ai.y);
}
/* Multiply the last z-coordinate by C to undo the isomorphism.
* Since the z-coordinates of the pre_a values are implied by the zr array of z-coordinate ratios,
* undoing the isomorphism here undoes the isomorphism for all pre_a values.
*/
secp256k1_fe_mul(z, &ai.z, &d.z);
}
SECP256K1_INLINE static void secp256k1_ecmult_table_verify(int n, int w) {
(void)n;
(void)w;
VERIFY_CHECK(((n) & 1) == 1);
VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1));
VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1));
}
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, const secp256k1_ge *pre, int n, int w) {
secp256k1_ecmult_table_verify(n,w);
if (n > 0) {
*r = pre[(n-1)/2];
} else {
*r = pre[(-n-1)/2];
secp256k1_fe_negate(&(r->y), &(r->y), 1);
}
}
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *r, const secp256k1_ge *pre, const secp256k1_fe *x, int n, int w) {
secp256k1_ecmult_table_verify(n,w);
if (n > 0) {
secp256k1_ge_set_xy(r, &x[(n-1)/2], &pre[(n-1)/2].y);
} else {
secp256k1_ge_set_xy(r, &x[(-n-1)/2], &pre[(-n-1)/2].y);
secp256k1_fe_negate(&(r->y), &(r->y), 1);
}
}
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_storage(secp256k1_ge *r, const secp256k1_ge_storage *pre, int n, int w) {
secp256k1_ecmult_table_verify(n,w);
if (n > 0) {
secp256k1_ge_from_storage(r, &pre[(n-1)/2]);
} else {
secp256k1_ge_from_storage(r, &pre[(-n-1)/2]);
secp256k1_fe_negate(&(r->y), &(r->y), 1);
}
}
/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits),
* with the following guarantees:
libsecp256k1/src/ecmult_impl.h view on Meta::CPAN
carry = (word >> (w-1)) & 1;
word -= carry << w;
wnaf[bit] = sign * word;
last_set_bit = bit;
bit += now;
}
#ifdef VERIFY
{
int verify_bit = bit;
VERIFY_CHECK(carry == 0);
while (verify_bit < 256) {
VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&s, verify_bit, 1) == 0);
verify_bit++;
}
}
#endif
return last_set_bit + 1;
}
struct secp256k1_strauss_point_state {
int wnaf_na_1[129];
int wnaf_na_lam[129];
int bits_na_1;
libsecp256k1/src/field.h view on Meta::CPAN
* operations are permitted on it. These are purely a function of what
* secp256k1_fe_ operations are applied on it, generally (implicitly) fixed at
* compile time, and do not depend on the chosen field implementation. Despite
* that, what these properties actually entail for the field representation
* values depends on the chosen field implementation. These properties are:
* - magnitude: an integer in [0,32]
* - normalized: 0 or 1; normalized=1 implies magnitude <= 1.
*
* In VERIFY mode, they are materialized explicitly as fields in the struct,
* allowing run-time verification of these properties. In that case, the field
* implementation also provides a secp256k1_fe_verify routine to verify that
* these fields match the run-time value and perform internal consistency
* checks. */
#ifdef VERIFY
# define SECP256K1_FE_VERIFY_FIELDS \
int magnitude; \
int normalized;
#else
# define SECP256K1_FE_VERIFY_FIELDS
#endif
libsecp256k1/src/field.h view on Meta::CPAN
* internal overflows. */
static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m);
/** Determine whether a is a square (modulo p).
*
* On input, a must be a valid field element.
*/
static int secp256k1_fe_is_square_var(const secp256k1_fe *a);
/** Check invariants on a field element (no-op unless VERIFY is enabled). */
static void secp256k1_fe_verify(const secp256k1_fe *a);
#define SECP256K1_FE_VERIFY(a) secp256k1_fe_verify(a)
/** Check that magnitude of a is at most m (no-op unless VERIFY is enabled). */
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m);
#define SECP256K1_FE_VERIFY_MAGNITUDE(a, m) secp256k1_fe_verify_magnitude(a, m)
#endif /* SECP256K1_FIELD_H */
libsecp256k1/src/field_10x26_impl.h view on Meta::CPAN
#ifndef SECP256K1_FIELD_REPR_IMPL_H
#define SECP256K1_FIELD_REPR_IMPL_H
#include "checkmem.h"
#include "util.h"
#include "field.h"
#include "modinv32_impl.h"
#ifdef VERIFY
static void secp256k1_fe_impl_verify(const secp256k1_fe *a) {
const uint32_t *d = a->n;
int m = a->normalized ? 1 : 2 * a->magnitude;
VERIFY_CHECK(d[0] <= 0x3FFFFFFUL * m);
VERIFY_CHECK(d[1] <= 0x3FFFFFFUL * m);
VERIFY_CHECK(d[2] <= 0x3FFFFFFUL * m);
VERIFY_CHECK(d[3] <= 0x3FFFFFFUL * m);
VERIFY_CHECK(d[4] <= 0x3FFFFFFUL * m);
VERIFY_CHECK(d[5] <= 0x3FFFFFFUL * m);
VERIFY_CHECK(d[6] <= 0x3FFFFFFUL * m);
VERIFY_CHECK(d[7] <= 0x3FFFFFFUL * m);
libsecp256k1/src/field_5x52_impl.h view on Meta::CPAN
#define SECP256K1_FIELD_REPR_IMPL_H
#include "checkmem.h"
#include "util.h"
#include "field.h"
#include "modinv64_impl.h"
#include "field_5x52_int128_impl.h"
#ifdef VERIFY
static void secp256k1_fe_impl_verify(const secp256k1_fe *a) {
const uint64_t *d = a->n;
int m = a->normalized ? 1 : 2 * a->magnitude;
/* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
VERIFY_CHECK(d[0] <= 0xFFFFFFFFFFFFFULL * m);
VERIFY_CHECK(d[1] <= 0xFFFFFFFFFFFFFULL * m);
VERIFY_CHECK(d[2] <= 0xFFFFFFFFFFFFFULL * m);
VERIFY_CHECK(d[3] <= 0xFFFFFFFFFFFFFULL * m);
VERIFY_CHECK(d[4] <= 0x0FFFFFFFFFFFFULL * m);
if (a->normalized) {
if ((d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) {
libsecp256k1/src/field_impl.h view on Meta::CPAN
if (!ret) {
secp256k1_fe_negate(&t1, &t1, 1);
secp256k1_fe_normalize_var(&t1);
VERIFY_CHECK(secp256k1_fe_equal(&t1, a));
}
#endif
return ret;
}
#ifndef VERIFY
static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; }
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { (void)a; (void)m; }
#else
static void secp256k1_fe_impl_verify(const secp256k1_fe *a);
static void secp256k1_fe_verify(const secp256k1_fe *a) {
/* Magnitude between 0 and 32. */
SECP256K1_FE_VERIFY_MAGNITUDE(a, 32);
/* Normalized is 0 or 1. */
VERIFY_CHECK((a->normalized == 0) || (a->normalized == 1));
/* If normalized, magnitude must be 0 or 1. */
if (a->normalized) SECP256K1_FE_VERIFY_MAGNITUDE(a, 1);
/* Invoke implementation-specific checks. */
secp256k1_fe_impl_verify(a);
}
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) {
VERIFY_CHECK(m >= 0);
VERIFY_CHECK(m <= 32);
VERIFY_CHECK(a->magnitude <= m);
}
static void secp256k1_fe_impl_normalize(secp256k1_fe *r);
SECP256K1_INLINE static void secp256k1_fe_normalize(secp256k1_fe *r) {
SECP256K1_FE_VERIFY(r);
secp256k1_fe_impl_normalize(r);
libsecp256k1/src/group.h view on Meta::CPAN
* In normal mode, the used group is secp256k1, which has cofactor=1 meaning that every point on the curve is in the
* group, and this function returns always true.
*
* When compiling in exhaustive test mode, a slightly different curve equation is used, leading to a group with a
* (very) small subgroup, and that subgroup is what is used for all cryptographic operations. In that mode, this
* function checks whether a point that is on the curve is in fact also in that subgroup.
*/
static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge);
/** Check invariants on an affine group element (no-op unless VERIFY is enabled). */
static void secp256k1_ge_verify(const secp256k1_ge *a);
#define SECP256K1_GE_VERIFY(a) secp256k1_ge_verify(a)
/** Check invariants on a Jacobian group element (no-op unless VERIFY is enabled). */
static void secp256k1_gej_verify(const secp256k1_gej *a);
#define SECP256K1_GEJ_VERIFY(a) secp256k1_gej_verify(a)
#endif /* SECP256K1_GROUP_H */