コード例 #1
0
def encrypt(privkey, passphrase):
    """ BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted privkey.

    :param privkey: Private key
    :type privkey: Base58
    :param str passphrase: UTF-8 encoded passphrase for encryption
    :return: BIP0038 non-ec-multiply encrypted wif key
    :rtype: Base58

    """
    privkeyhex = repr(privkey)  # hex
    addr = format(privkey.uncompressed.address, "BTC")
    a = compat_bytes(addr, 'ascii')
    salt = hashlib.sha256(hashlib.sha256(a).digest()).digest()[0:4]
    if SCRYPT_MODULE == "scrypt":
        if sys.version >= '3.0.0':
            key = scrypt.hash(passphrase, salt, 16384, 8, 8)
        else:
            key = scrypt.hash(str(passphrase), str(salt), 16384, 8, 8)
    elif SCRYPT_MODULE == "pylibscrypt":
        key = scrypt.scrypt(compat_bytes(passphrase, "utf-8"), salt, 16384, 8,
                            8)
    else:
        raise ValueError("No scrypt module loaded")
    (derived_half1, derived_half2) = (key[:32], key[32:])
    aes = AES.new(derived_half2)
    encrypted_half1 = _encrypt_xor(privkeyhex[:32], derived_half1[:16], aes)
    encrypted_half2 = _encrypt_xor(privkeyhex[32:], derived_half1[16:], aes)
    " flag byte is forced 0xc0 because Graphene only uses compressed keys "
    payload = (b'\x01' + b'\x42' + b'\xc0' + salt + encrypted_half1 +
               encrypted_half2)
    " Checksum "
    checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
    privatekey = hexlify(payload + checksum).decode('ascii')
    return Base58(privatekey)
コード例 #2
0
 def __bytes__(self):
     if not self.data:
         return compat_bytes(Bool(0))
     else:
         return compat_bytes(Bool(1)) + compat_bytes(
             self.data) if compat_bytes(self.data) else compat_bytes(
                 Bool(0))
コード例 #3
0
def varint(n):
    """ Varint encoding
    """
    data = b''
    while n >= 0x80:
        data += compat_bytes([(n & 0x7f) | 0x80])
        n >>= 7
    data += compat_bytes([n])
    return data
コード例 #4
0
 def __bytes__(self):
     if self.data is None:
         return bytes()
     b = b""
     for name, value in self.data.items():
         if isinstance(value, str):
             b += compat_bytes(value, 'utf-8')
         else:
             b += compat_bytes(value)
     return b
コード例 #5
0
 def compressed(self):
     """ Derive compressed public key """
     order = ecdsa.SECP256k1.generator.order()
     p = ecdsa.VerifyingKey.from_string(
         compat_bytes(self), curve=ecdsa.SECP256k1).pubkey.point
     x_str = ecdsa.util.number_to_string(p.x(), order)
     # y_str = ecdsa.util.number_to_string(p.y(), order)
     compressed = hexlify(
         compat_bytes(compat_chr(2 + (p.y() & 1)), 'ascii') + x_str).decode('ascii')
     return (compressed)
コード例 #6
0
    def verify(self, pubkeys=[], chain=None):
        if not chain:
            raise ValueError("Chain needs to be provided!")
        chain_params = self.getChainParams(chain)
        self.deriveDigest(chain)
        signatures = self.data["signatures"].data
        pubKeysFound = []

        for signature in signatures:
            sig = compat_bytes(signature)[1:]
            if sys.version >= '3.0':
                recoverParameter = (compat_bytes(signature)[0]) - 4 - 27  # recover parameter only
            else:
                recoverParameter = ord((compat_bytes(signature)[0])) - 4 - 27

            if USE_SECP256K1:
                ALL_FLAGS = secp256k1.lib.SECP256K1_CONTEXT_VERIFY | \
                            secp256k1.lib.SECP256K1_CONTEXT_SIGN
                # Placeholder
                pub = secp256k1.PublicKey(flags=ALL_FLAGS)
                # Recover raw signature
                sig = pub.ecdsa_recoverable_deserialize(sig, recoverParameter)
                # Recover PublicKey
                verifyPub = secp256k1.PublicKey(
                    pub.ecdsa_recover(compat_bytes(self.message), sig))
                # Convert recoverable sig to normal sig
                normalSig = verifyPub.ecdsa_recoverable_convert(sig)
                # Verify
                verifyPub.ecdsa_verify(compat_bytes(self.message), normalSig)
                phex = hexlify(
                    verifyPub.serialize(compressed=True)).decode('ascii')
                pubKeysFound.append(phex)
            else:
                p = self.recover_public_key(self.digest, sig, recoverParameter)
                # Will throw an exception of not valid
                p.verify_digest(
                    sig, self.digest, sigdecode=ecdsa.util.sigdecode_string)
                phex = hexlify(self.compressedPubkey(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
コード例 #7
0
def decrypt(encrypted_privkey, passphrase):
    """BIP0038 non-ec-multiply decryption. Returns WIF privkey.

    :param Base58 encrypted_privkey: Private key
    :param str passphrase: UTF-8 encoded passphrase for decryption
    :return: BIP0038 non-ec-multiply decrypted key
    :rtype: Base58
    :raises SaltException: if checksum verification failed (e.g. wrong
    password)

    """

    d = unhexlify(base58decode(encrypted_privkey))
    d = d[2:]  # remove trailing 0x01 and 0x42
    flagbyte = d[0:1]  # get flag byte
    d = d[1:]  # get payload
    assert flagbyte == b'\xc0', "Flagbyte has to be 0xc0"
    salt = d[0:4]
    d = d[4:-4]
    if SCRYPT_MODULE == "scrypt":
        if sys.version >= '3.0.0':
            key = scrypt.hash(passphrase, salt, 16384, 8, 8)
        else:
            key = scrypt.hash(str(passphrase), str(salt), 16384, 8, 8)
    elif SCRYPT_MODULE == "pylibscrypt":
        key = scrypt.scrypt(compat_bytes(passphrase, "utf-8"), salt, 16384, 8,
                            8)
    else:
        raise ValueError("No scrypt module loaded")
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]
    encryptedhalf1 = d[0:16]
    encryptedhalf2 = d[16:32]
    aes = AES.new(derivedhalf2)
    decryptedhalf2 = aes.decrypt(encryptedhalf2)
    decryptedhalf1 = aes.decrypt(encryptedhalf1)
    privraw = decryptedhalf1 + decryptedhalf2
    privraw = ('%064x' %
               (int(hexlify(privraw), 16) ^ int(hexlify(derivedhalf1), 16)))
    wif = Base58(privraw)
    """ Verify Salt """
    privkey = PrivateKey(format(wif, "wif"))
    addr = format(privkey.uncompressed.address, "BTC")
    a = compat_bytes(addr, 'ascii')
    saltverify = hashlib.sha256(hashlib.sha256(a).digest()).digest()[0:4]
    if saltverify != salt:
        raise SaltException(
            'checksum verification failed! Password may be incorrect.')
    return wif
コード例 #8
0
 def get_private(self):
     """ Derive private key from the brain key and the current sequence
         number
     """
     a = compat_bytes(self.account + self.role + self.password, 'utf8')
     s = hashlib.sha256(a).digest()
     return PrivateKey(hexlify(s).decode('ascii'))
コード例 #9
0
    def get_private(self):
        """ Derive private key from the brain key and the current sequence
            number
        """
        encoded = "%s %d" % (self.brainkey, self.sequence)
        a = compat_bytes(encoded, 'ascii')

        s = hashlib.sha256(hashlib.sha512(a).digest()).digest()
        return PrivateKey(hexlify(s).decode('ascii'))
コード例 #10
0
def base58encode(hexstring):
    byteseq = compat_bytes(hexstring, 'ascii')
    byteseq = unhexlify(byteseq)
    byteseq = compat_bytes(byteseq)

    n = 0
    leading_zeroes_count = 0
    for c in byteseq:
        n = n * 256 + c
        if n == 0:
            leading_zeroes_count += 1
    res = bytearray()
    while n >= 58:
        div, mod = divmod(n, 58)
        res.insert(0, BASE58_ALPHABET[mod])
        n = div
    else:
        res.insert(0, BASE58_ALPHABET[n])

    return (BASE58_ALPHABET[0:1] * leading_zeroes_count + res).decode('ascii')
コード例 #11
0
ファイル: memo.py プロジェクト: thomascherickal/smoke-python
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

    """
    from smokebase import transactions
    shared_secret = get_shared_secret(priv, pub)
    aes, check = init_aes(shared_secret, nonce)
    raw = compat_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 = OrderedDict([
        ("from", format(priv.pubkey, prefix)),
        ("to", format(pub, prefix)),
        ("nonce", nonce),
        ("check", check),
        ("encrypted", cipher),
        ("from_priv", repr(priv)),
        ("to_pub", repr(pub)),
        ("shared_secret", shared_secret),
    ])
    tx = Memo(**s)

    return "#" + base58encode(hexlify(compat_bytes(tx)).decode("ascii"))
コード例 #12
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 formatted data according to
        #   GrapheneObject and the data given in __init__()
        self.message = unhexlify(self.chainid) + compat_bytes(self)
        self.digest = hashlib.sha256(self.message).digest()

        # restore signatures
        self.data["signatures"] = sigs
コード例 #13
0
ファイル: memo.py プロジェクト: thomascherickal/smoke-python
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 "
    assert check == checksum, "Checksum failure"

    " Encryption "
    # remove the varint prefix (FIXME, long messages!)
    message = cipher[2:]
    message = aes.decrypt(unhexlify(compat_bytes(message, 'ascii')))
    try:
        return _unpad(message.decode('utf8'), 16)
    except:  # noqa FIXME(sneak)
        raise ValueError(message)
コード例 #14
0
 def unicodify(self):
     r = []
     for s in self.data:
         o = ord(s)
         if o <= 7:
             r.append("u%04x" % o)
         elif o == 8:
             r.append("b")
         elif o == 9:
             r.append("\t")
         elif o == 10:
             r.append("\n")
         elif o == 11:
             r.append("u%04x" % o)
         elif o == 12:
             r.append("f")
         elif o == 13:
             r.append("\r")
         elif 13 < o < 32:
             r.append("u%04x" % o)
         else:
             r.append(s)
     return compat_bytes("".join(r), "utf-8")
コード例 #15
0
 def __bytes__(self):
     """ Returns the raw private key """
     return compat_bytes(self._wif)
コード例 #16
0
 def __bytes__(self):
     """ Returns the raw public key (has length 33)"""
     return compat_bytes(self._pk)
コード例 #17
0
 def __bytes__(self):
     return compat_bytes(Id(self.opId)) + compat_bytes(self.op)
コード例 #18
0
 def __bytes__(self):
     return compat_bytes(self.length) + b"".join(
         [compat_bytes(a) for a in self.data])
コード例 #19
0
ファイル: memo.py プロジェクト: thomascherickal/smoke-python
def _unpad(s, BS):
    count = int(struct.unpack('B', compat_bytes(s[-1], 'ascii'))[0])
    if compat_bytes(s[-count::], 'ascii') == count * struct.pack('B', count):
        return s[:-count]
    return s
コード例 #20
0
    def sign(self, wifkeys, chain=None):
        """ Sign the transaction with the provided private keys.

            :param list wifkeys: Array of wif keys
            :param str chain: identifier for the chain

        """
        if not chain:
            raise ValueError("Chain needs to be provided!")
        self.deriveDigest(chain)

        # Get Unique private keys
        self.privkeys = []
        [
            self.privkeys.append(item) for item in wifkeys
            if item not in self.privkeys
        ]

        # Sign the message with every private key given!
        sigs = []
        for wif in self.privkeys:
            p = compat_bytes(PrivateKey(wif))
            i = 0
            if USE_SECP256K1:
                ndata = secp256k1.ffi.new("const int *ndata")
                ndata[0] = 0
                while True:
                    ndata[0] += 1
                    privkey = secp256k1.PrivateKey(p, raw=True)
                    sig = secp256k1.ffi.new(
                        'secp256k1_ecdsa_recoverable_signature *')
                    signed = secp256k1.lib.secp256k1_ecdsa_sign_recoverable(
                        privkey.ctx, sig, self.digest, privkey.private_key,
                        secp256k1.ffi.NULL, ndata)
                    assert signed == 1
                    signature, i = privkey.ecdsa_recoverable_serialize(sig)
                    if self._is_canonical(signature):
                        i += 4  # compressed
                        i += 27  # compact
                        break
            else:
                cnt = 0
                sk = ecdsa.SigningKey.from_string(p, curve=ecdsa.SECP256k1)
                while 1:
                    cnt += 1
                    if not cnt % 20:
                        log.info("Still searching for a canonical signature. "
                                 "Tried %d times already!" % cnt)

                    # Deterministic k
                    k = ecdsa.rfc6979.generate_k(
                        sk.curve.generator.order(),
                        sk.privkey.secret_multiplier,
                        hashlib.sha256,
                        hashlib.sha256(
                            self.digest + struct.pack("d", time.time(
                            ))  # use the local time to randomize the signature
                        ).digest())

                    # Sign message
                    #
                    sigder = sk.sign_digest(
                        self.digest, sigencode=ecdsa.util.sigencode_der, k=k)

                    # Reformating of signature
                    #
                    r, s = ecdsa.util.sigdecode_der(sigder,
                                                    sk.curve.generator.order())
                    signature = ecdsa.util.sigencode_string(
                        r, s, sk.curve.generator.order())

                    # This line allows us to convert a 2.7 byte array(which is just binary) to an array of byte values.
                    # We can then use the elements in sigder as integers, as in the following two lines.
                    sigder = array.array('B', sigder)

                    # Make sure signature is canonical!
                    #
                    lenR = sigder[3]
                    lenS = sigder[5 + lenR]
                    if lenR is 32 and lenS is 32:
                        # Derive the recovery parameter
                        #
                        i = self.recoverPubkeyParameter(
                            self.digest, signature, sk.get_verifying_key())
                        i += 4  # compressed
                        i += 27  # compact
                        break

            # pack signature
            #
            sigstr = struct.pack("<B", i)
            sigstr += signature

            sigs.append(Signature(sigstr))

        self.data["signatures"] = Array(sigs)
        return self
コード例 #21
0
 def __bytes__(self):
     # FIXME constraint data to self.length
     d = unhexlify(compat_bytes(self.data, 'utf-8'))
     return varint(len(d)) + d
コード例 #22
0
 def __bytes__(self):
     return varint(self.type_id) + compat_bytes(self.data)
コード例 #23
0
 def __bytes__(self):
     return compat_bytes(self.data)
コード例 #24
0
 def compressedPubkey(self, pk):
     order = pk.curve.generator.order()
     p = pk.pubkey.point
     x_str = ecdsa.util.number_to_string(p.x(), order)
     return compat_bytes(compat_chr(2 + (p.y() & 1)), 'ascii') + x_str
コード例 #25
0
 def isempty(self):
     if not self.data:
         return True
     return not bool(compat_bytes(self.data))
コード例 #26
0
 def deriveChecksum(self, s):
     """ Derive the checksum
     """
     checksum = hashlib.sha256(compat_bytes(s, "ascii")).hexdigest()
     return checksum[:4]
コード例 #27
0
 def __bytes__(self):
     b = b""
     b += varint(len(self.data))
     for e in self.data:
         b += compat_bytes(e[0]) + compat_bytes(e[1])
     return b
コード例 #28
0
 def __bytes__(self):
     """ Returns the raw content of the ``Base58CheckEncoded`` address """
     if self._address is None:
         return compat_bytes(self.derivesha512address())
     else:
         return compat_bytes(self._address)
コード例 #29
0
 def __bytes__(self):
     return compat_bytes(self.instance)  # only yield instance
コード例 #30
0
 def __bytes__(self):
     # padding
     asset = self.asset + "\x00" * (7 - len(self.asset))
     amount = round(float(self.amount) * 10**self.precision)
     return (struct.pack("<q", amount) + struct.pack("<b", self.precision) +
             compat_bytes(asset, "ascii"))