Skip to content

Commit

Permalink
Optimize BigInteger (neo-project#1280)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang authored and Tommo-L committed Jun 22, 2020
1 parent c6629b7 commit 0be3125
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 18 deletions.
7 changes: 3 additions & 4 deletions src/neo/Cryptography/Base58.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,15 @@ public static byte[] Decode(string input)
// Leading zero bytes get encoded as leading `1` characters
int leadingZeroCount = input.TakeWhile(c => c == Alphabet[0]).Count();
var leadingZeros = new byte[leadingZeroCount];
var bytesWithoutLeadingZeros = bi.ToByteArray()
.Reverse()// to big endian
.SkipWhile(b => b == 0);//strip sign byte
if (bi.IsZero) return leadingZeros;
var bytesWithoutLeadingZeros = bi.ToByteArray(isUnsigned: true, isBigEndian: true);
return leadingZeros.Concat(bytesWithoutLeadingZeros).ToArray();
}

public static string Encode(byte[] input)
{
// Decode byte[] to BigInteger
BigInteger value = new BigInteger(new byte[1].Concat(input).Reverse().ToArray());
BigInteger value = new BigInteger(input, isUnsigned: true, isBigEndian: true);

// Encode BigInteger to Base58 string
var sb = new StringBuilder();
Expand Down
5 changes: 2 additions & 3 deletions src/neo/Cryptography/ECC/ECDsa.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;

Expand All @@ -26,7 +25,7 @@ public ECDsa(ECPoint publicKey)
private BigInteger CalculateE(BigInteger n, byte[] message)
{
int messageBitLength = message.Length * 8;
BigInteger trunc = new BigInteger(message.Reverse().Concat(new byte[1]).ToArray());
BigInteger trunc = new BigInteger(message, isUnsigned: true, isBigEndian: true);
if (n.GetBitLength() < messageBitLength)
{
trunc >>= messageBitLength - n.GetBitLength();
Expand All @@ -38,7 +37,7 @@ public BigInteger[] GenerateSignature(byte[] message)
{
if (privateKey == null) throw new InvalidOperationException();
BigInteger e = CalculateE(curve.N, message);
BigInteger d = new BigInteger(privateKey.Reverse().Concat(new byte[1]).ToArray());
BigInteger d = new BigInteger(privateKey, isUnsigned: true, isBigEndian: true);
BigInteger r, s;
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
Expand Down
8 changes: 3 additions & 5 deletions src/neo/Cryptography/ECC/ECFieldElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,10 @@ public ECFieldElement Square()

public byte[] ToByteArray()
{
byte[] data = Value.ToByteArray();
byte[] data = Value.ToByteArray(isUnsigned: true, isBigEndian: true);
if (data.Length == 32)
return data.Reverse().ToArray();
if (data.Length > 32)
return data.Take(32).Reverse().ToArray();
return Enumerable.Repeat<byte>(0, 32 - data.Length).Concat(data.Reverse()).ToArray();
return data;
return Enumerable.Repeat<byte>(0, 32 - data.Length).Concat(data).ToArray();
}

public static ECFieldElement operator -(ECFieldElement x)
Expand Down
12 changes: 6 additions & 6 deletions src/neo/Cryptography/ECC/ECPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ public static ECPoint DecodePoint(byte[] encoded, ECCurve curve)
if (encoded.Length != (expectedLength + 1))
throw new FormatException("Incorrect length for compressed encoding");
int yTilde = encoded[0] & 1;
BigInteger X1 = new BigInteger(encoded.Skip(1).Reverse().Concat(new byte[1]).ToArray());
BigInteger X1 = new BigInteger(encoded.AsSpan(1), isUnsigned: true, isBigEndian: true);
p = DecompressPoint(yTilde, X1, curve);
break;
}
case 0x04: // uncompressed
{
if (encoded.Length != (2 * expectedLength + 1))
throw new FormatException("Incorrect length for uncompressed/hybrid encoding");
BigInteger X1 = new BigInteger(encoded.Skip(1).Take(expectedLength).Reverse().Concat(new byte[1]).ToArray());
BigInteger Y1 = new BigInteger(encoded.Skip(1 + expectedLength).Reverse().Concat(new byte[1]).ToArray());
BigInteger X1 = new BigInteger(encoded.AsSpan(1, expectedLength), isUnsigned: true, isBigEndian: true);
BigInteger Y1 = new BigInteger(encoded.AsSpan(1 + expectedLength), isUnsigned: true, isBigEndian: true);
p = new ECPoint(new ECFieldElement(X1, curve), new ECFieldElement(Y1, curve), curve);
break;
}
Expand Down Expand Up @@ -143,10 +143,10 @@ public byte[] EncodePoint(bool commpressed)
else
{
data = new byte[65];
byte[] yBytes = Y.Value.ToByteArray().Reverse().ToArray();
byte[] yBytes = Y.Value.ToByteArray(isUnsigned: true, isBigEndian: true);
Buffer.BlockCopy(yBytes, 0, data, 65 - yBytes.Length, yBytes.Length);
}
byte[] xBytes = X.Value.ToByteArray().Reverse().ToArray();
byte[] xBytes = X.Value.ToByteArray(isUnsigned: true, isBigEndian: true);
Buffer.BlockCopy(xBytes, 0, data, 33 - xBytes.Length, xBytes.Length);
data[0] = commpressed ? Y.Value.IsEven ? (byte)0x02 : (byte)0x03 : (byte)0x04;
return data;
Expand Down Expand Up @@ -379,7 +379,7 @@ private static sbyte[] WindowNaf(sbyte width, BigInteger k)
throw new ArgumentException();
if (p.IsInfinity)
return p;
BigInteger k = new BigInteger(n.Reverse().Concat(new byte[1]).ToArray());
BigInteger k = new BigInteger(n, isUnsigned: true, isBigEndian: true);
if (k.Sign == 0)
return p.Curve.Infinity;
return Multiply(p, k);
Expand Down

0 comments on commit 0be3125

Please sign in to comment.