From bcdf1637787154a7d20d06fefd235424fda1a1e4 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Wed, 19 Aug 2015 18:16:18 +0300 Subject: [PATCH] Salsa20 + wrapper stub --- Novacoin/Hash.cs | 2 +- Novacoin/Interop.cs | 55 +++++++++++++++++ Novacoin/Novacoin.csproj | 1 + Novacoin/ScryptHash256.cs | 141 +++++++++++++++++++++++++++++++++++++++++++++ NovacoinTest/Program.cs | 8 +++ 5 files changed, 206 insertions(+), 1 deletions(-) create mode 100644 Novacoin/ScryptHash256.cs diff --git a/Novacoin/Hash.cs b/Novacoin/Hash.cs index c5622d2..731e795 100644 --- a/Novacoin/Hash.cs +++ b/Novacoin/Hash.cs @@ -62,7 +62,7 @@ namespace Novacoin public override string ToString() { - return Interop.ToHex(_hashBytes); + return Interop.ToHex(Interop.ReverseIfLE(_hashBytes)); } } } diff --git a/Novacoin/Interop.cs b/Novacoin/Interop.cs index a2ead39..f21c5c2 100644 --- a/Novacoin/Interop.cs +++ b/Novacoin/Interop.cs @@ -24,6 +24,61 @@ namespace Novacoin public class Interop { + public static byte[] ReverseIfLE(byte[] source) + { + if (BitConverter.IsLittleEndian) + { + Array.Reverse(source); + } + + return source; + } + + public static byte[] LEBytes(uint[] values) + { + if (BitConverter.IsLittleEndian) + { + byte[] result = new byte[values.Length * sizeof(uint)]; + Buffer.BlockCopy(values, 0, result, 0, result.Length); + + return result; + } + else + { + List result = new List(); + + foreach (uint i in values) + { + result.AddRange(LEBytes(i)); + } + + return result.ToArray(); + } + } + + public static uint[] ToUInt32Array(byte[] bytes) + { + if (BitConverter.IsLittleEndian) + { + uint[] result = new uint[bytes.Length / sizeof(uint)]; + Buffer.BlockCopy(bytes, 0, result, 0, result.Length); + + return result; + } + else + { + List result = new List(); + + for (int i = 0; i < bytes.Length; i += 4) + { + result.Add(LEBytesToUInt32(bytes.Skip(i).Take(4).ToArray())); + } + + return result.ToArray(); + } + + } + public static byte[] LEBytes(ushort n) { byte[] resultBytes = BitConverter.GetBytes(n); diff --git a/Novacoin/Novacoin.csproj b/Novacoin/Novacoin.csproj index 0053701..fa86325 100644 --- a/Novacoin/Novacoin.csproj +++ b/Novacoin/Novacoin.csproj @@ -45,6 +45,7 @@ + diff --git a/Novacoin/ScryptHash256.cs b/Novacoin/ScryptHash256.cs new file mode 100644 index 0000000..cd0caa3 --- /dev/null +++ b/Novacoin/ScryptHash256.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +//using System.Security.Cryptography; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Asn1; + +namespace Novacoin +{ + public class ScryptHash256 : Hash + { + // 32 bytes + public override int hashSize + { + get { return 32; } + } + + public ScryptHash256() : base() { } + public ScryptHash256(byte[] bytesArray) : base(bytesArray) { } + public ScryptHash256(IList bytesList) : base(bytesList) { } + + public static ScryptHash256 Compute256(IEnumerable inputBytes) + { + byte[] dataBytes = inputBytes.ToArray(); + + uint[] V = new uint[(131072 + 63) / sizeof(uint)]; + + // sha1 test: + // Rfc2898DeriveBytes key1 = new Rfc2898DeriveBytes(dataBytes, dataBytes, 1); + // byte[] keyBytes1 = key1.GetBytes(128); + + + // stub: + byte[] keyBytes1 = null; + + uint[] X = Interop.ToUInt32Array(keyBytes1); + + ushort i, j, k; + for (i = 0; i < 1024; i++) + { + Array.Copy(X, 0, V, i * 32, 32); + + xor_salsa8(ref X, 0, ref X, 16); + xor_salsa8(ref X, 16, ref X, 0); + } + for (i = 0; i < 1024; i++) + { + j = (ushort)(32 * (X[16] & 1023)); + for (k = 0; k < 32; k++) + X[k] ^= V[j + k]; + xor_salsa8(ref X, 0, ref X, 16); + xor_salsa8(ref X, 16, ref X, 0); + } + + byte[] xBytes = Interop.LEBytes(X); + + // sha1 test: + // Rfc2898DeriveBytes key2 = new Rfc2898DeriveBytes(dataBytes, xBytes, 1); + // byte[] keyBytes2 = key2.GetBytes(32); + + byte[] keyBytes2 = null; + + return new ScryptHash256(keyBytes2); + } + + private static void xor_salsa8(ref uint[] B, int indexB, ref uint[] Bx, int indexBx) + { + uint x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15; + byte i; + + x00 = (B[indexB + 0] ^= Bx[indexBx + 0]); + x01 = (B[indexB + 1] ^= Bx[indexBx + 1]); + x02 = (B[indexB + 2] ^= Bx[indexBx + 2]); + x03 = (B[indexB + 3] ^= Bx[indexBx + 3]); + x04 = (B[indexB + 4] ^= Bx[indexBx + 4]); + x05 = (B[indexB + 5] ^= Bx[indexBx + 5]); + x06 = (B[indexB + 6] ^= Bx[indexBx + 6]); + x07 = (B[indexB + 7] ^= Bx[indexBx + 7]); + x08 = (B[indexB + 8] ^= Bx[indexBx + 8]); + x09 = (B[indexB + 9] ^= Bx[indexBx + 9]); + x10 = (B[indexB + 10] ^= Bx[indexBx + 10]); + x11 = (B[indexB + 11] ^= Bx[indexBx + 11]); + x12 = (B[indexB + 12] ^= Bx[indexBx + 12]); + x13 = (B[indexB + 13] ^= Bx[indexBx + 13]); + x14 = (B[indexB + 14] ^= Bx[indexBx + 14]); + x15 = (B[indexB + 15] ^= Bx[indexBx + 15]); + + Func R = (a, b) => (((a) << (b)) | ((a) >> (32 - (b)))); + + for (i = 0; i < 8; i += 2) + { + /* Operate on columns. */ + x04 ^= R(x00 + x12, 7); x09 ^= R(x05 + x01, 7); + x14 ^= R(x10 + x06, 7); x03 ^= R(x15 + x11, 7); + + x08 ^= R(x04 + x00, 9); x13 ^= R(x09 + x05, 9); + x02 ^= R(x14 + x10, 9); x07 ^= R(x03 + x15, 9); + + x12 ^= R(x08 + x04, 13); x01 ^= R(x13 + x09, 13); + x06 ^= R(x02 + x14, 13); x11 ^= R(x07 + x03, 13); + + x00 ^= R(x12 + x08, 18); x05 ^= R(x01 + x13, 18); + x10 ^= R(x06 + x02, 18); x15 ^= R(x11 + x07, 18); + + /* Operate on rows. */ + x01 ^= R(x00 + x03, 7); x06 ^= R(x05 + x04, 7); + x11 ^= R(x10 + x09, 7); x12 ^= R(x15 + x14, 7); + + x02 ^= R(x01 + x00, 9); x07 ^= R(x06 + x05, 9); + x08 ^= R(x11 + x10, 9); x13 ^= R(x12 + x15, 9); + + x03 ^= R(x02 + x01, 13); x04 ^= R(x07 + x06, 13); + x09 ^= R(x08 + x11, 13); x14 ^= R(x13 + x12, 13); + + x00 ^= R(x03 + x02, 18); x05 ^= R(x04 + x07, 18); + x10 ^= R(x09 + x08, 18); x15 ^= R(x14 + x13, 18); + } + + B[indexB + 0] += x00; + B[indexB + 1] += x01; + B[indexB + 2] += x02; + B[indexB + 3] += x03; + B[indexB + 4] += x04; + B[indexB + 5] += x05; + B[indexB + 6] += x06; + B[indexB + 7] += x07; + B[indexB + 8] += x08; + B[indexB + 9] += x09; + B[indexB + 10] += x10; + B[indexB + 11] += x11; + B[indexB + 12] += x12; + B[indexB + 13] += x13; + B[indexB + 14] += x14; + B[indexB + 15] += x15; + } + } +} diff --git a/NovacoinTest/Program.cs b/NovacoinTest/Program.cs index e77bf59..924d659 100644 --- a/NovacoinTest/Program.cs +++ b/NovacoinTest/Program.cs @@ -6,6 +6,7 @@ using System.Text; namespace NovacoinTest { using Novacoin; + using System.Collections.Generic; class Program { @@ -98,6 +99,13 @@ namespace NovacoinTest CNovacoinAddress donationAddress = new CNovacoinAddress(strDonationAddress); Console.WriteLine("Address reserialization is OK: {0}", donationAddress.ToString() == pubKeyTest.GetKeyID().ToString()); + /* + IEnumerable dataBytesForScrypt = b1.header.ToBytes(); + ScryptHash256 scryptHash = ScryptHash256.Compute256(dataBytesForScrypt); + + Console.WriteLine(scryptHash.ToString()); + + */ Console.ReadLine(); } } -- 1.7.1