[#16] Remove Tz fix formating #17

Merged
PavelGrossSpb merged 1 commit from PavelGrossSpb/frostfs-sdk-csharp:Refactoring into master 2024-07-16 07:27:56 +00:00
15 changed files with 123 additions and 723 deletions

View file

@ -111,13 +111,16 @@ internal class NetmapServiceProvider : ContextAccessor
var valueBytes = param.Value.ToByteArray(); var valueBytes = param.Value.ToByteArray();
switch (key) switch (key)
{ {
case "AuditFee": settings.AuditFee = GetLongValue(valueBytes); break;
case "BasicIncomeRate": settings.BasicIncomeRate = GetLongValue(valueBytes); break;
case "ContainerFee": settings.ContainerFee = GetLongValue(valueBytes); break; case "ContainerFee": settings.ContainerFee = GetLongValue(valueBytes); break;
case "ContainerAliasFee": settings.ContainerAliasFee = GetLongValue(valueBytes); break;
case "EpochDuration": settings.EpochDuration = GetLongValue(valueBytes); break; case "EpochDuration": settings.EpochDuration = GetLongValue(valueBytes); break;
case "IRCandidateFee": settings.IRCandidateFee = GetLongValue(valueBytes); break; case "InnerRingCandidateFee": settings.InnerRingCandidateFee = GetLongValue(valueBytes); break;
case "MaxECDataCount": settings.MaxECDataCount = GetLongValue(valueBytes); break; case "MaxECDataCount": settings.MaxECDataCount = GetLongValue(valueBytes); break;
case "MaxECParityCount": settings.MaxECParityCount = GetLongValue(valueBytes); break; case "MaxECParityCount": settings.MaxECParityCount = GetLongValue(valueBytes); break;
case "MaxObjectSize": settings.MaxObjectSize = GetLongValue(valueBytes); break; case "MaxObjectSize": settings.MaxObjectSize = GetLongValue(valueBytes); break;
case "WithdrawalFee": settings.WithdrawalFee = GetLongValue(valueBytes); break; case "WithdrawFee": settings.WithdrawFee = GetLongValue(valueBytes); break;
case "HomomorphicHashingDisabled": settings.HomomorphicHashingDisabled = GetBoolValue(valueBytes); break; case "HomomorphicHashingDisabled": settings.HomomorphicHashingDisabled = GetBoolValue(valueBytes); break;
case "MaintenanceModeAllowed": settings.MaintenanceModeAllowed = GetBoolValue(valueBytes); break; case "MaintenanceModeAllowed": settings.MaintenanceModeAllowed = GetBoolValue(valueBytes); break;
default: settings.UnnamedSettings.Add(key, valueBytes); break; default: settings.UnnamedSettings.Add(key, valueBytes); break;

View file

@ -73,52 +73,6 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
return await GetObject(request, ctx); return await GetObject(request, ctx);
} }
internal Task<ObjectId> PutObjectAsync(PutObjectParameters parameters, Context ctx)
{
if (parameters.Header == null)
throw new ArgumentException("Value cannot be null", nameof(parameters.Header));
if (parameters.Payload == null)
throw new ArgumentException("Value cannot be null", nameof(parameters.Payload));
if (parameters.ClientCut)
return PutClientCutObject(parameters, ctx);
else
return PutStreamObject(parameters, ctx);
}
internal async Task<ObjectId> PutSingleObjectAsync(FrostFsObject modelObject, Context ctx)
{
var sessionToken = await GetOrCreateSession(ctx);
var grpcObject = tools.CreateObject(modelObject);
var request = new PutSingleRequest
{
Body = new PutSingleRequest.Types.Body()
{
Object = grpcObject
}
};
request.AddMetaHeader();
request.AddObjectSessionToken(
sessionToken,
grpcObject.Header.ContainerId,
grpcObject.ObjectId,
ObjectSessionContext.Types.Verb.Put,
Context.Key
);
request.Sign(Context.Key);
var response = await client.PutSingleAsync(request, null, ctx.Deadline, ctx.CancellationToken);
Verifier.CheckResponse(response);
return ObjectId.FromHash(grpcObject.ObjectId.Value.ToByteArray());
}
internal async Task DeleteObjectAsync(ContainerId cid, ObjectId oid, Context ctx) internal async Task DeleteObjectAsync(ContainerId cid, ObjectId oid, Context ctx)
{ {
var request = new DeleteRequest var request = new DeleteRequest
@ -169,6 +123,52 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
} }
} }
internal Task<ObjectId> PutObjectAsync(PutObjectParameters parameters, Context ctx)
{
if (parameters.Header == null)
throw new ArgumentException("Value cannot be null", nameof(parameters.Header));
if (parameters.Payload == null)
throw new ArgumentException("Value cannot be null", nameof(parameters.Payload));
if (parameters.ClientCut)
return PutClientCutObject(parameters, ctx);
else
return PutStreamObject(parameters, ctx);
}
internal async Task<ObjectId> PutSingleObjectAsync(FrostFsObject modelObject, Context ctx)
{
var sessionToken = await GetOrCreateSession(ctx);
var grpcObject = tools.CreateObject(modelObject);
var request = new PutSingleRequest
{
Body = new PutSingleRequest.Types.Body()
{
Object = grpcObject
}
};
request.AddMetaHeader();
request.AddObjectSessionToken(
sessionToken,
grpcObject.Header.ContainerId,
grpcObject.ObjectId,
ObjectSessionContext.Types.Verb.Put,
Context.Key
);
request.Sign(Context.Key);
var response = await client.PutSingleAsync(request, null, ctx.Deadline, ctx.CancellationToken);
Verifier.CheckResponse(response);
return ObjectId.FromHash(grpcObject.ObjectId.Value.ToByteArray());
}
private async Task<ObjectId> PutClientCutObject(PutObjectParameters parameters, Context ctx) private async Task<ObjectId> PutClientCutObject(PutObjectParameters parameters, Context ctx)
{ {
var payloadStream = parameters.Payload!; var payloadStream = parameters.Payload!;
@ -181,24 +181,36 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
var networkSettings = await Context.Client.GetNetworkSettingsAsync(ctx); var networkSettings = await Context.Client.GetNetworkSettingsAsync(ctx);
var partSize = (int)networkSettings.MaxObjectSize; var objectSize = (int)networkSettings.MaxObjectSize;
var buffer = new byte[partSize];
var fullLength = header.PayloadLength;
if (payloadStream.CanSeek)
{
objectSize = (int)Math.Min(objectSize, payloadStream.Length);
if (fullLength == 0)
fullLength = (ulong)payloadStream.Length;
}
if (fullLength == 0)
throw new ArgumentException("Payload stream must be able to seek or PayloadLength must be specified");
var buffer = new byte[objectSize];
var largeObject = new LargeObject(header.ContainerId); var largeObject = new LargeObject(header.ContainerId);
var split = new Split(); var split = new Split();
var fullLength = (ulong)payloadStream.Length;
while (true) while (true)
{ {
var bytesCount = await payloadStream.ReadAsync(buffer, 0, partSize); var bytesCount = await payloadStream.ReadAsync(buffer, 0, objectSize);
split.Previous = sentObjectIds.LastOrDefault(); split.Previous = sentObjectIds.LastOrDefault();
largeObject.AppendBlock(buffer, bytesCount); largeObject.AppendBlock(buffer, bytesCount);
currentObject = new FrostFsObject(header.ContainerId, bytesCount < partSize ? buffer.Take(bytesCount).ToArray() : buffer) currentObject = new FrostFsObject(header.ContainerId, bytesCount < objectSize ? buffer[..bytesCount] : buffer)
.SetSplit(split); .SetSplit(split);
if (largeObject.PayloadLength == fullLength) if (largeObject.PayloadLength == fullLength)
@ -271,20 +283,31 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
using var stream = await PutObjectInit(initRequest, ctx); using var stream = await PutObjectInit(initRequest, ctx);
var buffer = new byte[Constants.ObjectChunkSize]; var bufferSize = parameters.BufferMaxSize > 0 ? parameters.BufferMaxSize : Constants.ObjectChunkSize;
if (payload.CanSeek)
{
bufferSize = (int)Math.Min(payload.Length, bufferSize);
}
else if (header.PayloadLength > 0)
{
bufferSize = (int)Math.Min((long)header.PayloadLength, bufferSize);
}
var buffer = new byte[bufferSize];
while (true) while (true)
{ {
var bufferLength = await payload.ReadAsync(buffer, 0, Constants.ObjectChunkSize, ctx.CancellationToken); var bytesCount = await payload.ReadAsync(buffer, 0, bufferSize, ctx.CancellationToken);
if (bufferLength == 0) if (bytesCount == 0)
break; break;
var chunkRequest = new PutRequest(initRequest) var chunkRequest = new PutRequest(initRequest)
{ {
Body = new PutRequest.Types.Body Body = new PutRequest.Types.Body
{ {
Chunk = ByteString.CopyFrom(buffer[..bufferLength]), Chunk = ByteString.CopyFrom(buffer[..bytesCount]),
}, },
VerifyHeader = null VerifyHeader = null
}; };

View file

@ -25,12 +25,8 @@ internal class ObjectTools(ClientEnvironment ctx) : ContextAccessor (ctx)
grpcHeader.OwnerId = Context.Owner.ToGrpcMessage(); grpcHeader.OwnerId = Context.Owner.ToGrpcMessage();
grpcHeader.Version = Context.Version.ToGrpcMessage(); grpcHeader.Version = Context.Version.ToGrpcMessage();
if (@object.Payload != null)
{
grpcHeader.PayloadLength = (ulong)@object.Payload.Length; grpcHeader.PayloadLength = (ulong)@object.Payload.Length;
grpcHeader.PayloadHash = Sha256Checksum(@object.Payload); grpcHeader.PayloadHash = Sha256Checksum(@object.Payload);
}
var split = @object.Header.Split; var split = @object.Header.Split;
if (split != null) if (split != null)

View file

@ -3,19 +3,19 @@ using System.Collections.Generic;
namespace FrostFS.SDK.ClientV2; namespace FrostFS.SDK.ClientV2;
public class NetworkSettings public class NetworkSettings
{ {
public ulong AuditFee { get; internal set; }
public ulong BasicIncomeRate { get; internal set; }
public ulong ContainerFee { get; internal set; } public ulong ContainerFee { get; internal set; }
public ulong ContainerAliasFee { get; internal set; } public ulong ContainerAliasFee { get; internal set; }
public ulong InnerRingCandidateFee { get; internal set; }
public ulong WithdrawFee { get; internal set; }
public ulong EpochDuration { get; internal set; } public ulong EpochDuration { get; internal set; }
public ulong IRCandidateFee { get; internal set; } public ulong InnerRingCandidateFee { get; internal set; }
public ulong MaxObjectSize { get; internal set; } public ulong MaxObjectSize { get; internal set; }
public ulong MaxECDataCount { get; internal set; } public ulong MaxECDataCount { get; internal set; }
public ulong MaxECParityCount { get; internal set; } public ulong MaxECParityCount { get; internal set; }
public ulong WithdrawalFee { get; internal set; } public ulong WithdrawFee { get; internal set; }
public bool HomomorphicHashingDisabled { get; internal set; } public bool HomomorphicHashingDisabled { get; internal set; }
public bool MaintenanceModeAllowed { get; internal set; } public bool MaintenanceModeAllowed { get; internal set; }
public Dictionary<string, object> UnnamedSettings { get; } = []; public Dictionary<string, object> UnnamedSettings { get; } = [];
} }

View file

@ -1,7 +1,5 @@
using Google.Protobuf; using Google.Protobuf;
using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Digests;
using System;
using System.Buffers.Binary;
using System.Security.Cryptography; using System.Security.Cryptography;
namespace FrostFS.SDK.Cryptography; namespace FrostFS.SDK.Cryptography;
@ -20,35 +18,11 @@ public static class Extentions
public static byte[] Sha256(this byte[] value) public static byte[] Sha256(this byte[] value)
{ {
using var sha256 = SHA256.Create(); var sha256 = SHA256.Create();
return sha256.ComputeHash(value); return sha256.ComputeHash(value);
} }
internal static byte[] Sha256(this byte[] value, int offset, int count)
{
using var sha256 = SHA256.Create();
return sha256.ComputeHash(value, offset, count);
}
internal static byte[] Sha256(this ReadOnlySpan<byte> value)
{
using var sha256 = SHA256.Create();
return sha256.ComputeHash(value.ToArray());
}
public static ByteString Sha256(this IMessage data) public static ByteString Sha256(this IMessage data)
{ {
return ByteString.CopyFrom(data.ToByteArray().Sha256()); return ByteString.CopyFrom(data.ToByteArray().Sha256());
} }
public static ByteString Sha256(this ByteString data)
{
return ByteString.CopyFrom(data.ToByteArray().Sha256());
}
public static ulong Murmur64(this byte[] value, uint seed)
{
using var murmur = new Murmur3_128(seed);
return BinaryPrimitives.ReadUInt64LittleEndian(murmur.ComputeHash(value));
}
} }

View file

@ -1,253 +0,0 @@
using System;
using System.Security.Cryptography;
namespace FrostFS.SDK.Cryptography.Tz;
// GF127 represents element of GF(2^127)
public class GF127 : IEquatable<GF127>
{
public const int ByteSize = 16;
public const ulong MSB64 = (ulong)1 << 63; // 2^63
public static readonly GF127 Zero = new(0, 0);
public static readonly GF127 One = new(1, 0);
public static readonly GF127 X127X631 = new(MSB64 + 1, MSB64); // x^127+x^63+1
private readonly ulong[] _data;
public ulong this[int index]
{
get { return _data[index]; }
set { _data[index] = value; }
}
public GF127(ulong[] value)
{
if (value is null || value.Length != 2)
throw new ArgumentException(nameof(value) + "is invalid");
_data = value;
}
// Constructs new element of GF(2^127) as u1*x^64 + u0.
// It is assumed that u1 has zero MSB.
public GF127(ulong u0, ulong u1) : this(new ulong[] { u0, u1 })
{
}
public GF127() : this(0, 0)
{
}
public override bool Equals(object obj)
{
if (obj is null)
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj is GF127 b)
return Equals(b);
return false;
}
public override int GetHashCode()
{
return this[0].GetHashCode() + this[1].GetHashCode();
}
public bool Equals(GF127 other)
{
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
return this[0] == other[0] && this[1] == other[1];
}
// return the index of MSB
private int IndexOfMSB()
{
int i = Helper.GetLeadingZeros(this[1]);
if (i == 64)
i += Helper.GetLeadingZeros(this[0]);
return 127 - i;
}
// Set index n to 1
public static GF127 SetN(int n)
{
if (n < 64)
return new GF127((ulong)1 << n, 0);
return new GF127(0, (ulong)1 << (n - 64));
}
// Add
public static GF127 operator +(GF127 a, GF127 b)
{
return new GF127(a[0] ^ b[0], a[1] ^ b[1]);
}
// Bitwise-and
public static GF127 operator &(GF127 a, GF127 b)
{
return new GF127(a[0] & b[0], a[1] & b[1]);
}
// Multiply
public static GF127 operator *(GF127 a, GF127 b) // 2^63 * 2, 10
{
GF127 r = new();
GF127 c = a;
if (b[1] == 0)
{
for (int i = 0; i < b[0].GetNonZeroLength(); i++)
{
if ((b[0] & ((ulong)1 << i)) != 0)
r += c;
c = Mul10(c); // c = c * 2
}
}
else
{
for (int i = 0; i < 64; i++)
{
if ((b[0] & ((ulong)1 << i)) != 0)
r += c;
c = Mul10(c); // c = c * 2
}
for (int i = 0; i < b[1].GetNonZeroLength(); i++)
{
if ((b[1] & ((ulong)1 << i)) != 0)
r += c;
c = Mul10(c);
}
}
return r;
}
// Inverse, returns a^-1
// Extended Euclidean Algorithm
// https://link.springer.com/content/pdf/10.1007/3-540-44499-8_1.pdf
public static GF127 Inv(GF127 a)
{
GF127 v = X127X631,
u = a,
c = new(1, 0),
d = new(0, 0),
t,
x;
int du = u.IndexOfMSB();
int dv = v.IndexOfMSB();
// degree of polynomial is a position of most significant bit
while (du != 0)
{
if (du < dv)
{
(v, u) = (u, v);
(dv, du) = (du, dv);
(d, c) = (c, d);
}
x = SetN(du - dv);
t = x * v;
u += t;
// because * performs reduction on t, manually reduce u at first step
if (u.IndexOfMSB() == 127)
u += X127X631;
t = x * d;
c += t;
du = u.IndexOfMSB();
dv = v.IndexOfMSB();
}
return c;
}
// Mul10 returns a*x
public static GF127 Mul10(GF127 a)
{
GF127 b = new();
var c = (a[0] & MSB64) >> 63;
b[0] = a[0] << 1;
b[1] = (a[1] << 1) ^ c;
if ((b[1] & MSB64) != 0)
{
b[0] ^= X127X631[0];
b[1] ^= X127X631[1];
}
return b;
}
// Mul11 returns a*(x+1)
public static GF127 Mul11(GF127 a)
{
GF127 b = new();
var c = (a[0] & MSB64) >> 63;
b[0] = a[0] ^ (a[0] << 1);
b[1] = a[1] ^ (a[1] << 1) ^ c;
if ((b[1] & MSB64) == 0) return b;
b[0] ^= X127X631[0];
b[1] ^= X127X631[1];
return b;
}
// Random returns random element from GF(2^127).
// Is used mostly for testing.
public static GF127 Random()
{
using RandomNumberGenerator rng = RandomNumberGenerator.Create();
return new GF127(rng.NextUlong(), rng.NextUlong() >> 1);
}
// FromByteArray does the deserialization stuff
public GF127 FromByteArray(byte[] data)
{
if (data.Length != ByteSize)
throw new ArgumentException(
nameof(data) + $" wrong data lenght, {nameof(GF127)} expect={ByteSize}, actual={data.Length}"
);
var t0 = new byte[8];
var t1 = new byte[8];
Array.Copy(data, 0, t1, 0, 8);
Array.Copy(data, 8, t0, 0, 8);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(t0);
Array.Reverse(t1);
}
_data[0] = BitConverter.ToUInt64(t0, 0);
_data[1] = BitConverter.ToUInt64(t1, 0);
if ((_data[1] & MSB64) != 0)
throw new ArgumentException(nameof(data) + " invalid data");
return this;
}
// ToArray() represents element of GF(2^127) as byte array of length 16.
public byte[] ToByteArray()
{
var buff = new byte[16];
var b0 = BitConverter.GetBytes(_data[0]);
var b1 = BitConverter.GetBytes(_data[1]);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(b0);
Array.Reverse(b1);
}
Array.Copy(b1, 0, buff, 0, 8);
Array.Copy(b0, 0, buff, 8, 8);
return buff;
}
// ToString() returns hex-encoded representation, starting with MSB.
public override string ToString()
{
return BitConverter.ToString(ToByteArray()).Replace("-", "");
}
}

View file

@ -1,30 +0,0 @@
using System;
using System.Security.Cryptography;
namespace FrostFS.SDK.Cryptography.Tz;
public static class Helper
{
public static ulong NextUlong(this RandomNumberGenerator rng)
{
var buff = new byte[8];
rng.GetBytes(buff);
return BitConverter.ToUInt64(buff, 0);
}
public static int GetLeadingZeros(ulong value)
{
var i = 64;
while (value != 0)
{
value >>= 1;
i--;
}
return i;
}
public static int GetNonZeroLength(this ulong value)
{
return 64 - GetLeadingZeros(value);
}
}

View file

@ -1,179 +0,0 @@
using System;
using System.Linq;
namespace FrostFS.SDK.Cryptography.Tz;
public class SL2 : IEquatable<SL2>
{
// 2x2 matrix
private readonly GF127[][] data;
public static readonly SL2 ID = new(
new GF127(1, 0), new GF127(0, 0), new GF127(0, 0), new GF127(1, 0));
public static readonly SL2 A = new(
new GF127(2, 0), new GF127(1, 0), new GF127(1, 0), new GF127(0, 0));
public static readonly SL2 B = new(
new GF127(2, 0), new GF127(3, 0), new GF127(1, 0), new GF127(1, 0));
// Indexer
public GF127[] this[int i]
{
get { return data[i]; }
set { data[i] = value; }
}
public SL2(GF127[][] value)
{
if (value is null || value.Length != 2 || !value.All(p => p.Length == 2))
throw new ArgumentException(nameof(value) + $" invalid {nameof(GF127)} matrics");
data = value;
}
public SL2(GF127 g00, GF127 g01, GF127 g10, GF127 g11)
: this([[g00, g01], [g10, g11]])
{
}
public SL2() : this(GF127.One, GF127.Zero, GF127.Zero, GF127.One)
{
}
public override bool Equals(object obj)
{
if (obj is null)
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj is SL2 b)
return Equals(b);
return false;
}
public override int GetHashCode()
{
return this[0][0].GetHashCode() +
this[0][1].GetHashCode() +
this[1][0].GetHashCode() +
this[1][1].GetHashCode();
}
public bool Equals(SL2 other)
{
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
return this[0][0].Equals(other[0][0]) &&
this[0][1].Equals(other[0][1]) &&
this[1][0].Equals(other[1][0]) &&
this[1][1].Equals(other[1][1]);
}
// 2X2 matrix multiplication
public static SL2 operator *(SL2 a, SL2 b)
{
return new SL2(
a[0][0] * b[0][0] + a[0][1] * b[1][0],
a[0][0] * b[0][1] + a[0][1] * b[1][1],
a[1][0] * b[0][0] + a[1][1] * b[1][0],
a[1][0] * b[0][1] + a[1][1] * b[1][1]);
}
// Multiplication using strassen algorithm
public static SL2 MulStrassen(SL2 a, SL2 b)
{
GF127[] t =
[
(a[0][0] + a[1][1]) * (b[0][0] + b[1][1]), // t[0] == (a11 + a22) * (b11 + b22)
(a[1][0] + a[1][1]) * b[0][0], // t[1] == (a21 + a22) * b11
(b[0][1] + b[1][1]) * a[0][0], // t[2] == (b12 + b22) * a11
(b[1][0] + b[0][0]) * a[1][1], // t[3] == (b21 + b11) * a22
(a[0][0] + a[0][1]) * b[1][1], // t[4] == (a11 + a12) * b22
(a[1][0] + a[0][0]) * (b[0][0] + b[0][1]), // t[5] == (a21 + a11) * (b11 + b12)
(a[0][1] + a[1][1]) * (b[1][0] + b[1][1]), // t[6] == (a12 + a22) * (b21 + b22)
];
SL2 r = new();
r[0][1] = t[2] + t[4]; // r12 == a11*b12 + a11*b22 + a11*b22 + a12*b22 == a11*b12 + a12*b22
r[1][0] = t[1] + t[3]; // r21 == a21*b11 + a22*b11 + a22*b21 + a22*b11 == a21*b11 + a22*b21
// r11 == (a11*b11 + a22*b11` + a11*b22` + a22*b22`) + (a22*b21` + a22*b11`) + (a11*b22` + a12*b22`) +
// (a12*b21 + a22*b21` + a12*b22` + a22*b22`) == a11*b11 + a12*b21
r[0][0] = t[0] + t[3] + t[4] + t[6];
// r22 == (a11*b11` + a22*b11` + a11*b22` + a22*b22) + (a21*b11` + a22*b11`) + (a11*b12` + a11*b22`) +
// (a21*b11` + a11*b11` + a21*b12 + a11*b12`) == a21*b12 + a22*b22
r[1][1] = t[0] + t[1] + t[2] + t[5];
return r;
}
// Inv() returns inverse of a in SL2(GF(2^127))
public static SL2 Inv(SL2 a)
{
GF127[] t = new GF127[2];
t[0] = a[0][0] * a[1][1] + a[0][1] * a[1][0];
t[1] = GF127.Inv(t[0]);
SL2 r = new();
r[1][1] = t[1] * a[0][0];
r[0][1] = t[1] * a[0][1];
r[1][0] = t[1] * a[1][0];
r[0][0] = t[1] * a[1][1];
return r;
}
// MulA() returns this*A, A = {{x, 1}, {1, 0}}
public SL2 MulA()
{
var r = new SL2();
r[0][0] = GF127.Mul10(this[0][0]) + this[0][1]; // r11 == t11*x + t12
r[0][1] = this[0][0]; // r12 == t11
r[1][0] = GF127.Mul10(this[1][0]) + this[1][1]; // r21 == t21*x + t22
r[1][1] = this[1][0]; // r22 == t21
return r;
}
// MulB() returns this*B, B = {{x, x+1}, {1, 1}}
public SL2 MulB()
{
var r = new SL2();
r[0][0] = GF127.Mul10(this[0][0]) + this[0][1]; // r11 == t11*x + t12
r[0][1] = GF127.Mul10(this[0][0]) + this[0][0] + this[0][1]; // r12 == t11*x + t11 + t12
r[1][0] = GF127.Mul10(this[1][0]) + this[1][1]; // r21 == t21*x + t22
r[1][1] = GF127.Mul10(this[1][0]) + this[1][0] + this[1][1]; // r22 == t21*x + t21 + t22
return r;
}
public SL2 FromByteArray(byte[] data)
{
if (data.Length != 64)
throw new ArgumentException(nameof(SL2) + $" invalid data, exect={64}, ecatual={data.Length}");
this[0][0] = new GF127().FromByteArray(data[0..16]);
this[0][1] = new GF127().FromByteArray(data[16..32]);
this[1][0] = new GF127().FromByteArray(data[32..48]);
this[1][1] = new GF127().FromByteArray(data[48..64]);
return this;
}
public byte[] ToByteArray()
{
var buff = new byte[64];
Array.Copy(this[0][0].ToByteArray(), 0, buff, 0, 16);
Array.Copy(this[0][1].ToByteArray(), 0, buff, 16, 16);
Array.Copy(this[1][0].ToByteArray(), 0, buff, 32, 16);
Array.Copy(this[1][1].ToByteArray(), 0, buff, 48, 16);
return buff;
}
public override string ToString()
{
return this[0][0].ToString() + this[0][1].ToString() +
this[1][0].ToString() + this[1][1].ToString();
}
}

View file

@ -1,140 +0,0 @@
//using System;
//using System.Collections.Generic;
//using System.Security;
//using System.Security.Cryptography;
//namespace FrostFS.SDK.Cryptography.Tz;
//public class TzHash : HashAlgorithm
//{
// private const int TzHashLength = 64;
// private GF127[] x;
// public override int HashSize => TzHashLength;
// public TzHash()
// {
// Initialize();
// }
// public override void Initialize()
// {
// x = new GF127[4];
// Reset();
// HashValue = null;
// }
// public void Reset()
// {
// x[0] = new GF127(1, 0);
// x[1] = new GF127(0, 0);
// x[2] = new GF127(0, 0);
// x[3] = new GF127(1, 0);
// }
// public byte[] ToByteArray()
// {
// var buff = new byte[HashSize];
// for (int i = 0; i < 4; i++)
// {
// Array.Copy(x[i].ToByteArray(), 0, buff, i * 16, 16);
// }
// return buff;
// }
// [SecurityCritical]
// protected override void HashCore(byte[] array, int ibStart, int cbSize)
// {
// _ = HashData(array[ibStart..(ibStart + cbSize)]);
// }
// [SecurityCritical]
// protected override byte[] HashFinal()
// {
// return HashValue = ToByteArray();
// }
// [SecurityCritical]
// private int HashData(byte[] data)
// {
// var n = data.Length;
// for (int i = 0; i < n; i++)
// {
// for (int j = 7; j >= 0; j--)
// {
// MulBitRight(ref x[0], ref x[1], ref x[2], ref x[3], (data[i] & (1 << j)) != 0);
// }
// }
// return n;
// }
// // MulBitRight() multiply A (if the bit is 0) or B (if the bit is 1) on the right side
// private void MulBitRight(ref GF127 c00, ref GF127 c01, ref GF127 c10, ref GF127 c11, bool bit)
// {
// // plan 1
// GF127 t;
// if (bit)
// { // MulB
// t = c00;
// c00 = GF127.Mul10(c00) + c01; // c00 = c00 * x + c01
// c01 = GF127.Mul11(t) + c01; // c01 = c00 * (x+1) + c01
// t = c10;
// c10 = GF127.Mul10(c10) + c11; // c10 = c10 * x + c11
// c11 = GF127.Mul11(t) + c11; // c11 = c10 * (x+1) + c11
// }
// else
// { // MulA
// t = c00;
// c00 = GF127.Mul10(c00) + c01; // c00 = c00 * x + c01
// c01 = t; // c01 = c00
// t = c10;
// c10 = GF127.Mul10(c10) + c11; // c10 = c10 * x + c11
// c11 = t; // c11 = c10;
// }
// //// plan 2
// //var r = new SL2(c00, c01, c10, c11);
// //if (bit)
// // r.MulB();
// //else
// // r.MulA();
// }
// // Concat() performs combining of hashes based on homomorphic characteristic.
// public static byte[] Concat(List<byte[]> hs)
// {
// var r = SL2.ID;
// foreach (var h in hs)
// {
// r *= new SL2().FromByteArray(h);
// }
// return r.ToByteArray();
// }
// // Validate() checks if hashes in hs combined are equal to h.
// public static bool Validate(byte[] h, List<byte[]> hs)
// {
// var expected = new SL2().FromByteArray(h);
// var actual = new SL2().FromByteArray(Concat(hs));
// return expected.Equals(actual);
// }
// // SubtractR() returns hash a, such that Concat(a, b) == c
// public static byte[] SubstractR(byte[] b, byte[] c)
// {
// var t1 = new SL2().FromByteArray(b);
// var t2 = new SL2().FromByteArray(c);
// var r = t2 * SL2.Inv(t1);
// return r.ToByteArray();
// }
// // SubtractL() returns hash b, such that Concat(a, b) == c
// public static byte[] SubstractL(byte[] a, byte[] c)
// {
// var t1 = new SL2().FromByteArray(a);
// var t2 = new SL2().FromByteArray(c);
// var r = SL2.Inv(t1) * t2;
// return r.ToByteArray();
// }
//}

View file

@ -9,4 +9,6 @@ public class PutObjectParameters
public Stream? Payload { get; set; } public Stream? Payload { get; set; }
public bool ClientCut { get; set; } public bool ClientCut { get; set; }
public int BufferMaxSize { get; set; }
} }

View file

@ -1,4 +1,3 @@
using FrostFS.SDK.ClientV2;
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap; using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
using FrostFS.SDK.ClientV2.Mappers.GRPC; using FrostFS.SDK.ClientV2.Mappers.GRPC;

View file

@ -10,7 +10,6 @@ using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
using FrostFS.SDK.ClientV2.Mappers.GRPC; using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.Session; using FrostFS.Session;
using FrostFS.Refs; using FrostFS.Refs;
using System.Collections.Generic;
namespace FrostFS.SDK.Tests; namespace FrostFS.SDK.Tests;

View file

@ -3,7 +3,6 @@ using FrostFS.Netmap;
using Grpc.Core; using Grpc.Core;
using FrostFS.SDK.ClientV2; using FrostFS.SDK.ClientV2;
using Google.Protobuf; using Google.Protobuf;
using NuGet.Frameworks;
namespace FrostFS.SDK.Tests; namespace FrostFS.SDK.Tests;

View file

@ -46,7 +46,6 @@ public abstract class ObjectTestsBase
Mocker.ObjectHeader = new(ContainerId, ModelsV2.Enums.ObjectType.Regular, [new ObjectAttribute("k", "v")]) Mocker.ObjectHeader = new(ContainerId, ModelsV2.Enums.ObjectType.Regular, [new ObjectAttribute("k", "v")])
{ {
PayloadLength = 1,
Version = new ModelsV2.Version(2, 13), Version = new ModelsV2.Version(2, 13),
OwnerId = OwnerId.FromKey(ecdsaKey) OwnerId = OwnerId.FromKey(ecdsaKey)
}; };

View file

@ -63,8 +63,11 @@ public class SmokeTests
var result = await fsClient.GetNodeInfoAsync(); var result = await fsClient.GetNodeInfoAsync();
} }
[Fact] [Theory]
public async void SimpleScenarioTest() [InlineData(1)]
[InlineData(3 * 1024 * 1024)] // exactly one chunk size - 3MB
[InlineData(6 * 1024 * 1024 + 100)]
public async void SimpleScenarioTest(int objectSize)
{ {
using var fsClient = Client.GetInstance(GetOptions(this.key, this.url)); using var fsClient = Client.GetInstance(GetOptions(this.key, this.url));
@ -88,7 +91,7 @@ public class SmokeTests
Assert.NotNull(container); Assert.NotNull(container);
var bytes = GetRandomBytes(6 * 1024 * 1024 + 100); var bytes = GetRandomBytes(objectSize);
var param = new PutObjectParameters var param = new PutObjectParameters
{ {
@ -144,8 +147,13 @@ public class SmokeTests
} }
} }
[Fact] [Theory]
public async void ClientCutScenarioTest() [InlineData(1)]
[InlineData(64 * 1024 * 1024)] // exactly 1 block size - 64MB
[InlineData(64 * 1024 * 1024 - 1)]
[InlineData(64 * 1024 * 1024 + 1)]
[InlineData(2 * 64 * 1024 * 1024 + 256)]
public async void ClientCutScenarioTest(int objectSize)
{ {
using var fsClient = Client.GetInstance(GetOptions(this.key, this.url)); using var fsClient = Client.GetInstance(GetOptions(this.key, this.url));
@ -165,7 +173,7 @@ public class SmokeTests
Assert.NotNull(container); Assert.NotNull(container);
byte[] bytes = GetRandomBytes(150 * 1024 * 1024); byte[] bytes = GetRandomBytes(objectSize);
var param = new PutObjectParameters var param = new PutObjectParameters
{ {