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.Security.Cryptography;
3using System.Numerics;
4
6{
11 public abstract class MontgomeryCurve : PrimeFieldCurve
12 {
13 private EdwardsCurveBase pair = null;
14
23 public MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger Order,
24 int Cofactor)
25 : base(Prime, BasePoint, Order, Cofactor)
26 {
27 }
28
38 public MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger Order,
39 int Cofactor, byte[] Secret)
40 : base(Prime, BasePoint, Order, Cofactor, Secret)
41 {
42 }
43
47 protected abstract BigInteger A
48 {
49 get;
50 }
51
58 public abstract PointOnCurve ToXY(PointOnCurve UV);
59
66 public abstract PointOnCurve ToUV(PointOnCurve XY);
67
74 public override void AddTo(ref PointOnCurve P, PointOnCurve Q)
75 {
76 this.Double(ref P);
77 }
78
83 public override void Double(ref PointOnCurve P)
84 {
85 throw new NotSupportedException("Scalar multiplication is performed using a Montgomery ladder.");
86 }
87
94 public BigInteger ScalarMultiplication(BigInteger N, BigInteger U)
95 {
96 return this.ScalarMultiplication(N.ToByteArray(), U);
97 }
98
105 public abstract BigInteger ScalarMultiplication(byte[] N, BigInteger U);
106
114 public override PointOnCurve ScalarMultiplication(byte[] N, PointOnCurve P, bool Normalize)
115 {
116 return new PointOnCurve(this.ScalarMultiplication(N, P.X), BigInteger.Zero);
117 }
118
128 public static BigInteger XFunction(byte[] N, BigInteger U,
129 BigInteger A24, BigInteger p, int Bits)
130 {
131 BigInteger x1 = U;
132 BigInteger x2 = BigInteger.One;
133 BigInteger z2 = BigInteger.Zero;
134 BigInteger x3 = U;
135 BigInteger z3 = BigInteger.One;
136 BigInteger A, AA, B, BB, E, C, D, DA, CB;
137 int kt;
138 int swap = 0;
139
140 kt = (Bits + 7) >> 3;
141 if (N.Length < kt)
142 Array.Resize(ref N, kt);
143
144 while (--Bits >= 0)
145 {
146 kt = (N[Bits >> 3] >> (Bits & 7)) & 1;
147 swap ^= kt;
148 ConditionalSwap(swap, ref x2, ref x3);
149 ConditionalSwap(swap, ref z2, ref z3);
150 swap = kt;
151
152 A = BigInteger.Remainder(x2 + z2, p);
153 AA = BigInteger.Remainder(A * A, p);
154 B = BigInteger.Remainder(x2 - z2, p);
155 BB = BigInteger.Remainder(B * B, p);
156 E = BigInteger.Remainder(AA - BB, p);
157 C = BigInteger.Remainder(x3 + z3, p);
158 D = BigInteger.Remainder(x3 - z3, p);
159 DA = BigInteger.Remainder(D * A, p);
160 CB = BigInteger.Remainder(C * B, p);
161
162 x3 = DA + CB;
163 x3 = BigInteger.Remainder(x3 * x3, p);
164 z3 = DA - CB;
165 z3 = BigInteger.Remainder(x1 * BigInteger.Remainder(z3 * z3, p), p);
166 x2 = BigInteger.Remainder(AA * BB, p);
167 z2 = BigInteger.Remainder(E * (AA + BigInteger.Remainder(A24 * E, p)), p);
168 }
169
170 ConditionalSwap(swap, ref x2, ref x3);
171 ConditionalSwap(swap, ref z2, ref z3);
172
173 BigInteger Result = BigInteger.Remainder(x2 * BigInteger.ModPow(z2, p - Two, p), p);
174 if (Result.Sign < 0)
175 Result += p;
176
177 return Result;
178 }
179
189 private static void ConditionalSwap(int swap, ref BigInteger I2, ref BigInteger I3)
190 {
191 byte[] x2 = I2.ToByteArray();
192 byte[] x3 = I3.ToByteArray();
193 int i, c = x2.Length, d = x3.Length;
194 byte Dummy;
195 byte Mask;
196 bool Sign;
197
198 if (c < d)
199 {
200 Sign = (x2[c - 1] & 0x80) != 0;
201 Array.Resize(ref x2, d);
202
203 if (Sign)
204 {
205 while (c < d)
206 x2[c++] = 0xff;
207 }
208 else
209 c = d;
210 }
211 else if (d < c)
212 {
213 Sign = (x3[d - 1] & 0x80) != 0;
214 Array.Resize(ref x3, c);
215
216 if (Sign)
217 {
218 while (d < c)
219 x3[d++] = 0xff;
220 }
221 //else
222 // d = c;
223 }
224
225 Mask = (byte)(0xff * swap);
226
227 for (i = 0; i < c; i++)
228 {
229 Dummy = (byte)(Mask & (x2[i] ^ x3[i]));
230 x2[i] ^= Dummy;
231 x3[i] ^= Dummy;
232 }
233
234 I2 = new BigInteger(x2);
235 I3 = new BigInteger(x3);
236 }
237
242 {
243 get
244 {
245 if (this.pair is null)
246 this.pair = this.CreatePair();
247
248 return this.pair;
249 }
250 }
251
256 public abstract EdwardsCurveBase CreatePair();
257
262 {
263 get
264 {
265 PointOnCurve PublicKey = base.PublicKeyPoint;
266
267 if (PublicKey.Y.IsZero)
268 {
269 PublicKey.Y = this.CalcV(PublicKey.X);
270 this.PublicKeyPoint = PublicKey;
271 }
272
273 return PublicKey;
274 }
275 }
276
282 public BigInteger CalcV(BigInteger U)
283 {
284 BigInteger U2 = this.modP.Multiply(U, U);
285 BigInteger U3 = this.modP.Multiply(U, U2);
286 BigInteger V2 = BigInteger.Remainder(U3 + this.modP.Multiply(this.A, U2) + U, this.Prime);
287
288 BigInteger V1 = this.modP.Sqrt(V2);
289 if (V1.Sign < 0)
290 V1 += this.Prime;
291
292 BigInteger V = this.Prime - V1;
293 if (V1 < V)
294 V = V1;
295
296 return V;
297 }
298
304 public override byte[] Encode(PointOnCurve Point)
305 {
306 byte[] Bin = Point.X.ToByteArray();
307 int c = this.orderBytes;
308
309 if (Bin.Length < c)
310 Array.Resize(ref Bin, c);
311
312 return Bin;
313 }
314
320 public override PointOnCurve Decode(byte[] Point)
321 {
322 BigInteger U = ToInt(Point);
323 PointOnCurve P = new PointOnCurve(U, this.CalcV(U));
324
325 return P;
326 }
327
332 public override void SetPrivateKey(byte[] Secret)
333 {
334 base.SetPrivateKey(Secret);
335 this.pair = null;
336 }
337
338 }
339}
Base class of different types of Edwards curves over a prime field.
readonly int orderBytes
Number of bytes used for the order of the curve.
abstract byte[] Sign(byte[] Data)
Creates a signature of Data using the ECDSA algorithm.
static BigInteger ToInt(byte[] Binary)
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 biratinal 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,...
MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger Order, int Cofactor, byte[] Secret)
Base class of Montgomery curves, with biratinal Edwards equivalent over a prime field.
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 .
MontgomeryCurve(BigInteger Prime, PointOnCurve BasePoint, BigInteger Order, int Cofactor)
Base class of Montgomery curves (y²=x³+Ax²+x), with biratinal Edwards equivalent over a prime field.
BigInteger ScalarMultiplication(BigInteger N, BigInteger U)
Performs the scalar multiplication of N *U .
abstract EdwardsCurveBase CreatePair()
Creates the Edwards Curve pair.
abstract BigInteger A
a Coefficient in the definition of the curve E: v²=u³+A*u²+u
override byte[] Encode(PointOnCurve Point)
Encodes a point on the curve.
abstract PointOnCurve ToXY(PointOnCurve UV)
Converts a pair of (U,V) coordinates to a pair of (X,Y) coordinates in the birational Edwards curve.
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 PointOnCurve Decode(byte[] Point)
Decodes an encoded 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:11