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
| import os from hashlib import sha256 from Crypto.Cipher import AES from Crypto.Util.Padding import pad
FLAG = b'test'
a,b=82 ,57 p = 2**a * 3**b - 1 Fp2.<i> = GF(p^2, modulus=x^2+1) R.<x> = PolynomialRing(Fp2)
E_start = EllipticCurve(Fp2, [0,6,0,1,0])
E_start.set_order((p+1)^2)
def get_basis(E, l): n = (p+1) // l return (n*G for G in E.gens())
P2, Q2 = get_basis(E_start, 2**a) P3, Q3 = get_basis(E_start, 3**b)
bobs_key = randint(0,3**b-1)
KB = P3 + bobs_key*Q3
phiB = E_start.isogeny(KB, algorithm="factored")
EB = phiB.codomain()
EB.set_order((p+1)**2, num_checks=0)
PB, QB = phiB(P2), phiB(Q2)
alices_key = randint(0,2**a-1)
KA = P2 + alices_key*Q2
phiA = E_start.isogeny(KA, algorithm="factored")
EA = phiA.codomain()
EA.set_order((p+1)**2, num_checks=0)
PA, QA = phiA(P3), phiA(Q3)
shared_kernel_B = PA + bobs_key * QA
phi_shared_B = EA.isogeny(shared_kernel_B, algorithm="factored")
E_shared_B = phi_shared_B.codomain()
shared_j = E_shared_B.j_invariant()
key = sha256(str(shared_j).encode()).digest() iv = os.urandom(16) cipher = AES.new(key, AES.MODE_CBC, iv) ciphertext = cipher.encrypt(pad(FLAG, 16))
def point_to_list(P): return [int(c) for c in P[0].polynomial()] + [int(c) for c in P[1].polynomial()]
def fp2_to_list(x): return [int(c) for c in x.polynomial()]
bob_raw = [] bob_raw += fp2_to_list(EB.a4()) bob_raw += fp2_to_list(EB.a6())
bob_raw += point_to_list(PB) bob_raw += point_to_list(QB)
alice_raw = [] alice_raw += fp2_to_list(EA.a4()) alice_raw += fp2_to_list(EA.a6()) alice_raw += point_to_list(PA) alice_raw += point_to_list(QA)
state = int(p) def next_rand(): global state state = (state * 1664525 + 1013904223) % 2**32 return state
dim = 12
M_bob = matrix(ZZ, dim, dim) for r in range(dim): for c in range(dim): M_bob[r,c] = (next_rand() % 10 + 10) if r == c else (next_rand() % 5)
Y_bob = vector(ZZ, bob_raw) * M_bob
M_alice = matrix(ZZ, dim, dim) for r in range(dim): for c in range(dim): M_alice[r,c] = (next_rand() % 10 + 10) if r == c else (next_rand() % 5) Y_alice = vector(ZZ, alice_raw) * M_alice
output = { "params": {"a": a, "b": b}, "points": { "Pa": point_to_list(P2), "Qa": point_to_list(Q2), "Pb": point_to_list(P3), "Qb": point_to_list(Q3) }, "bob_obfuscated": [int(x) for x in Y_bob], "alice_obfuscated": [int(x) for x in Y_alice], "iv": iv.hex(), "ciphertext": ciphertext.hex() } print(output)
""" {'params': {'a': 82, 'b': 57}, 'points': {'Pa': [7380850815870338233148512740368733393216750196703188, 5781954610054982624656905099319449213829965338618246, 1486772483200244464773044820638015227748898433862021, 4041742208160696689470310574913121590144200565209905], 'Qa': [2586575241375377553825568347148553107143283928101556, 7320346671385192793231812101943719336977545395447990, 733636809907296631648191211385947621063533411574256, 5605387748200021584999470184847449699679973078488898], 'Pb': [3426033097771937683305003923302157856773113387142756, 985698126496332100172970040944741456419416603351759, 1705990864855260484227941677048030711112818343076291, 2024639615167016143613082316835526849592146176134329], 'Qb': [3210811026802762630650301828332190426691685119105305, 169218263487330523145547468183984807764163462641345, 1011283628296715746489505093400091319095209130170219, 4260482332111897582524427327736011991754995723487706]}, 'bob_obfuscated': [203216789142581305197722930125351051178489832272874948, 103451143990351090548150562828305766374778166367334743, 128385043821113943220154406817301591600434705357425337, 148721712019250874702421429405961145245884308621636284, 107450918943296049650435208380326306041925061431182755, 108464709125122928458164660443532606143146211433427714, 223429435910571460464979624202352016712591253148328955, 158116135335965154112308826699937612715840377818614605, 167803599172317038283177182077091592826307156540816241, 143817839441487927738837134600596555719979620674913418, 186175056475907603625656541033372102161902994275461358, 195952285339273458274453344082354272141798683842481140], 'alice_obfuscated': [183828390298905838118474328843290916454768465327957660, 185807950963310833056459703998531928875591946831486097, 202219550644070674757245934429643890698528180191737908, 214188863260511182820355681072152986957678050102275625, 161269727976229633611717179589472619840461994012715891, 190710353557551571288330244751254081553527339480374966, 136211896733579722427367479142885387075540353041669882, 163011277996214335433775404719035139917392368645665784, 203102808146393180905593010731146445447359500361776599, 131383143356992706106026454760530073612421183793624652, 197453624754216387417629452253283246906315251699375152, 250895715588427247878798824490953369076564145957903096], 'iv': 'e0d8d8692e9c16a4ecfb70c660690a9c', 'ciphertext': 'b07d542002008668e55fba154c8b9cdd11dbc90724ef18cc6868ecc05d27c92b1281c9225e2d231ef4e8d38b7cdd81a2'} """
|