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