Пример #1
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)
Пример #2
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)
Пример #3
0
def sign_donation_tx(tx, i, priv):
    from bitcoin.main import fast_multiply, decode_privkey, G, inv, N
    from bitcoin.transaction import der_encode_sig
    k = sign_k
    hashcode = btc.SIGHASH_ALL
    i = int(i)
    if len(priv) <= 33:
        priv = btc.safe_hexlify(priv)
    pub = btc.privkey_to_pubkey(priv)
    address = btc.pubkey_to_address(pub)
    signing_tx = btc.signature_form(
            tx, i, btc.mk_pubkey_script(address), hashcode)

    msghash = btc.bin_txhash(signing_tx, hashcode)
    z = btc.hash_to_int(msghash)
    # k = deterministic_generate_k(msghash, priv)
    r, y = fast_multiply(G, k)
    s = inv(k, N) * (z + r * decode_privkey(priv)) % N
    rawsig = 27 + (y % 2), r, s

    sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2)
    # sig = ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = btc.deserialize(tx)
    txobj["ins"][i]["script"] = btc.serialize_script([sig, pub])
    return btc.serialize(txobj)
Пример #4
0
def sign_donation_tx(tx, i, priv):
    from bitcoin.main import fast_multiply, decode_privkey, G, inv, N
    from bitcoin.transaction import der_encode_sig
    k = sign_k
    hashcode = btc.SIGHASH_ALL
    i = int(i)
    if len(priv) <= 33:
        priv = btc.safe_hexlify(priv)
    pub = btc.privkey_to_pubkey(priv)
    address = btc.pubkey_to_address(pub)
    signing_tx = btc.signature_form(tx, i, btc.mk_pubkey_script(address),
                                    hashcode)

    msghash = btc.bin_txhash(signing_tx, hashcode)
    z = btc.hash_to_int(msghash)
    # k = deterministic_generate_k(msghash, priv)
    r, y = fast_multiply(G, k)
    s = inv(k, N) * (z + r * decode_privkey(priv)) % N
    rawsig = 27 + (y % 2), r, s

    sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2)
    # sig = ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = btc.deserialize(tx)
    txobj["ins"][i]["script"] = btc.serialize_script([sig, pub])
    return btc.serialize(txobj)
Пример #5
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
Пример #6
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))
Пример #7
0
def sign(tx_hash: bytes, private_key: str):
    msg_hash = tx_hash
    z = bitcoin.hash_to_int(msg_hash)
    k = bitcoin.deterministic_generate_k(msg_hash, private_key)

    r, y = bitcoin.fast_multiply(bitcoin.G, k)
    s = bitcoin.inv(k, bitcoin.N) * (
        z + r * bitcoin.decode_privkey(private_key)) % bitcoin.N

    v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < bitcoin.N else 1)
                    ), r, s if s * 2 < bitcoin.N else bitcoin.N - s
    if 'compressed' in bitcoin.get_privkey_format(private_key):
        v += 4
    hex_str_r = hex(r)[2:]
    if len(hex_str_r) < 64:
        hex_str_r = ((64 - len(hex_str_r)) * "0") + hex_str_r
    hex_str_s = hex(s)[2:]
    if len(hex_str_s) < 64:
        hex_str_s = ((64 - len(hex_str_s)) * "0") + hex_str_s
    signature = hex_str_r + hex_str_s
    recovery = v - 27
    return signature, recovery
Пример #8
0
def ecdsa_sign_k(z, d, k):
    r, y = bitcoin.fast_multiply(bitcoin.G, k)
    s = bitcoin.inv(k, bitcoin.N) * (z + r * d) % bitcoin.N
    v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < bitcoin.N else 1)
                    ), r, s if s * 2 < bitcoin.N else bitcoin.N - s
    return v, r, s


# Generate secret key & the corresponding public key and address
sk = random.SystemRandom().randrange(1, bitcoin.N)
Q = bitcoin.fast_multiply(bitcoin.G, sk)

# Sign 2 differents messages with same k
signing_k = random.SystemRandom().randrange(1, bitcoin.N)
z1 = bitcoin.hash_to_int(hashlib.sha256('first_message').hexdigest())
z2 = bitcoin.hash_to_int(hashlib.sha256('second_message').hexdigest())
v1, r1, s1 = ecdsa_sign_k(z1, sk, signing_k)
v2, r2, s2 = ecdsa_sign_k(z2, sk, signing_k)
assert r1 == r2
print('+ R used   = {:x}'.format(r1))

# Calculate k candidates
k_candidates = [(z1 - z2) * bitcoin.inv(s1 - s2, bitcoin.N) % bitcoin.N,
                (z1 - z2) * bitcoin.inv(s1 + s2, bitcoin.N) % bitcoin.N]
for k in k_candidates:
    priv_key = (s1 * k - z1) * bitcoin.inv(r1, bitcoin.N) % bitcoin.N
    if bitcoin.fast_multiply(bitcoin.G, priv_key) == Q:
        print('+ Calc key = {0}'.format(priv_key))
        break
else:
Пример #9
0
from bitcoin import fast_add, fast_multiply, G, hash_to_int, inv, N
from hashlib import sha256
from random import SystemRandom

# Generate secret key & the corresponding public key and address
d = SystemRandom().randrange(1, N)
Q = fast_multiply(G, d);

# Choose a 2 random numbers
a = SystemRandom().randrange(1, N)
b = SystemRandom().randrange(1, N)

# calculate a signature
r = fast_add(fast_multiply(G, a), fast_multiply(Q, b))[0]
s = r * inv(b, N)

# Calculate the hash corresponding to the signature (r,s)
h = a * r * inv(b, N)

# calculate the hash of the message we want to sign
z = hash_to_int(sha256('0xDEADBEEF').hexdigest())

# re-calculate s to sign z
s_p = s * (z + d*r) * inv(h + d*r, N)

# et voila
w = inv(s_p, N)
u1, u2 = z*w % N, r*w % N
x, y = fast_add(fast_multiply(G, u1), fast_multiply(Q, u2))
assert(r == x and (r % N) and (s_p % N))
Пример #10
0
def get_z(msg):
    hash = hashlib.sha256(msg).hexdigest()
    return bitcoin.hash_to_int(hash)
Пример #11
0

def fast_substract(a, b):
    x1, y1 = a
    x2, y2 = b
    return fast_add((x1, y1), (x2, -y2))


inv = bitcoin.inv

# We don't know d but we can get Q from emitted signatures
d = bitcoin.decode_privkey(bitcoin.random_key())
Q = fast_multiply(G, d)

# We build up a message to sign
msghash = hashlib.sha256('a_random_message').hexdigest()
z = bitcoin.hash_to_int(msghash)

cpt = 0
while True:
    cpt = cpt + 1
    r = random.SystemRandom().randrange(1, N)
    s = random.SystemRandom().randrange(1, N / 2)
    if r == fast_add(fast_multiply(G, z * inv(s, N)),
                     fast_multiply(Q, r * inv(s, N)))[0]:
        break

assert bitcoin.ecdsa_raw_verify(msghash, (27, r, s), Q)
print('v={0}\nr={1}\ns={2}'.format(27, r, s))
print('Find after {} attempts.'.format(cpt))