import ecdsa from hashlib import sha256, sha512 from google.protobuf.message import Message from frostfs_sdk.client.models.ecdsa_model import ECDSA from frostfs_sdk.protos.models.refs.types_pb2 import SignatureRFC6979, Signature class Signer: @staticmethod def sign_message_rfc_6979(key: ECDSA, message: Message) -> SignatureRFC6979: return SignatureRFC6979( key=key.public_key, sign=Signer.sign_rfc6979(key.private_key, message.SerializeToString()) ) @staticmethod def sign_rfc6979(private_key: bytes, message: bytes) -> bytes: if len(private_key) == 0 or private_key is None: raise ValueError(f"Incorrect private_key: {private_key}") sk = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.NIST256p, hashfunc=sha256) signature = sk.sign_deterministic(message) return signature @staticmethod def sign_message(key: ECDSA, message: Message) -> SignatureRFC6979: return SignatureRFC6979( key=key.public_key, sign=Signer.sign(key.private_key, message.SerializeToString()) ) @staticmethod def sign(private_key: bytes, message: bytes) -> bytes: if len(private_key) == 0 or private_key is None: raise ValueError(f"Incorrect private key: {private_key}") sk = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.NIST256p, hashfunc=sha512) signature = sk.sign(message) # the first byte indicates the node version marker signature_with_marker = bytes([0x04]) + signature return signature_with_marker @staticmethod def _sign_message_part(key: ECDSA, data: Message) -> Signature: return Signature( key=key.public_key, sign=Signature.sign(key.private_key, data.SerializeToString()) )