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 {
22 public static byte[] Sign(byte[] Data, byte[] PrivateKey, HashFunctionArray HashFunction,
23 int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve)
24 {
25 BigInteger e = CalcE(Data, HashFunction, ScalarBytes, MsbMask);
26 BigInteger r, s, PrivateKeyInt = EllipticCurve.ToInt(PrivateKey);
27 PointOnCurve P1;
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[ScalarBytes << 1];
51
52 byte[] S = r.ToByteArray();
53 if (S.Length != ScalarBytes)
54 Array.Resize(ref S, ScalarBytes);
55
56 Array.Copy(S, 0, Signature, 0, ScalarBytes);
57
58 S = s.ToByteArray();
59 if (S.Length != ScalarBytes)
60 Array.Resize(ref S, ScalarBytes);
61
62 Array.Copy(S, 0, Signature, ScalarBytes, ScalarBytes);
63
64 return Signature;
65 }
66
67 private static BigInteger CalcE(byte[] Data, HashFunctionArray HashFunction,
68 int ScalarBytes, byte MsbMask)
69 {
70 byte[] Hash = HashFunction(Data);
71 int c = Hash.Length;
72
73 if (c != ScalarBytes)
74 Array.Resize(ref Hash, ScalarBytes);
75
76 Hash[ScalarBytes - 1] &= MsbMask;
77
78 return EllipticCurve.ToInt(Hash);
79 }
80
91 public static byte[] Sign(Stream Data, byte[] PrivateKey, HashFunctionStream HashFunction,
92 int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve)
93 {
94 BigInteger e = CalcE(Data, HashFunction, ScalarBytes, MsbMask);
95 BigInteger r, s, PrivateKeyInt = EllipticCurve.ToInt(PrivateKey);
96 PointOnCurve P1;
97 byte[] k;
98
99 do
100 {
101 do
102 {
103 k = Curve.GenerateSecret();
104 P1 = Curve.ScalarMultiplication(k, Curve.BasePoint, true);
105 }
106 while (P1.IsXZero);
107
108 r = BigInteger.Remainder(P1.X, Curve.Order);
109 s = Curve.ModulusN.Divide(Curve.ModulusN.Add(e,
110 Curve.ModulusN.Multiply(r, PrivateKeyInt)), EllipticCurve.ToInt(k));
111 }
112 while (s.IsZero);
113
114 if (r.Sign < 0)
115 r += Curve.Prime;
116
117 P1.Normalize(Curve);
118
119 byte[] Signature = new byte[ScalarBytes << 1];
120
121 byte[] S = r.ToByteArray();
122 if (S.Length != ScalarBytes)
123 Array.Resize(ref S, ScalarBytes);
124
125 Array.Copy(S, 0, Signature, 0, ScalarBytes);
126
127 S = s.ToByteArray();
128 if (S.Length != ScalarBytes)
129 Array.Resize(ref S, ScalarBytes);
130
131 Array.Copy(S, 0, Signature, ScalarBytes, ScalarBytes);
132
133 return Signature;
134 }
135
136 private static BigInteger CalcE(Stream Data, HashFunctionStream HashFunction,
137 int ScalarBytes, byte MsbMask)
138 {
139 byte[] Hash = HashFunction(Data);
140 int c = Hash.Length;
141
142 if (c != ScalarBytes)
143 Array.Resize(ref Hash, ScalarBytes);
144
145 Hash[ScalarBytes - 1] &= MsbMask;
146
147 return EllipticCurve.ToInt(Hash);
148 }
149
161 public static bool Verify(byte[] Data, byte[] PublicKey, HashFunctionArray HashFunction,
162 int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve, byte[] Signature)
163 {
164 int c = Signature.Length;
165 if (c != ScalarBytes << 1)
166 return false;
167
168 c >>= 1;
169
170 byte[] Bin = new byte[c];
171 Array.Copy(Signature, 0, Bin, 0, c);
172
173 BigInteger r = EllipticCurve.ToInt(Bin);
174
175 Bin = new byte[c];
176 Array.Copy(Signature, c, Bin, 0, c);
177
178 BigInteger s = EllipticCurve.ToInt(Bin);
179 PointOnCurve PublicKeyPoint = Curve.Decode(PublicKey);
180
181 if (!PublicKeyPoint.NonZero || r.IsZero || s.IsZero || r >= Curve.Order || s >= Curve.Order)
182 return false;
183
184 BigInteger e = CalcE(Data, HashFunction, ScalarBytes, MsbMask);
185 BigInteger w = Curve.ModulusN.Invert(s);
186 BigInteger u1 = Curve.ModulusN.Multiply(e, w);
187 BigInteger u2 = Curve.ModulusN.Multiply(r, w);
188 PointOnCurve P2 = Curve.ScalarMultiplication(u1, Curve.BasePoint, true);
189 PointOnCurve P3 = Curve.ScalarMultiplication(u2, PublicKeyPoint, true);
190 Curve.AddTo(ref P2, P3);
191
192 if (!P2.NonZero)
193 return false;
194
195 P2.Normalize(Curve);
196
197 BigInteger Compare = BigInteger.Remainder(P2.X, Curve.Order);
198 if (Compare.Sign < 0)
199 Compare += Curve.Order;
200
201 return Compare == r;
202 }
203
215 public static bool Verify(Stream Data, byte[] PublicKey, HashFunctionStream HashFunction,
216 int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve, byte[] Signature)
217 {
218 int c = Signature.Length;
219 if (c != ScalarBytes << 1)
220 return false;
221
222 c >>= 1;
223
224 byte[] Bin = new byte[c];
225 Array.Copy(Signature, 0, Bin, 0, c);
226
227 BigInteger r = EllipticCurve.ToInt(Bin);
228
229 Bin = new byte[c];
230 Array.Copy(Signature, c, Bin, 0, c);
231
232 BigInteger s = EllipticCurve.ToInt(Bin);
233 PointOnCurve PublicKeyPoint = Curve.Decode(PublicKey);
234
235 if (!PublicKeyPoint.NonZero || r.IsZero || s.IsZero || r >= Curve.Order || s >= Curve.Order)
236 return false;
237
238 BigInteger e = CalcE(Data, HashFunction, ScalarBytes, MsbMask);
239 BigInteger w = Curve.ModulusN.Invert(s);
240 BigInteger u1 = Curve.ModulusN.Multiply(e, w);
241 BigInteger u2 = Curve.ModulusN.Multiply(r, w);
242 PointOnCurve P2 = Curve.ScalarMultiplication(u1, Curve.BasePoint, true);
243 PointOnCurve P3 = Curve.ScalarMultiplication(u2, PublicKeyPoint, true);
244 Curve.AddTo(ref P2, P3);
245
246 if (!P2.NonZero)
247 return false;
248
249 P2.Normalize(Curve);
250
251 BigInteger Compare = BigInteger.Remainder(P2.X, Curve.Order);
252 if (Compare.Sign < 0)
253 Compare += Curve.Order;
254
255 return Compare == r;
256 }
257
258 }
259}
Implements the Elliptic Curve Digital Signature Algorithm (ECDSA).
Definition: ECDSA.cs:11
static byte[] Sign(Stream Data, byte[] PrivateKey, HashFunctionStream HashFunction, int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve)
Signs data using the ECDSA algorithm.
Definition: ECDSA.cs:91
static bool Verify(Stream Data, byte[] PublicKey, HashFunctionStream HashFunction, int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve, byte[] Signature)
Verifies a signature of Data made by the ECDSA algorithm.
Definition: ECDSA.cs:215
static bool Verify(byte[] Data, byte[] PublicKey, HashFunctionArray HashFunction, int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve, byte[] Signature)
Verifies a signature of Data made by the ECDSA algorithm.
Definition: ECDSA.cs:161
static byte[] Sign(byte[] Data, byte[] PrivateKey, HashFunctionArray HashFunction, int ScalarBytes, byte MsbMask, PrimeFieldCurve Curve)
Signs data using the ECDSA algorithm.
Definition: ECDSA.cs:22
Abstract base class for elliptic curves.
virtual PointOnCurve Decode(byte[] Point)
Decodes an encoded point on the curve.
static BigInteger ToInt(byte[] Binary)
Converts a little-endian binary representation of a big integer to a BigInteger.
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:28
Represents a point on a curve.
Definition: PointOnCurve.cs:11
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).