krashfire (OP)
Member

Offline
Activity: 138
Merit: 14
|
 |
January 30, 2026, 01:22:07 PM Last edit: February 02, 2026, 01:42:16 PM by krashfire |
|
originally, the valid signatures were created using a = random b = random r = aG + bQ s = r * modinv(b, N) % N z = a * s (b, N)% N but how do we get to the same r but different s and z? i use 2 different method where i shift the aG and bQ value to get to the same point r without knowing the scalar values of a and b. method 1 was just by shifting points by introducing a random t value. for shift method 1 i had remove the formula to get to b2. and for method 2, i had remove the formula to get to a3. this is for security reasons. ----------------Original Method --------------- a = c32057b132ccc2e4e8316c8890d94414f1272b7852ae31dde5e3c56628adffea b = a0c199016141c4eaf3da12e0f842b87367ca2ec5b516aa34c3be4bca03a1f9fe r = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 s = ad168812c770129297a98bd7174b2b398be9f943fb3f6436b1fc3d5014b8c276 z = c649388570ee23462d0e3dfd949ae74af2d827f057a39cef77164aa02a27239e Sig valid? True
----------------Shifting Method 1---------------
t = 13ce15fa6ffa32f5b5705ed88458fb011135a20770efd8c5aeca4230b9be8ea3 tG = 374a8eba1aa5a9ce5a4eb1715fdb02acdb758e01320a2958db8b8ae972d92562 a2 = d6ee6daba2c6f5da9da1cb6115323f16025ccd7fc39e0aa394ae0796e26c8e8d aG2 = 22d0ade127b4bd233fad6d94292ba8b12c806a09cde89841ab0501f3558afa75 b2Q = c9678036959879a6657f29e38f0f703abab83fa7268cc48d2e435d92dfd7029a r2 = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 same r? True
--- VERIFICATION a2 * G = aG2 --- a2 * G = 22d0ade127b4bd233fad6d94292ba8b12c806a09cde89841ab0501f3558afa75 aG2 = 22d0ade127b4bd233fad6d94292ba8b12c806a09cde89841ab0501f3558afa75 Match? True
--- COMPARE R2 with original R --- R2 = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 R = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 Same? True
----------------Shifting Method 2---------------
b3 = 582fc4c7615923c3d8eb52f459f5cccd4f034da6baf99d8cca11f6f6083eb920 aG3 = bd52365541cb878083beecd6311ba669667f4a24b59c66ab82086f083ecc6a25 b3Q = 6eac120996babe43f54d3666de1408c7b5144c43c77833ea99dbf8828f0d45e2 r3 = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 Same r? True
--- VERIFICATION aG3 + b3Q = R3 --- recomputed R3 = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 Match? True
--- VERIFICATION R3 vs original R --- R3 = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 R = 36194c81caa083d2204c64f3b7e0ebc79d8a29917073e08c2ad2639a5ba963f5 Same? True
does both shifting method gets me to a different a and b values to get to the same r but different s and z? yes. shift 1 , using a certain formula, i could get to different a2 and b2 values.. to get to a2 the formula was a2 = a + t , for shift 2 , i had use a random b3 value and eventually the a3. and as everyone knows same r and different s and z gives u the k nonce and the private key. no point uploading the full formula here. the admins are going to delete them anyways. but i think some of you may figure out soon enough the mathematical linkage that i did not put up. the missing part.. ok. bye.
|
KRASH
|
|
|
cyberzzz
Newbie
Offline
Activity: 9
Merit: 0
|
 |
January 31, 2026, 12:08:38 PM Last edit: January 31, 2026, 12:44:11 PM by cyberzzz |
|
To get double R you need original k value add in original z value itself
s_add = 1 (its up to you) k = (your_k value) z_add = k * s_add
r2 = r1 s2 = s1 + s_add z2 = z1 + z_add
this is impossible to solve for recreating unknown K value
if we want to solve signature in todays technology, lattice attack and polynomials attack but in bruteforce way
Question: is your shifting method same pubkey recovered Y = (R*s-G*m)/r ??
your shifting method is interesting
|
|
|
|
|
krashfire (OP)
Member

Offline
Activity: 138
Merit: 14
|
 |
February 02, 2026, 08:25:46 AM Last edit: February 02, 2026, 01:43:17 PM by krashfire |
|
To get double R you need original k value add in original z value itself
s_add = 1 (its up to you) k = (your_k value) z_add = k * s_add
r2 = r1 s2 = s1 + s_add z2 = z1 + z_add
this is impossible to solve for recreating unknown K value
if we want to solve signature in todays technology, lattice attack and polynomials attack but in bruteforce way
Question: is your shifting method same pubkey recovered Y = (R*s-G*m)/r ??
your shifting method is interesting
If you look at the original formula I mention above, once you get the different a and b, it leads to the same r but different s and z. Typically if we use the conventional method of using same K nonce for the same r but different s and z, we still get different u1 and U2 values. Now I'm just starting from u1 and U2 first. So take the conventional method, get it's u1 and U2 values of two signatures that has the same r but different s and z, compute it's u1 and U2, then u1=a and U2 = b. You get the same signature. But in order for us who don't have the private key or K nonce to get to a valid same pubkey signatures. We use the shifting method. Where after getting the aG and bQ value, we use a random t value to get aG2 = aG + tG and bQ2 = bQ - tG. This gives us the shifting value that leads to the same r. r =aG + bQ and r = aG2 + bQ2. Then to compute it's a and b value. It's just a2 = a + t , that's equal to aG when scalar multiplied. now you are left with looking for b2. the formula to get b2 is ALMOST opposite but similar. then now u have a different a2 and b2 value that leads to the same r but due to its a2 and b2 value being different from a and b value , when the same formula is applied which is s= r * inv(b,n) and z = a * s (b, N) % n, we get the same r value but different s and z value that is valid for the same pubkey
To get double R you need original k value add in original z value itself
s_add = 1 (its up to you) k = (your_k value) z_add = k * s_add
r2 = r1 s2 = s1 + s_add z2 = z1 + z_add
this is impossible to solve for recreating unknown K value
if we want to solve signature in todays technology, lattice attack and polynomials attack but in bruteforce way
Question: is your shifting method same pubkey recovered Y = (R*s-G*m)/r ??
your shifting method is interesting
Hey man... I replied wrongly. I meant to reply that to a person in my inbox. And yes...it does gives the same valid public key.
|
KRASH
|
|
|
krashfire (OP)
Member

Offline
Activity: 138
Merit: 14
|
 |
February 02, 2026, 02:38:29 PM |
|
Here is the code. i had remove in method 1 how to get to b2 and in method 2 starting with random b value obviously for security reasons. from random import SystemRandom
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 G = (Gx, Gy)
pubkey_x = 96953063599923793356065023910106792740284067034392039319548634253844580007549 pubkey_y = 24213599371259323050868340559734230940120001082991520973823206482901563403021 Q = (pubkey_x % P, pubkey_y % P)
def modinv(a, m): if a < 0: a = (a % m + m) % m g, x, _ = extended_gcd(a, m) if g != 1: raise Exception('Modular inverse does not exist') return x % m
def extended_gcd(a, b): if a == 0: return b, 0, 1 gcd, x1, y1 = extended_gcd(b % a, a) x = y1 - (b // a) * x1 y = x1 return gcd, x, y
def point_add(p1, p2): if p1 is None: return p2 if p2 is None: return p1 x1, y1 = p1 x2, y2 = p2 x1, y1 = x1 % P, y1 % P x2, y2 = x2 % P, y2 % P if x1 == x2: if y1 == y2: s = (3 * x1 * x1 * modinv(2 * y1, P)) % P else: return None else: s = ((y2 - y1) * modinv((x2 - x1) % P, P)) % P x3 = (s * s - x1 - x2) % P y3 = (s * (x1 - x3) - y1) % P return (x3, y3)
def point_neg(p): x, y = p return (x, (-y) % P)
def point_mul(point, scalar): result = None current = point while scalar > 0: if scalar & 1: result = point_add(result, current) current = point_add(current, current) scalar >>= 1 return result
def verify_sig(r, s, z): s_inv = modinv(s, N) u1 = (z * s_inv) % N u2 = (r * s_inv) % N u1G = point_mul(G, u1) u2Q = point_mul(Q, u2) P_ver = point_add(u1G, u2Q) if P_ver is None: return False return P_ver[0] % N == r
print("\n==================== ORIGINAL METHOD ====================")
rand = SystemRandom()
a = rand.randrange(1, N) b = rand.randrange(1, N)
aG = point_mul(G, a) bQ = point_mul(Q, b) R = point_add(aG, bQ) r = R[0] % N s = r * modinv(b, N) % N z = a * s % N
print(f"a = {a:064x}") print(f"b = {b:064x}") print(f"r = {r:064x}") print(f"s = {s:064x}") print(f"z = {z:064x}") print(f"Qx = {Q[0]:064x}") print(f"Qy = {Q[1]:064x}")
valid = verify_sig(r, s, z) print(f"Signature Valid? = {valid}")
print("\n==================== METHOD 1: SHIFTING aG & bQ ====================")
t = rand.randrange(1, N) tG = point_mul(G, t)
aG2 = point_add(aG, tG) b2Q = point_add(bQ, point_neg(tG)) R2 = point_add(aG2, b2Q) r2 = R2[0] % N
#calculate a2 and verify a2 = (a + t) % N a2G = point_mul(G, a2)
print(f"t = {t:064x}") print(f"tG = {tG[0]:064x}") print(f"a2 = {a2:064x}") print(f"aG2 = {aG2[0]:064x}") print(f"b2Q = {b2Q[0]:064x}") print(f"r2 = {r2:064x}") print(f"Same r? {r == r2}") print(f"a2*G = a2G = {a2G[0]:064x}")
print(f"Verification") print(f"a2G = aG2 value? {a2G == aG2}")
|
KRASH
|
|
|
cyberzzz
Newbie
Offline
Activity: 9
Merit: 0
|
 |
February 02, 2026, 11:01:20 PM Last edit: Today at 05:55:27 AM by cyberzzz |
|
i study your method a little bit , your method fall into random pubkey Q same r value in signature, if we dont know d or k it is impossible to recreate it my code below, the shifting method 1 is for u1 known and for method 2 is u2 known it is same method even if we randomize u1 and u2 as long as R value is the same but different Q this is not security concern but how security of secp256k1 becomes amazing from fastecdsa import keys, curve from fastecdsa.point import Point
G = curve.secp256k1.G N = curve.secp256k1.q
x = 0xd2c55 Q = x * G d = x
def modinv(a, m): return pow(a, -1, m)
def find_discrete_log_bruteforce(target_point, base_point, max_range=10**8): print(f"Warning: Trying to find discrete log (this only works for small values)...") for x in range(1, max_range): if x * base_point == target_point: return x if x % 1000000 == 0: print(f" Tried up to {x}...") return None
print("="*70) print("ORIGINAL METHOD") print("="*70) a = 0x66c33e700328854cd120d020646019f65fc1c3907c696d1a7e9d2ea5ebd8a7c3 b = 0x4b35921a5cd5b9b07fc792cc552f04c84e15a7287034fbcfd5bbea41887dcacc
aG = a * G bQ = b * Q R = aG + bQ r = R.x s = (r * modinv(b, N)) % N z = (a * s) % N s_inv = modinv(s, N) u1 = (z * s_inv) % N u2 = (r * s_inv) % N
print(f"\nScalar values:") print(f"a = {a:064x}") print(f"b = {b:064x}") print(f"\nSignature components:") print(f"r = {r:064x}") print(f"s = {s:064x}") print(f"z = {z:064x}") print(f"\nVerification values:") print(f"u1 = {u1:064x}") print(f"u2 = {u2:064x}") print(f"\nVerification: u1*G + u2*Q should equal R") verify_point = u1 * G + u2 * Q print(f"u1*G + u2*Q = {verify_point.x:064x}") print(f"Match with r? {verify_point.x == r}")
print("\n" + "="*70) print("SHIFTING METHOD 1") print("="*70) print("Concept: Add a random value T to 'a', adjust 'b' accordingly") print("-"*70)
T = (N-a) +1 T_times_G = T * G
print(f"\nRandom shift value:") print(f"T = {T:064x}") print(f"T * G = {T_times_G.x:064x}")
a2 = (a + T) % N
print(f"\nNew scalar a2:") print(f"a2 = a + T") print(f"a2 = {a2:064x}")
a2_times_G = a2 * G
print(f"a2 * G = {a2_times_G.x:064x}")
b2_times_Q = bQ + (-T_times_G)
print(f"\nAdjusted point b2*Q:") print(f"b2 * Q = b*Q - T*G") print(f"b2 * Q = {b2_times_Q.x:064x}")
b2 = (b - T * modinv(d, N)) % N
print(f"\nCalculated scalar b2:") print(f"b2 = b - T/d") print(f"b2 = {b2:064x}")
verify_b2Q = b2 * Q print(f"\nVerification:") print(f"b2 * Q = {verify_b2Q.x:064x}") print(f"Expected = {b2_times_Q.x:064x}") print(f"Match? {verify_b2Q.x == b2_times_Q.x}")
R2 = a2_times_G + b2_times_Q r2 = R2.x
print(f"\nResulting r value:") print(f"r2 = {r2:064x}") print(f"Same as original r? {r2 == r}")
s2 = (r2 * modinv(b2, N)) % N z2 = (a2 * s2) % N
print(f"\nMethod 1 Signature components:") print(f"s2 = {s2:064x}") print(f"z2 = {z2:064x}")
s2_inv = modinv(s2, N) u1_2 = (z2 * s2_inv) % N u2_2 = (r2 * s2_inv) % N
print(f"\nMethod 1 Verification values:") print(f"u1_2 = {u1_2:064x}") print(f"u2_2 = {u2_2:064x}") print(f"\nVerification: u1_2*G + u2_2*Q should equal R") verify_point2 = u1_2 * G + u2_2 * Q print(f"u1_2*G + u2_2*Q = {verify_point2.x:064x}") print(f"Match with r2? {verify_point2.x == r2}")
print("\n" + "="*70) print("SHIFTING METHOD 2") print("="*70) print("Concept: Choose random 'b3', calculate corresponding 'a3*G'") print("-"*70)
b3 = 0x582fc4c7615923c3d8eb52f459f5cccd4f034da6baf99d8cca11f6f6083eb920
print(f"\nRandom scalar b3:") print(f"b3 = {b3:064x}")
b3_times_Q = b3 * Q
print(f"b3 * Q = {b3_times_Q.x:064x}")
a3_times_G = R + (-b3_times_Q)
print(f"\nCalculated point a3*G:") print(f"a3 * G = R - b3*Q") print(f"a3 * G = {a3_times_G.x:064x}")
a3 = (a + (b - b3) * d) % N
print(f"\nCalculated scalar a3:") print(f"a3 = a + (b - b3)*d") print(f"a3 = {a3:064x}")
verify_a3G = a3 * G print(f"\nVerification:") print(f"a3 * G = {verify_a3G.x:064x}") print(f"Expected = {a3_times_G.x:064x}") print(f"Match? {verify_a3G.x == a3_times_G.x}")
R3 = a3_times_G + b3_times_Q r3 = R3.x
print(f"\nResulting r value:") print(f"r3 = {r3:064x}") print(f"Same as original r? {r3 == r}")
s3 = (r3 * modinv(b3, N)) % N z3 = (a3 * s3) % N
print(f"\nMethod 2 Signature components:") print(f"s3 = {s3:064x}") print(f"z3 = {z3:064x}")
s3_inv = modinv(s3, N) u1_3 = (z3 * s3_inv) % N u2_3 = (r3 * s3_inv) % N
print(f"\nMethod 2 Verification values:") print(f"u1_3 = {u1_3:064x}") print(f"u2_3 = {u2_3:064x}") print(f"\nVerification: u1_3*G + u2_3*Q should equal R") verify_point3 = u1_3 * G + u2_3 * Q print(f"u1_3*G + u2_3*Q = {verify_point3.x:064x}") print(f"Match with r3? {verify_point3.x == r3}")
print("\n" + "="*70) print("SUMMARY - ALL THREE METHODS") print("="*70) print(f"\nAll three methods produce the same r value:") print(f"Original r: {r:064x}") print(f"Method 1 r2: {r2:064x}") print(f"Method 2 r3: {r3:064x}") print(f"All same? {r == r2 == r3}")
print(f"\n" + "-"*70) print("But each method produces DIFFERENT (s, z, u1, u2) values:") print("-"*70)
print(f"\nORIGINAL:") print(f"s = {s:064x}") print(f"z = {z:064x}") print(f"u1 = {u1:064x}") print(f"u2 = {u2:064x}")
print(f"\nMETHOD 1:") print(f"s2 = {s2:064x}") print(f"z2 = {z2:064x}") print(f"u1_2 = {u1_2:064x}") print(f"u2_2 = {u2_2:064x}")
print(f"\nMETHOD 2:") print(f"s3 = {s3:064x}") print(f"z3 = {z3:064x}") print(f"u1_3 = {u1_3:064x}") print(f"u2_3 = {u2_3:064x}")
print(f"\n" + "="*70) print("DIFFERENCES:") print("="*70) print(f"s values different? {s != s2 and s != s3 and s2 != s3}") print(f"z values different? {z != z2 and z != z3 and z2 != z3}") print(f"u1 values different? {u1 != u1_2 and u1 != u1_3 and u1_2 != u1_3}") print(f"u2 values different? {u2 != u2_2 and u2 != u2_3 and u2_2 != u2_3}")
|
|
|
|
|
krashfire (OP)
Member

Offline
Activity: 138
Merit: 14
|
 |
Today at 11:02:46 AM Last edit: Today at 11:33:17 AM by krashfire |
|
you do know that the formula above. r = aG + bQ, gives valid signature for the given public key, right? if it's not valid. meaning if it's not the same pubkey . the signature, even though valid for ecdsa secp256k1 but it would be invalid if the set of signatures doesn't point to the same pubkey? hahaha..ok. if you say so. 🤷♂️.. and stop using AI. ai that we have publicly can only work with what it already knows. not with new formulas. sometimes it works. most of the time, it doesn't.
|
KRASH
|
|
|
cyberzzz
Newbie
Offline
Activity: 9
Merit: 0
|
 |
Today at 03:06:09 PM Last edit: Today at 04:24:32 PM by cyberzzz |
|
you are right, AI has a limit , im comparing the result of the code from ai to my own code that doesnt need d or k but the result is same, as long as we cant solve this equation "doubler = ((z2*s1 - z1*s2) * modinv(r2*(s2-s1),n) % n)" , Ai known only this equation to solve d for doubler equation, we can try collab for this research, im trying different methods including all types of equation that doesnt appear by ai, but as of now the doubler methods is negative
note that in d in my code we can use "kx = (z1 * modinv(s1 - r1, n)) % n" as x and its k both same in all types of equation so we can use this as starting point for d
can i try your full code?? i have missed something?? or its about that we can try our own method that ai doesnt know because it has a limit??
|
|
|
|
|
|