[#16] Remove Tz fix formating
All checks were successful
DCO / DCO (pull_request) Successful in 50s
All checks were successful
DCO / DCO (pull_request) Successful in 50s
Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
parent
fefa2da218
commit
00a1e9412f
15 changed files with 123 additions and 723 deletions
|
@ -111,13 +111,16 @@ internal class NetmapServiceProvider : ContextAccessor
|
|||
var valueBytes = param.Value.ToByteArray();
|
||||
switch (key)
|
||||
{
|
||||
case "AuditFee": settings.AuditFee = GetLongValue(valueBytes); break;
|
||||
case "BasicIncomeRate": settings.BasicIncomeRate = 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 "IRCandidateFee": settings.IRCandidateFee = GetLongValue(valueBytes); break;
|
||||
case "InnerRingCandidateFee": settings.InnerRingCandidateFee = GetLongValue(valueBytes); break;
|
||||
case "MaxECDataCount": settings.MaxECDataCount = GetLongValue(valueBytes); break;
|
||||
case "MaxECParityCount": settings.MaxECParityCount = 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 "MaintenanceModeAllowed": settings.MaintenanceModeAllowed = GetBoolValue(valueBytes); break;
|
||||
default: settings.UnnamedSettings.Add(key, valueBytes); break;
|
||||
|
|
|
@ -73,52 +73,6 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var payloadStream = parameters.Payload!;
|
||||
|
@ -181,24 +181,36 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
|
||||
var networkSettings = await Context.Client.GetNetworkSettingsAsync(ctx);
|
||||
|
||||
var partSize = (int)networkSettings.MaxObjectSize;
|
||||
var buffer = new byte[partSize];
|
||||
var objectSize = (int)networkSettings.MaxObjectSize;
|
||||
|
||||
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 split = new Split();
|
||||
|
||||
var fullLength = (ulong)payloadStream.Length;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
var bytesCount = await payloadStream.ReadAsync(buffer, 0, partSize);
|
||||
var bytesCount = await payloadStream.ReadAsync(buffer, 0, objectSize);
|
||||
|
||||
split.Previous = sentObjectIds.LastOrDefault();
|
||||
|
||||
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);
|
||||
|
||||
if (largeObject.PayloadLength == fullLength)
|
||||
|
@ -270,21 +282,32 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
initRequest.Sign(Context.Key);
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
var chunkRequest = new PutRequest(initRequest)
|
||||
{
|
||||
Body = new PutRequest.Types.Body
|
||||
{
|
||||
Chunk = ByteString.CopyFrom(buffer[..bufferLength]),
|
||||
Chunk = ByteString.CopyFrom(buffer[..bytesCount]),
|
||||
},
|
||||
VerifyHeader = null
|
||||
};
|
||||
|
|
|
@ -25,13 +25,9 @@ internal class ObjectTools(ClientEnvironment ctx) : ContextAccessor (ctx)
|
|||
|
||||
grpcHeader.OwnerId = Context.Owner.ToGrpcMessage();
|
||||
grpcHeader.Version = Context.Version.ToGrpcMessage();
|
||||
|
||||
if (@object.Payload != null)
|
||||
{
|
||||
grpcHeader.PayloadLength = (ulong)@object.Payload.Length;
|
||||
grpcHeader.PayloadHash = Sha256Checksum(@object.Payload);
|
||||
}
|
||||
|
||||
grpcHeader.PayloadLength = (ulong)@object.Payload.Length;
|
||||
grpcHeader.PayloadHash = Sha256Checksum(@object.Payload);
|
||||
|
||||
var split = @object.Header.Split;
|
||||
if (split != null)
|
||||
{
|
||||
|
|
|
@ -3,19 +3,19 @@ using System.Collections.Generic;
|
|||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public class NetworkSettings
|
||||
{
|
||||
public ulong ContainerFee { 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 IRCandidateFee { get; internal set; }
|
||||
public ulong MaxObjectSize { get; internal set; }
|
||||
public ulong MaxECDataCount { get; internal set; }
|
||||
public ulong MaxECParityCount { get; internal set; }
|
||||
public ulong WithdrawalFee { get; internal set; }
|
||||
public bool HomomorphicHashingDisabled { get; internal set; }
|
||||
public bool MaintenanceModeAllowed { get; internal set; }
|
||||
|
||||
public Dictionary<string, object> UnnamedSettings { get; } = [];
|
||||
}
|
||||
{
|
||||
public ulong AuditFee { get; internal set; }
|
||||
public ulong BasicIncomeRate { get; internal set; }
|
||||
public ulong ContainerFee { get; internal set; }
|
||||
public ulong ContainerAliasFee { get; internal set; }
|
||||
public ulong EpochDuration { get; internal set; }
|
||||
public ulong InnerRingCandidateFee { get; internal set; }
|
||||
public ulong MaxObjectSize { get; internal set; }
|
||||
public ulong MaxECDataCount { get; internal set; }
|
||||
public ulong MaxECParityCount { get; internal set; }
|
||||
public ulong WithdrawFee { get; internal set; }
|
||||
public bool HomomorphicHashingDisabled { get; internal set; }
|
||||
public bool MaintenanceModeAllowed { get; internal set; }
|
||||
|
||||
public Dictionary<string, object> UnnamedSettings { get; } = [];
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
using Google.Protobuf;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace FrostFS.SDK.Cryptography;
|
||||
|
@ -20,35 +18,11 @@ public static class Extentions
|
|||
|
||||
public static byte[] Sha256(this byte[] value)
|
||||
{
|
||||
using var sha256 = SHA256.Create();
|
||||
var sha256 = SHA256.Create();
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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("-", "");
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
// }
|
||||
//}
|
|
@ -9,4 +9,6 @@ public class PutObjectParameters
|
|||
public Stream? Payload { get; set; }
|
||||
|
||||
public bool ClientCut { get; set; }
|
||||
|
||||
public int BufferMaxSize { get; set; }
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using FrostFS.SDK.ClientV2;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
|
|
@ -10,7 +10,6 @@ using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
|||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
using FrostFS.Session;
|
||||
using FrostFS.Refs;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FrostFS.SDK.Tests;
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ using FrostFS.Netmap;
|
|||
using Grpc.Core;
|
||||
using FrostFS.SDK.ClientV2;
|
||||
using Google.Protobuf;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace FrostFS.SDK.Tests;
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ public abstract class ObjectTestsBase
|
|||
ContainerId = new ContainerId(Base58.Encode(Mocker.ContainerGuid.ToBytes()));
|
||||
|
||||
Mocker.ObjectHeader = new(ContainerId, ModelsV2.Enums.ObjectType.Regular, [new ObjectAttribute("k", "v")])
|
||||
{
|
||||
PayloadLength = 1,
|
||||
{
|
||||
Version = new ModelsV2.Version(2, 13),
|
||||
OwnerId = OwnerId.FromKey(ecdsaKey)
|
||||
};
|
||||
|
|
|
@ -63,8 +63,11 @@ public class SmokeTests
|
|||
var result = await fsClient.GetNodeInfoAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void SimpleScenarioTest()
|
||||
[Theory]
|
||||
[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));
|
||||
|
||||
|
@ -88,7 +91,7 @@ public class SmokeTests
|
|||
|
||||
Assert.NotNull(container);
|
||||
|
||||
var bytes = GetRandomBytes(6 * 1024 * 1024 + 100);
|
||||
var bytes = GetRandomBytes(objectSize);
|
||||
|
||||
var param = new PutObjectParameters
|
||||
{
|
||||
|
@ -144,8 +147,13 @@ public class SmokeTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void ClientCutScenarioTest()
|
||||
[Theory]
|
||||
[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));
|
||||
|
||||
|
@ -165,7 +173,7 @@ public class SmokeTests
|
|||
|
||||
Assert.NotNull(container);
|
||||
|
||||
byte[] bytes = GetRandomBytes(150 * 1024 * 1024);
|
||||
byte[] bytes = GetRandomBytes(objectSize);
|
||||
|
||||
var param = new PutObjectParameters
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue