78

I'm afraid you won't like the answer. These curves - including the secp256k1 curve, y2 = x3 + 7` - 'look' nice when evaluated in typical number fields (integers, reals, ...), but secp256k1 is defined over the field Z2256-232-977, which means the X and Y coordinates are 256-bit integers modulo a large number. Curves using such coordinates do not have nice ...


23

you can check the Bitcoin doc https://en.bitcoin.it/wiki/Secp256k1 , there you will find some technical details about the secp256k1 used in bitcoin. Below an illustration of the secp256k1's elliptic curve y2 = x3 + 7 over the real numbers (plot using www.desmos.com/calculator/ialhd71we3) in the context of a finite field Zp, which greatly changes the ECC ...


11

No, there is not one private key. There is one Master private key. The master private key is then used to generate more private keys in a deterministic fashion, i.e. using the same master private key, you will generate the same private keys. Those private keys are what are actually used in your wallet. Their public keys are generated and the addressees ...


11

The Schnorr implementation was never in Bitcoin Core. Rather it is in the libsecp256k1 library that is a subtree in Bitcoin Core. The commit you reference is actually a commit in that library which appears in Core's commit history because the subtree in Core is periodically updated with the libsecp256k1 upstream source code. The reason for removal is ...


10

Secp256k1 was designed to be a 256-bit size elliptic curve without cofactor and admitting an efficient endomorphism for optimization purposes. The choices of the relevant parameters are derived from these criteria. P is selected allow a more efficient implementation on general purpose computers. See Solinas' paper on Generalized Mersenne Numbers. We don't ...


9

The secp256k1 curve is defined over x and y coordinates that are members of the finite field GF(2^256 - 2^32 - 977), or in other words, their operations hold only when considered modulo 115792089237316195423570985008687907853269984665640564039457584007908834671663. 55066263022277343669578718895168534326250603453777594175500187360389116729240^3 - (...


7

The size of secp256k1's coordinate field is 2256 - 232 - 977. That means there are only 232 + 977 (about 4 billion) possible 32-byte combinations that are not a valid coordinate. Only slightly less than half (around 2255 - 1.17 * 2127) of those are the X coordinate of a point on the curve (in fact, for every valid X coordinate, there are either exactly 0 ...


7

The reasons for the 3 numbers: Bitcoin uses 256-bit ECDSA signatures. These require in the order of 2128 steps to find a private key from the public key is known. This is Bitcoin's security level: we aim to always require an attacker to perform 2128 steps. If the seed has less than 128 bits of entropy, this inevitably leads to a faster algorithm, where an ...


7

You're right, there is no strict requirement that the private key is strictly less than the group order. However, it is required that the resulting public key is uniform, which implies that (x % n) must be uniformly distributed between 1 and n-1 inclusive (or at least indistinguishably close to uniform). The easiest way to accomplish this is by saying that ...


7

How should these two functions be used properly? A simple answer is "not at all". Those functions are not exposed in the public API of libsecp256k1, and that's the reason why they don't have user-targeted documentation. Instead, they're used as internal subroutines, mostly for the implementation of ECDSA and Schnorr signatures. Be advised that ...


6

Below extract should answer your question. public class ECKeyPair implements Key { private static final SecureRandom secureRandom = new SecureRandom (); private static final X9ECParameters curve = SECNamedCurves.getByName ("secp256k1"); private static final ECDomainParameters domain = new ECDomainParameters (curve.getCurve (), curve.getG (), ...


5

If people in general would more often pick lower integers as private keys than larger integers, then it would be a good strategy for an attacker to start with lower integers. However, the opposite also holds. If people would more often pick larger numbers, then atackers would ideally start at the end and work their way backwards. In practice, no such bias ...


5

Since the secp256k1 curve order is prime, every point on the curve except the point at infinity is a generator. Nothing is known about how the designers of the curve chose this specific generator. However, there is one tell-tale sign that hints about its construction. When the chosen generator G is multiplied by 1/2 (i.e. multiplied by the multiplicative ...


5

There is no concrete determination that makes one 'y' value negative or not in an EC point. Feel free to make your own convention, like y-values <= than half of p are negative, and > half of p are positive. That's just a convention, though. Related: What does the curve used in Bitcoin, secp256k1, look like? Also, how can you identify which pub key is ...


5

Without (void) data;, gcc will complain about data being an unused variable. This is used throughout the codebase, especially for context objects, to deal with parameters which are required for API/consistency reasons but not actually needed.


5

The comment stating n “has to be prime” is a bit confusing. The order of base point “has” to be prime in the sense that this is a requirement in the particular documents defining standard curves—for example, in SECG, which includes secp256k1. Bitcoin's base point order r is prime. In SECG, it is also stated that cofactor of secp256k1 curve is 1, which ...


5

Bip-32 allows me to dereive keys based off a root key pair, and all these keys will be on the secp256k1 curve. This is actually not true. The BIP32 proposal simply states that (emphasis mine): In the rest of this text we will assume the public key cryptography used in Bitcoin, namely elliptic curve cryptography using the field and curve parameters ...


5

These magic values: 302e0201010420 a00706052b8104000a Openssl seems to use these values for DER encoding rules, and it doesn't seem to have anything to do with secp256k1 or Bitcoin specifically. Is this a correct assumption? They have nothing to do with Bitcoin, but I believe that those bytes contain a reference to secp256k1 (probably through ...


5

You are using the eliptic curve function of openssl and providing a serialized bytestring as an input. DER (Distinguished Encoding Rules) is a restricted variant of BER for producing unequivocal transfer syntax for data structures described by ASN.1. The ASN1 structure for a privkey looks like this: # ASN.1 STRUCTURE FOR PRIVATE KEY: # 30 <-- ...


5

The 04 first byte header indicates this is an uncompressed point (02 indicates compressed). From there, it is simply an x followed by y representation - The first 32 bytes are x, the following 32 bytes are y. Therefore, x = 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 y = 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 ...


4

I usually use the following analogy to oversimplify things: The secret key is how far you walk along a known curve starting from a known point and the public point is where on the curve you wind up when you finish. If you repeat the same walk, you will always wind up at the same place. The operation is irreversible because the curve is complex, you can only ...


4

The code you are referring to in libsecp256k1 is not for ECDSA. It implements the custom compact signatures that Bitcoin Core uses for message signing and verification. The normal ECDSA code in libsecp256k1 should be identical in acceptance to the one in OpenSSL (apart from the fact that by default, it only accepts and produces low-s signatures, as a way ...


4

I just merged a PR by Rusty Russell that aims to explain its purpose. From the text that was added: While secp256k1 code is written to be constant-time no matter what secret values are, it's possible that a future compiler may output code which isn't, and also that the CPU may not emit the same radio frequencies or draw the same amount power for all ...


4

The secp256k1 library uses RFC6979 to generate deterministic nonce values (k). It essentially takes the hash of both the private key and the message being signed in order to get k. This means that signing the same message with the same private key multiple times will always result in the same signature. Other libraries may not do this. ECDSA only requires ...


4

You can negate a point (x, y) by simply changing it to (x, −y). The document that defines ECDSA reminds us of this fact: https://www.secg.org/sec1-v2.pdf Here's a screenshot: So once you have negated one of your points, just add it to the other one, and you have achieved subtraction.


4

In ECDSA, the private key is a scalar 256-bit number. The public key is a elliptic curve point on the secp256k1 curve. Elliptic curves are abelian groups made up of the set of points resulting from repeatedly applying its group operation starting with its base point G. The group operation is the addition of two points. So, starting with the base point as the ...


3

since the group is cyclic with order N, then this key will be equal to 0x14551231950b75fc4402da1732fc9bebd (your key modulo N) >>> hex(N) '0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' >>> y=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE >>> multiply(y) (...


3

Notice that without this cast, data would be unused in this function. This is probably here for the purpose of preventing compiler warnings about unused variables, while keeping the argument in the function signature.


3

These are used in the "hybrid" public key format, which is an uncompressed format (it has both X and Y coordinates, like 0x04) that still stores the odd/evenness of the Y coordinate (like 0x02/0x03). It is defined in ANSI X9.62-1998 Sections 4.3.6 and 4.3.7, and seems totally useless to me. However, OpenSSL supported it, thus when switching to libsecp256k1 ...


3

If you look at the source code, secp256k1_ec_pubkey_parse doesn't actually use its ctx argument. So no harm is done if it's null. You can see in the code that there is a VERIFY_CHECK macro to test if ctx is non-null. However, this is meant only for testing; you can see in util.h that nothing is actually done about the test unless the VERIFY macro is ...


Only top voted, non community-wiki answers of a minimum length are eligible