#!/usr/bin/env python3 import argparse import json import pathlib import re def inv(value: int, prime: int) -> int: return pow(value % prime, -1, prime) def int_to_bytes(value: int) -> bytes: return value.to_bytes(max(1, (value.bit_length() + 7) // 8), "big") def recover_slope(share_a: dict, share_b: dict, prime: int) -> int: x1, y1 = int(share_a["x"]), int(share_a["y"]) x2, y2 = int(share_b["x"]), int(share_b["y"]) return ((y2 - y1) * inv(x2 - x1, prime)) % prime def recover_secret(share: dict, slope: int, prime: int) -> int: return (int(share["y"]) - slope * int(share["x"])) % prime def main() -> int: parser = argparse.ArgumentParser() parser.add_argument( "export", nargs="?", default="../public/escrow_export.json", help="path to escrow_export.json", ) args = parser.parse_args() data = json.loads(pathlib.Path(args.export).read_text()) prime = int(data["field_prime"]) calibration = data["calibration_batch"]["shares"] production_share = data["quarantine_batch"]["shares"][0] slope = recover_slope(calibration[0], calibration[1], prime) secret_int = recover_secret(production_share, slope, prime) flag = int_to_bytes(secret_int).decode() if not re.fullmatch(r"caplag\{[^{}]+\}", flag): raise SystemExit("recovered secret is not a caplag flag") print(flag) return 0 if __name__ == "__main__": raise SystemExit(main())