예제 #1
0
def quick_sign_message(message, wif, hashfn=hashlib.sha256):
    if not isinstance(message, bytes):
        message = bytes(message, "utf-8")

    digest = hashfn(message).digest()
    priv_key = QuickPrivateKey(wif)
    if sys.version > '3':
        p = bytes(priv_key)
    else:
        p = bytes(priv_key.__bytes__())

    ndata = CCffi.new("const int *ndata")
    ndata[0] = 0
    while True:
        ndata[0] += 1
        signature = CCffi.new('secp256k1_ecdsa_recoverable_signature *')
        signed = CClib.secp256k1_ecdsa_sign_recoverable(
            CCGLOBAL_CONTEXT.ctx, signature, digest, p, CCffi.NULL, ndata)

        if not signed:
            raise AssertionError()

        output = CCffi.new('unsigned char[%d]' % 64)
        recid = CCffi.new('int *')

        CClib.secp256k1_ecdsa_recoverable_signature_serialize_compact(
            CCGLOBAL_CONTEXT.ctx, output, recid, signature)

        output_sig = CCffi.buffer(output, 64)

        if _is_canonical(output_sig):
            return bytes(CCutils.int_to_bytes(31 + recid[0]) + output_sig)
예제 #2
0
def serialize_recoverable(recover_sig, context=GLOBAL_CONTEXT):
    output = ffi.new('unsigned char[%d]' % CDATA_SIG_LENGTH)
    recid = ffi.new('int *')

    lib.secp256k1_ecdsa_recoverable_signature_serialize_compact(
        context.ctx, output, recid, recover_sig)

    return bytes(ffi.buffer(output, CDATA_SIG_LENGTH)) + int_to_bytes(recid[0])
예제 #3
0
def sigrec_decode(sigrec):
    """
    Decodes a pk-recoverable signature in the format used by LN to be input to ``PublicKey.from_signature_and_message``.

    Args:
        sigrec(:obj:`bytes`): the signature to be decoded.

    Returns:
        :obj:`bytes`: the decoded signature.
    """

    rid, rsig = int_to_bytes(sigrec[0] - 31), sigrec[1:]
    rsig_rid = rsig + rid

    return rsig_rid
예제 #4
0
def sigrec_encode(rsig_rid):
    """
    Encodes a pk-recoverable signature to be used in LN. ``rsig_rid`` can be obtained trough
    ``PrivateKey.sign_recoverable``. The required format has the recovery id as the last byte, and for signing LN
    messages we need it as the first. From: https://twitter.com/rusty_twit/status/1182102005914800128

    Args:
        rsig_rid(:obj:`bytes`): the signature to be encoded.

    Returns:
        :obj:`bytes`: the encoded signature.
    """

    rsig, rid = rsig_rid[:64], rsig_rid[64]
    sigrec = int_to_bytes(rid + 31) + rsig

    return sigrec
예제 #5
0
def sigrec_decode(sigrec):
    """
    Decodes a pk-recoverable signature in the format used by LN to be input to ``PublicKey.from_signature_and_message``.

    Args:
        sigrec(:obj:`bytes`): the signature to be decoded.

    Returns:
        :obj:`bytes`: the decoded signature.

    Raises:
        :obj:`ValueError`: if the SigRec is not properly encoded (first byte is not 31 + recovery id)
    """

    int_rid, rsig = sigrec[0] - 31, sigrec[1:]
    if int_rid < 0:
        raise ValueError("Wrong SigRec")
    else:
        rid = int_to_bytes(int_rid)

    return rsig + rid
예제 #6
0
파일: keys.py 프로젝트: Daice/coincurve
    def sign_recoverable(self,
                         message: bytes,
                         hasher: Hasher = sha256,
                         custom_nonce: Nonce = DEFAULT_NONCE) -> bytes:
        """
        Create a recoverable ECDSA signature.

        :param message: The message to sign.
        :param hasher: The hash function to use, which must return 32 bytes. By default,
                       the `sha256` algorithm is used. If `None`, no hashing occurs.
        :param custom_nonce: Custom nonce data in the form `(nonce_function, input_data)`. Refer to
                             [secp256k1_recovery.h](https://github.com/bitcoin-core/secp256k1/blob/f8c0b57e6ba202b1ce7c5357688de97c9c067697/include/secp256k1_recovery.h#L78-L79).
        :return: The recoverable ECDSA signature.
        :raises ValueError: If the message hash was not 32 bytes long, the nonce generation
                            function failed, or the private key was invalid.
        """
        msg_hash = hasher(message) if hasher is not None else message
        if len(msg_hash) != 32:
            raise ValueError('Message hash must be 32 bytes long.')

        ndata = ffi.new("const int *ndata")
        ndata[0] = 0
        while 1:
            ndata[0] += 1
            signature = ffi.new('secp256k1_ecdsa_recoverable_signature *')

            signed = lib.secp256k1_ecdsa_sign_recoverable(
                self.context.ctx, signature, msg_hash, self.secret, ffi.NULL,
                ndata)

            if not signed:
                raise ValueError(
                    'The nonce generation function failed, or the private key was invalid.'
                )

            #return serialize_recoverable(signature, self.context)
            i, sig = serialize_recoverable(signature, self.context)
            if i != -1:
                return int_to_bytes(i) + sig
예제 #7
0
def test_bytes_int_conversion():
    bytestr = b'\x00' + urandom(31)
    assert pad_scalar(int_to_bytes(bytes_to_int(bytestr))) == bytestr
예제 #8
0
def KANGAROOS():

    # debug
    if flag_profile == "custom":

        #midJsize = (Wsqrt//2)+1
        midJsize = int(round(1.0 * Wsqrt / 2))

        pow2Jmax = getPow2Jmax(midJsize)
        sizeJmax = 2**pow2Jmax

        #sizeJmax = Wsqrt*8
        #pow2Jmax = int(round(math.log(sizeJmax,2)))

        pow2dp = (pow2W // 2) - 2  #
        DPmodule = 2**pow2dp

    # settings by Pollard
    # expected of 2w^(1/2) group operations
    #elif flag_profile ==  "standart":
    else:
        # mean jumpsize
        # by Pollard ".. The best choice of m (mean jump size) is w^(1/2)/2 .."
        #midJsize = (Wsqrt//2)+1
        midJsize = int(round(1.0 * Wsqrt / 2))

        pow2Jmax = getPow2Jmax(midJsize)
        sizeJmax = 2**pow2Jmax

        # discriminator for filter added new distinguished points (ram economy)
        pow2dp = (pow2W // 2) - 2  #
        DPmodule = 2**pow2dp

    if flag_debug > 0:
        if flag_debug > 0:
            print('[DPmodule] 2^%s = %s' % (pow2dp, DPmodule))
            print('[sizeJmax] 2^%s = %s' % (pow2Jmax, sizeJmax))

    # dT/dW - int, sum distance traveled
    dT = dW = 0

    # Tp/Wp - point, sum distance traveled
    Tp = Wp = False

    # generate random start points

    # Tame
    if 1:
        #dT = (3<<(pow2bits-2)) + random.randint(1,(2**(pow2bits-1)))	# by 57fe
        dT = M  # by Pollard
        if not (dT % 2):
            dT += 1
            # T odd recommended

        if (not flag_gmpy2) and flag_coincurve:
            Tp = Gp.multiply(int_to_bytes(dT))
        else:
            Tp = mul_ka(dT)

        if flag_debug > 1: print('dT 0x%064x' % (dT))

    # Wild
    if 1:
        #dW = random.randint(1, (1<<(pow2bits-1)))	# by 57fe
        dW = 1  # by Pollard

        if (not flag_gmpy2) and flag_coincurve:
            Wp = PublicKey.combine_keys([W0p, Gp.multiply(int_to_bytes(dW))])
        else:
            Wp = add_a(W0p, mul_ka(dW))

        if flag_debug > 1: print('dW 0x%064x' % (dW))

    print('[+] T+W kangaroos - ready')

    # DTp/DWp - points, distinguished of Tp/Wp
    DTp, DWp = dict(), dict(
    )  # dict is hashtable of python, provides uniqueness distinguished points

    t0 = t1 = t2 = t1_info = t2_info = time.time()
    n_jump = last_jump = 0
    prvkey = False

    # main loop
    while (1):

        # Tame
        if 1:
            n_jump += 1

            # Xcoord
            Xcoord = getXcoord(Tp)

            pw = Xcoord % pow2Jmax
            pw = int(pw)
            nowjumpsize = 1 << pw

            # check, is it distinguished point?
            if Xcoord % DPmodule == 0:

                # add new distinguished point
                DTp[Xcoord] = dT

                if flag_debug > 1:
                    printstr = '\r[tame] T+W=%s+%s=%s' % (len(DTp), len(DWp),
                                                          len(DTp) + len(DWp))
                    printstr += '; %064x 0x%x' % (Xcoord, dT)
                    print(printstr)
                    save2file('tame.txt', 'a', '%064x %s\n' % (Xcoord, dT))
                # compare distinguished points, Tame & Wild
                compare = list(set(DTp) & set(DWp))
                if len(compare) > 0:
                    dDT = DTp[compare[0]]
                    dDW = DWp[compare[0]]
                    if dDT > dDW:
                        prvkey = dDT - dDW
                    elif dDW > dDT:
                        prvkey = dDW - dDT
                    else:
                        print("\r[error] dDW == dDT !!! (0x%x)" % dDW)
                        exit(-1)

            if prvkey: break

            dT += nowjumpsize
            if (not flag_gmpy2) and flag_coincurve:
                Tp = PublicKey.combine_keys([Tp, Sp[pw]])
            else:
                Tp = add_a(Tp, Sp[pw])

        if prvkey: break

        # Wild
        if 1:
            n_jump += 1

            # Xcoord
            Xcoord = getXcoord(Wp)

            pw = Xcoord % pow2Jmax
            pw = int(pw)
            nowjumpsize = 1 << pw

            # add new distinguished point
            if Xcoord % DPmodule == 0:

                # add new distinguished point
                DWp[Xcoord] = dW

                if flag_debug > 1:
                    printstr = '\r[wild] T+W=%s+%s=%s' % (len(DTp), len(DWp),
                                                          len(DTp) + len(DWp))
                    printstr += '; %064x 0x%x' % (Xcoord, dW)
                    print(printstr)
                    save2file('wild.txt', 'a', '%064x %s\n' % (Xcoord, dW))
                # compare distinguished points, Tame & Wild
                compare = list(set(DTp) & set(DWp))
                if len(compare) > 0:
                    dDT = DTp[compare[0]]
                    dDW = DWp[compare[0]]
                    if dDT > dDW:
                        prvkey = dDT - dDW
                    elif dDW > dDT:
                        prvkey = dDW - dDT
                    else:
                        print("\r[error] dDW == dDT !!! (0x%x)" % dDW)
                        exit(-1)

            if prvkey: break

            dW += nowjumpsize
            if (not flag_gmpy2) and flag_coincurve:
                Wp = PublicKey.combine_keys([Wp, Sp[pw]])
            else:
                Wp = add_a(Wp, Sp[pw])

        if prvkey: break

        if not (n_jump % 5000):

            t2 = t2_info = time.time()

            # info
            if (flag_debug > 0 and (t2_info - t1_info) > 10) or prvkey:
                printstr = '\r[i] DP T+W=%s+%s=%s; dp/kgr=%.1f' % (
                    len(DTp), len(DWp), len(DTp) + len(DWp), 1.0 *
                    (len(DTp) + len(DWp)) / 2)
                printstr += ' ' * 60
                print(printstr)
                t1_info = t2_info

            # indicator, progress, time
            if (t2 - t1) > 1 or prvkey:
                printstr = '\r'
                printstr += '[%s ' % (time_format(t2 - t0,
                                                  (1, 1, 1, 1, 1, 1, 0, 0)))
                if t2 - t1 != 0:
                    printstr += '; %s j/s' % prefSI(
                        (n_jump - last_jump) / (t2 - t1))
                else:
                    printstr += '; %s j/s' % prefSI(
                        (n_jump - last_jump) / 0.001)
                #printstr += '; %sj of %sj %.1f%%' % (
                printstr += '; %sj %.1f%%' % (
                    n_jump if n_jump < 10**3 else prefSI(n_jump)
                    #, 2*Wsqrt if 2*Wsqrt < 10**3 else prefSI(2*Wsqrt)
                    ,
                    (1.0 * n_jump / (2 * Wsqrt)) * 100)
                if 1 or flag_debug < 1:
                    printstr += '; dp/kgr=%.1f' % (1.0 *
                                                   (len(DTp) + len(DWp)) / 2)
                #printstr += 'lost_TIME_left'
                timeleft = (t2 - t0) * (1 - (1.0 * n_jump /
                                             (2 * Wsqrt))) / (1.0 * n_jump /
                                                              (2 * Wsqrt))
                if timeleft > 0:
                    printstr += ';%s ]  ' % (time_format(
                        timeleft, (1, 1, 1, 1, 1, 1, 0, 0)))
                else:
                    printstr += ';%s ]  ' % (time_format(
                        0, (1, 1, 1, 1, 1, 1, 0, 0)))
                if sys.version_info[0] == 2:
                    print(printstr, end='')
                    sys.stdout.flush()
                else:
                    print(printstr, end='', flush=True)
                t1 = t2
                last_jump = n_jump

    return prvkey, n_jump, (time.time() - t0), len(DTp), len(DWp)
예제 #9
0
        print('[range] 2^%s..2^%s ; W = U - L = 0x%x (2^%s)' %
              (pow2L, pow2U, W, pow2W))

    if pow2W < bitMin or pow2W > bitMax:
        print('[error] W must be 2^%s..2^%s!' % (bitMin, bitMax))
        usage()
    if pow2W > 55:
        print('[warn!] W = 2^%s too big! long runtime expected' % (pow2W))

    print("[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]")
    starttime = time.time()

    Sp = [Gp]
    for k in xrange(255):
        if (not flag_gmpy2) and flag_coincurve:
            Sp.append(Sp[k].multiply(int_to_bytes(2)))
        else:
            Sp.append(mul_2a(Sp[k]))
    print('[+] Sp-table of pow2 points - ready')

    #print("[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]")

    list_runjump, list_runtime, list_dpkgr = list(), list(), list()

    #timeit
    for i in xrange(Ntimeit):

        print("[~~~~~~~~~~~~~~~~~~~~~~[%s/%s]~~~~~~~~~~~~~~~~~~~~~]" %
              (i + 1, Ntimeit))
        if flag_debug > 1:
            save2file('tame.txt', 'w', '')