Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
XEdDSA.cs
2{/*
7 public delegate void GetRandomBytesHandler(byte[] Bytes);
8
14 public static class XEdDSA
15 {
16 private readonly static RandomNumberGenerator rnd = RandomNumberGenerator.Create();
17
22 public static void GetBytes(byte[] Bytes)
23 {
24 lock (rnd)
25 {
26 rnd.GetBytes(Bytes);
27 }
28 }
29
38 public static byte[] Sign(byte[] Data, byte[] PrivateKey,
39 HashFunction HashFunction, MontgomeryCurve Curve)
40 {
41 return Sign(Data, PrivateKey, HashFunction, Curve, GetBytes);
42 }
43
53 public static byte[] Sign(byte[] Data, byte[] PrivateKey,
54 HashFunction HashFunction, MontgomeryCurve Curve,
55 GetRandomBytesHandler GetRandomBytes)
56 {
57 int ScalarBytes = PrivateKey.Length;
58
59 EdwardsCurveBase Pair = Curve.Pair;
60 PointOnCurve UV = Curve.PublicKeyPoint;
61 PointOnCurve XY = Curve.ToXY(UV); // E
62 byte[] a = PrivateKey;
63 byte[] A = EdDSA.Encode(XY, Pair);
64
65 if ((A[ScalarBytes - 1] & 0x80) != 0)
66 {
67 A[ScalarBytes - 1] &= 0x7f;
68 BigInteger a2 = Pair.Order - EllipticCurve.ToInt(a);
69 if (a2.Sign < 0)
70 a2 += Pair.Order;
71
72 a = a2.ToByteArray();
73 if (a.Length != ScalarBytes)
74 Array.Resize(ref a, ScalarBytes);
75 }
76
77 int DataLen = Data.Length;
78 byte[] Z = new byte[64];
79 byte[] Bin = new byte[ScalarBytes + DataLen + 64];
80
81 GetRandomBytes?.Invoke(Z);
82
83 Buffer.BlockCopy(a, 0, Bin, 0, ScalarBytes);
84 Buffer.BlockCopy(Data, 0, Bin, ScalarBytes, DataLen);
85 Buffer.BlockCopy(Z, 0, Bin, ScalarBytes + DataLen, 64);
86
87 BigInteger r = EllipticCurve.ToInt(Hash1(Bin, ScalarBytes, HashFunction));
88 r = BigInteger.Remainder(r, Pair.Order);
89 if (r.Sign < 0)
90 r += Pair.Order;
91
92 PointOnCurve R = Pair.ScalarMultiplication(r, Pair.BasePoint, true);
93 byte[] Rs = EdDSA.Encode(R, Pair);
94
95 Bin = new byte[(ScalarBytes << 1) + DataLen];
96
97 Buffer.BlockCopy(Rs, 0, Bin, 0, ScalarBytes);
98 Buffer.BlockCopy(A, 0, Bin, ScalarBytes, ScalarBytes);
99 Buffer.BlockCopy(Data, 0, Bin, ScalarBytes << 1, DataLen);
100
101 BigInteger h = EllipticCurve.ToInt(HashFunction(Bin));
102 h = BigInteger.Remainder(h, Pair.Order);
103
104 BigInteger s = Pair.ModulusN.Add(r, Pair.ModulusN.Multiply(h, EllipticCurve.ToInt(a)));
105 byte[] ss = s.ToByteArray();
106 byte[] Signature = new byte[ScalarBytes << 1];
107
108 Buffer.BlockCopy(Rs, 0, Signature, 0, ScalarBytes);
109 Buffer.BlockCopy(ss, 0, Signature, ScalarBytes, ss.Length);
110
111 return Signature;
112 }
113
114 private static byte[] Hash1(byte[] Data, int ScalarBytes, HashFunction HashFunction)
115 {
116 int c = Data.Length;
117 byte[] Bin = new byte[ScalarBytes + c];
118 int i;
119
120 Bin[0] = 0xfe;
121
122 for (i = 1; i < ScalarBytes; i++)
123 Bin[i] = 0xff;
124
125 Buffer.BlockCopy(Data, 0, Bin, ScalarBytes, c);
126
127 return HashFunction(Data);
128 }
129
141 public static bool Verify(byte[] Data, byte[] PublicKey, HashFunction HashFunction,
142 MontgomeryCurve Curve, byte[] Signature, int PBits, int QBits)
143 {
144 try
145 {
146 int ScalarBytes = Signature.Length;
147 if ((ScalarBytes & 1) != 0)
148 return false;
149
150 byte[] Signature2 = (byte[])Signature.Clone();
151 byte[] PublicKey2 = (byte[])PublicKey.Clone();
152 byte SignBit = (byte)(Signature2[ScalarBytes - 1] & 0x80);
153 Signature2[ScalarBytes - 1] &= 0x7f;
154
155 ScalarBytes >>= 1;
156
157 if (PublicKey2.Length != ScalarBytes)
158 return false;
159
160 PublicKey2[ScalarBytes - 1] |= SignBit;
161
162 return EdDSA.Verify(Data, PublicKey2, HashFunction, Curve.Pair, Signature2);
163
164 // PointOnCurve P = Curve.Decode(PublicKey);
165 // BigInteger U = P.X;
166 // if (U >= Curve.Prime)
167 // return false;
168 //
169 // byte[] Rs = new byte[ScalarBytes];
170 // Buffer.BlockCopy(Signature, 0, Rs, 0, ScalarBytes);
171 // EdwardsCurveBase Pair = Curve.Pair;
172 // PointOnCurve R = EdDSA.Decode(Rs, Pair);
173 //
174 // byte[] ss = new byte[ScalarBytes];
175 // Buffer.BlockCopy(Signature, ScalarBytes, ss, 0, ScalarBytes);
176 // BigInteger s = EllipticCurve.ToInt(ss);
177 //
178 // if (ModulusP.CalcBits(R.Y) >= PBits)
179 // return false;
180 //
181 // if (ModulusP.CalcBits(ss) >= QBits)
182 // return false;
183 //
184 // byte[] Bin = U.ToByteArray();
185 // if (Bin.Length != ScalarBytes)
186 // Array.Resize(ref Bin, ScalarBytes);
187 //
188 // int MaskBits = PBits & 7;
189 // if (MaskBits != 0)
190 // Bin[ScalarBytes - 1] &= (byte)(0xff >> (8 - MaskBits));
191 //
192 // BigInteger UMasked = EllipticCurve.ToInt(Bin);
193 // PointOnCurve AP = Curve.ToXY(new PointOnCurve(U, Curve.CalcV(U)));
194 //
195 // byte[] A = EdDSA.Encode(AP, Pair);
196 // A[ScalarBytes - 1] &= 0x7f; // A.s=0
197 //
198 // int DataLen = Data.Length;
199 //
200 // Bin = new byte[(ScalarBytes << 1) + DataLen];
201 // Buffer.BlockCopy(Rs, 0, Bin, 0, ScalarBytes);
202 // Buffer.BlockCopy(A, 0, Bin, ScalarBytes, ScalarBytes);
203 // Buffer.BlockCopy(Data, 0, Bin, ScalarBytes << 1, DataLen);
204 //
205 // BigInteger h = EllipticCurve.ToInt(HashFunction(Bin));
206 // h = BigInteger.Remainder(h, Pair.Order);
207 //
208 // PointOnCurve Rcheck = Pair.ScalarMultiplication(h, AP, true);
209 // Pair.Negate(ref Rcheck);
210 // Pair.AddTo(ref Rcheck, Pair.ScalarMultiplication(s, Pair.BasePoint, true));
211 //
212 // if (!Rcheck.Y.Equals(R.Y))
213 // return false;
214 //
215 // if (!Rcheck.X.IsEven.Equals(R.X.IsEven))
216 // return false;
217 //
218 // return true;
219 }
220 catch (ArgumentException)
221 {
222 return false;
223 }
224 }
225
226 }*/
227}