Пример #1
0
    def _create_blocks(self, block_count, batch_count,
                       valid_block=True, valid_batch=True):
        block_list = []

        for i in range(block_count):
            batch_list = self._create_batches(
                batch_count, 2, valid_batch=valid_batch)
            batch_ids = [batch.header_signature for batch in batch_list]

            block_header = BlockHeader(signer_pubkey=self.public_key,
                                       batch_ids=batch_ids)

            header_bytes = block_header.SerializeToString()

            if valid_block:
                signature = signing.sign(
                    header_bytes,
                    self.private_key)
            else:
                signature = "bad_signature"

            block = Block(header=header_bytes,
                          batches=batch_list,
                          header_signature=signature)

            block_list.append(block)

        return block_list
Пример #2
0
    def _send_xo_txn(self, name, action, space=""):

        # Serialization is just a delimited utf-8 encoded string
        payload = ",".join([name, action, str(space)]).encode()

        # Construct the address
        address = self._get_address(name)

        header = TransactionHeader(
            signer_pubkey=self._public_key,
            family_name="xo",
            family_version="1.0",
            inputs=[address],
            outputs=[address],
            dependencies=[],
            payload_encoding="csv-utf8",
            payload_sha512=_sha512(payload),
            batcher_pubkey=self._public_key).SerializeToString()

        signature = signing.sign(header, self._private_key)

        transaction = Transaction(header=header,
                                  payload=payload,
                                  header_signature=signature)

        batch_list = self._create_batch_list([transaction])

        result = self._send_request("batches", batch_list.SerializeToString(),
                                    'application/octet-stream')

        return result
Пример #3
0
    def _create_batches(self, batch_count, txn_count,
                        valid_batch=True, valid_txn=True,
                        valid_batcher=True):

        batch_list = []

        for i in range(batch_count):
            txn_list = self._create_transactions(txn_count, valid_txn,
                                                 valid_batcher)
            txn_sig_list = [txn.header_signature for txn in txn_list]

            batch_header = BatchHeader(signer_pubkey=self.public_key)
            batch_header.transaction_ids.extend(txn_sig_list)

            header_bytes = batch_header.SerializeToString()

            if valid_batch:
                signature = signing.sign(
                    header_bytes,
                    self.private_key)
            else:
                signature = "bad_signature"

            batch = Batch(header=header_bytes,
                          transactions=txn_list,
                          header_signature=signature)

            batch_list.append(batch)

        return batch_list
    def test_deserialized_wait_timer(self):
        wait_timer = \
            EnclaveWaitTimer(
                duration=3.14159,
                previous_certificate_id='Bond.  James Bond.',
                local_mean=2.71828)

        serialized = wait_timer.serialize()
        signing_key = self._create_random_key()
        wait_timer.signature = \
            signing.sign(serialized, signing_key)

        copy_wait_timer = \
            EnclaveWaitTimer.wait_timer_from_serialized(
                serialized,
                wait_timer.signature)

        self.assertAlmostEquals(
            wait_timer.request_time,
            copy_wait_timer.request_time)
        self.assertAlmostEquals(
            wait_timer.duration,
            copy_wait_timer.duration)
        self.assertEqual(
            wait_timer.previous_certificate_id,
            copy_wait_timer.previous_certificate_id)
        self.assertAlmostEquals(
            wait_timer.local_mean,
            copy_wait_timer.local_mean)
        self.assertEqual(
            wait_timer.signature,
            copy_wait_timer.signature)

        self.assertEqual(serialized, copy_wait_timer.serialize())
Пример #5
0
    def create_wait_timer(cls,
                          validator_address,
                          previous_certificate_id,
                          local_mean,
                          minimum_wait_time):
        with cls._lock:
            # If we don't have a PoET private key, then the enclave has not
            # been properly initialized (either by calling create_signup_info
            # or unseal_signup_data)
            if cls._poet_private_key is None:
                raise \
                    ValueError(
                        'Enclave must be initialized before attempting to '
                        'create a wait timer')

            # Create some value from the cert ID.  We are just going to use
            # the seal key to sign the cert ID.  We will then use the
            # low-order 64 bits to change that to a number [0, 1]
            tag = \
                base64.b64decode(
                    signing.sign(
                        previous_certificate_id,
                        cls._seal_private_key))

            tagd = float(struct.unpack('Q', tag[-8:])[0]) / (2**64 - 1)

            # Now compute the duration with a minimum wait time guaranteed
            duration = minimum_wait_time - local_mean * math.log(tagd)

            # Create and sign the wait timer
            wait_timer = \
                EnclaveWaitTimer(
                    validator_address=validator_address,
                    duration=duration,
                    previous_certificate_id=previous_certificate_id,
                    local_mean=local_mean)
            wait_timer.signature = \
                signing.sign(
                    wait_timer.serialize(),
                    cls._poet_private_key)

            # Keep track of the active wait timer
            cls._active_wait_timer = wait_timer

            return wait_timer
Пример #6
0
    def _create_batch_list(self, transactions):
        transaction_signatures = [t.header_signature for t in transactions]

        header = BatchHeader(
            signer_pubkey=self._public_key,
            transaction_ids=transaction_signatures).SerializeToString()

        signature = signing.sign(header, self._private_key)

        batch = Batch(header=header,
                      transactions=transactions,
                      header_signature=signature)
        return BatchList(batches=[batch])
Пример #7
0
    def sign_object(self, signingkey):
        """Generates a string signature for the object using the signing
        key.

        Args:
            signingkey (str): hex encoded private key
        """

        self._originator_id = None
        serialized = self.serialize(signable=True)
        self.Signature = signing.sign(serialized, signingkey)

        self._recover_verifying_address()
        self._identifier = hashlib.sha256(self.Signature).hexdigest()
Пример #8
0
def _sign_message_with_transaction(transaction, message_type, key):
    """
    Signs a transaction message or transaction
    :param transaction (dict):
    :param key (str): A signing key
    returns message, txnid (tuple): The first 16 characters
    of a sha256 hexdigest.
    """
    transaction['Nonce'] = time.time()
    pub = signing.encode_pubkey(signing.generate_pubkey(key), "hex")
    transaction["public_key"] = pub
    sig = signing.sign(_dict2cbor(transaction), key)
    transaction['Signature'] = sig

    txnid = hashlib.sha256(transaction['Signature']).hexdigest()[:16]
    message = {
        'Transaction': transaction,
        '__TYPE__': message_type,
        '__NONCE__': time.time(),
    }
    cbor_serialized_message = _dict2cbor(message)
    signature = signing.sign(cbor_serialized_message, key)
    message['__SIGNATURE__'] = signature
    return message, txnid
Пример #9
0
    def _sign_block(self, block):
        """ The block should be complete and the final
        signature from the publishing validator(this validator) needs to
        be added.
        """
        # Temp signature creation to use as identifier
        temp_key = signing.generate_privkey()
        public_key = signing.encode_pubkey(signing.generate_pubkey(temp_key),
                                           "hex")

        block.block_header.signer_pubkey = public_key
        block_header = block.block_header
        header_bytes = block_header.SerializeToString()
        signature = signing.sign(header_bytes, temp_key)
        block.set_signature(signature)
        return block
Пример #10
0
    def _create_transactions(self, count, valid=True, valid_batcher=True):
        txn_list = []

        for i in range(count):
            payload = {'Verb': 'set',
                       'Name': 'name' + str(random.randint(0, 100)),
                       'Value': random.randint(0, 100)}
            intkey_prefix = \
                hashlib.sha512('intkey'.encode('utf-8')).hexdigest()[0:6]

            addr = intkey_prefix + \
                hashlib.sha512(payload["Name"].encode('utf-8')).hexdigest()

            payload_encode = hashlib.sha512(cbor.dumps(payload)).hexdigest()

            header = TransactionHeader(
                signer_pubkey=self.public_key,
                family_name='intkey',
                family_version='1.0',
                inputs=[addr],
                outputs=[addr],
                dependencies=[],
                payload_encoding="application/cbor",
                payload_sha512=payload_encode)

            if valid_batcher:
                header.batcher_pubkey = self.public_key
            else:
                header.batcher_pubkey = "bad_batcher"

            header_bytes = header.SerializeToString()

            if valid:
                signature = signing.sign(
                    header_bytes,
                    self.private_key)
            else:
                signature = "bad_signature"

            transaction = Transaction(
                header=header_bytes,
                payload=cbor.dumps(payload),
                header_signature=signature)

            txn_list.append(transaction)

        return txn_list
Пример #11
0
    def test_deserialized_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_digest='Indigestion. Pepto Bismol.')

        serialized = wait_certificate.serialize()
        signing_key = self._create_random_key()
        wait_certificate.signature = \
            signing.sign(serialized, signing_key)

        copy_wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_from_serialized(
                serialized,
                wait_certificate.signature)

        self.assertAlmostEquals(wait_certificate.request_time,
                                copy_wait_certificate.request_time)
        self.assertAlmostEquals(wait_certificate.duration,
                                copy_wait_certificate.duration)
        self.assertEqual(wait_certificate.previous_certificate_id,
                         copy_wait_certificate.previous_certificate_id)
        self.assertAlmostEquals(wait_certificate.local_mean,
                                copy_wait_certificate.local_mean)
        self.assertEqual(wait_certificate.validator_address,
                         copy_wait_certificate.validator_address)
        self.assertEqual(wait_certificate.nonce, copy_wait_certificate.nonce)
        self.assertEqual(wait_certificate.block_digest,
                         copy_wait_certificate.block_digest)
        self.assertEqual(wait_certificate.signature,
                         copy_wait_certificate.signature)

        self.assertEqual(serialized, copy_wait_certificate.serialize())
    def test_is_valid_pub_key(self):
        pubkey = signing.generate_pubkey("5KQ4iQQGgbQX9MmfiPUwwHBL1R"
                                         "GPa86NwFbqrWoodjuzruqFVDd")
        pub = signing.encode_pubkey(pubkey, "hex")
        minfo = {
            'Nonce': 100,
            'PublicKey': pub,
            'TransactionType': '/Transaction',
            'Dependencies': []
        }
        sig = signing.sign(
            signed_object.dict2cbor(minfo),
            "5KQ4iQQGgbQX9MmfiPUwwHBL1RGPa86NwFbqrWoodjuzruqFVDd")
        # Create valid transaction
        minfo["Signature"] = sig
        temp = Transaction(minfo)
        self.assertTrue(temp.is_valid("unused"))

        # Change transaction after it was signed
        minfo["Nonce"] = time.time()
        temp = Transaction(minfo)
        self.assertFalse(temp.is_valid("unused"))
Пример #13
0
    def create_signup_info(cls, originator_public_key_hash,
                           most_recent_wait_certificate_id):
        with cls._lock:
            # First we need to create a public/private key pair for the PoET
            # enclave to use.
            cls._poet_private_key = signing.generate_privkey()
            cls._poet_public_key = \
                signing.generate_pubkey(cls._poet_private_key)
            cls._active_wait_timer = None

            # We are going to fake out the sealing the signup data.
            signup_data = {
                'poet_public_key':
                signing.encode_pubkey(cls._poet_public_key, 'hex'),
                'poet_private_key':
                signing.encode_privkey(cls._poet_private_key, 'hex')
            }
            sealed_signup_data = \
                base64.b64encode(dict2json(signup_data))

            # Create a fake report
            report_data = '{0}{1}'.format(
                originator_public_key_hash.upper(),
                signing.encode_pubkey(cls._poet_public_key, 'hex').upper())
            quote = {
                'report_body':
                hashlib.sha256(dict2json(report_data)).hexdigest()
            }

            # Fake our "proof" data.
            verification_report = {
                'id':
                base64.b64encode(
                    hashlib.sha256(
                        datetime.datetime.now().isoformat()).hexdigest()),
                'isvEnclaveQuoteStatus':
                'OK',
                'isvEnclaveQuoteBody':
                base64.b64encode(dict2json(quote)),
                'pseManifestStatus':
                'OK',
                'pseManifestHash':
                base64.b64encode(
                    hashlib.sha256(b'Do you believe in '
                                   'manifest destiny?').hexdigest()),
                'nonce':
                most_recent_wait_certificate_id
            }

            proof_data_dict = {
                'verification_report':
                dict2json(verification_report),
                'signature':
                signing.sign(dict2json(verification_report),
                             cls._report_private_key)
            }
            proof_data = dict2json(proof_data_dict)

            return \
                EnclaveSignupInfo(
                    poet_public_key=signup_data['poet_public_key'],
                    proof_data=proof_data,
                    anti_sybil_id=originator_public_key_hash,
                    sealed_signup_data=sealed_signup_data)
Пример #14
0
    def create_wait_certificate(cls, block_digest):
        with cls._lock:
            # If we don't have a PoET private key, then the enclave has not
            # been properly initialized (either by calling create_signup_info
            # or unseal_signup_data)
            if cls._poet_private_key is None:
                raise \
                    WaitCertificateError(
                        'Enclave must be initialized before attempting to '
                        'create a wait certificate')

            # Several criteria need to be met before we can create a wait
            # certificate:
            # 1. We have an active timer
            # 2. The active timer has expired
            # 3. The active timer has not timed out
            #
            # Note - we make a concession for the genesis block (i.e., a wait
            # timer for which the previous certificate ID is the Null
            # identifier) in that we don't require the timer to have expired
            # and we don't worry about the timer having timed out.
            if cls._active_wait_timer is None:
                raise \
                    WaitCertificateError(
                        'Enclave active wait timer has not been initialized')

            is_not_genesis_block = \
                (cls._active_wait_timer.previous_certificate_id !=
                 NullIdentifier)

            now = time.time()
            expire_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration

            if is_not_genesis_block and now < expire_time:
                raise \
                    WaitCertificateError(
                        'Cannot create wait certificate because timer has '
                        'not expired')

            time_out_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration + \
                TIMER_TIMEOUT_PERIOD

            if is_not_genesis_block and time_out_time < now:
                raise \
                    WaitCertificateError(
                        'Cannot create wait certificate because timer '
                        'has timed out')

            # Create a random nonce for the certificate.  For our "random"
            # nonce we will take the timer signature, concat that with the
            # current time, JSON-ize it and create a SHA-256 hash over it.
            # Probably not considered random by security professional
            # standards, but it is good enough for the simulator.
            random_string = \
                dict2json({
                    'wait_timer_signature': cls._active_wait_timer.signature,
                    'now': datetime.datetime.utcnow().isoformat()
                })
            nonce = hashlib.sha256(random_string).hexdigest()

            # First create a new enclave wait certificate using the data
            # provided and then sign the certificate with the PoET private key
            wait_certificate = \
                EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                    wait_timer=cls._active_wait_timer,
                    nonce=nonce,
                    block_digest=block_digest)
            wait_certificate.signature = \
                signing.sign(
                    wait_certificate.serialize(),
                    cls._poet_private_key)

            # Now that we have created the certificate, we no longer have an
            # active timer
            cls._active_wait_timer = None

            return wait_certificate