from ecdsa import SigningKey, SECP256k1, VerifyingKey from ecdsa import util as ecdsaUtil import binascii import hashlib def generate_pem(): sk = SigningKey.generate(curve=SECP256k1) pem = sk.to_pem() pem = pem.decode("utf-8") return pem def get_sin_from_pem(pem): public_key = get_compressed_public_key_from_pem(pem) version = get_version_from_compressed_key(public_key) checksum = get_checksum_from_version(version) return base58encode(version + checksum) def get_compressed_public_key_from_pem(pem): vks = SigningKey.from_pem(pem).get_verifying_key().to_string() bts = binascii.hexlify(vks) compressed = compress_key(bts) return compressed def sign(message, pem): message = message.encode() sk = SigningKey.from_pem(pem) signed = sk.sign(message, hashfunc=hashlib.sha256, sigencode=ecdsaUtil.sigencode_der) return binascii.hexlify(signed).decode() def base58encode(hexastring): chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' int_val = int(hexastring, 16) encoded = encode58("", int_val, chars) return encoded def encode58(string, int_val, chars): if int_val == 0: return string else: new_val, rem = divmod(int_val, 58) new_string = (chars[rem]) + string return encode58(new_string, new_val, chars) def get_checksum_from_version(version): return sha_digest(sha_digest(version))[0:8] def get_version_from_compressed_key(key): sh2 = sha_digest(key) rphash = hashlib.new('ripemd160') rphash.update(binascii.unhexlify(sh2)) rp1 = rphash.hexdigest() return '0F02' + rp1 def sha_digest(hexastring): return hashlib.sha256(binascii.unhexlify(hexastring)).hexdigest() def compress_key(bts): intval = int(bts, 16) prefix = find_prefix(intval) return prefix + bts[0:64].decode("utf-8") def find_prefix(intval): if(intval % 2 == 0): prefix = '02' else: prefix = '03' return prefix