Salsa20 + wrapper stub
[NovacoinLibrary.git] / Novacoin / ScryptHash256.cs
1 \feffusing System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 //using System.Security.Cryptography;
7
8 using Org.BouncyCastle.Crypto;
9 using Org.BouncyCastle.Security;
10 using Org.BouncyCastle.Asn1;
11
12 namespace Novacoin
13 {
14     public class ScryptHash256 : Hash
15     {
16         // 32 bytes
17         public override int hashSize
18         {
19             get { return 32; }
20         }
21
22         public ScryptHash256() : base() { }
23         public ScryptHash256(byte[] bytesArray) : base(bytesArray) { }
24         public ScryptHash256(IList<byte> bytesList) : base(bytesList) { }
25
26         public static ScryptHash256 Compute256(IEnumerable<byte> inputBytes)
27         {
28             byte[] dataBytes = inputBytes.ToArray();
29
30             uint[] V = new uint[(131072 + 63) / sizeof(uint)];
31
32             // sha1 test:
33             //            Rfc2898DeriveBytes key1 = new Rfc2898DeriveBytes(dataBytes, dataBytes, 1);
34             //            byte[] keyBytes1 = key1.GetBytes(128);
35
36
37             // stub:
38             byte[] keyBytes1 = null;
39
40             uint[] X = Interop.ToUInt32Array(keyBytes1);
41
42             ushort i, j, k;
43             for (i = 0; i < 1024; i++)
44             {
45                 Array.Copy(X, 0, V, i * 32, 32);
46
47                 xor_salsa8(ref X, 0, ref X, 16);
48                 xor_salsa8(ref X, 16, ref X, 0);
49             }
50             for (i = 0; i < 1024; i++)
51             {
52                 j = (ushort)(32 * (X[16] & 1023));
53                 for (k = 0; k < 32; k++)
54                     X[k] ^= V[j + k];
55                 xor_salsa8(ref X, 0, ref X, 16);
56                 xor_salsa8(ref X, 16, ref X, 0);
57             }
58
59             byte[] xBytes = Interop.LEBytes(X);
60
61             // sha1 test:
62             //            Rfc2898DeriveBytes key2 = new Rfc2898DeriveBytes(dataBytes, xBytes, 1);
63             //            byte[] keyBytes2 = key2.GetBytes(32);
64
65             byte[] keyBytes2 = null;
66
67             return new ScryptHash256(keyBytes2);
68         }
69
70         private static void xor_salsa8(ref uint[] B, int indexB, ref uint[] Bx, int indexBx)
71         {
72             uint x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;
73             byte i;
74
75             x00 = (B[indexB + 0] ^= Bx[indexBx + 0]);
76             x01 = (B[indexB + 1] ^= Bx[indexBx + 1]);
77             x02 = (B[indexB + 2] ^= Bx[indexBx + 2]);
78             x03 = (B[indexB + 3] ^= Bx[indexBx + 3]);
79             x04 = (B[indexB + 4] ^= Bx[indexBx + 4]);
80             x05 = (B[indexB + 5] ^= Bx[indexBx + 5]);
81             x06 = (B[indexB + 6] ^= Bx[indexBx + 6]);
82             x07 = (B[indexB + 7] ^= Bx[indexBx + 7]);
83             x08 = (B[indexB + 8] ^= Bx[indexBx + 8]);
84             x09 = (B[indexB + 9] ^= Bx[indexBx + 9]);
85             x10 = (B[indexB + 10] ^= Bx[indexBx + 10]);
86             x11 = (B[indexB + 11] ^= Bx[indexBx + 11]);
87             x12 = (B[indexB + 12] ^= Bx[indexBx + 12]);
88             x13 = (B[indexB + 13] ^= Bx[indexBx + 13]);
89             x14 = (B[indexB + 14] ^= Bx[indexBx + 14]);
90             x15 = (B[indexB + 15] ^= Bx[indexBx + 15]);
91
92             Func<uint, int, uint> R = (a, b) => (((a) << (b)) | ((a) >> (32 - (b))));
93
94             for (i = 0; i < 8; i += 2)
95             {
96                 /* Operate on columns. */
97                 x04 ^= R(x00 + x12, 7); x09 ^= R(x05 + x01, 7);
98                 x14 ^= R(x10 + x06, 7); x03 ^= R(x15 + x11, 7);
99
100                 x08 ^= R(x04 + x00, 9); x13 ^= R(x09 + x05, 9);
101                 x02 ^= R(x14 + x10, 9); x07 ^= R(x03 + x15, 9);
102
103                 x12 ^= R(x08 + x04, 13); x01 ^= R(x13 + x09, 13);
104                 x06 ^= R(x02 + x14, 13); x11 ^= R(x07 + x03, 13);
105
106                 x00 ^= R(x12 + x08, 18); x05 ^= R(x01 + x13, 18);
107                 x10 ^= R(x06 + x02, 18); x15 ^= R(x11 + x07, 18);
108
109                 /* Operate on rows. */
110                 x01 ^= R(x00 + x03, 7); x06 ^= R(x05 + x04, 7);
111                 x11 ^= R(x10 + x09, 7); x12 ^= R(x15 + x14, 7);
112
113                 x02 ^= R(x01 + x00, 9); x07 ^= R(x06 + x05, 9);
114                 x08 ^= R(x11 + x10, 9); x13 ^= R(x12 + x15, 9);
115
116                 x03 ^= R(x02 + x01, 13); x04 ^= R(x07 + x06, 13);
117                 x09 ^= R(x08 + x11, 13); x14 ^= R(x13 + x12, 13);
118
119                 x00 ^= R(x03 + x02, 18); x05 ^= R(x04 + x07, 18);
120                 x10 ^= R(x09 + x08, 18); x15 ^= R(x14 + x13, 18);
121             }
122
123             B[indexB + 0] += x00;
124             B[indexB + 1] += x01;
125             B[indexB + 2] += x02;
126             B[indexB + 3] += x03;
127             B[indexB + 4] += x04;
128             B[indexB + 5] += x05;
129             B[indexB + 6] += x06;
130             B[indexB + 7] += x07;
131             B[indexB + 8] += x08;
132             B[indexB + 9] += x09;
133             B[indexB + 10] += x10;
134             B[indexB + 11] += x11;
135             B[indexB + 12] += x12;
136             B[indexB + 13] += x13;
137             B[indexB + 14] += x14;
138             B[indexB + 15] += x15;
139         }
140     }
141 }