Ejemplo n.º 1
0
def decrypt(secret, message):
    message = message.encode('utf-8')
    curve = SECP256k1.curve()
    order = SECP256k1.order()
    R_size = 1 + 32
    mac_size = hashlib.sha256().digest_size

    message_binary = base64.b64decode(message)
    if len(message_binary) < (R_size + mac_size):
        return None

    R = decode_point(message_binary)
    d = message_binary[R_size:R_size + mac_size]
    prefix_bytes = message_binary[R_size + mac_size:R_size + mac_size + 8]
    c = message_binary[R_size + mac_size + 8:]
    S = (secret * R).x()
    S_bytes = S.to_bytes(32, 'big')
    k_E = hashlib.sha256(S_bytes + b'\0\0\0\1').digest()
    k_M = hashlib.sha256(S_bytes + b'\0\0\0\2').digest()
    d_verify = hmac.new(k_M, prefix_bytes + c, hashlib.sha256).digest()
    if d_verify != d:
        return None
    ctr = Counter.new(64, prefix=prefix_bytes)
    cipher = AES.new(key=k_E, mode=AES.MODE_CTR, counter=ctr)
    padded = cipher.decrypt(c)
    try:
        return unpad(padded, AES.block_size).decode('utf-8')
    except:
        return None
Ejemplo n.º 2
0
def decode_point(p):
    # See http://www.secg.org/download/aid-780/sec1-v2.pdf section 2.3.4
    curve = SECP256k1.curve()
    order = SECP256k1.order()
    baselen = 32

    if p[0] == 4:
        # 3
        x_str = p[1:baselen + 1]
        y_str = p[baselen + 1:]
        return point(int.from_bytes(x_str, 'big'), int.from_bytes(y_str, 'big'))
    else:
        # 2.3
        if p[0] == 2:
            yp = 0
        elif p[0] == 3:
            yp = 1
        else:
            return None
        # 2.2
        x_str = p[1:baselen + 1]
        x = int.from_bytes(x_str, 'big')
        # 2.4.1
        alpha = ((x * x * x) + (curve.a() * x) + curve.b()) % curve.p()
        beta = pycoin.ecdsa.numbertheory.modular_sqrt(alpha, curve.p())
        if (beta - yp) % 2 == 0:
            y = beta
        else:
            y = curve.p() - beta
        return point(x, y)
Ejemplo n.º 3
0
 def test_inverse_mod(self):
     prime = generator_secp256k1.curve().p()
     order = generator_secp256k1.order()
     for v in range(70):
         n = int(float("1e%d" % v))
         i = inverse_mod(n, prime)
         assert n * i % prime == 1
         i = inverse_mod(n, order)
         assert n * i % order == 1
Ejemplo n.º 4
0
    def test_key_limits(self):
        nc = 'BTC'
        cc = b'000102030405060708090a0b0c0d0e0f'
        order = generator_secp256k1.order()

        for k in -1, 0, order, order + 1:
            self.assertRaises(InvalidSecretExponentError, Key, secret_exponent=k)
            self.assertRaises(InvalidSecretExponentError, BIP32Node, nc, cc, secret_exponent=k)

        for i in range(1, 512):
            Key(secret_exponent=i)
            BIP32Node(nc, cc, secret_exponent=i)
Ejemplo n.º 5
0
def sigmake(a_key, a_hash_for_sig, a_sig_type=SIGHASH_ALL):
    """
    Signs a_hash_for_sig with a_key and returns a DER-encoded signature
    with a_sig_type appended.
    """
    order = generator_secp256k1.order()
    r, s = ecdsa_sign(generator_secp256k1, a_key.secret_exponent(), a_hash_for_sig)

    if s + s > order:
        s = order - s

    return sigencode_der(r, s) + bytes_from_int(a_sig_type)
Ejemplo n.º 6
0
def sigmake(a_key, a_hash_for_sig, a_sig_type=SIGHASH_ALL):
    """
    Signs a_hash_for_sig with a_key and returns a DER-encoded signature
    with a_sig_type appended.
    """
    order = generator_secp256k1.order()
    r, s = ecdsa_sign(generator_secp256k1, a_key.secret_exponent(),
                      a_hash_for_sig)

    if s + s > order:
        s = order - s

    return sigencode_der(r, s) + int2byte(a_sig_type)
Ejemplo n.º 7
0
def verify(pubkey, signature, data):
    """ Verify data is signed by private key.

    Args:
        pubkey (str): Hex encoded 33Byte compressed public key
        signature (str): Hex encoded signature in DER format.

    Return:
        bool: True if signature is valid.
    """
    public_pair = encoding.sec_to_public_pair(h2b(pubkey))
    val = util.bytestoint(h2b(data))
    sig = ecdsa.util.sigdecode_der(h2b(signature), G.order())
    return ecdsa_verify(G, public_pair, val, sig)
Ejemplo n.º 8
0
def sign(privkey, data):
    """ Sign data with given private key.

    Args:
        privkey (str): Hex encoded private key
        data (str): Hex encoded data to be signed.

    Return:
        str: Hex encoded signature in DER format.
    """
    secret_exponent = Key.from_text(privkey_to_wif(privkey)).secret_exponent()
    e = util.bytestoint(h2b(data))
    r, s = ecdsa_sign(G, secret_exponent, e)
    return b2h(ecdsa.util.sigencode_der(r, s, G.order()))
Ejemplo n.º 9
0
def encrypt(point, message):
    message = message.encode('utf-8')
    padded = pad(message, AES.block_size)
    r = random.SystemRandom().randint(0, SECP256k1.order())
    R = SECP256k1 * r
    S = (point * r).x()
    S_bytes = S.to_bytes((S.bit_length() + 7) // 8, 'big')
    k_E = hashlib.sha256(S_bytes + b'\0\0\0\1').digest()
    k_M = hashlib.sha256(S_bytes + b'\0\0\0\2').digest()
    prefix_bytes = random.SystemRandom().getrandbits(64).to_bytes(8, 'little')
    ctr = Counter.new(64, prefix=prefix_bytes)
    cipher = AES.new(key=k_E, mode=AES.MODE_CTR, counter=ctr)
    c = cipher.encrypt(padded)
    d = hmac.new(k_M, prefix_bytes + c, hashlib.sha256).digest()
    result = base64.b64encode(encode_point(R, True) + d + prefix_bytes + c).decode('utf-8')
    return textwrap.fill(result, 40)
Ejemplo n.º 10
0
    def test_key_limits(self):
        nc = 'BTC'
        cc = b'000102030405060708090a0b0c0d0e0f'
        order = generator_secp256k1.order()

        for k in -1, 0, order, order + 1:
            self.assertRaises(InvalidSecretExponentError,
                              Key,
                              secret_exponent=k)
            self.assertRaises(InvalidSecretExponentError,
                              BIP32Node,
                              nc,
                              cc,
                              secret_exponent=k)

        for i in range(1, 512):
            Key(secret_exponent=i)
            BIP32Node(nc, cc, secret_exponent=i)
Ejemplo n.º 11
0
def test_special_k():
    """
    Check that my reworked version of ecdsa.deterministic_generate_k works
    like the old one, minus my salt.
    """
    import random
    from pycoin.ecdsa.ecdsa import deterministic_generate_k
    from pycoin.ecdsa import generator_secp256k1

    from pycoin.contrib.msg_signing import deterministic_make_k

    order = generator_secp256k1.order()
    r = random.Random(42)
    saw = set()
    for i in range(10000):
        se = r.randint(2, order-2)
        val = r.randint(0, 2**32)

        old = deterministic_generate_k(order, se, val)
        new = deterministic_make_k(order, se, val, trust_no_one=False)

        assert old == new
        assert new not in saw
        saw.add(new)
Ejemplo n.º 12
0
def test_special_k():
    """
    Check that my reworked version of ecdsa.deterministic_generate_k works
    like the old one, minus my salt.
    """
    import random
    from pycoin.ecdsa.ecdsa import deterministic_generate_k
    from pycoin.ecdsa import generator_secp256k1

    from pycoin.contrib.msg_signing import deterministic_make_k

    order = generator_secp256k1.order()
    r = random.Random(42)
    saw = set()
    for i in range(10000):
        se = r.randint(2, order - 2)
        val = r.randint(0, 2 ** 32)

        old = deterministic_generate_k(order, se, val)
        new = deterministic_make_k(order, se, val, trust_no_one=False)

        assert old == new
        assert new not in saw
        saw.add(new)
Ejemplo n.º 13
0
def dummy_signature(sig_type):
    order = generator_secp256k1.order()
    r, s = order - 1, order // 2
    return der.sigencode_der(r, s) + bytes_from_int(sig_type)
Ejemplo n.º 14
0
def dummy_signature(sig_type):
    order = generator_secp256k1.order()
    r, s = order - 1, order // 2
    return der.sigencode_der(r, s) + bytes_from_int(sig_type)
Ejemplo n.º 15
0
def signECDSAsecp256k1(msg, privKey):
    msgHash = sha3_256Hash(msg)
    signature = sign(generator_secp256k1, privKey, msgHash)
    return signature


def verifyECDSAsecp256k1(msg, signature, pubKey):
    msgHash = sha3_256Hash(msg)
    valid = verify(generator_secp256k1, pubKey, msgHash, signature)
    return valid


# assinatura da mensagem utilizando ECDSA utilizando a curva secp256k1 e hash SHA3-256
msg = "Message for ECDSA signing"
privKey = secrets.randbelow(generator_secp256k1.order())
signature = signECDSAsecp256k1(msg, privKey)
print("Message:", msg)
print("Private key:", hex(privKey))
print("Signature: r=" + hex(signature[0]) + ", s=" + hex(signature[1]))

# verificando a assinatura utilizando ECDSA utilizando secp256k1 e hash SHA3-256
pubKey = (generator_secp256k1 * privKey).pair()
valid = verifyECDSAsecp256k1(msg, signature, pubKey)
print("\nMessage:", msg)
print("Public key: (" + hex(pubKey[0]) + ", " + hex(pubKey[1]) + ")")
print("Signature valid?", valid)

# verificando a assinatura utilizando ECDSA utilizando secp256k1 e hash SHA3-256
msg = "Tampered message"
valid = verifyECDSAsecp256k1(msg, signature, pubKey)