Beispiel #1
0
def buildTxApdu(dongle_path, data):
    """
	Generate apdu from data. This apdu is to be sent into the ledger key.

	Argument:
	dongle_path -- value returned by parseBip32Path
	data -- bytes value returned by dposlib.core.crypto.getBytes

	Return bytes
	"""

    path_len = len(dongle_path)

    if len(data) > 255 - (path_len + 1):
        data1 = data[:255 - (path_len + 1)]
        data2 = data[255 - (path_len + 1):]
        p1 = util.unhexlify("e0040040")
    else:
        data1 = data
        data2 = util.unhexlify("")
        p1 = util.unhexlify("e0048040")

    return [
        p1 + util.intasb(1 + path_len + len(data1)) +
        util.intasb(path_len // 4) + dongle_path + data1,
        util.unhexlify("e0048140") + util.intasb(len(data2)) +
        data2 if len(data2) else None
    ]
Beispiel #2
0
def getKeys(secret):
    """
    Generate keyring containing secp256k1 keys-pair and wallet import format
    (WIF).

    Args:
        secret (str, bytes or int): anything that could issue a private key on
            secp256k1 curve.

    Returns:
        dict: public, private and WIF keys.
    """
    if isinstance(secret, int):
        privateKey = "%064x" % secret
        seed = unhexlify(privateKey)
    elif isinstance(secret, str):
        privateKey = secret if HEX.match(secret) else \
            secp256k1.hash_sha256(secret).decode()
        seed = unhexlify(privateKey)
    elif isinstance(secret, bytes):
        privateKey = secret.decode() if BHEX.match(secret) else \
            secp256k1.hash_sha256(secret).decode()
        seed = unhexlify(privateKey)
    publicKey = secp256k1.PublicKey.from_seed(seed)
    return {
        "publicKey": publicKey.encode().decode(),
        "privateKey": privateKey,
        "wif": getWIF(seed)
    }
Beispiel #3
0
def buildSignatureApdu(data, dongle_path, what="tx", schnorr=True):
    apdu = []
    path_len = len(dongle_path)
    payload = len(data) + len(dongle_path) + 1

    if payload > payloadMax:
        raise CommException('Payload size:', payload, 'exceeds max length:',
                            payloadMax)

    data = splitData(data, dongle_path)
    if len(data) == 1:
        first, body, last = data[0], [], None
    else:
        first, body, last = data[0], data[1:-1], data[-1]

    p2 = p2_schnorr_leg if schnorr else p2_ecdsa
    p1 = p1_single if last is None else p1_first
    op = getattr(sys.modules[__name__], "op_sign_" + what)

    apdu.append(
        unhexlify(cla + op + p1 + p2) + intasb(path_len + 1 + len(first)) +
        intasb(path_len // 4) + dongle_path + first)

    for b in body:
        apdu.append(unhexlify(cla + op + p1_more + p2) + intasb(len(b)) + b)

    if last is not None:
        apdu.append(
            unhexlify(cla + op + p1_last + p2) + intasb(len(last)) + last)

    return apdu
Beispiel #4
0
def serialize(tx):
    buf = BytesIO()

    # deal with vendorField
    if "vendorFieldHex" in tx:
        vendorField = unhexlify(tx["vendorFieldHex"])
    else:
        vendorField = tx["vendorField"].encode("utf-8")

    # common part
    pack("<BBBBI", buf, (255, Transaction.VERSION, rest.cfg.pubKeyHash,
                         tx["type"], tx["timestamp"]))
    pack_bytes(buf, unhexlify(tx["senderPublicKey"]))
    pack("<QB", buf, (tx["fee"], len(vendorField)))
    pack_bytes(buf, vendorField)

    # custom part
    pack_bytes(buf, serializePayload(tx))

    #signatures part
    pack_bytes(buf, unhexlify(tx["signature"]))
    if "signSignature" in tx:
        pack_bytes(buf, unhexlify(tx["signSignature"]))
    elif "secondSignature" in tx:
        pack_bytes(buf, unhexlify(tx["secondSignature"]))

    result = buf.getvalue()
    buf.close()
    return result
Beispiel #5
0
 def test_get_id_from_bytes(self):
     self.assertEqual(
         "0091128b8cb24758c8d1ed1dfe9c7ac3713691f54b96ce12ca3cbc675aa13d9a",
         dposlib.core.crypto.getIdFromBytes(
             bin_.unhexlify(TestArkCrypto.signed_tx0_hex))
     ) and self.assertEqual(
         "d6f5208aaf8988b97e12260c554d04a149845f0160aa82d8c53eaa0836d3cf56",
         dposlib.core.crypto.getIdFromBytes(
             bin_.unhexlify(TestArkCrypto.signSigned_tx0_hex)))
Beispiel #6
0
def getAddress(publicKey):
    """
	Computes ARK address from keyring.

	Argument:
	keys (ArkyDict) -- keyring returned by `getKeys`

	Return str
	"""
    ripemd160 = hashlib.new('ripemd160', unhexlify(publicKey)).digest()[:20]
    seed = unhexlify(cfg.marker) + ripemd160
    return base58.b58encode_check(seed)
Beispiel #7
0
def getAddress(publicKey):
    """
	Computes ARK address from keyring.

	Argument:
	publicKey (str) -- public key string

	Return str
	"""
    ripemd160 = hashlib.new('ripemd160', unhexlify(publicKey)).digest()[:20]
    seed = unhexlify(cfg.marker) + ripemd160
    b58 = base58.b58encode_check(seed)
    return b58.decode('utf-8') if isinstance(b58, bytes) else b58
Beispiel #8
0
def serialize(tx, **options):
    """
    Serialize transaction.

    Args:
        tx (dict or Transaction): transaction object.

    Returns:
        bytes: transaction serial representation.
    """
    buf = BytesIO()
    vendorField = tx.get("vendorField", "").encode("utf-8")[:255]
    version = tx.get("version", 1)

    # common part
    pack("<BBB", buf, (0xff, version, cfg.pubkeyHash))
    if version >= 2:
        pack("<IHQ", buf, (
            tx.get("typeGroup", 1),
            tx["type"],
            tx["nonce"],
        ))
    else:
        pack("<BI", buf, (
            tx["type"],
            tx["timestamp"],
        ))
    pack_bytes(buf, unhexlify(tx["senderPublicKey"]))
    pack("<QB", buf, (tx["fee"], len(vendorField)))
    pack_bytes(buf, vendorField)

    # custom part
    pack_bytes(buf, serde.serializePayload(tx))

    # signatures part
    if not options.get("exclude_sig", False):
        pack_bytes(buf, unhexlify(tx.get("signature", "")))
    if not options.get("exclude_second_sig", False):
        pack_bytes(buf, unhexlify(tx.get("signSignature", "")))
    if "signatures" in tx and not options.get("exclude_multi_sig", False):
        if version == 1:
            pack("<B", buf, (0xff, ))
        pack_bytes(buf, b"".join([unhexlify(sig) for sig in tx["signatures"]]))

    # id part
    if "id" in tx:
        pack_bytes(buf, unhexlify(tx.get("id", "")))

    result = buf.getvalue()
    buf.close()
    return result
Beispiel #9
0
    def multiSignWithKey(self, privateKey):
        """
        Add a signature in `signatures` field according to given index and
        privateKey.

        Args:
            privateKey (str): private key as hex string.
        """
        # remove id if any and set fee if needed
        self.pop("id", False)
        if "fee" not in self:
            setFees(self)
        # get public key from private key
        publicKey = dposlib.core.crypto.secp256k1.PublicKey.from_seed(
            unhexlify(privateKey))
        publicKey = hexlify(publicKey.encode())
        # create a multi-signature
        signature = dposlib.core.crypto.getSignatureFromBytes(
            serialize(self,
                      exclude_sig=True,
                      exclude_multi_sig=True,
                      exclude_second_sig=True), privateKey)
        # add multisignature in transaction
        try:
            self.appendMultiSignature(publicKey, signature)
        except Exception:
            raise ValueError("public key %s not allowed here" % publicKey)
Beispiel #10
0
def getSignature(tx, private):
	return hexlify(
		crypto_sign(
			hashlib.sha256(getBytes(tx)).digest(),
			unhexlify(private)
		)[:crypto_sign_BYTES]
	)
Beispiel #11
0
def buildPukApdu(dongle_path):
    path_len = len(dongle_path)
    return \
        unhexlify(cla + op_puk + p1_non_confirm + p2_no_chaincode) + \
        intasb(path_len + 1) + \
        intasb(path_len // 4) + \
        dongle_path
Beispiel #12
0
def _1_9(tx, buf):
    asset = tx.get("asset", {})
    claim = asset.get("claim", False)
    if not claim:
        raise Exception("no claim data found")
    pack_bytes(buf, unhexlify(claim["lockTransactionId"]))
    pack_bytes(buf, claim["unlockSecret"].encode("utf-8"))
Beispiel #13
0
def _2_6(tx, buf):
    asset = tx.get("asset", {})
    data = asset.get("data", {})

    registrationId = unhexlify(asset.get("registrationId", ""))

    try:
        ipfs = data.get("ipfsData", "")
        ipfs = \
            str(ipfs).encode("utf-8") if not isinstance(ipfs, bytes) \
            else ipfs
    except Exception as e:
        raise Exception("bad ipfs hash\n%r" % e)
    try:
        name = data.get("name", "")
        name = \
            str(name).encode("utf-8") if not isinstance(name, bytes) \
            else name
    except Exception as e:
        raise Exception("bad entity name\n%r" % e)

    pack(
        "<BBBB", buf, (
            int(asset.get("type", 0)),
            int(asset.get("subType", 0)),
            int(asset.get("action", 0)),
            len(registrationId)
        )
    )
    pack_bytes(buf, registrationId)
    pack("<B", buf, (len(name), ))
    pack_bytes(buf, name)
    pack("<B", buf, (len(ipfs), ))
    pack_bytes(buf, ipfs)
Beispiel #14
0
def _1_1(tx, buf):
    asset = tx.get("asset", {})
    if "signature" in asset:
        secondPublicKey = asset["signature"]["publicKey"]
    else:
        raise Exception("no secondSecret or secondPublicKey given")
    pack_bytes(buf, unhexlify(secondPublicKey))
Beispiel #15
0
def _9000_0(tx, buf):
    asset = tx["asset"].get("nftCollection", {})

    name = asset["name"]
    if 5 <= len(name) <= 40:
        pack("<B", buf, (len(name), ))
        pack_bytes(buf, name.encode("utf-8"))
    else:
        raise Exception("bad namelength [5-80]: %s" % name)

    description = asset["description"]
    if 5 <= len(description) <= 80:
        pack("<B", buf, (len(description), ))
        pack_bytes(buf, description.encode("utf-8"))
    else:
        raise Exception("bad description length [5-80]: %s" % description)

    pack("<I", buf, (max(1, asset["maximumSupply"]), ))

    jsonSchema = compactJson(asset["jsonSchema"])
    pack("<I", buf, (len(jsonSchema), ))
    pack_bytes(buf, jsonSchema.encode("utf-8"))

    allowedIssuers = asset.get("allowedIssuers", [])[:10]
    pack("<I", buf, (len(allowedIssuers), ))
    for allowedIssuer in allowedIssuers:
        pack_bytes(buf, unhexlify(allowedIssuer))

    metadata = compactJson(asset.get("metadata", {}))
    pack("<I", buf, (len(metadata), ))
    pack_bytes(buf, metadata.encode("utf-8"))
Beispiel #16
0
def setVendorFieldHex(cls, value, encoding="utf-8"):
    value = value.decode(encoding) if isinstance(value, bytes) else value
    if (re.match(r"^[0-9a-fA-F]*$", value) is not None
            and len(value) % 2 == 0):
        cls._reset()
        cls._setitem("vendorField", unhexlify(value).decode(encoding))
    else:
        raise ValueError("'%s' seems not be a valid hex string" % value)
Beispiel #17
0
def verifySignatureFromBytes(data, publicKey, signature):
    """
    Verify signature.

    Args:
        data (bytes): data
        publicKey (str): public key as hex string
        signature (str): signature as hex string
    Returns:
        True if signature matches the public key
    """
    pubkey = unhexlify(publicKey)
    msg = secp256k1.hash_sha256(data)
    sig = unhexlify(signature)
    if len(signature) == 128:
        return schnorr.bcrypto410_verify(msg, pubkey, sig)
    else:
        return ecdsa.verify(msg, pubkey, sig)
Beispiel #18
0
def getAddress(publicKey, marker=None):
    """
    Compute ARK address from publicKey.

    Args:
        publicKey (str): public key
        marker (int): network marker (optional)
    Returns:
        the address
    """
    if marker and isinstance(marker, int):
        marker = hex(marker)[2:]
    else:
        marker = None
    ripemd160 = hashlib.new('ripemd160', unhexlify(publicKey)).digest()[:20]
    seed = unhexlify(cfg.marker if not marker else marker) + ripemd160
    b58 = base58.b58encode_check(seed)
    return b58.decode('utf-8') if isinstance(b58, bytes) else b58
Beispiel #19
0
def _1_3(tx, buf):
    asset = tx.get("asset", {})
    delegatePublicKeys = asset.get("votes", False)
    if delegatePublicKeys:
        pack("<B", buf, (len(delegatePublicKeys), ))
        for delegatePublicKey in delegatePublicKeys:
            delegatePublicKey = delegatePublicKey.replace("+", "01") \
                                .replace("-", "00")
            pack_bytes(buf, unhexlify(delegatePublicKey))
    else:
        raise Exception("no up/down vote given")
Beispiel #20
0
def verifySignature(value, publicKey, signature):
    """
    Verify signature.

    Args:
        value (str): value as hex string
        publicKey (str): public key as hex string
        signature (str): signature as hex string
    Returns:
        True if signature matches the public key
    """
    return verifySignatureFromBytes(unhexlify(value), publicKey, signature)
Beispiel #21
0
def verifySignatureFromBytes(data, publicKey, signature):
    """
	Verify signature.

	Arguments:
	data (bytes) -- data in bytes
	publicKey (str) -- a public key as hex string
	signature (str) -- a signature as hex string

	Return bool
	"""
    if len(publicKey) == 66:
        publicKey = uncompressEcdsaPublicKey(publicKey)
    verifyingKey = VerifyingKey.from_string(unhexlify(publicKey), SECP256k1,
                                            hashlib.sha256)
    try:
        verifyingKey.verify(unhexlify(signature), data, hashlib.sha256,
                            sigdecode_der)
    except (BadSignatureError, UnexpectedDER):
        return False
    return True
Beispiel #22
0
def verifySignature(value, publicKey, signature):
    """
	Verify signature.

	Arguments:
	value (bytes) -- value as hex string in bytes
	publicKey (str) -- a public key as hex string
	signature (str) -- a signature as hex string

	Return bool
	"""
    return verifySignatureFromBytes(unhexlify(value), publicKey, signature)
Beispiel #23
0
def getWIF(seed):
    """
	Computes WIF address from seed.

	Argument:
	seed (bytes) -- a sha256 sequence bytes

	Return str
	"""
    seed = unhexlify(
        cfg.wif) + seed[:32] + (b"\x01" if cfg.compressed else b"")
    return base58.b58encode_check(seed)
Beispiel #24
0
def _9000_1(tx, buf):
    asset = tx["asset"].get("nftToken", {})

    pack_bytes(buf, unhexlify(asset["collectionId"]))

    attributes = compactJson(asset["attributes"])
    pack("<I", buf, (len(attributes), ))
    pack_bytes(buf, attributes.encode("utf-8"))

    recipientId = asset.get("recipientId", "")
    pack("<B", buf, (len(recipientId), ))
    if recipientId:
        pack_bytes(buf, recipientId.encode("utf-8"))
Beispiel #25
0
def buildPkeyApdu(dongle_path):
    """
	Generate apdu to get public key from ledger key.

	Argument:
	dongle_path -- value returned by parseBip32Path

	Return bytes
	"""

    path_len = len(dongle_path)
    return util.unhexlify("e0020040") + util.intasb(1 + path_len) + \
           util.intasb(path_len//4) + dongle_path
Beispiel #26
0
def getWIF(seed):
    """
    Compute WIF address from seed.

    Args:
        seed (bytes): a sha256 sequence bytes
    Returns:
        WIF address
    """
    if hasattr(cfg, "wif"):
        seed = unhexlify(cfg.wif) + seed[:32] + b"\x01"  # \x01 -> compressed
        b58 = base58.b58encode_check(seed)
        return str(b58.decode('utf-8') if isinstance(b58, bytes) else b58)
Beispiel #27
0
def getBytes(tx):
	buf = BytesIO()

	# write type and timestamp
	pack("<bi", buf, (tx["type"], tx["timestamp"]))
	# write senderPublicKey as bytes in buffer
	pack_bytes(buf, unhexlify(tx["senderPublicKey"]))
	# if there is a requesterPublicKey
	if "requesterPublicKey" in tx:
		pack_bytes(buf, unhexlify(tx["requesterPublicKey"]))
	# if there is a recipientId
	if "recipientId" in tx:
		pack(">Q", buf, (int(tx["recipientId"][:-len(cfg.marker)]),))
	else:
		pack(">Q", buf, (0,))
	# write amount
	pack("<Q", buf, (int(tx["amount"]),))
	# if there is asset data
	if tx.get("asset", False):
		asset = tx["asset"]
		typ = tx["type"]
		if typ == 1 and "signature" in asset:
			pack_bytes(buf, unhexlify(asset["signature"]["publicKey"]))
		elif typ == 2 and "delegate" in asset:
			pack_bytes(buf, asset["delegate"]["username"].encode("utf-8"))
		elif typ == 3 and "votes" in asset:
			pack_bytes(buf, "".join(asset["votes"]).encode("utf-8"))
		else:
			pass
	# if there is a signature
	if tx.get("signature", False):
		pack_bytes(buf, unhexlify(tx["signature"]))
	# if there is a second signature
	if tx.get("signSignature", False):
		pack_bytes(buf, unhexlify(tx["signSignature"]))

	result = buf.getvalue()
	buf.close()
	return result
Beispiel #28
0
def _9000_2(tx, buf):
    asset = tx["asset"].get("nftTransfer", {})

    nftIds = asset["nftIds"][0:10]
    pack("<B", buf, (len(nftIds), ))
    for nftId in nftIds:
        pack_bytes(buf, unhexlify(nftId))

    recipientId = \
        str(tx["recipientId"]) \
        if not isinstance(tx["recipientId"], bytes) \
        else tx["recipientId"]
    recipientId = base58.b58decode_check(recipientId)
    pack_bytes(buf, recipientId)
Beispiel #29
0
def _1_4(tx, buf):
    asset = tx.get("asset", {})
    multiSignature = asset.get("multiSignature", False)
    if multiSignature:
        pack(
            "<BB", buf, (
                multiSignature["min"],
                len(multiSignature["publicKeys"])
            )
        )
        pack_bytes(
            buf, b"".join(
                [unhexlify(sig) for sig in multiSignature["publicKeys"]]
            )
        )
Beispiel #30
0
def getSignatureFromBytes(data, privateKey):
    """
	Generate data signature using private key.

	Arguments:
	data (bytes) -- data in bytes
	privateKey (str) -- a private key as hex string

	Return str
	"""
    signingKey = SigningKey.from_string(unhexlify(privateKey), SECP256k1,
                                        hashlib.sha256)
    return hexlify(
        signingKey.sign_deterministic(data,
                                      hashlib.sha256,
                                      sigencode=sigencode_der_canonize))