Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
EllipticCurvePublicKey.cs
1using System;
3using System.Diagnostics.CodeAnalysis;
4using System.Numerics;
8
10{
15 {
19 public override string Oid => "1.2.840.10045.2.1";
20
21 private int version;
22 private FieldType? field;
23 private BigInteger a;
24 private BigInteger b;
25 private BigInteger order;
26 private BigInteger coFactor;
27 private PointOnCurve basePoint;
28 private PointOnCurve? publicKey;
29 private EllipticCurve? namedCurve;
30
34 public override bool IsConfigured => this.field is not null || this.namedCurve is not null;
35
41 public override bool Configure(Vector SecurityInfo)
42 {
43 if (SecurityInfo.Length != 2)
44 return false;
45
46 object? Obj = SecurityInfo.LastElementNested;
47
48 if (Obj is Vector EcParameters)
49 {
50 if (EcParameters.Length < 5 || EcParameters.Length > 6)
51 return false;
52
53 if (EcParameters.FirstElement is not BigInteger Version ||
54 Version < int.MinValue ||
55 Version > int.MaxValue ||
56 EcParameters[1] is not FieldType Field ||
57 EcParameters[2] is not Vector Curve ||
58 Curve.Length < 2 || // Curve may have an optional third parameter: seed, a BIT STRING, which is not use in the signature validation, but available for documentation, if available.
59 Curve.FirstElement is not byte[] A ||
60 Curve[1] is not byte[] B ||
61 EcParameters[3] is not byte[] BasePoint ||
62 EcParameters[4] is not BigInteger Order)
63 {
64 return false;
65 }
66
67 BigInteger CoFactor;
68
69 if (EcParameters.Length == 6)
70 {
71 if (EcParameters[5] is BigInteger h)
72 CoFactor = h;
73 else
74 return false;
75 }
76 else
77 CoFactor = 1;
78
79 if (BasePoint.Length == 0)
80 return false;
81
83 return false;
84
85 this.version = (int)Version;
86 this.field = Field;
87 this.a = EllipticCurve.ToInt(A, true);
88 this.b = EllipticCurve.ToInt(B, true);
89 this.order = Order;
90 this.coFactor = CoFactor;
91 this.basePoint = G.Value;
92
93 return true;
94 }
95 else if (Obj is INamedCurve NamedCurve)
96 {
97 this.namedCurve = NamedCurve.GetCurve();
98
99 this.order = this.namedCurve.Order;
100 this.coFactor = this.namedCurve.Cofactor;
101 this.basePoint = this.namedCurve.BasePoint;
102
103 if (this.namedCurve is PrimeFieldCurve PrimeFieldCurve)
104 {
105 this.field = new PrimeField(PrimeFieldCurve.Prime);
106
107 if (this.namedCurve is WeierstrassCurve WeierstrassCurve)
108 {
109 this.a = WeierstrassCurve.A;
110 this.b = WeierstrassCurve.B;
111 }
112 else if (this.namedCurve is MontgomeryCurve MontgomeryCurve)
113 this.a = MontgomeryCurve.A;
114 else if (this.namedCurve is EdwardsCurve EdwardsCurve)
115 this.a = EdwardsCurve.D;
116 else if (this.namedCurve is EdwardsTwistedCurve EdwardsTwistedCurve)
117 this.a = EdwardsTwistedCurve.D;
118 }
119
120 return true;
121 }
122 else
123 return false;
124 }
125
132 public static bool TryParsePoint(byte[] Data, [NotNullWhen(true)] out PointOnCurve? Result)
133 {
134 if (Data.Length == 0)
135 {
136 Result = null;
137 return false;
138 }
139
140 switch (Data[0])
141 {
142 case 0: // Infinity
143 Result = new PointOnCurve();
144 return true;
145
146 case 4:
147 case 6:
148 case 7:
149 int c = (Data.Length - 1) / 2;
150 byte[] Gx = new byte[c];
151 byte[] Gy = new byte[c];
152
153 Buffer.BlockCopy(Data, 1, Gx, 0, c);
154 Buffer.BlockCopy(Data, 1 + c, Gy, 0, c);
155
156 Result = new PointOnCurve(
157 EllipticCurve.ToInt(Gx, true),
158 EllipticCurve.ToInt(Gy, true));
159 return true;
160
161 case 2: // Compressed, Y is even
162 c = Data.Length - 1;
163 Gx = new byte[c];
164
165 Buffer.BlockCopy(Data, 1, Gx, 0, c);
166
167 Result = new PointOnCurve(
168 EllipticCurve.ToInt(Gx, true),
169 0);
170 return true;
171
172 case 3: // Compressed, Y is odd
173 c = Data.Length - 1;
174 Gx = new byte[c];
175
176 Buffer.BlockCopy(Data, 1, Gx, 0, c);
177
178 Result = new PointOnCurve(
179 EllipticCurve.ToInt(Gx, true),
180 1);
181 return true;
182
183 default:
184 Result = null;
185 return false;
186 }
187 }
188
194 public override bool SetPublicKey(object? PublicKey)
195 {
196 if (PublicKey is not byte[] PublicKeyData)
197 return false;
198
199 if (!TryParsePoint(PublicKeyData, out this.publicKey))
200 return false;
201
202 return true;
203 }
204
208 public bool HasNamedCurve => this.namedCurve is not null;
209
213 public EllipticCurve NamedCurve => this.namedCurve!;
214
218 public int Version => this.version;
219
223 public FieldType Field => this.field!;
224
228 public BigInteger A => this.a;
229
233 public BigInteger B => this.b;
234
238 public BigInteger Order => this.order;
239
243 public BigInteger CoFactor => this.coFactor;
244
248 public PointOnCurve BasePoint => this.basePoint;
249
253 public PointOnCurve PublicKey => this.publicKey ?? new PointOnCurve();
254
259 public override void GetParsedParameters(Dictionary<string, object?> Parameters)
260 {
261 if (this.namedCurve is not null)
262 Parameters["NamedCurve"] = this.namedCurve.GetType().FullName;
263
264 this.field?.GetParsedParameters(Parameters);
265
266 Parameters["A"] = this.a;
267 Parameters["B"] = this.b;
268 Parameters["Order"] = this.order;
269 Parameters["CoFactor"] = this.coFactor;
270 Parameters["G.X"] = this.basePoint.X;
271 Parameters["G.Y"] = this.basePoint.Y;
272 Parameters["X"] = this.publicKey?.X;
273 Parameters["Y"] = this.publicKey?.Y;
274 }
275 }
276}
abstract void GetParsedParameters(Dictionary< string, object?> Parameters)
Gets parsed parameters from the field type definition, if available.
abstract EllipticCurve GetCurve()
Gets the Elliptic Curve associated with the named curve.
override void GetParsedParameters(Dictionary< string, object?> Parameters)
Gets parsed parameters from the public key definition, if available.
override bool Configure(Vector SecurityInfo)
If the object can be configured by the security information provided.
override bool SetPublicKey(object? PublicKey)
Sets the public key, based on the security information provided.
static bool TryParsePoint(byte[] Data, [NotNullWhen(true)] out PointOnCurve? Result)
Tries to parse a point on a curve.
BigInteger D
d coefficient of Edwards curve.
Base class of Edwards curves (x²+y²=1+dx²y²) over a prime field.
Definition: EdwardsCurve.cs:10
Base class of Twisted Edwards curves (-x²+y²=1+dx²y²) over a prime field.
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.
PointOnCurve BasePoint
Base-point of curve.
Base class of Montgomery curves (y²=x³+Ax²+x), with birational Edwards equivalent over a prime field.
Base class of Elliptic curves over a prime field.
Base class of Weierstrass curves (y²=x³+ax+b) over a prime field.
Represents a point on a curve.
Definition: PointOnCurve.cs:10