Created
November 17, 2018 03:06
-
-
Save minhtt159/896b4ffdcb161e5841361371324a8408 to your computer and use it in GitHub Desktop.
ECC - Return
This file contains 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
p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff | |
a = p-3 | |
b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b | |
r = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 | |
x = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 | |
y = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 | |
class CurveFp(object): | |
def __init__(self, p, a, b): | |
assert 3 == p % 4 | |
self.__p = p | |
self.__a = a | |
self.__b = b | |
def p(self): | |
return self.__p | |
def a(self): | |
return self.__a | |
def b(self): | |
return self.__b | |
def contains_point(self, x, y): | |
return (y * y - (x * x * x + self.__a * x + self.__b)) % self.__p == 0 | |
def complete_point(self, x): | |
y = square_roots(x * x * x + self.__a * x + self.__b, self.__p) | |
y = y[0] | |
if self.contains_point(x, y): | |
return Point(self, x, y) | |
else: | |
return INFINITY | |
class Point(object): | |
def __init__(self, curve, x, y, order=None): | |
self.__curve = curve | |
self.__x = x | |
self.__y = y | |
self.__order = order | |
if order: | |
assert self * order == INFINITY | |
def __add__(self, other): | |
if other == INFINITY: | |
return self | |
if self == INFINITY: | |
return other | |
assert self.__curve == other.__curve | |
if self.__x == other.__x: | |
if (self.__y + other.__y) % self.__curve.p() == 0: | |
return INFINITY | |
else: | |
return self.double() | |
p = self.__curve.p() | |
l = ((other.__y - self.__y) * inverse_mod(other.__x - self.__x, p)) % p | |
x3 = (l * l - self.__x - other.__x) % p | |
y3 = (l * (self.__x - x3) - self.__y) % p | |
return Point(self.__curve, x3, y3) | |
def __mul__(self, other): | |
def leftmost_bit(x): | |
assert x > 0 | |
result = 1L | |
while result <= x: | |
result = 2 * result | |
return result / 2 | |
e = other | |
if self.__order: | |
e = e % self.__order | |
if e == 0: | |
return INFINITY | |
if self == INFINITY: | |
return INFINITY | |
assert e > 0 | |
e3 = 3 * e | |
negative_self = Point(self.__curve, self.__x, -self.__y, self.__order) | |
i = leftmost_bit(e3) / 2 | |
result = self | |
while i > 1: | |
result = result.double() | |
if (e3 & i) != 0 and (e & i) == 0: | |
result = result + self | |
if (e3 & i) == 0 and (e & i) != 0: | |
result = result + negative_self | |
i = i / 2 | |
return result | |
def __rmul__(self, other): | |
return self * other | |
def __str__(self): | |
if self == INFINITY: | |
return "infinity" | |
return "(%d,%d)" % (self.__x, self.__y) | |
def double(self): | |
if self == INFINITY: | |
return INFINITY | |
p = self.__curve.p() | |
a = self.__curve.a() | |
l = ((3 * self.__x * self.__x + a) * | |
inverse_mod(2 * self.__y, p)) % p | |
x3 = (l * l - 2 * self.__x) % p | |
y3 = (l * (self.__x - x3) - self.__y) % p | |
return Point(self.__curve, x3, y3) | |
def x(self): | |
return self.__x | |
def y(self): | |
return self.__y | |
def curve(self): | |
return self.__curve | |
def order(self): | |
return self.__order | |
def inverse_mod(a, m): | |
if a < 0 or m <= a: | |
a = a % m | |
c, d = a, m | |
uc, vc, ud, vd = 1, 0, 0, 1 | |
while c != 0: | |
q, c, d = divmod(d, c) + (c, ) | |
uc, vc, ud, vd = ud - q * uc, vd - q * vc, uc, vc | |
assert d == 1 | |
if ud > 0: | |
return ud | |
else: | |
return ud + m | |
#square roots for moduli 3 (mod 4) | |
def square_roots(a, m): | |
s = pow(a, (m + 1) / 4, m) | |
return s, m - s | |
INFINITY = Point(None, None, None) | |
def urandom(size): | |
return '\x04'*size; # chosen by fair dice roll | |
# guaranteed to be random | |
class Signature(object): | |
def __init__(self, r, s): | |
self.r = r | |
self.s = s | |
def __str__(self): | |
return '(' + str(self.r) + ',' + str(self.s) + ')' | |
class Public_key(object): | |
def __init__(self, generator, point): | |
self.curve = generator.curve() | |
self.generator = generator | |
self.point = point | |
n = generator.order() | |
if not n: | |
raise RuntimeError, "Generator point must have order." | |
def verifies(self, hash_digest, signature): | |
try: | |
G = self.generator | |
n = G.order() | |
r = signature.r | |
s = signature.s | |
if r < 1 or r > n-1: return False | |
if s < 1 or s > n-1: return False | |
c = inverse_mod(s, n) | |
u1 = (hash_digest * c) % n | |
u2 = (r * c) % n | |
xy = u1 * G + u2 * self.point | |
v = xy.x() % n | |
return v == r | |
except: | |
return False | |
def __str__(self): | |
return str(self.point) | |
class Private_key(object): | |
def __init__(self, public_key, secret_multiplier): | |
self.public_key = public_key | |
self.secret_multiplier = secret_multiplier | |
def sign(self, hash_digest, k): | |
G = self.public_key.generator | |
n = G.order() | |
k = k % n | |
p1 = k * G | |
r = p1.x() | |
if r == 0: raise RuntimeError, "amazingly unlucky random number r" | |
s = ( inverse_mod(k, n) * (hash_digest + (self.secret_multiplier * r) % n) ) % n | |
if s == 0: raise RuntimeError, "amazingly unlucky random number s" | |
return Signature(r, s) |
This file contains 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
from ec import * | |
from hashlib import sha1 as H | |
import sys | |
import string | |
from Crypto.Util.number import bytes_to_long | |
class Unbuffered(object): | |
def __init__(self, stream): | |
self.stream = stream | |
def write(self, data): | |
self.stream.write(data) | |
self.stream.flush() | |
def writelines(self, datas): | |
self.stream.writelines(datas) | |
self.stream.flush() | |
def __getattr__(self, attr): | |
return getattr(self.stream, attr) | |
sys.stdout = Unbuffered(sys.stdout) | |
# Secret key | |
flag = open('flag.txt','r').read().replace('SVATTT2018{','').replace('}','') | |
secret = int(flag, 16) | |
assert secret < r | |
# submit SVATTT2018{flag} | |
# The curve | |
E = CurveFp(p, a, b) | |
assert E.contains_point(x, y) | |
# Base point | |
P = Point(E, x, y, r) | |
errorMsg = "This is not a pwn challenge, you're pissing me off" | |
def check(number): | |
if not all(c in string.digits for c in number): | |
return False | |
number = int(number) | |
if number < 0 or number >= p: | |
return False | |
return True | |
def readpoint(msg): | |
try: | |
inp = raw_input(msg) | |
Px, Py = inp.replace(' ','').split(',') | |
if not check(Px) or not check(Py): | |
return False | |
Px, Py = int(Px), int(Py) | |
return Point(E, Px, Py, r) | |
except: | |
return False | |
def readsignature(msg): | |
try: | |
inp = raw_input(msg) | |
_r, s = inp.replace(' ','').split(',') | |
if not check(_r) or not check(s): | |
return False | |
_r, s = int(_r), int(s) | |
return Signature(_r, s) | |
except: | |
return False | |
def sendpublickey(pk, prvKey): | |
# send public key | |
print 'Public key', str(pk) | |
# send signature | |
k = bytes_to_long(urandom(32)) | |
hash_digest = bytes_to_long(H(str(pk)).digest()) | |
try: | |
print 'Signature', prvKey.sign(hash_digest, k) | |
return True | |
except: | |
print 'Try again!' | |
return False | |
if __name__ == '__main__': | |
inp = raw_input('Suggested base point: ' + str(P) + '\nAccept?[Y/n] ').lower() | |
if inp == 'n' or inp == 'no': | |
while 1: | |
Q = readpoint('Base Point: ') | |
if Q == False: | |
Q = P | |
sP = Q * secret | |
pubKey = Public_key(Q, sP) | |
prvKey = Private_key(pubKey, secret) | |
if not sendpublickey(sP, prvKey): | |
continue | |
inp = raw_input('Accept?[Y/n] ').lower() | |
if inp == 'n' or inp == 'no': | |
continue | |
break | |
else: | |
sP = P * secret | |
pubKey = Public_key(P, sP) | |
prvKey = Private_key(pubKey, secret) | |
sendpublickey(sP, prvKey) | |
print 'Welcome to the admin panel' | |
while 1: | |
cmd = raw_input('Cmd: ') | |
hash_digest = bytes_to_long(H(str(cmd)).digest()) | |
# print prvKey.sign(hash_digest, bytes_to_long(urandom(32))) | |
signature = readsignature('Signature: ') | |
if signature == False: | |
print errorMsg | |
break | |
if pubKey.verifies(hash_digest, signature): | |
exec(cmd) | |
else: | |
print errorMsg | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment