def do_test_signature(self, chain, display_chain, type):
     merkle_tree_generator = MerkleTreeGenerator()
     merkle_tree_generator.populate(get_test_data_generator())
     _ = merkle_tree_generator.get_blockchain_data()
     gen = merkle_tree_generator.get_proof_generator(
         '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', chain)
     p1 = next(gen)
     _ = next(gen)
     p3 = next(gen)
     p1_expected = {'type': ['MerkleProof2017', 'Extension'],
                    'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
                    'targetHash': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b',
                    'proof': [{'right': 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35'},
                              {'right': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'}],
                    'anchors': [
                        {'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582',
                         'type': type,
                         'chain': display_chain}]}
     p3_expected = {'type': ['MerkleProof2017', 'Extension'],
                    'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
                    'targetHash': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce',
                    'proof': [{'left': '4295f72eeb1e3507b8461e240e3b8d18c1e7bd2f1122b11fc9ec40a65894031a'}],
                    'anchors': [{'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582',
                                 'type': type,
                                 'chain': display_chain}]}
     self.assertEqual(p1, p1_expected)
     self.assertEqual(p3, p3_expected)
Exemple #2
0
 def test_generate(self):
     merkle_tree_generator = MerkleTreeGenerator()
     merkle_tree_generator.populate(get_test_data_generator())
     byte_array = merkle_tree_generator.get_blockchain_data()
     self.assertEqual(
         b2h(byte_array),
         '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')
    def test_proofs(self):
        merkle_tree_generator = MerkleTreeGenerator()
        merkle_tree_generator.populate(get_test_data_generator())
        _ = merkle_tree_generator.get_blockchain_data()
        gen = merkle_tree_generator.get_proof_generator(
            '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', Chain.mainnet)

        p1 = next(gen)
        _ = next(gen)
        p3 = next(gen)

        p1_expected = {'type': ['MerkleProof2017', 'Extension'],
                       'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
                       'targetHash': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b',
                       'proof': [{'right': 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35'},
                                 {'right': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'}],
                       'anchors': [
                           {'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582',
                            'type': 'BTCOpReturn'}]}

        p3_expected = {'type': ['MerkleProof2017', 'Extension'],
                       'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
                       'targetHash': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce',
                       'proof': [{'left': '4295f72eeb1e3507b8461e240e3b8d18c1e7bd2f1122b11fc9ec40a65894031a'}],
                       'anchors': [{'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582',
                                    'type': 'BTCOpReturn'}]}
        self.assertEqual(p1, p1_expected)
        self.assertEqual(p3, p3_expected)
Exemple #4
0
class SimplifiedCertificateBatchIssuer:
    """
    Class to issue blockcerts without relying on filesystem usage.

    Please note that it currently only supports anchoring to Ethereum.
    """
    def __init__(self, config: 'AttrDict', unsigned_certs: dict):
        # 1- Prepare config and unsigned certs (These come from my latest changes in cert-tools
        self.config = config
        self.config.original_chain = self.config.chain
        self.config.chain = Chain.parse_from_chain(self.config.chain)

        self.path_to_secret = os.path.join(config.usb_name, config.key_file)

        self.unsigned_certs = unsigned_certs
        self.cert_generator = self._create_cert_generator()

        # 2- Calculate Merkle Tree and Root
        self.merkle_tree_generator = MerkleTreeGenerator()
        self.merkle_tree_generator.populate(self.cert_generator)
        self.merkle_root = self.merkle_tree_generator.get_blockchain_data()

    def issue(self) -> Tuple[str, Dict]:
        """Anchor the merkle root in a blockchain transaction and add the tx id and merkle proof to each cert."""
        tx_id = self._broadcast_transaction()
        signed_certs = self._add_proof_to_certs(tx_id)
        return tx_id, signed_certs

    def _add_proof_to_certs(self, tx_id) -> Dict:
        """Add merkle proof to the JSON of the certificates."""
        proof_generator = self.merkle_tree_generator.get_proof_generator(
            tx_id, self.config.chain)
        signed_certs = copy.deepcopy(self.unsigned_certs)
        for _, cert in signed_certs.items():
            proof = next(proof_generator)
            cert['signature'] = proof
        return signed_certs

    def _broadcast_transaction(self) -> str:
        """Broadcast the tx used to anchor a merkle root to a given blockchain."""
        self.transaction_handler = SimplifiedEthereumTransactionHandler(
            chain=self.config.original_chain.split('_')[1],
            path_to_secret=self.path_to_secret,
            private_key=self.config.get('eth_private_key'),
            recommended_max_cost=self.config.gas_price * self.config.gas_limit,
            account_from=self.config.get('eth_public_key')
            or self.config.issuing_address,
        )
        tx_id = self.transaction_handler.issue_transaction(self.merkle_root)
        return tx_id

    def _create_cert_generator(self) -> Generator:
        """Return a generator of jsonld-normalized unsigned certs."""
        for uid, cert in self.unsigned_certs.items():
            normalized = normalize_jsonld(cert, detect_unmapped_fields=False)
            yield normalized.encode('utf-8')
 def test_generate(self):
     merkle_tree_generator = MerkleTreeGenerator()
     merkle_tree_generator.populate(get_test_data_generator())
     byte_array = merkle_tree_generator.get_blockchain_data()
     self.assertEqual(b2h(byte_array), '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')
    def do_test_signature(self, chain, display_chain, type):
        self.maxDiff = None
        app_config = mock.Mock()
        app_config.issuing_method = "transaction"

        merkle_tree_generator = MerkleTreeGenerator()
        merkle_tree_generator.populate(get_test_data_generator())
        _ = merkle_tree_generator.get_blockchain_data()
        gen = merkle_tree_generator.get_proof_generator(
            '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582',
            'http://example.com', chain)
        p1 = next(gen)
        _ = next(gen)
        p3 = next(gen)

        p1_json_proof = {
            'path': [{
                'right':
                'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35'
            }, {
                'right':
                '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'
            }],
            'merkleRoot':
            '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
            'targetHash':
            '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b',
            'anchors': [
                helpers.tx_to_blink(
                    chain,
                    '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582'
                )
            ]
        }
        mp2019 = MerkleProof2019()
        proof_value = mp2019.encode(p1_json_proof)

        p1_expected = {
            "type": "MerkleProof2019",
            "created": p1['created'],
            "proofValue": proof_value.decode('utf8'),
            "proofPurpose": "assertionMethod",
            "verificationMethod": "http://example.com"
        }

        p3_json_proof = {
            'path': [{
                'left':
                '4295f72eeb1e3507b8461e240e3b8d18c1e7bd2f1122b11fc9ec40a65894031a'
            }],
            'merkleRoot':
            '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
            'targetHash':
            '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce',
            'anchors': [
                helpers.tx_to_blink(
                    chain,
                    '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582'
                )
            ]
        }
        mp2019 = MerkleProof2019()
        proof_value = mp2019.encode(p3_json_proof)

        p3_expected = {
            "type": "MerkleProof2019",
            "created": p3['created'],
            "proofValue": proof_value.decode('utf8'),
            "proofPurpose": "assertionMethod",
            "verificationMethod": "http://example.com"
        }

        self.assertEqual(p1, p1_expected)
        self.assertEqual(p3, p3_expected)