Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
lock9 committed Dec 3, 2019
2 parents 045ea0a + 9bc0d54 commit 6e4e6df
Show file tree
Hide file tree
Showing 139 changed files with 1,781 additions and 3,062 deletions.
6 changes: 3 additions & 3 deletions src/neo/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,9 @@ internal void EnsureMaxBlockSize(IEnumerable<Transaction> txs)
public ConsensusPayload MakePrepareRequest()
{
var random = new Random();
byte[] buffer = new byte[sizeof(ulong)];
Span<byte> buffer = stackalloc byte[sizeof(ulong)];
random.NextBytes(buffer);
Block.ConsensusData.Nonce = BitConverter.ToUInt64(buffer, 0);
Block.ConsensusData.Nonce = BitConverter.ToUInt64(buffer);
EnsureMaxBlockSize(Blockchain.Singleton.MemPool.GetSortedVerifiedTransactions());
Block.Timestamp = Math.Max(TimeProvider.Current.UtcNow.ToTimestampMS(), PrevHeader.Timestamp + 1);

Expand Down Expand Up @@ -346,7 +346,7 @@ public void Reset(byte viewNumber)
{
PrevHash = Snapshot.CurrentBlockHash,
Index = Snapshot.Height + 1,
NextConsensus = Blockchain.GetConsensusAddress(NativeContract.NEO.GetValidators(Snapshot).ToArray())
NextConsensus = Blockchain.GetConsensusAddress(NativeContract.NEO.GetValidators(Snapshot))
};
var pv = Validators;
Validators = NativeContract.NEO.GetNextBlockValidators(Snapshot);
Expand Down
10 changes: 5 additions & 5 deletions src/neo/Consensus/ConsensusService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ internal ConsensusService(IActorRef localNode, IActorRef taskManager, ConsensusC

private bool AddTransaction(Transaction tx, bool verify)
{
if (verify && !tx.Verify(context.Snapshot, context.SendersFeeMonitor.GetSenderFee(tx.Sender)))
if (verify && tx.Verify(context.Snapshot, context.SendersFeeMonitor.GetSenderFee(tx.Sender)) != RelayResultReason.Succeed)
{
Log($"Invalid transaction: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
RequestChangeView(ChangeViewReason.TxInvalid);
Expand Down Expand Up @@ -189,7 +189,7 @@ private void InitializeConsensus(byte viewNumber)

private void Log(string message, LogLevel level = LogLevel.Info)
{
Plugin.Log(nameof(ConsensusService), level, message);
Utility.Log(nameof(ConsensusService), level, message);
}

private void OnChangeViewReceived(ConsensusPayload payload, ChangeView message)
Expand Down Expand Up @@ -231,7 +231,7 @@ private void OnCommitReceived(ConsensusPayload payload, Commit commit)
{
existingCommitPayload = payload;
}
else if (Crypto.Default.VerifySignature(hashData, commit.Signature,
else if (Crypto.VerifySignature(hashData, commit.Signature,
context.Validators[payload.ValidatorIndex].EncodePoint(false)))
{
existingCommitPayload = payload;
Expand Down Expand Up @@ -433,7 +433,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m
byte[] hashData = context.EnsureHeader().GetHashData();
for (int i = 0; i < context.CommitPayloads.Length; i++)
if (context.CommitPayloads[i]?.ConsensusMessage.ViewNumber == context.ViewNumber)
if (!Crypto.Default.VerifySignature(hashData, context.CommitPayloads[i].GetDeserializedMessage<Commit>().Signature, context.Validators[i].EncodePoint(false)))
if (!Crypto.VerifySignature(hashData, context.CommitPayloads[i].GetDeserializedMessage<Commit>().Signature, context.Validators[i].EncodePoint(false)))
context.CommitPayloads[i] = null;

if (context.TransactionHashes.Length == 0)
Expand Down Expand Up @@ -573,7 +573,7 @@ private void OnTimer(Timer timer)
{
var reason = ChangeViewReason.Timeout;

if (context.Block != null && context.TransactionHashes?.Count() > context.Transactions?.Count)
if (context.Block != null && context.TransactionHashes?.Length > context.Transactions?.Count)
{
reason = ChangeViewReason.TxNotFound;
}
Expand Down
28 changes: 26 additions & 2 deletions src/neo/Cryptography/Base58.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,37 @@
using System.Linq;
using System.Numerics;
using System.Text;
using static Neo.Helper;

namespace Neo.Cryptography
{
public static class Base58
{
public const string Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

public static byte[] Base58CheckDecode(this string input)
{
byte[] buffer = Decode(input);
if (buffer.Length < 4) throw new FormatException();
byte[] checksum = buffer.Sha256(0, buffer.Length - 4).Sha256();
if (!buffer.AsSpan(^4).SequenceEqual(checksum.AsSpan(..4)))
throw new FormatException();
var ret = buffer[..^4];
Array.Clear(buffer, 0, buffer.Length);
return ret;
}

public static string Base58CheckEncode(this ReadOnlySpan<byte> data)
{
byte[] checksum = data.Sha256().Sha256();
Span<byte> buffer = stackalloc byte[data.Length + 4];
data.CopyTo(buffer);
checksum.AsSpan(..4).CopyTo(buffer[data.Length..]);
var ret = Encode(buffer);
buffer.Clear();
return ret;
}

public static byte[] Decode(string input)
{
// Decode Base58 string to BigInteger
Expand All @@ -27,10 +51,10 @@ public static byte[] Decode(string input)
var leadingZeros = new byte[leadingZeroCount];
if (bi.IsZero) return leadingZeros;
var bytesWithoutLeadingZeros = bi.ToByteArray(isUnsigned: true, isBigEndian: true);
return leadingZeros.Concat(bytesWithoutLeadingZeros).ToArray();
return Concat(leadingZeros, bytesWithoutLeadingZeros);
}

public static string Encode(byte[] input)
public static string Encode(ReadOnlySpan<byte> input)
{
// Decode byte[] to BigInteger
BigInteger value = new BigInteger(input, isUnsigned: true, isBigEndian: true);
Expand Down
25 changes: 11 additions & 14 deletions src/neo/Cryptography/Crypto.cs
Original file line number Diff line number Diff line change
@@ -1,47 +1,44 @@
using System;
using System.Linq;
using System.Security.Cryptography;

namespace Neo.Cryptography
{
public class Crypto
public static class Crypto
{
public static readonly Crypto Default = new Crypto();

public byte[] Hash160(byte[] message)
public static byte[] Hash160(ReadOnlySpan<byte> message)
{
return message.Sha256().RIPEMD160();
}

public byte[] Hash256(byte[] message)
public static byte[] Hash256(ReadOnlySpan<byte> message)
{
return message.Sha256().Sha256();
}

public byte[] Sign(byte[] message, byte[] prikey, byte[] pubkey)
public static byte[] Sign(byte[] message, byte[] prikey, byte[] pubkey)
{
using (var ecdsa = ECDsa.Create(new ECParameters
{
Curve = ECCurve.NamedCurves.nistP256,
D = prikey,
Q = new ECPoint
{
X = pubkey.Take(32).ToArray(),
Y = pubkey.Skip(32).ToArray()
X = pubkey[..32],
Y = pubkey[32..]
}
}))
{
return ecdsa.SignData(message, HashAlgorithmName.SHA256);
}
}

public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey)
public static bool VerifySignature(ReadOnlySpan<byte> message, ReadOnlySpan<byte> signature, byte[] pubkey)
{
if (pubkey.Length == 33 && (pubkey[0] == 0x02 || pubkey[0] == 0x03))
{
try
{
pubkey = Cryptography.ECC.ECPoint.DecodePoint(pubkey, Cryptography.ECC.ECCurve.Secp256r1).EncodePoint(false).Skip(1).ToArray();
pubkey = ECC.ECPoint.DecodePoint(pubkey, ECC.ECCurve.Secp256r1).EncodePoint(false)[1..];
}
catch
{
Expand All @@ -50,7 +47,7 @@ public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey)
}
else if (pubkey.Length == 65 && pubkey[0] == 0x04)
{
pubkey = pubkey.Skip(1).ToArray();
pubkey = pubkey[1..];
}
else if (pubkey.Length != 64)
{
Expand All @@ -61,8 +58,8 @@ public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey)
Curve = ECCurve.NamedCurves.nistP256,
Q = new ECPoint
{
X = pubkey.Take(32).ToArray(),
Y = pubkey.Skip(32).ToArray()
X = pubkey[..32],
Y = pubkey[32..]
}
}))
{
Expand Down
3 changes: 3 additions & 0 deletions src/neo/Cryptography/ECC/ECCurve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ public class ECCurve
public readonly ECPoint Infinity;
public readonly ECPoint G;

public readonly int ExpectedECPointLength;

private ECCurve(BigInteger Q, BigInteger A, BigInteger B, BigInteger N, byte[] G)
{
this.Q = Q;
this.ExpectedECPointLength = (Q.GetBitLength() + 7) / 8;
this.A = new ECFieldElement(A, this);
this.B = new ECFieldElement(B, this);
this.N = N;
Expand Down
6 changes: 3 additions & 3 deletions src/neo/Cryptography/ECC/ECDsa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public ECDsa(ECPoint publicKey)
this.curve = publicKey.Curve;
}

private BigInteger CalculateE(BigInteger n, byte[] message)
private BigInteger CalculateE(BigInteger n, ReadOnlySpan<byte> message)
{
int messageBitLength = message.Length * 8;
BigInteger trunc = new BigInteger(message, isUnsigned: true, isBigEndian: true);
Expand All @@ -33,7 +33,7 @@ private BigInteger CalculateE(BigInteger n, byte[] message)
return trunc;
}

public BigInteger[] GenerateSignature(byte[] message)
public BigInteger[] GenerateSignature(ReadOnlySpan<byte> message)
{
if (privateKey == null) throw new InvalidOperationException();
BigInteger e = CalculateE(curve.N, message);
Expand Down Expand Up @@ -91,7 +91,7 @@ private static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger k, ECPoint Q, Bi
return R;
}

public bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
public bool VerifySignature(ReadOnlySpan<byte> message, BigInteger r, BigInteger s)
{
if (r.Sign < 1 || s.Sign < 1 || r.CompareTo(curve.N) >= 0 || s.CompareTo(curve.N) >= 0)
return false;
Expand Down
9 changes: 4 additions & 5 deletions src/neo/Cryptography/ECC/ECFieldElement.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Numerics;

namespace Neo.Cryptography.ECC
Expand Down Expand Up @@ -28,9 +27,7 @@ public override bool Equals(object obj)
if (obj == this)
return true;

ECFieldElement other = obj as ECFieldElement;

if (other == null)
if (!(obj is ECFieldElement other))
return false;

return Equals(other);
Expand Down Expand Up @@ -145,7 +142,9 @@ public byte[] ToByteArray()
byte[] data = Value.ToByteArray(isUnsigned: true, isBigEndian: true);
if (data.Length == 32)
return data;
return Enumerable.Repeat<byte>(0, 32 - data.Length).Concat(data).ToArray();
byte[] buffer = new byte[32];
Buffer.BlockCopy(data, 0, buffer, buffer.Length - data.Length, data.Length);
return buffer;
}

public static ECFieldElement operator -(ECFieldElement x)
Expand Down
35 changes: 15 additions & 20 deletions src/neo/Cryptography/ECC/ECPoint.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Neo.IO;
using System;
using System.IO;
using System.Linq;
using System.Numerics;
using static Neo.Helper;

namespace Neo.Cryptography.ECC
{
Expand All @@ -18,10 +18,7 @@ public bool IsInfinity

public int Size => IsInfinity ? 1 : 33;

public ECPoint()
: this(null, null, ECCurve.Secp256r1)
{
}
public ECPoint() : this(null, null, ECCurve.Secp256r1) { }

internal ECPoint(ECFieldElement x, ECFieldElement y, ECCurve curve)
{
Expand All @@ -40,28 +37,27 @@ public int CompareTo(ECPoint other)
return Y.CompareTo(other.Y);
}

public static ECPoint DecodePoint(byte[] encoded, ECCurve curve)
public static ECPoint DecodePoint(ReadOnlySpan<byte> encoded, ECCurve curve)
{
ECPoint p = null;
int expectedLength = (curve.Q.GetBitLength() + 7) / 8;
switch (encoded[0])
{
case 0x02: // compressed
case 0x03: // compressed
{
if (encoded.Length != (expectedLength + 1))
if (encoded.Length != (curve.ExpectedECPointLength + 1))
throw new FormatException("Incorrect length for compressed encoding");
int yTilde = encoded[0] & 1;
BigInteger X1 = new BigInteger(encoded.AsSpan(1), isUnsigned: true, isBigEndian: true);
BigInteger X1 = new BigInteger(encoded[1..], isUnsigned: true, isBigEndian: true);
p = DecompressPoint(yTilde, X1, curve);
break;
}
case 0x04: // uncompressed
{
if (encoded.Length != (2 * expectedLength + 1))
if (encoded.Length != (2 * curve.ExpectedECPointLength + 1))
throw new FormatException("Incorrect length for uncompressed/hybrid encoding");
BigInteger X1 = new BigInteger(encoded.AsSpan(1, expectedLength), isUnsigned: true, isBigEndian: true);
BigInteger Y1 = new BigInteger(encoded.AsSpan(1 + expectedLength), isUnsigned: true, isBigEndian: true);
BigInteger X1 = new BigInteger(encoded[1..(1 + curve.ExpectedECPointLength)], isUnsigned: true, isBigEndian: true);
BigInteger Y1 = new BigInteger(encoded[(1 + curve.ExpectedECPointLength)..], isUnsigned: true, isBigEndian: true);
p = new ECPoint(new ECFieldElement(X1, curve), new ECFieldElement(Y1, curve), curve);
break;
}
Expand Down Expand Up @@ -105,23 +101,22 @@ void ISerializable.Deserialize(BinaryReader reader)

public static ECPoint DeserializeFrom(BinaryReader reader, ECCurve curve)
{
int expectedLength = (curve.Q.GetBitLength() + 7) / 8;
byte[] buffer = new byte[1 + expectedLength * 2];
Span<byte> buffer = stackalloc byte[1 + curve.ExpectedECPointLength * 2];
buffer[0] = reader.ReadByte();
switch (buffer[0])
{
case 0x02:
case 0x03:
{
if (reader.Read(buffer, 1, expectedLength) != expectedLength)
if (reader.Read(buffer[1..(1 + curve.ExpectedECPointLength)]) != curve.ExpectedECPointLength)
{
throw new FormatException();
}
return DecodePoint(buffer.Take(1 + expectedLength).ToArray(), curve);
return DecodePoint(buffer[..(1 + curve.ExpectedECPointLength)], curve);
}
case 0x04:
{
if (reader.Read(buffer, 1, expectedLength * 2) != expectedLength * 2)
if (reader.Read(buffer[1..(1 + curve.ExpectedECPointLength * 2)]) != curve.ExpectedECPointLength * 2)
{
throw new FormatException();
}
Expand Down Expand Up @@ -175,10 +170,10 @@ public static ECPoint FromBytes(byte[] pubkey, ECCurve curve)
return DecodePoint(pubkey, curve);
case 64:
case 72:
return DecodePoint(new byte[] { 0x04 }.Concat(pubkey.Skip(pubkey.Length - 64)).ToArray(), curve);
return DecodePoint(Concat(new byte[] { 0x04 }, pubkey[^64..]), curve);
case 96:
case 104:
return DecodePoint(new byte[] { 0x04 }.Concat(pubkey.Skip(pubkey.Length - 96).Take(64)).ToArray(), curve);
return DecodePoint(Concat(new byte[] { 0x04 }, pubkey[^96..^32]), curve);
default:
throw new FormatException();
}
Expand Down Expand Up @@ -241,7 +236,7 @@ internal static ECPoint Multiply(ECPoint p, BigInteger k)
// The length of the precomputation array
int preCompLen = 1;

ECPoint[] preComp = preComp = new ECPoint[] { p };
ECPoint[] preComp = new ECPoint[] { p };
ECPoint twiceP = p.Twice();

if (preCompLen < reqPreCompLen)
Expand Down

0 comments on commit 6e4e6df

Please sign in to comment.