Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ECDSA.cs
1using System;
2using System.IO;
3using System.Numerics;
4
6{
10 public static class ECDSA
11 {
21 public static byte[] Sign(byte[] Data, bool BigEndian, byte[] PrivateKey,
23 {
24 BigInteger e = CalcE(Data, HashFunction, Curve);
25 BigInteger r, s, PrivateKeyInt = EllipticCurve.ToInt(PrivateKey);
26 PointOnCurve P1;
27 int OrderBytes = Curve.OrderBytes;
28 byte[] k;
29
30 do
31 {
32 do
33 {
34 k = Curve.GenerateSecret();
35 P1 = Curve.ScalarMultiplication(k, Curve.BasePoint, true);
36 }
37 while (P1.IsXZero);
38
39 r = BigInteger.Remainder(P1.X, Curve.Order);
40 s = Curve.ModulusN.Divide(Curve.ModulusN.Add(e,
41 Curve.ModulusN.Multiply(r, PrivateKeyInt)), EllipticCurve.ToInt(k));
42 }
43 while (s.IsZero);
44
45 if (r.Sign < 0)
46 r += Curve.Prime;
47
48 P1.Normalize(Curve);
49
50 byte[] Signature = new byte[OrderBytes << 1];
51
52 byte[] S = r.ToByteArray(); // Little endian
53 if (S.Length != OrderBytes)
54 Array.Resize(ref S, OrderBytes);
55
56 if (BigEndian)
57 Array.Reverse(S);
58
59 Buffer.BlockCopy(S, 0, Signature, 0, OrderBytes);
60
61 S = s.ToByteArray(); // Little endian
62 if (S.Length != OrderBytes)
63 Array.Resize(ref S, OrderBytes);
64
65 if (BigEndian)
66 Array.Reverse(S);
67
68 Buffer.BlockCopy(S, 0, Signature, OrderBytes, OrderBytes);
69
70 return Signature;
71 }
72
73 private static BigInteger CalcE(byte[] Data, HashFunctionArray HashFunction,
74 PrimeFieldCurve Curve)
75 {
76 return CalcE(HashFunction(Data), Curve);
77 }
78
79 private static BigInteger CalcE(Stream Data, HashFunctionStream HashFunction,
80 PrimeFieldCurve Curve)
81 {
82 return CalcE(HashFunction(Data), Curve);
83 }
84
85 private static BigInteger CalcE(byte[] Hash, PrimeFieldCurve Curve)
86 {
87 //Console.Out.WriteLine("Hash: " + Hashes.BinaryToString(Hash));
88
89 int c = Hash.Length;
90 int MaxC = Curve.OrderBytes;
91
92 if (c != MaxC)
93 {
94 byte[] Hash2 = new byte[MaxC];
95
96 if (c < MaxC)
97 Buffer.BlockCopy(Hash, 0, Hash2, MaxC - c, c);
98 else
99 Buffer.BlockCopy(Hash, 0, Hash2, 0, MaxC);
100
101 Hash = Hash2;
102 }
103
104 //Console.Out.WriteLine("Hash (padded): " + Hashes.BinaryToString(Hash));
105
106 BigInteger e = EllipticCurve.ToInt(Hash, true);
107
108 //Console.Out.WriteLine("e: " + e.ToString());
109
110 return e;
111 }
112
122 public static byte[] Sign(Stream Data, bool BigEndian, byte[] PrivateKey,
124 {
125 BigInteger e = CalcE(Data, HashFunction, Curve);
126 BigInteger r, s, PrivateKeyInt = EllipticCurve.ToInt(PrivateKey);
127 PointOnCurve P1;
128 int OrderBytes = Curve.OrderBytes;
129 byte[] k;
130
131 do
132 {
133 do
134 {
135 k = Curve.GenerateSecret();
136 P1 = Curve.ScalarMultiplication(k, Curve.BasePoint, true);
137 }
138 while (P1.IsXZero);
139
140 r = BigInteger.Remainder(P1.X, Curve.Order);
141 s = Curve.ModulusN.Divide(Curve.ModulusN.Add(e,
142 Curve.ModulusN.Multiply(r, PrivateKeyInt)), EllipticCurve.ToInt(k));
143 }
144 while (s.IsZero);
145
146 if (r.Sign < 0)
147 r += Curve.Prime;
148
149 P1.Normalize(Curve);
150
151 byte[] Signature = new byte[OrderBytes << 1];
152
153 byte[] S = r.ToByteArray(); // Little endian
154 if (S.Length != OrderBytes)
155 Array.Resize(ref S, OrderBytes);
156
157 if (BigEndian)
158 Array.Reverse(S); // Big endian
159
160 Buffer.BlockCopy(S, 0, Signature, 0, OrderBytes);
161
162 S = s.ToByteArray(); // Little endian
163 if (S.Length != OrderBytes)
164 Array.Resize(ref S, OrderBytes);
165
166 if (BigEndian)
167 Array.Reverse(S); // Big endian
168
169 Buffer.BlockCopy(S, 0, Signature, OrderBytes, OrderBytes);
170
171 return Signature;
172 }
173
184 public static bool Verify(byte[] Data, byte[] PublicKey, bool BigEndian,
185 HashFunctionArray HashFunction, PrimeFieldCurve Curve, byte[] Signature)
186 {
187 int c = Signature.Length;
188 if (c != Curve.OrderBytes << 1)
189 return false;
190
191 c >>= 1;
192
193 byte[] Bin = new byte[c];
194 Buffer.BlockCopy(Signature, 0, Bin, 0, c);
195
196 BigInteger r = EllipticCurve.ToInt(Bin, BigEndian);
197
198 Bin = new byte[c];
199 Buffer.BlockCopy(Signature, c, Bin, 0, c);
200
201 BigInteger s = EllipticCurve.ToInt(Bin, BigEndian);
202 PointOnCurve PublicKeyPoint = Curve.Decode(PublicKey, BigEndian);
203
204 return Verify(Data, PublicKeyPoint, HashFunction, Curve, r, s);
205 }
206
217 public static bool Verify(byte[] Data, PointOnCurve PublicKeyPoint,
219 BigInteger s)
220 {
221 if (!PublicKeyPoint.NonZero || r.IsZero || s.IsZero || r >= Curve.Order || s >= Curve.Order)
222 return false;
223
224 BigInteger e = CalcE(Data, HashFunction, Curve);
225 BigInteger w = Curve.ModulusN.Invert(s);
226 BigInteger u1 = Curve.ModulusN.Multiply(e, w);
227 BigInteger u2 = Curve.ModulusN.Multiply(r, w);
228 PointOnCurve P2 = Curve.ScalarMultiplication(u1, Curve.BasePoint, true);
229 PointOnCurve P3 = Curve.ScalarMultiplication(u2, PublicKeyPoint, true);
230 Curve.AddTo(ref P2, P3);
231
232 if (!P2.NonZero)
233 return false;
234
235 P2.Normalize(Curve);
236
237 BigInteger Compare = BigInteger.Remainder(P2.X, Curve.Order);
238 if (Compare.Sign < 0)
239 Compare += Curve.Order;
240
241 return Compare == r;
242 }
243
254 public static bool Verify(Stream Data, byte[] PublicKey, bool BigEndian,
255 HashFunctionStream HashFunction, PrimeFieldCurve Curve, byte[] Signature)
256 {
257 int c = Signature.Length;
258 if (c != Curve.OrderBytes << 1)
259 return false;
260
261 c >>= 1;
262
263 byte[] Bin = new byte[c];
264 Buffer.BlockCopy(Signature, 0, Bin, 0, c);
265
266 BigInteger r = EllipticCurve.ToInt(Bin);
267
268 Bin = new byte[c];
269 Buffer.BlockCopy(Signature, c, Bin, 0, c);
270
271 BigInteger s = EllipticCurve.ToInt(Bin);
272 PointOnCurve PublicKeyPoint = Curve.Decode(PublicKey, BigEndian);
273
274 if (!PublicKeyPoint.NonZero || r.IsZero || s.IsZero || r >= Curve.Order || s >= Curve.Order)
275 return false;
276
277 BigInteger e = CalcE(Data, HashFunction, Curve);
278 BigInteger w = Curve.ModulusN.Invert(s);
279 BigInteger u1 = Curve.ModulusN.Multiply(e, w);
280 BigInteger u2 = Curve.ModulusN.Multiply(r, w);
281 PointOnCurve P2 = Curve.ScalarMultiplication(u1, Curve.BasePoint, true);
282 PointOnCurve P3 = Curve.ScalarMultiplication(u2, PublicKeyPoint, true);
283 Curve.AddTo(ref P2, P3);
284
285 if (!P2.NonZero)
286 return false;
287
288 P2.Normalize(Curve);
289
290 BigInteger Compare = BigInteger.Remainder(P2.X, Curve.Order);
291 if (Compare.Sign < 0)
292 Compare += Curve.Order;
293
294 return Compare == r;
295 }
296
297 }
298}
Implements the Elliptic Curve Digital Signature Algorithm (ECDSA).
Definition: ECDSA.cs:11
static bool Verify(Stream Data, byte[] PublicKey, bool BigEndian, HashFunctionStream HashFunction, PrimeFieldCurve Curve, byte[] Signature)
Verifies a signature of Data made by the ECDSA algorithm.
Definition: ECDSA.cs:254
static bool Verify(byte[] Data, byte[] PublicKey, bool BigEndian, HashFunctionArray HashFunction, PrimeFieldCurve Curve, byte[] Signature)
Verifies a signature of Data made by the ECDSA algorithm.
Definition: ECDSA.cs:184
static byte[] Sign(byte[] Data, bool BigEndian, byte[] PrivateKey, HashFunctionArray HashFunction, PrimeFieldCurve Curve)
Signs data using the ECDSA algorithm.
Definition: ECDSA.cs:21
static byte[] Sign(Stream Data, bool BigEndian, byte[] PrivateKey, HashFunctionStream HashFunction, PrimeFieldCurve Curve)
Signs data using the ECDSA algorithm.
Definition: ECDSA.cs:122
static bool Verify(byte[] Data, PointOnCurve PublicKeyPoint, HashFunctionArray HashFunction, PrimeFieldCurve Curve, BigInteger r, BigInteger s)
Verifies a signature of Data made by the ECDSA algorithm.
Definition: ECDSA.cs:217
Abstract base class for elliptic curves.
static BigInteger ToInt(byte[] Binary, bool BigEndian)
Converts a little-endian binary representation of a big integer to a BigInteger.
int OrderBytes
Number of bytes required to represent the order of the curve.
PointOnCurve Decode(byte[] Point)
Decodes an encoded point on the curve.
PointOnCurve BasePoint
Base-point of curve.
abstract void AddTo(ref PointOnCurve P, PointOnCurve Q)
Adds Q to P .
BigInteger Invert(BigInteger x)
Inverts a number in the field Z[p].
Definition: ModulusP.cs:112
BigInteger Multiply(BigInteger a, BigInteger b)
Multiplies two numbers, modulus p
Definition: ModulusP.cs:80
BigInteger Add(BigInteger a, BigInteger b)
Adds two numbers, modulus p
Definition: ModulusP.cs:31
BigInteger Divide(BigInteger a, BigInteger b)
Divides two numbers, modulus p
Definition: ModulusP.cs:91
Base class of Elliptic curves over a prime field.
override PointOnCurve ScalarMultiplication(byte[] N, PointOnCurve P, bool Normalize)
Performs the scalar multiplication of N *P .
ModulusP ModulusN
Arithmetic modulus n (the order)
override byte[] GenerateSecret()
Generates a new secret.
delegate byte[] HashFunctionStream(Stream Data)
Delegate to hash function.
delegate byte[] HashFunctionArray(byte[] Data)
Delegate to hash function.
HashFunction
Hash method enumeration.
Definition: Hashes.cs:26
Represents a point on a curve.
Definition: PointOnCurve.cs:10
void Normalize(PrimeFieldCurve Curve)
Normalizes a point, if in homogeneous coorinates.
bool IsXZero
If the X-coordinate is zero.
bool NonZero
If the point is not zero (infinity).