Bitcoin Forum
May 11, 2024, 07:00:38 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Why does signature verification calculate the square root of y?  (Read 157 times)
NotATether (OP)
Legendary
*
Offline Offline

Activity: 1596
Merit: 6735


bitcoincleanup.com / bitmixlist.org


View Profile WWW
August 03, 2022, 09:26:36 AM
Last edit: August 03, 2022, 01:09:55 PM by NotATether
Merited by NeuroticFish (1)
 #1

When calculating coordinates from an ECDSA (r,s) signature, or when computing the public key with specific odd/even Y, we usually do something like this:

Code:
x = x^3 + 7 mod p
y = x^((p+1)/4) mod p

Why are we taking the square root of y instead of just y?


EDIT: I should be clear that I was expecting this operation to take the square root of (y^2) not its fourth root.


Later, when we are attempting to identify the value of y that is even or odd, we take the recID, which tells us whether the Y coordinate is supposed to be even or odd, and subtract the square root of y minus 0 or 1 respectively.

And the last bit of the result tells us whether this is the even or odd part of sqrt(y) (doing p-y gives us the y coordinate of opposite parity). But how does this tell us anything about y itself?

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
1715410838
Hero Member
*
Offline Offline

Posts: 1715410838

View Profile Personal Message (Offline)

Ignore
1715410838
Reply with quote  #2

1715410838
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715410838
Hero Member
*
Offline Offline

Posts: 1715410838

View Profile Personal Message (Offline)

Ignore
1715410838
Reply with quote  #2

1715410838
Report to moderator
1715410838
Hero Member
*
Offline Offline

Posts: 1715410838

View Profile Personal Message (Offline)

Ignore
1715410838
Reply with quote  #2

1715410838
Report to moderator
pooya87
Legendary
*
Offline Offline

Activity: 3444
Merit: 10558



View Profile
August 03, 2022, 11:50:55 AM
 #2

Code:
x = x^3 + 7 mod p
y = x^((p+1)/4) mod p
The first one looks like the Elliptic Curve equation (correct form is y2=x3 + ax + b with a=0 and b=7 for secp256k1) when you only have x and want to find y you have to compute square root of the right side (sqrt of x3 +7).

To find square root mod p when p%4 = 3 (prime of secp256k1 curve is like that) you can compute x(p+1)/4 (mod p) instead.

Quote
and subtract the square root of y minus 0 or 1 respectively.
0 or 1 is subtracted from the recid not the square root.

Quote
But how does this tell us anything about y itself?
When signing the message hash the recid is computed by adding 1 to it if y was odd and adding 0 if it were even. So when recovering public keys if that 1 existed in recid we have to return the odd y.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
NotATether (OP)
Legendary
*
Offline Offline

Activity: 1596
Merit: 6735


bitcoincleanup.com / bitmixlist.org


View Profile WWW
August 03, 2022, 12:54:55 PM
Last edit: August 03, 2022, 01:07:40 PM by NotATether
Merited by pooya87 (2)
 #3

To find square root mod p when p%4 = 3 (prime of secp256k1 curve is like that) you can compute x(p+1)/4 (mod p) instead.

I'm trying to grok my head around this.

We have y^2 = x^3 + 7 so before I wrote this topic I had the idea that the next statement took the 4th root of Right Hand Side (power by p+1 is equivalent to just 1, and I had the belief that coord^((p+1)/2) was equivalent to taking the square root - since we clearly cannot raise by the fractional power 1/2, but (p+1)/2 is equivalent to that).

In other words, (y^2)^((p+1)/4) would've been sqrt(y) not y. It's like in algebra how you apply the first sqrt and then you have (y)^((p+1)/2).

But apparently the p+1 is to ensure that modulus is zero, i.e. (p+1) % 4 = 0, and then the division by 4 is done. So how is dividing this shifted prime by 4 equivalent to a square root?

Is it because we are now taking the modular power by a whole number? Then why 4 specifically and not some other number?

Quote
0 or 1 is subtracted from the recid not the square root.

No look, bitcoinsig.js that is used in the "brainwallet.github.io" sites has this in the verificaiton algo:

Code:
function verify_message(signature, message, addrtype) {
    try {
        var sig = Crypto.util.base64ToBytes(signature);
    } catch(err) {
        return false;
    }

    if (sig.length != 65)
        return false;

    // extract r,s from signature
    var r = BigInteger.fromByteArrayUnsigned(sig.slice(1,1+32));
    var s = BigInteger.fromByteArrayUnsigned(sig.slice(33,33+32));

    // get recid
    var compressed = false;
    var nV = sig[0];
    if (nV < 27 || nV >= 35)
        return false;
    if (nV >= 31) {
        compressed = true;
        nV -= 4;
    }
    var recid = BigInteger.valueOf(nV - 27);

    var ecparams = getSECCurveByName("secp256k1");
    var curve = ecparams.getCurve();
    var a = curve.getA().toBigInteger();
    var b = curve.getB().toBigInteger();
    var p = curve.getQ();
    var G = ecparams.getG();
    var order = ecparams.getN();

    var x = r.add(order.multiply(recid.divide(BigInteger.valueOf(2))));
    var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p);
    var beta = alpha.modPow(p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)), p);

    // It's subtracting recID from Y here, i.e. it is effectively subtracting 0 or 1 from it (ignoring the higher bit) - NotATether
    var y = beta.subtract(recid).isEven() ? beta : p.subtract(beta);

    var R = new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));
    var e = BigInteger.fromByteArrayUnsigned(msg_digest(message));
    var minus_e = e.negate().mod(order);
    var inv_r = r.modInverse(order);
    var Q = (R.multiply(s).add(G.multiply(minus_e))).multiply(inv_r);

    var public_key = Q.getEncoded(compressed);
    var addr = new Bitcoin.Address(Bitcoin.Util.sha256ripe160(public_key));

    addr.version = addrtype ? addrtype : 0;
    return addr.toString();
}

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
j2002ba2
Full Member
***
Offline Offline

Activity: 204
Merit: 437


View Profile
August 03, 2022, 01:16:06 PM
Merited by NeuroticFish (3), NotATether (3), pooya87 (2)
 #4

To find square root mod p when p%4 = 3 (prime of secp256k1 curve is like that) you can compute x(p+1)/4 (mod p) instead.

I'm trying to grok my head around this.

We have y^2 = x^3 + 7 so before I wrote this topic I had the idea that the next statement took the 4th root of Right Hand Side (power by p+1 is equivalent to just 1, and I had the belief that coord^((p+1)/2) was equivalent to taking the square root - since we clearly cannot raise by the fractional power 1/2, but (p+1)/2 is equivalent to that).

In other words, (y^2)^((p+1)/4) would've been sqrt(y) not y. It's like in algebra how you apply the first sqrt and then you have (y)^((p+1)/2).

But apparently the p+1 is to ensure that modulus is zero, i.e. (p+1) % 4 = 0, and then the division by 4 is done. So how is dividing this shifted prime by 4 equivalent to a square root?

Is it because we are now taking the modular power by a whole number? Then why 4 specifically and not some other number?
It all comes from Fermat's little theorem:
yp = y (mod p)
then
yp+1 = y2 (mod p)
y(p+1)/4 = y1/2 (mod p)

You could do similar stuff for cube roots as well:
xp+2 = x3 (mod p)
x(p+2)/9 = x1/3 (mod p)

pooya87
Legendary
*
Offline Offline

Activity: 3444
Merit: 10558



View Profile
August 03, 2022, 02:28:54 PM
 #5

Code:
    // It's subtracting recID from Y here, i.e. it is effectively subtracting 0 or 1 from it (ignoring the higher bit) - NotATether
    var y = beta.subtract(recid).isEven() ? beta : p.subtract(beta);
I gotta admit, that is weird! Maybe it is done like this to shorten the code and not need multiple branches.
Since the result of subtraction (beta-recid) is not used anywhere else, it is just a temporary variable used inside the ternary conditional operator to check if computed y (or beta) is even or not.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
witcher_sense
Legendary
*
Offline Offline

Activity: 2338
Merit: 4336

🔐BitcoinMessage.Tools🔑


View Profile WWW
August 03, 2022, 02:43:09 PM
 #6

Since I barely understand elliptic curve cryptography and can't say something smart, I will simply quote a someone else's answer:

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 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).



█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
j2002ba2
Full Member
***
Offline Offline

Activity: 204
Merit: 437


View Profile
August 03, 2022, 05:31:31 PM
 #7

No look, bitcoinsig.js that is used in the "brainwallet.github.io" sites has this in the verificaiton algo:
verify_message follows this algorithm ECDSA Public key recovery.

The function calling verify_message sets the first byte of signature to 27..34.
This corresponds to the eight cases, two for x (x or x+n, bit zero of recid), and two for y (y or p-y, bit 1, zero for even y, one for odd y), uncompressed or compressed (if first byte is >= 31).

At the end it returns the address of decoded public key.

You could see how Bitcoin Core does sign here
NotATether (OP)
Legendary
*
Offline Offline

Activity: 1596
Merit: 6735


bitcoincleanup.com / bitmixlist.org


View Profile WWW
August 03, 2022, 05:44:41 PM
Last edit: August 04, 2022, 03:48:47 AM by NotATether
 #8

It all comes from Fermat's little theorem:
yp = y (mod p)
then
yp+1 = y2 (mod p)
y(p+1)/4 = y1/2 (mod p)

You could do similar stuff for cube roots as well:
xp+2 = x3 (mod p)
x(p+2)/9 = x1/3 (mod p)




Thanks, that's exactly what I needed!

EDIT: in other words, it's not doing (y^2)^(1/4), but actually ((y^2)^2)*1/4. The variable is the square of y, but we take the temporary square of it before we take its 4th root (sqrt of sqrt).

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!