[#40] Client: Add memory optimization for hash

Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
Pavel Gross 2025-03-11 22:56:28 +03:00
parent 32a7e64538
commit 809bd90352
17 changed files with 170 additions and 64 deletions

View file

@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Security.Cryptography;
using FrostFS.Refs;
@ -13,7 +14,7 @@ using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using Signature = FrostFS.Refs.Signature;
namespace FrostFS.SDK.Client;
@ -74,7 +75,7 @@ public static class RequestSigner
};
}
public static ByteString SignData(this ECDsa key, byte[] data)
public static ByteString SignData(this ECDsa key, ReadOnlyMemory<byte> data)
{
if (key is null)
{
@ -84,27 +85,61 @@ public static class RequestSigner
Span<byte> result = stackalloc byte[65];
result[0] = 0x04;
//var hash = new byte[65];
//hash[0] = 0x04;
key.SignHash(data.Sha512()).AsSpan().CopyTo(result[1..]);
return ByteString.CopyFrom(result);
}
internal static Signature SignMessagePart(this ECDsa key, IMessage? data)
public static ByteString SignDataByHash(this ECDsa key, byte[] hash)
{
var data2Sign = data is null ? [] : data.ToByteArray();
if (key is null)
{
throw new ArgumentNullException(nameof(key));
}
Span<byte> result = stackalloc byte[65];
result[0] = 0x04;
key.SignHash(hash).AsSpan().CopyTo(result[1..]);
return ByteString.CopyFrom(result);
}
internal static Signature SignMessagePart(this ClientKey key, IMessage? data)
{
if (data is null)
{
return new Signature
{
Key = key.PublicKeyProto,
Sign = key.ECDsaKey.SignData(ReadOnlyMemory<byte>.Empty),
};
}
var size = data.CalculateSize();
if (size == 0)
{
return new Signature
{
Key = key.PublicKeyProto,
Sign = key.ECDsaKey.SignData(ReadOnlyMemory<byte>.Empty),
};
}
using HashStream stream = new();
data.WriteTo(stream);
var sig = new Signature
{
Key = ByteString.CopyFrom(key.PublicKey()),
Sign = key.SignData(data2Sign),
Key = key.PublicKeyProto,
Sign = key.ECDsaKey.SignDataByHash(stream.Hash())
};
return sig;
}
internal static void Sign(this IVerifiableMessage message, ECDsa key)
internal static void Sign(this IVerifiableMessage message, ClientKey key)
{
var meta = message.GetMetaHeader();
IVerificationHeader verify = message switch