def ecdsa_pubkey_recovery_raw(m: bytes, dsasig: Signature, odd1even0: int) -> PubKey:
    h = int_from_hash(m, ec.n)
    r, s = dsasig
    r1 = mod_inv(r, ec.n)
    R = (r, ec.yOdd(r, odd1even0))
    return ec.pointAdd(ec.pointMultiply( s * r1 % ec.n, R),
                       ec.pointMultiply(-h * r1 % ec.n, ec.G))
def ecdsa_verify_raw(m: bytes, dsasig: Signature, pubkey: PubKey) -> bool:
    h = int_from_hash(m, ec.n)
    r, s = dsasig
    s1 = mod_inv(s, ec.n)
    R = ec.pointAdd(ec.pointMultiply(r * s1 % ec.n, pubkey),
                    ec.pointMultiply(h * s1 % ec.n, ec.G))
    return R[0] % ec.n == r
Esempio n. 3
0
def ecssa_pubkey_recovery_raw(e: bytes, ssasig: Signature) -> PubKey:
    r, s = ssasig
    R = (r, ec.yQuadraticResidue(r, True))
    e = int_from_hash(e, ec.n)
    assert e != 0 and e < ec.n, "invalid challenge e"
    e1 = mod_inv(e, ec.n)
    return ec.pointAdd(ec.pointMultiply((e1 * s) % ec.n, ec.G),
                       ec.pointMultiply(ec.n - e1, R))
def verify_commit(receipt: Receipt, c: Message, hasher = sha256) -> bool:
    w, R = receipt
    ec.yOdd(w, False)  # receipt[0] is valid iif its y does exist
    tuple_from_Point(ec, R)  # verify R is a good point
    if type(c) == str: c = hasher(c.encode()).digest()
    e = hasher(bytes_from_Point(ec, R, True) + c).digest()
    e = int.from_bytes(e, 'big')
    W = ec.pointAdd(R, ec.pointMultiply(e, ec.G))
    # w in [1..n-1] dsa
    # w in [1..p-1] ssa
    # different verify functions?
    return w % ec.n == W[0] % ec.n
Esempio n. 5
0
def ecssa_pubkey_recovery_raw(m: bytes,
                              ssasig: Signature,
                              hasher=sha256) -> PubKey:
    R_x, s = ssasig
    R = (R_x, ec.y(R_x, 0))
    R_x = R_x.to_bytes(32, 'big')
    e = hasher(R_x + m).digest()
    e = int_from_hash(e, ec.order)
    assert e != 0 and e < ec.order, "invalid e value"
    e1 = mod_inv(e, ec.order)
    return ec.pointAdd(ec.pointMultiply(e1, R),
                       ec.pointMultiply(-e1 * s % ec.order, ec.G))
Esempio n. 6
0
def ecssa_verify_raw(m: bytes,
                     ssasig: Signature,
                     pub: PubKey,
                     hasher=sha256) -> bool:
    R_x, s = ssasig[0].to_bytes(32, 'big'), ssasig[1]
    e = hasher(R_x + m).digest()
    e = int_from_hash(e, ec.order)
    if e == 0 or e >= ec.order: return False
    R = ec.pointAdd(ec.pointMultiply(e, pub), ec.pointMultiply(s, ec.G))
    if R[1] % 2 == 1:  # R.y odd
        return False
    return R[0] == ssasig[0]
Esempio n. 7
0
def ecssa_verify_raw(m: bytes,
                     ssasig: Signature,
                     pub: PubKey,
                     hasher=sha256) -> bool:
    r, s = ssasig
    e = hasher(
        r.to_bytes(32, byteorder="big") + bytes_from_Point(ec, pub, True) +
        m).digest()
    e = int_from_hash(e, ec.n)
    if e == 0 or e >= ec.n:
        return False
    # R = sG - eP
    R = ec.pointAdd(ec.pointMultiply(s, ec.G), ec.pointMultiply(ec.n - e, pub))
    if ec.jacobi(R[1]) != 1:
        return False
    return R[0] == ssasig[0]
Esempio n. 8
0
def bip32_ckd(xparentkey: bytes, index: Union[bytes, int]) -> bytes:
    """Child Key Derivation (CDK)

    Key derivation is normal if the extended parent key is public or
    child_index is less than 0x80000000.
    
    Key derivation is hardened if the extended parent key is private and
    child_index is not less than 0x80000000.
    """

    if isinstance(index, int):
        index = index.to_bytes(4, 'big')
    elif isinstance(index, bytes):
        assert len(index) == 4
    else:
        raise TypeError("a 4 bytes int is required")

    xparent = b58decode_check(xparentkey, 78)

    version = xparent[:4]

    # serialization data
    xkey = version  # version
    xkey += (xparent[4] + 1).to_bytes(1, 'big')  # (increased) depth

    if (version in PUBLIC):
        assert xparent[45] in (2, 3), \
               "version/key mismatch in extended parent key"
        Parent_bytes = xparent[45:]
        Parent = tuple_from_Point(ec, Parent_bytes)
        xkey += h160(Parent_bytes)[:4]  # parent pubkey fingerprint
        assert index[0] < 0x80, \
               "no private/hardened derivation from pubkey"
        xkey += index  # child index
        parent_chain_code = xparent[13:45]  ## normal derivation
        # actual extended key (key + chain code) derivation
        h = HMAC(parent_chain_code, Parent_bytes + index, sha512).digest()
        offset = int.from_bytes(h[:32], 'big')
        Offset = ec.pointMultiply(offset, ec.G)
        Child = ec.pointAdd(Parent, Offset)
        Child_bytes = bytes_from_Point(ec, Child, True)
        xkey += h[32:]  # chain code
        xkey += Child_bytes  # public key
    elif (version in PRIVATE):
        assert xparent[45] == 0, "version/key mismatch in extended parent key"
        parent = int.from_bytes(xparent[46:], 'big')
        Parent = ec.pointMultiply(parent, ec.G)
        Parent_bytes = bytes_from_Point(ec, Parent, True)
        xkey += h160(Parent_bytes)[:4]  # parent pubkey fingerprint
        xkey += index  # child index
        # actual extended key (key + chain code) derivation
        parent_chain_code = xparent[13:45]
        if (index[0] < 0x80):  ## normal derivation
            h = HMAC(parent_chain_code, Parent_bytes + index, sha512).digest()
        else:  ## hardened derivation
            h = HMAC(parent_chain_code, xparent[45:] + index, sha512).digest()
        offset = int.from_bytes(h[:32], 'big')
        child = (parent + offset) % ec.order
        child_bytes = b'\x00' + child.to_bytes(32, 'big')
        xkey += h[32:]  # chain code
        xkey += child_bytes  # private key
    else:
        raise ValueError("invalid extended key version")

    return b58encode_check(xkey)
s1 = ((h1 + r * q) * mod_inv(k1, ec.n)) % ec.n
# if s1 == 0 (extremely unlikely for large ec.n) go back to a different ephemeral key
assert s1 != 0

print("     r:", hex(r))
print("    s1:", hex(s1))

print("*** Signature Verification")
w = mod_inv(s1, ec.n)
u = (h1 * w) % ec.n
v = (r * w) % ec.n
assert u != 0
assert v != 0
U = ec.pointMultiply(u, ec.G)
V = ec.pointMultiply(v, Q)
x, y = ec.pointAdd(U, V)
print(r == x % ec.n)

print("\n*** Malleated Signature")
s1m = ec.n - s1
print("     r:", hex(r))
print("   *s1:", hex(s1m))

print("*** Malleated Signature Verification")
w = mod_inv(s1m, ec.n)
u = (h1 * w) % ec.n
v = (r * w) % ec.n
assert u != 0
assert v != 0
U = ec.pointMultiply(u, ec.G)
V = ec.pointMultiply(v, Q)
assert k1 != 0

K1 = ec.pointMultiply(k1, ec.G)

s1 = (k1-h1*q) % ec.n
# if s1 == 0 (extremely unlikely for large ec.n) go back to a different ephemeral key
assert s1 != 0

print(" K1[0]:", hex(K1[0]))
print(" K1[1]:", hex(K1[1]))
print("    s1:", hex(s1))

print("*** Signature Verification")
minush1 = -h1 %ec.n
V = ec.pointMultiply(minush1, Q)
V = ec.pointAdd(K1, V)
print(V == ec.pointMultiply(s1, ec.G))

print("\n*** Another message")
msg2 = "and Paolo is right to be afraid"
print(msg2)

print("*** Hash of the message")
h_bytes = sha256(msg2.encode()).digest()
# hash(msg) must be transformed into an integer modulo ec.n:
h2 = int.from_bytes(h_bytes, 'big') % ec.n
assert h2 != 0
print("    h2:", hex(h2))

print("\n*** Signature")
k2 = k1 #very bad! Never reuse the same ephemeral key!!!