Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#ifndef SECP256K1_ELLSWIFT_H2#define SECP256K1_ELLSWIFT_H4#include "secp256k1.h"6#ifdef __cplusplus7extern "C" {8#endif10/* This module provides an implementation of ElligatorSwift as well as a11* version of x-only ECDH using it (including compatibility with BIP324).12*13* ElligatorSwift is described in https://eprint.iacr.org/2022/759 by14* Chavez-Saab, Rodriguez-Henriquez, and Tibouchi. It permits encoding15* uniformly chosen public keys as 64-byte arrays which are indistinguishable16* from uniformly random arrays.17*18* Let f be the function from pairs of field elements to point X coordinates,19* defined as follows (all operations modulo p = 2^256 - 2^32 - 977)20* f(u,t):21* - Let C = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852,22* a square root of -3.23* - If u=0, set u=1 instead.24* - If t=0, set t=1 instead.25* - If u^3 + t^2 + 7 = 0, multiply t by 2.26* - Let X = (u^3 + 7 - t^2) / (2 * t)27* - Let Y = (X + t) / (C * u)28* - Return the first in [u + 4 * Y^2, (-X/Y - u) / 2, (X/Y - u) / 2] that is an29* X coordinate on the curve (at least one of them is, for any u and t).30*31* Then an ElligatorSwift encoding of x consists of the 32-byte big-endian32* encodings of field elements u and t concatenated, where f(u,t) = x.33* The encoding algorithm is described in the paper, and effectively picks a34* uniformly random pair (u,t) among those which encode x.35*36* If the Y coordinate is relevant, it is given the same parity as t.37*38* Changes w.r.t. the paper:39* - The u=0, t=0, and u^3+t^2+7=0 conditions result in decoding to the point40* at infinity in the paper. Here they are remapped to finite points.41* - The paper uses an additional encoding bit for the parity of y. Here the42* parity of t is used (negating t does not affect the decoded x coordinate,43* so this is possible).44*45* For mathematical background about the scheme, see the doc/ellswift.md file.46*/48/** A pointer to a function used by secp256k1_ellswift_xdh to hash the shared X49* coordinate along with the encoded public keys to a uniform shared secret.50*51* Returns: 1 if a shared secret was successfully computed.52* 0 will cause secp256k1_ellswift_xdh to fail and return 0.53* Other return values are not allowed, and the behaviour of54* secp256k1_ellswift_xdh is undefined for other return values.55* Out: output: pointer to an array to be filled by the function56* In: x32: pointer to the 32-byte serialized X coordinate57* of the resulting shared point (will not be NULL)58* ell_a64: pointer to the 64-byte encoded public key of party A59* (will not be NULL)60* ell_b64: pointer to the 64-byte encoded public key of party B61* (will not be NULL)62* data: arbitrary data pointer that is passed through63*/64typedef int (*secp256k1_ellswift_xdh_hash_function)(65unsigned char *output,66const unsigned char *x32,67const unsigned char *ell_a64,68const unsigned char *ell_b64,69void *data70);72/** An implementation of an secp256k1_ellswift_xdh_hash_function which uses73* SHA256(prefix64 || ell_a64 || ell_b64 || x32), where prefix64 is the 64-byte74* array pointed to by data. */75SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix;77/** An implementation of an secp256k1_ellswift_xdh_hash_function compatible with78* BIP324. It returns H_tag(ell_a64 || ell_b64 || x32), where H_tag is the79* BIP340 tagged hash function with tag "bip324_ellswift_xonly_ecdh". Equivalent80* to secp256k1_ellswift_xdh_hash_function_prefix with prefix64 set to81* SHA256("bip324_ellswift_xonly_ecdh")||SHA256("bip324_ellswift_xonly_ecdh").82* The data argument is ignored. */83SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324;85/** Construct a 64-byte ElligatorSwift encoding of a given pubkey.86*87* Returns: 1 always.88* Args: ctx: pointer to a context object89* Out: ell64: pointer to a 64-byte array to be filled90* In: pubkey: pointer to a secp256k1_pubkey containing an91* initialized public key92* rnd32: pointer to 32 bytes of randomness93*94* It is recommended that rnd32 consists of 32 uniformly random bytes, not95* known to any adversary trying to detect whether public keys are being96* encoded, though 16 bytes of randomness (padded to an array of 32 bytes,97* e.g., with zeros) suffice to make the result indistinguishable from98* uniform. The randomness in rnd32 must not be a deterministic function of99* the pubkey (it can be derived from the private key, though).100*101* It is not guaranteed that the computed encoding is stable across versions102* of the library, even if all arguments to this function (including rnd32)103* are the same.104*105* This function runs in variable time.106*/107SECP256K1_API int secp256k1_ellswift_encode(108const secp256k1_context *ctx,109unsigned char *ell64,110const secp256k1_pubkey *pubkey,111const unsigned char *rnd32112) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);114/** Decode a 64-bytes ElligatorSwift encoded public key.115*116* Returns: always 1117* Args: ctx: pointer to a context object118* Out: pubkey: pointer to a secp256k1_pubkey that will be filled119* In: ell64: pointer to a 64-byte array to decode120*121* This function runs in variable time.122*/123SECP256K1_API int secp256k1_ellswift_decode(124const secp256k1_context *ctx,125secp256k1_pubkey *pubkey,126const unsigned char *ell64127) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);129/** Compute an ElligatorSwift public key for a secret key.130*131* Returns: 1: secret was valid, public key was stored.132* 0: secret was invalid, try again.133* Args: ctx: pointer to a context object (not secp256k1_context_static)134* Out: ell64: pointer to a 64-byte array to receive the ElligatorSwift135* public key136* In: seckey32: pointer to a 32-byte secret key137* auxrnd32: (optional) pointer to 32 bytes of randomness138*139* Constant time in seckey and auxrnd32, but not in the resulting public key.140*141* It is recommended that auxrnd32 contains 32 uniformly random bytes, though142* it is optional (and does result in encodings that are indistinguishable from143* uniform even without any auxrnd32). It differs from the (mandatory) rnd32144* argument to secp256k1_ellswift_encode in this regard.145*146* This function can be used instead of calling secp256k1_ec_pubkey_create147* followed by secp256k1_ellswift_encode. It is safer, as it uses the secret148* key as entropy for the encoding (supplemented with auxrnd32, if provided).149*150* Like secp256k1_ellswift_encode, this function does not guarantee that the151* computed encoding is stable across versions of the library, even if all152* arguments (including auxrnd32) are the same.153*/154SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create(155const secp256k1_context *ctx,156unsigned char *ell64,157const unsigned char *seckey32,158const unsigned char *auxrnd32159) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);161/** Given a private key, and ElligatorSwift public keys sent in both directions,162* compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH).163*164* Returns: 1: shared secret was successfully computed165* 0: secret was invalid or hashfp returned 0166* Args: ctx: pointer to a context object.167* Out: output: pointer to an array to be filled by hashfp.168* In: ell_a64: pointer to the 64-byte encoded public key of party A169* (will not be NULL)170* ell_b64: pointer to the 64-byte encoded public key of party B171* (will not be NULL)172* seckey32: pointer to our 32-byte secret key173* party: boolean indicating which party we are: zero if we are174* party A, non-zero if we are party B. seckey32 must be175* the private key corresponding to that party's ell_?64.176* This correspondence is not checked.177* hashfp: pointer to a hash function.178* data: arbitrary data pointer passed through to hashfp.179*180* Constant time in seckey32.181*182* This function is more efficient than decoding the public keys, and performing183* ECDH on them.184*/185SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_xdh(186const secp256k1_context *ctx,187unsigned char *output,188const unsigned char *ell_a64,189const unsigned char *ell_b64,190const unsigned char *seckey32,191int party,192secp256k1_ellswift_xdh_hash_function hashfp,193void *data194) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7);196#ifdef __cplusplus197}198#endif200#endif /* SECP256K1_ELLSWIFT_H */
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.