def inverse(self): g, x, y = self.element.egcd(self.modulus) if g.degree() != 0: assert False else: # We can receive any unit (i.e., polynomial of degree 0) as gcd. In this case we have to adjust the result by multiplying with the inverse of the gcd. return self.newElement(x * modinv(g.coeffs[0], self.base))
def solve(): N = 4966306421059967 P = 73176001 Q = 67867967 E = 65537 assert N == P * Q D = modinv(E, (P - 1) * (Q - 1)) key = RSA.construct((N, E, D, P, Q)) return key.exportKey().decode('ascii')
def sign(C, sk, msg): ctx = sha256() ctx.update(msg.encode()) k = int(ctx.hexdigest(), 16) ctx = sha512() ctx.update(msg.encode()) h = int(ctx.hexdigest(), 16) P = k * C.G r = P.x assert r > 0, "Error: cannot sign this message." s = (modinv(k, C.q) * (h + sk * r)) % C.q assert s > 0, "Error: cannot sign this message." return (r, s)
def polyLongDiv(self, rhs): assert isinstance(rhs, ZpXElement) assert self.p == rhs.p, "Polynomials must be from the same ring." assert rhs.degree() > -1 remainder = self quotient = self.newZero() divisorCoeff, divisorDegree = rhs.leadingMonomial() while remainder.degree() >= rhs.degree(): remainderCoeff, remainderDegree = remainder.leadingMonomial() quotLeading = self.newMonomial( remainderCoeff * modinv(divisorCoeff, self.p), remainderDegree - divisorDegree) quotient = quotient + quotLeading remainder = remainder - rhs * quotLeading return quotient, remainder
def solve(): C = 12348446374818124785047003483520927723463037176164584182534831412133180628481657983543696351026847573095962444977455917028098119080577417044024579966437124155634016811401377813838933094471740535056528617449150832316250210717642685426014874295549265720543891802958288398542235894670411933149625284652440953413212310794688880607583457638169630078 N = 73777733563828426821166743687859698789401296904268065723223154794019196925155447471863968833565501516440592954626981887392525580215103640010829661360292651828071519332853318312581688446978063704198253456823934612199636980854860094387209952373707617504589502368238807522652542968313964862007011712816434186396732995632792741802214139582180905539 E = 65537 # http://factordb.com/index.php?query=73777733563828426821166743687859698789401296904268065723223154794019196925155447471863968833565501516440592954626981887392525580215103640010829661360292651828071519332853318312581688446978063704198253456823934612199636980854860094387209952373707617504589502368238807522652542968313964862007011712816434186396732995632792741802214139582180905539 # https://www.alpertron.com.ar/ECM.HTM factors = [ 8934727973, 8956702949, 9076526447, 9574275233, 10199411813, 10356805913, 10362212843, 10760545121, 11457435851, 11484927547, 11491735579, 11587612873, 12401035021, 12788765111, 12934352957, 13460169187, 13479307337, 13701911497, 13904452147, 14231105627, 14514834589, 14653558889, 15032846233, 15099169441, 15247982213, 15273824113, 15429622627, 15485652857, 15604984711, 15945139799, 16201532203, 16505224579, 16747163959, 17016067721 ] reduced = N for x in factors: reduced //= x if reduced > 1: print('msieve -q', reduced) proc = subprocess.run(['msieve', '-q', str(reduced)], stdout=subprocess.PIPE) s = proc.stdout.decode('ascii') trace(s) xs = re.findall(r'^p\d+: (\d+)', s, re.M) for x in xs: x = int(x) factors.append(x) reduced //= x assert reduced == 1 th = reduce(operator.mul, (x - 1 for x in factors), 1) D = modinv(E, th) M = pow(C, D, N) flag = unh(f'{M:x}').decode('ascii') return flag
def verify(C, Q, msg, r, s): if Q.IDENTITY_ELEMENT == Q: return False if not C.is_point_on_curve((Q.x, Q.y)): return False if r < 1 or r > C.q - 1: return False if s < 1 or s > C.q - 1: return False ctx = sha512() ctx.update(msg.encode()) h = int(ctx.hexdigest(), 16) s_inv = modinv(s, C.q) u = h * s_inv % C.q v = r * s_inv % C.q P = u * C.G + v * Q return r == P.x
def solve(host='2019shell1.picoctf.com:41419', port=None): flag_rx = re.compile(r'(picoCTF\{[^\}]+\})') with Interact(host, port) as ii: while True: try: ii.waitfor(r'#### NEW PROBLEM ####\n') except Interact.Error: trace(ii.buf) break data = dict() while True: s = ii.waitfor(r' : |FOLLOWING ####\n') if ':' in s: na = s.split()[0] xa = int(ii.waitfor(r'\n')) data[na] = xa else: wat = ii.waitfor(r'\n').strip() break ii.waitfor(r'FEASIBLE\? \(Y\/N\):') wat = ''.join(sorted(data.keys())) + f'-{wat}' res = dict() if wat == 'pq-n': p, q = data['p'], data['q'] res['n'] = p * q elif wat == 'np-q': n, p = data['n'], data['p'] res['q'] = n // p elif wat == 'en-q': e, n = data['e'], data['n'] decimal.getcontext().prec = len(str(n)) * 20 a = n - (e + 1) b = a * a - 4 * n if b >= 0: b = int(dec(b).sqrt()) q = (a - b) // 2 p = (a + b) // 2 if p * q == n: res['q'] = q res['p'] = p elif wat == 'pq-totient(n)': p, q = data['p'], data['q'] e = (p - 1) * (q - 1) res['totient(n)'] = e elif wat == 'enplaintext-ciphertext': e, n, m = data['e'], data['n'], data['plaintext'] c = pow(m, e, n) res['ciphertext'] = c elif wat == 'ciphertexten-plaintext': e, n, c = data['e'], data['n'], data['ciphertext'] # m = pow(c, d, n) # res['plaintext'] = m elif wat == 'epq-d': e, p, q = data['e'], data['p'], data['q'] d = modinv(e, (p - 1) * (q - 1)) res['d'] = d elif wat == 'ciphertextenp-plaintext': e, n, p, c = data['e'], data['n'], data['p'], data[ 'ciphertext'] q = n // p d = modinv(e, (p - 1) * (q - 1)) m = pow(c, d, n) res['plaintext'] = m else: raise Exception(wat) if res: ii.send('Y') ii.waitfor(r'WHAT YOU GOT\! ###\n') for _ in range(len(res)): q = ii.waitfor(r': ').split(':')[0] ii.send(str(res[q])) else: ii.send('N') x = res['plaintext'] flag = binascii.unhexlify(f'{x:x}').decode('ascii') return flag
def nthRoot(self, n): # TODO: This will not be part of the code we ship out. mOrder = self.base**self.power - 1 assert gcd(mOrder, n) == 1 return self**modinv(n, mOrder)