Exemplo n.º 1
0
def ecssa_sign(m: Message,
               prvkey: PrvKey,
               eph_prv: Optional[PrvKey] = None,
               hasher=sha256) -> Signature:
    if type(m) == str: m = hasher(m.encode()).digest()
    prvkey = int_from_Scalar(ec, prvkey)
    eph_prv = rfc6979(prvkey, m,
                      hasher) if eph_prv is None else int_from_Scalar(
                          ec, eph_prv)
    return ecssa_sign_raw(m, prvkey, eph_prv,
                          hasher)  # FIXME: this is just the message hasher
def ecssa_commit_and_sign(m: Message, prvkey: Scalar, c: Message, eph_prv: Optional[Scalar] = None, hasher = sha256) -> Tuple[Signature, Receipt]:
    if type(m) == str: m = hasher(m.encode()).digest()
    prvkey = int_from_Scalar(ec, prvkey)
    if type(c) == str: c = hasher(c.encode()).digest()
    eph_prv = rfc6979(prvkey, m, hasher) if eph_prv is None else int_from_Scalar(ec, eph_prv)

    # commit
    R, eph_prv = tweak(eph_prv, c, hasher)
    # sign
    sig = ecssa_sign_raw(m, prvkey, eph_prv, hasher)
    # commit receipt
    receipt = (sig[0], R)
    return sig, receipt
def bip32_master_prvkey_from_seed(bip32_seed: Union[str, bytes], version: bytes) -> bytes:
    """derive the master extended private key from the seed"""
    if type(bip32_seed) == str: # hex string
        bip32_seed = bytes.fromhex(bip32_seed)
    assert version in PRIVATE, "wrong version, master key must be private"

    # serialization data
    xmprv = version                             # version
    xmprv += b'\x00'                            # depth
    xmprv += b'\x00\x00\x00\x00'                # parent pubkey fingerprint
    xmprv += b'\x00\x00\x00\x00'                # child index

    # actual extended key (key + chain code) derivation
    hashValue = HMAC(b"Bitcoin seed", bip32_seed, sha512).digest()
    mprv = int_from_Scalar(ec, hashValue[:32])
    xmprv += hashValue[32:]                     # chain code
    xmprv += b'\x00' + mprv.to_bytes(32, 'big') # private key

    return b58encode_check(xmprv)
Exemplo n.º 4
0
    def test_ecssamusig(self):
        msg = 'message to sign'
        m = sha256(msg.encode()).digest()

        # first signer (is the message needed here? maybe for rfc6979?)
        prv1 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d92ad1d')
        Q1 = ec.pointMultiply(prv1, ec.G)
        HQ1 = int_from_hash(
            sha256(bytes_from_Point(ec, Q1, False)).digest(), ec.order)
        prv1 = HQ1 * prv1

        eph_prv1 = 0x012a2a833eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbb
        R1 = ec.pointMultiply(eph_prv1, ec.G)
        if R1[1] % 2 == 1:  #must be even
            eph_prv1 = ec.order - eph_prv1
            R1 = ec.pointMultiply(eph_prv1, ec.G)
        R1_x = R1[0]

        # second signer (is the message needed here? maybe for rfc6979?)
        prv2 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d')
        Q2 = ec.pointMultiply(prv2, ec.G)
        HQ2 = int_from_hash(
            sha256(bytes_from_Point(ec, Q2, False)).digest(), ec.order)
        prv2 = HQ2 * prv2

        eph_prv2 = 0x01a2a0d3eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbdb
        R2 = ec.pointMultiply(eph_prv2, ec.G)
        if R2[1] % 2 == 1:  #must be even
            eph_prv2 = ec.order - eph_prv2
            R2 = ec.pointMultiply(eph_prv2, ec.G)
        R2_x = R2[0]

        ######################
        # exchange Rx, compute s
        ######################

        # first signer use R2_x
        R2_y_recovered = ec.y(R2_x, 0)
        R2_recovered = (R2_x, R2_y_recovered)
        R1_All = ec.pointAdd(R1, R2_recovered)
        if R1_All[1] % 2 == 1:  # must be even
            eph_prv1 = ec.order - eph_prv1
        R1_All_x = R1_All[0].to_bytes(32, 'big')
        e1 = int_from_hash(sha256(R1_All_x + m).digest(), ec.order)
        assert e1 != 0 and e1 < ec.order, "sign fail"
        s1 = (eph_prv1 - e1 * prv1) % ec.order

        # second signer use R1_x
        R1_y_recovered = ec.y(R1_x, 0)
        R1_recovered = (R1_x, R1_y_recovered)
        R2_All = ec.pointAdd(R2, R1_recovered)
        if R2_All[1] % 2 == 1:
            eph_prv2 = ec.order - eph_prv2
        R2_All_x = R2_All[0].to_bytes(32, 'big')
        e2 = int_from_hash(sha256(R2_All_x + m).digest(), ec.order)
        assert e2 != 0 and e2 < ec.order, "sign fail"
        s2 = (eph_prv2 - e2 * prv2) % ec.order

        ######################
        # combine signatures into a single signature
        ######################

        # anyone can do the following
        assert R1_All_x == R2_All_x, "sign fail"
        R_All_x = R1_All[0]
        s_All = (s1 + s2) % ec.order
        ssasig = (R_All_x, s_All)
        Q_All = ec.pointAdd(ec.pointMultiply(HQ1, Q1),
                            ec.pointMultiply(HQ2, Q2))

        self.assertTrue(ecssa_verify(msg, ssasig, Q_All, sha256))
    def test_ecssamusig(self):
        msg = 'message to sign'
        m = sha256(msg.encode()).digest()

        # first signer (is the message needed here? maybe for rfc6979?)
        prv1 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d92ad1d')
        Q1 = ec.pointMultiply(prv1, ec.G)
        HQ1 = int_from_hash(
            sha256(bytes_from_Point(ec, Q1, False)).digest(), ec.n)
        prv1 = HQ1 * prv1

        eph_prv1 = 0x012a2a833eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbb
        R1 = ec.pointMultiply(eph_prv1, ec.G)
        R1_x = R1[0]
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R1[1]) != 1:
            eph_prv1 = ec.n - eph_prv1
            R1 = R1_x, ec.yQuadraticResidue(R1_x, True)
            #R1 = ec.pointMultiply(eph_prv1, ec.G)

        # second signer (is the message needed here? maybe for rfc6979?)
        prv2 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d')
        Q2 = ec.pointMultiply(prv2, ec.G)
        HQ2 = int_from_hash(
            sha256(bytes_from_Point(ec, Q2, False)).digest(), ec.n)
        prv2 = HQ2 * prv2

        eph_prv2 = 0x01a2a0d3eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbdb
        R2 = ec.pointMultiply(eph_prv2, ec.G)
        R2_x = R2[0]
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R2[1]) != 1:
            eph_prv2 = ec.n - eph_prv2
            R2 = R2_x, ec.yQuadraticResidue(R2_x, True)
            #R2 = ec.pointMultiply(eph_prv2, ec.G)

        Q_All = ec.pointAdd(ec.pointMultiply(HQ1, Q1),
                            ec.pointMultiply(HQ2, Q2))  # joint public key

        ########################
        # exchange Rx, compute s

        # first signer use R2_x
        # break the simmetry: any criteria could be used, jacobi is standard
        y = ec.yQuadraticResidue(R2_x, True)
        R2_recovered = (R2_x, y)
        R1_All = ec.pointAdd(R1, R2_recovered)
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R1_All[1]) != 1:
            # no need to actually change R1_All[1], as it is not used anymore
            # let's fix eph_prv1 instead, as it is used later
            eph_prv1 = ec.n - eph_prv1
        e1 = int_from_hash(
            sha256(R1_All[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, Q_All, True) + m).digest(), ec.n)
        assert e1 != 0 and e1 < ec.n, "sign fail"
        s1 = (eph_prv1 + e1 * prv1) % ec.n

        # second signer use R1_x
        # break the simmetry: any criteria could be used, jacobi is standard
        y = ec.yQuadraticResidue(R1_x, True)
        R1_recovered = (R1_x, y)
        R2_All = ec.pointAdd(R2, R1_recovered)
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R2_All[1]) != 1:
            # no need to actually change R2_All[1], as it is not used anymore
            # let's fix eph_prv2 instead, as it is used later
            eph_prv2 = ec.n - eph_prv2
        e2 = int_from_hash(
            sha256(R2_All[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, Q_All, True) + m).digest(), ec.n)
        assert e2 != 0 and e2 < ec.n, "sign fail"
        s2 = (eph_prv2 + e2 * prv2) % ec.n

        ############################################
        # combine signatures into a single signature

        # anyone can do the following
        assert R1_All[0] == R2_All[0], "sign fail"
        s_All = (s1 + s2) % ec.n
        ssasig = (R1_All[0], s_All)

        self.assertTrue(ecssa_verify(msg, ssasig, Q_All, sha256))