示例#1
0
 def test_Bool(self):
     u = types.Bool(True)
     self.assertEqual(py23_bytes(u), b"\x01")
     self.assertEqual(str(u), 'true')
     u = types.Bool(False)
     self.assertEqual(py23_bytes(u), b"\x00")
     self.assertEqual(str(u), 'false')
示例#2
0
 def test_varint32(self):
     u = types.Varint32(2**32 - 1)
     self.assertEqual(py23_bytes(u), b"\xff\xff\xff\xff\x0f")
     self.assertEqual(str(u), str(4294967295))
     u = types.Id(2**32 - 1)
     self.assertEqual(py23_bytes(u), b"\xff\xff\xff\xff\x0f")
     self.assertEqual(str(u), str(4294967295))
示例#3
0
文件: memo.py 项目: dpays/dpay-cli
def encode_memo(priv, pub, nonce, message, **kwargs):
    """ Encode a message with a shared secret between Alice and Bob

        :param PrivateKey priv: Private Key (of Alice)
        :param PublicKey pub: Public Key (of Bob)
        :param int nonce: Random nonce
        :param str message: Memo message
        :return: Encrypted message
        :rtype: hex
    """
    shared_secret = get_shared_secret(priv, pub)

    aes, check = init_aes(shared_secret, nonce)
    raw = py23_bytes(message, 'utf8')
    # Padding
    BS = 16
    if len(raw) % BS:
        raw = _pad(raw, BS)
    # Encryption
    cipher = hexlify(aes.encrypt(raw)).decode('ascii')
    prefix = kwargs.pop("prefix", default_prefix)
    s = {
        "from": format(priv.pubkey, prefix),
        "to": format(pub, prefix),
        "nonce": nonce,
        "check": check,
        "encrypted": cipher,
        "prefix": prefix
    }
    tx = Memo(**s)
    return "#" + base58encode(hexlify(py23_bytes(tx)).decode("ascii"))
示例#4
0
 def test_bytes_int(self):
     """
     In Py3, bytes(int) -> bytes object of size given by the parameter initialized with null
     """
     self.assertEqual(py23_bytes(5), b'\x00\x00\x00\x00\x00')
     # Test using newint:
     self.assertEqual(py23_bytes(int(5)), b'\x00\x00\x00\x00\x00')
     self.assertTrue(isinstance(py23_bytes(int(5)), bytes_types))
示例#5
0
    def test_string(self):
        u = types.String("HelloFoobar")
        self.assertEqual(py23_bytes(u), b"\x0bHelloFoobar")
        self.assertEqual(str(u), "HelloFoobar")

        u = types.String("\x07\x08\x09\x0a\x0b\x0c\x0d\x0e")
        self.assertEqual(py23_bytes(u), b"\x14u0007b\t\nu000bf\ru000e")
        self.assertEqual(str(u), "\x07\x08\x09\x0a\x0b\x0c\x0d\x0e")
示例#6
0
 def test_Optional(self):
     u = types.Optional(types.Uint16(10))
     self.assertEqual(py23_bytes(u), b"\x01\n\x00")
     self.assertEqual(str(u), '10')
     self.assertFalse(u.isempty())
     u = types.Optional(None)
     self.assertEqual(py23_bytes(u), b"\x00")
     self.assertEqual(str(u), 'None')
     self.assertTrue(u.isempty())
示例#7
0
    def test_isinstance_bytes_subclass(self):
        """
        Issue #89
        """
        value = py23_bytes(b'abc')

        class Magic():
            def __bytes__(self):
                return py23_bytes(b'abc')

        self.assertEqual(value, py23_bytes(Magic()))
示例#8
0
 def test_array(self):
     u = types.Array([types.Uint8(10) for x in range(2)] + [11])
     self.assertEqual(
         py23_bytes(u),
         b'\x03\n\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
     self.assertEqual(str(u), "[10, 10, 11]")
     u = types.Set([types.Uint16(10) for x in range(10)])
     self.assertEqual(
         py23_bytes(u),
         b"\n\n\x00\n\x00\n\x00\n\x00\n\x00\n\x00\n\x00\n\x00\n\x00\n\x00")
     self.assertEqual(str(u), "[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]")
     u = types.Array(["Foobar"])
     # We do not support py23_bytes of Array containing String only!
     # self.assertEqual(py23_bytes(u), b'')
     self.assertEqual(str(u), '["Foobar"]')
示例#9
0
 def test_Signature(self):
     u = types.Signature(b"\x00" * 33)
     self.assertEqual(py23_bytes(u), b"\x00" * 33)
     self.assertEqual(
         str(u),
         '"000000000000000000000000000000000000000000000000000000000000000000"'
     )
示例#10
0
 def test_bytes_encoding_arg_non_kwarg(self):
     """
     As above, but with a positional argument
     """
     u = u'Unicode string: \u5b54\u5b50'
     b = py23_bytes(u, 'utf-8')
     self.assertEqual(b, u.encode('utf-8'))
示例#11
0
    def test_Static_variant(self):
        class Tmp(types.Uint16):
            def json(self):
                return "Foobar"

        u = types.Static_variant(Tmp(10), 10)
        self.assertEqual(py23_bytes(u), b"\n\n\x00")
        self.assertEqual(str(u), '[10, "Foobar"]')
示例#12
0
    def verify(self, pubkeys=[], chain=None, recover_parameter=False):
        """Returned pubkeys have to be checked if they are existing"""
        if not chain:
            raise
        chain_params = self.getChainParams(chain)
        self.deriveDigest(chain)
        signatures = self.data["signatures"].data
        pubKeysFound = []

        for signature in signatures:
            if recover_parameter:
                p = verify_message(
                    self.message,
                    py23_bytes(signature)
                )
            else:
                p = None
            if p is None:
                for i in range(4):
                    try:
                        p = verify_message(
                            self.message,
                            py23_bytes(signature),
                            recover_parameter=i
                        )
                        phex = hexlify(p).decode('ascii')
                        pubKeysFound.append(phex)
                    except Exception:
                        p = None
            else:
                phex = hexlify(p).decode('ascii')
                pubKeysFound.append(phex)

        for pubkey in pubkeys:
            if not isinstance(pubkey, PublicKey):
                raise Exception("Pubkeys must be array of 'PublicKey'")

            k = pubkey.unCompressed()[2:]
            if k not in pubKeysFound and repr(pubkey) not in pubKeysFound:
                k = PublicKey(PublicKey(k).compressed())
                f = format(k, chain_params["prefix"])
                raise Exception("Signature for %s missing!" % f)
        return pubKeysFound
示例#13
0
 def test_bytes_encoding_arg(self):
     """
     The bytes class has changed in Python 3 to accept an
     additional argument in the constructor: encoding.
     It would be nice to support this without breaking the
     isinstance(..., bytes) test below.
     """
     u = u'Unicode string: \u5b54\u5b50'
     b = py23_bytes(u, encoding='utf-8')
     self.assertEqual(b, u.encode('utf-8'))
示例#14
0
 def doit(self, printWire=False, ops=None):
     if ops is None:
         ops = [Operation(self.op)]
     tx = Signed_Transaction(ref_block_num=self.ref_block_num,
                             ref_block_prefix=self.ref_block_prefix,
                             expiration=self.expiration,
                             operations=ops)
     tx = tx.sign([self.wif], chain=self.prefix)
     tx.verify([PrivateKey(self.wif, prefix=u"DWB").pubkey], self.prefix)
     txWire = hexlify(py23_bytes(tx)).decode("ascii")
示例#15
0
 def hash_op(event):
     """ This method generates a hash of blockchain operation. """
     if isinstance(event, dict) and "type" in event and "value" in event:
         op_type = event["type"]
         if len(op_type) > 10 and op_type[len(op_type) -
                                          10:] == "_operation":
             op_type = op_type[:-10]
         op = event["value"]
         event = [op_type, op]
     data = json.dumps(event, sort_keys=True)
     return hashlib.sha1(py23_bytes(data, 'utf-8')).hexdigest()
示例#16
0
    def prehash_message(self, timestamp, account, method, params, nonce):
        """ Prepare a hash for the Conveyor API request with SHA256 according
            to https://github.com/dpays/rpc-auth
            Hashing of `second` is then done inside `ecdsasig.sign_message()`.

            :param str timestamp: valid iso8601 datetime ending in "Z"
            :param str account: valid dPay blockchain account name
            :param str method: Conveyor method name to be called
            :param bytes param: base64 encoded request parameters
            :param bytes nonce: random 8 bytes

        """
        first = hashlib.sha256(py23_bytes(timestamp + account + method +
                                          params, self.ENCODING))
        return self.K + first.digest() + nonce
示例#17
0
 def test_sign_message(self, module):
     if module == "cryptography":
         if not ecda.CRYPTOGRAPHY_AVAILABLE:
             return
         ecda.SECP256K1_MODULE = "cryptography"
     elif module == "secp256k1":
         if not ecda.SECP256K1_AVAILABLE:
             return
         ecda.SECP256K1_MODULE = "secp256k1"
     else:
         ecda.SECP256K1_MODULE = module
     pub_key = py23_bytes(repr(PrivateKey(wif).pubkey), "latin")
     signature = ecda.sign_message("Foobar", wif)
     pub_key_sig = ecda.verify_message("Foobar", signature)
     self.assertEqual(hexlify(pub_key_sig), pub_key)
示例#18
0
    def __init__(self, url="https://api.dsite.io",
                 dpay_instance=None):
        """ Initialize a Conveyor instance
            :param str url: (optional) URL to the Conveyor API, defaults to
                https://api.dsite.io
            :param dpaycli.dpay.DPay dpay_instance: DPay instance

        """

        self.url = url
        self.dpay = dpay_instance or shared_dpay_instance()
        self.id = 0
        self.ENCODING = 'utf-8'
        self.TIMEFORMAT = '%Y-%m-%dT%H:%M:%S.%f'
        self.K = hashlib.sha256(py23_bytes('dpay_jsonrpc_auth',
                                           self.ENCODING)).digest()
示例#19
0
    def id(self):
        """ The transaction id of this transaction
        """
        # Store signatures temporarily since they are not part of
        # transaction id
        sigs = self.data["signatures"]
        self.data.pop("signatures", None)

        # Generage Hash of the seriliazed version
        h = hashlib.sha256(py23_bytes(self)).digest()

        # recover signatures
        self.data["signatures"] = sigs

        # Return properly truncated tx hash
        return hexlify(h[:20]).decode("ascii")
示例#20
0
文件: rc.py 项目: dpays/dpay-cli
 def get_tx_size(self, op):
     """Returns the tx size of an operation"""
     ops = [Operation(op)]
     prefix = u"BEX"
     wif = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
     ref_block_num = 34294
     ref_block_prefix = 3707022213
     expiration = "2016-04-06T08:29:27"
     tx = Signed_Transaction(ref_block_num=ref_block_num,
                             ref_block_prefix=ref_block_prefix,
                             expiration=expiration,
                             operations=ops)
     tx = tx.sign([wif], chain=prefix)
     txWire = hexlify(py23_bytes(tx)).decode("ascii")
     tx_size = len(txWire)
     return tx_size
示例#21
0
    def deriveDigest(self, chain):
        chain_params = self.getChainParams(chain)
        # Chain ID
        self.chainid = chain_params["chain_id"]

        # Do not serialize signatures
        sigs = self.data["signatures"]
        self.data["signatures"] = []

        # Get message to sign
        #   bytes(self) will give the wire formated data according to
        #   GrapheneObject and the data given in __init__()
        self.message = unhexlify(self.chainid) + py23_bytes(self)
        self.digest = hashlib.sha256(self.message).digest()

        # restore signatures
        self.data["signatures"] = sigs
示例#22
0
文件: memo.py 项目: dpays/dpay-cli
def decode_memo(priv, message):
    """ Decode a message with a shared secret between Alice and Bob

        :param PrivateKey priv: Private Key (of Bob)
        :param base58encoded message: Encrypted Memo message
        :return: Decrypted message
        :rtype: str
        :raise ValueError: if message cannot be decoded as valid UTF-8
               string
    """
    # decode structure
    raw = base58decode(message[1:])
    from_key = PublicKey(raw[:66])
    raw = raw[66:]
    to_key = PublicKey(raw[:66])
    raw = raw[66:]
    nonce = str(struct.unpack_from("<Q", unhexlify(raw[:16]))[0])
    raw = raw[16:]
    check = struct.unpack_from("<I", unhexlify(raw[:8]))[0]
    raw = raw[8:]
    cipher = raw

    if repr(to_key) == repr(priv.pubkey):
        shared_secret = get_shared_secret(priv, from_key)
    elif repr(from_key) == repr(priv.pubkey):
        shared_secret = get_shared_secret(priv, to_key)
    else:
        raise ValueError("Incorrect PrivateKey")

    # Init encryption
    aes, checksum = init_aes(shared_secret, nonce)

    # Check
    if not check == checksum:
        raise AssertionError("Checksum failure")

    # Encryption
    # remove the varint prefix (FIXME, long messages!)
    message = cipher[2:]
    message = aes.decrypt(unhexlify(py23_bytes(message, 'ascii')))
    try:
        return _unpad(message.decode('utf8'), 16)
    except:  # noqa FIXME(sneak)
        raise ValueError(message)
示例#23
0
文件: memo.py 项目: dpays/dpay-cli
def init_aes_bts(shared_secret, nonce):
    """ Initialize AES instance

        :param hex shared_secret: Shared Secret to use as encryption key
        :param int nonce: Random nonce
        :return: AES instance
        :rtype: AES

    """
    # Shared Secret
    ss = hashlib.sha512(unhexlify(shared_secret)).digest()
    # Seed
    seed = py23_bytes(str(nonce), 'ascii') + hexlify(ss)
    seed_digest = hexlify(hashlib.sha512(seed).digest()).decode('ascii')
    # Check'sum'
    check = hashlib.sha256(unhexlify(seed_digest)).digest()
    check = struct.unpack_from("<I", check[:4])[0]
    # AES
    key = unhexlify(seed_digest[0:64])
    iv = unhexlify(seed_digest[64:96])
    return AES.new(key, AES.MODE_CBC, iv)
示例#24
0
    def upload(self, image, account, image_name=None):
        """ Uploads an image

            :param str/bytes image: path to the image or image in bytes representation which should be uploaded
            :param str account: Account which is used to upload. A posting key must be provided.
            :param str image_name: optional

            .. code-block:: python

                from dpaycli import DPay
                from dpaycli.imageuploader import ImageUploader
                stm = DPay(keys=["5xxx"]) # private posting key
                iu = ImageUploader(dpay_instance=stm)
                iu.upload("path/to/image.png", "account_name") # "private posting key belongs to account_name

        """
        account = Account(account, dpay_instance=self.dpay)
        if "posting" not in account:
            account.refresh()
        if "posting" not in account:
            raise AssertionError("Could not access posting permission")
        for authority in account["posting"]["key_auths"]:
            posting_wif = self.dpay.wallet.getPrivateKeyForPublicKey(
                authority[0])

        if isinstance(image, string_types):
            image_data = open(image, 'rb').read()
        elif isinstance(image, io.BytesIO):
            image_data = image.read()
        else:
            image_data = image

        message = py23_bytes(self.challenge, "ascii") + image_data
        signature = sign_message(message, posting_wif)
        signature_in_hex = hexlify(signature).decode("ascii")

        files = {image_name or 'image': image_data}
        url = "%s/%s/%s" % (self.base_url, account["name"], signature_in_hex)
        r = requests.post(url, files=files)
        return r.json()
示例#25
0
    def _request(self, account, method, params, key):
        """Assemble the request, hash it, sign it and send it to the Conveyor
            instance. Returns the server response as JSON.

            :param str account: account name
            :param str method: Conveyor method name to be called
            :param dict params: request parameters as `dict`
            :param str key: DPay posting key for signing

        """
        params_bytes = py23_bytes(json.dumps(params), self.ENCODING)
        params_enc = base64.b64encode(params_bytes).decode(self.ENCODING)
        timestamp = datetime.utcnow().strftime(self.TIMEFORMAT)[:-3] + "Z"
        nonce_int = random.getrandbits(64)
        nonce_bytes = struct.pack('>Q', nonce_int)  # 64bit ULL, big endian
        nonce_str = "%016x" % (nonce_int)

        message = self.prehash_message(timestamp, account, method,
                                       params_enc, nonce_bytes)
        signature = sign_message(message, key)
        signature_hex = hexlify(signature).decode(self.ENCODING)

        request = {
            "jsonrpc": "2.0",
            "id": self.id,
            "method": method,
            "params": {
                "__signed": {
                    "account": account,
                    "nonce": nonce_str,
                    "params": params_enc,
                    "signatures": [signature_hex],
                    "timestamp": timestamp
                }
            }
        }
        r = requests.post(self.url, data=json.dumps(request))
        self.id += 1
        return r.json()
示例#26
0
文件: memo.py 项目: dpays/dpay-cli
def encode_memo_bts(priv, pub, nonce, message):
    """ Encode a message with a shared secret between Alice and Bob

        :param PrivateKey priv: Private Key (of Alice)
        :param PublicKey pub: Public Key (of Bob)
        :param int nonce: Random nonce
        :param str message: Memo message
        :return: Encrypted message
        :rtype: hex

    """
    shared_secret = get_shared_secret(priv, pub)
    aes = init_aes_bts(shared_secret, nonce)
    # Checksum
    raw = py23_bytes(message, 'utf8')
    checksum = hashlib.sha256(raw).digest()
    raw = (checksum[0:4] + raw)
    # Padding
    BS = 16
    # FIXME: this adds 16 bytes even if not required
    if len(raw) % BS:
        raw = _pad(raw, BS)
    # Encryption
    return hexlify(aes.encrypt(raw)).decode('ascii')
示例#27
0
文件: memo.py 项目: dpays/dpay-cli
def decode_memo_bts(priv, pub, nonce, message):
    """ Decode a message with a shared secret between Alice and Bob

        :param PrivateKey priv: Private Key (of Bob)
        :param PublicKey pub: Public Key (of Alice)
        :param int nonce: Nonce used for Encryption
        :param bytes message: Encrypted Memo message
        :return: Decrypted message
        :rtype: str
        :raise ValueError: if message cannot be decoded as valid UTF-8
               string

    """
    shared_secret = get_shared_secret(priv, pub)
    aes = init_aes_bts(shared_secret, nonce)
    # Encryption
    raw = py23_bytes(message, 'ascii')
    cleartext = aes.decrypt(unhexlify(raw))
    # TODO, verify checksum
    message = cleartext[4:]
    try:
        return _unpad(message.decode('utf8'), 16)
    except Exception:
        raise ValueError(message)
示例#28
0
 def test_int16(self):
     u = types.Int16(2**15 - 1)
     self.assertEqual(py23_bytes(u), b"\xff\x7f")
     self.assertEqual(str(u), str(2**15 - 1))
示例#29
0
 def test_int64(self):
     u = types.Int64(2**63 - 1)
     self.assertEqual(py23_bytes(u), b"\xff\xff\xff\xff\xff\xff\xff\x7f")
     self.assertEqual(str(u), str(9223372036854775807))
示例#30
0
 def test_uint64(self):
     u = types.Uint64(2**64 - 1)
     self.assertEqual(py23_bytes(u), b"\xff\xff\xff\xff\xff\xff\xff\xff")
     self.assertEqual(str(u), str(2**64 - 1))