def test_create_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.') self.assertAlmostEquals(wait_timer.request_time, wait_certificate.request_time) self.assertAlmostEquals(wait_timer.duration, wait_certificate.duration) self.assertEqual(wait_timer.previous_certificate_id, wait_certificate.previous_certificate_id) self.assertAlmostEquals(wait_timer.local_mean, wait_certificate.local_mean) self.assertEqual(wait_timer.validator_address, wait_certificate.validator_address) self.assertEqual(wait_certificate.nonce, 'Eeny, meeny, miny, moe.') self.assertEqual(wait_certificate.block_digest, 'Indigestion. Pepto Bismol.') self.assertIsNone(wait_certificate.signature) # You probably wonder why I bother assigning # wait_certificate.previous_certificate_id to a local variable - # this is to simply get around PEP8. # If I don't, it complains about the line being too long. # If I do a line continuation, it complains about a space around the =. previous_certificate_id = wait_certificate.previous_certificate_id other_wait_certificate = \ EnclaveWaitCertificate( duration=wait_certificate.duration, previous_certificate_id=previous_certificate_id, local_mean=wait_certificate.local_mean, request_time=wait_certificate.request_time, validator_address='1600 Pennsylvania Avenue NW', nonce='Eeny, meeny, miny, moe.', block_digest=wait_certificate.block_digest) self.assertAlmostEquals(wait_certificate.duration, other_wait_certificate.duration) self.assertEqual(wait_certificate.previous_certificate_id, other_wait_certificate.previous_certificate_id) self.assertAlmostEquals(wait_certificate.local_mean, other_wait_certificate.local_mean) self.assertAlmostEquals(wait_certificate.request_time, other_wait_certificate.request_time) self.assertEqual(wait_certificate.validator_address, other_wait_certificate.validator_address) self.assertEqual(wait_certificate.nonce, other_wait_certificate.nonce) self.assertEqual(wait_certificate.block_digest, other_wait_certificate.block_digest) self.assertIsNone(other_wait_certificate.signature)
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.assertAlmostEqual( wait_certificate.request_time, copy_wait_certificate.request_time) self.assertAlmostEqual( wait_certificate.duration, copy_wait_certificate.duration) self.assertEqual( wait_certificate.previous_certificate_id, copy_wait_certificate.previous_certificate_id) self.assertAlmostEqual( 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_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_serialize_wait_certificate(self): wait_timer = \ EnclaveWaitTimer( 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.') self.assertIsNotNone(wait_certificate.serialize())
def test_serialize_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.') self.assertIsNotNone(wait_certificate.serialize())
def deserialize_wait_certificate(cls, serialized_certificate, signature): return \ EnclaveWaitCertificate.wait_certificate_from_serialized( serialized_certificate=serialized_certificate, signature=signature)
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
def test_create_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.') self.assertAlmostEqual( wait_timer.request_time, wait_certificate.request_time) self.assertAlmostEqual( wait_timer.duration, wait_certificate.duration) self.assertEqual( wait_timer.previous_certificate_id, wait_certificate.previous_certificate_id) self.assertAlmostEqual( wait_timer.local_mean, wait_certificate.local_mean) self.assertEqual( wait_timer.validator_address, wait_certificate.validator_address) self.assertEqual(wait_certificate.nonce, 'Eeny, meeny, miny, moe.') self.assertEqual( wait_certificate.block_digest, 'Indigestion. Pepto Bismol.') self.assertIsNone(wait_certificate.signature) # You probably wonder why I bother assigning # wait_certificate.previous_certificate_id to a local variable - # this is to simply get around PEP8. # If I don't, it complains about the line being too long. # If I do a line continuation, it complains about a space around the =. previous_certificate_id = wait_certificate.previous_certificate_id other_wait_certificate = \ EnclaveWaitCertificate( duration=wait_certificate.duration, previous_certificate_id=previous_certificate_id, local_mean=wait_certificate.local_mean, request_time=wait_certificate.request_time, validator_address='1600 Pennsylvania Avenue NW', nonce='Eeny, meeny, miny, moe.', block_digest=wait_certificate.block_digest) self.assertAlmostEqual( wait_certificate.duration, other_wait_certificate.duration) self.assertEqual( wait_certificate.previous_certificate_id, other_wait_certificate.previous_certificate_id) self.assertAlmostEqual( wait_certificate.local_mean, other_wait_certificate.local_mean) self.assertAlmostEqual( wait_certificate.request_time, other_wait_certificate.request_time) self.assertEqual( wait_certificate.validator_address, other_wait_certificate.validator_address) self.assertEqual(wait_certificate.nonce, other_wait_certificate.nonce) self.assertEqual( wait_certificate.block_digest, other_wait_certificate.block_digest) self.assertIsNone(other_wait_certificate.signature)
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 we 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 if cls._active_wait_timer is None: raise \ WaitCertificateError( 'Enclave active wait timer has not been initialized') # HACK ALERT!! HACK ALERT!! HACK ALERT!! HACK ALERT!! # # Today, without the genesis utility we cannot make these checks. # Once we have the genesis utility, this code needs to change to # Depend upon the timer not being expired or timed out. The # Original specification requires this check. # # HACK ALERT!! HACK ALERT!! HACK ALERT!! HACK ALERT!! # # if not cls._active_wait_timer.has_expired(): # raise \ # WaitCertificateError( # 'Cannot create wait certificate because timer has ' # 'not expired') # if wait_timer.has_timed_out(): # 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 = pybitcointools.sha256(random_string) # 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 = \ pybitcointools.ecdsa_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
def create_wait_certificate(cls, wait_timer, 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 \ ValueError( '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 caller's wait timer is the active wait timer. We are not # going to rely the objects, being the same, but will compute # a signature over the object and verify that the signatures # are the same. # 3. The active timer has expired # 4. 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 \ ValueError( 'There is not a current enclave active wait timer') if wait_timer is None or \ cls._active_wait_timer.signature != \ signing.sign( wait_timer.serialize(), cls._poet_private_key): raise \ ValueError( 'Validator is not using the current wait timer') 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 \ ValueError( '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 \ ValueError( '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.encode()).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