Path: blob/master/Discrete-Logarithm-Problem/Elliptic-Curve-DLP/Algo-Pollard-Rho/Challenges/Multiplayer-2/server.sage
1403 views
import asyncore, socket, json, sqlite3, time12FLAG1 = "flag{XXXXXXXXXXX}"3POINT_TRESHOLD = 20045def json_response(code, additional_parameter=""):6response_codes = {70 : "Point added",81 : "Collision found",92 : "Point already included",103 : 'Wrong input format. Please provide a string like this: {"x": val, "y": val, "c": val, "d": val, "groupID": val})',114 : "Value mismatch! X != c*P + d*Q",125 : "Server Error"13}14return '{"Response": "%d", "Message": "%s"%s}' % (code, response_codes[code], additional_parameter)151617# Teams should choose a non-guessable groupID18def get_response(x, y, c, d, groupID):19# open connection to database20conn = sqlite3.connect("points.db")21conn.row_factory = sqlite3.Row22conn_cursor = conn.cursor()2324# convert sage integers to string to avoid "Python int too large for SQLite INTEGER"25x = str(x)26y = str(y)27c = str(c)28d = str(d)2930# Select records that map to the same X value31conn_cursor.execute("SELECT * FROM points WHERE x = :x", {"x": x})32query = conn_cursor.fetchall()3334# No record found -> Point is not yet included35if len(query) == 0:36# Insert point into database37conn_cursor.execute("INSERT INTO points (x, y, c, d, groupID) VALUES (?, ?, ?, ?, ?)",38(x, y, c, d, groupID))39# Get number of points added by this group40conn_cursor.execute("SELECT x FROM points WHERE groupID = :gID", {"gID": groupID})41points_found = conn_cursor.fetchall()42add_param = ', "points_found": %d' % len(points_found)43# When they found POINT_TRESHOLD distinguished points and a collision occured, return the colliding values as well44if len(points_found) > POINT_TRESHOLD:45add_param += ', "flag1": "%s"' % FLAG146if server.collision_found:47# compute x from the collision, second flag is just x (not in flag format)48add_param += ', "collision": %s' % (server.collision)49response = json_response(0, add_param)50else:51# One (or more) records found -> check if they have the same exponents52is_included = False53for row in query:54if row["c"] == c and row["d"] == d:55is_included = True56response = json_response(2)57break5859if not is_included:60# Exponents are different -> Collision found, add this point61conn_cursor.execute("INSERT INTO points (x, y, c, d, groupID, collision) VALUES (?, ?, ?, ?, ?, 1)",62(x, y, c, d, groupID))63# Get number of points added by this group64conn_cursor.execute("SELECT x FROM points WHERE groupID = :gID", {"gID": groupID})65points_found = conn_cursor.fetchall()66add_param = ', "points_found": %d' % len(points_found)67# add collision68server.collision_found = True69server.collision = '{"c_1": %s, "d_1": %s, "c_2": %s, "d_2": %s}' % (c, d, row["c"], row["d"])70if len(points_found) > POINT_TRESHOLD:71add_param += ', "collision": %s' % (server.collision)72else:73add_param += ', "collision": "collision found but not enough distinguished points submitted yet"'7475response = json_response(1, add_param + ', "c": %s, "d": %s' % (row["c"], row["d"]))7677# close db connection and return response78conn.commit()79conn_cursor.close()80conn.close()81return response828384class DLogHandler(asyncore.dispatcher_with_send):8586def handle_read(self):87try:88json_data = self.recv(8192)89if not json_data:90return9192data = json.loads(json_data)93# check if the format is correct94if not ("x" in data and "y" in data and "c" in data and "d" in data and "groupID" in data):95response = json_response(3)96else:97c = Integer(data["c"])98d = Integer(data["d"])99x = Integer(data["x"])100y = Integer(data["y"])101X = E((x, y))102if X == c*P + d*Q:103response = get_response(data["x"], data["y"], data["c"], data["d"], data["groupID"])104else:105print("expected %s = %d*%s + %d*%s, but got %s" % (c*P + d*Q, c, P, d, Q, X))106response = json_response(4)107108self.send(response)109110except Exception as e:111response = json_response(5, ', "Error Message": "%s"' % e)112113114class Server(asyncore.dispatcher_with_send):115116def __init__(self, host, port):117asyncore.dispatcher.__init__(self)118self.create_socket(socket.AF_INET, socket.SOCK_STREAM)119self.set_reuse_addr()120self.bind((host, port))121self.listen(5)122# variable to store some collision123self.collision_found = False124self.collision = {}125126def handle_accept(self):127pair = self.accept()128if pair is not None:129sock, addr = pair130print("incoming connection from %s" % repr(addr))131DLogHandler(sock)132133134if __name__ == '__main__':135136load("parameters.sage")137server = Server(serverAdress, serverPort)138asyncore.loop()139140141