Ejemplo n.º 1
0
def ecdsa_raw_verify_one_to_one(msghash, vrs, sender_pub, receiver_priv):
    v, r, s = vrs
    w = bitcoin.inv(s, N)
    z = bitcoin.hash_to_int(msghash)
    u1, u2 = z * w % N, r * w % N
    receiver_pub = bitcoin.decode_pubkey(bitcoin.privtopub(receiver_priv))
    receiver_sender_shared = bitcoin.fast_multiply(
        bitcoin.decode_pubkey(sender_pub),
        bitcoin.decode_privkey(receiver_priv))
    u1Qr = bitcoin.fast_multiply(receiver_pub, u1)
    u2Qs = bitcoin.fast_multiply(receiver_sender_shared, u2)
    x, y = bitcoin.fast_add(u1Qr, u2Qs)
    return bool(r == x and (r % N) and (s % N))
Ejemplo n.º 2
0
def becies_decode(encodedstr):
    if (encodedstr[:3] != BECIES_MAGIC_BYTES):
        raise "BECIES magic header not found"
    encodedstr = encodedstr[3:]

    flags, o = _from_vli(encodedstr)
    encodedstr = encodedstr[o:]

    isaddresses = flags & BECIES_ADDRESSES_FLAG
    isgroup = flags & BECIES_GROUP_FLAG
    addresses = []
    offsets = []
    num_to_activate = None
    if (isaddresses):
        num_addresses, o = _from_vli(encodedstr)
        encodedstr = encodedstr[o:]
        addresses = [encodedstr[i:i + 20] for i in range(0, num_addresses, 20)]
        encodedstr = encodedstr[(num_addresses * 20):]
    if (isgroup):
        num_to_activate, o = _from_vli(encodedstr)
        encodedstr = encodedstr[o:]
        num_offsets, o = _from_vli(encodedstr)
        offsets = [encodedstr[i:i + n] for i in range(0, num_addresses, 32)]
        encodedstr = encodedstr[(num_offsets * 32):]
    ephemeral_pubkey = encodedstr[:33]
    encodedstr = encodedstr[33:]
    ephemeral_pubkey = bitcoin.decode_pubkey(ephemeral_pubkey)
    lcipher, o = _from_vli(encodedstr)
    encodedstr = encodedstr[o:]
    ciphertext = encodedstr[:lcipher]
    encodedstr = encodedstr[o:]
    tag = encodedstr
    return ephemeral_pubkey, ciphertext, tag, addresses, num_to_activate, offsets
Ejemplo n.º 3
0
 def __init__(self, public_key):
     pubkey_points = bitcoin.decode_pubkey(binascii.unhexlify(public_key), 'bin')
     pubx = pubkey_points[0]
     puby = pubkey_points[1]
     edcsa = ECDSA.secp256r1()
     self.PublicKey = edcsa.Curve.point(pubx, puby)
     self.PublicKeyHash = Crypto.ToScriptHash(self.PublicKey.encode_point(True), unhex=True)
Ejemplo n.º 4
0
    def __init__(self, private_key: bytes):
        self.private_key = private_key
        self.public_key = None

        bitcoin.change_curve(
            115792089210356248762697446949407573530086143415290314195533631308867097853951,
            115792089210356248762697446949407573529996955224135760342422259061068512044369,
            115792089210356248762697446949407573530086143415290314195533631308867097853948,
            41058363725152142129326129780047268409114441015993725554835256314039467401291,
            48439561293906451759052585252797914202762949526041747995844080717082404635286,
            36134250956749795798585127919587881956611106672985015071877198253568414405109
        )

        length = len(self.private_key)

        if length != 32:
            raise ValueError("Invalid private key")

        if length == 32:
            try:
                pubkey_encoded_not_compressed = bitcoin.privkey_to_pubkey(
                    private_key)
                pubkey_points = bitcoin.decode_pubkey(
                    pubkey_encoded_not_compressed, 'bin')

                pubx = pubkey_points[0]
                puby = pubkey_points[1]
                self.public_key = cryptography.ECDSA.secp256r1().Curve.point(
                    pubx, puby)
            except Exception:
                raise ValueError("Could not determine public key")
Ejemplo n.º 5
0
def generate_keyfiles(n, m, vf, sf):
    '''Generate a set of public and private keys
    for testing.
    n - the number of OR loops
    m - the number of keys per loop (note: constant in this crude version)
    vf - the file path to which to write the verification keys
    sf - the file path to which to write the signing (private) keys
    '''
    signing_indices = [random.choice(range(m)) for _ in range(n)]
    priv=[]
    with open(sf,'wb') as f:
	for i in range(n):
	    priv.append(os.urandom(32))
	    f.write(binascii.hexlify(priv[i])+'\n')    
    with open(vf,'wb') as f:
	for i in range(n):
	    pubkeys = []
	    for j in range(m):
		if j==signing_indices[i]:
		    p = btc.privtopub(priv[i])
		else:
		    p = btc.privtopub(os.urandom(32))
		p = btc.decode_pubkey(p)
		p = btc.encode_pubkey(p,'bin_compressed')
		pubkeys.append(binascii.hexlify(p))
	    f.write(','.join(pubkeys)+'\n')
Ejemplo n.º 6
0
    def __init__(self, priv_key=None):
        """
        Create an instance
        :param priv_key: a private key
        """

        if priv_key is None:
            priv_key = bytes(random_bytes(32))

        length = len(priv_key)

        if length != 32:  # Just handle 32 byte version
            raise ValueError("Invalid private key length")

        self.PrivateKey = bytearray(priv_key[-32:])  #Get last 32 bytes

        try:
            pubkey_encoded_not_compressed = bitcoin.privkey_to_pubkey(priv_key)
        except Exception as e:
            raise Exception("Could not determine public key")

        if pubkey_encoded_not_compressed:
            pubkey_points = bitcoin.decode_pubkey(
                pubkey_encoded_not_compressed, 'bin')

            pubx = pubkey_points[0]
            puby = pubkey_points[1]
            edcsa = ECDSA.secp256r1()
            self.PublicKey = edcsa.Curve.point(pubx, puby)
Ejemplo n.º 7
0
def generate_keyfiles(n, m, vf, sf):
    '''Generate a set of public and private keys
    for testing.
    n - the number of OR loops
    m - the number of keys per loop (note: constant in this crude version)
    vf - the file path to which to write the verification keys
    sf - the file path to which to write the signing (private) keys
    '''
    signing_indices = [random.choice(range(m)) for _ in range(n)]
    priv = []
    with open(sf, 'wb') as f:
        for i in range(n):
            priv.append(os.urandom(32))
            f.write(binascii.hexlify(priv[i]) + '\n')
    with open(vf, 'wb') as f:
        for i in range(n):
            pubkeys = []
            for j in range(m):
                if j == signing_indices[i]:
                    p = btc.privtopub(priv[i])
                else:
                    p = btc.privtopub(os.urandom(32))
                p = btc.decode_pubkey(p)
                p = btc.encode_pubkey(p, 'bin_compressed')
                pubkeys.append(binascii.hexlify(p))
            f.write(','.join(pubkeys) + '\n')
Ejemplo n.º 8
0
 def decode(public_value_compressed_base58):
     """
     Decode the base58 public_value to the decimal x and y values
     """
     public_value_compressed_hex = binascii.hexlify(base58.b58decode(public_value_compressed_base58))
     public_value_x, public_value_y = bitcoin.decode_pubkey(public_value_compressed_hex.decode())
     return (public_value_x, public_value_y)
Ejemplo n.º 9
0
 def decode(public_value_compressed_base58):
     """
     Decode the base58 public_value to the decimal x and y values
     """
     public_value_compressed_hex = binascii.hexlify(base58.b58decode(public_value_compressed_base58))
     public_value_x, public_value_y = bitcoin.decode_pubkey(public_value_compressed_hex.decode())
     return (public_value_x, public_value_y)
Ejemplo n.º 10
0
def ecdsa_raw_sign_one_to_one(msghash, sender_priv, receiver_pub):
    z = bitcoin.hash_to_int(msghash)
    k = bitcoin.deterministic_generate_k(msghash, sender_priv)
    r, y = bitcoin.fast_multiply(bitcoin.decode_pubkey(receiver_pub), k)
    s = bitcoin.inv(k, N) * (z + r * bitcoin.decode_privkey(sender_priv)) % N
    v, r, s = 27 + ((y % 2) ^
                    (0 if s * 2 < N else 1)), r, s if s * 2 < N else N - s
    return v, r, s
Ejemplo n.º 11
0
def ringsig_sign_substitute(msghash, priv, pub_xs, pub_ys):
    # Number of pubkeys
    n = len(pub_xs)
    # Create list of pubkeys as (x, y) points
    pubs = [(pub_xs[i], recover_y(pub_xs[i], bit(pub_ys, i)))
            for i in range(n)]
    # My pubkey
    my_pub = b.decode_pubkey(b.privtopub(priv))
    # Compute my index in the pubkey list
    my_index = 0
    while my_index < n:
        if pubs[my_index] == my_pub:
            break
        my_index += 1
    assert my_index < n
    # Compute the signer's I value
    I = b.multiply(hash_to_pubkey(list(my_pub)), priv)
    # Select a random ephemeral key
    k = b.hash_to_int(b.random_key())
    # Store the list of intermediate values in the "ring"
    e = [None] * n
    # Compute the entry in the ring corresponding to the signer's index
    kpub = b.privtopub(k)
    kmulpub = b.multiply(hash_to_pubkey(list(my_pub)), k)
    orig_left = hash_array([msghash, kpub[0], kpub[1], kmulpub[0], kmulpub[1]])
    orig_right = hash_value(orig_left)
    e[my_index] = {"left": orig_left, "right": orig_right}
    # Map of intermediate s values (part of the signature)
    s = [None] * n
    for i in list(range(my_index + 1, n)) + list(range(my_index + 1)):
        prev_i = (i - 1) % n
        # In your position in the ring, set the s value based on your private
        # knowledge of k; this lets you "invert" the hash function in order to
        # ensure a consistent ring. At all other positions, select a random s
        if i == my_index:
            s[prev_i] = b.add_privkeys(
                k, b.mul_privkeys(e[prev_i]["right"], priv))
        else:
            s[prev_i] = b.hash_to_int(b.random_key())
        # Create the next values in the ring based on the chosen s value
        pub1 = b.subtract_pubkeys(b.privtopub(s[prev_i]),
                                  b.multiply(pubs[i], e[prev_i]["right"]))
        pub2 = b.subtract_pubkeys(
            b.multiply(hash_to_pubkey(list(pubs[i])), s[prev_i]),
            b.multiply(I, e[prev_i]["right"]))
        left = hash_array([msghash, pub1[0], pub1[1], pub2[0], pub2[1]])
        right = hash_value(left)
        e[i] = {"left": left, "right": right}
    # Check that the ring is consistent
    assert (left, right) == (orig_left, orig_right)
    # Return the first value in the ring, the s values, and the signer's
    # I value in compressed form
    return (e[0]["left"], s, I[0], I[1] % 2)
Ejemplo n.º 12
0
def import_keys(vf, sf=None):
    '''Import the verification keys;
    one list of pubkeys per loop in hex format, comma separated
    the first pubkey in each list is to be understood as the input
    for the connecting node.    
    vf - the path to the file containing verification pubkeys
    sf - the path to the file containing signing keys, if applicable.
    Returns:
    vks - set of verification keys
    signing_indices - the indices corresponding to the private keys
    sks - the list of private keys
    '''
    vks = {}
    with open(vf, 'rb') as f:
        or_loops = f.readlines()
        for i, loop in enumerate(or_loops):
            raw_pks = loop.strip().split(',')
            vks[i] = [btc.decode_pubkey(pk) for pk in raw_pks]
    if not sf:
        return (vks, None, None)
    #import the signing private keys;
    #at least one per loop
    with open(sf, 'rb') as f:
        raw_sks = f.readlines()
        sks = [binascii.unhexlify(priv.strip()) for priv in raw_sks]
    #check that the signing keys have the right configuration
    if not len(sks) == len(vks):
        raise Exception("Need " + str(len(vks)) +
                        " signing keys for a valid signature, got " +
                        str(len(sks)))
    sk_pks = [btc.decode_pubkey(btc.privtopub(sk)) for sk in sks]
    signing_indices = []
    for loop in vks:
        if not len(set(vks[loop]).intersection(set(sk_pks))) == 1:
            raise Exception(
                "Verification key loop does not contain a signing key.")
        signing_indices.append(
            [x for x, item in enumerate(vks[loop]) if item in sk_pks][0])
    #signing keys have right configuration relative to verification keys.
    return (vks, signing_indices, sks)
Ejemplo n.º 13
0
def ringsig_sign_substitute(msghash, priv, pub_xs, pub_ys):
    # Number of pubkeys
    n = len(pub_xs)
    # Create list of pubkeys as (x, y) points
    pubs = [(pub_xs[i], recover_y(pub_xs[i], bit(pub_ys, i))) for i in range(n)]
    # My pubkey
    my_pub = b.decode_pubkey(b.privtopub(priv))
    # Compute my index in the pubkey list
    my_index = 0
    while my_index < n:
        if pubs[my_index] == my_pub:
            break
        my_index += 1
    assert my_index < n
    # Compute the signer's I value
    I = b.multiply(hash_to_pubkey(list(my_pub)), priv)
    # Select a random ephemeral key
    k = b.hash_to_int(b.random_key())
    # Store the list of intermediate values in the "ring"
    e = [None] * n
    # Compute the entry in the ring corresponding to the signer's index
    kpub = b.privtopub(k)
    kmulpub = b.multiply(hash_to_pubkey(list(my_pub)), k)
    orig_left = hash_array([msghash, kpub[0], kpub[1], kmulpub[0], kmulpub[1]])
    orig_right = hash_value(orig_left)
    e[my_index] = {"left": orig_left, "right": orig_right}
    # Map of intermediate s values (part of the signature)
    s = [None] * n
    for i in list(range(my_index + 1, n)) + list(range(my_index + 1)):
        prev_i = (i - 1) % n
        # In your position in the ring, set the s value based on your private
        # knowledge of k; this lets you "invert" the hash function in order to
        # ensure a consistent ring. At all other positions, select a random s
        if i == my_index:
            s[prev_i] = b.add_privkeys(k, b.mul_privkeys(e[prev_i]["right"], priv))
        else:
            s[prev_i] = b.hash_to_int(b.random_key())
        # Create the next values in the ring based on the chosen s value
        pub1 = b.subtract_pubkeys(b.privtopub(s[prev_i]),
                                  b.multiply(pubs[i], e[prev_i]["right"]))
        pub2 = b.subtract_pubkeys(b.multiply(hash_to_pubkey(list(pubs[i])), s[prev_i]),
                                  b.multiply(I, e[prev_i]["right"]))
        left = hash_array([msghash, pub1[0], pub1[1], pub2[0], pub2[1]])
        right = hash_value(left)
        e[i] = {"left": left, "right": right}
    # Check that the ring is consistent
    assert (left, right) == (orig_left, orig_right)
    # Return the first value in the ring, the s values, and the signer's
    # I value in compressed form
    return (e[0]["left"], s, I[0], I[1] % 2)
Ejemplo n.º 14
0
    def __init__(self, priv_key):
        """
        Create an instance.

        Args:
            priv_key (bytes): a private key.

        Raises:
            ValueError:
                if the input `priv_key` length is not 32, 96, or 104
                if the input `priv_key` length is 32 but the public key still could not be determined
        """
        self.setup_curve()
        self.PublicKeyHash = None
        self.PublicKey = None
        self.PrivateKey = None

        length = len(priv_key)

        if length != 32 and length != 96 and length != 104:
            raise ValueError("Invalid private key")

        self.PrivateKey = bytearray(priv_key[-32:])

        pubkey_encoded_not_compressed = None

        if length == 32:
            try:
                pubkey_encoded_not_compressed = bitcoin.privkey_to_pubkey(
                    priv_key)
            except Exception:
                raise ValueError("Could not determine public key")

        elif length == 96 or length == 104:
            skip = length - 96
            pubkey_encoded_not_compressed = bytearray(b'\x04') + bytearray(
                priv_key[skip:skip + 64])

        if pubkey_encoded_not_compressed:
            pubkey_points = bitcoin.decode_pubkey(
                pubkey_encoded_not_compressed, 'bin')

            pubx = pubkey_points[0]
            puby = pubkey_points[1]
            edcsa = ECDSA.secp256r1()
            self.PublicKey = edcsa.Curve.point(pubx, puby)

        self.PublicKeyHash = Crypto.ToScriptHash(
            self.PublicKey.encode_point(True), unhex=True)
Ejemplo n.º 15
0
def import_keys(vf, sf=None):
    '''Import the verification keys;
    one list of pubkeys per loop in hex format, comma separated
    the first pubkey in each list is to be understood as the input
    for the connecting node.    
    vf - the path to the file containing verification pubkeys
    sf - the path to the file containing signing keys, if applicable.
    Returns:
    vks - set of verification keys
    signing_indices - the indices corresponding to the private keys
    sks - the list of private keys
    '''
    vks = {}
    with open(vf,'rb') as f:
	or_loops = f.readlines()
	for i,loop in enumerate(or_loops):
	    raw_pks = loop.strip().split(',')
	    vks[i] = [btc.decode_pubkey(pk) for pk in raw_pks]
    if not sf:
	return (vks, None, None)
    #import the signing private keys;
    #at least one per loop
    with open(sf,'rb') as f:
	raw_sks = f.readlines()
	sks = [binascii.unhexlify(priv.strip()) for priv in raw_sks]
    #check that the signing keys have the right configuration
    if not len(sks)==len(vks):
	raise Exception("Need "+str(len(vks))+" signing keys for a valid signature, got "+str(len(sks)))
    sk_pks = [btc.decode_pubkey(btc.privtopub(sk)) for sk in sks]
    signing_indices = []
    for loop in vks:
	if not len(set(vks[loop]).intersection(set(sk_pks)))==1:
	    raise Exception("Verification key loop does not contain a signing key.")
	signing_indices.append([x for x,item in enumerate(vks[loop]) if item in sk_pks][0])
    #signing keys have right configuration relative to verification keys.
    return (vks, signing_indices, sks)
Ejemplo n.º 16
0
def encrypt(plaintext, pubkey, ephemeral_key=_secure_ephemeral()):
    optional_shared_info = ('', '')
    shared_secret = bitcoin.decode_pubkey(
        bitcoin.multiply(pubkey, ephemeral_key))[1]
    shared_secret_bin = _int2bin32b(shared_secret)

    ephemeral_pubkey = bitcoin.privtopub(ephemeral_key)

    symmetric_key, mac_key = ecies_derive_keys(
        shared_secret_bin, optional_shared_info0=optional_shared_info[0])

    aes = AESCipher(symmetric_key)
    encrypted_string = aes.encrypt(plaintext)

    tag = ecies_compute_tag(mac_key=mac_key,
                            encrypted_string=encrypted_string,
                            optional_shared_info1=optional_shared_info[1])
    return ephemeral_pubkey, encrypted_string, tag
Ejemplo n.º 17
0
def becies_shared_secret(
    private_key,
    public_key,
    optional_shared_info0=''
):  #we do NOT use http://www.secg.org/sec1-v2.pdf ANSI KDF function, we use pkcs5_pbkdf2_hmac_sha512.  It's got more hardening and it's more common and already a part of bitcoin
    shared_secret_point = bitcoin.multiply(public_key, private_key)
    shared_secret = bitcoin.decode_pubkey(shared_secret_point)[
        1]  #todo: check point at infinity? todo: compressed pubkey?
    shared_secret_bin = _int2bin32b(shared_secret)

    salt = 'becies'
    key = shared_secret_bin + optional_shared_info0
    hmac_result = pbkdf2_hmac(
        _becies_hashname, key, salt=salt + key, iterations=2048
    )  #https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
    symmetric_key = hmac_result[:(len(hmac_result) // 2)]
    mac_key = hmac_result[(len(hmac_result) // 2):]
    return symmetric_key, mac_key
Ejemplo n.º 18
0
    def __init__(self, priv_key):

        self.setup_curve()

        length = len(priv_key)

        if length != 32 and length != 96 and length != 104:
            raise Exception("Invalid private key")

        self.PrivateKey = bytearray(priv_key[-32:])

        pubkey_encoded_not_compressed = None

        if length == 32:

            pubkey_encoded_not_compressed = bitcoin.privkey_to_pubkey(priv_key)

        elif length == 64 or length == 72:
            skip = length - 64
            pubkey_encoded_not_compressed = bytearray(
                b'04').hex() + priv_key[skip:]

        elif length == 96 or length == 104:
            skip = length - 96
            pubkey_encoded_not_compressed = bytearray(b'\x04') + bytearray(
                priv_key[skip:skip + 64])

        if pubkey_encoded_not_compressed:
            pubkey_points = bitcoin.decode_pubkey(
                pubkey_encoded_not_compressed, 'bin')

            pubx = pubkey_points[0]
            puby = pubkey_points[1]
            edcsa = ECDSA.secp256r1()
            self.PublicKey = edcsa.Curve.point(pubx, puby)

        else:
            raise Exception("Could not determine public key")

        self.PublicKeyHash = Crypto.ToScriptHash(
            self.PublicKey.encode_point(True), unhex=True)
Ejemplo n.º 19
0
def decrypt(ciphertuple, privkey):
    optional_shared_info = ('', '')
    ephemeral_pubkey = ciphertuple[0]
    encrypted_string = ciphertuple[1]
    msgtag = ciphertuple[2]

    shared_secret = bitcoin.decode_pubkey(
        bitcoin.multiply(privkey,
                         ephemeral_pubkey))[1]  #todo: check point at infinity
    shared_secret_bin = _int2bin32b(shared_secret)

    symmetric_key, mac_key = ecies_derive_keys(
        shared_secret_bin, optional_shared_info0=optional_shared_info[0])

    tag = ecies_compute_tag(mac_key=mac_key,
                            encrypted_string=encrypted_string,
                            optional_shared_info1=optional_shared_info[1])
    if (tag != msgtag):
        raise "Decryption Failure...tag mismatch. The message may have been tampered with"

    aes = AESCipher(symmetric_key)
    return aes.decrypt(encrypted_string)
Ejemplo n.º 20
0
def decompress_secp256k1_pubkey(data):
    x, y = decode_pubkey(data, 'bin_compressed')
    p = ecdsa.ellipticcurve.Point(ecdsa.SECP256k1.curve, x, y)
    return ecdsa.VerifyingKey.from_public_point(p, ecdsa.SECP256k1)