[#1] Move files to top level directory

Signed-off-by: Ivan Pchelintsev <i.pchelintsev@yadro.com>
This commit is contained in:
Ivan Pchelintsev 2024-05-16 10:23:38 +03:00
parent 013d8a8436
commit 11eff4e23e
76 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,157 @@
using System.Buffers.Binary;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;
using Google.Protobuf;
using Org.BouncyCastle.Asn1.Sec;
namespace FrostFS.SDK.Cryptography;
public static class KeyExtension
{
public const byte NeoAddressVersion = 0x35;
private const int CompressedPublicKeyLength = 33;
private const int UncompressedPublicKeyLength = 65;
private static readonly uint CheckSigDescriptor =
BinaryPrimitives.ReadUInt32LittleEndian(Encoding.ASCII.GetBytes("System.Crypto.CheckSig").Sha256());
public static byte[] Compress(this byte[] publicKey)
{
if (publicKey.Length != UncompressedPublicKeyLength)
throw new FormatException(
$"{nameof(Compress)} argument isn't uncompressed public key. " +
$"expected length={UncompressedPublicKeyLength}, actual={publicKey.Length}"
);
var secp256r1 = SecNamedCurves.GetByName("secp256r1");
var point = secp256r1.Curve.DecodePoint(publicKey);
return point.GetEncoded(true);
}
public static byte[] Decompress(this byte[] publicKey)
{
if (publicKey.Length != CompressedPublicKeyLength)
throw new FormatException(
$"{nameof(Decompress)} argument isn't compressed public key. " +
$"expected length={CompressedPublicKeyLength}, actual={publicKey.Length}"
);
var secp256r1 = SecNamedCurves.GetByName("secp256r1");
var point = secp256r1.Curve.DecodePoint(publicKey);
return point.GetEncoded(false);
}
private static byte[] CreateSignatureRedeemScript(this byte[] publicKey)
{
if (publicKey.Length != CompressedPublicKeyLength)
throw new FormatException(
$"{nameof(CreateSignatureRedeemScript)} argument isn't compressed public key. " +
$"expected length={CompressedPublicKeyLength}, actual={publicKey.Length}"
);
var script = new byte[] { 0x0c, CompressedPublicKeyLength }; //PUSHDATA1 33
script = ArrayHelper.Concat(script, publicKey);
script = ArrayHelper.Concat(script, new byte[] { 0x41 }); //SYSCALL
script = ArrayHelper.Concat(script, BitConverter.GetBytes(CheckSigDescriptor)); //Neo_Crypto_CheckSig
return script;
}
public static byte[] GetScriptHash(this byte[] publicKey)
{
var script = publicKey.CreateSignatureRedeemScript();
return script.Sha256().RIPEMD160();
}
private static string ToAddress(this byte[] scriptHash, byte version)
{
Span<byte> data = stackalloc byte[21];
data[0] = version;
scriptHash.CopyTo(data[1..]);
return Base58.Base58CheckEncode(data);
}
private static byte[] GetPrivateKeyFromWIF(string wif)
{
if (wif == null) throw new ArgumentNullException();
var data = wif.Base58CheckDecode();
if (data.Length != 34 || data[0] != 0x80 || data[33] != 0x01)
throw new FormatException();
var privateKey = new byte[32];
Buffer.BlockCopy(data, 1, privateKey, 0, privateKey.Length);
Array.Clear(data, 0, data.Length);
return privateKey;
}
public static string Address(this ECDsa key)
{
return key.PublicKey().PublicKeyToAddress();
}
public static string PublicKeyToAddress(this byte[] publicKey)
{
if (publicKey.Length != CompressedPublicKeyLength)
throw new FormatException(
nameof(publicKey) +
$" isn't encoded compressed public key. " +
$"expected length={CompressedPublicKeyLength}, actual={publicKey.Length}"
);
return publicKey.GetScriptHash().ToAddress(NeoAddressVersion);
}
public static byte[] PublicKey(this ECDsa key)
{
var param = key.ExportParameters(false);
var pubkey = new byte[33];
var pos = 33 - param.Q.X.Length;
param.Q.X.CopyTo(pubkey, pos);
if (new BigInteger(param.Q.Y.Reverse().Concat(new byte[] { 0x00 }).ToArray()).IsEven)
pubkey[0] = 0x2;
else
pubkey[0] = 0x3;
return pubkey;
}
public static byte[] PrivateKey(this ECDsa key)
{
return key.ExportParameters(true).D;
}
public static ECDsa LoadPrivateKey(this byte[] private_key)
{
var secp256r1 = SecNamedCurves.GetByName("secp256r1");
var public_key =
secp256r1.G.Multiply(new Org.BouncyCastle.Math.BigInteger(1, private_key)).GetEncoded(false)[1..];
var key = ECDsa.Create(new ECParameters
{
Curve = ECCurve.NamedCurves.nistP256,
D = private_key,
Q = new ECPoint
{
X = public_key[..32],
Y = public_key[32..]
}
});
return key;
}
public static ECDsa LoadWif(this string wif)
{
var private_key = GetPrivateKeyFromWIF(wif);
return LoadPrivateKey(private_key);
}
public static ECDsa LoadPublicKey(this byte[] public_key)
{
var public_key_full = public_key.Decompress()[1..];
var key = ECDsa.Create(new ECParameters
{
Curve = ECCurve.NamedCurves.nistP256,
Q = new ECPoint
{
X = public_key_full[..32],
Y = public_key_full[32..]
}
});
return key;
}
}