def generateRPoints(params): curve = ECCurve(params.a, params.b, params.p, params.n, params.gx, params.gy) pointG = ECPoint(params.gx, params.gy) pointQ = ECPoint(params.qx, params.qy) rPoints = [] for i in range(NUM_R_POINTS): a = random.randint(2, curve.n) b = random.randint(2, curve.n) aG = curve.multiply(a, pointG) bQ = curve.multiply(b, pointQ) r = curve.add(aG, bQ) e = {} e['a'] = a e['b'] = b e['x'] = r.x e['y'] = r.y rPoints.append(e) return rPoints
def main(): if len(sys.argv) != 8: print("Usage: a1 b1 a2 b2 x y job") exit() a1 = parseInt(sys.argv[1]) b1 = parseInt(sys.argv[2]) a2 = parseInt(sys.argv[3]) b2 = parseInt(sys.argv[4]) endX = parseInt(sys.argv[5]) endY = parseInt(sys.argv[6]) name = sys.argv[7] try: ecdl.loadConfig("config/config.json") except: print("Error opening config: " + sys.exc_info[0]) sys.exit(1) ctx = ecdl.loadContext(name) curve = ctx.curve rPoints = ctx.rPoints dBits = ctx.params.dBits # Get G and Q g = ECPoint(ctx.params.gx, ctx.params.gy) q = ECPoint(ctx.params.qx, ctx.params.qy) endPoint = ECPoint(endX, endY) # Calculate starting points p1Start = curve.add(curve.multiply(a1, g), curve.multiply(b1, q)) p2Start = curve.add(curve.multiply(a2, g), curve.multiply(b2, q)) a1, b1, point1, a2, b2, point2 = findCollision(curve, g, q, a1, b1, p1Start, a2, b2, p2Start, endPoint, rPoints, dBits) if a1 == None: return # Compute private key k = (((a1 - a2) % curve.n) * invm(b2 - b1, curve.n)) % curve.n r = curve.multiply(k, g) print("Q= " + hex(q.x) + " " + hex(q.y)) print("kG = " + hex(r.x) + " " + hex(r.y)) print("") print("k=" + hex(k))
def getLength(curve, startA, startB, startPoint, endPoint, rPoints, dBits): point = startPoint a = startA b = startB points = [] i = 0 length = 1 # We want to terminate the walk if it is statistically too long limit = (2**dBits) * 4 while True: idx = point.x & 0x1f length = length + 1 if point.x == endPoint.x and point.y == endPoint.y: print("Found endpoint") return length break # Increment the point and coefficients r = ECPoint(rPoints[idx]['x'], rPoints[idx]['y']) point = curve.add(point, r) a = (a + rPoints[idx]['a']) % curve.n b = (b + rPoints[idx]['b']) % curve.n if i > limit: print("Walk is too long. Terminating") return -1 return length
def _getWalkLength(self, startA, startB, startPoint): point = startPoint a = startA b = startB i = 0 length = 1 # We want to terminate the walk if it is statistically too long limit = (2**self.params.dBits) * 4 while True: idx = point.x & 0x1f length = length + 1 if point.x == self.endPoint.x and point.y == self.endPoint.y: print("Found endpoint") return length break # Increment the point and coefficients r = ECPoint(self.rPoints[idx]['x'], self.rPoints[idx]['y']) point = self.curve.add(point, r) a = (a + self.rPoints[idx]['a']) % self.curve.n b = (b + self.rPoints[idx]['b']) % self.curve.n if i > limit: print("Walk is too long. Terminating") return -1 return length
def createContext(params, name, email): ctx = ECDLPContext(name) ctx.params = params ctx.rPoints = generateRPoints(ctx.params) Database.createContext(ctx.name, ctx.email, ctx.params, ctx.rPoints) ctx.curve = ECCurve(ctx.params.a, ctx.params.b, ctx.params.p, ctx.params.n, ctx.params.gx, ctx.params.gy) ctx.pointG = ECPoint(ctx.params.gx, ctx.params.gy) ctx.pointQ = ECPoint(ctx.params.qx, ctx.params.qy) ctx.database = Database.getConnection(ctx.name) return ctx
def nextPoint(curve, a, b, point, rPoints): idx = point.x & 0x1f newPoint = curve.add(point, ECPoint(rPoints[idx]['x'], rPoints[idx]['y'])) newA = (a + rPoints[idx]['a']) % curve.n newB = (b + rPoints[idx]['b']) % curve.n return newA, newB, newPoint
def loadContext(name): ctx = ECDLPContext(name) ctx.database = Database.getConnection(ctx.name) ctx.database.open() ctx.rPoints = ctx.database.getRPoints() ctx.params = ctx.database.getParams() ctx.status = ctx.database.getStatus() ctx.solution = ctx.database.getSolution() ctx.collisions = ctx.database.getNumCollisions() ctx.database.close() ctx.curve = ECCurve(ctx.params.a, ctx.params.b, ctx.params.p, ctx.params.n, ctx.params.gx, ctx.params.gy) ctx.pointG = ECPoint(ctx.params.gx, ctx.params.gy) ctx.pointQ = ECPoint(ctx.params.qx, ctx.params.qy) return ctx
def _nextPoint(self, a, b, point): idx = point.x & 0x1f newPoint = self.curve.add( point, ECPoint(self.rPoints[idx]['x'], self.rPoints[idx]['y'])) newA = (a + self.rPoints[idx]['a']) % self.curve.n newB = (b + self.rPoints[idx]['b']) % self.curve.n return newA, newB, newPoint
def checkForRobinHood(curve, start, end, start2, rPoints): point = start count = 0 while True: idx = point.x & 0x1f if point.x == start2.x and point.y == start2.y: return True if point.x == end.x and point.y == end.y: return False point = curve.add(point, ECPoint(rPoints[idx]['x'], rPoints[idx]['y']))
def keygen(): # use the secp256k1 curve p = int('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16) a = 0 b = 7 g = ECPoint(int('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), int('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16)) G = EllipticCurve(p, g, a, b) # generate private key x = randint(1, p) h = G.mul(g, x) return (x, G, g, p, h)
def __init__(self, params, rPoints, a1, b1, a2, b2, endPoint): # Get params self.params = params self.a1 = a1 self.b1 = b1 self.a2 = a2 self.b2 = b2 self.endPoint = endPoint self.rPoints = rPoints # Set up curve self.curve = ECCurve(params.a, params.b, params.p, params.n, params.gx, params.gy) # Compute starting points g = ECPoint(self.params.gx, self.params.gy) q = ECPoint(self.params.qx, self.params.qy) self.point1 = self.curve.add(self.curve.multiply(a1, g), self.curve.multiply(b1, q)) self.point2 = self.curve.add(self.curve.multiply(a2, g), self.curve.multiply(b2, q))
def _isRobinHood(self): currentPoint = self.point1 count = 0 while True: idx = currentPoint.x & 0x1f if currentPoint.x == self.point2.x and currentPoint.y == self.point2.y: return True if currentPoint.x == self.endPoint.x and currentPoint.y == self.endPoint.y: return False # Iterate to next point currentPoint = self.curve.add( currentPoint, ECPoint(self.rPoints[idx]['x'], self.rPoints[idx]['y']))
def solveNextCollision(ctx): ctx.database.open() coll = ctx.database.getNextCollision() ctx.database.close() if coll == None: return solver = RhoSolver(ctx.params, ctx.rPoints, coll['a1'], coll['b1'], coll['a2'], coll['b2'], ECPoint(coll['x'], coll['y'])) solver.solve() ctx.database.open() if solver.solved == True: print("The solution is " + util.toHex(solver.k)) ctx.database.setSolution(solver.k) ctx.database.updateCollisionStatus(coll['id'], 'T') else: ctx.database.updateCollisionStatus(coll['id'], 'F') ctx.database.close()
def submit_points(id): # Get the context ctx = getContext(id) if ctx == None: print("Count not find context " + id) return "", 404 # Check if the job is still running if ctx.status == "stopped": return "", 500 content = request.json modulus = pow(2, ctx.params.dBits) points = [] # Verify all points for i in range(len(content)): a = util.parseInt(content[i]['a']) b = util.parseInt(content[i]['b']) x = util.parseInt(content[i]['x']) y = util.parseInt(content[i]['y']) length = content[i]['length'] # Verify the exponents are within range if a <= 0 or a >= ctx.curve.n or b <= 0 or b >= ctx.curve.n: print("Invalid exponents:") print(str(a)) print(str(b)) return "", 400 # Verify point is valid if x < 0 or x >= ctx.curve.p or y < 0 or y >= ctx.curve.p: print("Invalid point:") print("X: " + str(x)) print("y: " + str(y)) return "", 400 # Check that the x value has the correct number of 0 bits if x % modulus != 0: print("[" + hex(x) + "," + hex(y) + "]") print("Not distinguished point! Rejecting!") return "", 400 # Verify aG = bQ = (x,y) endPoint = ECPoint(x, y) if verifyPoint(ctx.curve, ctx.pointG, ctx.pointQ, a, b, endPoint) == False: print("Invalid point!") print(content[i]) print("") return "", 400 # Append to list dp = {} dp['a'] = a dp['b'] = b dp['x'] = x dp['y'] = y dp['length'] = length points.append(dp) # Connect to database ctx.database.open() # Write list to database collisions = ctx.database.insertMultiple(points) # If there are any collisions, add them to the collisions table if collisions != None: for c in collisions: dp = ctx.database.get(c['x'], c['y']) print("==== FOUND COLLISION ====") print("a1: " + hex(c['a'])) print("b1: " + hex(c['b'])) print("length: " + util.intToString(c['length'])) print("") print("a2: " + hex(dp['a'])) print("b2: " + hex(dp['b'])) print("length: " + util.intToString(dp['length'])) print("") print("x: " + hex(c['x'])) print("y: " + hex(c['y'])) ctx.database.insertCollision(c['a'], c['b'], c['length'], dp['a'], dp['b'], dp['length'], c['x'], c['y']) ctx.database.close() return ""