zenroom fixes

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
This commit is contained in:
Jürgen Eckel 2022-04-07 09:00:55 +02:00
parent 5fd8bde123
commit b455434aac
5 changed files with 60 additions and 8 deletions

View File

@ -6,7 +6,8 @@
from functools import reduce from functools import reduce
import base58 import base58
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256 from cryptoconditions import ThresholdSha256, Ed25519Sha256, ZenroomSha256
from cryptoconditions import Fulfillment
from planetmint.transactions.common.exceptions import AmountError from planetmint.transactions.common.exceptions import AmountError
from .utils import _fulfillment_to_details, _fulfillment_from_details from .utils import _fulfillment_to_details, _fulfillment_from_details
@ -70,6 +71,7 @@ class Output(object):
# and fulfillment! # and fulfillment!
condition = {} condition = {}
try: try:
# TODO verify if a script is returned in case of zenroom fulfillments
condition['details'] = _fulfillment_to_details(self.fulfillment) condition['details'] = _fulfillment_to_details(self.fulfillment)
except AttributeError: except AttributeError:
pass pass
@ -123,6 +125,9 @@ class Output(object):
elif len(public_keys) == 1 and not isinstance(public_keys[0], list): elif len(public_keys) == 1 and not isinstance(public_keys[0], list):
if isinstance(public_keys[0], Fulfillment): if isinstance(public_keys[0], Fulfillment):
ffill = public_keys[0] ffill = public_keys[0]
elif isinstance( public_keys[0], Fulfillment.ZenroomSha512Fulfillment):
ffill = ZenroomSha256(
public_key=base58.b58decode(public_keys[0]))
else: else:
ffill = Ed25519Sha256( ffill = Ed25519Sha256(
public_key=base58.b58decode(public_keys[0])) public_key=base58.b58decode(public_keys[0]))

View File

@ -100,8 +100,8 @@ definitions:
uri: uri:
type: string type: string
pattern: "^ni:///sha-256;([a-zA-Z0-9_-]{0,86})[?]\ pattern: "^ni:///sha-256;([a-zA-Z0-9_-]{0,86})[?]\
(fpt=(ed25519|threshold)-sha-256(&)?|cost=[0-9]+(&)?|\ (fpt=(ed25519|threshold|zenroom)-sha-256(&)?|cost=[0-9]+(&)?|\
subtypes=ed25519-sha-256(&)?){2,3}$" subtypes=(ed25519|zenroom)-sha-256(&)?){2,3}$"
public_keys: public_keys:
"$ref": "#/definitions/public_keys" "$ref": "#/definitions/public_keys"
input: input:
@ -147,7 +147,7 @@ definitions:
properties: properties:
type: type:
type: string type: string
pattern: "^ed25519-sha-256$" pattern: "^(ed25519|zenroom)-sha-256$"
public_key: public_key:
"$ref": "#/definitions/base58" "$ref": "#/definitions/base58"
- type: object - type: object

View File

@ -17,7 +17,7 @@ from functools import lru_cache
import rapidjson import rapidjson
import base58 import base58
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256 from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256, ZenroomSha256
from cryptoconditions.exceptions import ( from cryptoconditions.exceptions import (
ParsingError, ASN1DecodeError, ASN1EncodeError) ParsingError, ASN1DecodeError, ASN1EncodeError)
try: try:
@ -235,6 +235,7 @@ class Transaction(object):
currently: currently:
- Ed25519Fulfillment - Ed25519Fulfillment
- ThresholdSha256 - ThresholdSha256
- ZenroomSha256
Furthermore, note that all keys required to fully sign the Furthermore, note that all keys required to fully sign the
Transaction have to be passed to this method. A subset of all Transaction have to be passed to this method. A subset of all
will cause this method to fail. will cause this method to fail.
@ -289,7 +290,7 @@ class Transaction(object):
currently: currently:
- Ed25519Fulfillment - Ed25519Fulfillment
- ThresholdSha256. - ThresholdSha256.
- ZenroomSha256
Args: Args:
input_ (:class:`~planetmint.transactions.common.transaction. input_ (:class:`~planetmint.transactions.common.transaction.
Input`) The Input to be signed. Input`) The Input to be signed.
@ -302,11 +303,46 @@ class Transaction(object):
elif isinstance(input_.fulfillment, ThresholdSha256): elif isinstance(input_.fulfillment, ThresholdSha256):
return cls._sign_threshold_signature_fulfillment(input_, message, return cls._sign_threshold_signature_fulfillment(input_, message,
key_pairs) key_pairs)
elif isinstance(input_.fulfillment, ZenroomSha256):
return cls._sign_threshold_signature_fulfillment(input_, message,
key_pairs)
else: else:
raise ValueError( raise ValueError(
'Fulfillment couldn\'t be matched to ' 'Fulfillment couldn\'t be matched to '
'Cryptocondition fulfillment type.') 'Cryptocondition fulfillment type.')
@classmethod
def _sign_zenroom_fulfillment(cls, input_, message, key_pairs):
"""Signs a Zenroomful.
Args:
input_ (:class:`~planetmint.transactions.common.transaction.
Input`) The input to be signed.
message (str): The message to be signed
key_pairs (dict): The keys to sign the Transaction with.
"""
# NOTE: To eliminate the dangers of accidentally signing a condition by
# reference, we remove the reference of input_ here
# intentionally. If the user of this class knows how to use it,
# this should never happen, but then again, never say never.
input_ = deepcopy(input_)
public_key = input_.owners_before[0]
message = sha3_256(message.encode())
if input_.fulfills:
message.update('{}{}'.format(
input_.fulfills.txid, input_.fulfills.output).encode())
try:
# cryptoconditions makes no assumptions of the encoding of the
# message to sign or verify. It only accepts bytestrings
input_.fulfillment.sign(
message.digest(), base58.b58decode(key_pairs[public_key].encode()))
except KeyError:
raise KeypairMismatchException('Public key {} is not a pair to '
'any of the private keys'
.format(public_key))
return input_
@classmethod @classmethod
def _sign_simple_signature_fulfillment(cls, input_, message, key_pairs): def _sign_simple_signature_fulfillment(cls, input_, message, key_pairs):
"""Signs a Ed25519Fulfillment. """Signs a Ed25519Fulfillment.

View File

@ -191,6 +191,12 @@ def _fulfillment_to_details(fulfillment):
'threshold': fulfillment.threshold, 'threshold': fulfillment.threshold,
'subconditions': subconditions, 'subconditions': subconditions,
} }
if fulfillment.type_name == 'zenroom-sha-256':
return {
'type': 'zenroom-sha-256',
'public_key': base58.b58encode(fulfillment.public_key).decode(),
'script': base58.b58encode(fulfillment.script).decode(),
}
raise UnsupportedTypeError(fulfillment.type_name) raise UnsupportedTypeError(fulfillment.type_name)
@ -215,4 +221,9 @@ def _fulfillment_from_details(data, _depth=0):
threshold.add_subfulfillment(cond) threshold.add_subfulfillment(cond)
return threshold return threshold
if data['type'] == 'zenroom-sha-256':
public_key = base58.b58decode(data['public_key'])
script = base58.b58decode(data['script'])
zenroom = ZenroomSha256( script= script, data=None , keys= {public_key})
raise UnsupportedTypeError(data.get('type')) raise UnsupportedTypeError(data.get('type'))

View File

@ -89,7 +89,7 @@ install_requires = [
'pymongo==3.11.4', 'pymongo==3.11.4',
'python-rapidjson==1.0', 'python-rapidjson==1.0',
'pyyaml==5.4.1', 'pyyaml==5.4.1',
'requests==2.25.1', 'requests>=2.25.1',
'setproctitle==1.2.2', 'setproctitle==1.2.2',
'werkzeug==2.0.3', 'werkzeug==2.0.3',
] ]