<p>The secp256k1 curve equation is:</p>
<ul>
<li>Points <em>(x,y)</em> for which <em>y<sup>2</sup> = x<sup>3</sup> + 7</em> mod <em>p</em>, where <em>p = 2<sup>256</sup>-2<sup>32</sup>-977</em></li>
</ul>
<p>If we solve this for <em>y</em>, we get <em>y = ±√(x<sup>3</sup> +7) mod p</em>.</p>
<p>Of course, this is not a normal square root, but a square root for the field of integers modulo <em>p</em>, but otherwise this equation is correct. To compute such a modular square root, the <a href="https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm" rel="nofollow noreferrer">Tonelli-Shanks</a> algorithm is used. It can deal with many cases, depending on the structure of the modulus, but for our <em>p</em> modulus it simplifies to just:</p>
<ul>
<li><em>√a mod p = a<sup>(p+1)/4</sup> mod p</em> (for any prime <em>p</em> for which <em>p+1</em> is a multiple of <em>4</em>).</li>
</ul>

CC BY-SA 4.0
2021-09-12T02:01:43.243Z
Tad confused what A is supposed to be, I assumed it was (x^3)+7 but after doing the equation for x = 72488970228380509287422715226575535698893157273063074627791787432852706183111, I got 5945770897828140901859913642993887309423255879987770157450768201525288715151 for y, which is incorrect, any chance you could help me out?
Raccoondude
CC BY-SA 4.0
2021-09-12T02:15:13.427Z
Yes, *a* is *x^3 + 7* here. Given x=72488970228380509287422715226575535698893157273063074627791787432852706183111, you get a=x^3+7=4037741034981857009060200306242622473933214174234453045209672395016311171624 (mod p). y = a^((p+1)/4) = 62070622898698443831883535403436258712770888294397026493185421712108624767191 (again mod p). Its negation -y = 53721466338617751591687449605251649140499096371243537546272162295800209904472 is also a valid corresponding Y coordinate.
Pieter Wuille
CC BY-SA 4.0
2021-09-12T02:54:20.833Z
Theres mutible Y cords @W@ How would I get the one I need for my private for example without using my private? Thats kinda what im looking for to understand how bitcoin works, because im a bit confused how your supposed to get the "y" that was generated with the private
Raccoondude
CC BY-SA 4.0
2021-09-12T03:03:50.653Z
That information is normally part of the public key. In SEC encoded compressed public keys you have (0x02 or 0x03) + (32-byte X coord), with the 0x02/0x03 indicating whether Y is even or odd. In BIP340 Schnorr public keys, the Y coordinate is implicitly even, and the private key is negated at signing time if the Y coordinate would otherwise be odd.
Pieter Wuille
CC BY-SA 4.0
2021-09-12T03:14:06.647Z
Ok, so basically, lets say im looking for Y, but it doesn't come up when I do your function, what do I do then exactly to get the Y I need?
Raccoondude
CC BY-SA 4.0
2021-09-12T03:18:53.310Z
As I just said: you'll be looking for either the even or the odd one. Which one you need is always going to be clear from the context (it's either implied, or encoded in the public key).
Pieter Wuille
CC BY-SA 4.0
2021-09-12T03:25:20.037Z
Yeah, but once I look for the first Y doing a^(p+1)/4 mod p, and its not it, what do I do then?
Raccoondude
CC BY-SA 4.0
2021-09-12T04:13:14.537Z
Im getting incorrect results when doing pow(a,int((curve.p+1)/4),curve.p), I get 5945770897828140901859913642993887309423255879987770157450768201525288715151, do you know what this is about?
Raccoondude
CC BY-SA 4.0
2021-09-12T12:05:34.027Z
Is that Python? Don't use "int(.../4)", as it converts the argument to a floating point number, losing precision. You need integer division here which avoids that conversion (use "...//4" instead).
Pieter Wuille
CC BY-SA 4.0
2021-09-11T17:36:38.020Z
2021-09-11T17:44:02.420Z
2021-09-11T17:44:02.420Z
Pieter Wuille
<p>Ok, so I get address generation now, and I understand that X is hashed, however for verification of a signature, we need the public point, (x,y)</p>
<p>How would one get Y from X?</p>
<p>Lets take an example, im gonna use my generator (0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8) and use private &quot;10&quot; (using a = 0, b = 7, p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f) to get:</p>
<p>(0xa0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,0x893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7)</p>
<p>Now we remove Y, to only have: 0xa0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7</p>
<p>Meaning that we need to get Y from X, how would I do this? I never seen this explained really and everything I tried doesn't result in the correct Y value</p>

<signature><signrawtransaction>
How to get Y from X
Raccoondude
# How to get Y from X

(Asked by: username_0 on 2021-09-11)

Ok, so I get address generation now, and I understand that X is hashed, however for verification of a signature, we need the public point, (x,y)

How would one get Y from X?

Lets take an example, im gonna use my generator (0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8) and use private "10" (using a = 0, b = 7, p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f) to get:

(0xa0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,0x893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7)

Now we remove Y, to only have: 0xa0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7

Meaning that we need to get Y from X, how would I do this? I never seen this explained really and everything I tried doesn't result in the correct Y value

**Tags:** signature, signrawtransaction


---

## 1 answers

### Answer by username_1 on 2021-09-11. Score: 2

The secp256k1 curve equation is:

* Points *(x,y)* for which *y2 = x3 + 7* mod *p*, where *p = 2256-232-977*

If we solve this for *y*, we get *y = ±√(x3 +7) mod p*.

Of course, this is not a normal square root, but a square root for the field of integers modulo *p*, but otherwise this equation is correct. To compute such a modular square root, the [Tonelli-Shanks](https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm) algorithm is used. It can deal with many cases, depending on the structure of the modulus, but for our *p* modulus it simplifies to just:

* *√a mod p = a(p+1)/4 mod p* (for any prime *p* for which *p+1* is a multiple of *4*).

> **Comments:**
> **username_0**: Tad confused what A is supposed to be, I assumed it was (x^3)+7 but after doing the equation for x = 72488970228380509287422715226575535698893157273063074627791787432852706183111, I got 5945770897828140901859913642993887309423255879987770157450768201525288715151 for y, which is incorrect, any chance you could help me out?  
> **username_1**: Yes, *a* is *x^3 + 7* here. Given x=72488970228380509287422715226575535698893157273063074627791787432852706183111, you get a=x^3+7=4037741034981857009060200306242622473933214174234453045209672395016311171624 (mod p). y = a^((p+1)/4) = 62070622898698443831883535403436258712770888294397026493185421712108624767191 (again mod p). Its negation -y = 53721466338617751591687449605251649140499096371243537546272162295800209904472 is also a valid corresponding Y coordinate.  
> **username_0**: Theres mutible Y cords @W@ How would I get the one I need for my private for example without using my private? Thats kinda what im looking for to understand how bitcoin works, because im a bit confused how your supposed to get the "y" that was generated with the private  
> **username_1**: That information is normally part of the public key. In SEC encoded compressed public keys you have (0x02 or 0x03) + (32-byte X coord), with the 0x02/0x03 indicating whether Y is even or odd. In BIP340 Schnorr public keys, the Y coordinate is implicitly even, and the private key is negated at signing time if the Y coordinate would otherwise be odd.  
> **username_0**: Ok, so basically, lets say im looking for Y, but it doesn't come up when I do your function, what do I do then exactly to get the Y I need?  
> **username_1**: As I just said: you'll be looking for either the even or the odd one. Which one you need is always going to be clear from the context (it's either implied, or encoded in the public key).  
> **username_0**: Yeah, but once I look for the first Y doing a^(p+1)/4 mod p, and its not it, what do I do then?  
> **username_0**: Im getting incorrect results when doing pow(a,int((curve.p+1)/4),curve.p), I get 5945770897828140901859913642993887309423255879987770157450768201525288715151, do you know what this is about?  
> **username_1**: Is that Python? Don't use "int(.../4)", as it converts the argument to a floating point number, losing precision. You need integer division here which avoids that conversion (use "...//4" instead).  

---

