Source code for transparentmeta.crypto.signer

# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (c) 2025 Transparent Audio
# Author: Valerio Velardo - valerio@transparentaudio.ai

"""
This module provides a `Signer` class that enables signing messages using
the Ed25519 cryptographic algorithm. It supports different character
encodings for message conversion before signing.
"""

import logging

from cryptography.hazmat.primitives.asymmetric import ed25519

from transparentmeta.crypto.character_encoding import CharacterEncoding
from transparentmeta.utils.encoding_utils import (
    decode_bytes_to_hexadecimal_string,
    encode_string_to_bytes,
)

logger = logging.getLogger(__name__)


[docs] class Signer: """A utility class for digitally signing messages using the Ed25519 cryptographic algorithm. Attributes: private_key (ed25519.Ed25519PrivateKey): The private key used for signing messages. character_encoding (CharacterEncoding): The encoding used for converting strings to bytes before signing. """
[docs] def __init__( self, private_key: ed25519.Ed25519PrivateKey, character_encoding: CharacterEncoding = CharacterEncoding.UTF8, ) -> None: """Initializes the signer with a private key and a character encoding. Args: private_key (ed25519.Ed25519PrivateKey): The private key for signing messages. character_encoding (CharacterEncoding): The encoding used for converting strings to bytes before signing. """ self.private_key = private_key self.character_encoding = character_encoding
[docs] def sign(self, message: str) -> str: """Signs a message using Ed25519 and returns a hex-encoded signature. Args: message (str): The message to sign. Returns: str: Hex-encoded digital signature. """ signature_bytes = self._sign(message) signature = self._decode_signature(signature_bytes) logger.debug( "Signed message '%.40s' with signature: '%s'", message, signature, ) return signature
def _sign(self, message: str) -> bytes: message_bytes = encode_string_to_bytes( message, self.character_encoding.value ) signature_bytes = self.private_key.sign(message_bytes) return signature_bytes def _decode_signature(self, signature_bytes: bytes) -> str: return decode_bytes_to_hexadecimal_string( signature_bytes, self.character_encoding.value )