/// <inheritdoc />
        public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, ReadOnlySpan <byte> domain = default)
        {
            if (signature.Length != SignatureLength)
            {
                throw new ArgumentOutOfRangeException(nameof(signature), signature.Length, $"Signature must be {SignatureLength} bytes long.");
            }

            EnsureInitialised();
            EnsurePublicKey();

            Bls384Interop.BlsPublicKey blsPublicKey;
            int publicKeyBytesRead;

            unsafe
            {
                fixed(byte *publicKeyPtr = _publicKey)
                {
                    publicKeyBytesRead = Bls384Interop.PublicKeyDeserialize(out blsPublicKey, publicKeyPtr, _publicKey !.Length);
                }
            }
            if (publicKeyBytesRead != _publicKey.Length)
            {
                throw new Exception($"Error deserializing BLS public key, length: {publicKeyBytesRead}");
            }

            Bls384Interop.BlsSignature blsSignature;
            int signatureBytesRead;

            unsafe
            {
                fixed(byte *signaturePtr = signature)
                {
                    signatureBytesRead = Bls384Interop.SignatureDeserialize(out blsSignature, signaturePtr, SignatureLength);
                }
            }
            if (signatureBytesRead != signature.Length)
            {
                throw new Exception($"Error deserializing BLS signature, length: {signatureBytesRead}");
            }

            int result;

            if (domain.Length > 0)
            {
                if (hash.Length != HashLength)
                {
                    throw new ArgumentOutOfRangeException(nameof(hash), hash.Length, $"Hash with domain must be {HashLength} bytes long.");
                }
                if (domain.Length != DomainLength)
                {
                    throw new ArgumentOutOfRangeException(nameof(domain), domain.Length, $"Domain must be {DomainLength} bytes long.");
                }

                var hashWithDomain = new Span <byte>(new byte[HashLength + DomainLength]);
                hash.CopyTo(hashWithDomain);
                domain.CopyTo(hashWithDomain.Slice(HashLength));

                unsafe
                {
                    fixed(byte *hashPtr = hashWithDomain)
                    {
                        result = Bls384Interop.VerifyHashWithDomain(blsSignature, blsPublicKey, hashPtr);
                    }
                }
            }
            else
            {
                unsafe
                {
                    fixed(byte *hashPtr = hash)
                    {
                        result = Bls384Interop.VerifyHash(blsSignature, blsPublicKey, hashPtr, hash.Length);
                    }
                }
            }

            return(result == 1);
        }