From 85353f7002b61e728b6d082bb5e9881cc066c273 Mon Sep 17 00:00:00 2001 From: diminator Date: Fri, 15 Apr 2016 16:32:27 +0200 Subject: [PATCH] updated cryptoconditions replaced get_subcondition_from_vk --- bigchaindb/crypto.py | 8 ++-- bigchaindb/util.py | 34 +++++++--------- setup.py | 2 +- tests/db/test_bigchain_api.py | 75 +++++++++++++++++------------------ 4 files changed, 57 insertions(+), 62 deletions(-) diff --git a/bigchaindb/crypto.py b/bigchaindb/crypto.py index bdd6aaaa..96be68e2 100644 --- a/bigchaindb/crypto.py +++ b/bigchaindb/crypto.py @@ -1,7 +1,7 @@ # Separate all crypto code so that we can easily test several implementations import sha3 -from cryptoconditions import ed25519 +from cryptoconditions import crypto def hash_data(data): @@ -10,8 +10,8 @@ def hash_data(data): def generate_key_pair(): - sk, pk = ed25519.ed25519_generate_key_pair() + sk, pk = crypto.ed25519_generate_key_pair() return sk.decode(), pk.decode() -SigningKey = ed25519.SigningKey -VerifyingKey = ed25519.VerifyingKey +SigningKey = crypto.Ed25519SigningKey +VerifyingKey = crypto.Ed25519VerifyingKey diff --git a/bigchaindb/util.py b/bigchaindb/util.py index 85ffc418..3cfb4048 100644 --- a/bigchaindb/util.py +++ b/bigchaindb/util.py @@ -4,8 +4,7 @@ import time import multiprocessing as mp from datetime import datetime -from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment -from cryptoconditions.fulfillment import Fulfillment +import cryptoconditions as cc import bigchaindb from bigchaindb import exceptions @@ -194,11 +193,11 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None): conditions = [] for fulfillment in fulfillments: if len(new_owners) > 1: - condition = ThresholdSha256Fulfillment(threshold=len(new_owners)) + condition = cc.ThresholdSha256Fulfillment(threshold=len(new_owners)) for new_owner in new_owners: - condition.add_subfulfillment(Ed25519Fulfillment(public_key=new_owner)) + condition.add_subfulfillment(cc.Ed25519Fulfillment(public_key=new_owner)) elif len(new_owners) == 1: - condition = Ed25519Fulfillment(public_key=new_owners[0]) + condition = cc.Ed25519Fulfillment(public_key=new_owners[0]) conditions.append({ 'new_owners': new_owners, 'condition': { @@ -258,10 +257,10 @@ def sign_tx(transaction, sks): for fulfillment in tx['transaction']['fulfillments']: fulfillment_message = get_fulfillment_message(transaction, fulfillment) - parsed_fulfillment = Fulfillment.from_json(fulfillment_message['condition']['condition']['details']) - + parsed_fulfillment = cc.Fulfillment.from_json(fulfillment_message['condition']['condition']['details']) + parsed_fulfillment_copy = copy.deepcopy(parsed_fulfillment) # single current owner - if isinstance(parsed_fulfillment, Ed25519Fulfillment): + if isinstance(parsed_fulfillment, cc.Ed25519Fulfillment): current_owner = fulfillment['current_owners'][0] try: parsed_fulfillment.sign(serialize(fulfillment_message), key_pairs[current_owner]) @@ -269,11 +268,15 @@ def sign_tx(transaction, sks): raise exceptions.KeypairMismatchException('Public key {} is not a pair to any of the private keys' .format(current_owner)) # multiple current owners - elif isinstance(parsed_fulfillment, ThresholdSha256Fulfillment): + elif isinstance(parsed_fulfillment, cc.ThresholdSha256Fulfillment): # replace the fulfillments with the signed fulfillments parsed_fulfillment.subconditions = [] for current_owner in fulfillment['current_owners']: - subfulfillment = get_subcondition_from_vk(fulfillment_message['condition'], current_owner) + try: + subfulfillment = parsed_fulfillment_copy.get_subcondition_from_vk(current_owner)[0] + except IndexError: + exceptions.KeypairMismatchException('Public key {} cannot be found in the fulfillment' + .format(current_owner)) try: subfulfillment.sign(serialize(fulfillment_message), key_pairs[current_owner]) except KeyError: @@ -320,7 +323,7 @@ def verify_signature(signed_transaction): fulfillment_message = get_fulfillment_message(signed_transaction, fulfillment) # verify the fulfillment (for now lets assume there is only one owner) try: - parsed_fulfillment = Fulfillment.from_uri(fulfillment['fulfillment']) + parsed_fulfillment = cc.Fulfillment.from_uri(fulfillment['fulfillment']) except Exception: return False is_valid = parsed_fulfillment.validate(serialize(fulfillment_message)) @@ -372,7 +375,7 @@ def get_fulfillment_message(transaction, fulfillment, serialized=False): # there is no previous transaction so we need to create one on the fly else: current_owner = transaction['transaction']['fulfillments'][0]['current_owners'][0] - condition = json.loads(Ed25519Fulfillment(public_key=current_owner).serialize_json()) + condition = json.loads(cc.Ed25519Fulfillment(public_key=current_owner).serialize_json()) fulfillment_message['condition'] = {'condition': {'details': condition}} if serialized: return serialize(fulfillment_message) @@ -399,13 +402,6 @@ def get_hash_data(transaction): return crypto.hash_data(serialize(tx)) -def get_subcondition_from_vk(condition, vk): - threshold_fulfillment = Fulfillment.from_json(condition['condition']['details']) - for subcondition in threshold_fulfillment.subconditions: - if subcondition['body'].public_key.to_ascii().decode() == vk: - return subcondition['body'] - - def transform_create(tx): """Change the owner and signature for a ``CREATE`` transaction created by a node""" diff --git a/setup.py b/setup.py index f41b9880..5b1cec03 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,7 @@ setup( 'rethinkdb==2.2.0.post4', 'pysha3==0.3', 'pytz==2015.7', - 'cryptoconditions==0.1.6', + 'cryptoconditions==0.2.0', 'statsd==3.2.1', 'python-rapidjson==0.0.6', 'logstats==0.2.1', diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index df2cfa6d..1e2c3a85 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -6,9 +6,7 @@ import json import pytest import rethinkdb as r -from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment -from cryptoconditions.condition import Condition -from cryptoconditions.fulfillment import Fulfillment +import cryptoconditions as cc import bigchaindb from bigchaindb import util @@ -330,7 +328,7 @@ class TestTransactionValidation(object): # create a correctly signed transaction and change the signature tx_signed = b.sign_transaction(tx_valid, user_sk) fulfillment = tx_signed['transaction']['fulfillments'][0]['fulfillment'] - changed_fulfillment = Ed25519Fulfillment().from_uri(fulfillment) + changed_fulfillment = cc.Ed25519Fulfillment().from_uri(fulfillment) changed_fulfillment.signature = b'0' * 64 tx_signed['transaction']['fulfillments'][0]['fulfillment'] = changed_fulfillment.serialize_uri() @@ -1178,15 +1176,15 @@ class TestCryptoconditions(object): def test_fulfillment_transaction_create(self, b, user_vk): tx = b.create_transaction(b.me, user_vk, None, 'CREATE') condition = tx['transaction']['conditions'][0]['condition'] - condition_from_uri = Condition.from_uri(condition['uri']) - condition_from_json = Fulfillment.from_json(condition['details']).condition + condition_from_uri = cc.Condition.from_uri(condition['uri']) + condition_from_json = cc.Fulfillment.from_json(condition['details']).condition assert condition_from_uri.serialize_uri() == condition_from_json.serialize_uri() assert condition['details']['public_key'] == user_vk tx_signed = b.sign_transaction(tx, b.me_private) fulfillment = tx_signed['transaction']['fulfillments'][0] - fulfillment_from_uri = Fulfillment.from_uri(fulfillment['fulfillment']) + fulfillment_from_uri = cc.Fulfillment.from_uri(fulfillment['fulfillment']) assert fulfillment['current_owners'][0] == b.me assert fulfillment_from_uri.public_key.to_ascii().decode() == b.me @@ -1202,22 +1200,22 @@ class TestCryptoconditions(object): prev_tx = b.get_transaction(prev_tx_id['txid']) prev_condition = prev_tx['transaction']['conditions'][0]['condition'] - prev_condition_from_uri = Condition.from_uri(prev_condition['uri']) - prev_condition_from_json = Fulfillment.from_json(prev_condition['details']).condition + prev_condition_from_uri = cc.Condition.from_uri(prev_condition['uri']) + prev_condition_from_json = cc.Fulfillment.from_json(prev_condition['details']).condition assert prev_condition_from_uri.serialize_uri() == prev_condition_from_json.serialize_uri() assert prev_condition['details']['public_key'] == user_vk condition = tx['transaction']['conditions'][0]['condition'] - condition_from_uri = Condition.from_uri(condition['uri']) - condition_from_json = Fulfillment.from_json(condition['details']).condition + condition_from_uri = cc.Condition.from_uri(condition['uri']) + condition_from_json = cc.Fulfillment.from_json(condition['details']).condition assert condition_from_uri.serialize_uri() == condition_from_json.serialize_uri() assert condition['details']['public_key'] == other_vk tx_signed = b.sign_transaction(tx, user_sk) fulfillment = tx_signed['transaction']['fulfillments'][0] - fulfillment_from_uri = Fulfillment.from_uri(fulfillment['fulfillment']) + fulfillment_from_uri = cc.Fulfillment.from_uri(fulfillment['fulfillment']) assert fulfillment['current_owners'][0] == user_vk assert fulfillment_from_uri.public_key.to_ascii().decode() == user_vk @@ -1227,7 +1225,7 @@ class TestCryptoconditions(object): def test_override_condition_create(self, b, user_vk): tx = b.create_transaction(b.me, user_vk, None, 'CREATE') - fulfillment = Ed25519Fulfillment(public_key=user_vk) + fulfillment = cc.Ed25519Fulfillment(public_key=user_vk) tx['transaction']['conditions'][0]['condition'] = { 'details': json.loads(fulfillment.serialize_json()), 'uri': fulfillment.condition.serialize_uri() @@ -1236,7 +1234,7 @@ class TestCryptoconditions(object): tx_signed = b.sign_transaction(tx, b.me_private) fulfillment = tx_signed['transaction']['fulfillments'][0] - fulfillment_from_uri = Fulfillment.from_uri(fulfillment['fulfillment']) + fulfillment_from_uri = cc.Fulfillment.from_uri(fulfillment['fulfillment']) assert fulfillment['current_owners'][0] == b.me assert fulfillment_from_uri.public_key.to_ascii().decode() == b.me @@ -1250,7 +1248,7 @@ class TestCryptoconditions(object): prev_tx_id = b.get_owned_ids(user_vk).pop() tx = b.create_transaction(user_vk, other_vk, prev_tx_id, 'TRANSFER') - fulfillment = Ed25519Fulfillment(public_key=other_vk) + fulfillment = cc.Ed25519Fulfillment(public_key=other_vk) tx['transaction']['conditions'][0]['condition'] = { 'details': json.loads(fulfillment.serialize_json()), 'uri': fulfillment.condition.serialize_uri() @@ -1258,7 +1256,7 @@ class TestCryptoconditions(object): tx_signed = b.sign_transaction(tx, user_sk) fulfillment = tx_signed['transaction']['fulfillments'][0] - fulfillment_from_uri = Fulfillment.from_uri(fulfillment['fulfillment']) + fulfillment_from_uri = cc.Fulfillment.from_uri(fulfillment['fulfillment']) assert fulfillment['current_owners'][0] == user_vk assert fulfillment_from_uri.public_key.to_ascii().decode() == user_vk @@ -1269,7 +1267,7 @@ class TestCryptoconditions(object): tx = b.create_transaction(b.me, user_vk, None, 'CREATE') original_fulfillment = tx['transaction']['fulfillments'][0] fulfillment_message = util.get_fulfillment_message(tx, original_fulfillment, serialized=True) - fulfillment = Ed25519Fulfillment(public_key=b.me) + fulfillment = cc.Ed25519Fulfillment(public_key=b.me) fulfillment.sign(fulfillment_message, crypto.SigningKey(b.me_private)) tx['transaction']['fulfillments'][0]['fulfillment'] = fulfillment.serialize_uri() @@ -1286,7 +1284,7 @@ class TestCryptoconditions(object): original_fulfillment = tx['transaction']['fulfillments'][0] fulfillment_message = util.get_fulfillment_message(tx, original_fulfillment, serialized=True) - fulfillment = Ed25519Fulfillment(public_key=user_vk) + fulfillment = cc.Ed25519Fulfillment(public_key=user_vk) fulfillment.sign(fulfillment_message, crypto.SigningKey(user_sk)) tx['transaction']['fulfillments'][0]['fulfillment'] = fulfillment.serialize_uri() @@ -1300,7 +1298,7 @@ class TestCryptoconditions(object): first_input_tx = b.get_owned_ids(user_vk).pop() first_tx = b.create_transaction(user_vk, other_vk, first_input_tx, 'TRANSFER') - first_tx_condition = Ed25519Fulfillment(public_key=other_vk) + first_tx_condition = cc.Ed25519Fulfillment(public_key=other_vk) first_tx['transaction']['conditions'][0]['condition'] = { 'details': json.loads(first_tx_condition.serialize_json()), 'uri': first_tx_condition.condition.serialize_uri() @@ -1308,7 +1306,7 @@ class TestCryptoconditions(object): first_tx_fulfillment = first_tx['transaction']['fulfillments'][0] first_tx_fulfillment_message = util.get_fulfillment_message(first_tx, first_tx_fulfillment, serialized=True) - first_tx_fulfillment = Ed25519Fulfillment(public_key=user_vk) + first_tx_fulfillment = cc.Ed25519Fulfillment(public_key=user_vk) first_tx_fulfillment.sign(first_tx_fulfillment_message, crypto.SigningKey(user_sk)) first_tx['transaction']['fulfillments'][0]['fulfillment'] = first_tx_fulfillment.serialize_uri() @@ -1327,7 +1325,7 @@ class TestCryptoconditions(object): next_tx_fulfillment = next_tx['transaction']['fulfillments'][0] next_tx_fulfillment_message = util.get_fulfillment_message(next_tx, next_tx_fulfillment, serialized=True) - next_tx_fulfillment = Ed25519Fulfillment(public_key=other_vk) + next_tx_fulfillment = cc.Ed25519Fulfillment(public_key=other_vk) next_tx_fulfillment.sign(next_tx_fulfillment_message, crypto.SigningKey(other_sk)) next_tx['transaction']['fulfillments'][0]['fulfillment'] = next_tx_fulfillment.serialize_uri() @@ -1342,9 +1340,9 @@ class TestCryptoconditions(object): first_input_tx = b.get_owned_ids(user_vk).pop() first_tx = b.create_transaction(user_vk, [other1_vk, other2_vk], first_input_tx, 'TRANSFER') - first_tx_condition = ThresholdSha256Fulfillment(threshold=2) - first_tx_condition.add_subfulfillment(Ed25519Fulfillment(public_key=other1_vk)) - first_tx_condition.add_subfulfillment(Ed25519Fulfillment(public_key=other2_vk)) + first_tx_condition = cc.ThresholdSha256Fulfillment(threshold=2) + first_tx_condition.add_subfulfillment(cc.Ed25519Fulfillment(public_key=other1_vk)) + first_tx_condition.add_subfulfillment(cc.Ed25519Fulfillment(public_key=other2_vk)) first_tx['transaction']['conditions'][0]['condition'] = { 'details': json.loads(first_tx_condition.serialize_json()), @@ -1370,11 +1368,11 @@ class TestCryptoconditions(object): next_tx_fulfillment = next_tx['transaction']['fulfillments'][0] next_tx_fulfillment_message = util.get_fulfillment_message(next_tx, next_tx_fulfillment, serialized=True) - next_tx_fulfillment = ThresholdSha256Fulfillment(threshold=2) - next_tx_subfulfillment1 = Ed25519Fulfillment(public_key=other1_vk) + next_tx_fulfillment = cc.ThresholdSha256Fulfillment(threshold=2) + next_tx_subfulfillment1 = cc.Ed25519Fulfillment(public_key=other1_vk) next_tx_subfulfillment1.sign(next_tx_fulfillment_message, crypto.SigningKey(other1_sk)) next_tx_fulfillment.add_subfulfillment(next_tx_subfulfillment1) - next_tx_subfulfillment2 = Ed25519Fulfillment(public_key=other2_vk) + next_tx_subfulfillment2 = cc.Ed25519Fulfillment(public_key=other2_vk) next_tx_subfulfillment2.sign(next_tx_fulfillment_message, crypto.SigningKey(other2_sk)) next_tx_fulfillment.add_subfulfillment(next_tx_subfulfillment2) next_tx['transaction']['fulfillments'][0]['fulfillment'] = next_tx_fulfillment.serialize_uri() @@ -1390,9 +1388,9 @@ class TestCryptoconditions(object): first_input_tx = b.get_owned_ids(user_vk).pop() first_tx = b.create_transaction(user_vk, [other1_vk, other2_vk], first_input_tx, 'TRANSFER') - first_tx_condition = ThresholdSha256Fulfillment(threshold=2) - first_tx_condition.add_subfulfillment(Ed25519Fulfillment(public_key=other1_vk)) - first_tx_condition.add_subfulfillment(Ed25519Fulfillment(public_key=other2_vk)) + first_tx_condition = cc.ThresholdSha256Fulfillment(threshold=2) + first_tx_condition.add_subfulfillment(cc.Ed25519Fulfillment(public_key=other1_vk)) + first_tx_condition.add_subfulfillment(cc.Ed25519Fulfillment(public_key=other2_vk)) first_tx['transaction']['conditions'][0]['condition'] = { 'details': json.loads(first_tx_condition.serialize_json()), @@ -1418,13 +1416,13 @@ class TestCryptoconditions(object): next_tx_fulfillment = next_tx['transaction']['fulfillments'][0] next_tx_fulfillment_message = util.get_fulfillment_message(next_tx, next_tx_fulfillment, serialized=True) - next_tx_fulfillment = ThresholdSha256Fulfillment(threshold=2) - next_tx_subfulfillment1 = Ed25519Fulfillment(public_key=other1_vk) + next_tx_fulfillment = cc.ThresholdSha256Fulfillment(threshold=2) + next_tx_subfulfillment1 = cc.Ed25519Fulfillment(public_key=other1_vk) next_tx_subfulfillment1.sign(next_tx_fulfillment_message, crypto.SigningKey(other1_sk)) next_tx_fulfillment.add_subfulfillment(next_tx_subfulfillment1) # Wrong signing happens here - next_tx_subfulfillment2 = Ed25519Fulfillment(public_key=other1_vk) + next_tx_subfulfillment2 = cc.Ed25519Fulfillment(public_key=other1_vk) next_tx_subfulfillment2.sign(next_tx_fulfillment_message, crypto.SigningKey(other1_sk)) next_tx_fulfillment.add_subfulfillment(next_tx_subfulfillment2) next_tx['transaction']['fulfillments'][0]['fulfillment'] = next_tx_fulfillment.serialize_uri() @@ -1443,9 +1441,9 @@ class TestCryptoconditions(object): assert len(tx['transaction']['conditions'][0]['condition']['details']['subfulfillments']) == 2 # expected condition subfulfillments - expected_condition = ThresholdSha256Fulfillment(threshold=2) - expected_condition.add_subfulfillment(Ed25519Fulfillment(public_key=user_vk)) - expected_condition.add_subfulfillment(Ed25519Fulfillment(public_key=user2_vk)) + expected_condition = cc.ThresholdSha256Fulfillment(threshold=2) + expected_condition.add_subfulfillment(cc.Ed25519Fulfillment(public_key=user_vk)) + expected_condition.add_subfulfillment(cc.Ed25519Fulfillment(public_key=user2_vk)) tx_expected_condition = { 'details': json.loads(expected_condition.serialize_json()), 'uri': expected_condition.condition.serialize_uri() @@ -1469,7 +1467,7 @@ class TestCryptoconditions(object): tx_transfer_signed = b.sign_transaction(tx_transfer, [user_sk, user2_sk]) # expected fulfillment - expected_fulfillment = Fulfillment.from_json(tx_create['transaction']['conditions'][0]['condition']['details']) + expected_fulfillment = cc.Fulfillment.from_json(tx_create['transaction']['conditions'][0]['condition']['details']) subfulfillment1 = expected_fulfillment.subconditions[0]['body'] subfulfillment2 = expected_fulfillment.subconditions[1]['body'] @@ -1493,7 +1491,8 @@ class TestCryptoconditions(object): # create a transaction with multiple new_owners tx = b.create_transaction(b.me, new_owners, None, 'CREATE') + condition = cc.Fulfillment.from_json(tx['transaction']['conditions'][0]['condition']['details']) for new_owner in new_owners: - subcondition = util.get_subcondition_from_vk(tx['transaction']['conditions'][0], new_owner) + subcondition = condition.get_subcondition_from_vk(new_owner)[0] assert subcondition.public_key.to_ascii().decode() == new_owner