示例#1
0
def recoverECDSAKey(token, hashalg, curve, compressed):
    header, body, sig = token.split(".")
    rs = base64.b64decode(sig + "==")
    n = len(rs) // 2
    r = int(rs[:n].hex(), 16)
    s = int(rs[n:].hex(), 16)
    # compute the 2 points having r has X coordinate
    y1, y2 = mod_sqrt(r**3 + curve.a * r + curve.b, curve.p)
    R1 = Point(r, y1, curve)
    R2 = Point(r, y2, curve)
    # compute r^1
    r_inv = int(gmpy2.invert(r, curve.q))
    # compute message hash
    message = header + "." + body
    h = int(hashalg.new(message.encode()).hexdigest(), 16)
    G = Point(curve.gx, curve.gy, curve)
    # recover the two possible public keys
    k1 = r_inv * (s * R1 - h * G)
    k2 = r_inv * (s * R2 - h * G)
    k1_ = ECC.construct(curve=curve.name.lower(), point_x=k1.x, point_y=k1.y)
    k2_ = ECC.construct(curve=curve.name.lower(), point_x=k2.x, point_y=k2.y)
    print("Found 2 public ECDSA keys !")
    print(f"x={k1.x}\ny={k1.y}")
    print(k1_.export_key(format="PEM", compress=compressed))
    print("")
    print(f"x={k2.x}\ny={k2.y}")
    print(k2_.export_key(format="PEM", compress=compressed))
示例#2
0
def bytes_to_point(b: bytes) -> Point:
    """Takes a compressed bytes representation and returns the corresponding point"""
    if b == 0:
        return Point.IDENTITY_ELEMENT
    p = CURVE.p
    yp, x_enc = b[0], b[1:]
    yp = 0 if yp == 2 else 1
    x = int.from_bytes(x_enc, "big")
    y = mod_sqrt((x ** 3 + CURVE.a * x + CURVE.b) % p, p)[0]
    if y % 2 == yp:
        return Point(x, y, CURVE)
    else:
        return Point(x, p - y, CURVE)
def elliptic_hash(msg: bytes, CURVE: Curve):
    p = CURVE.p
    i = 0
    while True:
        i += 1
        prefixed_msg = str(i).encode() + msg
        h = sha256(prefixed_msg).hexdigest()
        x = int(h, 16)
        if x >= p:
            continue

        y_sq = (x ** 3 + CURVE.a * x + CURVE.b) % p
        y = mod_sqrt(y_sq, p)[0]

        if CURVE.is_point_on_curve((x, y)):
            b = int(md5(prefixed_msg).hexdigest(), 16) % 2
            return Point(x, y, CURVE) if b else Point(x, p - y, CURVE)
示例#4
0
文件: bip32.py 项目: volbil/bc4py
    def from_extended_key(cls, key, is_public=False):
        """
        Create a BIP32Key by importing from extended private or public key string
        If public is True, return a public-only key regardless of input type.
        """
        # Sanity checks
        if isinstance(key, str):
            raw = check_decode(key)
        else:
            raw = b'\x00\x00\x00\x00' + key
        if len(raw) != 78:
            raise ValueError("extended key format wrong length")

        # Verify address version/type
        version = raw[:4]
        if version == b'\x00\x00\x00\x00':
            is_testnet = None
            is_pubkey = None
        elif version in EX_MAIN_PRIVATE:
            is_testnet = False
            is_pubkey = False
        elif version in EX_TEST_PRIVATE:
            is_testnet = True
            is_pubkey = False
        elif version in EX_MAIN_PUBLIC:
            is_testnet = False
            is_pubkey = True
        elif version in EX_TEST_PUBLIC:
            is_testnet = True
            is_pubkey = True
        else:
            raise ValueError("unknown extended key version")

        # Extract remaining fields
        depth = raw[4]
        fpr = raw[5:9]
        child = struct.unpack(">L", raw[9:13])[0]
        chain = raw[13:45]
        data = raw[45:78]

        # check prefix of key
        is_pubkey = (data[0] == 2 or data[0] == 3)

        # Extract private key or public key point
        if not is_pubkey:
            secret = int.from_bytes(data[1:], 'big')
            public = get_public_key(secret, secp256k1)
        else:
            # Recover public curve point from compressed key
            # Python3 FIX
            lsb = data[0] & 1 if type(data[0]) == int else ord(data[0]) & 1
            x = int.from_bytes(data[1:], 'big')
            ys = (x**3 + 7) % FIELD_ORDER  # y^2 = x^3 + 7 mod p
            y, _ = mod_sqrt(ys, FIELD_ORDER)
            if y & 1 != lsb:
                y = FIELD_ORDER - y
            secret = None
            public = Point(x, y, secp256k1)

        if not is_pubkey and is_public:
            return cls(secret=None,
                       public=public,
                       chain=chain,
                       depth=depth,
                       index=child,
                       fpr=fpr,
                       path='m')
        else:
            return cls(secret=secret,
                       public=public,
                       chain=chain,
                       depth=depth,
                       index=child,
                       fpr=fpr,
                       path='m')