# Path: ejtp/util/hasher.py
# @StringDecorator()
# @StringDecorator(args=False, ret=True, strict=True)
# def strict(obj=None):
#     ''' Convert an object into a strict JSON string '''
#     if isinstance(obj, bool) or obj==None or isinstance(obj, int):
#         return json.dumps(obj)
#     if isinstance(obj, String):
#         return json.dumps(obj.export())
#     if isinstance(obj, RawData):
#         obj = tuple(obj)
#     if isinstance(obj, list) or isinstance(obj, tuple):
#         return "[%s]" % ",".join([strict(x).export() for x in obj])
#     if isinstance(obj, dict):
#         strdict = {}
#         for key in obj:
#             strdict[key] = obj[key]
#         keys = sorted(strdict.keys())
#         return "{%s}" % ",".join([strict(key).export()+":"+strict(strdict[key]).export() for key in keys])


from persei import String, RawDataDecorator, StringDecorator
from ejtp.util.hasher import strict
from Crypto.Hash import SHA256 as hashclass
        from . import rotate
        from . import aes
        from . import rsa
        from . import ecc
import streql
        import json
        # where your public key and private key are different.
        return self.proto()

    def is_public(self):
        return self.proto() == self.public()

    def can_encrypt(self):
        '''
        Is this encryptor capable of encryption?

        By default, assumes true. Override where this is not guaranteed.
        '''
        return True

    @RawDataDecorator(strict=True)
    def hash_obj(self, plaintext):
        '''
        Produces a Crypto.Hash object.
        '''
        h = hashclass.new()
        h.update(plaintext.export())
        return h

    @RawDataDecorator(ret=True, strict=True)
    def hash(self, plaintext):
        '''
        Produces a binary SHA-256 hash.
        '''
        return self.hash_obj(plaintext.export()).digest()


# Path: ejtp/util/hasher.py
# @StringDecorator()
# @StringDecorator(args=False, ret=True, strict=True)
# def strict(obj=None):
#     ''' Convert an object into a strict JSON string '''
#     if isinstance(obj, bool) or obj==None or isinstance(obj, int):
#         return json.dumps(obj)
#     if isinstance(obj, String):
#         return json.dumps(obj.export())
#     if isinstance(obj, RawData):
#         obj = tuple(obj)
#     if isinstance(obj, list) or isinstance(obj, tuple):
#         return "[%s]" % ",".join([strict(x).export() for x in obj])
#     if isinstance(obj, dict):
#         strdict = {}
#         for key in obj:
#             strdict[key] = obj[key]
#         keys = sorted(strdict.keys())
#         return "{%s}" % ",".join([strict(key).export()+":"+strict(strdict[key]).export() for key in keys])


# Path: ejtp/crypto/encryptor.py
from persei import String, RawDataDecorator, StringDecorator
from ejtp.util.hasher import strict
from Crypto.Hash import SHA256 as hashclass
        from . import rotate
        from . import aes
        from . import rsa
        from . import ecc
import streql
        import json

        # where your public key and private key are different.
        return self.proto()

    def is_public(self):
        return self.proto() == self.public()

    def can_encrypt(self):
        '''
        Is this encryptor capable of encryption?

        By default, assumes true. Override where this is not guaranteed.
        '''
        return True

    @RawDataDecorator(strict=True)
    def hash_obj(self, plaintext):
        '''
        Produces a Crypto.Hash object.
        '''
        h = hashclass.new()
        h.update(plaintext.export())
        return h

    @RawDataDecorator(ret=True, strict=True)
    def hash(self, plaintext):
        '''
        Produces a binary SHA-256 hash.
        '''
        return self.hash_obj(plaintext.export()).digest()


    @RawDataDecorator(ret=True, strict=True)