[#3] Move to netstandard 2.0

Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
p.gross 2024-05-29 12:43:00 +03:00
parent ae3fc419a4
commit 0c4723c705
55 changed files with 2508 additions and 1818 deletions

View file

@ -1,77 +1,97 @@
using System;
using System.Linq;
using System.Numerics;
using System.Text;
namespace FrostFS.SDK.Cryptography
using Org.BouncyCastle.Security.Certificates;
namespace FrostFS.SDK.Cryptography;
public static class Base58
{
public static class Base58
public const string Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
public static byte[] Base58CheckDecode(this string input)
{
public const string Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
if (input is null)
throw new ArgumentNullException(nameof(input));
byte[] buffer = Decode(input);
public static byte[] Base58CheckDecode(this string input)
if (buffer.Length < 4)
throw new FormatException();
byte[] checksum = buffer[0..(buffer.Length - 4)].Sha256().Sha256();
if (!buffer.AsSpan(buffer.Length - 4).SequenceEqual(checksum[..4].AsSpan()))
throw new FormatException();
var ret = buffer[..^4];
Array.Clear(buffer, 0, buffer.Length);
return ret;
}
public static string Base58CheckEncode(this ReadOnlySpan<byte> data)
{
byte[] checksum = data.ToArray().Sha256().Sha256();
Span<byte> buffer = stackalloc byte[data.Length + 4];
data.CopyTo(buffer);
checksum[..4].AsSpan().CopyTo(buffer[data.Length..]);
var ret = Encode(buffer);
buffer.Clear();
return ret;
}
public static byte[] Decode(string input)
{
// Decode Base58 string to BigInteger
var bi = BigInteger.Zero;
for (int i = 0; i < input.Length; i++)
{
if (input is null) throw new ArgumentNullException(nameof(input));
byte[] buffer = Decode(input);
if (buffer.Length < 4) throw new FormatException();
byte[] checksum = buffer[0..(buffer.Length - 4)].Sha256().Sha256();
if (!buffer.AsSpan(^4).SequenceEqual(checksum.AsSpan(..4)))
throw new FormatException();
var ret = buffer[..^4];
Array.Clear(buffer, 0, buffer.Length);
return ret;
int digit = Alphabet.IndexOf(input[i]);
if (digit < 0)
throw new FormatException($"Invalid Base58 character '{input[i]}' at position {i}");
bi = bi * Alphabet.Length + digit;
}
public static string Base58CheckEncode(this ReadOnlySpan<byte> data)
int leadingZeroCount = input.TakeWhile(c => c == Alphabet[0]).Count();
var leadingZeros = new byte[leadingZeroCount];
if (bi.IsZero)
return leadingZeros;
var bytesBigEndian = bi.ToByteArray().Reverse();
var firstNonZeroIndex = 0;
while(bytesBigEndian.ElementAt(firstNonZeroIndex) == 0x0)
firstNonZeroIndex++;
var bytesWithoutLeadingZeros = bytesBigEndian.Skip(firstNonZeroIndex).ToArray();
return ArrayHelper.Concat(leadingZeros, bytesWithoutLeadingZeros);
}
public static string Encode(ReadOnlySpan<byte> input)
{
var data = input.ToArray().Reverse().Concat(new byte[] { 0 }).ToArray();
BigInteger value = new(data);
// Encode BigInteger to Base58 string
var sb = new StringBuilder();
while (value > 0)
{
byte[] checksum = data.ToArray().Sha256().Sha256();
Span<byte> buffer = stackalloc byte[data.Length + 4];
data.CopyTo(buffer);
checksum.AsSpan(..4).CopyTo(buffer[data.Length..]);
var ret = Encode(buffer);
buffer.Clear();
return ret;
value = BigInteger.DivRem(value, Alphabet.Length, out var remainder);
sb.Insert(0, Alphabet[(int)remainder]);
}
public static byte[] Decode(string input)
// Append `1` for each leading 0 byte
for (int i = 0; i < input.Length && input[i] == 0; i++)
{
// Decode Base58 string to BigInteger
var bi = BigInteger.Zero;
for (int i = 0; i < input.Length; i++)
{
int digit = Alphabet.IndexOf(input[i]);
if (digit < 0)
throw new FormatException($"Invalid Base58 character '{input[i]}' at position {i}");
bi = bi * Alphabet.Length + digit;
}
// Encode BigInteger to byte[]
// Leading zero bytes get encoded as leading `1` characters
int leadingZeroCount = input.TakeWhile(c => c == Alphabet[0]).Count();
var leadingZeros = new byte[leadingZeroCount];
if (bi.IsZero) return leadingZeros;
var bytesWithoutLeadingZeros = bi.ToByteArray(isUnsigned: true, isBigEndian: true);
return ArrayHelper.Concat(leadingZeros, bytesWithoutLeadingZeros);
}
public static string Encode(ReadOnlySpan<byte> input)
{
// Decode byte[] to BigInteger
BigInteger value = new(input, isUnsigned: true, isBigEndian: true);
// Encode BigInteger to Base58 string
var sb = new StringBuilder();
while (value > 0)
{
value = BigInteger.DivRem(value, Alphabet.Length, out var remainder);
sb.Insert(0, Alphabet[(int)remainder]);
}
// Append `1` for each leading 0 byte
for (int i = 0; i < input.Length && input[i] == 0; i++)
{
sb.Insert(0, Alphabet[0]);
}
return sb.ToString();
sb.Insert(0, Alphabet[0]);
}
return sb.ToString();
}
}