Exemple #1
0
def map2curve_simple_swu(alpha: bytearray, i: int=1) -> ecc.Point:
    '''Maps the octet bytearray alpha into the elliptic curve, and returns a 
       point from the elliptic curve.
    '''
    t =  HashToBase(alpha, i)
    alpha = pow(t, 2, PRIME)
    alpha = -alpha % PRIME
    right = (pow(alpha, 2, PRIME) + alpha) % PRIME
    right = pow(right, PRIME-2, PRIME) # right^(-1) % PRIME   
    right = (right + 1)  % PRIME
    left = -B % PRIME
    left =  (left * pow(A, PRIME-2, PRIME)) % PRIME # (left * A^-1) % PRIME
    x2 = (left * right) % PRIME
    x3 = (alpha * x2)  % PRIME
    h2 = pow(x2, 3, PRIME) # x2 ^ 3  % PRIME
    i2 = (x2 * A)  % PRIME
    i2 = (i2 + B) % PRIME
    h2 = (h2 + i2)  % PRIME
    h3 = pow(x3, 3, PRIME) # x3 ^ 3  % PRIME
    i3 = (x3 * A)  % PRIME
    i3 = (i3 + B)  % PRIME
    h3 = (h3 + i3)  % PRIME
    y1 = pow(h2, (PRIME+1) // 4, PRIME) # h2 ^ ((p + 1) / 4)  % PRIME
    y2 = pow(h3, (PRIME+1) // 4, PRIME) # h3 ^ ((p + 1) / 4)  % PRIME
    if pow(y1, 2, PRIME) == h2:
        return ecc.Point(curve_256, x2, y1)
    else:
        return ecc.Point(curve_256, x3, y2)
Exemple #2
0
def from_sec(string,
             curve=curves.SECP256k1,
             hashfunc=sha1,
             validate_point=True):
    """Convert a public key in SEC binary format to a verifying key."""
    # based on code from https://github.com/richardkiss/pycoin
    if string.startswith(b('\x04')):
        # uncompressed
        return VerifyingKey.from_string(string[1:], curve, hashfunc,
                                        validate_point)
    elif string.startswith(b('\x02')) or string.startswith(b('\x03')):
        # compressed
        is_even = string.startswith(b('\x02'))
        x = string_to_number(string[1:])
        order = curve.order
        p = curve.curve.p()
        alpha = (pow(x, 3, p) + (curve.curve.a() * x) + curve.curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        if is_even == bool(beta & 1):
            y = p - beta
        else:
            y = beta
        if validate_point:
            assert ecdsa.point_is_valid(curve.generator, x, y)
        point = ellipticcurve.Point(curve.curve, x, y, order)
        return VerifyingKey.from_public_point(point, curve, hashfunc)
Exemple #3
0
def uncompress_public_key(public_key):
    """
    Uncompress the compressed public key.

    :param public_key: compressed public key
    :return: uncompressed public key
    """
    is_even = public_key.startswith(b'\x02')
    x = string_to_number(public_key[1:])

    curve = ecdsa.NIST256p.curve
    order = ecdsa.NIST256p.order
    p = curve.p()
    alpha = (pow(x, 3, p) + (curve.a() * x) + curve.b()) % p

    beta = square_root_mod_prime(alpha, p)

    if is_even == bool(beta & 1):
        y = p - beta
    else:
        y = beta

    point = ellipticcurve.Point(curve, x, y, order)
    from ecdsa.util import number_to_string
    return b''.join([
        number_to_string(point.x(), order),
        number_to_string(point.y(), order)
    ])
Exemple #4
0
def vk_from_point(x: bytes, y: bytes):
    curve = ecdsa_curves.NIST256p
    x = int(x.hex(), 16)
    y = int(y.hex(), 16)

    p = ellipticcurve.Point(curve.curve, x, y)
    key = VerifyingKey.from_public_point(p, curve)

    return key
Exemple #5
0
def ecdsa_cose_to_key(encoded: bytes) -> VerifyingKey:
    decoded = loads(encoded)

    kty = decoded[CoseKey.KTY]
    curve = _ecdsa_curves[decoded[CoseKey.CRV]]
    x = int(decoded[CoseKey.X].hex(), 16)
    y = int(decoded[CoseKey.Y].hex(), 16)

    p = ellipticcurve.Point(curve.curve, x, y)
    key = VerifyingKey.from_public_point(p, curve)

    return key
def point_decompress(curve, data):
    prefix = data[0]
    assert (prefix in ['\x02', '\x03'])
    parity = 1 if prefix == '\x02' else -1

    x = util.string_to_number(data[1:])

    y = numbertheory.square_root_mod_prime(
        (x * x * x + curve.a() * x + curve.b()) % curve.p(), curve.p())

    y = parity * y % curve.p()
    return ellipticcurve.Point(curve, x, y)
Exemple #7
0
 def readkeys(self, path):
     """
     read private keys from a directory, which must containser private.key, address and public.key
     """
     self.address = open(path + "/address").read()
     self.private_key_js = open(path + "/private.key").read()
     self.public_key_js = open(path + "/public.key").read()
     sk_obj = json.loads(self.private_key_js)
     X = int(sk_obj['X'])
     Y = int(sk_obj['Y'])
     D = int(sk_obj['D'])
     self.public_key = VerifyingKey.from_public_point(ellipticcurve.Point(NIST256p.curve, X, Y), NIST256p, double_sha256)
     self.private_key = SigningKey.from_secret_exponent(D, NIST256p, double_sha256)
Exemple #8
0
def secp224k1():
    _a = 0x0000000000000000000000000000000000000000000000000000000000
    _b = 0x0000000000000000000000000000000000000000000000000000000005
    _p = 0x00fffffffffffffffffffffffffffffffffffffffffffffffeffffe56d
    _Gx = 0x00a1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45c
    _Gy = 0x007e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5
    _r = 0x010000000000000000000000000001dce8d2ec6184caf0a971769fb1f7
    curve_secp224k1 = ellipticcurve.CurveFp(_p, _a, _b)
    generator_secp224k1 = ellipticcurve.Point(curve_secp224k1, _Gx, _Gy, _r)
    secp224k1_instance = curves.Curve("SECP224k1", curve_secp224k1,
                                      generator_secp224k1, (1, 3, 132, 0, 20),
                                      "secp256k1")
    return secp224k1_instance
Exemple #9
0
    def FromCoordinates(cls, x: int, y: int) -> IPoint:
        """
        Construct class from point coordinates.

        Args:
            x (int): X coordinate of the point
            y (int): Y coordinate of the point

        Returns:
            IPoint: IPoint object
        """
        return cls(
            ellipticcurve.PointJacobi.from_affine(
                ellipticcurve.Point(curve_256, x, y)))
Exemple #10
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(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")
Exemple #11
0
def derive_pub_key(x, y, curve, hashfunc):
    """
    Not sure if this actually works, examples provided on the github page are wrong (see issues)
    :param x: X coordinate of the elliptic curve
    :param y: Y coordinate of the elliptic curve
    :param curve: Which curve to use
    :param hashfunc: Which hash function used for hashing the data before signing
    :return: A public key
    """
    x = base64decode(x)
    x = binascii.hexlify(x)
    y = base64decode(y)
    y = binascii.hexlify(y)
    x = int(x, 16)
    y = int(y, 16)
    point = ellipticcurve.Point(curves.NIST256p, x, y)
    return keys.VerifyingKey.from_public_point(point,
                                               curves.NIST256p,
                                               hashfunc=sha256)
    def FromPoint(cls, key_point: IPoint) -> IPublicKey:
        """
        Construct class from key point.

        Args:
            key_point (IPoint object): Key point

        Returns:
            IPublicKey: IPublicKey object

        Raises:
            ValueError: If key point is not valid
        """
        try:
            return cls(
                ecdsa.VerifyingKey.from_public_point(ellipticcurve.Point(
                    curve_256, key_point.X(), key_point.Y()),
                                                     curve=curves.NIST256p))
        except keys.MalformedPointError as ex:
            raise ValueError("Invalid public key point") from ex
def validate_keys(sk: int, vk: Point) -> bool:
    std_sk = SigningKey.from_secret_exponent(sk, SECP256k1, sha256)
    std_vk = std_sk.get_verifying_key()
    std_point = ellipticcurve.Point(SECP256k1.curve, vk[0].value, vk[1].value)
    std_vk_from_point = VerifyingKey.from_public_point(std_point, SECP256k1,
                                                       sha256)
    public_keys_match = std_vk_from_point.to_string() == std_vk.to_string()

    print(
        f"Your private key is {sk} and the respective public key is {represent_point(vk)}."
    )
    if public_keys_match:
        print(
            f"This private key generates the same public key using py-ecdsa.")
    else:
        print(
            f"The public key generated using py-ecdsa is {str(std_vk.pubkey.point)}"
        )

    return public_keys_match
Exemple #14
0
    def _verifying_key_from_pubkey(cls, pubkey):
        """ Converts a 33-byte compressed pubkey into an ecdsa.VerifyingKey object. """
        if not isinstance(pubkey, (bytes, bytearray)):
            raise TypeError('pubkey must be raw bytes')
        if len(pubkey) != 33:
            raise ValueError('pubkey must be 33 bytes')
        if pubkey[0] not in (2, 3):
            raise ValueError('invalid pubkey prefix byte')
        curve = cls.CURVE.curve

        is_odd = pubkey[0] == 3
        x = bytes_to_int(pubkey[1:])

        # p is the finite field order
        a, b, p = curve.a(), curve.b(), curve.p()  # pylint: disable=invalid-name
        y2 = pow(x, 3, p) + b  # pylint: disable=invalid-name
        assert a == 0  # Otherwise y2 += a * pow(x, 2, p)
        y = NT.square_root_mod_prime(y2 % p, p)
        if bool(y & 1) != is_odd:
            y = p - y
        point = EC.Point(curve, x, y)

        return ecdsa.VerifyingKey.from_public_point(point, curve=cls.CURVE)
Exemple #15
0
def toPoint( x, y):
    return ellipticcurve.Point(ecdsa.ecdsa.generator_256.curve(), x, y, ecdsa.ecdsa.generator_256.order())
 def generate_symmetric_key(vk_hex, sk):
     sk = int(sk, 16)
     vk_point = ellipticcurve.Point(_curve, int(vk_hex[:64], 16),
                                    int(vk_hex[64:], 16), _order)
     shared_key = vk_point * sk
     return shared_key
Exemple #17
0
from ecdsa import ellipticcurve
from ecdsa.util import randrange
#from ecdsa.ecdsa import curve_secp256k1
from ecdsa.curves import SECP256k1
from ecdsa import numbertheory

# Certicom secp256-k1
_a = 0x0000000000000000000000000000000000000000000000000000000000000000
_b = 0x0000000000000000000000000000000000000000000000000000000000000007
_p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
_Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
_r = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

curve_secp256k1 = ellipticcurve.CurveFp(_p, _a, _b)
generator_secp256k1 = ellipticcurve.Point(curve_secp256k1, _Gx, _Gy, _r)

def ring_signature(siging_key, key_idx, M, y, G=SECP256k1.generator, hash_func=hashlib.sha3_256):
    """
        Generates a ring signature for a message given a specific set of
        public keys and a signing key belonging to one of the public keys
        in the set.

        PARAMS
        ------

            signing_key: (int) The with which the message is to be anonymously signed.

            key_idx: (int) The index of the public key corresponding to the signature
                private key over the list of public keys that compromise the signature.
Exemple #18
0
def ecdsa_pub(x, y):
    """Create a public key from a public point"""
    point = ellipticcurve.Point(SECP256k1, x, y)
    return VerifyingKey.from_public_point(point, curve=SECP256k1)
Exemple #19
0
import ecdsa
import ecdsa.ellipticcurve as EC

curve = ecdsa.SECP256k1
x = int('11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c', 16)
y = int('b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3', 16)
point = EC.Point(curve.curve, x, y)
pubkey = ecdsa.VerifyingKey.from_public_point(point, curve)

hash1 = 90774958364900180671716888080665726921328827653065727390791155349203800699667

r1 = 97921318692748166969765893503724782362221860890089306445657980140065784098104
s1 = 17870770544568028453805091504963125490615703388985597936947183001452377396233

sig = ecdsa.ecdsa.Signature(r1, s1)
if pubkey.pubkey.verifies(hash1, sig):
    print("Good")
else:
    print("Bad")

hash1 = 70438975929202441702137589012525894517177874894451752259863210250765743151652

r1 = 67469108926628898148530592947733862172872496318648607111578457920563549925544
s1 = 48322980310687297275040392060954045679965067960426297271026705220954611568793

sig = ecdsa.ecdsa.Signature(r1, s1)
if pubkey.pubkey.verifies(hash1, sig):
    print("Good")
else:
    print("Bad")
Exemple #20
0
_b = 0x0000000000000000000000000000000000000000000000000000000000000007
# Curve's generator point is:
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
# prime number of points in the group (the order)
_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

# The ECDSA curve (secp256k1) is:
# Note that we could get that from ecdsa lib, e.g.:
# SECP256k1.__dict__['curve']
_curve = ellipticcurve.CurveFp(_p, _a, _b)

# The generator base point is:
# Note that we could get that from ecdsa lib, e.g.:
# SECP256k1.__dict__['generator']
_G = ellipticcurve.Point(_curve, _Gx, _Gy, _order)


# method used by both PrivateKey and PublicKey - TODO clean - add in another module?
def add_magic_prefix(message):
    magic_prefix = b'\x18Bitcoin Signed Message:\n'
    message_size = len(message).to_bytes(1, byteorder='big')
    message_encoded = message.encode('utf-8')
    message_magic = magic_prefix + message_size + message_encoded
    return message_magic


class PrivateKey:
    """Represents an ECDSA private key.

    Attributes
Exemple #21
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