示例#1
0
    def _sign(self, pdata, sks, dump_json_data):
        if not isinstance(sks, list):
            sks = [sks]

        jheader = '{"alg": "ES256"}'
        jheader_b64 = base64url_encode(jheader)

        jpayload = json.dumps(pdata) if dump_json_data else pdata
        jpayload_b64 = base64url_encode(jpayload)

        pdata_sig = {'payload': jpayload_b64,
                     'signatures': []}

        for sk in sks:
            sig_string_b64 = jws.sign(jheader, jpayload, sk, is_json=True)

            order = sk.curve.order
            sig_string = base64url_decode(sig_string_b64)
            r, s = sigdecode_string(sig_string, order)
            sig_der = sigencode_der(r, s, order)
            sig_der_b64 = base64url_encode(sig_der)

            pdata_sig['signatures'].append({'protected': jheader_b64,
                                            'signature': sig_der_b64})

        return pdata_sig
示例#2
0
文件: ecc.py 项目: chrisrico/electrum
 def from_signature(klass, sig, recid, h, curve):  # TODO use libsecp??
     """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """
     from ecdsa import util, numbertheory
     from . import msqr
     curveFp = curve.curve
     G = curve.generator
     order = G.order()
     # extract r,s from signature
     r, s = util.sigdecode_string(sig, order)
     # 1.1
     x = r + (recid//2) * order
     # 1.3
     alpha = ( x * x * x  + curveFp.a() * x + curveFp.b() ) % curveFp.p()
     beta = msqr.modular_sqrt(alpha, curveFp.p())
     y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta
     # 1.4 the constructor checks that nR is at infinity
     try:
         R = Point(curveFp, x, y, order)
     except:
         raise InvalidECPointException()
     # 1.5 compute e from message:
     e = string_to_number(h)
     minus_e = -e % order
     # 1.6 compute Q = r^-1 (sR - eG)
     inv_r = numbertheory.inverse_mod(r,order)
     try:
         Q = inv_r * ( s * R + minus_e * G )
     except:
         raise InvalidECPointException()
     return klass.from_public_point( Q, curve )
 def verify(self, msg, sig):
     order = (2 ** self.prepared_key.curve.key_size) - 1
     signature = sigencode_der(*sigdecode_string(sig, order), order=order)
     try:
         self.prepared_key.verify(signature, msg, ec.ECDSA(self.hash_alg()))
         return True
     except:
         return False
示例#4
0
    def _create_auth_token(self, sk, profile):
        jheader = '{"alg": "ES256"}'
        jheader_b64 = base64url_encode(jheader)

        body = {'id': profile.profile_id, 'timestamp': int(time.time())}
        jbody = json.dumps(body)
        jbody_b64 = base64url_encode(jbody)

        sig_string_b64 = jws.sign(jheader, jbody, sk, is_json=True)

        order = sk.curve.order
        sig_string = base64url_decode(sig_string_b64)
        r, s = sigdecode_string(sig_string, order)
        sig_der = sigencode_der(r, s, order)
        sig_der_b64 = base64url_encode(sig_der)

        return '{0}.{1}.{2}'.format(jheader_b64, jbody_b64, sig_der_b64)
示例#5
0
    def verify_message(self, address, signature, message):
        """ See http://www.secg.org/download/aid-780/sec1-v2.pdf for the math """
        from ecdsa import numbertheory, ellipticcurve, util
        import msqr

        curve = curve_secp256k1
        G = generator_secp256k1
        order = G.order()
        # extract r,s from signature
        sig = base64.b64decode(signature)
        if len(sig) != 65:
            raise BaseException("Wrong encoding")
        r, s = util.sigdecode_string(sig[1:], order)
        nV = ord(sig[0])
        if nV < 27 or nV >= 35:
            raise BaseException("Bad encoding")
        if nV >= 31:
            compressed = True
            nV -= 4
        else:
            compressed = False

        recid = nV - 27
        # 1.1
        x = r + (recid / 2) * order
        # 1.3
        alpha = (x * x * x + curve.a() * x + curve.b()) % curve.p()
        beta = msqr.modular_sqrt(alpha, curve.p())
        y = beta if (beta - recid) % 2 == 0 else curve.p() - beta
        # 1.4 the constructor checks that nR is at infinity
        R = ellipticcurve.Point(curve, x, y, order)
        # 1.5 compute e from message:
        h = Hash(self.msg_magic(message))
        e = string_to_number(h)
        minus_e = -e % order
        # 1.6 compute Q = r^-1 (sR - eG)
        inv_r = numbertheory.inverse_mod(r, order)
        Q = inv_r * (s * R + minus_e * G)
        public_key = ecdsa.VerifyingKey.from_public_point(Q, curve=SECP256k1)
        # check that Q is the public key
        public_key.verify_digest(sig[1:], h, sigdecode=ecdsa.util.sigdecode_string)
        # check that we get the original signing address
        addr = public_key_to_bc_address(encode_point(public_key, compressed))
        if address != addr:
            raise BaseException("Bad signature")
示例#6
0
def verify_message(address, signature, message):
    """ See http://www.secg.org/download/aid-780/sec1-v2.pdf for the math """
    curve = ecdsa.curves.SECP256k1.curve  # curve_secp256k1
    G = ecdsa.curves.SECP256k1.generator
    order = G.order()
    # extract r,s from signature
    if len(signature) != 65: raise BaseException("Wrong signature")
    r, s = util.sigdecode_string(signature[1:], order)
    nV = ord(signature[0])
    if nV < 27 or nV >= 35:
        raise BaseException("Bad encoding")
    if nV >= 31:
        compressed = True
        nV -= 4
    else:
        compressed = False

    recid = nV - 27
    # 1.1
    x = r + (recid / 2) * order
    # 1.3
    alpha = (x * x * x + curve.a() * x + curve.b()) % curve.p()
    beta = ecdsa.numbertheory.square_root_mod_prime(alpha, curve.p())
    y = beta if (beta - recid) % 2 == 0 else curve.p() - beta
    # 1.4 the constructor checks that nR is at infinity
    R = ellipticcurve.Point(curve, x, y, order)
    # 1.5 compute e from message:
    h = sha256(sha256(message_magic(message)).digest()).digest()
    e = util.string_to_number(h)
    minus_e = -e % order
    # 1.6 compute Q = r^-1 (sR - eG)
    inv_r = numbertheory.inverse_mod(r, order)
    Q = inv_r * (s * R + minus_e * G)
    public_key = ecdsa.VerifyingKey.from_public_point(Q, curve=ecdsa.curves.SECP256k1)
    # check that Q is the public key
    public_key.verify_digest(signature[1:], h, sigdecode=ecdsa.util.sigdecode_string)

    if address:
        address_type = int(binascii.hexlify(tools.b58decode(address, None)[0]), 16)
        addr = tools.public_key_to_bc_address('\x04' + public_key.to_string(), address_type, compress=compressed)
        if address != addr:
            raise Exception("Invalid signature")
示例#7
0
文件: lbrycrd.py 项目: lbryio/lbryum
 def from_signature(cls, sig, recid, h, curve):
     """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """
     curveFp = curve.curve
     G = curve.generator
     order = G.order()
     # extract r,s from signature
     r, s = util.sigdecode_string(sig, order)
     # 1.1
     x = r + (recid / 2) * order
     # 1.3
     alpha = (x * x * x + curveFp.a() * x + curveFp.b()) % curveFp.p()
     beta = msqr.modular_sqrt(alpha, curveFp.p())
     y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta
     # 1.4 the constructor checks that nR is at infinity
     R = Point(curveFp, x, y, order)
     # 1.5 compute e from message:
     e = string_to_number(h)
     minus_e = -e % order
     # 1.6 compute Q = r^-1 (sR - eG)
     inv_r = numbertheory.inverse_mod(r, order)
     Q = inv_r * (s * R + minus_e * G)
     return cls.from_public_point(Q, curve)
示例#8
0
 def from_signature(klass, sig, recid, h, curve):
     """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """
     from ecdsa import util, numbertheory
     from . import msqr
     curveFp = curve.curve
     G = curve.generator
     order = G.order()
     # extract r,s from signature
     r, s = util.sigdecode_string(sig, order)
     # 1.1
     x = r + (recid // 2) * order
     # 1.3
     alpha = (x * x * x + curveFp.a() * x + curveFp.b()) % curveFp.p()
     beta = msqr.modular_sqrt(alpha, curveFp.p())
     y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta
     # 1.4 the constructor checks that nR is at infinity
     R = Point(curveFp, x, y, order)
     # 1.5 compute e from message:
     e = string_to_number(h)
     minus_e = -e % order
     # 1.6 compute Q = r^-1 (sR - eG)
     inv_r = numbertheory.inverse_mod(r, order)
     Q = inv_r * (s * R + minus_e * G)
     return klass.from_public_point(Q, curve)
    message_2 = str("message_2")

    #Generates the private key using the NIST224p curve, and SHA-1 hash function
    sk = SigningKey.generate(curve=NIST224p)

    #This is the secret number used to sign messages
    actualPrivateKey = sk.privkey.secret_multiplier

    #gets the public key (vk)
    vk = sk.get_verifying_key()

    #Signing a message
    signature = sk.sign(message_1.encode('utf-8'), k=22)

    #Pulling out the Signature Pair
    r1, s1 = sigdecode_string(signature, vk.pubkey.order)

    #Singing a second message using the same K value, using the same K value is what opens ECDSA to attack
    signature2 = sk.sign(message_2.encode("utf-8"), k=22)

    #Pulling out the second Signature Pair (Note: r1 == r2 due to the K value being the same)
    r2, s2 = sigdecode_string(signature2, vk.pubkey.order)

    #Get message Hash
    messageHash1 = sha1(message_1.encode('utf-8')).hexdigest()
    messageHash2 = sha1(message_2.encode('utf-8')).hexdigest()

    #Start the attack
    privateKeyCalculation = attack(vk.pubkey.order, (r1, s1), (r2, s2),
                                   messageHash1, messageHash2)
示例#10
0
    def verify_message(self, address, signature, message):
        """Creates a public key from a message signature and verifies message

        Bitcoin uses a compact format for message signatures (for tx sigs it
        uses normal DER format). The format has the normal r and s parameters
        that ECDSA signatures have but also includes a prefix which encodes
        extra information. Using the prefix the public key can be
        reconstructed from the signature.

        |  Prefix values:
        |      27 - 0x1B = first key with even y
        |      28 - 0x1C = first key with odd y
        |      29 - 0x1D = second key with even y
        |      30 - 0x1E = second key with odd y

        If key is compressed add 4 (31 - 0x1F, 32 - 0x20, 33 - 0x21, 34 - 0x22 respectively)

        Raises
        ------
        ValueError
            If signature is invalid
        """

        sig = b64decode(signature.encode('utf-8'))
        if len(sig) != 65:
            raise ValueError('Invalid signature size')

        # get signature prefix, compressed and recid (which key is odd/even)
        prefix = sig[0]
        if prefix < 27 or prefix > 35:
            return False
        if prefix >= 31:
            compressed = True
            recid = prefix - 31
        else:
            compressed = False
            recid = prefix - 27

        # create message digest -- note double hashing
        message_magic = add_magic_prefix(message)
        message_digest = hashlib.sha256(
            hashlib.sha256(message_magic).digest()).digest()

        #
        # use recid, r and s to get the point in the curve
        #

        # get signature's r and s
        r, s = sigdecode_string(sig[1:], _order)

        # ger R's x coordinate
        x = r + (recid // 2) * _order

        # get R's y coordinate (y**2 = x**3 + 7)
        y_values = sqrt_mod((x**3 + 7) % _p, _p, True)
        if (y_values[0] - recid) % 2 == 0:
            y = y_values[0]
        else:
            y = y_values[1]

        # get R (recovered ephemeral key) from x,y
        R = ellipticcurve.Point(_curve, x, y, _order)

        # get e (hash of message encoded as big integer)
        e = int(hexlify(message_digest), 16)

        # compute public key Q = r^-1 (sR - eG)
        # because Point substraction is not defined we will instead use:
        # Q = r^-1 (sR + (-eG) )
        minus_e = -e % _order
        inv_r = numbertheory.inverse_mod(r, _order)
        Q = inv_r * (s * R + minus_e * _G)

        # instantiate the public key and verify message
        public_key = VerifyingKey.from_public_point(Q, curve=SECP256k1)
        key_hex = hexlify(public_key.to_string()).decode('utf-8')
        pubkey = PublicKey.from_hex('04' + key_hex)
        if not pubkey.verify(signature, message):
            return False

        # confirm that the address provided corresponds to that public key
        if pubkey.get_address(compressed=compressed).to_string() != address:
            return False

        return True
示例#11
0
print(
    "======================================================================================================="
)
print(
    "======================================================================================================="
)
msg1 = "We are not uncertain with the vote.".encode('utf-8')
msg2 = "We are uncertain with the vote.".encode('utf-8')
print("Hash 1:\t\t\t\t", int.from_bytes(sha256(msg1).digest(),
                                        byteorder='big'))
print("Hash 2:\t\t\t\t", int.from_bytes(sha256(msg2).digest(),
                                        byteorder='big'))
k = 7800010500099000107000320001190009700011500032000104000101000114000101
signature1 = priv_key.sign(msg1, k=k, hashfunc=sha256)
signature2 = priv_key.sign(msg2, k=k + 1, hashfunc=sha256)
human_sign_1 = sigdecode_string(signature1, pub_key.pubkey.order)
human_sign_2 = sigdecode_string(signature2, pub_key.pubkey.order)
r1 = human_sign_1[0]
r2 = human_sign_2[0]
print(
    "======================================================================================================="
)
print(
    "======================================================================================================="
)
print("Signature 1")
print("\tR:\t\t\t", human_sign_1[0])
print("\tS:\t\t\t", human_sign_1[1])
print("Signature 2")
print("\tR:\t\t\t", human_sign_2[0])
print("\tS:\t\t\t", human_sign_2[1])
示例#12
0
def ecdsa_sign(sk, msg, k=None):
    """Sign ecdsa"""
    sig = sk.sign(msg, hashfunc=sha3.sha3_256, k=k)
    signature = util.sigdecode_string(sig, order)

    return signature  # matches haskell output
示例#13
0
def decode_sig(sig):
    r, s = sigdecode_string(sig, SECP256k1.generator.order())
    return r, s