Exemple #1
0
    def test_dhZ(self):
        from ecdsa.keys import SigningKey   # VerifyingKey
        from ecdsa.curves import NIST521p

        # Party V(recepient) declares a satic key pair
        curve = NIST521p
        v_stc = SigningKey.generate(curve=curve)

        # and advertise to Party U(Sender) ( U <--(pub key)-- V)
        v_pub = v_stc.get_verifying_key()
        self.assertEqual(v_pub.curve, curve)
        print(v_pub.curve)

        # Party U provides a ephemeral key
        u_epk = SigningKey.generate(curve=v_pub.curve)

        from jose.jwa import ec
        # Compute ECDH as shared secret
        # This shared secret itself is NOT have to be exchanged.
        shared_secret_u = ec.ecdsa_dhZ(v_pub, u_epk)

        # Party V recive Epemeral Public Key ( U --(pub key)--> V)
        v_epk = u_epk.get_verifying_key()

        # Party V compute
        shared_secret_v = ec.ecdsa_dhZ(v_epk, v_stc)

        # Secrete Agreeed!
        self.assertEqual(shared_secret_u, shared_secret_v)
Exemple #2
0
 def setUp(self):
     self.private_key = SigningKey.generate()
     self.public_keys = tuple(PublicKey.from_signing_key(SigningKey.generate()) for _ in range(2))
     self.operation = Operation(OperationRev(), 'http://example.com', self.public_keys)
     sign_object(PublicKey.from_signing_key(self.private_key), self.private_key, self.operation)
     self.uuid = self.operation.uuid
     self.identifier = Identifier.from_operation(self.operation)
Exemple #3
0
    def setUp(self):
        initialise_database('test_database_file')

        self.private_keys = [SigningKey.generate(), SigningKey.generate()]
        self.public_keys = [PublicKey.from_signing_key(private_key) for private_key in self.private_keys]

        self.operation = [
            Operation(OperationRev(), 'http://example.com/', [self.public_keys[1]]),
            Operation(OperationRev(), 'http://example2.com/', [self.public_keys[0], self.public_keys[1]]),
            Operation(OperationRev(), 'http://example3.com/', [self.public_keys[1]])
        ]
Exemple #4
0
    def test_new_keys(self):
        user = User.new_keys(curve=NIST256p)

        self.assertIsInstance(user, User)
        self.assertIsInstance(user._private_key, SigningKey)
        self.assertIsInstance(user._public_key.verifying_key, VerifyingKey)

        self.assertEqual(user._private_key.to_der(),
                         SigningKey.from_string(user._private_key.to_string(), NIST256p).to_der())

        self.assertEqual(len(user._private_key.to_der()), len(SigningKey.generate(curve=NIST256p).to_der()))
        self.assertNotEqual(len(user._private_key.to_der()), len(SigningKey.generate().to_der()))
Exemple #5
0
    def new_keys(cls, curve=NIST192p):  # TODO different curve as default?
        """
        Create new user using auto-generated keys.

        :param curve: private key's generation curve
        """
        return cls(SigningKey.generate(curve=curve))
    def __init__(self, public_key: str = None, private_key: str = None):
        """

        :param public_key: base58 encoded
        :param private_key: base58 encoded
        """
        self.__public_key = None
        self.__private_key = None

        if private_key is not None:
            self.__private_key = SigningKey.from_string(
                b58decode(private_key),
                curve=NIST256p
            )
            self.__public_key = self.__private_key.get_verifying_key()

        if public_key is not None:
            self.__public_key = VerifyingKey.from_string(
                self.decompress(b58decode(public_key))[1:],
                curve=NIST256p
            )

        if public_key is None and private_key is None:
            self.__private_key = SigningKey.generate(curve=NIST256p)
            self.__public_key = self.__private_key.get_verifying_key()
Exemple #7
0
    def test_exchage(self):
        from ecdsa import SigningKey, NIST521p

        alice_own = SigningKey.generate(curve=NIST521p)
        bob_own = SigningKey.generate(curve=NIST521p)

        alice_pri = alice_own.privkey
        alice_pub = alice_pri.public_key

        bob_pri = bob_own.privkey
        bob_pub = bob_pri.public_key

        alice_pub_point = alice_pub.point
        bob_pub_point = bob_pub.point

        print(alice_pub_point, bob_pub_point)
Exemple #8
0
    def test_generate(self):
        def hexdigest(digester, data):
            import hashlib
            return hashlib.new(digester, data).hexdigest()

        def longdigest(digester, data):
            return int(hexdigest(digester, data), 16)

        from ecdsa.keys import SigningKey, VerifyingKey
        from ecdsa.curves import NIST521p

        pri = SigningKey.generate(curve=NIST521p)
        pub = pri.get_verifying_key()
        self.assertTrue(isinstance(pub, VerifyingKey))

        data = 'what a wonderfull world.'
        digest = longdigest('sha256', b(data))

        sig = pri.sign_number(digest)
        self.assertTrue(isinstance(sig, tuple))
        self.assertEqual(len(sig), 2)

        from ecdsa.ecdsa import Signature
        sigobj = Signature(*sig)        # (r, s)
        self.assertTrue(pub.pubkey.verifies(digest, sigobj))
Exemple #9
0
    def setUp(self):
        self.private_key = SigningKey.generate(curve=NIST256p)
        self.public_key = PublicKey.from_signing_key(self.private_key)

        self.operation = Operation(OperationRev(), 'http://example.com/', [self.public_key])

        sign_object(self.public_key, self.private_key, self.operation)
Exemple #10
0
    def test_no_database(self):
        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Block.get_ids_list()

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Block.get(sha256(b'something').digest())

        private_key = SigningKey.generate()
        public_key = PublicKey.from_signing_key(private_key)

        operations = [
            Operation(OperationRev(), 'http://example0.com/', [public_key]),
            Operation(OperationRev(), 'http://example1.com/', [public_key])
        ]

        for op in operations:
            sign_object(public_key, private_key, op)

        block = Block.from_operations_list(BlockRev(), int(time.time()), operations)
        block.mine()
        sign_object(public_key, private_key, block)

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            block.put()

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            block.remove()
Exemple #11
0
    def test_generate(self):
        from ecdsa import SigningKey, NIST521p

        sk = SigningKey.generate(curve=NIST521p)
        pri = sk.privkey
        pub = pri.public_key
        param = dict(
            crv=sk.curve,
            x=pub.point.x(),
            y=pub.point.y(),
            d=pri.secret_multiplier)

        # Curve
        from ecdsa.ellipticcurve import Point, CurveFp
        from ecdsa.ecdsa import curve_521

        self.assertTrue(isinstance(curve_521, CurveFp))
        self.assertTrue(isinstance(param['crv'].curve, CurveFp))
        self.assertEqual(curve_521, param['crv'].curve)
        self.assertEqual(pub.point.curve(), curve_521)

        # Point
        p_new = Point(curve_521, param['x'], param['y'])
        self.assertEqual(p_new, pub.point)
        self.assertTrue(isinstance(pub.point, Point))

        # Public Key
        from ecdsa.ecdsa import Public_key, generator_521
        self.assertEqual(generator_521, pub.generator)
        pub_new = Public_key(generator_521, p_new)

        # Private Key
        from ecdsa.ecdsa import Private_key
        pri_new = Private_key(pub_new, param['d'])

        # Signature
        from ecdsa.ecdsa import string_to_int, Signature
        from hashlib import sha512
        from uuid import uuid1
        rnd = uuid1().int
        msg = "hello, it's me.".encode('utf8')
        digest = string_to_int(sha512(msg).digest())
        signature_new = pri_new.sign(digest, rnd)
        signature_old = pri.sign(digest, rnd)
        self.assertTrue(isinstance(signature_new, Signature))
        self.assertEqual(signature_new.r, signature_old.r)
        self.assertEqual(signature_new.s, signature_old.s)
        import six      # python3 no long
        self.assertTrue(type(signature_new.r) in six.integer_types)
        self.assertTrue(type(signature_new.s) in six.integer_types)

        # Verify
        print(pub.verifies(digest, signature_new))
        print(pub_new.verifies(digest, signature_old))

        #
        print(dir(pri_new))
        print(dir(pub_new))
        print(dir(pub_new.curve))
Exemple #12
0
    def setUp(self):
        self.private_keys = [SigningKey.generate(curve=NIST256p) for _ in range(3)]
        self.public_keys = [PublicKey.from_signing_key(private_key) for private_key in self.private_keys]

        self.operation = [
            Operation(OperationRev(), 'http://example.com/', [self.public_keys[1], self.public_keys[2]]),
            None, None
        ]
Exemple #13
0
def generate_key(identifier):
    from brave.core.application.model import Application

    key = SigningKey.generate(NIST256p, hashfunc=sha256)
    Application.objects(
        id=identifier,
        key__private=None  # Make sure we don't override an existing one.
    ).update(set__key__private=hexlify(key.to_string()))
Exemple #14
0
    def setUp(self):
        self.private_key = SigningKey.generate()
        self.public_key = PublicKey.from_signing_key(self.private_key)

        self.operations = [Operation(
            OperationRev(), 'http://example.com/', [self.public_key]) for _ in range(Block.MIN_OPERATIONS + 1)]
        for op in self.operations:
            sign_object(self.public_key, self.private_key, op)
Exemple #15
0
    def setUp(self):
        initialise_database('test_database_file')

        self.operations = [
            Operation(OperationRev(), 'http://example.com/' + url, [PublicKey.from_signing_key(SigningKey.generate())])
            for url in ('first/', 'second/')]

        for op in self.operations:
            sk = SigningKey.generate()
            sign_object(PublicKey.from_signing_key(sk), sk, op)

        block = Block.from_operations_list(BlockRev(), 42, self.operations)
        block.mine()
        sk = SigningKey.generate()
        sign_object(PublicKey.from_signing_key(sk), sk, block)
        block.put()

        self.identifiers = [Identifier.from_operation(op) for op in self.operations]
Exemple #16
0
    def setUp(self):
        initialise_database('test_database_file')

        self.private_key = SigningKey.generate()
        self.public_key = PublicKey.from_signing_key(self.private_key)
        # self.uuids = [uuid4() for _ in range(3)]

        self.operations = [[
            Operation(OperationRev(),'http://example0.com/v0/', [self.public_key]),
            Operation(OperationRev(),'http://example1.com/v0/', [self.public_key])
        ]]

        for op in self.operations[0]:
            sign_object(self.public_key, self.private_key, op)

        self.operations.append([
            Operation(OperationRev.from_obj(self.operations[0][0]), 'http://example0.com/v1/', [self.public_key]),
            Operation(OperationRev.from_obj(self.operations[0][1]), 'http://example1.com/v1/', [self.public_key]),
            Operation(OperationRev(), 'http://example2.com/v0/', [self.public_key])
        ])

        for op in self.operations[1]:
            sign_object(self.public_key, self.private_key, op)

        self.operations.append([
            Operation(OperationRev.from_obj(self.operations[1][0]),'http://example0.com/v2/', [self.public_key]),
            Operation(OperationRev.from_obj(self.operations[1][1]), 'http://example1.com/v2/', [self.public_key])
        ])

        for op in self.operations[2]:
            sign_object(self.public_key, self.private_key, op)

        self.operations.append([
            Operation(OperationRev.from_obj(self.operations[1][1]), 'http://alternative1.com/', [self.public_key]),
            Operation(OperationRev.from_obj(self.operations[1][2]), 'http://alternative2.com/', [self.public_key])
        ])

        for op in self.operations[3]:
            sign_object(self.public_key, self.private_key, op)

        timestamp = int(time.time()) - 100

        self.blocks = [Block.from_operations_list(BlockRev(), timestamp, self.operations[0])]
        self.blocks[0].mine()
        sign_object(self.public_key, self.private_key, self.blocks[0])
        self.blocks.append(
            Block.from_operations_list(BlockRev.from_obj(self.blocks[0]), timestamp + 20, self.operations[1]))
        self.blocks[1].mine()
        sign_object(self.public_key, self.private_key, self.blocks[1])
        self.blocks.append(
            Block.from_operations_list(BlockRev.from_obj(self.blocks[1]), timestamp + 40, self.operations[2]))
        self.blocks[2].mine()
        sign_object(self.public_key, self.private_key, self.blocks[2])
        self.blocks.append(
            Block.from_operations_list(BlockRev.from_obj(self.blocks[1]), timestamp + 60, self.operations[3]))
        self.blocks[3].mine()
        sign_object(self.public_key, self.private_key, self.blocks[3])
Exemple #17
0
def generate_key(identifier):
    from brave.core.application.model import Application
    
    key = SigningKey.generate(NIST256p, hashfunc=sha256)
    Application.objects(
            id = identifier,
            key__private = None  # Make sure we don't override an existing one.
        ).update(
            set__key__private = hexlify(key.to_string())
        )
Exemple #18
0
    def setUp(self):

        initialise_database('test_database_file')

        self.private_key = SigningKey.generate()
        self.public_key = PublicKey.from_signing_key(self.private_key)

        self.operations = [
            Operation(OperationRev(), 'http://example.com/', [self.public_key]),
            Operation(OperationRev(), 'http://example2.com/', [self.public_key]),
            Operation(OperationRev(), 'http://example3.com/', [self.public_key])
        ]
Exemple #19
0
    def test_no_database(self):
        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Operation.get_ids_list()

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Operation.get(sha256(b'something').digest())

        operation = Operation(OperationRev(), 'http://example.com/', [])
        sk = SigningKey.generate()
        sign_object(PublicKey.from_signing_key(sk), sk, operation)

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            operation.put(BlockRev())

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            operation.remove(BlockRev())
Exemple #20
0
 def __init__(self):
     # Load our keys into a usable form.
     try:
         config['api.private'] = SigningKey.from_string(unhexlify(config['api.private']), curve=NIST256p, hashfunc=sha256)
         config['api.public'] = VerifyingKey.from_string(unhexlify(config['api.public']), curve=NIST256p, hashfunc=sha256)
     except:
         log.critical("Core Service API identity, public, or private key missing.")
         
         private = SigningKey.generate(NIST256p, hashfunc=sha256)
         
         log.critical("Here's a new private key; update the api.private setting to reflect this.\n%s", private.to_string().encode('hex'))
         log.critical("Here's that key's public key; this is what you register with Core.\n%s",  private.get_verifying_key().to_string().encode('hex'))
         log.critical("After registering, save the server's public key to api.public and your service's ID to api.identity.")
         
         exit(-1)
     
     super(StartupMixIn, self).__init__()
Exemple #21
0
    def setUp(self):
        self.private_key = SigningKey.generate()
        self.public_key = PublicKey.from_signing_key(self.private_key)
        self.timestamp = int(time.time())

        self.operations = (
            Operation(OperationRev(), 'http://example1.com/', [self.public_key]),
            Operation(OperationRev(), 'http://example2.com/', [self.public_key])
        )

        for op in self.operations:
            sign_object(self.public_key, self.private_key, op)

        self.block = Block.from_operations_list(BlockRev(), self.timestamp, self.operations)

        self.block.mine()
        sign_object(self.public_key, self.private_key, self.block)
Exemple #22
0
    def test_no_database(self):
        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Identifier.get_uuid_list()

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Identifier.get(uuid4())

        operation = Operation(OperationRev(), 'http://example.com/', [])
        sk = SigningKey.generate()
        sign_object(PublicKey.from_signing_key(sk), sk, operation)
        identifier = Identifier.from_operation(operation)

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            identifier.put()

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            identifier.remove()
Exemple #23
0
    def __init__(self,
                 *,
                 private_key: Optional[Union[str, bytes]] = None,
                 public_key: Optional[bytes] = None):
        assert not (private_key and public_key), 'Pass only one key'
        if public_key:
            self._sk = None
            self._vk = VerifyingKey.from_string(public_key, curve=SECP256k1)
            return

        if private_key:
            if isinstance(private_key, str):
                self._sk = signing_key_from_seed(private_key)
            else:
                self._sk = SigningKey.from_string(private_key, curve=SECP256k1)
        else:
            entropy = PRNG(secrets.randbits(512))
            self._sk = SigningKey.generate(entropy=entropy, curve=SECP256k1)

        self._vk = self._sk.get_verifying_key()
Exemple #24
0
def config():
    # Load and validate the format of our auth config data
    try:
        config['api.identity']
        config['api.private'] = SigningKey.from_string(unhexlify(config['api.private']), curve=NIST256p, hashfunc=sha256)
        config['api.public'] = VerifyingKey.from_string(unhexlify(config['api.public']), curve=NIST256p, hashfunc=sha256)
    except:
        private = SigningKey.generate(NIST256p, hashfunc=sha256)

        error_message = "Core Service API identity, public, or private key missing.<br /><br />\n\n"

        error_message += "Here's a new private key; update the api.private setting to reflect this.<br />\n" + \
                         "%s <br /><br />\n\n" % private.to_string().encode('hex')

        error_message += "Here's that key's public key; this is what you register with Core.<br />\n" + \
                         "%s <br /><br /><br />\n\n" % private.get_verifying_key().to_string().encode('hex')

        error_message += "After registering, save the server's public key to api.public " + \
                         "and your service's ID to api.identity.<br /><br />"

        return error_message

    # config data looks good, allow auth attempt
    return '<a href="'+url_for('authorize')+'">Click here to auth</a>'
Exemple #25
0
    def check_app(app):
        try:
            for var in CoreAPI.required_config_variables_:
                app.config[var]
        except KeyError as e:
            private = SigningKey.generate(NIST256p, hashfunc=sha256)

            error_message =  "\n================================================================================\n"

            error_message += "Core Service API identity, public, or private key missing.\n\n"

            error_message += "Here's a new private key; update the api.private setting to reflect this.\n" + \
                             "%s \n\n" % private.to_string().encode('hex')

            error_message += "Here's that key's public key; this is what you register with Core.\n" + \
                             "%s \n\n" % private.get_verifying_key().to_string().encode('hex')

            error_message += textwrap.fill("After registering, make sure to populate all of the following in config.py: {0}" \
                                 .format(", ".join(CoreAPI.required_config_variables_)))
                             
            error_message += "\n================================================================================\n\n"
        
            print error_message
            raise
def make_key_from_entropy_source(entropy=None):
    return SigningKey.generate(SECP256k1, entropy=entropy) 
Exemple #27
0
Fichier : ct.py Projet : Acen/core
    """Return a string representation of a date according to RFC 1123
    (HTTP/1.1).

    The supplied date must be in UTC.

    """
    weekday = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][dt.weekday()]
    month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
             "Oct", "Nov", "Dec"][dt.month - 1]
    return "%s, %02d %s %04d %02d:%02d:%02d UTC" % (weekday, dt.day, month,
        dt.year, dt.hour, dt.minute, dt.second)




provider = SigningKey.generate(NIST256p, hashfunc=sha256)
service = SigningKey.generate(NIST256p, hashfunc=sha256)


print("Private Keys Generated")
print("Provider:", emit(provider))
print(" Service:", emit(service))


provider_pub = provider.get_verifying_key()
service_pub = service.get_verifying_key()


print("\nPublic Keys Extracted")
print("Provider:", emit(provider_pub))
print(" Service:", emit(service_pub))
Exemple #28
0
    return text_hash


def sha512(text):
    from hashlib import sha512

    text_hash = sha512(text.encode()).hexdigest()
    return text_hash


def get_hash(text, hash_func=sha256):
    return hash_func(text)


if __name__ == "__main__":
    a = SigningKey.generate()
    a_private = a.privkey.secret_multiplier
    a_public = a.verifying_key.pubkey.point

    b = SigningKey.generate()
    b_private = b.privkey.secret_multiplier
    b_public = b.verifying_key.pubkey.point

    a_b_key = str(a_public * b_private)
    b_a_key = str(b_public * a_private)

    with open("output.txt", "w") as f:
        f.write(f"""Секретный ключ #1 : {a_private}
Публичный ключ #1 : {a_public}
Секретный ключ #2 : {b_private}
Публичный ключ #2 : {b_public}
Exemple #29
0
def generate_keypair() -> (SigningKey, str):
    sk = SigningKey.generate(NIST256p)
    vk = sk.get_verifying_key()
    return sk, vk.to_string().hex()
Exemple #30
0
    return text_hash


def sha512(text):
    from hashlib import sha512

    text_hash = sha512(text.encode()).hexdigest()
    return text_hash


def get_hash(text, hash_func=sha256):
    return hash_func(text)


if __name__ == "__main__":
    alice_key = SigningKey.generate()
    alice_key_private = alice_key.privkey.secret_multiplier
    alice_key_public = alice_key.verifying_key.pubkey.point

    bob_key = SigningKey.generate()
    bob_key_private = bob_key.privkey.secret_multiplier
    bob_key_public = bob_key.verifying_key.pubkey.point

    alice_bob_key = str(alice_key_public * bob_key_private)
    bob_alice_key = str(alice_key_private * bob_key_public)

    print(f"""
        Bob secret key = {bob_key_private}
        Bob public key = {bob_key_public}

        Alice secret key = {alice_key_private}
Exemple #31
0
def make_key_from_entropy_source(entropy=None):
    return SigningKey.generate(SECP256k1, entropy=entropy)
Exemple #32
0
 def generate_private_key():
     private_key = SigningKey.generate(SECP256k1)
     return private_key.to_string()
Exemple #33
0
    """Return a string representation of a date according to RFC 1123
    (HTTP/1.1).

    The supplied date must be in UTC.

    """
    weekday = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][dt.weekday()]
    month = [
        "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
        "Nov", "Dec"
    ][dt.month - 1]
    return "%s, %02d %s %04d %02d:%02d:%02d UTC" % (
        weekday, dt.day, month, dt.year, dt.hour, dt.minute, dt.second)


provider = SigningKey.generate(NIST256p, hashfunc=sha256)
service = SigningKey.generate(NIST256p, hashfunc=sha256)

print("Private Keys Generated")
print("Provider:", emit(provider))
print(" Service:", emit(service))

provider_pub = provider.get_verifying_key()
service_pub = service.get_verifying_key()

print("\nPublic Keys Extracted")
print("Provider:", emit(provider_pub))
print(" Service:", emit(service_pub))

print("\nAt this point the application would register its application:")
print(" * Create an application request.")
Exemple #34
0
 def generate_private_key() -> bytes:
     private_key = SigningKey.generate(NIST256p)
     return private_key.to_string()
Exemple #35
0
    def test_init(self):
        sk = SigningKey.generate()
        user = User(sk)

        self.assertEqual(user._private_key, sk)
        self.assertEqual(user._public_key.der, sk.get_verifying_key().to_der())
Exemple #36
0
    def test_sign_operation(self):
        op = Operation(OperationRev(), 'http://example.com/', [PublicKey.from_signing_key(SigningKey.generate())])
        user = User.new_keys()

        with self.assertRaisesRegex(Operation.VerifyError, "object is not signed"):
            op.verify()

        user.sign_object(op)

        self.assertTrue(op.verify())
        self.assertEqual(op.public_key, user._public_key)
Exemple #37
0
 def __init__(self, sk=None):
     if sk is None:
         self.sk = SigningKey.generate(SECP256k1)
     else:
         self.sk = SigningKey.from_string(sk, SECP256k1)
Exemple #38
0
    def setUp(self):
        initialise_database('test_database_file')

        self.private_keys = [SigningKey.generate() for _ in range(3)]
        self.public_keys = [PublicKey.from_signing_key(private_key) for private_key in self.private_keys]
        self.uuids = [uuid4() for _ in range(3)]