Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
MontgomeryCurve.cs
1using System;
2using System.Numerics;
3
5{
10 public abstract class MontgomeryCurve : PrimeFieldCurve
11 {
12 private EdwardsCurveBase pair = null;
13 private BigInteger a;
14
24 public MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger A,
25 BigInteger Order, int Cofactor)
26 : base(Prime, BasePoint, Order, Cofactor)
27 {
28 this.a = A;
29 }
30
41 public MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger A,
42 BigInteger Order, int Cofactor, byte[] Secret)
43 : base(Prime, BasePoint, Order, Cofactor, Secret)
44 {
45 this.a = A;
46 }
47
51 public BigInteger A => this.a;
52
59 public abstract PointOnCurve ToXY(PointOnCurve UV);
60
67 public abstract PointOnCurve ToUV(PointOnCurve XY);
68
75 public override void AddTo(ref PointOnCurve P, PointOnCurve Q)
76 {
77 this.Double(ref P);
78 }
79
84 public override void Double(ref PointOnCurve P)
85 {
86 throw new NotSupportedException("Scalar multiplication is performed using a Montgomery ladder.");
87 }
88
95 public BigInteger ScalarMultiplication(BigInteger N, BigInteger U)
96 {
97 return this.ScalarMultiplication(N.ToByteArray(), U);
98 }
99
106 public abstract BigInteger ScalarMultiplication(byte[] N, BigInteger U);
107
115 public override PointOnCurve ScalarMultiplication(byte[] N, PointOnCurve P, bool Normalize)
116 {
117 return new PointOnCurve(this.ScalarMultiplication(N, P.X), BigInteger.Zero);
118 }
119
129 public static BigInteger XFunction(byte[] N, BigInteger U,
130 BigInteger A24, BigInteger p, int Bits)
131 {
132 BigInteger x1 = U;
133 BigInteger x2 = BigInteger.One;
134 BigInteger z2 = BigInteger.Zero;
135 BigInteger x3 = U;
136 BigInteger z3 = BigInteger.One;
137 BigInteger A, AA, B, BB, E, C, D, DA, CB;
138 int kt;
139 int swap = 0;
140
141 kt = (Bits + 7) >> 3;
142 if (N.Length < kt)
143 Array.Resize(ref N, kt);
144
145 while (--Bits >= 0)
146 {
147 kt = (N[Bits >> 3] >> (Bits & 7)) & 1;
148 swap ^= kt;
149 ConditionalSwap(swap, ref x2, ref x3);
150 ConditionalSwap(swap, ref z2, ref z3);
151 swap = kt;
152
153 A = BigInteger.Remainder(x2 + z2, p);
154 AA = BigInteger.Remainder(A * A, p);
155 B = BigInteger.Remainder(x2 - z2, p);
156 BB = BigInteger.Remainder(B * B, p);
157 E = BigInteger.Remainder(AA - BB, p);
158 C = BigInteger.Remainder(x3 + z3, p);
159 D = BigInteger.Remainder(x3 - z3, p);
160 DA = BigInteger.Remainder(D * A, p);
161 CB = BigInteger.Remainder(C * B, p);
162
163 x3 = DA + CB;
164 x3 = BigInteger.Remainder(x3 * x3, p);
165 z3 = DA - CB;
166 z3 = BigInteger.Remainder(x1 * BigInteger.Remainder(z3 * z3, p), p);
167 x2 = BigInteger.Remainder(AA * BB, p);
168 z2 = BigInteger.Remainder(E * (AA + BigInteger.Remainder(A24 * E, p)), p);
169 }
170
171 ConditionalSwap(swap, ref x2, ref x3);
172 ConditionalSwap(swap, ref z2, ref z3);
173
174 BigInteger Result = BigInteger.Remainder(x2 * BigInteger.ModPow(z2, p - Two, p), p);
175 if (Result.Sign < 0)
176 Result += p;
177
178 return Result;
179 }
180
190 private static void ConditionalSwap(int swap, ref BigInteger I2, ref BigInteger I3)
191 {
192 byte[] x2 = I2.ToByteArray();
193 byte[] x3 = I3.ToByteArray();
194 int i, c = x2.Length, d = x3.Length;
195 byte Dummy;
196 byte Mask;
197 bool Sign;
198
199 if (c < d)
200 {
201 Sign = (x2[c - 1] & 0x80) != 0;
202 Array.Resize(ref x2, d);
203
204 if (Sign)
205 {
206 while (c < d)
207 x2[c++] = 0xff;
208 }
209 else
210 c = d;
211 }
212 else if (d < c)
213 {
214 Sign = (x3[d - 1] & 0x80) != 0;
215 Array.Resize(ref x3, c);
216
217 if (Sign)
218 {
219 while (d < c)
220 x3[d++] = 0xff;
221 }
222 //else
223 // d = c;
224 }
225
226 Mask = (byte)(0xff * swap);
227
228 for (i = 0; i < c; i++)
229 {
230 Dummy = (byte)(Mask & (x2[i] ^ x3[i]));
231 x2[i] ^= Dummy;
232 x3[i] ^= Dummy;
233 }
234
235 I2 = new BigInteger(x2);
236 I3 = new BigInteger(x3);
237 }
238
243 {
244 get
245 {
246 if (this.pair is null)
247 this.pair = this.CreatePair();
248
249 return this.pair;
250 }
251 }
252
257 public abstract EdwardsCurveBase CreatePair();
258
263 {
264 get
265 {
266 PointOnCurve PublicKey = base.PublicKeyPoint;
267
268 if (PublicKey.Y.IsZero)
269 {
270 PublicKey.Y = this.CalcV(PublicKey.X);
271 this.PublicKeyPoint = PublicKey;
272 }
273
274 return PublicKey;
275 }
276 }
277
283 public BigInteger CalcV(BigInteger U)
284 {
285 BigInteger U2 = this.modP.Multiply(U, U);
286 BigInteger U3 = this.modP.Multiply(U, U2);
287 BigInteger V2 = BigInteger.Remainder(U3 + this.modP.Multiply(this.a, U2) + U, this.Prime);
288
289 BigInteger V1 = this.modP.Sqrt(V2);
290 if (V1.Sign < 0)
291 V1 += this.Prime;
292
293 BigInteger V = this.Prime - V1;
294 if (V1 < V)
295 V = V1;
296
297 return V;
298 }
299
306 public override byte[] Encode(PointOnCurve Point, bool BigEndian)
307 {
308 byte[] Bin = Point.X.ToByteArray(); // Little-endian
309
310 if (Bin.Length != this.orderBytes)
311 Array.Resize(ref Bin, this.orderBytes);
312
313 if (BigEndian)
314 Array.Reverse(Bin); // Big-endian
315
316 return Bin;
317 }
318
325 public override PointOnCurve Decode(byte[] Point, bool BigEndian)
326 {
327 BigInteger U = ToInt(Point, BigEndian);
328 PointOnCurve P = new PointOnCurve(U, this.CalcV(U));
329
330 return P;
331 }
332
337 public override void SetPrivateKey(byte[] Secret)
338 {
339 base.SetPrivateKey(Secret);
340 this.pair = null;
341 }
342
348 public override bool IsPoint(PointOnCurve Point)
349 {
350 // Check if point matches y²=x³+Ax²+x=x(x²+Ax+1)=x(x(x+A)+1)
351
352 BigInteger Left = this.modP.Multiply(Point.Y, Point.Y);
353
354 BigInteger Right = this.modP.Multiply(
355 Point.X,
356 this.modP.Add(
357 1,
358 this.modP.Multiply(
359 Point.X,
360 this.modP.Add(
361 Point.X,
362 this.a))));
363
364 return Left == Right;
365 }
366 }
367}
Base class of different types of Edwards curves over a prime field.
byte[] Sign(byte[] Data)
Creates a signature of Data using the ECDSA algorithm.
readonly int orderBytes
Number of bytes used for the order of the curve.
static BigInteger ToInt(byte[] Binary, bool BigEndian)
Converts a little-endian binary representation of a big integer to a BigInteger.
virtual byte[] PublicKey
Encoded public key
PointOnCurve BasePoint
Base-point of curve.
BigInteger Sqrt(BigInteger N)
Computes sqrt(N) mod p.
Definition: ModulusP.cs:155
BigInteger Multiply(BigInteger a, BigInteger b)
Multiplies two numbers, modulus p
Definition: ModulusP.cs:80
Base class of Montgomery curves (y²=x³+Ax²+x), with birational Edwards equivalent over a prime field.
static BigInteger XFunction(byte[] N, BigInteger U, BigInteger A24, BigInteger p, int Bits)
Performs the scalar multiplication of N *U .
override void SetPrivateKey(byte[] Secret)
Sets the private key (and therefore also the public key) of the curve.
abstract PointOnCurve ToUV(PointOnCurve XY)
Converts a pair of (X,Y) coordinates for the birational Edwards curve to a pair of (U,...
override PointOnCurve ScalarMultiplication(byte[] N, PointOnCurve P, bool Normalize)
Performs the scalar multiplication of N *P .
override void Double(ref PointOnCurve P)
Doubles a point on the curve.
override void AddTo(ref PointOnCurve P, PointOnCurve Q)
Adds Q to P .
BigInteger ScalarMultiplication(BigInteger N, BigInteger U)
Performs the scalar multiplication of N *U .
abstract EdwardsCurveBase CreatePair()
Creates the Edwards Curve pair.
MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger A, BigInteger Order, int Cofactor, byte[] Secret)
Base class of Montgomery curves, with birational Edwards equivalent over a prime field.
abstract PointOnCurve ToXY(PointOnCurve UV)
Converts a pair of (U,V) coordinates to a pair of (X,Y) coordinates in the birational Edwards curve.
override bool IsPoint(PointOnCurve Point)
Checks if a point is on the curve.
override PointOnCurve Decode(byte[] Point, bool BigEndian)
Decodes an encoded point on the curve.
MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger A, BigInteger Order, int Cofactor)
Base class of Montgomery curves (y²=x³+Ax²+x), with birational Edwards equivalent over a prime field.
BigInteger CalcV(BigInteger U)
Calculates the V-coordinate, given the corresponding U-coordinate.
abstract BigInteger ScalarMultiplication(byte[] N, BigInteger U)
Performs the scalar multiplication of N *U .
override PointOnCurve PublicKeyPoint
Public key.
EdwardsCurveBase Pair
Edwards Curve pair.
override byte[] Encode(PointOnCurve Point, bool BigEndian)
Encodes a point on the curve.
Base class of Elliptic curves over a prime field.
readonly ModulusP modP
Arithmetic modulus p
Represents a point on a curve.
Definition: PointOnCurve.cs:10