예제 #1
0
    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:]
예제 #2
0
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
예제 #3
0
 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)
예제 #4
0
    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)
예제 #5
0
    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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
# 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)