Last active
October 22, 2024 18:45
-
-
Save Goatghosts/680d4538a3650fcdfe2364c987946f61 to your computer and use it in GitHub Desktop.
I was playing with the constants related to the implementation of endomorphism on the secp256k1 curve, and through strange manipulations, I was able to derive LAMBDA and LAMBDA^2 from B1 and B2. I am not familiar with the original document, so this was a bit of a discovery for me. But overall, there's probably nothing useful here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import copy | |
import random | |
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F | |
a = 0x0000000000000000000000000000000000000000000000000000000000000000 | |
b = 0x0000000000000000000000000000000000000000000000000000000000000007 | |
PLUS_G = ( | |
55066263022277343669578718895168534326250603453777594175500187360389116729240, | |
32670510020758816978083085130507043184471273380659243275938904335757337482424, | |
) | |
N = 115792089237316195423570985008687907852837564279074904382605163141518161494337 | |
A1 = 64502973549206556628585045361533709077 | |
B1 = -303414439467246543595250775667605759171 | |
B1_NEG = 303414439467246543595250775667605759171 | |
A2 = 367917413016453100223835821029139468248 | |
B2 = 64502973549206556628585045361533709077 | |
B3 = N - (B1_NEG + B2) | |
def double_point(point): | |
x, y = point | |
s = ((3 * x * x + a) * pow(2 * y, P - 2, P)) % P | |
x3 = (s * s - 2 * x) % P | |
y3 = (s * (x - x3) - y) % P | |
return (x3, y3) | |
def add_points(point1, point2): | |
if point1 == point2: | |
return double_point(point1) | |
x1, y1 = point1 | |
x2, y2 = point2 | |
s = ((y2 - y1) * pow(x2 - x1, P - 2, P)) % P | |
x3 = (s * s - x1 - x2) % P | |
y3 = (s * (x1 - x3) - y1) % P | |
return (x3, y3) | |
def scalar_mult(scalar, point): | |
current_point = copy.copy(point) | |
bits = bin(scalar)[2:] | |
for bit in bits[1:]: | |
current_point = double_point(current_point) | |
if bit == "1": | |
current_point = add_points(current_point, point) | |
return current_point | |
def base_test(): | |
k = int.from_bytes(random.randbytes(2), "big") | |
k_point = scalar_mult(k, PLUS_G) | |
print("random scalar:", k, "| random point:", k_point) | |
k1 = (B2 * k) % N | |
k2 = (B3 * k) % N | |
k3 = (B1_NEG * k) % N | |
k1_point = scalar_mult(B2, k_point) | |
k2_point = scalar_mult(B3, k_point) | |
k3_point = scalar_mult(B1_NEG, k_point) | |
print("k1_point", k1, k1_point) | |
print("k2_point", k2, k2_point) | |
print("k3_point", k3, k3_point) | |
def check_constants(k, b1, b2, b3): | |
k1 = (b2 * k) % N | |
k2 = (b1 * k) % N | |
k3 = (b3 * k) % N | |
k1_point = scalar_mult(k1, PLUS_G) | |
k2_point = scalar_mult(k2, PLUS_G) | |
k3_point = scalar_mult(k3, PLUS_G) | |
assert k1_point[1] == k2_point[1] == k3_point[1] | |
def main(): | |
k = int.from_bytes(random.randbytes(32), "big") | |
b1 = B1_NEG % N | |
b2 = B2 % N | |
while b1 != 1 and b2 != 1: | |
distance = N // b2 + 1 | |
b1 = b1 * distance % N | |
b2 = b2 * distance % N | |
b3 = N - (b2 + b1) | |
print(f"B1 = {b1} ({b1.bit_length()} bits), B2 = {b2} ({b2.bit_length()} bits)") | |
check_constants(k, b1, b2, b3) | |
print("LAMBDA:", b2) | |
print("LAMBDA (x1):", b3) | |
print("LAMBDA (x2):", b1) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment