diff --git a/Docs/docfx.json b/Docs/docfx.json index dffea54a550..d225a16f1b2 100644 --- a/Docs/docfx.json +++ b/Docs/docfx.json @@ -8,7 +8,6 @@ "src/Libplanet.Action/Libplanet.Action.csproj", "src/Libplanet.Common/Libplanet.Common.csproj", "src/Libplanet.Crypto/Libplanet.Crypto.csproj", - "src/Libplanet.Crypto.Secp256k1/Libplanet.Crypto.Secp256k1.csproj", "tools/Libplanet.Explorer.Cocona/Libplanet.Explorer.Cocona.csproj", "tools/Libplanet.Extensions.Cocona/Libplanet.Extensions.Cocona.csproj", "test/Libplanet.Mocks/Libplanet.Mocks.csproj", diff --git a/Libplanet.sln b/Libplanet.sln index 6727a518cad..5df0979c1e1 100644 --- a/Libplanet.sln +++ b/Libplanet.sln @@ -37,10 +37,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Libplanet.Net", "src\Libpla EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Libplanet.Net.Tests", "test\Libplanet.Net.Tests\Libplanet.Net.Tests.csproj", "{6D7A63C9-16AB-4B7E-B9C0-0956E1E02610}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Libplanet.Crypto.Secp256k1", "src\Libplanet.Crypto.Secp256k1\Libplanet.Crypto.Secp256k1.csproj", "{9F88C871-CB37-4A88-BACF-540AC253C202}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Libplanet.Crypto.Secp256k1.Tests", "test\Libplanet.Crypto.Secp256k1.Tests\Libplanet.Crypto.Secp256k1.Tests.csproj", "{B1A38DDE-5534-4625-A3F2-A585BA7A1198}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Libplanet.Explorer.Cocona", "tools\Libplanet.Explorer.Cocona\Libplanet.Explorer.Cocona.csproj", "{8698E0C2-1A82-43E6-8A26-3D9A825CF574}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Libplanet.Explorer.Cocona.Tests", "test\Libplanet.Explorer.Cocona.Tests\Libplanet.Explorer.Cocona.Tests.csproj", "{F782BC86-9CE6-4F69-8F77-710A399CB54F}" @@ -391,42 +387,6 @@ Global {6D7A63C9-16AB-4B7E-B9C0-0956E1E02610}.Release|x64.Build.0 = Release|Any CPU {6D7A63C9-16AB-4B7E-B9C0-0956E1E02610}.Release|x86.ActiveCfg = Release|Any CPU {6D7A63C9-16AB-4B7E-B9C0-0956E1E02610}.Release|x86.Build.0 = Release|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Debug|x64.ActiveCfg = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Debug|x64.Build.0 = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Debug|x86.ActiveCfg = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Debug|x86.Build.0 = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.ReleaseMono|Any CPU.ActiveCfg = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.ReleaseMono|Any CPU.Build.0 = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.ReleaseMono|x64.ActiveCfg = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.ReleaseMono|x64.Build.0 = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.ReleaseMono|x86.ActiveCfg = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.ReleaseMono|x86.Build.0 = Debug|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Release|Any CPU.Build.0 = Release|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Release|x64.ActiveCfg = Release|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Release|x64.Build.0 = Release|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Release|x86.ActiveCfg = Release|Any CPU - {9F88C871-CB37-4A88-BACF-540AC253C202}.Release|x86.Build.0 = Release|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Debug|x64.ActiveCfg = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Debug|x64.Build.0 = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Debug|x86.ActiveCfg = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Debug|x86.Build.0 = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.ReleaseMono|Any CPU.ActiveCfg = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.ReleaseMono|Any CPU.Build.0 = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.ReleaseMono|x64.ActiveCfg = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.ReleaseMono|x64.Build.0 = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.ReleaseMono|x86.ActiveCfg = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.ReleaseMono|x86.Build.0 = Debug|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Release|Any CPU.Build.0 = Release|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Release|x64.ActiveCfg = Release|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Release|x64.Build.0 = Release|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Release|x86.ActiveCfg = Release|Any CPU - {B1A38DDE-5534-4625-A3F2-A585BA7A1198}.Release|x86.Build.0 = Release|Any CPU {8698E0C2-1A82-43E6-8A26-3D9A825CF574}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8698E0C2-1A82-43E6-8A26-3D9A825CF574}.Debug|Any CPU.Build.0 = Debug|Any CPU {8698E0C2-1A82-43E6-8A26-3D9A825CF574}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -719,8 +679,6 @@ Global {A43E44E5-F9C1-44BD-A593-419EC113117B} = {B9C00FAF-36CF-463A-83FA-43E6B974AE2E} {2E17A091-DC29-41FB-ABC8-767BD75FFB07} = {AC908E33-B856-4E23-9F81-B7F7C97A07F9} {6D7A63C9-16AB-4B7E-B9C0-0956E1E02610} = {B9C00FAF-36CF-463A-83FA-43E6B974AE2E} - {9F88C871-CB37-4A88-BACF-540AC253C202} = {AC908E33-B856-4E23-9F81-B7F7C97A07F9} - {B1A38DDE-5534-4625-A3F2-A585BA7A1198} = {B9C00FAF-36CF-463A-83FA-43E6B974AE2E} {8698E0C2-1A82-43E6-8A26-3D9A825CF574} = {88E7FAF4-CEEC-48B6-9114-71CFE3FC0F50} {F782BC86-9CE6-4F69-8F77-710A399CB54F} = {B9C00FAF-36CF-463A-83FA-43E6B974AE2E} {763BAD3E-3244-4E8F-8182-2BF35774262A} = {AC908E33-B856-4E23-9F81-B7F7C97A07F9} diff --git a/changes/v5.md b/changes/v5.md index 2c8b415824c..92730337c58 100644 --- a/changes/v5.md +++ b/changes/v5.md @@ -374,14 +374,10 @@ below. The default SDK version for the project has been bumped up to .NET 6.0. The list of supported SDKs is as follows - - netstandard2.0 - netstandard2.1 - netcoreapp3.1 - net6.0" -> Support for `netstandard2.0` is coming to an end soon, please note that -projects using `netstandard2.0` will be deprecated. - The `VersionPrefix` property has been moved from the *src/Libplanet/Libplanet.csproj* file to the `Directory.Build.props` file. diff --git a/sdk/node/Libplanet.Node.Executable/Libplanet.Node.Executable.csproj b/sdk/node/Libplanet.Node.Executable/Libplanet.Node.Executable.csproj index 5da10a9d60b..c8f43a632c2 100644 --- a/sdk/node/Libplanet.Node.Executable/Libplanet.Node.Executable.csproj +++ b/sdk/node/Libplanet.Node.Executable/Libplanet.Node.Executable.csproj @@ -27,7 +27,6 @@ - diff --git a/sdk/node/Libplanet.Node/Actions/PluginLoader.cs b/sdk/node/Libplanet.Node/Actions/PluginLoader.cs index 352c1e0e12e..65192072bb5 100644 --- a/sdk/node/Libplanet.Node/Actions/PluginLoader.cs +++ b/sdk/node/Libplanet.Node/Actions/PluginLoader.cs @@ -10,6 +10,16 @@ internal static class PluginLoader { public static IActionLoader LoadActionLoader(string modulePath, string typeName) { + if (Type.GetType(typeName) is { } type) + { + if (Activator.CreateInstance(type) is not IActionLoader obj) + { + throw new InvalidOperationException(); + } + + return obj; + } + var assembly = LoadAssembly(modulePath); return Create(assembly, typeName); } @@ -17,6 +27,16 @@ public static IActionLoader LoadActionLoader(string modulePath, string typeName) public static IPolicyActionsRegistry LoadPolicyActionRegistry( string relativePath, string typeName) { + if (Type.GetType(typeName) is { } type) + { + if (Activator.CreateInstance(type) is not IPolicyActionsRegistry obj) + { + throw new InvalidOperationException(); + } + + return obj; + } + var assembly = LoadAssembly(relativePath); return Create(assembly, typeName); } diff --git a/sdk/node/Libplanet.Node/Services/ActionService.cs b/sdk/node/Libplanet.Node/Services/ActionService.cs index 7238781b97d..1c3fdb07a88 100644 --- a/sdk/node/Libplanet.Node/Services/ActionService.cs +++ b/sdk/node/Libplanet.Node/Services/ActionService.cs @@ -18,7 +18,8 @@ private static IActionLoader GetActionLoader(ActionOptions options) { if (options.ActionLoaderType != string.Empty) { - var modulePath = options.ModulePath; + var modulePath = options.ModulePath != string.Empty + ? Path.GetFullPath(options.ModulePath) : string.Empty; var actionLoaderType = options.ActionLoaderType; return PluginLoader.LoadActionLoader(modulePath, actionLoaderType); } @@ -30,7 +31,8 @@ private static IPolicyActionsRegistry GetPolicyActionsRegistry(ActionOptions opt { if (options.PolicyActionRegistryType != string.Empty) { - var modulePath = options.ModulePath; + var modulePath = options.ModulePath != string.Empty + ? Path.GetFullPath(options.ModulePath) : string.Empty; var policyActionRegistryType = options.PolicyActionRegistryType; return PluginLoader.LoadPolicyActionRegistry(modulePath, policyActionRegistryType); } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ce9c961b5b8..b2113b1f8ba 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ - $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp3.1 + $(TargetFrameworks);netstandard2.1 9 true false diff --git a/src/Libplanet.Common/ByteUtil.cs b/src/Libplanet.Common/ByteUtil.cs index 8ce8134c360..83514f07efb 100644 --- a/src/Libplanet.Common/ByteUtil.cs +++ b/src/Libplanet.Common/ByteUtil.cs @@ -6,9 +6,14 @@ using System.Collections.Immutable; using System.Diagnostics.Contracts; using System.Globalization; +using System.IO; using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; +using System.Text; +using System.Text.Json; +using Bencodex.Json; +using Bencodex.Types; namespace Libplanet.Common { @@ -23,6 +28,16 @@ public static class ByteUtil '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', }; + private static readonly BencodexJsonConverter BencodexJsonConverter = new (); + private static readonly JsonSerializerOptions SerializerOptions = new () + { + WriteIndented = true, + Converters = + { + BencodexJsonConverter, + }, + }; + /// /// Converts a hexadecimal string to a mutable array. /// @@ -232,5 +247,15 @@ public static bool Satisfies(IReadOnlyList hashDigest, long difficulty) var result = new BigInteger(digestArray); return result < target; } + + public static byte[] CreateMessage(IValue value) + { + using var ms = new MemoryStream(); + using var writer = new Utf8JsonWriter(ms, new JsonWriterOptions { Indented = true }); + BencodexJsonConverter.Write(writer, value, SerializerOptions); + ms.Position = 0; + using var sr = new StreamReader(ms); + return Encoding.UTF8.GetBytes(sr.ReadToEnd()); + } } } diff --git a/src/Libplanet.Common/FixedSizedQueue.cs b/src/Libplanet.Common/FixedSizedQueue.cs index 16c993a7ea9..9b7e5ae1253 100644 --- a/src/Libplanet.Common/FixedSizedQueue.cs +++ b/src/Libplanet.Common/FixedSizedQueue.cs @@ -46,7 +46,7 @@ public FixedSizedQueue(int size) while (Count > Size) { // Ensure we don't exceed the maximum size. - TryDequeue(out T _); + TryDequeue(out T? _); } } } diff --git a/src/Libplanet.Common/Libplanet.Common.csproj b/src/Libplanet.Common/Libplanet.Common.csproj index 595138eed71..9c8101404cf 100644 --- a/src/Libplanet.Common/Libplanet.Common.csproj +++ b/src/Libplanet.Common/Libplanet.Common.csproj @@ -4,6 +4,7 @@ + diff --git a/src/Libplanet.Crypto.Secp256k1/Libplanet.Crypto.Secp256k1.csproj b/src/Libplanet.Crypto.Secp256k1/Libplanet.Crypto.Secp256k1.csproj deleted file mode 100644 index 5296ede1606..00000000000 --- a/src/Libplanet.Crypto.Secp256k1/Libplanet.Crypto.Secp256k1.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - 10 - true - $(NoWarn);NU5104 - - - - - - - - - - - - - - - diff --git a/src/Libplanet.Crypto.Secp256k1/Secp256k1CryptoBackend.cs b/src/Libplanet.Crypto.Secp256k1/Secp256k1CryptoBackend.cs deleted file mode 100644 index f062b56cf6c..00000000000 --- a/src/Libplanet.Crypto.Secp256k1/Secp256k1CryptoBackend.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Libplanet.Common; -using Libplanet.Crypto; - -namespace Libplanet.Crypto.Secp256k1; - -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Security.Cryptography; -using Libplanet; -using Secp256k1Net; -using Libplanet.Crypto; - -[SuppressMessage( - "Minor Code Smell", - "S101:Types should be named in PascalCase", - Justification = "Term \"secp256k1\" is a single word.")] -public class Secp256k1CryptoBackend : ICryptoBackend - where T : HashAlgorithm -{ - private readonly Secp256k1 _instance = new Secp256k1(); - private readonly object _instanceLock = new object(); - - public byte[] Sign(HashDigest messageHash, PrivateKey privateKey) - { - lock (_instanceLock) - { - var secp256K1Signature = new byte[Secp256k1.SIGNATURE_LENGTH]; - var privateKeyBytes = new byte[Secp256k1.PRIVKEY_LENGTH]; - - privateKey.ByteArray.CopyTo( - privateKeyBytes, - Secp256k1.PRIVKEY_LENGTH - privateKey.ByteArray.Length); - - _instance.Sign( - secp256K1Signature, - messageHash.ToByteArray(), - privateKeyBytes); - - var signature = new byte[Secp256k1.SERIALIZED_DER_SIGNATURE_MAX_SIZE]; - _instance.SignatureSerializeDer( - signature, - secp256K1Signature, - out int signatureLength); - - return signature.Take(signatureLength).ToArray(); - } - } - - public bool Verify( - HashDigest messageHash, - byte[] signature, - PublicKey publicKey) - { - lock (_instanceLock) - { - var secp256K1Signature = new byte[64]; - _instance.SignatureParseDer(secp256K1Signature, signature); - - byte[] secp256K1PublicKey = new byte[64]; - byte[] serializedPublicKey = publicKey.Format(false); - _instance.PublicKeyParse(secp256K1PublicKey, serializedPublicKey); - - return _instance.Verify( - secp256K1Signature, - messageHash.ToByteArray(), - secp256K1PublicKey); - } - } -} diff --git a/src/Libplanet.Crypto/Address.cs b/src/Libplanet.Crypto/Address.cs index e0866620e28..47b0159353b 100644 --- a/src/Libplanet.Crypto/Address.cs +++ b/src/Libplanet.Crypto/Address.cs @@ -5,13 +5,11 @@ using System.Diagnostics.Contracts; using System.Globalization; using System.Linq; -using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using Bencodex; using Bencodex.Types; using Libplanet.Common; -using Org.BouncyCastle.Crypto.Digests; namespace Libplanet.Crypto { @@ -259,35 +257,32 @@ public int CompareTo(object? obj) => obj is Address other private static string ToChecksumAddress(string hex) { - byte[] bytes = Encoding.ASCII.GetBytes(hex); - byte[] hash = CalculateHash(bytes); - string hashHex = ByteUtil.Hex(hash); - string address = string.Empty; - - for (var i = 0; i < hex.Length; i++) + var value = new Nethereum.Util.AddressUtil().ConvertToChecksumAddress(hex); + if (value.StartsWith("0x")) { - char c = hex[i]; - address += (hashHex[i] >= '8') ? char.ToUpper(c, CultureInfo.InvariantCulture) : c; + return value.Substring(2); } - return address; + return value; } - private static byte[] CalculateHash(byte[] value) + private static ImmutableArray DeriveAddress(PublicKey key) { - var digest = new KeccakDigest(256); - var output = new byte[digest.GetDigestSize()]; - digest.BlockUpdate(value, 0, value.Length); - digest.DoFinal(output, 0); - return output; + var initaddr = new Nethereum.Util.Sha3Keccack().CalculateHash( + GetPubKeyNoPrefix(key, false)); + var addr = new byte[initaddr.Length - 12]; + Array.Copy(initaddr, 12, addr, 0, initaddr.Length - 12); + var address = ToChecksumAddress( + Nethereum.Hex.HexConvertors.Extensions.HexByteConvertorExtensions.ToHex(addr)); + return ByteUtil.ParseHexToImmutable(address); } - private static ImmutableArray DeriveAddress(PublicKey key) + private static byte[] GetPubKeyNoPrefix(PublicKey publicKey, bool compressed = false) { - byte[] hashPayload = key.Format(false).Skip(1).ToArray(); - var output = CalculateHash(hashPayload); - - return output.Skip(output.Length - Size).ToImmutableArray(); + var pubKey = publicKey.Format(compressed); + var arr = new byte[pubKey.Length - 1]; + Array.Copy(pubKey, 1, arr, 0, arr.Length); + return arr; } private static ImmutableArray DeriveAddress(string hex) diff --git a/src/Libplanet.Crypto/CryptoConfig.cs b/src/Libplanet.Crypto/CryptoConfig.cs index dbe14798343..393cd5c4c11 100644 --- a/src/Libplanet.Crypto/CryptoConfig.cs +++ b/src/Libplanet.Crypto/CryptoConfig.cs @@ -1,5 +1,3 @@ -using System.Security.Cryptography; - namespace Libplanet.Crypto { /// @@ -7,14 +5,14 @@ namespace Libplanet.Crypto /// public static class CryptoConfig { - private static ICryptoBackend? _cryptoBackend; + private static ICryptoBackend? _cryptoBackend; /// /// Global cryptography backend to sign and verify messages. /// - public static ICryptoBackend CryptoBackend + public static ICryptoBackend CryptoBackend { - get => _cryptoBackend ??= new DefaultCryptoBackend(); + get => _cryptoBackend ??= new DefaultCryptoBackend(); set => _cryptoBackend = value; } } diff --git a/src/Libplanet.Crypto/DefaultCryptoBackend.cs b/src/Libplanet.Crypto/DefaultCryptoBackend.cs index e08b80745cc..49ccaf1b0b1 100644 --- a/src/Libplanet.Crypto/DefaultCryptoBackend.cs +++ b/src/Libplanet.Crypto/DefaultCryptoBackend.cs @@ -1,69 +1,89 @@ -using System.IO; -using System.Security.Cryptography; -using Libplanet.Common; -using Org.BouncyCastle.Asn1; -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Signers; -using Org.BouncyCastle.Math; +using System; +using System.Collections.Generic; +using System.Text; +using Nethereum.Util; +using Secp256k1Net; +using ByteUtil = Libplanet.Common.ByteUtil; namespace Libplanet.Crypto { - public class DefaultCryptoBackend : ICryptoBackend - where T : HashAlgorithm + public class DefaultCryptoBackend : ICryptoBackend { - public byte[] Sign(HashDigest messageHash, PrivateKey privateKey) - { - var h = new Sha256Digest(); - var kCalculator = new HMacDsaKCalculator(h); - var signer = new ECDsaSigner(kCalculator); - signer.Init(true, privateKey.KeyParam); - BigInteger[] rs = signer.GenerateSignature(messageHash.ToByteArray()); - var r = rs[0]; - var s = rs[1]; + private const int Offset = 27; - BigInteger otherS = privateKey.KeyParam.Parameters.N.Subtract(s); - if (s.CompareTo(otherS) == 1) + public byte[] Sign(byte[] message, PrivateKey privateKey) + { + lock (PrivateKey._secpLock) { - s = otherS; - } + using var secp = new Secp256k1(); + var keccak = new Sha3Keccack(); + var messageHash = HashPrefixedMessage(message); + var keyBytes = privateKey.ToByteArray(); + var sig1 = new byte[Secp256k1.UNSERIALIZED_SIGNATURE_SIZE]; + var sig2 = new byte[Secp256k1.SERIALIZED_SIGNATURE_SIZE]; + var signature = new byte[Secp256k1.UNSERIALIZED_SIGNATURE_SIZE]; + if (!secp.SignRecoverable(sig1, messageHash, keyBytes)) + { + throw new InvalidOperationException("Failed to sign the message."); + } - using var bos = new MemoryStream(72); - using (var seq = new DerSequenceGenerator(bos)) - { - seq.AddObject(new DerInteger(r)); - seq.AddObject(new DerInteger(s)); - } + if (!secp.RecoverableSignatureSerializeCompact(sig2, out var recoverId, sig1)) + { + throw new InvalidOperationException("Failed to serialize the signature."); + } - return bos.ToArray(); + Array.Copy(sig2, signature, sig2.Length); + signature[sig2.Length] = Convert.ToByte(recoverId + Offset); + return signature; + } } - public bool Verify( - HashDigest messageHash, - byte[] signature, - PublicKey publicKey) + public bool Verify(byte[] message, byte[] signature, PublicKey publicKey) + => Verify(message, signature, publicKey.Address); + + public bool Verify(byte[] message, byte[] signature, Address signer) { - try + lock (PrivateKey._secpLock) { - Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(signature); + using var secp = new Secp256k1(); + var keccak = new Sha3Keccack(); + var publicKeyOutput = new byte[Secp256k1.PUBKEY_LENGTH]; + var serializedKey = new byte[Secp256k1.SERIALIZED_UNCOMPRESSED_PUBKEY_LENGTH]; + var messageHash = HashPrefixedMessage(message); + var recoverId = signature[signature.Length - 1] - Offset; - var rs = new[] + var sig2 = new byte[Secp256k1.UNSERIALIZED_SIGNATURE_SIZE]; + if (!secp.RecoverableSignatureParseCompact(sig2, signature, recoverId)) { - ((DerInteger)asn1Sequence[0]).Value, - ((DerInteger)asn1Sequence[1]).Value, - }; - var verifier = new ECDsaSigner(); - verifier.Init(false, publicKey.KeyParam); + return false; + } - return verifier.VerifySignature(messageHash.ToByteArray(), rs[0], rs[1]); - } - catch (IOException) - { - return false; - } - catch (Asn1ParsingException) - { - return false; + if (!secp.Recover(publicKeyOutput, sig2, messageHash)) + { + return false; + } + + if (!secp.PublicKeySerialize(serializedKey, publicKeyOutput)) + { + return false; + } + + return signer.Equals(new PublicKey(serializedKey).Address); } } + + private static byte[] HashPrefixedMessage(byte[] message) + { + var bytePrefix = ByteUtil.ParseHex("19"); + var textBytePrefix = Encoding.UTF8.GetBytes( + "Ethereum Signed Message:\n" + message.Length); + var byteList = new List( + bytePrefix.Length + textBytePrefix.Length + message.Length); + + byteList.AddRange(bytePrefix); + byteList.AddRange(textBytePrefix); + byteList.AddRange(message); + return new DefaultMessageHasher().Hash(byteList.ToArray()); + } } } diff --git a/src/Libplanet.Crypto/ICryptoBackend.cs b/src/Libplanet.Crypto/ICryptoBackend.cs index 3c2b48ee1d4..b371765f9db 100644 --- a/src/Libplanet.Crypto/ICryptoBackend.cs +++ b/src/Libplanet.Crypto/ICryptoBackend.cs @@ -1,47 +1,39 @@ using System; -using System.Security.Cryptography; -using Libplanet.Common; namespace Libplanet.Crypto { /// /// Cryptography backend interface. /// - /// A which corresponds to a digest. - /// - public interface ICryptoBackend - where T : HashAlgorithm + public interface ICryptoBackend { /// - /// Creates a signature from with the corresponding + /// Creates a signature from with the corresponding /// . /// - /// A 32 bytes message hash digest hashed with SHA256 to sign. + /// A 32 bytes message hash digest hashed with SHA256 to sign. /// /// to sign - /// . + /// . /// - /// Created a signature from with the corresponding + /// Created a signature from with the corresponding /// . /// - byte[] Sign(HashDigest messageHash, PrivateKey privateKey); + byte[] Sign(byte[] message, PrivateKey privateKey); /// /// Verifies whether a was created from - /// a with the corresponding . + /// a with the corresponding . /// - /// A 32 bytes message hash digest hashed with SHA256. + /// A 32 bytes message hash digest hashed with SHA256. /// A signature that was created from the - /// . - /// used for verification. + /// . + /// used for verification. /// if the was created - /// from the with the corresponding + /// from the with the corresponding /// . Otherwise . /// If any exception is thrown, the given /// is considered as invalid. - bool Verify( - HashDigest messageHash, - byte[] signature, - PublicKey publicKey); + bool Verify(byte[] message, byte[] signature, Address signer); } } diff --git a/src/Libplanet.Crypto/Libplanet.Crypto.csproj b/src/Libplanet.Crypto/Libplanet.Crypto.csproj index 7ea3441fd03..899431a39cf 100644 --- a/src/Libplanet.Crypto/Libplanet.Crypto.csproj +++ b/src/Libplanet.Crypto/Libplanet.Crypto.csproj @@ -4,7 +4,9 @@ - + + + diff --git a/src/Libplanet.Crypto/PrivateKey.cs b/src/Libplanet.Crypto/PrivateKey.cs index 93c91b995ea..8e1e89fa1ce 100644 --- a/src/Libplanet.Crypto/PrivateKey.cs +++ b/src/Libplanet.Crypto/PrivateKey.cs @@ -1,20 +1,13 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Linq; using System.Runtime.CompilerServices; using System.Security.Cryptography; using Libplanet.Common; -using Org.BouncyCastle.Asn1.Sec; -using Org.BouncyCastle.Asn1.X9; -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Generators; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Math; -using Org.BouncyCastle.Math.EC; -using Org.BouncyCastle.Security; -using ECPoint = Org.BouncyCastle.Math.EC.ECPoint; +using Secp256k1Net; namespace Libplanet.Crypto { @@ -42,7 +35,9 @@ namespace Libplanet.Crypto /// public class PrivateKey : IEquatable { + internal static readonly object _secpLock = new object(); private const int KeyByteSize = 32; + private readonly ImmutableArray _bytes; private PublicKey? _publicKey; /// @@ -50,7 +45,7 @@ public class PrivateKey : IEquatable /// It can be analogous to creating a new account in a degree. /// public PrivateKey() - : this(GenerateKeyParam()) + : this(GenerateBytes()) { } @@ -66,16 +61,14 @@ public PrivateKey() /// A valid array for a can be encoded /// using property. /// - public PrivateKey(IReadOnlyList privateKey) - : this(privateKey is byte[] ba ? ba : privateKey.ToArray(), informedConsent: true) + public PrivateKey(byte[] privateKey) + : this(privateKey.ToImmutableArray()) + { + } + + public PrivateKey(in ImmutableArray immutableBytes) + : this(immutableBytes, verify: true) { - if (privateKey.Count != KeyByteSize) - { - throw new ArgumentOutOfRangeException( - nameof(privateKey), - $"The key must be {KeyByteSize} bytes." - ); - } } /// @@ -91,27 +84,18 @@ public PrivateKey(IReadOnlyList privateKey) /// Thrown when the given string is /// not a valid hexadecimal string. public PrivateKey(string hex) - : this(unverifiedKey: GenerateBytesFromHexString(hex), informedConsent: true) + : this(GenerateBytesFromHexString(hex), verify: true) { } - public PrivateKey(byte[] unverifiedKey, bool informedConsent) - : this(GenerateKeyFromBytes(unverifiedKey)) + private PrivateKey(in ImmutableArray bytes, bool verify) { - // The `informedConsent` parameter mainly purposes to prevent this overload from - // being chosen instead of PrivatKey(IReadOnly) by mistake. - if (!informedConsent) + if (verify && !VerifyBytes(bytes)) { - throw new ArgumentException( - nameof(informedConsent), - "The caller should ensure the key is valid and safe enough." - ); + throw new ArgumentException("Invalid private key.", nameof(bytes)); } - } - private PrivateKey(ECPrivateKeyParameters keyParam) - { - KeyParam = keyParam; + _bytes = bytes; } /// @@ -124,10 +108,13 @@ public PublicKey PublicKey { if (_publicKey is null) { - ECDomainParameters ecParams = GetECParameters(); - ECPoint q = ecParams.G.Multiply(KeyParam.D); - var kp = new ECPublicKeyParameters("ECDSA", q, ecParams); - _publicKey = new PublicKey(kp); + lock (_secpLock) + { + using var secp256k1 = new Secp256k1(); + var publicKey = new byte[Secp256k1.PUBKEY_LENGTH]; + secp256k1.PublicKeyCreate(publicKey, _bytes.ToArray()); + _publicKey = new PublicKey(publicKey, verify: false); + } } return _publicKey; @@ -160,8 +147,6 @@ public PublicKey PublicKey [Pure] public ImmutableArray ByteArray => ToByteArray().ToImmutableArray(); - internal ECPrivateKeyParameters KeyParam { get; } - public static bool operator ==(PrivateKey left, PrivateKey right) => left.Equals(right); public static bool operator !=(PrivateKey left, PrivateKey right) => !left.Equals(right); @@ -180,20 +165,23 @@ public PublicKey PublicKey /// not a valid hexadecimal string. [Pure] public static PrivateKey FromString(string hex) - { - return new PrivateKey( - unverifiedKey: GenerateBytesFromHexString(hex), - informedConsent: true - ); - } + => new PrivateKey(GenerateBytesFromHexString(hex), verify: true); - public bool Equals(PrivateKey? other) => KeyParam.Equals(other?.KeyParam); + public bool Equals(PrivateKey? other) + => other is not null && _bytes.SequenceEqual(other._bytes); public override bool Equals(object? obj) => obj is PrivateKey other && Equals(other); - public override int GetHashCode() => - unchecked(ByteUtil.CalculateHashCode(ToByteArray()) * 397 ^ - KeyParam.GetHashCode()); + public override int GetHashCode() + { + HashCode hash = default; + for (var i = 0; i < _bytes.Length; i++) + { + hash.Add(_bytes[i]); + } + + return hash.ToHashCode(); + } /// /// Creates a signature from the given . @@ -226,8 +214,8 @@ public override int GetHashCode() => /// public byte[] Sign(byte[] message) { - HashDigest hashed = HashDigest.DeriveFrom(message); - return CryptoConfig.CryptoBackend.Sign(hashed, this); + // HashDigest hashed = HashDigest.DeriveFrom(message); + return CryptoConfig.CryptoBackend.Sign(message, this); } /// @@ -253,8 +241,8 @@ public byte[] Sign(byte[] message) /// public ImmutableArray Sign(ImmutableArray message) { - HashDigest hashed = HashDigest.DeriveFrom(message); - byte[] sig = CryptoConfig.CryptoBackend.Sign(hashed, this); + // HashDigest hashed = HashDigest.DeriveFrom(message); + byte[] sig = CryptoConfig.CryptoBackend.Sign(message.ToArray(), this); return Unsafe.As>(ref sig); } @@ -320,21 +308,14 @@ public ImmutableArray Decrypt(ImmutableArray ciphertext) => [Pure] public SymmetricKey ExchangeKey(PublicKey publicKey) { - ECPoint p = CalculatePoint(publicKey.KeyParam); - BigInteger x = p.AffineXCoord.ToBigInteger(); - BigInteger y = p.AffineYCoord.ToBigInteger(); - - byte[] xbuf = x.ToByteArrayUnsigned(); - var ybuf = new byte[] { (byte)(y.TestBit(0) ? 0x03 : 0x02) }; - - var hash = new Sha256Digest(); - var result = new byte[hash.GetDigestSize()]; - - hash.BlockUpdate(ybuf, 0, ybuf.Length); - hash.BlockUpdate(xbuf, 0, xbuf.Length); - hash.DoFinal(result, 0); + lock (_secpLock) + { + using var secp256k1 = new Secp256k1(); + var secret = new byte[Secp256k1.SECRET_LENGTH]; + secp256k1.Ecdh(secret, publicKey.Raw.ToArray(), _bytes.ToArray()); - return new SymmetricKey(result); + return new SymmetricKey(secret); + } } /// @@ -359,71 +340,45 @@ public SymmetricKey ExchangeKey(PublicKey publicKey) /// /// [Pure] - public byte[] ToByteArray() => - KeyParam.D.ToByteArrayUnsigned(); + public byte[] ToByteArray() => _bytes.ToArray(); - internal static ECDomainParameters GetECParameters() + internal static byte[] GetPublicKey(in ImmutableArray raw, bool compress) { - return GetECParameters("secp256k1"); - } - - private static ECDomainParameters GetECParameters(string name) - { - X9ECParameters ps = SecNamedCurves.GetByName(name); - return new ECDomainParameters(ps.Curve, ps.G, ps.N, ps.H); - } - - private static ECPrivateKeyParameters GenerateKeyParam() - { - var gen = new ECKeyPairGenerator(); - var secureRandom = new SecureRandom(); - ECDomainParameters ecParams = GetECParameters(); - var keyGenParam = - new ECKeyGenerationParameters(ecParams, secureRandom); - gen.Init(keyGenParam); - - const int maxTries = 3000; - int tries = 0; - ECPrivateKeyParameters result; - - while (tries < maxTries) + lock (_secpLock) { - result = (ECPrivateKeyParameters)gen.GenerateKeyPair().Private; - if (result.D.ToByteArrayUnsigned().Length == KeyByteSize) + using var secp256k1 = new Secp256k1(); + var length = compress + ? Secp256k1.SERIALIZED_COMPRESSED_PUBKEY_LENGTH + : Secp256k1.SERIALIZED_UNCOMPRESSED_PUBKEY_LENGTH; + var flag = compress + ? Flags.SECP256K1_EC_COMPRESSED : Flags.SECP256K1_EC_UNCOMPRESSED; + var publicKey = new byte[length]; + if (!secp256k1.PublicKeySerialize(publicKey, raw.ToArray(), flag)) { - return result; + throw new NotSupportedException("Failed to serialize a public key."); } - tries++; + return publicKey; } - - throw new GenerateKeyParamTriesExceedException( - "Can't find appropriate parameter for private key" + - $"(maxTries: {maxTries})" - ); } - private static ECPrivateKeyParameters GenerateKeyFromBytes(byte[] privateKey) + private static byte[] GenerateBytes() { - if (privateKey.All(b => b.Equals(0x00))) + lock (_secpLock) { - throw new ArgumentException("Every bytes in Private key is zero value."); + using var secp256k1 = new Secp256k1(); + using var rnd = RandomNumberGenerator.Create(); + var privateKey = new byte[Secp256k1.PRIVKEY_LENGTH]; + do + { + rnd.GetBytes(privateKey); + } + while (!secp256k1.SecretKeyVerify(privateKey)); + return privateKey; } - - var param = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger(1, privateKey), - GetECParameters() - ); - - // For sanity check. -#pragma warning disable SA1312, S1481 - var _ = new PrivateKey(param).PublicKey; -#pragma warning restore SA1312, S1481 - return param; } - private static byte[] GenerateBytesFromHexString(string hex) + private static ImmutableArray GenerateBytesFromHexString(string hex) { byte[] bytes = ByteUtil.ParseHex(hex); if (bytes.Length != KeyByteSize) @@ -434,45 +389,16 @@ private static byte[] GenerateBytesFromHexString(string hex) ); } - return bytes; + return bytes.ToImmutableArray(); } - private ECPoint CalculatePoint(ECPublicKeyParameters pubKeyParams) + private static bool VerifyBytes(in ImmutableArray bytes) { - ECDomainParameters dp = KeyParam.Parameters; - if (!dp.Equals(pubKeyParams.Parameters)) + lock (_secpLock) { - throw new InvalidOperationException( - "ECDH public key has wrong domain parameters" - ); + using var secp256k1 = new Secp256k1(); + return bytes.Length == KeyByteSize && secp256k1.SecretKeyVerify(bytes.ToArray()); } - - BigInteger d = KeyParam.D; - - ECPoint q = dp.Curve.DecodePoint(pubKeyParams.Q.GetEncoded(true)); - if (q.IsInfinity) - { - throw new InvalidOperationException( - "Infinity is not a valid public key for ECDH" - ); - } - - BigInteger h = dp.H; - if (!h.Equals(BigInteger.One)) - { - d = dp.H.ModInverse(dp.N).Multiply(d).Mod(dp.N); - q = ECAlgorithms.ReferenceMultiply(q, h); - } - - ECPoint p = q.Multiply(d).Normalize(); - if (p.IsInfinity) - { - throw new InvalidOperationException( - "Infinity is not a valid agreement value for ECDH" - ); - } - - return p; } } } diff --git a/src/Libplanet.Crypto/PublicKey.cs b/src/Libplanet.Crypto/PublicKey.cs index 65a3fca8239..7496de7c09b 100644 --- a/src/Libplanet.Crypto/PublicKey.cs +++ b/src/Libplanet.Crypto/PublicKey.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Globalization; @@ -10,7 +11,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using Libplanet.Common; -using Org.BouncyCastle.Crypto.Parameters; +using Secp256k1Net; namespace Libplanet.Crypto { @@ -36,13 +37,15 @@ namespace Libplanet.Crypto [JsonConverter(typeof(PublicKeyJsonConverter))] public class PublicKey : IEquatable { + private readonly ImmutableArray _bytes; + /// /// Creates a instance from the given - /// array (i.e., ), + /// array (i.e., ), /// which encodes a valid /// ECDSA public key. /// - /// A valid array that + /// A valid array that /// encodes an ECDSA public key. It can be either compressed or /// not. /// A valid array for @@ -50,14 +53,26 @@ public class PublicKey : IEquatable /// method. /// /// - public PublicKey(IReadOnlyList publicKey) - : this(GetECPublicKeyParameters(publicKey is byte[] ba ? ba : publicKey.ToArray())) + public PublicKey(byte[] bytes) + : this(bytes, verify: true) { } - internal PublicKey(ECPublicKeyParameters keyParam) + internal PublicKey(byte[] bytes, bool verify) { - KeyParam = keyParam; + if (verify) + { + if (!TryGetPublicKey(bytes, out var publicKey)) + { + throw new ArgumentException("Invalid public key bytes.", nameof(bytes)); + } + + _bytes = publicKey!.ToImmutableArray(); + } + else + { + _bytes = bytes.ToImmutableArray(); + } } /// @@ -65,7 +80,7 @@ internal PublicKey(ECPublicKeyParameters keyParam) /// public Address Address => new Address(this); - internal ECPublicKeyParameters KeyParam { get; } + internal ImmutableArray Raw => _bytes; public static bool operator ==(PublicKey left, PublicKey right) => left.Equals(right); @@ -83,13 +98,43 @@ internal PublicKey(ECPublicKeyParameters keyParam) /// is not a valid hexadecimal string. /// public static PublicKey FromHex(string hex) => - new PublicKey(ByteUtil.ParseHex(hex)); + new PublicKey(ByteUtil.ParseHex(hex), verify: true); - public bool Equals(PublicKey? other) => KeyParam.Equals(other?.KeyParam); + public static bool Verify( + Address signer, ImmutableArray message, ImmutableArray signature) + { + if (signature.IsDefaultOrEmpty) + { + return false; + } + + try + { + // var hashed = HashDigest.DeriveFrom(message); + return CryptoConfig.CryptoBackend.Verify( + message.ToArray(), signature.ToArray(), signer); + } + catch (Exception) + { + return false; + } + } + + public bool Equals(PublicKey? other) + => other is not null && _bytes.SequenceEqual(other._bytes); public override bool Equals(object? obj) => obj is PublicKey other && Equals(other); - public override int GetHashCode() => KeyParam.GetHashCode(); + public override int GetHashCode() + { + HashCode hash = default; + foreach (byte b in _bytes) + { + hash.Add(b); + } + + return hash.ToHashCode(); + } /// /// Encodes this public key into a mutable array representation. @@ -105,8 +150,7 @@ public static PublicKey FromHex(string hex) => /// /// [Pure] - public byte[] Format(bool compress) => - KeyParam.Q.GetEncoded(compress); + public byte[] Format(bool compress) => PrivateKey.GetPublicKey(_bytes, compress); /// /// Encodes this public key into a immutable array representation. @@ -124,6 +168,9 @@ public byte[] Format(bool compress) => public ImmutableArray ToImmutableArray(bool compress) => Format(compress).ToImmutableArray(); + [Pure] + public byte[] ToArray() => Format(false); + /// /// Encrypts a plaintext to a ciphertext, which can be decrypted /// with the corresponding . @@ -180,41 +227,7 @@ public ImmutableArray Encrypt(ImmutableArray message) => /// Otherwise . [Pure] public bool Verify(IReadOnlyList message, IReadOnlyList signature) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - if (signature == null) - { - throw new ArgumentNullException(nameof(signature)); - } - - if (signature is ImmutableArray i ? i.IsDefaultOrEmpty : !signature.Any()) - { - return false; - } - - try - { - HashDigest hashed = message switch - { - byte[] ma => HashDigest.DeriveFrom(ma), - ImmutableArray im => HashDigest.DeriveFrom(im), - _ => HashDigest.DeriveFrom(message.ToArray()), - }; - return CryptoConfig.CryptoBackend.Verify( - hashed, - signature is byte[] ba ? ba : signature.ToArray(), - publicKey: this - ); - } - catch (Exception) - { - return false; - } - } + => Verify(Address, message.ToImmutableArray(), signature.ToImmutableArray()); /// /// Gets the public key's hexadecimal representation in compressed form. @@ -228,14 +241,21 @@ public bool Verify(IReadOnlyList message, IReadOnlyList signature) /// public override string ToString() => ToHex(true); - private static ECPublicKeyParameters GetECPublicKeyParameters(byte[] bs) + private static bool TryGetPublicKey( + byte[] bytes, [MaybeNullWhen(false)] out byte[] publicKey) { - var ecParams = PrivateKey.GetECParameters(); - return new ECPublicKeyParameters( - "ECDSA", - ecParams.Curve.DecodePoint(bs), - ecParams - ); + lock (PrivateKey._secpLock) + { + using var secp256k1 = new Secp256k1(); + publicKey = new byte[Secp256k1.PUBKEY_LENGTH]; + if (secp256k1.PublicKeyParse(publicKey, bytes)) + { + return true; + } + + publicKey = null; + return false; + } } } diff --git a/src/Libplanet.Crypto/SymmetricKey.cs b/src/Libplanet.Crypto/SymmetricKey.cs index 5cfbcce5a43..84a0b8803b1 100644 --- a/src/Libplanet.Crypto/SymmetricKey.cs +++ b/src/Libplanet.Crypto/SymmetricKey.cs @@ -3,12 +3,8 @@ using System.Diagnostics.Contracts; using System.IO; using System.Linq; +using System.Security.Cryptography; using Libplanet.Common; -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Modes; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Security; namespace Libplanet.Crypto { @@ -23,11 +19,11 @@ namespace Libplanet.Crypto /// public class SymmetricKey : IEquatable { - private const int KeyBitSize = 256; - private const int MacBitSize = 128; - private const int NonceBitSize = 128; + private const int KeyByteSize = 32; // 256 bits + private const int TagByteSize = 16; // 128 bits + private const int NonceByteSize = 12; // 128 bits - private readonly SecureRandom _secureRandom; + private readonly RandomNumberGenerator _secureRandom; private readonly byte[] _key; @@ -51,12 +47,12 @@ public class SymmetricKey : IEquatable /// public SymmetricKey(byte[] key) { - _secureRandom = new SecureRandom(); + _secureRandom = RandomNumberGenerator.Create(); - if (key == null || key.Length != KeyBitSize / 8) + if (key == null || key.Length != KeyByteSize) { throw new ArgumentException( - $"Key needs to be {KeyBitSize} bit!", + $"Key needs to be {KeyByteSize} bytes!", nameof(key)); } @@ -113,33 +109,29 @@ public bool Equals(SymmetricKey? other) /// /// [Pure] - public byte[] Encrypt(byte[] message, byte[]? nonSecret = null) + public byte[] Encrypt(byte[] message, byte[] nonSecret) { - var nonce = new byte[NonceBitSize / 8]; - _secureRandom.NextBytes(nonce, 0, nonce.Length); - - nonSecret = nonSecret ?? new byte[] { }; - - var cipher = new GcmBlockCipher(new AesEngine()); - var parameters = new AeadParameters( - new KeyParameter(_key), MacBitSize, nonce, nonSecret - ); - cipher.Init(true, parameters); - - var cipherText = new byte[cipher.GetOutputSize(message.Length)]; - int len = - cipher.ProcessBytes(message, 0, message.Length, cipherText, 0); - cipher.DoFinal(cipherText, len); - - using var combinedStream = new MemoryStream(); - using (var binaryWriter = new BinaryWriter(combinedStream)) - { - binaryWriter.Write(nonSecret); - binaryWriter.Write(nonce); - binaryWriter.Write(cipherText); - } - - return combinedStream.ToArray(); +#if NETSTANDARD2_0_OR_GREATER + using var aes = new AesGcm(_key); +#else + using var aes = new AesGcm(_key, tagSizeInBytes: TagByteSize); +#endif + byte[] nonce = new byte[NonceByteSize]; + _secureRandom.GetBytes(nonce); + + byte[] ciphertext = new byte[message.Length]; + byte[] tag = new byte[TagByteSize]; + _secureRandom.GetBytes(nonce); + + aes.Encrypt(nonce, message, ciphertext, tag, nonSecret); + + using var resultStream = new MemoryStream(); + using var writer = new BinaryWriter(resultStream); + writer.Write(nonSecret); + writer.Write(nonce); + writer.Write(ciphertext); + writer.Write(tag); + return resultStream.ToArray(); } /// @@ -164,48 +156,30 @@ public byte[] Encrypt(byte[] message, byte[]? nonSecret = null) [Pure] public byte[] Decrypt(byte[] ciphertext, int nonSecretLength = 0) { - if (ciphertext == null || ciphertext.Length == 0) - { - throw new ArgumentException( - "Encrypted Message Required!", - nameof(ciphertext)); - } - - using var cipherStream = new MemoryStream(ciphertext); - using var cipherReader = new BinaryReader(cipherStream); - byte[] nonSecretPayload = cipherReader.ReadBytes( - nonSecretLength - ); - byte[] nonce = cipherReader.ReadBytes(NonceBitSize / 8); - - var cipher = new GcmBlockCipher(new AesEngine()); - var parameters = new AeadParameters( - new KeyParameter(_key), - MacBitSize, - nonce, - nonSecretPayload); - cipher.Init(false, parameters); - - byte[] cipherText = cipherReader.ReadBytes( - ciphertext.Length - nonSecretLength - nonce.Length - ); - var plainText = - new byte[cipher.GetOutputSize(cipherText.Length)]; - +#if NETSTANDARD2_0_OR_GREATER + using var aes = new AesGcm(_key); +#else + using var aes = new AesGcm(_key, tagSizeInBytes: TagByteSize); +#endif + using var inputStream = new MemoryStream(ciphertext); + using var reader = new BinaryReader(inputStream); + var nonSecretPayload = reader.ReadBytes(nonSecretLength); + + byte[] nonce = reader.ReadBytes(NonceByteSize); + byte[] encryptedMessage = reader.ReadBytes( + ciphertext.Length - nonSecretLength - nonce.Length - TagByteSize); + byte[] tag = reader.ReadBytes(TagByteSize); + + byte[] decryptedMessage = new byte[encryptedMessage.Length]; try { - int len = cipher.ProcessBytes( - cipherText, 0, cipherText.Length, plainText, 0 - ); - cipher.DoFinal(plainText, len); - return plainText; + aes.Decrypt(nonce, encryptedMessage, tag, decryptedMessage, nonSecretPayload); + return decryptedMessage; } - catch (InvalidCipherTextException) + catch (Exception e) { - throw new InvalidCiphertextException( - "The ciphertext is invalid. " + - "Ciphertext may not have been encrypted with " + - "the corresponding public key"); + var message = "Failed to decrypt the ciphertext."; + throw new InvalidCiphertextException(message, e); } } diff --git a/src/Libplanet.Net/AppProtocolVersion.cs b/src/Libplanet.Net/AppProtocolVersion.cs index 1fb63805380..4e65555bea5 100644 --- a/src/Libplanet.Net/AppProtocolVersion.cs +++ b/src/Libplanet.Net/AppProtocolVersion.cs @@ -7,7 +7,6 @@ using Bencodex.Types; using Libplanet.Common; using Libplanet.Crypto; -using NetMQ; namespace Libplanet.Net { @@ -280,16 +279,10 @@ public override string ToString() => string.Format( [Pure] private static byte[] GetMessage(int version, IValue? extra) { - byte[] msg = NetworkOrderBitsConverter.GetBytes(version); - if (!(extra is null)) - { - byte[] extraBytes = _codec.Encode(extra); - int versionLength = msg.Length; - Array.Resize(ref msg, versionLength + extraBytes.Length); - extraBytes.CopyTo(msg, versionLength); - } - - return msg; + var list = new List( + new Integer(version), + extra is null ? Null.Value : extra); + return ByteUtil.CreateMessage(list); } } } diff --git a/src/Libplanet.Net/BoundPeer.cs b/src/Libplanet.Net/BoundPeer.cs index 64d2b99b530..1ffb055b20c 100644 --- a/src/Libplanet.Net/BoundPeer.cs +++ b/src/Libplanet.Net/BoundPeer.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics.Contracts; using System.Globalization; +using System.Linq; using System.Net; using Bencodex; using Bencodex.Types; @@ -59,7 +60,7 @@ internal BoundPeer( private BoundPeer(Bencodex.Types.Dictionary bencoded) : this( - new PublicKey(((Binary)bencoded[PublicKeyKey]).ByteArray), + new PublicKey(((Binary)bencoded[PublicKeyKey]).ByteArray.ToArray()), new DnsEndPoint( (Text)bencoded[EndPointHostKey], (Integer)bencoded[EndPointPortKey]), bencoded[PublicIpAddressKey] is Text text ? IPAddress.Parse(text) : null) diff --git a/src/Libplanet.Store/BlockSet.cs b/src/Libplanet.Store/BlockSet.cs index 59b45b83673..a7882d109d7 100644 --- a/src/Libplanet.Store/BlockSet.cs +++ b/src/Libplanet.Store/BlockSet.cs @@ -157,7 +157,7 @@ public IEnumerator> GetEnumerator() private Block? GetBlock(BlockHash key) { - if (_cache.TryGet(key, out Block cached)) + if (_cache.TryGet(key, out Block? cached)) { if (_store.ContainsBlock(key)) { diff --git a/src/Libplanet.Types/Blocks/BlockMarshaler.cs b/src/Libplanet.Types/Blocks/BlockMarshaler.cs index 1ca963c4cd0..0cac497335f 100644 --- a/src/Libplanet.Types/Blocks/BlockMarshaler.cs +++ b/src/Libplanet.Types/Blocks/BlockMarshaler.cs @@ -175,7 +175,7 @@ public static BlockMetadata UnmarshalBlockMetadata(Dictionary marshaled) PublicKey? publicKey = null; if (marshaled.ContainsKey(PublicKeyKey)) { - publicKey = new PublicKey(((Binary)marshaled[PublicKeyKey]).ByteArray); + publicKey = new PublicKey(((Binary)marshaled[PublicKeyKey]).ByteArray.ToArray()); miner = publicKey.Address; } else diff --git a/src/Libplanet.Types/Consensus/Validator.cs b/src/Libplanet.Types/Consensus/Validator.cs index 539e7b13e06..4fea566a280 100644 --- a/src/Libplanet.Types/Consensus/Validator.cs +++ b/src/Libplanet.Types/Consensus/Validator.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Numerics; using System.Text.Json.Serialization; using Bencodex; @@ -53,7 +54,7 @@ public Validator(Bencodex.Types.IValue bencoded) private Validator(Bencodex.Types.Dictionary bencoded) : this( - new PublicKey(((Binary)bencoded[PublicKeyKey]).ByteArray), + new PublicKey(((Binary)bencoded[PublicKeyKey]).ByteArray.ToArray()), (Integer)bencoded[PowerKey]) { } diff --git a/src/Libplanet.Types/Consensus/VoteMetadata.cs b/src/Libplanet.Types/Consensus/VoteMetadata.cs index cf9adbe39a2..73904072d2c 100644 --- a/src/Libplanet.Types/Consensus/VoteMetadata.cs +++ b/src/Libplanet.Types/Consensus/VoteMetadata.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Globalization; +using System.Linq; using System.Numerics; using System.Text.Json.Serialization; using Bencodex; @@ -126,7 +127,7 @@ private VoteMetadata(Bencodex.Types.Dictionary bencoded) TimestampFormat, CultureInfo.InvariantCulture), validatorPublicKey: new PublicKey( - ((Binary)bencoded[ValidatorPublicKeyKey]).ByteArray), + ((Binary)bencoded[ValidatorPublicKeyKey]).ByteArray.ToArray()), validatorPower: bencoded.ContainsKey(ValidatorPowerKey) ? (Integer)bencoded[ValidatorPowerKey] : (Integer?)null, diff --git a/src/Libplanet.Types/Tx/ITxSigningMetadata.cs b/src/Libplanet.Types/Tx/ITxSigningMetadata.cs index 83b88e67adb..4a003af8dd1 100644 --- a/src/Libplanet.Types/Tx/ITxSigningMetadata.cs +++ b/src/Libplanet.Types/Tx/ITxSigningMetadata.cs @@ -24,12 +24,5 @@ public interface ITxSigningMetadata : IEquatable /// from the . /// Address Signer { get; } - - /// - /// A of the account who signs this transaction. - /// The address is always corresponding to this for each transaction. - /// This cannot be . - /// - PublicKey PublicKey { get; } } } diff --git a/src/Libplanet.Types/Tx/Transaction.cs b/src/Libplanet.Types/Tx/Transaction.cs index 9d54135779c..f0c5b8a990b 100644 --- a/src/Libplanet.Types/Tx/Transaction.cs +++ b/src/Libplanet.Types/Tx/Transaction.cs @@ -156,9 +156,6 @@ private set /// public DateTimeOffset Timestamp => _unsignedTx.Timestamp; - /// - public PublicKey PublicKey => _unsignedTx.PublicKey; - /// public BlockHash? GenesisHash => _unsignedTx.GenesisHash; @@ -319,7 +316,7 @@ private static Transaction Create( actions, maxGasPrice, gasLimit); - var signMeta = new TxSigningMetadata(privateKey.PublicKey, nonce); + var signMeta = new TxSigningMetadata(privateKey.Address, nonce); var invoice = new TxInvoice( draftInvoice.GenesisHash, draftInvoice.UpdatedAddresses, diff --git a/src/Libplanet.Types/Tx/TransactionExtensions.cs b/src/Libplanet.Types/Tx/TransactionExtensions.cs index b9fe0737250..b65a7dd30fd 100644 --- a/src/Libplanet.Types/Tx/TransactionExtensions.cs +++ b/src/Libplanet.Types/Tx/TransactionExtensions.cs @@ -85,7 +85,7 @@ public static Transaction Sign( PrivateKey privateKey, long nonce) => - invoice.Combine(new TxSigningMetadata(privateKey.PublicKey, nonce)).Sign(privateKey); + invoice.Combine(new TxSigningMetadata(privateKey.Address, nonce)).Sign(privateKey); /// /// A instance. diff --git a/src/Libplanet.Types/Tx/TxMarshaler.cs b/src/Libplanet.Types/Tx/TxMarshaler.cs index 22d400780d8..d728df2f039 100644 --- a/src/Libplanet.Types/Tx/TxMarshaler.cs +++ b/src/Libplanet.Types/Tx/TxMarshaler.cs @@ -2,9 +2,13 @@ using System.Collections.Immutable; using System.Diagnostics.Contracts; using System.Globalization; +using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using System.Text; +using System.Text.Json; using Bencodex; +using Bencodex.Json; using Bencodex.Types; using Libplanet.Crypto; using Libplanet.Types.Assets; @@ -22,11 +26,20 @@ public static class TxMarshaler private static readonly Binary GasLimitKey = new Binary(new byte[] { 0x6c }); // 'l' private static readonly Binary NonceKey = new Binary(new byte[] { 0x6e }); // 'n' private static readonly Binary SignerKey = new Binary(new byte[] { 0x73 }); // 's' - private static readonly Binary PublicKeyKey = new Binary(new byte[] { 0x70 }); // 'p' private static readonly Binary SignatureKey = new Binary(new byte[] { 0x53 }); // 'S' private static readonly Binary ActionsKey = new Binary(new byte[] { 0x61 }); // 'a' private static readonly Codec Codec = new Codec(); + private static readonly BencodexJsonConverter BencodexJsonConverter = new (); + private static readonly JsonSerializerOptions SerializerOptions = new () + { + WriteIndented = true, + Converters = + { + BencodexJsonConverter, + }, + }; + [Pure] public static Bencodex.Types.Dictionary MarshalTxInvoice(this ITxInvoice invoice) { @@ -70,23 +83,33 @@ public static Bencodex.Types.Dictionary MarshalTxSigningMetadata( this ITxSigningMetadata metadata ) => Dictionary.Empty .Add(NonceKey, metadata.Nonce) - .Add(SignerKey, metadata.Signer.Bencoded) - .Add(PublicKeyKey, metadata.PublicKey.ToImmutableArray(compress: false)); + .Add(SignerKey, metadata.Signer.Bencoded); [Pure] - public static Bencodex.Types.Dictionary MarshalUnsignedTx(this IUnsignedTx unsignedTx) => - (Bencodex.Types.Dictionary)unsignedTx.MarshalTxInvoice() + public static Dictionary MarshalUnsignedTx(this IUnsignedTx unsignedTx) + => (Dictionary)unsignedTx.MarshalTxInvoice() .AddRange(unsignedTx.MarshalTxSigningMetadata()); [Pure] - public static Bencodex.Types.Dictionary MarshalTransaction( - this Transaction transaction) => - transaction.MarshalUnsignedTx().Add(SignatureKey, transaction.Signature); + public static string SerializeUnsignedTxToJson(this IUnsignedTx unsignedTx) + { + var dict = unsignedTx.MarshalUnsignedTx(); + using var ms = new MemoryStream(); + using var writer = new Utf8JsonWriter(ms, new JsonWriterOptions { Indented = true }); + BencodexJsonConverter.Write(writer, dict, SerializerOptions); + ms.Position = 0; + using var sr = new StreamReader(ms); + return sr.ReadToEnd(); + } + + [Pure] + public static Dictionary MarshalTransaction(this Transaction transaction) + => transaction.MarshalUnsignedTx().Add(SignatureKey, transaction.Signature); [Pure] public static ImmutableArray SerializeUnsignedTx(this IUnsignedTx unsignedTx) { - Bencodex.Types.Dictionary dict = unsignedTx.MarshalUnsignedTx(); + Dictionary dict = unsignedTx.MarshalUnsignedTx(); byte[] encoded = Codec.Encode(dict); ImmutableArray movedBytes = Unsafe.As>(ref encoded); @@ -125,8 +148,8 @@ public static ITxSigningMetadata UnmarshalTxSigningMetadata( Bencodex.Types.Dictionary dictionary ) => new TxSigningMetadata( - nonce: (Bencodex.Types.Integer)dictionary[NonceKey], - publicKey: new PublicKey(((Binary)dictionary[PublicKeyKey]).ByteArray) + signer: new Address(dictionary[SignerKey]), + nonce: (Bencodex.Types.Integer)dictionary[NonceKey] ); [Pure] @@ -169,6 +192,24 @@ public static IUnsignedTx DeserializeUnsignedTx(byte[] bytes) $"but {node.GetType().Name} given."); } + [Pure] + public static IUnsignedTx DeserializeUnsignedTxFromJson(string json) + { + using var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)); + var reader = new Utf8JsonReader(ms.ToArray()); + var value = BencodexJsonConverter.Read(ref reader, typeof(IValue), SerializerOptions) + ?? throw new InvalidOperationException("Failed to parse the unsigned transaction."); + if (value is Dictionary dict) + { + return UnmarshalUnsignedTx(dict); + } + + throw new DecodingException( + $"Expected a {typeof(Bencodex.Types.Dictionary).FullName}, " + + $"but {value.GetType().Name} given." + ); + } + [Pure] public static IUnsignedTx DeserializeUnsignedTx(ImmutableArray bytes) { diff --git a/src/Libplanet.Types/Tx/TxMetadata.cs b/src/Libplanet.Types/Tx/TxMetadata.cs index 411f292a416..487a75f8783 100644 --- a/src/Libplanet.Types/Tx/TxMetadata.cs +++ b/src/Libplanet.Types/Tx/TxMetadata.cs @@ -23,18 +23,17 @@ public sealed class TxMetadata private static readonly Binary SignerKey = new Binary(new byte[] { 0x73 }); // 's' private static readonly Binary GenesisHashKey = new Binary(new byte[] { 0x67 }); // 'g' private static readonly Binary UpdatedAddressesKey = new Binary(new byte[] { 0x75 }); // 'u' - private static readonly Binary PublicKeyKey = new Binary(new byte[] { 0x70 }); // 'p' private static readonly Binary TimestampKey = new Binary(new byte[] { 0x74 }); // 't' /// /// Creates a instance with a . /// Other fields can be set using property setters. /// - /// Configures and . + /// Configures . /// - public TxMetadata(PublicKey publicKey) + public TxMetadata(Address signer) { - PublicKey = publicKey; + Signer = signer; } /// @@ -50,7 +49,7 @@ public TxMetadata(ITransaction metadata) Nonce = metadata.Nonce; GenesisHash = metadata.GenesisHash; UpdatedAddresses = metadata.UpdatedAddresses; - PublicKey = metadata.PublicKey; + Signer = metadata.Signer; Timestamp = metadata.Timestamp; } @@ -72,7 +71,7 @@ public TxMetadata(Bencodex.Types.Dictionary dictionary) UpdatedAddresses = ((List)dictionary[UpdatedAddressesKey]) .Select(v => new Address(v)) .ToImmutableHashSet(); - PublicKey = new PublicKey(((Binary)dictionary[PublicKeyKey]).ByteArray); + Signer = new Address(((Binary)dictionary[SignerKey]).ByteArray); Timestamp = DateTimeOffset.ParseExact( (Text)dictionary[TimestampKey], TimestampFormat, @@ -89,10 +88,9 @@ public TxMetadata(Bencodex.Types.Dictionary dictionary) /// /// A of the account who signs this transaction. - /// This is derived from the . /// /// This is automatically derived from . - public Address Signer => new Address(PublicKey); + public Address Signer { get; } /// /// An approximated list of addresses whose states would be affected by actions in this @@ -107,13 +105,6 @@ public TxMetadata(Bencodex.Types.Dictionary dictionary) /// public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.UtcNow; - /// - /// A of the account who signs this transaction. - /// The address is always corresponding to this - /// for each transaction. This cannot be . - /// - public PublicKey PublicKey { get; } - /// /// A value of the genesis which this transaction is made /// from. This can be iff the transaction is contained in @@ -133,7 +124,6 @@ public Bencodex.Types.Dictionary ToBencodex() .Add(NonceKey, Nonce) .Add(SignerKey, Signer.Bencoded) .Add(UpdatedAddressesKey, updatedAddresses) - .Add(PublicKeyKey, PublicKey.ToImmutableArray(compress: false)) .Add(TimestampKey, timestamp); if (GenesisHash is { } genesisHash) @@ -155,7 +145,6 @@ public override string ToString() (UpdatedAddresses.Any() ? $"\n {string.Join("\n ", UpdatedAddresses)};\n" : ";\n") + - $" {nameof(PublicKey)} = {PublicKey},\n" + $" {nameof(Timestamp)} = {Timestamp},\n" + $" {nameof(GenesisHash)} = {GenesisHash?.ToString() ?? "(null)"},\n" + "}"; diff --git a/src/Libplanet.Types/Tx/TxSigningMetadata.cs b/src/Libplanet.Types/Tx/TxSigningMetadata.cs index 8ce71cd106f..9b0943824a6 100644 --- a/src/Libplanet.Types/Tx/TxSigningMetadata.cs +++ b/src/Libplanet.Types/Tx/TxSigningMetadata.cs @@ -16,11 +16,11 @@ public sealed class TxSigningMetadata : ITxSigningMetadata, IEquatable /// Creates a new instance by filling data for its fields. /// - /// The value for . + /// The value for . /// The value for . /// Thrown when the given /// is less than 0. - public TxSigningMetadata(PublicKey publicKey, long nonce) + public TxSigningMetadata(Address signer, long nonce) { if (nonce < 0) { @@ -29,10 +29,15 @@ public TxSigningMetadata(PublicKey publicKey, long nonce) $"The nonce must be greater than or equal to 0, but {nonce} was given."); } - PublicKey = publicKey; + Signer = signer; Nonce = nonce; } + public TxSigningMetadata(PublicKey publicKey, long nonce) + : this(publicKey.Address, nonce) + { + } + /// /// Creates a new instance by copying the fields from /// the given . @@ -40,16 +45,13 @@ public TxSigningMetadata(PublicKey publicKey, long nonce) /// The instance to copy /// fields from. public TxSigningMetadata(ITxSigningMetadata signingMetadata) - : this(signingMetadata.PublicKey, signingMetadata.Nonce) + : this(signingMetadata.Signer, signingMetadata.Nonce) { } /// /// This is automatically derived from . - public Address Signer => new Address(PublicKey); - - /// - public PublicKey PublicKey { get; } + public Address Signer { get; } /// public long Nonce { get; } @@ -57,7 +59,7 @@ public TxSigningMetadata(ITxSigningMetadata signingMetadata) /// [Pure] bool IEquatable.Equals(ITxSigningMetadata? other) => - other is { } o && o.PublicKey.Equals(PublicKey) && o.Nonce == Nonce; + other is { } o && o.Signer.Equals(Signer) && o.Nonce == Nonce; /// [Pure] @@ -71,7 +73,7 @@ public override bool Equals(object? obj) => /// [Pure] - public override int GetHashCode() => HashCode.Combine(PublicKey, Nonce); + public override int GetHashCode() => HashCode.Combine(Signer, Nonce); /// [Pure] @@ -80,7 +82,6 @@ public override string ToString() return nameof(TxMetadata) + " {\n" + $" {nameof(Nonce)} = {Nonce},\n" + $" {nameof(Signer)} = {Signer},\n" + - $" {nameof(PublicKey)} = {PublicKey},\n" + "}"; } } diff --git a/src/Libplanet.Types/Tx/UnsignedTx.cs b/src/Libplanet.Types/Tx/UnsignedTx.cs index be6afe80f34..65cb875e8b0 100644 --- a/src/Libplanet.Types/Tx/UnsignedTx.cs +++ b/src/Libplanet.Types/Tx/UnsignedTx.cs @@ -1,10 +1,14 @@ using System; using System.Collections.Immutable; using System.Diagnostics.Contracts; +using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using System.Text; +using System.Text.Json; using System.Text.Json.Serialization; using Bencodex; +using Bencodex.Json; using Libplanet.Crypto; using Libplanet.Types.Assets; using Libplanet.Types.Blocks; @@ -90,20 +94,17 @@ public UnsignedTx(ITxInvoice invoice, ITxSigningMetadata signingMetadata) /// public Address Signer => _signingMetadata.Signer; - /// - public PublicKey PublicKey => _signingMetadata.PublicKey; - /// /// Creates a signature for this transaction with the given . /// /// The private key to sign this transaction. /// A signature for this transaction. /// Thrown when the given - /// does not correspond to the of this transaction. + /// does not correspond to the of this transaction. [Pure] public ImmutableArray CreateSignature(PrivateKey privateKey) { - if (!privateKey.PublicKey.Equals(PublicKey)) + if (!privateKey.Address.Equals(Signer)) { throw new ArgumentException( "The given private key does not correspond to the public key.", @@ -125,7 +126,7 @@ public ImmutableArray CreateSignature(PrivateKey privateKey) /// this transaction, otherwise . [Pure] public bool VerifySignature(ImmutableArray signature) => - PublicKey.Verify(CreateMessage(), signature); + PublicKey.Verify(Signer, CreateMessage().ToImmutableArray(), signature); /// [Pure] @@ -175,12 +176,14 @@ public override string ToString() $" {nameof(Actions)} = {indentedActions},\n" + $" {nameof(Nonce)} = {Nonce},\n" + $" {nameof(Signer)} = {Signer},\n" + - $" {nameof(PublicKey)} = {PublicKey},\n" + "}"; } [Pure] - private byte[] CreateMessage() => - _codec.Encode(this.MarshalUnsignedTx()); + private byte[] CreateMessage() + { + var json = this.SerializeUnsignedTxToJson(); + return Encoding.UTF8.GetBytes(json); + } } } diff --git a/src/Libplanet/Consensus/Maj23Metadata.cs b/src/Libplanet/Consensus/Maj23Metadata.cs index 7b2eacebe38..6b5267364c0 100644 --- a/src/Libplanet/Consensus/Maj23Metadata.cs +++ b/src/Libplanet/Consensus/Maj23Metadata.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Globalization; +using System.Linq; using System.Text.Json.Serialization; using Bencodex; using Bencodex.Types; @@ -80,7 +81,7 @@ public Maj23Metadata(Dictionary encoded) TimestampFormat, CultureInfo.InvariantCulture), validatorPublicKey: new PublicKey( - ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray), + ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray.ToArray()), flag: (VoteFlag)(int)(Integer)encoded[FlagKey]) { } diff --git a/src/Libplanet/Consensus/ProposalClaimMetadata.cs b/src/Libplanet/Consensus/ProposalClaimMetadata.cs index 3c6064cd796..f648f5695d7 100644 --- a/src/Libplanet/Consensus/ProposalClaimMetadata.cs +++ b/src/Libplanet/Consensus/ProposalClaimMetadata.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Globalization; +using System.Linq; using System.Text.Json.Serialization; using Bencodex; using Bencodex.Types; @@ -91,7 +92,7 @@ public ProposalClaimMetadata(Dictionary encoded) TimestampFormat, CultureInfo.InvariantCulture), validatorPublicKey: new PublicKey( - ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray)) + ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray.ToArray())) { } #pragma warning restore SA1118 diff --git a/src/Libplanet/Consensus/ProposalMetadata.cs b/src/Libplanet/Consensus/ProposalMetadata.cs index 0b251391279..9892323358c 100644 --- a/src/Libplanet/Consensus/ProposalMetadata.cs +++ b/src/Libplanet/Consensus/ProposalMetadata.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Globalization; +using System.Linq; using System.Text.Json.Serialization; using Bencodex; using Bencodex.Types; @@ -108,7 +109,7 @@ public ProposalMetadata(Dictionary encoded) TimestampFormat, CultureInfo.InvariantCulture), validatorPublicKey: new PublicKey( - ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray), + ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray.ToArray()), marshaledBlock: ((Binary)encoded[BlockKey]).ToByteArray(), validRound: (Integer)encoded[ValidRoundKey]) { diff --git a/src/Libplanet/Consensus/VoteSetBitsMetadata.cs b/src/Libplanet/Consensus/VoteSetBitsMetadata.cs index e56a5f1f1ba..c78f38a93ba 100644 --- a/src/Libplanet/Consensus/VoteSetBitsMetadata.cs +++ b/src/Libplanet/Consensus/VoteSetBitsMetadata.cs @@ -87,7 +87,7 @@ public VoteSetBitsMetadata(Dictionary encoded) TimestampFormat, CultureInfo.InvariantCulture), validatorPublicKey: new PublicKey( - ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray), + ((Binary)encoded[ValidatorPublicKeyKey]).ByteArray.ToArray()), flag: (VoteFlag)(int)(Integer)encoded[FlagKey], voteBits: ((List)encoded[VoteBitsKey]) .Select(bit => (bool)(Bencodex.Types.Boolean)bit)) diff --git a/src/Libplanet/KeyStore/ProtectedPrivateKey.cs b/src/Libplanet/KeyStore/ProtectedPrivateKey.cs index d0d2a3ae233..d63b7468cb9 100644 --- a/src/Libplanet/KeyStore/ProtectedPrivateKey.cs +++ b/src/Libplanet/KeyStore/ProtectedPrivateKey.cs @@ -322,10 +322,7 @@ public PrivateKey Unprotect(string passphrase) ImmutableArray encKey = MakeEncryptionKey(derivedKey); ImmutableArray plaintext = Cipher.Decrypt(encKey, Ciphertext); - var key = new PrivateKey( - unverifiedKey: plaintext.ToBuilder().ToArray(), - informedConsent: true - ); + var key = new PrivateKey(plaintext.ToBuilder().ToArray()); Address actualAddress = key.Address; if (!Address.Equals(actualAddress)) { diff --git a/src/Libplanet/Libplanet.csproj b/src/Libplanet/Libplanet.csproj index e7c328d29bc..4a159ca6530 100644 --- a/src/Libplanet/Libplanet.csproj +++ b/src/Libplanet/Libplanet.csproj @@ -30,15 +30,10 @@ https://docs.libplanet.io/ - + - - - - diff --git a/test/Libplanet.Crypto.Secp256k1.Tests/Libplanet.Crypto.Secp256k1.Tests.csproj b/test/Libplanet.Crypto.Secp256k1.Tests/Libplanet.Crypto.Secp256k1.Tests.csproj deleted file mode 100644 index e9b0254b78d..00000000000 --- a/test/Libplanet.Crypto.Secp256k1.Tests/Libplanet.Crypto.Secp256k1.Tests.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - true - - - - - - - - - - - - - - - - diff --git a/test/Libplanet.Crypto.Secp256k1.Tests/Secp256k1CryptoBackendTest.cs b/test/Libplanet.Crypto.Secp256k1.Tests/Secp256k1CryptoBackendTest.cs deleted file mode 100644 index b26e0bcd3de..00000000000 --- a/test/Libplanet.Crypto.Secp256k1.Tests/Secp256k1CryptoBackendTest.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Libplanet.Common; -using Libplanet.Crypto; - -namespace Libplanet.Crypto.Secp256k1.Tests; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using Libplanet.Crypto; -using Libplanet.Crypto.Secp256k1; -using Xunit; - -public class Secp256k1CryptoBackendTest -{ - public static IEnumerable GenerateRandomBytes() - { - Random random = new (); - yield return new object[] { Array.Empty() }; - for (int i = 1; i < 100; i++) - { - byte[] bytes = new byte[i]; - random.NextBytes(bytes); - yield return new object[] { bytes }; - } - } - - [Theory] - [MemberData(nameof(GenerateRandomBytes))] - public void EnsureIfItBehavesEquivalentToDefaultCryptoBackend(byte[] bytes) - { - DefaultCryptoBackend defaultBackend = new (); - Secp256k1CryptoBackend nativeBackend = new (); - PrivateKey key = new (); - PublicKey pubKey = key.PublicKey; - var msgHash = HashDigest.DeriveFrom(bytes); - byte[] wrongHashBytes = new byte[HashDigest.Size]; - Array.Copy(msgHash.ToByteArray(), 0, wrongHashBytes, 0, wrongHashBytes.Length - 1); - wrongHashBytes[wrongHashBytes.Length - 1] = - unchecked((byte)(msgHash.ByteArray.Last() + 1)); - HashDigest wrongHash = new (wrongHashBytes); - - byte[] nativeSig = nativeBackend.Sign(msgHash, key); - Assert.True(defaultBackend.Verify(msgHash, nativeSig, pubKey)); - byte[] wrongNativeSig = nativeBackend.Sign(wrongHash, key); - Assert.False(defaultBackend.Verify(msgHash, wrongNativeSig, pubKey)); - - byte[] defaultSig = defaultBackend.Sign(msgHash, key); - Assert.True(nativeBackend.Verify(msgHash, defaultSig, pubKey)); - byte[] wrongDefaultSig = defaultBackend.Sign(wrongHash, key); - Assert.False(nativeBackend.Verify(msgHash, wrongDefaultSig, pubKey)); - } -} diff --git a/test/Libplanet.Explorer.Tests/GraphTypes/TransactionTypeTest.cs b/test/Libplanet.Explorer.Tests/GraphTypes/TransactionTypeTest.cs index a611b73c21b..2c605164223 100644 --- a/test/Libplanet.Explorer.Tests/GraphTypes/TransactionTypeTest.cs +++ b/test/Libplanet.Explorer.Tests/GraphTypes/TransactionTypeTest.cs @@ -33,7 +33,6 @@ public async Task Query() id nonce signer - publicKey updatedAddresses signature timestamp @@ -51,9 +50,6 @@ await ExecuteQueryAsync( (Dictionary)((ExecutionNode) result.Data!)?.ToValue()!; Assert.Null(result.Errors); Assert.Equal(transaction.Id.ToHex(), resultData["id"]); - Assert.Equal( - ByteUtil.Hex(transaction.PublicKey.Format(true)), - resultData["publicKey"]); Assert.Equal(transaction.Signer.ToString(), resultData["signer"]); Assert.Equal(ByteUtil.Hex(transaction.Signature), resultData["signature"]); Assert.Equal(transaction.Nonce, resultData["nonce"]); diff --git a/test/Libplanet.Extensions.Cocona.Tests/Fixtures/tx.bin b/test/Libplanet.Extensions.Cocona.Tests/Fixtures/tx.bin index dd41b6d212a..77112decac1 100644 Binary files a/test/Libplanet.Extensions.Cocona.Tests/Fixtures/tx.bin and b/test/Libplanet.Extensions.Cocona.Tests/Fixtures/tx.bin differ diff --git a/test/Libplanet.Mocks/Libplanet.Mocks.csproj b/test/Libplanet.Mocks/Libplanet.Mocks.csproj index 7a9608f925c..4cc315eab27 100644 --- a/test/Libplanet.Mocks/Libplanet.Mocks.csproj +++ b/test/Libplanet.Mocks/Libplanet.Mocks.csproj @@ -1,7 +1,7 @@ - $(TargetFrameworks);netstandard2.0;netstandard2.1 + $(TargetFrameworks);netstandard2.1 true false true diff --git a/test/Libplanet.Net.Tests/AppProtocolVersionTest.cs b/test/Libplanet.Net.Tests/AppProtocolVersionTest.cs index 8897a4a6782..ec1110ce372 100644 --- a/test/Libplanet.Net.Tests/AppProtocolVersionTest.cs +++ b/test/Libplanet.Net.Tests/AppProtocolVersionTest.cs @@ -23,12 +23,11 @@ public class AppProtocolVersionTest signer: SignerFixture.Address, signature: new byte[] { - 0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0x95, 0x9c, 0x59, 0x25, 0x83, 0x4e, - 0xbc, 0x45, 0x59, 0xd7, 0x9b, 0xca, 0x82, 0x4a, 0x69, 0x20, 0xe5, 0x18, - 0xf0, 0xc5, 0xad, 0xe2, 0xb9, 0xa3, 0xa3, 0xb3, 0x29, 0xbb, 0xa3, 0x3d, - 0xd8, 0x02, 0x20, 0x1d, 0xcb, 0x88, 0xa1, 0x3a, 0x3c, 0x19, 0x2d, 0xe1, - 0x9e, 0x39, 0xf6, 0x58, 0x05, 0xd4, 0x06, 0xbf, 0xb2, 0x93, 0xd1, 0x64, - 0x85, 0x75, 0xa8, 0xa2, 0xcb, 0x9f, 0x95, 0xd9, 0x90, 0xb9, 0x51, + 0xc6, 0xc8, 0xc1, 0x78, 0x52, 0xc6, 0x21, 0x0d, 0x97, 0xd7, 0x8b, 0xdd, 0xf1, 0x26, + 0x49, 0x94, 0x1b, 0x80, 0x8b, 0x6a, 0x3a, 0x90, 0xad, 0x62, 0x83, 0x3e, 0xf4, 0x2a, + 0x22, 0x2b, 0xc8, 0xf4, 0x07, 0x5e, 0xbe, 0x87, 0x32, 0x57, 0x34, 0xa9, 0x77, 0x1c, + 0x3c, 0x87, 0x24, 0x39, 0x4a, 0x71, 0xcc, 0x5f, 0xaa, 0x8b, 0x07, 0x96, 0xbf, 0xb2, + 0x7c, 0xf7, 0x7f, 0x11, 0xd1, 0x07, 0x49, 0xa2, 0x1c, }.ToImmutableArray() ); @@ -218,15 +217,14 @@ public void Token() { var expected = "1/271e00B29aeB93B2F4e30ECbebA4f72ac02f72b4/" + - "MEUCIQCJlZxZJYNOvEVZ15vKgkppIOUY8MWt4rmjo7Mpu6M92AIgHcuIoTo8GS3hnjn2WAXUBr+yk9Fk" + - "hXWoosufldmQuVE="; + "xsjBeFLGIQ2X14vd8SZJlBuAi2o6kK1igz70KiIryPQHXr6HMlc0qXccPIckOUpxzF+qiweWv7J8938R" + + "0QdJohw="; Assert.Equal(expected, ValidClaimFixture.Token); expected = "123/271e00B29aeB93B2F4e30ECbebA4f72ac02f72b4/" + "MEQCIAhd1E0voVfgAcpvypiNeh0TdMvJJso7w98UPTfirQSIAiAW1K5yQjFj6XOZUAu5GUmh8rtjIJla" + - "d9IV.b1ZmexcUQ==/" + - "dTM6Zm9v"; + "d9IV.b1ZmexcUQ==/dTM6Zm9v"; Assert.Equal(expected, ValidClaimWExtraFixture.Token); } @@ -237,8 +235,8 @@ public void FromToken() ValidClaimFixture, AppProtocolVersion.FromToken( "1/271e00B29aeB93B2F4e30ECbebA4f72ac02f72b4/" + - "MEUCIQCJlZxZJYNOvEVZ15vKgkppIOUY8MWt4rmjo7Mpu6M92AIgHcuIoTo8GS3hnjn2WAXUBr+y" + - "k9FkhXWoosufldmQuVE=" + "xsjBeFLGIQ2X14vd8SZJlBuAi2o6kK1igz70KiIryPQHXr6HMlc0qXccPIckOUpxzF+qiweWv7J8" + + "938R0QdJohw=" ) ); Assert.Equal( @@ -246,8 +244,7 @@ public void FromToken() AppProtocolVersion.FromToken( "123/271e00B29aeB93B2F4e30ECbebA4f72ac02f72b4/" + "MEQCIAhd1E0voVfgAcpvypiNeh0TdMvJJso7w98UPTfirQSIAiAW1K5yQjFj6XOZUAu5GUmh8rtj" + - "IJlad9IV.b1ZmexcUQ==/" + - "dTM6Zm9v" + "IJlad9IV.b1ZmexcUQ==/dTM6Zm9v" ) ); diff --git a/test/Libplanet.Net.Tests/Messages/MessageTest.cs b/test/Libplanet.Net.Tests/Messages/MessageTest.cs index 3ffac550e43..52549d313c5 100644 --- a/test/Libplanet.Net.Tests/Messages/MessageTest.cs +++ b/test/Libplanet.Net.Tests/Messages/MessageTest.cs @@ -118,7 +118,7 @@ public void GetId() var message = new BlockHeaderMsg(genesis.Hash, genesis.Header); Assert.Equal( new MessageId(ByteUtil.ParseHex( - "70b510a01be2ac0fbe87f69000e2d2b07cbd4dacf45b644c09f16f1490aafba4")), + "e1acbdc4d0cc1eb156cec60d0bf6d40fae3a90192e95719b12e6ee944c71b742")), message.Id); } diff --git a/test/Libplanet.Tests/Action/ActionEvaluatorTest.cs b/test/Libplanet.Tests/Action/ActionEvaluatorTest.cs index 64d9d208c0f..31105a26ad1 100644 --- a/test/Libplanet.Tests/Action/ActionEvaluatorTest.cs +++ b/test/Libplanet.Tests/Action/ActionEvaluatorTest.cs @@ -529,9 +529,9 @@ DumbAction MakeAction(Address address, char identifier, Address? transferTo = nu // have to be updated, since the order may change due to different PreEvaluationHash. (int TxIdx, int ActionIdx, string[] UpdatedStates, Address Signer)[] expectations = { - (1, 0, new[] { null, null, "C", null, null }, _txFx.Address2), // Adds "A" - (0, 0, new[] { "A", null, "C", null, null }, _txFx.Address1), // Adds "B" - (0, 1, new[] { "A", "B", "C", null, null }, _txFx.Address1), // Adds "C" + (0, 0, new[] { "A", null, null, null, null }, _txFx.Address1), // Adds "A" + (0, 1, new[] { "A", "B", null, null, null }, _txFx.Address1), // Adds "B" + (1, 0, new[] { "A", "B", "C", null, null }, _txFx.Address2), // Adds "C" }; #if DEBUG @@ -679,8 +679,8 @@ DumbAction MakeAction(Address address, char identifier, Address? transferTo = nu expectations = new (int TxIdx, int ActionIdx, string[] UpdatedStates, Address Signer)[] { (0, 0, new[] { "A,D", "B", "C", null, null }, _txFx.Address1), - (2, 0, new[] { "A,D", "B", "C", null, "F" }, _txFx.Address3), - (1, 0, new[] { "A,D", "B", "C", "E", "F" }, _txFx.Address2), + (1, 0, new[] { "A,D", "B", "C", "E", null }, _txFx.Address2), + (2, 0, new[] { "A,D", "B", "C", "E", "F" }, _txFx.Address3), }; #if DEBUG @@ -1684,10 +1684,10 @@ internal class OrderTxsForEvaluationData : IEnumerable // Spec for protocol version < 3. public List OrderedAddressesV0 = new List { - "0xB0ea0018Ab647418FA81c384194C9167e6A3C925", - "0x1d2B31bF9A2CA71051f8c66E1C783Ae70EF32798", - "0xfcbfa4977B2Fc7A608E4Bd2F6F0D6b27C0a4cd13", "0xc2A86014073D662a4a9bFCF9CB54263dfa4F5cBc", + "0xfcbfa4977B2Fc7A608E4Bd2F6F0D6b27C0a4cd13", + "0x1d2B31bF9A2CA71051f8c66E1C783Ae70EF32798", + "0xB0ea0018Ab647418FA81c384194C9167e6A3C925", "0x921Ba81C0be280C8A2faed79E14aD2a098874759", }; diff --git a/test/Libplanet.Tests/Blocks/BlockContentTest.cs b/test/Libplanet.Tests/Blocks/BlockContentTest.cs index f620ebb5f11..b7c346768ed 100644 --- a/test/Libplanet.Tests/Blocks/BlockContentTest.cs +++ b/test/Libplanet.Tests/Blocks/BlockContentTest.cs @@ -72,8 +72,8 @@ public void Transactions() new TxSigningMetadata(key.PublicKey, nonce: 0) ), signature: ByteUtil.ParseHexToImmutable( - "304402202a8324c83390b1fe0fdd4014056a049bc02ca059369ef62145fe574cb31224f" + - "d022073bf8a48403cf46f5fa63f26f3e8ef4db8ef1d841684856da63d9b7eeb91759a" + "cd51a992907121083ae2da9b39f94063fe5eb1bb91bb96dc83ced6add8370fe36" + + "394d6db0fca60ebfe40284e4c4cf6096cf5aa4e18bdc5d4f732033ea692e7521c" ) ); var txs = new[] { tx2, Block1Tx0, Block1Tx1 }.OrderBy(tx => tx.Id).ToImmutableList(); @@ -106,11 +106,11 @@ public void TransactionsWithDuplicateNonce() actions: TxActionList.Empty, maxGasPrice: null, gasLimit: null), - new TxSigningMetadata(Block1Tx1.PublicKey, nonce: 1L) + new TxSigningMetadata(Block1Tx1.Signer, nonce: 1L) ), signature: ByteUtil.ParseHexToImmutable( - "304502210099e580e8599acf0b26ad0a80315f2d488703ffde01e9449b4bf399593b8cc" + - "e63022002feb21bf0e4d76d25d17c8c1c4fbb3dfbda986e0693f984fbb302183ab7ece1" + "271c43e8c1a54c59686a49f13f1279765dd26a40a7b5e649a7dbf938bbcef3bf5" + + "e1d6be5b456506873fbd9d3e5b07a5f72bfeac19774cd8f8c7fd4f4f73abb6d1b" ) ); var txs = new[] { Block1Tx0, Block1Tx1, dupTx1 }.OrderBy(tx => tx.Id).ToArray(); @@ -127,9 +127,9 @@ public void TransactionsWithDuplicateNonce() evidenceHash: null), transactions: txs, evidence: evs)); - Assert.Equal(Block1Tx1.Id, e.TxId); + Assert.Equal(dupTx1.Id, e.TxId); Assert.Equal(2L, e.ExpectedNonce); - Assert.Equal(Block1Tx1.Nonce, e.ImproperNonce); + Assert.Equal(dupTx1.Nonce, e.ImproperNonce); } [Fact] @@ -144,14 +144,14 @@ public void TransactionsWithMissingNonce() actions: TxActionList.Empty, maxGasPrice: null, gasLimit: null), - new TxSigningMetadata(Block1Tx1.PublicKey, nonce: 3L) + new TxSigningMetadata(Block1Tx1.Signer, nonce: 3L) ), signature: ByteUtil.ParseHexToImmutable( - "3045022100bfdf79427028efea9449ad46fbf46d5a806694aa5bbab1a01f4c76b21acd" + - "cb16022057c851a01dd74797121385ccfc81e7b33842941189154b4d46d05e891a28e3eb" + "299543707e52a2ba0a20f6dfd306ca6a87c8f0567134c83f1a078af064547b9f4" + + "72f3e6d2bb88c7e7cc46a6d70017117f5cb75fbb5cbd7239e042d1273072e861c" ) ); - var txs = new[] { Block1Tx0, Block1Tx1, dupTx1 }.OrderBy(tx => tx.Id).ToArray(); + var txs = new[] { Block1Tx1, Block1Tx0, dupTx1 }.OrderBy(tx => tx.Id).ToArray(); var evs = Array.Empty(); InvalidTxNonceException e = Assert.Throws( () => new BlockContent( @@ -215,9 +215,9 @@ public void TxHash() { var expected = new HashDigest(new byte[] { - 0x65, 0x46, 0x98, 0xd3, 0x4b, 0x6d, 0x9a, 0x55, 0xb0, 0xc9, 0x3e, - 0x4f, 0xfb, 0x26, 0x39, 0x27, 0x83, 0x24, 0x86, 0x8c, 0x91, 0x96, - 0x5b, 0xc5, 0xf9, 0x6c, 0xb3, 0x07, 0x1d, 0x69, 0x03, 0xa0, + 0x9d, 0x64, 0x57, 0xe7, 0xbd, 0xc4, 0xb1, 0x9d, 0x1f, 0x34, 0x1c, 0x45, 0xc7, 0x87, + 0xcf, 0x80, 0xa1, 0x7c, 0x51, 0x4d, 0xa1, 0x0d, 0x70, 0x26, 0x06, 0xcc, 0x41, 0xf2, + 0x33, 0x87, 0xba, 0xdb, }); AssertBytesEqual(expected, Block1Content.TxHash); Assert.Null(GenesisContentPv0.TxHash); diff --git a/test/Libplanet.Tests/Blocks/BlockMetadataTest.cs b/test/Libplanet.Tests/Blocks/BlockMetadataTest.cs index 1f1810421f6..06fc8da6da2 100644 --- a/test/Libplanet.Tests/Blocks/BlockMetadataTest.cs +++ b/test/Libplanet.Tests/Blocks/BlockMetadataTest.cs @@ -129,7 +129,7 @@ public void MakeCandidateData() .Add("protocol_version", BlockMetadata.CurrentProtocolVersion) .Add( "transaction_fingerprint", - ParseHex("3d8e87977b1142863435b9385657e69557df8951a0698e9719f7d06c5fb8db1f") + ParseHex("5553c7f03ca10f7f9a58b051f65e1d35d52c28d658f3316545075dd07303cd71") ) .Add( "evidence_hash", @@ -151,7 +151,7 @@ public void MakeCandidateData() ) .Add( "transaction_fingerprint", - ParseHex("654698d34b6d9a55b0c93e4ffb2639278324868c91965bc5f96cb3071d6903a0") + ParseHex("9d6457e7bdc4b19d1f341c45c787cf80a17c514da10d702606cc41f23387badb") ) .Add("protocol_version", BlockMetadata.CurrentProtocolVersion) .Add( @@ -178,7 +178,7 @@ public void MakeCandidateDataPv1() .Add( "transaction_fingerprint", ParseHex( - "654698d34b6d9a55b0c93e4ffb2639278324868c91965bc5f96cb3071d6903a0" + "9d6457e7bdc4b19d1f341c45c787cf80a17c514da10d702606cc41f23387badb" ) ) .Add( @@ -207,7 +207,7 @@ public void DerivePreEvaluationHash() HashDigest hash = GenesisMetadata.DerivePreEvaluationHash(); AssertBytesEqual( - FromHex("9ff328716814fed03de454dfc0a9d9aeb0077ad0c393513bf29895a45ded13aa"), + FromHex("79c69838bb150cd31c77bf0a10db1f088dbd1509613b33db1081f2b39a6974e0"), hash.ByteArray); } diff --git a/test/Libplanet.Tests/Blocks/PreEvaluationBlockHeaderTest.cs b/test/Libplanet.Tests/Blocks/PreEvaluationBlockHeaderTest.cs index e7cea982f7d..0e405a39cb4 100644 --- a/test/Libplanet.Tests/Blocks/PreEvaluationBlockHeaderTest.cs +++ b/test/Libplanet.Tests/Blocks/PreEvaluationBlockHeaderTest.cs @@ -69,7 +69,7 @@ public void MakeCandidateData() .Add("state_root_hash", default(HashDigest).ByteArray) .Add( "transaction_fingerprint", - ParseHex("3d8e87977b1142863435b9385657e69557df8951a0698e9719f7d06c5fb8db1f") + ParseHex("5553c7f03ca10f7f9a58b051f65e1d35d52c28d658f3316545075dd07303cd71") ) .Add( "evidence_hash", @@ -102,7 +102,7 @@ public void MakeCandidateData() .Add( "transaction_fingerprint", ParseHex( - "654698d34b6d9a55b0c93e4ffb2639278324868c91965bc5f96cb3071d6903a0" + "9d6457e7bdc4b19d1f341c45c787cf80a17c514da10d702606cc41f23387badb" ) ) .Add( @@ -181,8 +181,8 @@ public void VerifySignature() // Same as block1.MakeSignature(_contents.Block1Key, arbitraryHash) ImmutableArray validSig = ByteUtil.ParseHexToImmutable( - "3045022100f975e902971092f16dbbb1fe6b7c956de648a8cd62346dbadc07e5fca4ce3" + - "07a02200987a349f0763efd0448659ed66c6bd0ad0971dd57fbb89c672aed592fbd70d6"); + "e50d22ff371bc82a57e0bf821d1628b00689b028f21bd1148c9c1851fa5e63746" + + "6d120d3fbfc0d3a42fc2825837bdc0ae058d5e75e4875f32420f0629a7af1e51b"); AssertBytesEqual( validSig, block1.MakeSignature(_contents.Block1Key, arbitraryHash)); @@ -215,22 +215,22 @@ public void DeriveBlockHash() _contents.GenesisMetadata, _contents.GenesisMetadata.DerivePreEvaluationHash()); AssertBytesEqual( - fromHex("d790aa3b2d985d58e6fe6547336ca9d2bfdb749a27cd58a17dbfd0c6880da8e3"), + fromHex("c08f58b8ed3e8c50cf7d3415191dd97dda4438d459eb8da93cb1e1c7449716c0"), genesis.DeriveBlockHash(default, null) ); AssertBytesEqual( - fromHex("47b5227dfdd99af4faf9ae9e82ef3b615063179d275081eae4c122685bbf7dcb"), + fromHex("85864e96e55112ba7a93923802cdfa419fad920f511f458ee33ddb0b51cce275"), genesis.DeriveBlockHash( default, genesis.MakeSignature(_contents.GenesisKey, default) ) ); AssertBytesEqual( - fromHex("2c45bb52e4c7d79caa28da9b63ec0f492262836c975bfa5bb27f62e96f2aad99"), + fromHex("d4f75f2a59ad25469abf5499d1458cad0b4390087b2c81318cacc3b495e5692a"), genesis.DeriveBlockHash(arbitraryHash, null) ); AssertBytesEqual( - fromHex("e985fcdce3f73dee90a4eaec9399283f856bb6f9326e4300bbe1d6126ff7ad55"), + fromHex("d22ae31924a68ac6d17e894fea437c3861c8cc2d1e24a657a2ef3e4331b6f639"), genesis.DeriveBlockHash( arbitraryHash, genesis.MakeSignature(_contents.GenesisKey, arbitraryHash)) @@ -240,19 +240,19 @@ public void DeriveBlockHash() _contents.Block1Metadata, _contents.Block1Metadata.DerivePreEvaluationHash()); AssertBytesEqual( - fromHex("ade696a646c9e4321cc90160807cba3d15d7cd28556d2dfb4103e8730a46038c"), + fromHex("b0b8bc62b85baa02cf941a5ea33db60ee890b098a197377af5ece82afadb4bb2"), block1.DeriveBlockHash(default, null) ); AssertBytesEqual( - fromHex("b3157a151d2168653e21ffc850f9d1a96bca6310275cccbeb9bd705f67c2e1c9"), + fromHex("31c8d60dcbff7a8a119ed25f239a829116f079074cf274613f599cc6dfe835d6"), block1.DeriveBlockHash(default, block1.MakeSignature(_contents.Block1Key, default)) ); AssertBytesEqual( - fromHex("3fd4ee37ed2fc5dae5a9533984f06b3975e176bdaa70689a3c14acd8b4ea384d"), + fromHex("6ce7bfd2a8d35876f7f0e1dfe974b206e8ac8ceee5cca3691350354bb2c08a84"), block1.DeriveBlockHash(arbitraryHash, null) ); AssertBytesEqual( - fromHex("83ceb4d1e5bbc385daaebfd044a5e4ba65bf1d8b63ef0aabe4d68fc5642b4516"), + fromHex("1026b747d6ad2f0096ca2aed76165814c18522693edac1f752a8e81fae569820"), block1.DeriveBlockHash( arbitraryHash, block1.MakeSignature(_contents.Block1Key, arbitraryHash) ) diff --git a/test/Libplanet.Tests/Crypto/PrivateKeyTest.cs b/test/Libplanet.Tests/Crypto/PrivateKeyTest.cs index 9dfb46e83af..a542bfe97f5 100644 --- a/test/Libplanet.Tests/Crypto/PrivateKeyTest.cs +++ b/test/Libplanet.Tests/Crypto/PrivateKeyTest.cs @@ -55,17 +55,17 @@ public void BytesTest() }; var key = new PrivateKey(bs); Assert.Equal(bs, key.ToByteArray()); - key = new PrivateKey(bs.ToImmutableArray()); + key = new PrivateKey(bs.ToImmutableArray().ToArray()); Assert.Equal(bs, key.ByteArray); } [Fact] public void BytesSanityCheckTest() { - Assert.Throws( + Assert.Throws( () => new PrivateKey(new byte[] { 0x87, 0x09, 0x12 }) ); - Assert.Throws(() => + Assert.Throws(() => new PrivateKey(new byte[31] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -73,7 +73,7 @@ public void BytesSanityCheckTest() 0x87, 0x09, 0x12, }) ); - Assert.Throws(() => + Assert.Throws(() => new PrivateKey(new byte[33] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -89,7 +89,7 @@ public void BytesSanityCheckTest() }; Assert.Throws(() => new PrivateKey(bs)); ImmutableArray ibs = bs.ToImmutableArray(); - Assert.Throws(() => new PrivateKey(ibs)); + Assert.Throws(() => new PrivateKey(ibs.ToArray())); } [Fact] @@ -116,7 +116,7 @@ public void PublicKeyTest() Assert.Equal(expected, new PrivateKey(keyBytes).PublicKey.Format(false)); Assert.Equal( expected, - new PrivateKey(keyBytes.ToImmutableArray()).PublicKey.Format(false) + new PrivateKey(keyBytes.ToImmutableArray().ToArray()).PublicKey.Format(false) ); } @@ -226,14 +226,12 @@ public void Decrypt() ); var cipherText = new byte[] { - 0x03, 0xe3, 0x1a, 0x0d, 0xea, 0x31, 0xe2, 0xb1, 0x32, 0x7b, - 0xd8, 0x70, 0x0a, 0xd3, 0x57, 0xcc, 0x69, 0x31, 0x4e, 0xca, - 0xd7, 0x0a, 0xe2, 0xe4, 0xfa, 0x55, 0x17, 0xa3, 0x3b, 0x67, - 0xcf, 0xb1, 0xc4, 0xfa, 0xa1, 0x10, 0xd4, 0xd2, 0x73, 0x11, - 0xef, 0xf1, 0x47, 0x99, 0xd7, 0x3d, 0x3c, 0xaa, 0xa2, 0x0e, - 0x35, 0x7c, 0x41, 0xc8, 0x8e, 0x14, 0x22, 0xc7, 0x64, 0xed, - 0xcc, 0xe0, 0x6c, 0x06, 0xb5, 0x86, 0x44, 0xc1, 0x68, 0xa5, - 0xab, 0xf3, 0x9d, 0xcb, 0x46, 0xb6, 0xe2, + 0x03, 0xc6, 0xcc, 0x1a, 0x70, 0xe4, 0x70, 0x0c, 0x96, 0x63, 0x8f, 0xf0, 0xd7, 0x8c, + 0x6c, 0xf9, 0x7a, 0xce, 0x75, 0x27, 0xbb, 0xb6, 0xee, 0xa2, 0x12, 0x41, 0xb6, 0x18, + 0x17, 0xf0, 0x6c, 0xb8, 0x37, 0xf6, 0x9d, 0xa2, 0x33, 0x4a, 0x03, 0xb1, 0xcb, 0xba, + 0x07, 0xa5, 0x5a, 0x35, 0xd8, 0xf0, 0xca, 0x44, 0xaf, 0xab, 0xb7, 0x7f, 0x97, 0x7e, + 0x06, 0x8b, 0xbe, 0xf8, 0xd6, 0x90, 0xc4, 0x47, 0x19, 0x99, 0x58, 0xee, 0x15, 0x86, + 0xd0, 0x82, 0xef, }; var expected = Encoding.ASCII.GetBytes("test message"); @@ -374,4 +372,4 @@ public void ThrowsWhenZeroBytesPrivateKey(byte[] bytes) Assert.Throws(() => new PrivateKey(bytes)); } } -} \ No newline at end of file +} diff --git a/test/Libplanet.Tests/Crypto/PublicKeyTest.cs b/test/Libplanet.Tests/Crypto/PublicKeyTest.cs index 9e62c6fdff1..6277d08fc55 100644 --- a/test/Libplanet.Tests/Crypto/PublicKeyTest.cs +++ b/test/Libplanet.Tests/Crypto/PublicKeyTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.ComponentModel; +using System.Linq; using System.Text; using Libplanet.Common; using Libplanet.Crypto; @@ -26,11 +27,12 @@ public void Constructor() "83440efbbef0657ac2ef6c6ee05db06a94532fda7ddc44a1695e5ce1a3d3c76db"); var mutable = new PublicKey(bytes); - var immutable = new PublicKey(bytes.ToImmutableArray()); + var immutable = new PublicKey(bytes); Assert.Equal(mutable, immutable); var compressedMutable = new PublicKey(mutable.Format(compress: true)); Assert.Equal(mutable, compressedMutable); - var compressedImmutable = new PublicKey(immutable.ToImmutableArray(compress: true)); + var compressedImmutable = new PublicKey( + immutable.ToImmutableArray(compress: true).ToArray()); Assert.Equal(mutable, compressedImmutable); } @@ -66,12 +68,15 @@ public void AddressTest() Assert.Equal(expected, publicKey.Address); } + /// + /// private key: "8dc9c703811d9ef7d513b88f07249f1b90cfa3981ad1e208fa62acda572831ac". + /// [Fact] public void Verify() { var pubKey = new PublicKey(ByteUtil.ParseHex( - "04b5a24aa2112720423bad39a0205182379d6f2b33e3487c9ab6cc8fc496f8a54" + - "83440efbbef0657ac2ef6c6ee05db06a94532fda7ddc44a1695e5ce1a3d3c76db")); + "0409142d7919d50d48314bf877a9e86d5da7a20a49e230e89fbb18e8c4681a908" + + "5ab74286cb0c6bf1e56f6e077b2e1630c329338c3bfd0471f1565fe8bcf8de935")); var payload = new byte[] { 0x64, 0x37, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, @@ -97,13 +102,13 @@ public void Verify() }; var signature = new byte[] { - 0x30, 0x44, 0x02, 0x20, 0x62, 0xcf, 0x8a, 0x04, 0x41, 0x9c, - 0x6a, 0x03, 0xba, 0xf5, 0x5d, 0xe1, 0x0d, 0x9b, 0x20, 0x0e, - 0xda, 0xa9, 0xdf, 0x2b, 0x9b, 0xf0, 0xcf, 0x98, 0x9f, 0xd6, - 0x5d, 0x71, 0xc5, 0x5c, 0x35, 0x60, 0x02, 0x20, 0x2a, 0xa5, - 0x59, 0x69, 0xd0, 0xad, 0xb1, 0x5e, 0x9e, 0x70, 0x8d, 0x83, - 0x00, 0xe1, 0x05, 0x31, 0x1e, 0x1a, 0x16, 0x16, 0x5d, 0xb7, - 0x3e, 0xd8, 0xf4, 0xf0, 0x05, 0x1d, 0x9f, 0x13, 0x81, 0xfd, + 0x1f, 0x80, 0xfb, 0x27, 0xbd, 0xdb, 0xea, 0xa5, 0x3a, 0x9e, + 0x90, 0xc5, 0xbb, 0xc6, 0x1d, 0x99, 0x8d, 0xcd, 0x2d, 0x4e, + 0x15, 0xdc, 0xeb, 0x4a, 0x78, 0x5f, 0x55, 0xac, 0x1c, 0xcb, + 0x01, 0x93, 0x38, 0xb4, 0xbf, 0xaf, 0x85, 0xbb, 0x02, 0xe8, + 0xeb, 0xe8, 0xa4, 0x21, 0xbe, 0x9f, 0x09, 0x6e, 0x43, 0xbf, + 0x33, 0x74, 0x21, 0x04, 0x83, 0xb9, 0x21, 0x8b, 0x6a, 0xbd, + 0x49, 0xfb, 0x58, 0xb7, 0x1b, }; Assert.True(pubKey.Verify(payload, signature)); Assert.False(pubKey.Verify(payload, ImmutableArray.Empty)); @@ -208,7 +213,8 @@ public void VerifyShouldNotCrashForAnyInputs() [Fact] public void EncryptTest() { - var prvKey = new PrivateKey(); + var prvKey = new PrivateKey( + "281747f1f29309b061e4a36a28ddc8276aec353cc312d3d8619d23ccf36172a5"); var pubKey = prvKey.PublicKey; var bs = Encoding.ASCII.GetBytes("hello world"); diff --git a/test/Libplanet.Tests/Crypto/SymmetricKeyTest.cs b/test/Libplanet.Tests/Crypto/SymmetricKeyTest.cs index 0408eb08811..072341bbf02 100644 --- a/test/Libplanet.Tests/Crypto/SymmetricKeyTest.cs +++ b/test/Libplanet.Tests/Crypto/SymmetricKeyTest.cs @@ -22,11 +22,10 @@ public void DecryptTest() { byte[] ciphertext = { - 0x18, 0x81, 0x34, 0x2a, 0x29, 0x30, 0xcd, 0xc2, 0x73, 0x4a, - 0xe1, 0x5e, 0x14, 0x3a, 0x09, 0xfe, 0x5b, 0x0a, 0x5f, 0x11, - 0x3b, 0x0e, 0x2f, 0xcf, 0xc8, 0xd5, 0x6f, 0x23, 0xc5, 0x08, - 0xa2, 0x89, 0x0d, 0x71, 0x39, 0xc5, 0x92, 0xcf, 0x4e, 0x4c, - 0x76, 0x75, 0x8a, 0x9b, 0x23, 0x17, 0xcb, 0x94, + 0xda, 0xff, 0x4f, 0xc7, 0x9f, 0x81, 0x2c, 0xdd, 0x1e, 0xa5, 0xf2, 0xd4, 0xab, 0x50, + 0x69, 0x8e, 0x56, 0xfb, 0xcf, 0x32, 0x64, 0x99, 0x8b, 0xff, 0xd4, 0xf0, 0x33, 0x11, + 0xd8, 0x8c, 0x4b, 0x82, 0x6c, 0x83, 0x0f, 0x57, 0x7c, 0xf2, 0x42, 0xd5, 0x32, 0xa4, + 0x69, 0x01, }; var expected = Encoding.ASCII.GetBytes("a secret message"); var aes = new SymmetricKey(KeyBytes); diff --git a/test/Libplanet.Tests/Fixtures/BlockContentFixture.cs b/test/Libplanet.Tests/Fixtures/BlockContentFixture.cs index 41f24de8d05..41e0f33b6f6 100644 --- a/test/Libplanet.Tests/Fixtures/BlockContentFixture.cs +++ b/test/Libplanet.Tests/Fixtures/BlockContentFixture.cs @@ -96,8 +96,8 @@ public BlockContentFixture() new TxSigningMetadata(Block1Tx0Key.PublicKey, nonce: 0L) ), signature: ByteUtil.ParseHexToImmutable( - "30440220422c85ea44845a56253654d95595ad06d6f09f862ca71b97e986ecbb453eac" + - "ae0220606e76276e40fa8f0795b880f712531fd6bd9db253bd8ab9c86aa4ab7d791d37" + "6054008481425278039421becc25fcb030d12714dc53490fdd5d43bcc8fe2d2a5" + + "b80a751bbde0b4813bd94ecd8e63bafee4f18db787beb117a5fc1aa5c2af9ca1b" ) ); Block1Tx1Key = PrivateKey.FromString( @@ -116,8 +116,8 @@ public BlockContentFixture() gasLimit: null), new TxSigningMetadata(Block1Tx1Key.PublicKey, nonce: 1L)), signature: ByteUtil.ParseHexToImmutable( - "3045022100abe3caabf2a46a297f2e4496f2c46d7e2f723e75fc42025d19f3ed7fce382" + - "d4e02200ffd36f7bef759b6c7ab43bc0f8959a0c463f88fd0f1faeaa209a8661506c4f0") + "f74609d91b9c5348ba248df1dcbce4114031971beb39c12874df3a8c4c8651540" + + "b31c9460da2b673cae61502036f6054353303be3c0b210ad9659afc6e9f5ce71b") ); Block1Ev0 = new TestEvidence( 0, GenesisKey.Address, new DateTimeOffset(2024, 5, 24, 14, 13, 9, 45, kst)); @@ -140,7 +140,7 @@ public BlockContentFixture() transactions: block1Transactions, evidence: block1Evidence); Block1TxHash = HashDigest.FromString( - "654698d34b6d9a55b0c93e4ffb2639278324868c91965bc5f96cb3071d6903a0"); + "9d6457e7bdc4b19d1f341c45c787cf80a17c514da10d702606cc41f23387badb"); Block1Metadata = new BlockMetadata(Block1Content); GenesisContentPv0 = new BlockContent( diff --git a/test/Libplanet.Tests/Tx/TransactionTest.cs b/test/Libplanet.Tests/Tx/TransactionTest.cs index 54cabe1923f..50ff799bceb 100644 --- a/test/Libplanet.Tests/Tx/TransactionTest.cs +++ b/test/Libplanet.Tests/Tx/TransactionTest.cs @@ -37,7 +37,7 @@ public void ConstructorWithVerification() InvalidTxSignatureException e = Assert.Throws( () => new Transaction(_fx.Tx, wrongSig)); TestUtils.AssertBytesEqual( - "d4e3e4db802ef1b19c4bc74dd8fae5da60108414a6772b060752825034cb7f1b", + "0a5b3d8ac9819ecd8343d6816a0632c20a669c45ad94ffc9f4005af3815a0f1b", e.TxId.ByteArray); } @@ -85,23 +85,21 @@ public void CreateWithSystemAction() AssertBytesEqual(privateKey.Address, tx.Signer); Assert.Empty(tx.UpdatedAddresses); - Assert.Equal(privateKey.PublicKey, tx.PublicKey); + Assert.Equal(privateKey.Address, tx.Signer); Assert.Equal(timestamp, tx.Timestamp); AssertBytesEqual( new byte[] { - 0x30, 0x44, 0x02, 0x20, 0x60, 0x8a, 0xbf, 0x3d, 0xdf, 0x50, - 0xf2, 0x00, 0x27, 0x56, 0xbb, 0x84, 0xc5, 0x65, 0x7c, 0xd9, - 0x4f, 0xbc, 0x33, 0x81, 0xe1, 0x0d, 0xc1, 0x5b, 0x23, 0x11, - 0xc4, 0x97, 0x61, 0x3e, 0xa0, 0xff, 0x02, 0x20, 0x44, 0x08, - 0xf8, 0x71, 0x43, 0x8c, 0x51, 0xd6, 0xa8, 0x22, 0x7d, 0x8c, - 0x7d, 0xb2, 0xc5, 0x97, 0x5b, 0xef, 0x72, 0x07, 0xfe, 0x4f, - 0x9d, 0x4c, 0x25, 0xc6, 0xb2, 0x1a, 0x89, 0xc7, 0xad, 0x10, + 0x08, 0xef, 0x2a, 0x58, 0x52, 0x8b, 0x15, 0xe5, 0xc3, 0x25, 0xe1, 0x59, 0x2a, + 0x5e, 0x1d, 0x3a, 0x8a, 0xf3, 0xeb, 0x12, 0x01, 0xfe, 0x1f, 0x2b, 0xf7, 0x42, + 0x80, 0xd1, 0xc1, 0xaa, 0x09, 0xbc, 0x19, 0xb1, 0x59, 0x77, 0x95, 0xaa, 0x03, + 0x74, 0x75, 0x5f, 0x6c, 0xdd, 0x69, 0x89, 0x3a, 0x82, 0x72, 0xd2, 0xcf, 0xee, + 0x31, 0x31, 0x7f, 0x53, 0x39, 0x25, 0xe4, 0x1c, 0xdf, 0x3d, 0x55, 0x61, 0x1b, }, tx.Signature ); AssertBytesEqual( - TxId.FromHex("eff61a6ee0faa2705b3dbd23abefbf18b4c864fa6b344c4fc3846cbb71a0e294"), + TxId.FromHex("babd317f0ce9961a528d9c923022fa4e0a360df0437463af7267ac40c5a889e6"), tx.Id ); } @@ -137,16 +135,16 @@ public void CreateWithCustomActions() new Address(privateKey.PublicKey), tx.Signer ); - Assert.Equal(privateKey.PublicKey, tx.PublicKey); + Assert.Equal(privateKey.Address, tx.Signer); Assert.Equal(timestamp, tx.Timestamp); AssertBytesEqual( - "3045022100c489671a0c97a0033c3273b15bb90bdff96e47bfaf475a1914ad5441bac32" + - "d6e022066ed765bbfead057a5cb12fa3ad4188833f1ea139f80383d062ffd315213289d", + "20687120cb1d510e954cb506af5e92d9b4e19cf1ddf509ba104863db202a5e2b7" + + "77d056be4e09f044182af2ebb79c449a4f619b5c77f5bd34567400e6dfcab881c", tx.Signature ); AssertBytesEqual( new TxId(ByteUtil.ParseHex( - "201ff302e08e0a3a6ce62415265dff6ec7c4439673f5079ceaeb2572fe05f632")), + "6b377f828e6e310d986f5812caa732f00841ebaf66ace2b2aab6fe417ee1b84d")), tx.Id ); } @@ -210,17 +208,17 @@ public void MakeWithSignature() var timestamp = new DateTimeOffset(2018, 11, 21, 0, 0, 0, TimeSpan.Zero); var signature = new byte[] { - 0x30, 0x44, 0x02, 0x20, 0x2f, 0x2d, 0xbe, 0x5a, 0x91, 0x65, 0x59, 0xde, 0xdb, 0xe8, - 0xd8, 0x4f, 0xa9, 0x20, 0xe2, 0x01, 0x29, 0x4d, 0x4f, 0x40, 0xea, 0x1e, 0x97, 0x44, - 0x1f, 0xbf, 0xa2, 0x5c, 0x8b, 0xd0, 0x0e, 0x23, 0x02, 0x20, 0x3c, 0x06, 0x02, 0x1f, - 0xb8, 0x3f, 0x67, 0x49, 0x92, 0x3c, 0x07, 0x59, 0x67, 0x96, 0xa8, 0x63, 0x04, 0xb0, - 0xc3, 0xfe, 0xbb, 0x6c, 0x7a, 0x7b, 0x58, 0x58, 0xe9, 0x7d, 0x37, 0x67, 0xe1, 0xe9, + 0xb6, 0x39, 0x6d, 0x8f, 0xbc, 0xb3, 0xb5, 0x9d, 0x88, 0xbb, 0x86, 0x93, 0x11, 0x7f, + 0xfb, 0x95, 0x57, 0xba, 0xcf, 0xc5, 0x1d, 0xef, 0x49, 0x28, 0x21, 0x62, 0x54, 0x55, + 0x0d, 0x7e, 0x17, 0xb0, 0x66, 0xdb, 0xc1, 0xb5, 0x07, 0x79, 0xd7, 0x45, 0x2c, 0x48, + 0xd2, 0xc9, 0x8d, 0x59, 0xb9, 0x91, 0xdb, 0x87, 0xfd, 0xfb, 0xda, 0x0c, 0xe0, 0x40, + 0xe2, 0x7e, 0xeb, 0xa2, 0x0f, 0xb8, 0xa3, 0xff, 0x1c, }; - var tx = new Transaction( - new UnsignedTx( + var unsignedTx = new UnsignedTx( new TxInvoice(timestamp: timestamp), - new TxSigningMetadata(privateKey.PublicKey, nonce: 0L) - ), + new TxSigningMetadata(privateKey.PublicKey, nonce: 0L)); + var tx = new Transaction( + unsignedTx: unsignedTx, signature: signature.ToImmutableArray() ); @@ -229,7 +227,7 @@ public void MakeWithSignature() tx.Signer ); Assert.Equal(ImmutableHashSet
.Empty, tx.UpdatedAddresses); - Assert.Equal(privateKey.PublicKey, tx.PublicKey); + Assert.Equal(privateKey.Address, tx.Signer); Assert.Equal(timestamp, tx.Timestamp); AssertBytesEqual( signature, @@ -239,9 +237,9 @@ public void MakeWithSignature() new TxId( new byte[] { - 0xb0, 0x69, 0xfd, 0xe2, 0x53, 0x88, 0x53, 0xbe, 0x81, 0xb3, 0xea, 0xac, - 0xc2, 0x38, 0x55, 0x42, 0x0e, 0x03, 0xe5, 0x62, 0x6f, 0x75, 0x7f, 0xa1, - 0x9b, 0x37, 0x92, 0x60, 0x1a, 0x94, 0x88, 0x81, + 0x35, 0x50, 0x73, 0x12, 0xcf, 0x5b, 0xae, 0xd8, 0xa3, 0x79, 0x69, 0xd2, + 0xb0, 0xb5, 0x9a, 0x16, 0xe4, 0x88, 0x81, 0xc1, 0x0e, 0xe4, 0xb4, 0x1d, + 0xed, 0x2d, 0x0f, 0xf5, 0x41, 0xf0, 0x03, 0xd1, } ), tx.Id @@ -312,8 +310,8 @@ public void Equality() var signingMetadata = new TxSigningMetadata(publicKey, 123L); var unsignedTx = new UnsignedTx(invoice, signingMetadata); ImmutableArray signature = ByteUtil.ParseHexToImmutable( - "30430220502da40025cf537d0517a111bb2078b04ec421755743177e0bad75ff47dcf" + - "066021f154bb551ec7e5e9228debcd44beee5a74db8249670e06f2c5b355f56730627"); + "6624cbd4281c0fb29d73f7912f8bec6a9bf4be4b73538148e5ef0352885906c54" + + "f05d12acbe0cf6afd8665b744db99a2a4a54cb473f9ac0077b93cc614e806a91c"); var tx = new Transaction(unsignedTx, signature: signature); Assert.Equal(invoice, tx); @@ -338,7 +336,7 @@ public void Equality() null, null); var diffSigningMetadata = new TxSigningMetadata( - i == 4 ? wrongKey.PublicKey : signingMetadata.PublicKey, + i == 4 ? wrongKey.Address : signingMetadata.Signer, i == 5 ? 456L : signingMetadata.Nonce ); @@ -392,8 +390,8 @@ public void JsonSerialization() var signingMetadata = new TxSigningMetadata(publicKey, 123L); var unsignedTx = new UnsignedTx(invoice, signingMetadata); ImmutableArray signature = ByteUtil.ParseHexToImmutable( - "30430220502da40025cf537d0517a111bb2078b04ec421755743177e0bad75ff47dcf" + - "066021f154bb551ec7e5e9228debcd44beee5a74db8249670e06f2c5b355f56730627"); + "6624cbd4281c0fb29d73f7912f8bec6a9bf4be4b73538148e5ef0352885906c54" + + "f05d12acbe0cf6afd8665b744db99a2a4a54cb473f9ac0077b93cc614e806a91c"); var tx = new Transaction(unsignedTx, signature: signature); #pragma warning disable MEN002 // Long lines are OK for test JSON data. @@ -401,14 +399,14 @@ public void JsonSerialization() tx, @" { - ""id"": ""926c8ee03479bfe29ee78ab71e81684badca177cee9c63bcc1a8f3bdf6ad4d45"", + ""id"": ""daa356224285b0a0aaafa1be222dc47ec1fea27b835e09c46a8b0c3cde797b73"", ""nonce"": 123, ""signer"": ""89F0eE48e8BeaE3131B17Dc79A1282A0D7EdC6b9"", ""updatedAddresses"": [ ""B61CE2Ce6d28237C1BC6E114616616762f1a12Ab"", ""D6D639DA5a58A78A564C2cD3DB55FA7CeBE244A9"" ], - ""signature"": ""MEMCIFAtpAAlz1N9BRehEbsgeLBOxCF1V0MXfgutdf9H3PBmAh8VS7VR7H5ekijevNRL7uWnTbgklnDgbyxbNV9WcwYn"", + ""signature"": ""ZiTL1CgcD7Kdc/eRL4vsapv0vktzU4FI5e8DUohZBsVPBdEqy\u002BDPav2GZbdE25mipKVMtHP5rAB3uTzGFOgGqRw="", ""actions"": [ { ""\uFEFFitem"": ""\uFEFFfoo"", @@ -422,7 +420,6 @@ public void JsonSerialization() } ], ""timestamp"": ""2023-03-29T01:02:03.456\u002B00:00"", - ""publicKey"": ""03f804c12768bf9e05978ee37c56d037f68523fd9079642691eec82e233e1559bf"", ""genesisHash"": ""92854cf0a62a7103b9c610fd588ad45254e64b74ceeeb209090ba572a41bf265"", ""maxGasPrice"": null, ""gasLimit"": null diff --git a/test/Libplanet.Tests/Tx/TxMarshalerTest.cs b/test/Libplanet.Tests/Tx/TxMarshalerTest.cs index 30ec6cdad03..b208cb5801b 100644 --- a/test/Libplanet.Tests/Tx/TxMarshalerTest.cs +++ b/test/Libplanet.Tests/Tx/TxMarshalerTest.cs @@ -34,11 +34,6 @@ public TxMarshalerTest() .Add(new byte[] { 0x75 }, Bencodex.Types.List.Empty); // 'u' _marshaledTxSigningMetadata = Bencodex.Types.Dictionary.Empty .Add(new byte[] { 0x6e }, 0L) // 'n' - .Add( - new byte[] { 0x70 }, // 'p' - ByteUtil.ParseHex( - "0446115b0131baccf94a5856ede871295f6f3d352e6847cda9c03e89fe09f7328" + - "08711ec97af6e341f110a326da1bdb81f5ae3badf76a90b22c8c491aed3aaa296")) .Add( new byte[] { 0x73 }, // 's' ByteUtil.ParseHex("c2a86014073d662a4a9bfcf9cb54263dfa4f5cbc")); @@ -48,8 +43,8 @@ public TxMarshalerTest() .Add( new byte[] { 0x53 }, // 'S' ByteUtil.ParseHex( - "304402202f2dbe5a916559dedbe8d84fa920e201294d4f40ea1e97441fbfa25c8bd00e" + - "2302203c06021fb83f6749923c07596796a86304b0c3febb6c7a7b5858e97d3767e1e9" + "b6396d8fbcb3b59d88bb8693117ffb9557bacfc51def4928216254550d7e17b06" + + "6dbc1b50779d7452c48d2c98d59b991db87fdfbda0ce040e27eeba20fb8a3ff1c" )); Bencodex.Types.Dictionary actionAttack = Bencodex.Types.Dictionary.Empty @@ -80,8 +75,8 @@ public TxMarshalerTest() .Add( new byte[] { 0x53 }, // 'S' ByteUtil.ParseHex( - "304402204cf2d4d92297a67fd04769f253e20e6213f063b8142fff4cb9e9c04733edbc" + - "1602200efebb0e2a7bcf4d5c7a628ed2e7a91f440afa31197ff616fb32d8badad3e9cc" + "eaf3bbcca2d6dcc03d74d04e367e393d2b3ddb44649aaa9d95cda82c28acafc40" + + "78d8321b3e5db669906a2b0d5afd02f8c27e7702062a3b1d5211eafc95369881c" )); } @@ -187,8 +182,8 @@ public void UnmarshalUnsignedTx() public void UnmarshalTransactionSignature() { AssertBytesEqual( - "304402202f2dbe5a916559dedbe8d84fa920e201294d4f40ea1e97441fbfa25c8bd00e" + - "2302203c06021fb83f6749923c07596796a86304b0c3febb6c7a7b5858e97d3767e1e9", + "b6396d8fbcb3b59d88bb8693117ffb9557bacfc51def4928216254550d7e17b06" + + "6dbc1b50779d7452c48d2c98d59b991db87fdfbda0ce040e27eeba20fb8a3ff1c", Assert.IsType>( TxMarshaler.UnmarshalTransactionSignature(_marshaledTransaction))); @@ -203,18 +198,18 @@ public void UnmarshalTransaction() Transaction tx = TxMarshaler.UnmarshalTransaction(_marshaledTransaction); - Assert.Equal(publicKey, tx.PublicKey); + Assert.Equal(publicKey.Address, tx.Signer); Assert.Equal(ImmutableHashSet
.Empty, tx.UpdatedAddresses); Assert.Equal(new Address(publicKey), tx.Signer); Assert.Equal(new DateTimeOffset(2018, 11, 21, 0, 0, 0, TimeSpan.Zero), tx.Timestamp); AssertBytesEqual( - "304402202f2dbe5a916559dedbe8d84fa920e201294d4f40ea1e97441fbfa25c8bd00e" + - "2302203c06021fb83f6749923c07596796a86304b0c3febb6c7a7b5858e97d3767e1e9", + "b6396d8fbcb3b59d88bb8693117ffb9557bacfc51def4928216254550d7e17b06" + + "6dbc1b50779d7452c48d2c98d59b991db87fdfbda0ce040e27eeba20fb8a3ff1c", tx.Signature ); AssertBytesEqual( new TxId(ByteUtil.ParseHex( - "b069fde2538853be81b3eaacc23855420e03e5626f757fa19b3792601a948881")), + "35507312cf5baed8a37969d2b0b59a16e48881c10ee4b41ded2d0ff541f003d1")), tx.Id ); @@ -231,7 +226,7 @@ public void UnmarshalTransactionWithCustomActions() TxMarshaler.UnmarshalTransaction( _marshaledTransactionWithCustomActions); - Assert.Equal(publicKey, tx.PublicKey); + Assert.Equal(publicKey.Address, tx.Signer); Assert.Equal( ImmutableHashSet.Create(new Address(publicKey)), tx.UpdatedAddresses @@ -239,13 +234,13 @@ public void UnmarshalTransactionWithCustomActions() Assert.Equal(new Address(publicKey), tx.Signer); Assert.Equal(new DateTimeOffset(2018, 11, 21, 0, 0, 0, TimeSpan.Zero), tx.Timestamp); AssertBytesEqual( - "304402204cf2d4d92297a67fd04769f253e20e6213f063b8142fff4cb9e9c04733edbc" + - "1602200efebb0e2a7bcf4d5c7a628ed2e7a91f440afa31197ff616fb32d8badad3e9cc", + "eaf3bbcca2d6dcc03d74d04e367e393d2b3ddb44649aaa9d95cda82c28acafc40" + + "78d8321b3e5db669906a2b0d5afd02f8c27e7702062a3b1d5211eafc95369881c", tx.Signature ); AssertBytesEqual( new TxId(ByteUtil.ParseHex( - "2c7d15f4c1d536ce4ca2a359bcd873a94f3c6518109ffabcf87e3485f363a534")), + "9aae665f856de01773d9ff43f0dcdbe8c348358cf965bd76cfe31ca0b50db64e")), tx.Id ); diff --git a/test/Libplanet.Tests/Tx/TxMetadataTest.cs b/test/Libplanet.Tests/Tx/TxMetadataTest.cs index 658150296bd..61f3c9b1977 100644 --- a/test/Libplanet.Tests/Tx/TxMetadataTest.cs +++ b/test/Libplanet.Tests/Tx/TxMetadataTest.cs @@ -45,13 +45,13 @@ public static IEnumerable ToBencodexTheoryData() => public void Constructor() { DateTimeOffset before = DateTimeOffset.UtcNow; - var meta = new TxMetadata(_key1.PublicKey); + var meta = new TxMetadata(_key1.Address); DateTimeOffset after = DateTimeOffset.UtcNow; Assert.Equal(0L, meta.Nonce); AssertBytesEqual(_key1.Address, meta.Signer); Assert.Empty(meta.UpdatedAddresses); Assert.InRange(meta.Timestamp, before, after); - Assert.Equal(_key1.PublicKey, meta.PublicKey); + Assert.Equal(_key1.Address, meta.Signer); Assert.Null(meta.GenesisHash); } @@ -69,7 +69,7 @@ public void CopyConstructor() AssertBytesEqual(meta1.Signer, copy1.Signer); Assert.Equal(meta1.UpdatedAddresses, copy1.UpdatedAddresses); Assert.Equal(meta1.Timestamp, copy1.Timestamp); - Assert.Equal(meta1.PublicKey, copy1.PublicKey); + Assert.Equal(meta1.Signer, copy1.Signer); AssertBytesEqual(meta1.GenesisHash, copy1.GenesisHash); var meta2 = new MetadataTransaction @@ -90,7 +90,7 @@ public void CopyConstructor() AssertBytesEqual(meta2.Signer, copy2.Signer); Assert.Equal(meta2.UpdatedAddresses, copy2.UpdatedAddresses); Assert.Equal(meta2.Timestamp, copy2.Timestamp); - Assert.Equal(meta2.PublicKey, copy2.PublicKey); + Assert.Equal(meta2.Signer, copy2.Signer); AssertBytesEqual(meta2.GenesisHash, copy2.GenesisHash); } @@ -110,7 +110,7 @@ public void Deserialize() Assert.Equal( new DateTimeOffset(2022, 5, 23, 10, 2, 0, default), meta1.Timestamp); - Assert.Equal(_key1.PublicKey, meta1.PublicKey); + Assert.Equal(_key1.Address, meta1.Signer); Assert.Null(meta1.GenesisHash); Bencodex.Types.Dictionary dict2 = Dictionary.Empty @@ -136,7 +136,7 @@ public void Deserialize() Assert.Equal( new DateTimeOffset(2022, 1, 12, 4, 56, 7, 890, default), meta2.Timestamp); - Assert.Equal(_key2.PublicKey, meta2.PublicKey); + Assert.Equal(_key2.Address, meta2.Signer); AssertBytesEqual( BlockHash.FromString( "83915317ebdbf870c567b263dd2e61ec9dca7fb381c592d80993291b6ffe5ad5"), @@ -148,7 +148,7 @@ public void Deserialize() [MemberData(nameof(ToBencodexTheoryData))] public void ToBencodex(DateTimeOffset timestamp) { - var meta1 = new TxMetadata(_key1.PublicKey) + var meta1 = new TxMetadata(_key1.Address) { Nonce = 123L, Timestamp = timestamp, @@ -157,13 +157,12 @@ public void ToBencodex(DateTimeOffset timestamp) .Add(new byte[] { 0x6e }, 123L) .Add(new byte[] { 0x73 }, _key1.Address.Bencoded) .Add(new byte[] { 0x75 }, new List()) - .Add(new byte[] { 0x74 }, "2022-05-23T10:02:00.000000Z") - .Add(new byte[] { 0x70 }, _key1.PublicKey.ToImmutableArray(compress: false)); + .Add(new byte[] { 0x74 }, "2022-05-23T10:02:00.000000Z"); AssertBencodexEqual( expected1, meta1.ToBencodex()); - var meta2 = new TxMetadata(_key2.PublicKey) + var meta2 = new TxMetadata(_key2.Address) { Nonce = 0L, UpdatedAddresses = new[] @@ -184,7 +183,6 @@ public void ToBencodex(DateTimeOffset timestamp) .Add(_key1.Address.Bencoded) .Add(_key2.Address.Bencoded)) .Add(new byte[] { 0x74 }, "2022-01-12T04:56:07.890000Z") - .Add(new byte[] { 0x70 }, _key2.PublicKey.ToImmutableArray(compress: false)) .Add( new byte[] { 0x67 }, ByteUtil.ParseHex( diff --git a/test/Libplanet.Tests/Tx/TxSigningMetadataTest.cs b/test/Libplanet.Tests/Tx/TxSigningMetadataTest.cs index 91938861a85..a0209db045e 100644 --- a/test/Libplanet.Tests/Tx/TxSigningMetadataTest.cs +++ b/test/Libplanet.Tests/Tx/TxSigningMetadataTest.cs @@ -17,7 +17,6 @@ public void Constructor() { var metadata = new TxSigningMetadata(PublicKey, 123L); Assert.Equal(PublicKey.Address, metadata.Signer); - Assert.Equal(PublicKey, metadata.PublicKey); Assert.Equal(123L, metadata.Nonce); Assert.Throws( @@ -30,12 +29,10 @@ public void CopyConstructor() var metadata = new TxSigningMetadata(PublicKey, 123L); var copy = new TxSigningMetadata(metadata); Assert.Equal(PublicKey.Address, copy.Signer); - Assert.Equal(PublicKey, copy.PublicKey); Assert.Equal(123L, copy.Nonce); var copyFromInterface = new TxSigningMetadata(new MockingTxSigningMetadata()); Assert.Equal(PublicKey.Address, copyFromInterface.Signer); - Assert.Equal(PublicKey, copyFromInterface.PublicKey); Assert.Equal(123L, copyFromInterface.Nonce); } @@ -78,7 +75,6 @@ public void JsonSerialization() @" { ""signer"": ""89F0eE48e8BeaE3131B17Dc79A1282A0D7EdC6b9"", - ""publicKey"": ""03f804c12768bf9e05978ee37c56d037f68523fd9079642691eec82e233e1559bf"", ""nonce"": 123 } ", @@ -92,8 +88,6 @@ private class MockingTxSigningMetadata : ITxSigningMetadata Address ITxSigningMetadata.Signer => PublicKey.Address; - PublicKey ITxSigningMetadata.PublicKey => PublicKey; - bool IEquatable.Equals(ITxSigningMetadata other) => false; } } diff --git a/test/Libplanet.Tests/Tx/UnsignedTxTest.cs b/test/Libplanet.Tests/Tx/UnsignedTxTest.cs index 618d006237e..b04a6ec2531 100644 --- a/test/Libplanet.Tests/Tx/UnsignedTxTest.cs +++ b/test/Libplanet.Tests/Tx/UnsignedTxTest.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Immutable; -using Bencodex; +using System.Text; using Libplanet.Action; using Libplanet.Action.Tests.Common; using Libplanet.Common; @@ -78,7 +78,7 @@ public void CreateSignature() new PrivateKey("51fb8c2eb261ed761429c297dd1f8952c8ce327d2ec2ec5bcc7728e3362627c2"); var wrongKey = new PrivateKey(); ImmutableArray signature = unsignedTx.CreateSignature(privateKey); - byte[] message = new Codec().Encode(unsignedTx.MarshalUnsignedTx()); + byte[] message = Encoding.UTF8.GetBytes(unsignedTx.SerializeUnsignedTxToJson()); Assert.True(privateKey.PublicKey.Verify(message, signature)); Assert.False(wrongKey.PublicKey.Verify(message, signature)); @@ -94,8 +94,8 @@ public void VerifySignature() var privateKey = new PrivateKey("51fb8c2eb261ed761429c297dd1f8952c8ce327d2ec2ec5bcc7728e3362627c2"); var signature = ByteUtil.ParseHexToImmutable( - "30430220502da40025cf537d0517a111bb2078b04ec421755743177e0bad75ff47dcf" + - "066021f154bb551ec7e5e9228debcd44beee5a74db8249670e06f2c5b355f56730627"); + "6624cbd4281c0fb29d73f7912f8bec6a9bf4be4b73538148e5ef0352885906c54" + + "f05d12acbe0cf6afd8665b744db99a2a4a54cb473f9ac0077b93cc614e806a91c"); var wrongSignature = ByteUtil.ParseHexToImmutable( "3045022100e4df322ba35e0e5ed96043b1c214e4a0f23734a7491b5db4c4a88834d3f47" + "48a0220691b0972641a8759ac921b731e5750c20505f05fd993d45b24eb989de33018b1"); @@ -126,7 +126,7 @@ public void Equality() null, null); var diffSigningMetadata = new TxSigningMetadata( - i == 4 ? wrongKey.PublicKey : _signingMetadata.PublicKey, + i == 4 ? wrongKey.Address : _signingMetadata.Signer, i == 5 ? 456L : _signingMetadata.Nonce ); @@ -177,7 +177,6 @@ public void JsonSerialization() ], ""nonce"": 123, ""signer"": ""89F0eE48e8BeaE3131B17Dc79A1282A0D7EdC6b9"", - ""publicKey"": ""03f804c12768bf9e05978ee37c56d037f68523fd9079642691eec82e233e1559bf"", ""maxGasPrice"": null, ""gasLimit"": null, } diff --git a/tools/Libplanet.Explorer/GraphTypes/TransactionType.cs b/tools/Libplanet.Explorer/GraphTypes/TransactionType.cs index 6d25e7619d6..2f829369b36 100644 --- a/tools/Libplanet.Explorer/GraphTypes/TransactionType.cs +++ b/tools/Libplanet.Explorer/GraphTypes/TransactionType.cs @@ -30,11 +30,6 @@ public TransactionType(IBlockChainContext context) description: "An address of the account who signed this transaction.", resolve: x => x.Source.Signer ); - Field>( - name: "PublicKey", - description: "A PublicKey of the account who signed this transaction.", - resolve: ctx => ctx.Source.PublicKey.Format(true) - ); Field>>>( name: "UpdatedAddresses", description: "Addresses whose states were affected by Actions.", diff --git a/tools/Libplanet.Tools/Libplanet.Tools.csproj b/tools/Libplanet.Tools/Libplanet.Tools.csproj index 88f57b3b5d8..fe67ac9ad6d 100644 --- a/tools/Libplanet.Tools/Libplanet.Tools.csproj +++ b/tools/Libplanet.Tools/Libplanet.Tools.csproj @@ -45,7 +45,6 @@ - diff --git a/tools/Libplanet.Tools/Program.cs b/tools/Libplanet.Tools/Program.cs index 4d1d3d2b3fd..f0a8561a5d3 100644 --- a/tools/Libplanet.Tools/Program.cs +++ b/tools/Libplanet.Tools/Program.cs @@ -5,7 +5,6 @@ namespace Libplanet.Tools; using System.Security.Cryptography; using System.Threading.Tasks; using Cocona; -using Libplanet.Crypto.Secp256k1; using Libplanet.Extensions.Cocona.Commands; using Libplanet.Extensions.Cocona.Extensions; using CryptoConfig = Libplanet.Crypto.CryptoConfig; @@ -29,16 +28,6 @@ public class Program public static Task Main(string[] args) { - try - { - CryptoConfig.CryptoBackend = new Secp256k1CryptoBackend(); - } - catch (Exception) - { - // If it fails to load the Secp256k1CryptoBackend for any reason - // fall back to the DefaultCryptoBackend instead. - } - return CoconaLiteApp.CreateHostBuilder() .ConfigureServices(services => {