Example #1
0
    def test_ilp_keys(self, sk_ilp, vk_ilp):
        sk = SigningKey(sk_ilp['b58'])
        assert sk.encode(encoding='base64') == sk_ilp['b64']
        assert binascii.hexlify(
            sk.encode(encoding='bytes')[:32]) == sk_ilp['hex']

        vk = VerifyingKey(vk_ilp['b58'])
        assert vk.encode(encoding='base64') == vk_ilp['b64']
        assert binascii.hexlify(vk.encode(encoding='bytes')) == vk_ilp['hex']
 def test_to_bytes(self, sk_ilp, vk_ilp):
     sk = SigningKey(sk_ilp['b58'])
     assert sk.encode(encoding='base58') == sk_ilp['b58']
     assert sk.encode(encoding='base64') == sk_ilp['b64']
     vk = VerifyingKey(vk_ilp['b58'])
     assert vk.encode(encoding='base58') == vk_ilp['b58']
     assert vk.encode(encoding='base64') == vk_ilp['b64']
Example #3
0
 def test_to_bytes(self, sk_ilp, vk_ilp):
     sk = SigningKey(sk_ilp['b58'])
     assert sk.encode(encoding='base58') == sk_ilp['b58']
     assert sk.encode(encoding='base64') == sk_ilp['b64']
     vk = VerifyingKey(vk_ilp['b58'])
     assert vk.encode(encoding='base58') == vk_ilp['b58']
     assert vk.encode(encoding='base64') == vk_ilp['b64']
 def test_valid_condition_invalid_signature_ilp(self, vk_ilp, signature):
     vk = VerifyingKey(
         VerifyingKey.encode(
             base64_add_padding(vk_ilp[2]['b64'])))
     msg = base64.b64decode(signature['msg'])
     assert vk.verify(msg, signature['msg'], encoding='base64') is False
     assert vk.verify(msg, binascii.hexlify(base64.b64decode(signature['msg'])), encoding='hex') is False
     assert vk.verify(msg, base64.b64decode(signature['msg']), encoding=None) is False
 def test_sign_verify(self, sk_ilp, vk_ilp):
     message = 'Hello World!'
     sk = SigningKey(sk_ilp['b58'])
     vk = VerifyingKey(vk_ilp['b58'])
     assert vk.verify(message, sk.sign(message)) is True
     assert vk.verify(message, sk.sign(message + 'dummy')) is False
     assert vk.verify(message + 'dummy', sk.sign(message)) is False
     vk = VerifyingKey(
         VerifyingKey.encode(
             base64_add_padding(vk_ilp[2]['b64'])))
     assert vk.verify(message, sk.sign(message)) is False
 def test_generate_sign_verify(self, vk_ilp):
     sk_b58, vk_b58 = ed25519_generate_key_pair()
     sk = SigningKey(sk_b58)
     vk = VerifyingKey(vk_b58)
     message = 'Hello World!'
     assert vk.verify(message, sk.sign(message)) is True
     assert vk.verify(message, sk.sign(message + 'dummy')) is False
     assert vk.verify(message + 'dummy', sk.sign(message)) is False
     vk = VerifyingKey(
         VerifyingKey.encode(
             base64_add_padding(vk_ilp[2]['b64'])))
     assert vk.verify(message, sk.sign(message)) is False
 def test_get_verifying_key(self, sk_ilp, vk_ilp):
     sk = SigningKey(sk_ilp['b58'])
     vk = VerifyingKey(vk_ilp['b58'])
     vk_from_sk = sk.get_verifying_key()
     assert vk.encode(encoding='bytes') == vk_from_sk.encode(encoding='bytes')
 def test_verifying_key_decode(self, vk_ilp):
     vk = VerifyingKey(vk_ilp['b58'])
     public_value = vk.encode(encoding='base64')
     assert public_value == vk_ilp['b64']
 def test_verifying_key_init(self, vk_ilp):
     vk = VerifyingKey(vk_ilp['b58'])
     assert vk.encode(encoding='base64') == vk_ilp['b64']
     assert vk.encode(encoding='bytes') == vk_ilp['byt']
Example #10
0
class Ed25519Fulfillment(Fulfillment):
    """ """

    TYPE_ID = 4
    FEATURE_BITMASK = 0x20
    PUBKEY_LENGTH = 32
    SIGNATURE_LENGTH = 64
    FULFILLMENT_LENGTH = PUBKEY_LENGTH + SIGNATURE_LENGTH

    def __init__(self, public_key=None):
        """
        ED25519: Ed25519 signature condition.

        This condition implements Ed25519 signatures.

        ED25519 is assigned the type ID 4. It relies only on the ED25519 feature suite
        which corresponds to a bitmask of 0x20.

        Args:
            public_key (VerifyingKey): Ed25519 publicKey
        """
        if public_key and isinstance(public_key, (str, bytes)):
            public_key = VerifyingKey(public_key)
        if public_key and not isinstance(public_key, VerifyingKey):
            raise TypeError
        self.public_key = public_key
        self.signature = None

    def write_common_header(self, writer):
        """
        Write static header fields.

        Some fields are common between the hash and the fulfillment payload. This
        method writes those field to anything implementing the Writer interface.
        It is used internally when generating the hash of the condition, when
        generating the fulfillment payload and when calculating the maximum fulfillment size.

        Args:
            writer (Writer, Hasher, Predictor): Target for outputting the header.
        """
        writer.write_var_octet_string(self.public_key)

    def sign(self, message, private_key):
        """
        Sign the message.

        This method will take the currently configured values for the message
        prefix and suffix and create a signature using the provided Ed25519 private key.

        Args:
            message (bytes): message to be signed
            private_key (:obj:`Ed25519SigningKey`) Ed25519 private key
        """
        sk = private_key
        vk = sk.get_verifying_key()

        self.public_key = vk

        # This would be the Ed25519ph version (JavaScript ES7):
        # const message = crypto.createHash('sha512')
        #   .update(Buffer.concat([this.messagePrefix, this.message]))
        #   .digest()

        self.signature = sk.sign(message, encoding='bytes')

    def generate_hash(self):
        """
        Generate the condition hash.

        Since the public key is the same size as the hash we'd be putting out here,
        we just return the public key.
        """
        if not self.public_key:
            raise ValueError('Requires a public publicKey')
        return self.public_key.encode(encoding='bytes')

    def parse_payload(self, reader, *args):
        """
        Parse the payload of an Ed25519 fulfillment.

        Read a fulfillment payload from a Reader and populate this object with that fulfillment.

        Args:
            reader (Reader): Source to read the fulfillment payload from.
        """
        self.public_key = VerifyingKey(
            base58.b58encode(
                reader.read_octet_string(Ed25519Fulfillment.PUBKEY_LENGTH)))
        self.signature = reader.read_octet_string(
            Ed25519Fulfillment.SIGNATURE_LENGTH)

    def write_payload(self, writer):
        """
        Generate the fulfillment payload.

        This writes the fulfillment payload to a Writer.

        FULFILLMENT_PAYLOAD =
            VARBYTES PUBLIC_KEY
            VARBYTES SIGNATURE

        Args:
            writer (Writer): Subject for writing the fulfillment payload.
        """
        writer.write_octet_string(self.public_key.encode(encoding='bytes'),
                                  Ed25519Fulfillment.PUBKEY_LENGTH)
        writer.write_octet_string(self.signature,
                                  Ed25519Fulfillment.SIGNATURE_LENGTH)
        return writer

    def calculate_max_fulfillment_length(self):
        return Ed25519Fulfillment.FULFILLMENT_LENGTH

    def to_dict(self):
        """
        Generate a dict of the fulfillment

        Returns:
            dict: representing the fulfillment
        """
        return {
            'type':
            'fulfillment',
            'type_id':
            self.TYPE_ID,
            'bitmask':
            self.bitmask,
            'public_key':
            self.public_key.encode(encoding='base58').decode(),
            'signature':
            base58.b58encode(self.signature) if self.signature else None
        }

    def parse_dict(self, data):
        """
        Generate fulfillment payload from a dict

        Args:
            data (dict): description of the fulfillment

        Returns:
            Fulfillment
        """
        self.public_key = VerifyingKey(data['public_key'])
        self.signature = base58.b58decode(
            data['signature']) if data['signature'] else None

    def validate(self, message=None, **kwargs):
        """
        Verify the signature of this Ed25519 fulfillment.

        The signature of this Ed25519 fulfillment is verified against the provided message and public key.

        Args:
            message (str): Message to validate against.

        Return:
            boolean: Whether this fulfillment is valid.
        """
        if not (message and self.signature):
            return False

        return self.public_key.verify(message,
                                      self.signature,
                                      encoding='bytes')
Example #11
0
 def test_get_verifying_key(self, sk_ilp, vk_ilp):
     sk = SigningKey(sk_ilp['b58'])
     vk = VerifyingKey(vk_ilp['b58'])
     vk_from_sk = sk.get_verifying_key()
     assert vk.encode(encoding='bytes') == vk_from_sk.encode(
         encoding='bytes')
Example #12
0
 def test_verifying_key_decode(self, vk_ilp):
     vk = VerifyingKey(vk_ilp['b58'])
     public_value = vk.encode(encoding='base64')
     assert public_value == vk_ilp['b64']
Example #13
0
 def test_verifying_key_init(self, vk_ilp):
     vk = VerifyingKey(vk_ilp['b58'])
     assert vk.encode(encoding='base64') == vk_ilp['b64']
     assert vk.encode(encoding='bytes') == vk_ilp['byt']
Example #14
0
 def test_generate_key_pair(self):
     sk_b58, vk_b58 = ed25519_generate_key_pair()
     assert len(base58.b58decode(sk_b58)) == 32
     assert len(base58.b58decode(vk_b58)) == 32
     assert SigningKey.encode(SigningKey.decode(sk_b58)) == sk_b58
     assert VerifyingKey.encode(VerifyingKey.decode(vk_b58)) == vk_b58
Example #15
0
 def test_verifying_key_encode(self, vk_ilp):
     public_value_base58 = VerifyingKey.encode(base64_add_padding(vk_ilp['b64']))
     assert public_value_base58 == vk_ilp['b58']