def xadd(x1, z1, x2, z2, x0, z0, n):
return (z0*((x1 - z1)*(x2 + z2) + (x1 + z1)*(x2 - z2))**2 % n)
def zadd(x1, z1, x2, z2, x0, z0, n):
return (x0*((x1 - z1)*(x2 + z2) - (x1 + z1)*(x2 - z2))**2 % n)
def xdouble(x0, z0, n):
return (((x0 + z0)**2)* ((x0 - z0)**2) % n)
def zdouble(x0, z0, a24, n):
return ((4*x0*z0)*((x0 - z0)**2 + a24*4*x0*z0) % n)
# Let elliptic curve be y**2 = x**3 + 6x**2 + x
n = 2425967623052370772757633156976982469681 # Let n be a very large prime
a24 = 2 # a24 = (A + 2)/4 = 2
# Let point one be [2 :: 1] P1
x1 = 2
z1 = 1
print "point 1 -> \nP1 [" + str(x1) + " :: " + str(z1) + "]"
# P2 = 2P1
x2 = xdouble(x1, z1, n)
z2 = zdouble(x1, z1, a24, n)
print "doubling -> \nP2 [" + str(x2) + " :: " + str(z2) + "]"
# P4' = 2P2
x3 = xdouble(x2, z2, n)
z3 = zdouble(x2, z2, a24, n)
print "doubling P2 -> \nP4' [" + str(x3) + " :: " + str(z3) + "]"
#P3 = P1 + P2 = P1 + 2P1 = 3P1
x4 = xadd(x2, z2, x1, z1, x1, z1, n)
z4 = zadd(x2, z2, x1, z1, x1, z1, n)
print "adding P2 + P1 (= 3P1), with difference coordinates P1 (P2 - P1 = 2P1 - P1 = P1) -> \nP3 [" + str(x4) + " :: " + str(z4) + "]"
#P4 = P3 + P1 = 3P1 + P1 = 4P1, 3P1 - P1 = 2P1 ie P2
x5 = xadd(x4, z4, x1, z1, x2, z2, n)
z5 = zadd(x4, z4, x1, z1, x2, z2, n)
print "adding P3 + P1 (= 4P1), with difference coordinates P2 (P3 - P1 = 3P1 - P1 = 2P1 = P2) -> \nP4 [" + str(x5) + " :: " + str(z5) + "]"
print "Clearly P4 should be equal to P4', however this is not the case "
ZGVmIHhhZGQoeDEsIHoxLCB4MiwgejIsIHgwLCB6MCwgbik6CglyZXR1cm4gKHowKigoeDEgLSB6MSkqKHgyICsgejIpICsgKHgxICsgejEpKih4MiAtIHoyKSkqKjIgJSBuKQoKZGVmIHphZGQoeDEsIHoxLCB4MiwgejIsIHgwLCB6MCwgbik6CglyZXR1cm4gKHgwKigoeDEgLSB6MSkqKHgyICsgejIpIC0gKHgxICsgejEpKih4MiAtIHoyKSkqKjIgJSBuKQoJCmRlZiB4ZG91YmxlKHgwLCB6MCwgbik6CglyZXR1cm4gKCgoeDAgKyB6MCkqKjIpKiAoKHgwIC0gejApKioyKSAlIG4pCgkKZGVmIHpkb3VibGUoeDAsIHowLCBhMjQsIG4pOgoJcmV0dXJuICgoNCp4MCp6MCkqKCh4MCAtIHowKSoqMiArIGEyNCo0KngwKnowKSAlIG4pCgojIExldCBlbGxpcHRpYyBjdXJ2ZSBiZSAgeSoqMiA9IHgqKjMgKyA2eCoqMiArIHgKbiA9IDI0MjU5Njc2MjMwNTIzNzA3NzI3NTc2MzMxNTY5NzY5ODI0Njk2ODEgIyBMZXQgbiBiZSBhIHZlcnkgbGFyZ2UgcHJpbWUKYTI0ID0gMiAgIyBhMjQgPSAoQSArIDIpLzQgPSAyCgojIExldCBwb2ludCBvbmUgYmUgWzIgOjogMV0gUDEKeDEgPSAyCnoxID0gMQpwcmludCAicG9pbnQgMSAtPiBcblAxIFsiICsgc3RyKHgxKSArICIgOjogIiArIHN0cih6MSkgKyAiXSIKCiMgUDIgPSAyUDEKeDIgPSB4ZG91YmxlKHgxLCB6MSwgbikKejIgPSB6ZG91YmxlKHgxLCB6MSwgYTI0LCBuKQpwcmludCAiZG91YmxpbmcgLT4gXG5QMiBbIiArIHN0cih4MikgKyAiIDo6ICIgKyBzdHIoejIpICsgIl0iCgojIFA0JyA9IDJQMgp4MyA9IHhkb3VibGUoeDIsIHoyLCBuKQp6MyA9IHpkb3VibGUoeDIsIHoyLCBhMjQsIG4pCnByaW50ICJkb3VibGluZyBQMiAtPiBcblA0JyBbIiArIHN0cih4MykgKyAiIDo6ICIgKyBzdHIoejMpICsgIl0iCgojUDMgPSBQMSArIFAyID0gUDEgKyAyUDEgPSAzUDEKeDQgPSB4YWRkKHgyLCB6MiwgeDEsIHoxLCB4MSwgejEsIG4pCno0ID0gemFkZCh4MiwgejIsIHgxLCB6MSwgeDEsIHoxLCBuKQpwcmludCAiYWRkaW5nIFAyICsgUDEgKD0gM1AxKSwgd2l0aCBkaWZmZXJlbmNlIGNvb3JkaW5hdGVzIFAxIChQMiAtIFAxID0gMlAxIC0gUDEgPSBQMSkgLT4gXG5QMyBbIiArIHN0cih4NCkgKyAiIDo6ICIgKyBzdHIoejQpICsgIl0iCgojUDQgPSBQMyArIFAxID0gM1AxICsgUDEgPSA0UDEsIDNQMSAtIFAxID0gMlAxIGllIFAyCng1ID0geGFkZCh4NCwgejQsIHgxLCB6MSwgeDIsIHoyLCBuKQp6NSA9IHphZGQoeDQsIHo0LCB4MSwgejEsIHgyLCB6MiwgbikKcHJpbnQgImFkZGluZyBQMyArIFAxICg9IDRQMSksIHdpdGggZGlmZmVyZW5jZSBjb29yZGluYXRlcyBQMiAoUDMgLSBQMSA9IDNQMSAtIFAxID0gMlAxID0gUDIpIC0+IFxuUDQgWyIgKyBzdHIoeDUpICsgIiA6OiAiICsgc3RyKHo1KSArICJdIgoKcHJpbnQgIkNsZWFybHkgUDQgc2hvdWxkIGJlIGVxdWFsIHRvIFA0JywgaG93ZXZlciB0aGlzIGlzIG5vdCB0aGUgY2FzZSAiIAo=