def getKeys(secret, seed=None): """ Generate keyring containing public key, signing and checking keys as attribute. Keyword arguments: secret (str or bytes) -- a human pass phrase seed (byte) -- a sha256 sequence bytes (private key actualy) Return dict """ if secret and not isinstance(secret, bytes): secret = secret.encode('utf-8') seed = hashlib.sha256(secret).digest() if not seed else seed signingKey = SigningKey.from_secret_exponent( int(binascii.hexlify(seed), 16), SECP256k1, hashlib.sha256) publicKey = signingKey.get_verifying_key().to_string() return { "publicKey": hexlify( compressEcdsaPublicKey(publicKey) if cfg.compressed else publicKey ), "privateKey": hexlify(signingKey.to_string()), "wif": getWIF(seed) }
def getKeys(secret="passphrase", seed=None, network=None): """ Generate keyring containing network, public and private key as attribute. secret or seed have to be provided, if network is not, cfg.__NETWORK__ is automatically selected. Keyword arguments: secret (str or bytes) -- a human pass phrase seed (byte) -- a sha256 sequence bytes network (object) -- a python object Returns ArkyDict >>> binascii.hexlify(getKeys("secret").public) b'03a02b9d5fdd1307c2ee4652ba54d492d1fd11a7d1bb3f3a44c4a05e79f19de933' """ network = ArkyDict( **network ) if network else cfg.__NETWORK__ # use cfg.__NETWORK__ network by default seed = hashlib.sha256( secret.encode("utf8") if not isinstance(secret, bytes) else secret ).digest() if not seed else seed keys = ArkyDict() # save wallet address keys.wif = getWIF(seed, network) # save network option keys.network = network # generate signing and verifying object and public key keys.signingKey = SigningKey.from_secret_exponent( int(binascii.hexlify(seed), 16), SECP256k1, hashlib.sha256) keys.checkingKey = keys.signingKey.get_verifying_key() keys.public = _compressEcdsaPublicKey(keys.checkingKey.to_string()) return keys
def __init__(self, x, y, curve_name, secret_multiplier=None): if not curve_name: raise ValueError("curve_name must be specified") self.curve_name = curve_name for c in curves: if c.name == curve_name or c.openssl_name == curve_name: curve = c break else: raise ValueError( "Curve '{0}' not supported by python-ecdsa".format(curve_name)) self.private_key = None self.public_key = None self.key_type = "ecdsa" if secret_multiplier: self.private_key = SigningKey.from_secret_exponent( secret_multiplier, curve) if x and y: point = Point(curve.curve, x, y) self.public_key = VerifyingKey.from_public_point(point, curve) if not self.public_key: self.public_key = self.private_key.get_verifying_key()
def public_key(self): """ """ if self._public_key: return self._public_key point = SigningKey.from_secret_exponent( secexp=int(self.secret_exponent, 16), curve=SECP256k1, hashfunc=hashlib.sha256, ).verifying_key.pubkey.point x = hex(point.x())[2:].strip('L') y = hex(point.y())[2:].strip('L') if self.__compressed: return ''.join(('02' if point.y() % 2 == 0 else '03', x)) else: return ''.join(('04', x, y))
def signing_key_from_seed(encoded_seed: str) -> SigningKey: """ Derives SigningKey from master seed. Reference: https://ripple.com/wiki/Account_Family#Root_Key_.28GenerateRootDeterministicKey.29 """ # Ripple seeds are base58-encoded and prefixed with letter "s" assert encoded_seed[0] == 's' seed = base58.b58decode_check(encoded_seed, alphabet=base58.RIPPLE_ALPHABET)[1:] seq = 0 while True: private_gen = int.from_bytes(first_half_of_sha512( seed, seq.to_bytes(4, byteorder='big')), byteorder='big') seq += 1 if SECP256k1.order >= private_gen: break public_key = VerifyingKey.from_public_point(SECP256k1.generator * private_gen, curve=SECP256k1) # Now that we have the private and public generators, we apparently # have to calculate a secret from them that can be used as a ECDSA # signing key. secret = i = 0 public_gen_compressed = public_key.to_string(encoding='compressed') while True: secret = int.from_bytes(first_half_of_sha512( public_gen_compressed, bytes(4), i.to_bytes(4, byteorder='big')), byteorder='big') i += 1 if SECP256k1.order >= secret: break secret = (secret + private_gen) % SECP256k1.order return SigningKey.from_secret_exponent(secret, curve=SECP256k1)
def generate_private_key(): """ () -> hex Generate a private key and Return respective public key pair using the Elliptical Curve Digital Signiture Algorithm. SECP256k1 curve. -> curve Generate a 'random' number to use in the generation of the private key. -> se Generate the key with the two above inputs and pass it through a SHA-256 hash. -> sha256(key) -> verifying_key Return the hexideciaml conversion of verifying key (public key pair to the private key generated) verifying_key -> hex This is our private key's public key pair. """ curve = ecdsa.curves.SECP256k1 se = random_secret_exponent(curve.order) key = SigningKey.from_secret_exponent(se, curve, hashlib.sha256) verifying_key = key.get_verifying_key() verifying_key_string = verifying_key.to_string() bitcoin_byte = b'04' key_hex = hexlify(key.to_string()) return hexlify(key.to_string())
def get_address(self, n, address_type): secexp = string_to_number(self.get_private_key(n)) pubkey = SigningKey.from_secret_exponent(secexp, SECP256k1).get_verifying_key() address = public_key_to_bc_address('\x04' + pubkey.to_string(), address_type) return address
def _get_master_private_key(self): return SigningKey.from_secret_exponent(self._secexp(), SECP256k1)
def sign(cls, key: 'EC2', data: bytes) -> bytes: sk = SigningKey.from_secret_exponent(int(hexlify(key.d), 16), curve=cls.get_curve()) return sk.sign_deterministic(data, hashfunc=cls.get_hash_func())
def test_ecdh_check(self): ''' https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-23#appendix-C ''' v_stc_material = { "kty": "EC", "crv": "P-256", "x": "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0", "y": "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps", "d": "0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo" } u_epk_material = { "kty": "EC", "crv": "P-256", "x": "weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ", "y": "e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck", "d": "VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw" } import re def _to_pub(km): return ( int(re.search(r"P-(\d+)$", km['crv']).group(1)), (base64.long_from_b64(km['x']), base64.long_from_b64(km['y'])), ) def _to_pri(km): return ( int(re.search(r"P-(\d+)$", km['crv']).group(1)), base64.long_from_b64(km['d']), ) pub_tuple = _to_pub(v_stc_material) pri_tuple = _to_pri(v_stc_material) import pydoc curve = pydoc.locate('ecdsa.curves.NIST{0}p'.format(pub_tuple[0])) from ecdsa import ( SigningKey, VerifyingKey, ellipticcurve as ec) x, y = pub_tuple[1] v_pub = VerifyingKey.from_public_point( ec.Point(curve.curve, x, y, curve.order), curve, ) v_stc = SigningKey.from_secret_exponent(pri_tuple[1], curve) # Party U provides a ephemeral key pub_tuple = _to_pub(u_epk_material) pri_tuple = _to_pri(u_epk_material) x, y = pub_tuple[1] u_epk = SigningKey.from_secret_exponent(pri_tuple[1], curve) from jose.jwa.ec import ecdsa_dhZ # Party U compute shared_secret_u = ecdsa_dhZ(v_pub, u_epk) print("Aggreement:", base64.long_to_b64(shared_secret_u)) from Crypto.Util.number import long_to_bytes from math import ceil block_size = int(ceil(pub_tuple[0] / 8.0)) # bit number(512 ) / 8 -> octets Zu = long_to_bytes(shared_secret_u, block_size) Z_jwa = [158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132, 38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121, 140, 254, 144, 196] self.assertEqual(_ilist(Zu), Z_jwa) # Other Information used in Concat KDF # AlgorithmID || PartyUInfo || PartyVInfo || SuppPubInfo from struct import pack def _otherInfo(alg, pu, pv, klen): return b('').join([ pack("!I", len(alg)), alg, pack("!I", len(pu)), pu, pack("!I", len(pv)), pv, pack("!I", klen), ]) oi_u = _otherInfo( b("A128GCM"), b("Alice"), b("Bob"), 16 * 8, # A128GCM ) oi_jwa = [ 0, 0, 0, 7, 65, 49, 50, 56, 71, 67, 77, 0, 0, 0, 5, 65, 108, 105, 99, 101, 0, 0, 0, 3, 66, 111, 98, 0, 0, 0, 128] print(">>>>>>>", type(oi_u)) print("<<<<<<<", oi_u) self.assertEqual(_ilist(oi_u), oi_jwa) # Coccat KDF : NIST defines SHA256 from Crypto.Hash import SHA256 def _ConcatKDF(Z, dkLen, otherInfo, digest_method=SHA256): def _src(counter_bytes): return b("").join([counter_bytes, Z, otherInfo]) from math import ceil from struct import pack dkm = b'' # Derived Key Material counter = 0 klen = int(ceil(dkLen / 8.0)) while len(dkm) < klen: counter += 1 counter_b = pack("!I", counter) dkm += digest_method.new(_src(counter_b)).digest() return dkm[:klen] _derived_key_u = _ConcatKDF(Zu, 16 * 8, oi_u) # Party V recive Epemeral Public Key v_epk = u_epk.get_verifying_key() Zv = long_to_bytes(ecdsa_dhZ(v_epk, v_stc), block_size) _derived_key_v = _ConcatKDF(Zv, 16 * 8, oi_u) self.assertEqual(_derived_key_u, _derived_key_v) kd_jwa = [ 86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26] self.assertEqual(_ilist(_derived_key_u), kd_jwa) self.assertEqual(b("VqqN6vgjbSBcIijNcacQGg"), base64.base64url_encode(_derived_key_u))
def generate_private_key(): curve = ecdsa.curves.SECP256k1 se = random_secret_exponent(curve.order) key = SigningKey.from_secret_exponent(se, curve, hashlib.sha256) return hexlify(key.to_string())