1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
| import os import hashlib from Crypto.Util.number import getPrime, isPrime, bytes_to_long, long_to_bytes, sieve_base from Crypto.Cipher import AES from Crypto.Util.Padding import pad from sage.all import * import random import json from Secret import flag
p_ec = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab K_field = GF(p_ec) E = EllipticCurve(K_field, [0, 4]) o = 793479390729215512516507951283169066088130679960393952059283337873017453583023682367384822284289
n1 = 859267 n2 = 52437899 n3 = 28355811
def generate_base_points(): while True: G1 = E.random_point() G2 = E.random_point() G3 = E.random_point() if G1.order() == o and G2.order() == o and G3.order() == o: P1 = (o // n1) * G1 P2 = (o // n2) * G2 P3 = (o // n3) * G3 return G1, G2, G3, P1, P2, P3
G1, G2, G3, P1, P2, P3 = generate_base_points()
while True: a0 = random.randrange(0, o) b0 = random.randrange(0, o) c0 = random.randrange(1, o) K_point = a0 * P1 + b0 * P2 + c0 * G3 if K_point != E(0): break
def encrypt_bytes_with_weil(data_bytes, K_point, P1, P2, P3, G1, G2, G3, o): bits = bin(bytes_to_long(data_bytes))[2:].zfill(len(data_bytes) * 8)
cs = [K_point.xy()] for bit in bits: a = random.randrange(0, o) b = random.randrange(0, o) c = random.randrange(0, o) if bit == '0': C = a * P1 + b * P2 + c * G3 else: C = a * P1 + b * G2 + c * P3 cs.append(C.xy()) return cs
SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ]
RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]
def key_expansion(key): w = [bytes_to_long(key[i:i+4]) for i in range(0, 16, 4)] for i in range(4, 44): temp = w[i-1] if i % 4 == 0: temp = ((temp << 8) & 0xffffffff) | (temp >> 24) temp = (SBOX[temp >> 24] << 24) | (SBOX[(temp >> 16) & 0xff] << 16) | \ (SBOX[(temp >> 8) & 0xff] << 8) | SBOX[temp & 0xff] temp ^= (RCON[i // 4] << 24) w.append(w[i-4] ^ temp) return b"".join([long_to_bytes(x, 4) for x in w[40:]])
def generate_prime(bits): while True: p_sub = 2 for prime in sieve_base: p_sub *= prime if p_sub.bit_length() > bits - 2: break
for k in range(2, 10000, 2): p = p_sub * k + 1 if isPrime(p): return p
p = generate_prime(1024) q = getPrime(1024) n = p * q e = 65537
random_key1 = os.urandom(16) random_key2 = os.urandom(16)
key = bytes([a ^ b for a, b in zip(random_key1, random_key2)])
cs = encrypt_bytes_with_weil(random_key1, K_point, P1, P2, P3, G1, G2, G3, o)
last_key = key_expansion(random_key2) c_rsa = pow(bytes_to_long(last_key), e, n)
iv = os.urandom(16) cipher = AES.new(key, AES.MODE_CBC, iv) c_aes = cipher.encrypt(pad(flag, 16))
print(f"n = {n}") print(f"c_rsa = {c_rsa}") print(f"iv = {iv.hex()}") print(f"c_aes = {c_aes.hex()}")
print(f"p_ec = {p_ec}") print(f"o = {o}") print(f"n1 = {n1}") print(f"n2 = {n2}") print(f"n3 = {n3}") print(f"cs_length = {len(cs)}")
cs_str = str(cs) with open("cs_data.txt", "w") as f: f.write(cs_str)
|