Bitcoin Forum
May 11, 2024, 11:47:33 PM *
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
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
1715471253
Hero Member
*
Offline Offline

Posts: 1715471253

View Profile Personal Message (Offline)

Ignore
1715471253
Reply with quote  #2

1715471253
Report to moderator
1715471253
Hero Member
*
Offline Offline

Posts: 1715471253

View Profile Personal Message (Offline)

Ignore
1715471253
Reply with quote  #2

1715471253
Report to moderator
Each block is stacked on top of the previous one. Adding another block to the top makes all lower blocks more difficult to remove: there is more "weight" above each block. A transaction in a block 6 blocks deep (6 confirmations) will be very difficult to remove.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
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!