|
| 1 | +#============================================================================# |
| 2 | +#============================ARCANE CALCULATOR===============================# |
| 3 | +#============================================================================# |
| 4 | + |
| 5 | +import hashlib |
| 6 | +from cryptography.fernet import Fernet |
| 7 | +import base64 |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +# GLOBALS --v |
| 12 | +arcane_loop_trial = True |
| 13 | +jump_into_full = False |
| 14 | +full_version_code = "" |
| 15 | + |
| 16 | +username_trial = "GOUGH" |
| 17 | +bUsername_trial = b"GOUGH" |
| 18 | + |
| 19 | +key_part_static1_trial = "picoCTF{1n_7h3_|<3y_of_" |
| 20 | +key_part_dynamic1_trial = "xxxxxxxx" |
| 21 | +key_part_static2_trial = "}" |
| 22 | +key_full_template_trial = key_part_static1_trial + key_part_dynamic1_trial + key_part_static2_trial |
| 23 | + |
| 24 | +star_db_trial = { |
| 25 | + "Alpha Centauri": 4.38, |
| 26 | + "Barnard's Star": 5.95, |
| 27 | + "Luhman 16": 6.57, |
| 28 | + "WISE 0855-0714": 7.17, |
| 29 | + "Wolf 359": 7.78, |
| 30 | + "Lalande 21185": 8.29, |
| 31 | + "UV Ceti": 8.58, |
| 32 | + "Sirius": 8.59, |
| 33 | + "Ross 154": 9.69, |
| 34 | + "Yin Sector CL-Y d127": 9.86, |
| 35 | + "Duamta": 9.88, |
| 36 | + "Ross 248": 10.37, |
| 37 | + "WISE 1506+7027": 10.52, |
| 38 | + "Epsilon Eridani": 10.52, |
| 39 | + "Lacaille 9352": 10.69, |
| 40 | + "Ross 128": 10.94, |
| 41 | + "EZ Aquarii": 11.10, |
| 42 | + "61 Cygni": 11.37, |
| 43 | + "Procyon": 11.41, |
| 44 | + "Struve 2398": 11.64, |
| 45 | + "Groombridge 34": 11.73, |
| 46 | + "Epsilon Indi": 11.80, |
| 47 | + "SPF-LF 1": 11.82, |
| 48 | + "Tau Ceti": 11.94, |
| 49 | + "YZ Ceti": 12.07, |
| 50 | + "WISE 0350-5658": 12.09, |
| 51 | + "Luyten's Star": 12.39, |
| 52 | + "Teegarden's Star": 12.43, |
| 53 | + "Kapteyn's Star": 12.76, |
| 54 | + "Talta": 12.83, |
| 55 | + "Lacaille 8760": 12.88 |
| 56 | +} |
| 57 | + |
| 58 | + |
| 59 | +def intro_trial(): |
| 60 | + print("\n===============================================\n\ |
| 61 | +Welcome to the Arcane Calculator, " + username_trial + "!\n") |
| 62 | + print("This is the trial version of Arcane Calculator.") |
| 63 | + print("The full version may be purchased in person near\n\ |
| 64 | +the galactic center of the Milky Way galaxy. \n\ |
| 65 | +Available while supplies last!\n\ |
| 66 | +=====================================================\n\n") |
| 67 | + |
| 68 | + |
| 69 | +def menu_trial(): |
| 70 | + print("___Arcane Calculator___\n\n\ |
| 71 | +Menu:\n\ |
| 72 | +(a) Estimate Astral Projection Mana Burn\n\ |
| 73 | +(b) [LOCKED] Estimate Astral Slingshot Approach Vector\n\ |
| 74 | +(c) Enter License Key\n\ |
| 75 | +(d) Exit Arcane Calculator") |
| 76 | + |
| 77 | + choice = input("What would you like to do, "+ username_trial +" (a/b/c/d)? ") |
| 78 | + |
| 79 | + if not validate_choice(choice): |
| 80 | + print("\n\nInvalid choice!\n\n") |
| 81 | + return |
| 82 | + |
| 83 | + if choice == "a": |
| 84 | + estimate_burn() |
| 85 | + elif choice == "b": |
| 86 | + locked_estimate_vector() |
| 87 | + elif choice == "c": |
| 88 | + enter_license() |
| 89 | + elif choice == "d": |
| 90 | + global arcane_loop_trial |
| 91 | + arcane_loop_trial = False |
| 92 | + print("Bye!") |
| 93 | + else: |
| 94 | + print("That choice is not valid. Please enter a single, valid \ |
| 95 | +lowercase letter choice (a/b/c/d).") |
| 96 | + |
| 97 | + |
| 98 | +def validate_choice(menu_choice): |
| 99 | + if menu_choice == "a" or \ |
| 100 | + menu_choice == "b" or \ |
| 101 | + menu_choice == "c" or \ |
| 102 | + menu_choice == "d": |
| 103 | + return True |
| 104 | + else: |
| 105 | + return False |
| 106 | + |
| 107 | + |
| 108 | +def estimate_burn(): |
| 109 | + print("\n\nSOL is detected as your nearest star.") |
| 110 | + target_system = input("To which system do you want to travel? ") |
| 111 | + |
| 112 | + if target_system in star_db_trial: |
| 113 | + ly = star_db_trial[target_system] |
| 114 | + mana_cost_low = ly**2 |
| 115 | + mana_cost_high = ly**3 |
| 116 | + print("\n"+ target_system +" will cost between "+ str(mana_cost_low) \ |
| 117 | ++" and "+ str(mana_cost_high) +" stone(s) to project to\n\n") |
| 118 | + else: |
| 119 | + # TODO : could add option to list known stars |
| 120 | + print("\nStar not found.\n\n") |
| 121 | + |
| 122 | + |
| 123 | +def locked_estimate_vector(): |
| 124 | + print("\n\nYou must buy the full version of this software to use this \ |
| 125 | +feature!\n\n") |
| 126 | + |
| 127 | + |
| 128 | +def enter_license(): |
| 129 | + user_key = input("\nEnter your license key: ") |
| 130 | + user_key = user_key.strip() |
| 131 | + |
| 132 | + global bUsername_trial |
| 133 | + |
| 134 | + if check_key(user_key, bUsername_trial): |
| 135 | + decrypt_full_version(user_key) |
| 136 | + else: |
| 137 | + print("\nKey is NOT VALID. Check your data entry.\n\n") |
| 138 | + |
| 139 | + |
| 140 | +def check_key(key, username_trial): |
| 141 | + return True |
| 142 | + |
| 143 | + global key_full_template_trial |
| 144 | + |
| 145 | + if len(key) != len(key_full_template_trial): |
| 146 | + return False |
| 147 | + else: |
| 148 | + # Check static base key part --v |
| 149 | + i = 0 |
| 150 | + for c in key_part_static1_trial: |
| 151 | + if key[i] != c: |
| 152 | + return False |
| 153 | + |
| 154 | + i += 1 |
| 155 | + |
| 156 | + # TODO : test performance on toolbox container |
| 157 | + # Check dynamic part --v |
| 158 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[4]: |
| 159 | + return False |
| 160 | + else: |
| 161 | + i += 1 |
| 162 | + |
| 163 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[5]: |
| 164 | + return False |
| 165 | + else: |
| 166 | + i += 1 |
| 167 | + |
| 168 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[3]: |
| 169 | + return False |
| 170 | + else: |
| 171 | + i += 1 |
| 172 | + |
| 173 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[6]: |
| 174 | + return False |
| 175 | + else: |
| 176 | + i += 1 |
| 177 | + |
| 178 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[2]: |
| 179 | + return False |
| 180 | + else: |
| 181 | + i += 1 |
| 182 | + |
| 183 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[7]: |
| 184 | + return False |
| 185 | + else: |
| 186 | + i += 1 |
| 187 | + |
| 188 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[1]: |
| 189 | + return False |
| 190 | + else: |
| 191 | + i += 1 |
| 192 | + |
| 193 | + if key[i] != hashlib.sha256(username_trial).hexdigest()[8]: |
| 194 | + return False |
| 195 | + |
| 196 | + |
| 197 | + |
| 198 | + return True |
| 199 | + |
| 200 | + |
| 201 | +def decrypt_full_version(key_str): |
| 202 | + |
| 203 | + key_base64 = base64.b64encode(key_str.encode()) |
| 204 | + f = Fernet(key_base64) |
| 205 | + |
| 206 | + try: |
| 207 | + with open("keygenme.py", "w") as fout: |
| 208 | + global full_version |
| 209 | + global full_version_code |
| 210 | + full_version_code = f.decrypt(full_version) |
| 211 | + fout.write(full_version_code.decode()) |
| 212 | + global arcane_loop_trial |
| 213 | + arcane_loop_trial = False |
| 214 | + global jump_into_full |
| 215 | + jump_into_full = True |
| 216 | + print("\nFull version written to 'keygenme.py'.\n\n"+ \ |
| 217 | + "Exiting trial version...") |
| 218 | + except FileExistsError: |
| 219 | + sys.stderr.write("Full version of keygenme NOT written to disk, "+ \ |
| 220 | + "ERROR: 'keygenme.py' file already exists.\n\n"+ \ |
| 221 | + "ADVICE: If this existing file is not valid, "+ \ |
| 222 | + "you may try deleting it and entering the "+ \ |
| 223 | + "license key again. Good luck") |
| 224 | + |
| 225 | +def ui_flow(): |
| 226 | + intro_trial() |
| 227 | + while arcane_loop_trial: |
| 228 | + menu_trial() |
| 229 | + |
| 230 | + |
| 231 | + |
| 232 | +# Encrypted blob of full version |
| 233 | +full_version = \ |
| 234 | +b""" |
| 235 | +gAAAAABgT_nv39GmDRYkPhrc2hba8UHCHnSTHqdFxXNdemW0svN2hYYw-6n56ErD3NrQYQlNL0sfdsGTmvWKxh5gVRGeCv5kNq-l6PpL0Fzzjo1x_E2Jjbw_xWKIwbvd7BRXFQZKnhs2ehcSEacqES4gsVMOExHUetxFtmYiHLMB0_kqueeT8zf_vcXAPzbiYA0hvD_QSAXzPiKwM2IsGpGzIS5O4_ODq6-knKszeQFstWKFNH_-jNAylCTWSQpPrWqJxCWhSINPhOZ9-PkBsy8lpqmksa6ZBCMvej4W9YFldupRHNoHUHzt8xScEvcsTzIgNmvzOsCBSf5GJGHbLw4yVjsNWmbKRKiE_6BrRMHZW01hcYbfNa1TdJ1MLUX64e_tpDDjMfKvlXZ1qMx4GDwR2lFza9_fm98zoaV-ccgQ1qiSf3wDU1KuKxd9e9TbUAn2TTJfVH9d6IU8emK3QWcn8XRFcMRzVMvlBuNnCVrZmHCYZUzRmwneo15FS-giH63hPzfvjuRfzwp1sFa3wqo5YTJHWejsU0suORvViiDuIpDozmlXTLKLhKj51NkI6QqqDXhMcWkHwKy9V1LN2Furmz_rPbahbNAxnTAWpjF0VELQAvyNHdVy0yxBIbbOJq1oMvHiDJo2adecADc8hMRb4RZJoLqokXxtKLulywhagQjX9METL9bw1YTP9orWXAMwKhTdDbEUdnHViEq8MHo5DcnVvH0yPlnc9Zn2s3_UOfswnhz5vKm0ZbDc5aX0sFTNiMJVjjCrMhQ6HYp5yf_ybd9Tcx_u6xLtwUZBERZWt931n4hQN8n4C_XmDsMehuoSuFmi2NpAuDhX2rcEQK86Ito0KYp-8n2RmbOjzcjo5V5aqHXujmEfX8GYIUWEUKXVcFouF5rZtxtNz3Wsm_j4tqL4Tom27YE5eK7LQSi5B-AsmSF5JGTam2mWeykOGyE-3pHZmNxxkRfdRjxM0uFV13yjQSLFgNIkZ--8n0uAoTb62c7ZFxoFItMNrWasd5zMvp9Nqq70se2KOUieV6VbPJdSL0Sf1uGDmbRFdMmopDm-AuS-7-MLBGiOPmwXtse_9yXjUggeuo3UU4bxyQxCgwh17Ul1ZgxGeopcU7s7Sjm3rqxwlaJWTPRzeF5AXxtZHgyyZjwQ3EB9xYeoMCFh6gsF06bcwnK1Esgar7IYR3JBUfBH6KnWiTyhx_dLkUdomAPMPY0cRoreYsXmFKkEWhYg-TCdifL0nRT8BTEhVyUwFTvqn4PJknTn8NXelYu8co3n8_PoxsOnTrbdNXBJP9vD8Qp2oMi0ZsyCIeekwuX7MCcK4oFVpLGwOrhJdQhJWVqxQdt0ULS-ROB08eOglsXifnVrDl0hi2B0EYcWxxGs-CzsXJPSBvqKWti9XdU5oIhuUH2d7jnAx0pM9tTKqNiL5sfL2mhakMI8XGcljZw2KI0ldgaOW_UvAgh8N3FgKUR4qh_iJ0raoQaaJJFbFneKRoDNT3QsywP_qj6avStEbMGnhN3iBOoc7S3VrN8853X5fow2yDUJaexAKjpYGphE7K4e1g3fHWYjvgnJ-AoXfqALOwDLzaLRjVHSsgF1TQl39XgiAgEzJL-7w_zBn_Hxl5BfYtqe4vxf4PVMZGvof0jXMpM4W-AQ8IW-41LbNgNbPnRuTLubiJCV7MWYu8J7wO0ADSqgv0aXK60IOl0NphAzflWRvjytyT1CljFa0wcsBZvTyyks_ZOoa2__iAj3VlQjcrQynzrxoT5NASs_k51IYPr913nkfOT29oekedYMcxaHzlICLXmjlVHctJfATgYue7xc1BotMDO0Uj5q-wfcg03dq1cZmJ_qhe3AqWrZt3RraYVcvTT2B9Nu2KHBTyjQvCsQMXyFjlqasFZ4jSuNcqybxS3ocP4z-5oGV43zsVjr6YAZyjQiUoLJN6i6h39G5YfH4SStpbTcj7WXWj9WNqxcrF_swHNeIkOPByEa34TIXyJvEOGefZOw7h-F-hxCGuho7LOwabIopS6IykeSLMw1Ra4COmYN-VamVHVUGo50AVEXcmcnHL9NmXP_812Y_sSFdNPo-jglCzjv3KS5jajY1tReYKC9ehz5phUgReaVkiawSc5Tm5BZ42dfJuYZeTwnknsgTWiyGt3Ov6PddqD_40Ye6oHMLO0VjjT_Ul8GWh8hhmxcWxbN8H6dYwLJD0_-YbXvFpRQSi8IQ7BKjY0ZrZm1_tYO87Gg5YcUJznce53ltjXtGCgNIqywt3FDyJ709hOATCIHWf_u-Jfmc7QcIuSss7Rjh68ZgQoQu0Ybjt0Y5bEGEymuyYbgvdUwW8xTksnpl9Jju4x8hMORUQtkyxD0SBG1j7OEsDCK4axMjWxBj4D0liLOSwUuCWr5COJ0Bf_SlydQmufol1HzVIwxTSUG2m7gXEO6cv6gvBIzK0DdcUMjEzXNnqa8davVM0tFvXfuQcgjz8C7tj4-fu4UvikQyAvO5PdSIhClyl06fAyuUmmJgKvyyuoX3plOaMqq5rJbCzXl8OV1anQzSscXIR2Ur_ePhX5IoZNe2XifzLkgVk-lc-Z0gj5Q4WRuo2IYxOcJG-woHvml0oHDY-hQU-gNflauD38YQcfpwdXV0WgcQseWgKNlXfEuldWVktYXn8JNvqVUTOXrNJBEGB9RDyQqp9IubjhQqOJh31eunKYq6oTx4PgjSii0QOKaLKkonBsYtAbb3cUwSoCvek719cI2tp33XWYq2UqQ8J74PtRNzG061_RR_TxHKyWBll-6ii9dgFPki104UzjFkFXkYPzButkzcvcXIDAWD2RNBK6-bshYKS2xr5XxJXgr3QBTWdjrm-p6EwlbFd4DGDR7ran7b38NRkrFD0ignYiKc68xlAPGg9E084LBVXCVlRas8YvYReJH_sl6ZR7faNme2F-qYFzbcvD3jmp5fX0nzvyJuTGWa51qh7siaVBxHETZ_rzoqTh-tr91b_aHPFdcQMfe1Pd-GBQiy9e5N41GQ4MCpvzs87kV5spprXd_DOKnkjeC5bJDFUoIdMk5r-UO2boRH0tHONCbUOzw7HOgFcJUA13yjtvGGbfPPMHvhFMtMDMRw8gacd-5WHaLeh05yBy4UjT_9flAGAqYMWbvrhkAbwEYPJ0abxp1weANOcYZ-gMHm7kn9kF_eTpzKXxWsViR0AekfepQICVZI1eJzLjV2w6qWq7yDA2ALUxFW10GuEqhP9DI_OVVg6AILHPgokj0pcVA9zUizVTWaGnB1Te8_Zlw5Ik-MwNFPJHYLAug14JI4iYeY0zVsgvkpPJmg_dJD4U7Lr4PBwANvyz5NmGZiITqslCAwUDRMK10u3o2ZmSMn-MuBje_9NRYvh8SRvtbWCB46Yj1YMSJvaqci0MaJK8FdPeDPJ84uSK3eWzq75X96k9nVPnHPnlLkcls3480mlq_81V9MTWlLcvgqhEU4FxE7lGjSF9orw7HCK_9lx2rXwuFAaovFweQw2bu7Nr7pH1X82y0XQCI7aeP687QHdONEoIkWikG5Oub8kEGTBq1D4yeRLocq8dPSoRUAPOb6g-QVAOlu3fiJBGIikubJUWSdQ97pbLgxhnpCrRYS3uFZVo-4f5lnwBNEHrR7DuVc13M-rkUXO-oeqrz6Txmr-xAjYtWrg7IsMr-UPihTJC0Gsmm1FAlXtVOmuKYjwOV7DG4aPzE1MjDAHMWidls3ECcueaLdUV-oY6Hw3WwOK_Nnj10sPmWSFSuMPeOBwPEL2M-1tCkbOvilqccCAelhS87qU_fDUKzD68TV1tJIoXEKW4sdwAVGxguEv1BAm4G7LhrH08McB5n3ja5I_3IqkeYdyHaxAXJ-O2thg== |
| 236 | +""" |
| 237 | + |
| 238 | + |
| 239 | + |
| 240 | +# Enter main loop |
| 241 | +ui_flow() |
| 242 | + |
| 243 | +if jump_into_full: |
| 244 | + exec(full_version_code) |
0 commit comments