Author

Topic: Secp256k1 returning half of 3G? (Read 146 times)

member
Activity: 239
Merit: 53
New ideas will be criticized and then admired.
December 17, 2024, 12:48:57 PM
#9
Don't get overwhelmed by the elliptic curve, first look at how it works from the private key perspective.
In decimal, if we have 3 divided by 2, the result is 1.5.

However, in the finite field that Secp256k1 uses, we don't use fractions. Instead, we find the modular inverse of 2 and multiply it by 3.

This operation is performed modulo n, which is the order of the field,

yielding: 57896044618658097711785492504343953926418782139537452191302581570759080747170

Code:
def mod_inv(a, n):
    t, n_t = 0, 1
    r, n_r = n, a
    while n_r != 0:
        Q = r // n_r
        t, n_t = n_t, t - Q * n_t
        r, n_r = n_r, r - Q * n_r
    if r > 1:
        raise ValueError(f"{a} has no modular inverse")
    if t < 0:
        t = t + n
    return t



target = 3

Div = 2

N = 115792089237316195423570985008687907852837564279074904382605163141518161494337

a = mod_inv(Div, N)
b = target * a % N

print("decimal:", target / Div)
print("private key:", b)
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
December 17, 2024, 11:59:00 AM
#8
Quote
But if you're using libsecp256k1 then you don't actually have to worry about constructing an N or a P for modulus. The library will reduce the values automatically.
How does the library "know" when to do regular inverse double 16G-->8G and when to do 7G---->SomethingG...
I am asking because every dot looks like any other dot. You do not know if multiplier*G is odd or even

(I was going to write a longer reply, but my iPhone screen glitched and I lost the reply force restarting. Sorry.)

Basically the types it uses are large enough to carry some overflow before it eventually runs out of bits.

BTW: the library is for point operations, so it only does mod P. There's another library, piggypiggy/fp256 on Github, for modular arithmetic with arbitrary modulus.
copper member
Activity: 821
Merit: 1992
December 17, 2024, 09:46:42 AM
#7
Quote
How does the library "know" when to do regular inverse double 16G-->8G and when to do 7G---->SomethingG...
That "something" is just "3.5". The choice of base point doesn't matter, if you can halve a point G, then you can halve every other point, in exactly the same way.

For example:
Code:
03 E60FCE93B59E9EC53011AABC21C23E97B2A31369B87A5AE9C44EE89E2A6DEC0A    16*G
02 2F01E5E15CCA351DAFF3843FB70F3C2F0A1BDD05E5AF888A67784EF3E10A2A01     8*G
02 5CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC     7*G
03 592152C398D6C719636A03A6DAD64246A5A6814AA62C156B0CE5332F6759B031   3.5*G
If you take "3.5*G", and double it, then you will get "7*G". If you want to halve a point, you can just multiply it by "1/2", which is equal to 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1 in secp256k1.

More than that: not only you can halve a point, but you can also get "one third", "one fifth", and "1/x" for any x-value, in range from 1 to 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140.

For example:
Code:
1/2=7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1
1/3=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81
1/5=66666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7
02 00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C63   (1/2)*G
03 4C7FF4F2BA8603998339C8E42675CEAC23EF2E9623FDB260B24B1C944A2EA1A9   (1/3)*G
03 A3C9D9DE2BA89D61C63AF260BE9759D752B8BFEF56EE41B2DAB2B99871AF38A8   (1/5)*G
And then, if you try to multiply 034C7FF4F2BA8603998339C8E42675CEAC23EF2E9623FDB260B24B1C944A2EA1A9 by three, you will get G, as a result.

To better understand it, you can try some smaller elliptic curve, for example where "p=79, n=67, base=(1,18)". Then, it will be easier to understand, that "1/2=34" in case of this smaller curve, in exactly the same way, as "1/2=7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1" in case of secp256k1. Because "34*2=68=67+1". And that's how you can calculate the inversion: if you multiply "1/x" by "x", then you should get exactly "1", if you compute it modulo "n". It is that simple.

Quote
You do not know if multiplier*G is odd or even
Exactly. And that's the reason, why elliptic curves are safe. In other case, if it would be possible to know, if a given distance between two points is "odd or even", then it would be trivial to break every possible private key.
jr. member
Activity: 45
Merit: 11
December 17, 2024, 09:02:52 AM
#6
Quote
But if you're using libsecp256k1 then you don't actually have to worry about constructing an N or a P for modulus. The library will reduce the values automatically.
How does the library "know" when to do regular inverse double 16G-->8G and when to do 7G---->SomethingG...
I am asking because every dot looks like any other dot. You do not know if multiplier*G is odd or even
?
Activity: -
Merit: -
December 17, 2024, 08:17:01 AM
#5
“To observe that elliptic curve points do not have fractional values, which can cause confusion when attempting to divide or halve a point like 3G. In elliptic curve cryptography (ECC), ‘halving’ a point is done through modular arithmetic, specifically the modular inverse .

For a point such as 3G, you would compute half of it by multiplying it by the modular inverse of 2 (mod N), where N is the curve order. This approach is based on Fermat’s Little Theorem, which allows for efficient computation of the inverse and modular operations .

In secp256k1, for instance, this can be done by calculating modinv(2) * 3G mod N, where N is the curve’s order. This ensures that operations remain within the field defined by the curve, ensuring consistency and avoiding errors that might arise from attempting to directly divide curve points .

By leveraging modular arithmetic, division of points on elliptic curves is avoided and operations stay within the correct field. This avoids potential pitfalls, while still allowing the manipulation of multiples of the base point, G.”
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
December 17, 2024, 07:38:52 AM
#4
You need to calculate modinv(2, N) and then multiply that by 3G to get half of it.

When you're calculating half of 3G like this, you are technically calculating (3*(2**(N-2)) mod N)G because of Fermat's little theorem.

Shortcut: 1/2 = modinv(2) = (N+1) / 2 because N is odd = 2**(-1) = 1 * 2**(-1) = 2**(N-1) * 2**(-1) = 2**(N-2) etc

My apologies, the private key operations are mod N, not mod P. Not sure why you had to copy half of my post though.

But if you're using libsecp256k1 then you don't actually have to worry about constructing an N or a P for modulus. The library will reduce the values automatically. All you have to do is use the secp256k1_fe types which you can find in the source code. Those functions are not exported though, so you're not going to find them in a compiled include header.
member
Activity: 165
Merit: 26
December 17, 2024, 04:08:53 AM
#3
You need to calculate modinv(2, N) and then multiply that by 3G to get half of it.

When you're calculating half of 3G like this, you are technically calculating (3*(2**(N-2)) mod N)G because of Fermat's little theorem.

Shortcut: 1/2 = modinv(2) = (N+1) / 2 because N is odd = 2**(-1) = 1 * 2**(-1) = 2**(N-1) * 2**(-1) = 2**(N-2) etc
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
December 16, 2024, 11:25:17 PM
#2
You need to calculate modinv(2G) and then multiply that by 3G to get half of it.

There is no such thing as fractions of a curve point, so "division" is emulated by using modinv and multiplication.

When you're calculating half of 3G like this, you are technically calculating (3*(p-2))G (mod p) because of Fermat's little theorem.

p may be a large number, but you don't have to actually add G that many times, you can convert 3*(p-2) into a bitwise (256-bits) representation, calculate G, 2G, 4G, 8G, 16G, 32G, 64G, 128G, 256G (which is 2^8G btw), 512G, ... (2^255)G and then using the distributive property of addition, add the parts together that make the coefficient equal to 3*(p-2).
jr. member
Activity: 45
Merit: 11
December 16, 2024, 10:16:49 PM
#1
So I am exploring this everything and I am learning a lot about bitcoin technical side and structure and also I am learning to programing at Python...

And I made like simple program where you can add dots on elliptic curve like Q+Q or Q+G and also I made G-Q, X*G and

 I made like Q:1/2 so this code will give me for 8G I will get 4G dot...

But when I did that for 3G I expected some error mistake or something because we do not have 1.5G...

So What am I doing wrong here? How I get the result for 3G... or 5G or any odd number * G

Thank you
Jump to: