def test_create_set_response(benchmark): battleshipMessage = MessageFactory( "battleship", "1.0", MessageFactory.sha512("battleship".encode("utf-8"))[0:6], None) context = create_context("secp256k1") publicKey = battleshipMessage.get_public_key() address = battleshipMessage.namespaces[0] + MessageFactory.sha256( publicKey.encode("utf-8")) benchmark(MessageFactory.create_set_response, battleshipMessage, [address]) return
def test_create_set_request(benchmark): battleshipMessage = MessageFactory( "battleship", "1.0", MessageFactory.sha512("battleship".encode("utf-8"))[0:6], None) context = create_context("secp256k1") publicKey = battleshipMessage.get_public_key() address = battleshipMessage.namespaces[0] + MessageFactory.sha256( publicKey.encode("utf-8")) data = ValidatorMap().SerializeToString() benchmark(MessageFactory.create_set_request, battleshipMessage, {address: data}) return
class SettingsMessageFactory: def __init__(self, signer=None): self._factory = MessageFactory( family_name="bgx_settings", family_version="1.0", namespace="000000", signer=signer) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1) key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts))) def _short_hash(in_str): return self._factory.sha256(in_str.encode())[:16] return self._factory.namespace + \ ''.join(_short_hash(x) for x in key_parts) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) def _create_tp_process_request(self, setting, payload): inputs = [ self._key_to_address('sawtooth.settings.vote.proposals'), self._key_to_address('sawtooth.settings.vote.authorized_keys'), self._key_to_address('sawtooth.settings.vote.approval_threshold'), self._key_to_address(setting) ] outputs = [ self._key_to_address('sawtooth.settings.vote.proposals'), self._key_to_address(setting) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_proposal_transaction(self, setting, value, nonce): proposal = SettingProposal(setting=setting, value=value, nonce=nonce) payload = SettingsPayload(action=SettingsPayload.PROPOSE, data=proposal.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_vote_proposal(self, proposal_id, setting, vote): vote = SettingVote(proposal_id=proposal_id, vote=vote) payload = SettingsPayload(action=SettingsPayload.VOTE, data=vote.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_get_request(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_get_request(addresses) def create_get_response(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_get_response({address: data}) def create_set_request(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_set_request({address: data}) def create_set_response(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_set_response(addresses) def create_add_event_request(self, key): return self._factory.create_add_event_request( "settings/update", [("updated", key)]) def create_add_event_response(self): return self._factory.create_add_event_response()
INTKEY_NAMESPACE = MessageFactory.sha512('intkey'.encode())[:6] XO_NAMESPACE = MessageFactory.sha512('xo'.encode())[:6] # pylint: disable=invalid-name class Families(enum.Enum): INTKEY = 1 XO = 2 FAMILY_CONFIG = { Families.INTKEY: { 'family_name': 'intkey', 'family_version': '1.0', 'namespace': MessageFactory.sha256('intkey'.encode())[:6] }, Families.XO: { 'family_name': 'xo', 'family_version': '1.0', 'namespace': MessageFactory.sha256('xo'.encode())[:6] }, } def make_intkey_payload(unique_value): return {'Verb': 'set', 'Name': unique_value, 'Value': 1000} def make_intkey_address(unique_value): return INTKEY_NAMESPACE + MessageFactory.sha512(
INTKEY_NAMESPACE = MessageFactory.sha512('intkey'.encode())[:6] XO_NAMESPACE = MessageFactory.sha512('xo'.encode())[:6] # pylint: disable=invalid-name class Families(enum.Enum): INTKEY = 1 XO = 2 FAMILY_CONFIG = { Families.INTKEY: { 'family_name': 'intkey', 'family_version': '1.0', 'namespace': MessageFactory.sha256('intkey'.encode())[:6] }, Families.XO: { 'family_name': 'xo', 'family_version': '1.0', 'namespace': MessageFactory.sha256('xo'.encode())[:6] }, } def make_intkey_payload(unique_value): return {'Verb': 'set', 'Name': unique_value, 'Value': 1000} def make_intkey_address(unique_value): return INTKEY_NAMESPACE + MessageFactory.sha512(
class UnitMessageFactory(object): def __init__(self, signer=None): self._factory = MessageFactory( family_name="hashblock_units", family_version="0.1.0", namespace=[MessageFactory.sha512('units'.encode("utf-8"))[0:6]], signer=signer) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1) key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts))) def _short_hash(in_str): return self._factory.sha256(in_str.encode())[:16] return self._factory.namespace + \ ''.join(_short_hash(x) for x in key_parts) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) def _create_tp_process_request(self, code, payload): inputs = [ self._key_to_address('hashblock.units.vote.proposals'), self._key_to_address('hashblock.units.vote.authorized_keys'), self._key_to_address('hashblock.units.vote.approval_threshold'), self._key_to_address(code) ] outputs = [ self._key_to_address('hashblock.units.vote.proposals'), self._key_to_address(code) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_proposal_transaction(self, code, value, nonce): proposal = UnitProposal(code=code, value=value, nonce=nonce) payload = UnitPayload(action=UnitPayload.PROPOSE, data=proposal.SerializeToString()) return self._create_tp_process_request(code, payload) def create_vote_proposal(self, proposal_id, code, vote): vote = UnitVote(proposal_id=proposal_id, vote=vote) payload = UnitPayload(action=UnitPayload.VOTE, data=vote.SerializeToString()) return self._create_tp_process_request(code, payload) def create_get_request(self, code): addresses = [self._key_to_address(code)] return self._factory.create_get_request(addresses) def create_get_response(self, code, value=None): address = self._key_to_address(code) if value is not None: entry = Unit.Entry(key=code, value=value) data = Unit(entries=[entry]).SerializeToString() else: data = None return self._factory.create_get_response({address: data}) def create_set_request(self, code, value=None): address = self._key_to_address(code) if value is not None: entry = Unit.Entry(key=code, value=value) data = Unit(entries=[entry]).SerializeToString() else: data = None return self._factory.create_set_request({address: data}) def create_set_response(self, code): addresses = [self._key_to_address(code)] return self._factory.create_set_response(addresses) def create_add_event_request(self, key): return self._factory.create_add_event_request("units/update", [("updated", key)]) def create_add_event_response(self): return self._factory.create_add_event_response()
class ConfigMessageFactory(object): def __init__(self, private=None, public=None): self._factory = MessageFactory(encoding="application/protobuf", family_name="sawtooth_config", family_version="1.0", namespace="000000", private=private, public=public) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): return self._factory.namespace + \ self._factory.sha256(key.encode("utf-8")) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) def _create_tp_process_request(self, setting, payload): inputs = [ self._key_to_address('sawtooth.config.authorization_type'), self._key_to_address('sawtooth.config.vote.proposals'), self._key_to_address('sawtooth.config.vote.authorized_keys'), self._key_to_address('sawtooth.config.vote.approval_threshold'), self._key_to_address(setting) ] outputs = [ self._key_to_address('sawtooth.config.vote.proposals'), self._key_to_address(setting) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_proposal_transaction(self, setting, value, nonce): proposal = ConfigProposal(setting=setting, value=value, nonce=nonce) payload = ConfigPayload(action=ConfigPayload.PROPOSE, data=proposal.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_vote_proposal(self, proposal_id, setting, vote): vote = ConfigVote(proposal_id=proposal_id, vote=vote) payload = ConfigPayload(action=ConfigPayload.VOTE, data=vote.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_get_request(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_get_request(addresses) def create_get_response(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_get_response({address: data}) def create_set_request(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_set_request({address: data}) def create_set_response(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_set_response(addresses)
class ValidatorRegistryMessageFactory(object): # The basename and enclave measurement values we will put into the enclave # quote in the attestation verification report. __VALID_BASENAME__ = \ bytes.fromhex( 'b785c58b77152cbe7fd55ee3851c4990' '00000000000000000000000000000000') __VALID_ENCLAVE_MEASUREMENT__ = \ bytes.fromhex( 'c99f21955e38dbb03d2ca838d3af6e43' 'ef438926ed02db4cc729380c8c7a174e') __REPORT_PRIVATE_KEY_PEM__ = \ '-----BEGIN PRIVATE KEY-----\n' \ 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsy/NmLwZP6Uj0\n' \ 'p5mIiefgK8VOK7KJ34g3h0/X6aFOd/Ff4j+e23wtQpkxsjVHWLM5SjElGhfpVDhL\n' \ '1WAMsQI9bpCWR4sjV6p7gOJhv34nkA2Grj5eSHCAJRQXCl+pJ9dYIeKaNoaxkdtq\n' \ '+Xme//ohtkkv/ZjMTfsjMl0RLXokJ+YhSuTpNSovRaCtZfLB5MihVJuV3Qzb2ROh\n' \ 'KQxcuyPy9tBtOIrBWJaFiXOLRxAijs+ICyzrqUBbRfoAztkljIBx9KNItHiC4zPv\n' \ 'o6DxpGSO2yMQSSrs13PkfyGWVZSgenEYOouEz07X+H5B29PPuW5mCl4nkoH3a9gv\n' \ 'rI6VLEx9AgMBAAECggEAImfFge4RCq4/eX85gcc7pRXyBjuLJAqe+7d0fWAmXxJg\n' \ 'vB+3XTEEi5p8GDoMg7U0kk6kdGe6pRnAz9CffEduU78FCPcbzCCzcD3cVWwkeUok\n' \ 'd1GQV4OC6vD3DBNjsrGdHg45KU18CjUphCZCQhdjvXynG+gZmWxZecuYXkg4zqPT\n' \ 'LwOkcdWBPhJ9CbjtiYOtKDZbhcbdfnb2fkxmvnAoz1OWNfVFXh+x7651FrmL2Pga\n' \ 'xGz5XoxFYYT6DWW1fL6GNuVrd97wkcYUcjazMgunuUMC+6XFxqK+BoqnxeaxnsSt\n' \ 'G2r0sdVaCyK1sU41ftbEQsc5oYeQ3v5frGZL+BgrYQKBgQDgZnjqnVI/B+9iarx1\n' \ 'MjAFyhurcKvFvlBtGKUg9Q62V6wI4VZvPnzA2zEaR1J0cZPB1lCcMsFACpuQF2Mr\n' \ '3VDyJbnpSG9q05POBtfLjGQdXKtGb8cfXY2SwjzLH/tvxHm3SP+RxvLICQcLX2/y\n' \ 'GTJ+mY9C6Hs6jIVLOnMWkRWamQKBgQDFITE3Qs3Y0ZwkKfGQMKuqJLRw29Tyzw0n\n' \ 'XKaVmO/pEzYcXZMPBrFhGvdmNcJLo2fcsmGZnmit8RP4ChwHUlD11dH1Ffqw9FWc\n' \ '387i0chlE5FhQPirSM8sWFVmjt2sxC4qFWJoAD/COQtKHgEaVKVc4sH/yRostL1C\n' \ 'r+7aWuqzhQKBgQDcuC5LJr8VPGrbtPz1kY3mw+r/cG2krRNSm6Egj6oO9KFEgtCP\n' \ 'zzjKQU9E985EtsqNKI5VdR7cLRLiYf6r0J6j7zO0IAlnXADP768miUqYDuRw/dUw\n' \ 'JsbwCZneefDI+Mp325d1/egjla2WJCNqUBp4p/Zf62f6KOmbGzzEf6RuUQKBgG2y\n' \ 'E8YRiaTOt5m0MXUwcEZk2Hg5DF31c/dkalqy2UYU57aPJ8djzQ8hR2x8G9ulWaWJ\n' \ 'KiCm8s9gaOFNFt3II785NfWxPmh7/qwmKuUzIdWFNxAsbHQ8NvURTqyccaSzIpFO\n' \ 'hw0inlhBEBQ1cB2r3r06fgQNb2BTT0Itzrd5gkNVAoGBAJcMgeKdBMukT8dKxb4R\n' \ '1PgQtFlR3COu2+B00pDyUpROFhHYLw/KlUv5TKrH1k3+E0KM+winVUIcZHlmFyuy\n' \ 'Ilquaova1YSFXP5cpD+PKtxRV76Qlqt6o+aPywm81licdOAXotT4JyJhrgz9ISnn\n' \ 'J13KkHoAZ9qd0rX7s37czb3O\n' \ '-----END PRIVATE KEY-----' def __init__(self, private=None, public=None): self._factory = MessageFactory( family_name="sawtooth_validator_registry", family_version="1.0", namespace="6a4372", private=private, public=public ) self.public_key_hash = hashlib.sha256(public.encode()).hexdigest() self._report_private_key = \ serialization.load_pem_private_key( self.__REPORT_PRIVATE_KEY_PEM__.encode(), password=None, backend=backends.default_backend()) # First we need to create a public/private key pair for the PoET # enclave to use. self._poet_private_key = \ "1f70fa2518077ad18483f48e77882d11983b537fa5f7cf158684d2c670fe4f1f" self.poet_public_key = \ signing.generate_public_key(self._poet_private_key) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): return self._factory.namespace + \ self._factory.sha256(key.encode("utf-8")) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) # Utility function for creating proof data as we need to be # able to update signatures when verification report changes # Returns a serialized proof data def create_proof_data(self, verification_report, evidence_payload): verification_report_json = json.dumps(verification_report) signature = \ self._report_private_key.sign( verification_report_json.encode(), padding.PKCS1v15(), hashes.SHA256()) proof_data_dict = OrderedDict([ ('evidence_payload', evidence_payload), ('verification_report', verification_report_json), ('signature', base64.b64encode(signature).decode())] ) return json.dumps(proof_data_dict) # Currently this is done in the enclave def create_signup_info(self, originator_public_key_hash, nonce, pse_manifest_status='OK'): # currently not used # _active_wait_timer = None # We are going to fake out the sealing the signup data. signup_data = { 'poet_public_key': self.poet_public_key, 'poet_private_key': self._poet_private_key } # Build up a fake SGX quote containing: # 1. The basename # 2. The report body that contains: # a. The enclave measurement # b. The report data SHA256(SHA256(OPK)|PPK) sgx_basename = \ sgx_structs.SgxBasename(name=self.__VALID_BASENAME__) sgx_measurement = \ sgx_structs.SgxMeasurement( m=self.__VALID_ENCLAVE_MEASUREMENT__) hash_input = \ '{0}{1}'.format( originator_public_key_hash.upper(), self.poet_public_key.upper()).encode() report_data = hashlib.sha256(hash_input).digest() sgx_report_data = sgx_structs.SgxReportData(d=report_data) sgx_report_body = \ sgx_structs.SgxReportBody( mr_enclave=sgx_measurement, report_data=sgx_report_data) sgx_quote = \ sgx_structs.SgxQuote( basename=sgx_basename, report_body=sgx_report_body) # Create a fake PSE manifest. A base64 encoding of the # originator public key hash should suffice. pse_manifest = \ base64.b64encode(originator_public_key_hash.encode()) timestamp = '2017-02-16T15:21:24.437048' # Fake our "proof" data. verification_report = OrderedDict([ ('epidPseudonym', originator_public_key_hash), ('id', base64.b64encode( hashlib.sha256( timestamp.encode()).hexdigest().encode()).decode()), ('isvEnclaveQuoteStatus', 'OK'), ('isvEnclaveQuoteBody', base64.b64encode(sgx_quote.serialize_to_bytes()).decode()), ('pseManifestStatus', pse_manifest_status), ('pseManifestHash', hashlib.sha256(base64.b64decode(pse_manifest)).hexdigest()), ('nonce', nonce), ('timestamp', timestamp) ]) proof_data = \ self.create_proof_data( verification_report=verification_report, evidence_payload={ 'pse_manifest': pse_manifest.decode() }) return \ SignUpInfo( poet_public_key=signup_data['poet_public_key'], proof_data=proof_data, anti_sybil_id=originator_public_key_hash, nonce=nonce) def create_tp_process_request(self, validator_id, payload): inputs = [ self._key_to_address('validator_list') ] outputs = [ self._key_to_address('validator_list'), self._key_to_address(validator_id) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, [], False) def create_get_request_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_get_request(addresses) def create_set_request_validator_info( self, validator_name, transaction_id, signup_info=None): if signup_info is None: signup_info = self.create_signup_info(self.public_key_hash, "000") data = ValidatorInfo( name=validator_name, id=self.public_key, signup_info=signup_info, transaction_id=transaction_id ).SerializeToString() address = self._key_to_address(self.public_key) return self._factory.create_set_request({address: data}) def create_set_response_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_set_response(addresses) def create_del_request_validator_info(self): data = b'' address = self._key_to_address(self.public_key) return self._factory.create_set_request({address: data}) def create_del_response_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_set_response(addresses) def create_get_request_validator_map(self): address = self._key_to_address("validator_map") addresses = [address] return self._factory.create_get_request(addresses) def create_get_empty_response_validator_map(self): address = self._key_to_address("validator_map") data = ValidatorMap().SerializeToString() return self._factory.create_get_response({address: data}) def create_get_response_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.public_key_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_get_response({address: data}) def create_set_request_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.public_key_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_set_request({address: data}) def create_set_response_validator_map(self): addresses = [self._key_to_address("validator_map")] return self._factory.create_set_response(addresses) def create_get_request_report_key_pem(self): return \ self._factory.create_get_request( ['000000a87cb5eafdcca6a87ccc804f5546a' 'b8e97a7d614626e4500e3b0c44298fc1c14']) def create_get_response_report_key_pem(self, pem=None): setting = Setting() if pem is not None: entry = Setting.Entry(key='sawtooth.poet.report_public_key_pem', value=pem) setting.entries.extend([entry]) data = setting.SerializeToString() return self._factory.create_get_response( {'000000a87cb5eafdcca6a87ccc804f5546a' 'b8e97a7d614626e4500e3b0c44298fc1c14': data}) def create_get_response_simulator_report_key_pem(self): pem = '''-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMvzZi8GT+lI9KeZiInn 4CvFTiuyid+IN4dP1+mhTnfxX+I/ntt8LUKZMbI1R1izOUoxJRoX6VQ4S9VgDLEC PW6QlkeLI1eqe4DiYb9+J5ANhq4+XkhwgCUUFwpfqSfXWCHimjaGsZHbavl5nv/6 IbZJL/2YzE37IzJdES16JCfmIUrk6TUqL0WgrWXyweTIoVSbld0M29kToSkMXLsj 8vbQbTiKwViWhYlzi0cQIo7PiAss66lAW0X6AM7ZJYyAcfSjSLR4guMz76Og8aRk jtsjEEkq7Ndz5H8hllWUoHpxGDqLhM9O1/h+QdvTz7luZgpeJ5KB92vYL6yOlSxM fQIDAQAB -----END PUBLIC KEY-----''' return self.create_get_response_report_key_pem(pem=pem) def create_get_request_enclave_measurements(self): return \ self._factory.create_get_request( ['000000a87cb5eafdcca6a87ccc804f5546a' 'b8e39ccaeec28506829e3b0c44298fc1c14']) def create_get_response_enclave_measurements(self, measurements=None): setting = Setting() if measurements is not None: entry = Setting.Entry(key='sawtooth.poet.' 'valid_enclave_measurements', value=measurements) setting.entries.extend([entry]) data = setting.SerializeToString() return self._factory.create_get_response( {'000000a87cb5eafdcca6a87ccc804f5546a' 'b8e39ccaeec28506829e3b0c44298fc1c14': data}) def create_get_response_simulator_enclave_measurements(self): return \ self.create_get_response_enclave_measurements( measurements='c99f21955e38dbb03d2ca838d3af6e43' 'ef438926ed02db4cc729380c8c7a174e') def create_get_request_enclave_basenames(self): return \ self._factory.create_get_request( ['000000a87cb5eafdcca6a87ccc804f5546a' 'b8ebec3b47bc008b27de3b0c44298fc1c14']) def create_get_response_enclave_basenames(self, basenames=None): setting = Setting() if basenames is not None: entry = Setting.Entry(key='sawtooth.poet.' 'valid_enclave_basenames', value=basenames) setting.entries.extend([entry]) data = setting.SerializeToString() return self._factory.create_get_response( {'000000a87cb5eafdcca6a87ccc804f5546a' 'b8ebec3b47bc008b27de3b0c44298fc1c14': data}) def create_get_response_simulator_enclave_basenames(self): return \ self.create_get_response_enclave_basenames( basenames='b785c58b77152cbe7fd55ee3851c4990' '00000000000000000000000000000000')
class ValidatorRegistryMessageFactory(object): # The basename and enclave measurement values we will put into the enclave # quote in the attestation verification report. __VALID_BASENAME__ = \ bytes.fromhex( 'b785c58b77152cbe7fd55ee3851c4990' '00000000000000000000000000000000') __VALID_ENCLAVE_MEASUREMENT__ = \ bytes.fromhex( 'c99f21955e38dbb03d2ca838d3af6e43' 'ef438926ed02db4cc729380c8c7a174e') __REPORT_PRIVATE_KEY_PEM__ = \ '-----BEGIN PRIVATE KEY-----\n' \ 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsy/NmLwZP6Uj0\n' \ 'p5mIiefgK8VOK7KJ34g3h0/X6aFOd/Ff4j+e23wtQpkxsjVHWLM5SjElGhfpVDhL\n' \ '1WAMsQI9bpCWR4sjV6p7gOJhv34nkA2Grj5eSHCAJRQXCl+pJ9dYIeKaNoaxkdtq\n' \ '+Xme//ohtkkv/ZjMTfsjMl0RLXokJ+YhSuTpNSovRaCtZfLB5MihVJuV3Qzb2ROh\n' \ 'KQxcuyPy9tBtOIrBWJaFiXOLRxAijs+ICyzrqUBbRfoAztkljIBx9KNItHiC4zPv\n' \ 'o6DxpGSO2yMQSSrs13PkfyGWVZSgenEYOouEz07X+H5B29PPuW5mCl4nkoH3a9gv\n' \ 'rI6VLEx9AgMBAAECggEAImfFge4RCq4/eX85gcc7pRXyBjuLJAqe+7d0fWAmXxJg\n' \ 'vB+3XTEEi5p8GDoMg7U0kk6kdGe6pRnAz9CffEduU78FCPcbzCCzcD3cVWwkeUok\n' \ 'd1GQV4OC6vD3DBNjsrGdHg45KU18CjUphCZCQhdjvXynG+gZmWxZecuYXkg4zqPT\n' \ 'LwOkcdWBPhJ9CbjtiYOtKDZbhcbdfnb2fkxmvnAoz1OWNfVFXh+x7651FrmL2Pga\n' \ 'xGz5XoxFYYT6DWW1fL6GNuVrd97wkcYUcjazMgunuUMC+6XFxqK+BoqnxeaxnsSt\n' \ 'G2r0sdVaCyK1sU41ftbEQsc5oYeQ3v5frGZL+BgrYQKBgQDgZnjqnVI/B+9iarx1\n' \ 'MjAFyhurcKvFvlBtGKUg9Q62V6wI4VZvPnzA2zEaR1J0cZPB1lCcMsFACpuQF2Mr\n' \ '3VDyJbnpSG9q05POBtfLjGQdXKtGb8cfXY2SwjzLH/tvxHm3SP+RxvLICQcLX2/y\n' \ 'GTJ+mY9C6Hs6jIVLOnMWkRWamQKBgQDFITE3Qs3Y0ZwkKfGQMKuqJLRw29Tyzw0n\n' \ 'XKaVmO/pEzYcXZMPBrFhGvdmNcJLo2fcsmGZnmit8RP4ChwHUlD11dH1Ffqw9FWc\n' \ '387i0chlE5FhQPirSM8sWFVmjt2sxC4qFWJoAD/COQtKHgEaVKVc4sH/yRostL1C\n' \ 'r+7aWuqzhQKBgQDcuC5LJr8VPGrbtPz1kY3mw+r/cG2krRNSm6Egj6oO9KFEgtCP\n' \ 'zzjKQU9E985EtsqNKI5VdR7cLRLiYf6r0J6j7zO0IAlnXADP768miUqYDuRw/dUw\n' \ 'JsbwCZneefDI+Mp325d1/egjla2WJCNqUBp4p/Zf62f6KOmbGzzEf6RuUQKBgG2y\n' \ 'E8YRiaTOt5m0MXUwcEZk2Hg5DF31c/dkalqy2UYU57aPJ8djzQ8hR2x8G9ulWaWJ\n' \ 'KiCm8s9gaOFNFt3II785NfWxPmh7/qwmKuUzIdWFNxAsbHQ8NvURTqyccaSzIpFO\n' \ 'hw0inlhBEBQ1cB2r3r06fgQNb2BTT0Itzrd5gkNVAoGBAJcMgeKdBMukT8dKxb4R\n' \ '1PgQtFlR3COu2+B00pDyUpROFhHYLw/KlUv5TKrH1k3+E0KM+winVUIcZHlmFyuy\n' \ 'Ilquaova1YSFXP5cpD+PKtxRV76Qlqt6o+aPywm81licdOAXotT4JyJhrgz9ISnn\n' \ 'J13KkHoAZ9qd0rX7s37czb3O\n' \ '-----END PRIVATE KEY-----' def __init__(self, private=None, public=None): self._factory = MessageFactory( encoding="application/protobuf", family_name="sawtooth_validator_registry", family_version="1.0", namespace="6a4372", private=private, public=public ) self.pubkey_hash = hashlib.sha256(public.encode()).hexdigest() self._report_private_key = \ serialization.load_pem_private_key( self.__REPORT_PRIVATE_KEY_PEM__.encode(), password=None, backend=backends.default_backend()) # First we need to create a public/private key pair for the PoET # enclave to use. self._poet_private_key = \ "1f70fa2518077ad18483f48e77882d11983b537fa5f7cf158684d2c670fe4f1f" self.poet_public_key = \ signing.generate_pubkey(self._poet_private_key) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): return self._factory.namespace + \ self._factory.sha256(key.encode("utf-8")) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) # Utility function for creating proof data as we need to be # able to update signatures when verification report changes # Returns a serialized proof data def create_proof_data(self, verification_report, evidence_payload): verification_report_json = json.dumps(verification_report) signature = \ self._report_private_key.sign( verification_report_json.encode(), padding.PKCS1v15(), hashes.SHA256()) proof_data_dict = OrderedDict([ ('evidence_payload', evidence_payload), ('verification_report', verification_report_json), ('signature', base64.b64encode(signature).decode())] ) return json.dumps(proof_data_dict) # Currently this is done in the enclave def create_signup_info(self, originator_public_key_hash, nonce): # currently not used # _active_wait_timer = None # We are going to fake out the sealing the signup data. signup_data = { 'poet_public_key': self.poet_public_key, 'poet_private_key': self._poet_private_key } # Build up a fake SGX quote containing: # 1. The basename # 2. The report body that contains: # a. The enclave measurement # b. The report data SHA256(SHA256(OPK)|PPK) sgx_basename = \ sgx_structs.SgxBasename(name=self.__VALID_BASENAME__) sgx_measurement = \ sgx_structs.SgxMeasurement( m=self.__VALID_ENCLAVE_MEASUREMENT__) hash_input = \ '{0}{1}'.format( originator_public_key_hash.upper(), self.poet_public_key.upper()).encode() report_data = hashlib.sha256(hash_input).digest() sgx_report_data = sgx_structs.SgxReportData(d=report_data) sgx_report_body = \ sgx_structs.SgxReportBody( mr_enclave=sgx_measurement, report_data=sgx_report_data) sgx_quote = \ sgx_structs.SgxQuote( basename=sgx_basename, report_body=sgx_report_body) # Create a fake PSE manifest. A base64 encoding of the # originator public key hash should suffice. pse_manifest = \ base64.b64encode(originator_public_key_hash.encode()) timestamp = '2017-02-16T15:21:24.437048' # Fake our "proof" data. verification_report = OrderedDict([ ('epidPseudonym', originator_public_key_hash), ('id', base64.b64encode( hashlib.sha256( timestamp.encode()).hexdigest().encode()).decode()), ('isvEnclaveQuoteStatus', 'OK'), ('isvEnclaveQuoteBody', base64.b64encode(sgx_quote.serialize_to_bytes()).decode()), ('pseManifestStatus', 'OK'), ('pseManifestHash', hashlib.sha256(base64.b64decode(pse_manifest)).hexdigest()), ('nonce', nonce), ('timestamp', timestamp) ]) proof_data = \ self.create_proof_data( verification_report=verification_report, evidence_payload={ 'pse_manifest': pse_manifest.decode() }) return \ SignUpInfo( poet_public_key=signup_data['poet_public_key'], proof_data=proof_data, anti_sybil_id=originator_public_key_hash, nonce=nonce) def create_tp_process_request(self, validator_id, payload): inputs = [ self._key_to_address('validator_list') ] outputs = [ self._key_to_address('validator_list'), self._key_to_address(validator_id) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, [], False) def create_get_request_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_get_request(addresses) def create_get_response_validator_info(self, validator_name): signup_info = self.create_signup_info(self.pubkey_hash, "000") data = ValidatorInfo( registered="registered", name=validator_name, id=self.public_key, signup_info=signup_info, transaction_id="0103c991863cae73630fe0a9b8988ad35840a3994ad010cd4c" "60f17ca70b2054115bd5bdb0233f745826a61db0d83a32365f" "e4026b39a731b0e457a5f09be194" ).SerializeToString() address = self._key_to_address(self.public_key) return self._factory.create_get_response({address: data}) def create_set_request_validator_info(self, validator_name, reg): signup_info = self.create_signup_info(self.pubkey_hash, "000") data = ValidatorInfo( registered=reg, name=validator_name, id=self.public_key, signup_info=signup_info, transaction_id="0103c991863cae73630fe0a9b8988ad35840a3994ad010cd4c" "60f17ca70b2054115bd5bdb0233f745826a61db0d83a32365f" "e4026b39a731b0e457a5f09be194" ).SerializeToString() address = self._key_to_address(self.public_key) return self._factory.create_set_request({address: data}) def create_set_response_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_set_response(addresses) def create_get_request_validator_map(self): address = self._key_to_address("validator_map") addresses = [address] return self._factory.create_get_request(addresses) def create_get_empty_response_validator_map(self): address = self._key_to_address("validator_map") data = ValidatorMap().SerializeToString() return self._factory.create_get_response({address: data}) def create_get_response_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.pubkey_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_get_response({address: data}) def create_set_request_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.pubkey_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_set_request({address: data}) def create_set_response_validator_map(self): addresses = [self._key_to_address("validator_map")] return self._factory.create_set_response(addresses) def create_get_request_report_key_pem(self): return \ self._factory.create_get_request( ['000000a87cb5eafdcca6a87ccc804f5546a' 'b8e97a7d614626e4500e3b0c44298fc1c14']) def create_get_response_report_key_pem(self, pem=None): setting = Setting() if pem is not None: entry = Setting.Entry(key='sawtooth.poet.report_public_key_pem', value=pem) setting.entries.extend([entry]) data = setting.SerializeToString() return self._factory.create_get_response( {'000000a87cb5eafdcca6a87ccc804f5546a' 'b8e97a7d614626e4500e3b0c44298fc1c14': data}) def create_get_response_simulator_report_key_pem(self): pem = '''-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMvzZi8GT+lI9KeZiInn 4CvFTiuyid+IN4dP1+mhTnfxX+I/ntt8LUKZMbI1R1izOUoxJRoX6VQ4S9VgDLEC PW6QlkeLI1eqe4DiYb9+J5ANhq4+XkhwgCUUFwpfqSfXWCHimjaGsZHbavl5nv/6 IbZJL/2YzE37IzJdES16JCfmIUrk6TUqL0WgrWXyweTIoVSbld0M29kToSkMXLsj 8vbQbTiKwViWhYlzi0cQIo7PiAss66lAW0X6AM7ZJYyAcfSjSLR4guMz76Og8aRk jtsjEEkq7Ndz5H8hllWUoHpxGDqLhM9O1/h+QdvTz7luZgpeJ5KB92vYL6yOlSxM fQIDAQAB -----END PUBLIC KEY-----''' return self.create_get_response_report_key_pem(pem=pem) def create_get_request_enclave_measurements(self): return \ self._factory.create_get_request( ['000000a87cb5eafdcca6a87ccc804f5546a' 'b8e39ccaeec28506829e3b0c44298fc1c14']) def create_get_response_enclave_measurements(self, measurements=None): setting = Setting() if measurements is not None: entry = Setting.Entry(key='sawtooth.poet.' 'valid_enclave_measurements', value=measurements) setting.entries.extend([entry]) data = setting.SerializeToString() return self._factory.create_get_response( {'000000a87cb5eafdcca6a87ccc804f5546a' 'b8e39ccaeec28506829e3b0c44298fc1c14': data}) def create_get_response_simulator_enclave_measurements(self): return \ self.create_get_response_enclave_measurements( measurements='c99f21955e38dbb03d2ca838d3af6e43' 'ef438926ed02db4cc729380c8c7a174e') def create_get_request_enclave_basenames(self): return \ self._factory.create_get_request( ['000000a87cb5eafdcca6a87ccc804f5546a' 'b8ebec3b47bc008b27de3b0c44298fc1c14']) def create_get_response_enclave_basenames(self, basenames=None): setting = Setting() if basenames is not None: entry = Setting.Entry(key='sawtooth.poet.' 'valid_enclave_basenames', value=basenames) setting.entries.extend([entry]) data = setting.SerializeToString() return self._factory.create_get_response( {'000000a87cb5eafdcca6a87ccc804f5546a' 'b8ebec3b47bc008b27de3b0c44298fc1c14': data}) def create_get_response_simulator_enclave_basenames(self): return \ self.create_get_response_enclave_basenames( basenames='b785c58b77152cbe7fd55ee3851c4990' '00000000000000000000000000000000')
class SettingsMessageFactory: def __init__(self, signer=None): self._factory = MessageFactory( family_name="sawtooth_settings", family_version="1.0", namespace="000000", signer=signer) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1) key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts))) def _short_hash(in_str): return self._factory.sha256(in_str.encode())[:16] return self._factory.namespace + \ ''.join(_short_hash(x) for x in key_parts) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) def _create_tp_process_request(self, setting, payload): inputs = [ self._key_to_address('sawtooth.settings.vote.proposals'), self._key_to_address('sawtooth.settings.vote.authorized_keys'), self._key_to_address('sawtooth.settings.vote.approval_threshold'), self._key_to_address(setting) ] outputs = [ self._key_to_address('sawtooth.settings.vote.proposals'), self._key_to_address(setting) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_proposal_transaction(self, setting, value, nonce): proposal = SettingProposal(setting=setting, value=value, nonce=nonce) payload = SettingsPayload(action=SettingsPayload.PROPOSE, data=proposal.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_vote_proposal(self, proposal_id, setting, vote): vote = SettingVote(proposal_id=proposal_id, vote=vote) payload = SettingsPayload(action=SettingsPayload.VOTE, data=vote.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_get_request(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_get_request(addresses) def create_get_response(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_get_response({address: data}) def create_set_request(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_set_request({address: data}) def create_set_response(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_set_response(addresses) def create_add_event_request(self, key): return self._factory.create_add_event_request( "settings/update", [("updated", key)]) def create_add_event_response(self): return self._factory.create_add_event_response()
class EventMessageFactory(object): def __init__(self, signer=None): self._factory = MessageFactory( family_name=FAMILY_NAME, family_version="0.1.0", namespace=[EVENTS_ADDRESS_PREFIX], signer=signer) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1) key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts))) def _short_hash(in_str): return self._factory.sha256(in_str.encode())[:16] return self._factory.namespace + \ ''.join(_short_hash(x) for x in key_parts) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) def _create_tp_process_request(self, code, payload): inputs = [ self._key_to_address('hashblock.events.initiate'), self._key_to_address('hashblock.events.reciprocate'), self._key_to_address(code) ] outputs = [ self._key_to_address('hashblock.events.initiate'), self._key_to_address('hashblock.events.reciprocate'), self._key_to_address(code) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_initiate_transaction( self, code, version, plus, minus, quantity, nonce): initiate = InitiateEvent( version=version, plus=plus, minus=minus, nonce=nonce) payload = EventPayload( action=EventPayload.INITIATE_EVENT, data=initiate.SerializeToString()) return self._create_tp_process_request(code, payload) def create_reciprocate_transaction(self, proposal_id, code, vote): vote = ReciprocateEvent(proposal_id=proposal_id, vote=vote) payload = EventPayload( action=EventPayload.RECIPROCATE_EVENT, data=vote.SerializeToString()) return self._create_tp_process_request(code, payload) def create_get_request(self, code): addresses = [self._key_to_address(code)] return self._factory.create_get_request(addresses) def create_get_response(self, code, value=None): address = self._key_to_address(code) if value is not None: entry = Unit.Entry(key=code, value=value) data = Unit(entries=[entry]).SerializeToString() else: data = None return self._factory.create_get_response({address: data}) def create_set_request(self, code, value=None): address = self._key_to_address(code) if value is not None: entry = Unit.Entry(key=code, value=value) data = Unit(entries=[entry]).SerializeToString() else: data = None return self._factory.create_set_request({address: data}) def create_set_response(self, code): addresses = [self._key_to_address(code)] return self._factory.create_set_response(addresses) def create_add_event_request(self, key): return self._factory.create_add_event_request( "events/update", [("updated", key)]) def create_add_event_response(self): return self._factory.create_add_event_response()
class ValidatorRegistryMessageFactory(object): __REPORT_PRIVATE_KEY_PEM__ = \ '-----BEGIN PRIVATE KEY-----\n' \ 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsy/NmLwZP6Uj0\n' \ 'p5mIiefgK8VOK7KJ34g3h0/X6aFOd/Ff4j+e23wtQpkxsjVHWLM5SjElGhfpVDhL\n' \ '1WAMsQI9bpCWR4sjV6p7gOJhv34nkA2Grj5eSHCAJRQXCl+pJ9dYIeKaNoaxkdtq\n' \ '+Xme//ohtkkv/ZjMTfsjMl0RLXokJ+YhSuTpNSovRaCtZfLB5MihVJuV3Qzb2ROh\n' \ 'KQxcuyPy9tBtOIrBWJaFiXOLRxAijs+ICyzrqUBbRfoAztkljIBx9KNItHiC4zPv\n' \ 'o6DxpGSO2yMQSSrs13PkfyGWVZSgenEYOouEz07X+H5B29PPuW5mCl4nkoH3a9gv\n' \ 'rI6VLEx9AgMBAAECggEAImfFge4RCq4/eX85gcc7pRXyBjuLJAqe+7d0fWAmXxJg\n' \ 'vB+3XTEEi5p8GDoMg7U0kk6kdGe6pRnAz9CffEduU78FCPcbzCCzcD3cVWwkeUok\n' \ 'd1GQV4OC6vD3DBNjsrGdHg45KU18CjUphCZCQhdjvXynG+gZmWxZecuYXkg4zqPT\n' \ 'LwOkcdWBPhJ9CbjtiYOtKDZbhcbdfnb2fkxmvnAoz1OWNfVFXh+x7651FrmL2Pga\n' \ 'xGz5XoxFYYT6DWW1fL6GNuVrd97wkcYUcjazMgunuUMC+6XFxqK+BoqnxeaxnsSt\n' \ 'G2r0sdVaCyK1sU41ftbEQsc5oYeQ3v5frGZL+BgrYQKBgQDgZnjqnVI/B+9iarx1\n' \ 'MjAFyhurcKvFvlBtGKUg9Q62V6wI4VZvPnzA2zEaR1J0cZPB1lCcMsFACpuQF2Mr\n' \ '3VDyJbnpSG9q05POBtfLjGQdXKtGb8cfXY2SwjzLH/tvxHm3SP+RxvLICQcLX2/y\n' \ 'GTJ+mY9C6Hs6jIVLOnMWkRWamQKBgQDFITE3Qs3Y0ZwkKfGQMKuqJLRw29Tyzw0n\n' \ 'XKaVmO/pEzYcXZMPBrFhGvdmNcJLo2fcsmGZnmit8RP4ChwHUlD11dH1Ffqw9FWc\n' \ '387i0chlE5FhQPirSM8sWFVmjt2sxC4qFWJoAD/COQtKHgEaVKVc4sH/yRostL1C\n' \ 'r+7aWuqzhQKBgQDcuC5LJr8VPGrbtPz1kY3mw+r/cG2krRNSm6Egj6oO9KFEgtCP\n' \ 'zzjKQU9E985EtsqNKI5VdR7cLRLiYf6r0J6j7zO0IAlnXADP768miUqYDuRw/dUw\n' \ 'JsbwCZneefDI+Mp325d1/egjla2WJCNqUBp4p/Zf62f6KOmbGzzEf6RuUQKBgG2y\n' \ 'E8YRiaTOt5m0MXUwcEZk2Hg5DF31c/dkalqy2UYU57aPJ8djzQ8hR2x8G9ulWaWJ\n' \ 'KiCm8s9gaOFNFt3II785NfWxPmh7/qwmKuUzIdWFNxAsbHQ8NvURTqyccaSzIpFO\n' \ 'hw0inlhBEBQ1cB2r3r06fgQNb2BTT0Itzrd5gkNVAoGBAJcMgeKdBMukT8dKxb4R\n' \ '1PgQtFlR3COu2+B00pDyUpROFhHYLw/KlUv5TKrH1k3+E0KM+winVUIcZHlmFyuy\n' \ 'Ilquaova1YSFXP5cpD+PKtxRV76Qlqt6o+aPywm81licdOAXotT4JyJhrgz9ISnn\n' \ 'J13KkHoAZ9qd0rX7s37czb3O\n' \ '-----END PRIVATE KEY-----' def __init__(self, private=None, public=None): self._factory = MessageFactory( encoding="application/protobuf", family_name="sawtooth_validator_registry", family_version="1.0", namespace="6a4372", private=private, public=public) self.pubkey_hash = hashlib.sha256(public.encode()).hexdigest() self._report_private_key = \ serialization.load_pem_private_key( self.__REPORT_PRIVATE_KEY_PEM__.encode(), password=None, backend=backends.default_backend()) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): return self._factory.namespace + \ self._factory.sha256(key.encode("utf-8")) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) # Utility function for creating proof data as we need to be # able to update signatures when verification report changes # Returns a serialized proof data def create_proof_data(self, verification_report, evidence_payload): verification_report_json = json.dumps(verification_report) signature = \ self._report_private_key.sign( verification_report_json.encode(), padding.PKCS1v15(), hashes.SHA256()) proof_data_dict = { 'evidence_payload': evidence_payload, 'verification_report': verification_report_json, 'signature': base64.b64encode(signature).decode() } return json.dumps(proof_data_dict) # Currently this is done in the enclave def create_signup_info(self, originator_public_key_hash, most_recent_wait_certificate_id): # First we need to create a public/private key pair for the PoET # enclave to use. poet_private_key = \ "1f70fa2518077ad18483f48e77882d11983b537fa5f7cf158684d2c670fe4f1f" poet_public_key = \ signing.generate_pubkey(poet_private_key) # currently not used # _active_wait_timer = None # We are going to fake out the sealing the signup data. signup_data = { 'poet_public_key': signing.encode_pubkey(poet_public_key, 'hex'), 'poet_private_key': signing.encode_privkey(poet_private_key, 'hex') } # Create a fake report report_data = '{0}{1}'.format( originator_public_key_hash.upper(), signing.encode_pubkey(poet_public_key, 'hex').upper()) quote = { 'report_body': hashlib.sha256(json.dumps(report_data).encode()).hexdigest() } # Create a fake PSE manifest. A base64 encoding of the # originator public key hash should suffice. pse_manifest = \ base64.b64encode(originator_public_key_hash.encode()) timestamp = '2017-02-16T15:21:24.437048' # Fake our "proof" data. verification_report = { 'epidPseudonym': originator_public_key_hash, 'id': base64.b64encode( hashlib.sha256( timestamp.encode()).hexdigest().encode()).decode(), 'isvEnclaveQuoteStatus': 'OK', 'isvEnclaveQuoteBody': base64.b64encode(json.dumps(quote).encode()).decode(), 'pseManifestStatus': 'OK', 'pseManifestHash': base64.b64encode( hashlib.sha256(pse_manifest).hexdigest().encode()).decode(), 'nonce': most_recent_wait_certificate_id, 'timestamp': timestamp } proof_data = \ self.create_proof_data( verification_report=verification_report, evidence_payload={ 'pse_manifest': pse_manifest.decode() }) return \ SignUpInfo( poet_public_key=signup_data['poet_public_key'], proof_data=proof_data, anti_sybil_id=originator_public_key_hash) def create_tp_process_request(self, validator_id, payload): inputs = [self._key_to_address('validator_list')] outputs = [ self._key_to_address('validator_list'), self._key_to_address(validator_id) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_get_request_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_get_request(addresses) def create_get_response_validator_info(self, validator_name): signup_info = self.create_signup_info(self.pubkey_hash, "000") data = ValidatorInfo(registered="registered", name=validator_name, id=self.public_key, signup_info=signup_info, block_num=0).SerializeToString() address = self._key_to_address(self.public_key) return self._factory.create_get_response({address: data}) def create_set_request_validator_info(self, validator_name, reg): signup_info = self.create_signup_info(self.pubkey_hash, "000") data = ValidatorInfo(registered=reg, name=validator_name, id=self.public_key, signup_info=signup_info, block_num=0).SerializeToString() address = self._key_to_address(self.public_key) return self._factory.create_set_request({address: data}) def create_set_response_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_set_response(addresses) def create_get_request_validator_map(self): address = self._key_to_address("validator_map") addresses = [address] return self._factory.create_get_request(addresses) def create_get_empty_resposne_validator_map(self): address = self._key_to_address("validator_map") data = ValidatorMap().SerializeToString() return self._factory.create_get_response({address: data}) def create_get_response_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.pubkey_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_get_response({address: data}) def create_set_request_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.pubkey_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_set_request({address: data}) def create_set_response_validator_map(self): addresses = [self._key_to_address("validator_map")] return self._factory.create_set_response(addresses)
class ValidatorRegistryMessageFactory(object): def __init__(self, private=None, public=None): self._factory = MessageFactory( encoding="application/protobuf", family_name="sawtooth_validator_registry", family_version="1.0", namespace="6a4372", private=private, public=public) self.pubkey_hash = hashlib.sha256(public.encode()).hexdigest() @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): return self._factory.namespace + \ self._factory.sha256(key.encode("utf-8")) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) # Currently this is done in the enclave def create_signup_info(self, originator_public_key_hash, most_recent_wait_certificate_id): # First we need to create a public/private key pair for the PoET # enclave to use. _poet_private_key = \ "1f70fa2518077ad18483f48e77882d11983b537fa5f7cf158684d2c670fe4f1f" _poet_public_key = \ signing.generate_pubkey(_poet_private_key) # currently not used # _active_wait_timer = None _report_private_key = \ signing.encode_privkey( signing.decode_privkey( '5Jz5Kaiy3kCiHE537uXcQnJuiNJshf2bZZn43CrALMGoCd3zRuo', 'wif'), 'hex') # We are going to fake out the sealing the signup data. signup_data = { 'poet_public_key': signing.encode_pubkey(_poet_public_key, 'hex'), 'poet_private_key': signing.encode_privkey(_poet_private_key, 'hex') } # Create a fake report report_data = '{0}{1}'.format( originator_public_key_hash.upper(), signing.encode_pubkey(_poet_public_key, 'hex').upper()) quote = { 'report_body': hashlib.sha256(json.dumps(report_data).encode()).hexdigest() } # Fake our "proof" data. verification_report = { 'id': base64.b64encode( bytes( hashlib.sha256(b'2017-02-16T15:21:24.437048').hexdigest(). encode())).decode(), 'isvEnclaveQuoteStatus': 'OK', 'isvEnclaveQuoteBody': base64.b64encode(json.dumps(quote).encode()).decode(), 'pseManifestStatus': 'OK', 'pseManifestHash': base64.b64encode( hashlib.sha256( bytes( b'Do you believe in ' b'manifest destiny?')).hexdigest().encode()).decode(), 'nonce': most_recent_wait_certificate_id } proof_data_dict = { 'verification_report': json.dumps(verification_report), 'signature': signing.sign(json.dumps(verification_report), _report_private_key) } proof_data = json.dumps(proof_data_dict) return \ SignUpInfo( poet_public_key=signup_data['poet_public_key'], proof_data=proof_data, anti_sybil_id=originator_public_key_hash) def create_tp_process_request(self, validator_id, payload): inputs = [self._key_to_address('validator_list')] outputs = [ self._key_to_address('validator_list'), self._key_to_address(validator_id) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_get_request_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_get_request(addresses) def create_get_response_validator_info(self, validator_name): signup_info = self.create_signup_info(self.pubkey_hash, "000") data = ValidatorInfo(registered="registered", name=validator_name, id=self.public_key, signup_info=signup_info, block_num=0).SerializeToString() address = self._key_to_address(self.public_key) return self._factory.create_get_response({address: data}) def create_set_request_validator_info(self, validator_name, reg): signup_info = self.create_signup_info(self.pubkey_hash, "000") data = ValidatorInfo(registered=reg, name=validator_name, id=self.public_key, signup_info=signup_info, block_num=0).SerializeToString() address = self._key_to_address(self.public_key) return self._factory.create_set_request({address: data}) def create_set_response_validator_info(self): addresses = [self._key_to_address(self.public_key)] return self._factory.create_set_response(addresses) def create_get_request_validator_map(self): address = self._key_to_address("validator_map") addresses = [address] return self._factory.create_get_request(addresses) def create_get_empty_resposne_validator_map(self): address = self._key_to_address("validator_map") data = ValidatorMap().SerializeToString() return self._factory.create_get_response({address: data}) def create_get_response_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.pubkey_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_get_response({address: data}) def create_set_request_validator_map(self): address = self._key_to_address("validator_map") validator_map = ValidatorMap() validator_map.entries.add(key=self.pubkey_hash, value=self.public_key) data = validator_map.SerializeToString() return self._factory.create_set_request({address: data}) def create_set_response_validator_map(self): addresses = [self._key_to_address("validator_map")] return self._factory.create_set_response(addresses)
class ConfigMessageFactory(object): def __init__(self, private=None, public=None): self._factory = MessageFactory( encoding="application/protobuf", family_name="sawtooth_config", family_version="1.0", namespace="000000", private=private, public=public ) @property def public_key(self): return self._factory.get_public_key() def _key_to_address(self, key): return self._factory.namespace + \ self._factory.sha256(key.encode("utf-8")) def create_tp_register(self): return self._factory.create_tp_register() def create_tp_response(self, status): return self._factory.create_tp_response(status) def _create_tp_process_request(self, setting, payload): inputs = [ self._key_to_address('sawtooth.config.authorization_type'), self._key_to_address('sawtooth.config.vote.proposals'), self._key_to_address('sawtooth.config.vote.authorized_keys'), self._key_to_address('sawtooth.config.vote.approval_threshold'), self._key_to_address(setting) ] outputs = [ self._key_to_address('sawtooth.config.vote.proposals'), self._key_to_address(setting) ] return self._factory.create_tp_process_request( payload.SerializeToString(), inputs, outputs, []) def create_proposal_transaction(self, setting, value, nonce): proposal = ConfigProposal(setting=setting, value=value, nonce=nonce) payload = ConfigPayload(action=ConfigPayload.PROPOSE, data=proposal.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_vote_proposal(self, proposal_id, setting, vote): vote = ConfigVote(proposal_id=proposal_id, vote=vote) payload = ConfigPayload(action=ConfigPayload.VOTE, data=vote.SerializeToString()) return self._create_tp_process_request(setting, payload) def create_get_request(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_get_request(addresses) def create_get_response(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_get_response({address: data}) def create_set_request(self, setting, value=None): address = self._key_to_address(setting) if value is not None: entry = Setting.Entry(key=setting, value=value) data = Setting(entries=[entry]).SerializeToString() else: data = None return self._factory.create_set_request({address: data}) def create_set_response(self, setting): addresses = [self._key_to_address(setting)] return self._factory.create_set_response(addresses)