def sign(self, pv): """ .. method:: sign(pv) :param pv: private key in hexadecimal or binary format Generate a signed transaction according to EIP-155. Once signed, the transaction can be converted to RLP and broadcasted to the Ethereum network. """ #accept hex and bin keys if pv.startswith("0x"): pv = pv[2:] pv = ecc.hex_to_bin(pv) #Check here: replay attacks eip https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md self.tx[6] = self.chain self.tx[7] = b'' self.tx[8] = b'' dk = self.hash(False).digest() v, rs = ecc.sign(ecc.SECP256K1, dk, pv, deterministic=sha2.SHA2(), recoverable=True) s = ecc.bin_to_hex(rs[32:]) sbg = bignum.BigNum("0x" + s) bg2 = bignum.BigNum(2) s2bg = sbg.mul(bg2) Nbg = bignum.BigNum(N) #Check here: https://github.com/ethereum/py_ecc/blob/master/py_ecc/secp256k1/secp256k1.py#L109 if s2bg.gte(Nbg): sn = Nbg.sub(sbg) s = sn.to_base(16) s = ecc.hex_to_bin(s) v = v ^ 1 else: s = rs[32:] self.tx[6] = v + self.chain * 2 + 35 self.tx[7] = rs[0:32] self.tx[8] = s # R and S must not start with 0 for RLP while self.tx[7][0] == 0: self.tx[7] = self.tx[7][1:] while self.tx[8][0] == 0: self.tx[8] = self.tx[8][1:]
def encode(payload, key): """ .. function:: encode(payload, key) Encode a JWT for target :samp:`payload` signed with :samp:`key`. Currently only ES256 encoding algorithm using prime256v1 curve is supported. :samp:`key` must be an ECDSA private key in hex format. If a private key is, for example, stored as a pem file, the needed hex string can be extracted from the OCTET STRING field associated value obtained from :: openssl asn1parse -in my_private.pem command (since pem is a base64 encoded, plus header, `DER <https://tools.ietf.org/html/rfc5915>`_). """ key = ec.hex_to_bin(key) jwt = jwt_header + '.' + base64.standard_b64encode(payload).strip('=') ss = sha2.SHA2(hashtype=sha2.SHA256) ss.update(jwt) signature = ec.sign(ec.SECP256R1, ss.digest(), key, deterministic=sha2.SHA2(hashtype=sha2.SHA256)) jwt = jwt + '.' + base64.standard_b64encode(signature).strip('=') return jwt
def _set_value(self, value, unit, idx): bg = bignum.BigNum(value) if unit != WEI: bgt = bignum.BigNum("1" + ("0" * unit)) bg.imul(bgt) bgt = None hh = bg.to_base(16) self.tx[idx] = ecc.hex_to_bin(hh)
def set_receiver(self, address): """ .. method:: set_receiver(address) :param address: the receiver address in hex format starting with 0x Set the receiver address to *address* """ if address.startswith("0x"): address = address[2:] self.tx[3] = ecc.hex_to_bin(address)
def set_data(self, value): """ .. method:: set_data(value) :param value: binary representation of transaction data. Can be hexadecimal or bytes. Set transaction data to *value* """ if type(value) == PSTRING and value.startswith("0x"): value = bignum.BigNum(value) value = ecc.hex_to_bin(value.to_base(16)) self.tx[5] = value
def encode_es256(payload, key): # The standard JWT header already base64 encoded. Equates to {"alg": "ES256", "typ": "JWT"} jwt_header = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9" key = ec.hex_to_bin(key) jwt = jwt_header + '.' + base64.standard_b64encode(payload).strip('=') ss = sha2.SHA2(hashtype=sha2.SHA256) ss.update(jwt) signature = ec.sign(ec.SECP256R1, ss.digest(), key, deterministic=sha2.SHA2(hashtype=sha2.SHA256)) jwt = jwt + '.' + base64.standard_b64encode(signature).strip('=').replace( "+", "-").replace("/", "_") return jwt
def get_address(pv): """ .. function::get_address(pv) Given the private key *pv*, return the corresponding Ethereum address *pv* can be given in both binary or hex format (starting with 0x) """ if pv.startswith("0x"): pv = ecc.hex_to_bin(pv) pbb = ecc.derive_public_key(ecc.SECP256K1, pv) pb = ecc.bin_to_hex(pbb) kk = keccak.Keccak() kk.update(pbb) dk = kk.hexdigest() db = kk.digest() addr = dk[-40:].lower() return "0x" + addr
# Authors: G. Baldi ################################################################################ import streams # import ecc and sha1 modules from crypto.ecc import ecc as ec from crypto.hash import sha1 as sha1 streams.serial() message = "Zerynth" # import a Public Key for SECP256R1 pb = ec.hex_to_bin( "7A181C7D3AD54EC3817CBAF86EA4E003AD492D8569102392A6EFE0C27E471A65553918EA1BAC86A68C78A30E9FE725EA499E14BEA96C3FE85E2267B74385E56B" ) # import a Private Key for SECP256R1 pv = ec.hex_to_bin( "6D5BE10E67D479FF99421A8DE030E2B4C5323EE477DA4C17420936CAC49C261E") while True: # calculate hash of message ss = sha1.SHA1() ss.update(message) digest = ss.digest() # Calculate non deterministic signature of digest # for SECP256R1 and pv signature = ec.sign(ec.SECP256R1, digest, pv)