Имеется скрипт выполняющий конвертацию HEX значений в конечный адрес по заданному алгоритму.
import base58 from ripemd160 import ripemd160 from sha256 import sha256 class PublicKey: p_curve = (2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1) n_curve = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 a_curve, b_curve = 0, 7 gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240 gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424 gpoint = (gx, gy) def __init__(self, private_key): self.private_key = private_key @property def private_key(self): return self.__private_key @private_key.setter def private_key(self, key): try: key = int(str(key), 16) except ValueError: raise NotImplementedError('Private key must be a hexadecimal number') if key <= 0 or key >= self.n_curve: raise Exception("Invalid Scalar/Private Key") self.__private_key = key def __modinv(self, a, n): lm, hm = 1, 0 low, high = a % n, n while low > 1: ratio = int(high/low) nm, new = int(hm-lm*ratio), int(high-low*ratio) lm, low, hm, high = nm, new, lm, low return lm % n def __ec_add(self, a, b): lam_add = ((b[1]-a[1]) * self.__modinv(b[0] - a[0], self.p_curve)) % self.p_curve x = (pow(lam_add, 2)-a[0]-b[0]) % self.p_curve y = (lam_add*(a[0]-x)-a[1]) % self.p_curve return x, y def __ec_double(self, a): lam = ((3*a[0]*a[0]+self.a_curve) * self.__modinv((2*a[1]), self.p_curve)) % self.p_curve x = int((lam*lam-2*a[0]) % self.p_curve) y = int((lam*(a[0]-x)-a[1]) % self.p_curve) return x, y def __ec_multiply(self, genpoint, scalarhex): scalarbin = str(bin(scalarhex))[2:] q = genpoint for i in range(1, len(scalarbin)): q = self.__ec_double(q) if scalarbin[i] == "1": q = self.__ec_add(q, genpoint) return q def __compute_public(self): return self.__ec_multiply(self.gpoint, self.private_key) def __public_address(self, key): key = bytes.fromhex(key) address = bytes.fromhex(f"00{ripemd160(sha256(key)).hex()}") checksum = sha256(sha256(address)) address = f"{address.hex()}{checksum.hex()[:8]}" address = base58.b58encode(bytes.fromhex(address)).decode("UTF-8") return address def write_public_keys(self): public_key = self.__compute_public() uncomp_pub = f"04{public_key[0]:0>64x}{public_key[1]:0>64x}" uncomp_addr = self.__public_address(uncomp_pub) arq1.write(f"Secret: {prompt}\n") arq1.write(f"-----------------------------------------------------------------\n") arq1.write(f"Uncompressed: {uncomp_addr}\n") arq2.write(f"{uncomp_addr}\n") if public_key[1] % 2 == 1: comp_pub = f"03{public_key[0]:0>64x}" else: comp_pub = f"02{public_key[0]:0>64x}" comp_addr = self.__public_address(comp_pub) arq1.write(f"Compressed: {comp_addr}\n") arq2.write(f"{comp_addr}\n") arq1.write(f"-----------------------------------------------------------------\n") with open("input.txt") as file: for line in file: arq1 = open('result.txt', 'a') arq2 = open('output.txt', 'a') prompt = str.strip(line) my_key = PublicKey(prompt) my_key.write_public_keys() arq1.close() arq2.close()
Скрипт полностью рабочий и алгоритм конвертации производит верные расчеты, но крайне медленно.
На обработку 300к строк уходит ~86 мин.
Помогите прикрутить многопоточность.