4using System.Security.Cryptography;
18 public const string Namespace =
"http://waher.se/Schema/EllipticCurves.xsd";
23 public static readonly BigInteger
Two =
new BigInteger(2);
33 protected static readonly RandomNumberGenerator
rnd = RandomNumberGenerator.Create();
43 protected readonly BigInteger
n;
65 private byte[] secret;
66 private byte[] privateKey;
67 private byte[] publicKey;
68 private byte[] additionalInfo;
96 this.privateKey =
null;
97 this.publicKey =
null;
98 this.additionalInfo =
null;
101 this.orderBytes = (this.orderBits + 7) >> 3;
102 this.msbOrderMask = 0xff;
108 this.msbOrderMask = 0;
111 this.msbOrderMask >>= MaskBits;
119 if (this.secret is
null)
132 if (this.privateKey is
null)
135 return this.privateKey;
146 if (this.publicKey is
null)
149 return this.publicKey;
160 if (this.additionalInfo is
null)
163 return this.additionalInfo;
174 if (this.publicKey is
null)
177 return this.publicKeyPoint;
182 this.publicKeyPoint = value;
234 this.publicKey = this.
Encode(P);
235 this.publicKeyPoint = P;
236 this.privateKey = Info.Item1;
237 this.additionalInfo = Info.Item2;
238 this.secret = Secret;
248 return new Tuple<byte[], byte[]>(Secret,
null);
258 byte[] X = Point.
X.ToByteArray();
259 byte[] Y = Point.
Y.ToByteArray();
261 if (X.Length !=
this.orderBytes)
262 Array.Resize(ref X, this.orderBytes);
264 if (Y.Length !=
this.orderBytes)
265 Array.Resize(ref Y, this.orderBytes);
267 byte[] Result =
new byte[this.orderBytes << 1];
269 Array.Copy(X, 0, Result, 0, this.orderBytes);
270 Array.Copy(Y, 0, Result, this.orderBytes, this.orderBytes);
282 if (Point.Length !=
this.orderBytes << 1)
283 throw new ArgumentException(
"Invalid point.", nameof(Point));
288 if ((Point[this.orderBytes - 1] & 0x80) != 0)
291 if ((Point[Point.Length - 1] & 0x80) != 0)
294 byte[] X =
new byte[XLen];
295 byte[] Y =
new byte[YLen];
297 Array.Copy(Point, 0, X, 0, this.orderBytes);
298 Array.Copy(Point, this.orderBytes, Y, 0, this.orderBytes);
300 return new PointOnCurve(
new BigInteger(X),
new BigInteger(Y));
336 for (i = 0; i < c; i++)
340 for (Bit = 1; Bit != 0; Bit <<= 1)
343 this.
AddTo(ref Result, P);
359 return new PointOnCurve(BigInteger.Zero, BigInteger.Zero);
395 public abstract byte[]
Sign(
byte[] Data);
402 public abstract byte[]
Sign(Stream Data);
426 public virtual void Export(XmlWriter Output)
428 if (this.secret is
null)
432 Output.WriteAttributeString(
"type", this.GetType().FullName);
433 Output.WriteAttributeString(
"d", Convert.ToBase64String(
this.secret));
434 Output.WriteEndElement();
442 XmlWriterSettings Settings =
new XmlWriterSettings()
445 OmitXmlDeclaration =
true
447 StringBuilder sb =
new StringBuilder();
448 using (XmlWriter w = XmlWriter.Create(sb, Settings))
454 return sb.ToString();
463 public static BigInteger
ToInt(
byte[] Binary)
465 int c = Binary.Length;
466 if ((Binary[c - 1] & 0x80) != 0)
467 Array.Resize(ref Binary, c + 1);
469 return new BigInteger(Binary);
Implements the Elliptic Curve Diffie-Hellman (ECDH) algorithm.
static byte[] GetSharedKey(byte[] LocalPrivateKey, byte[] RemotePublicKey, HashFunctionArray HashFunction, EllipticCurve Curve)
Gets a shared key using the Elliptic Curve Diffie-Hellman (ECDH) algorithm.
Abstract base class for elliptic curves.
virtual PointOnCurve ScalarMultiplication(byte[] N, PointOnCurve P, bool Normalize)
Performs the scalar multiplication of N *P .
EllipticCurve(PointOnCurve BasePoint, BigInteger Order, int Cofactor)
Abstract base class for elliptic curves.
readonly PointOnCurve g
Base point
abstract bool Verify(Stream Data, byte[] PublicKey, byte[] Signature)
Verifies a signature of Data made by the ECDSA algorithm.
readonly int orderBits
Number of bits used for the order of the curve.
abstract string CurveName
Name of curve.
virtual Tuple< byte[], byte[]> CalculatePrivateKey(byte[] Secret)
Calculates a private key from a secret.
abstract byte[] GenerateSecret()
Generates a new secret.
abstract bool Verify(byte[] Data, byte[] PublicKey, byte[] Signature)
Verifies a signature of Data made by the ECDSA algorithm.
BigInteger Order
Order of curve.
readonly int cofactor
cofactor
readonly int orderBytes
Number of bytes used for the order of the curve.
readonly BigInteger n
Order
byte[] AdditionalInfo
Curve-specific additional information
int OrderBits
Number of bits required to represent the order of the curve.
virtual PointOnCurve Decode(byte[] Point)
Decodes an encoded point on the curve.
abstract void Double(ref PointOnCurve P)
Doubles a point on the curve.
EllipticCurve(PointOnCurve BasePoint, BigInteger Order, int Cofactor, byte[] Secret)
Abstract base class for elliptic curves.
virtual void Export(XmlWriter Output)
Exports the curve parameters to XML.
virtual byte[] Encode(PointOnCurve Point)
Encodes a point on the curve.
int Cofactor
Cofactor of curve.
abstract byte[] Sign(Stream Data)
Creates a signature of Data using the ECDSA algorithm.
abstract byte[] Sign(byte[] Data)
Creates a signature of Data using the ECDSA algorithm.
string Export()
Exports the curve parameters to an XML string.
int OrderBytes
Number of bytes required to represent the order of the curve.
static BigInteger ToInt(byte[] Binary)
Converts a little-endian binary representation of a big integer to a BigInteger.
const string ElementName
"EllipticCurve"
virtual byte[] PublicKey
Encoded public key
void GenerateKeys()
Generates a new Private Key.
static readonly BigInteger Two
2
virtual void Init()
Method initiazing the elliptic curve properties.
virtual PointOnCurve Zero
Neutral point.
static readonly RandomNumberGenerator rnd
Random number generator
const string Namespace
http://waher.se/Schema/EllipticCurves.xsd
PointOnCurve BasePoint
Base-point of curve.
virtual byte[] GetSharedKey(byte[] RemotePublicKey, HashFunctionArray HashFunction)
Gets a shared key using the Elliptic Curve Diffie-Hellman (ECDH) algorithm.
byte[] PrivateKey
Private key
virtual void SetPrivateKey(byte[] Secret)
Sets the private key (and therefore also the public key) of the curve.
virtual PointOnCurve PublicKeyPoint
Public key, as a point on the elliptic curve.
readonly byte msbOrderMask
Mask for most significant byte of scalars.
abstract void AddTo(ref PointOnCurve P, PointOnCurve Q)
Adds Q to P .
PointOnCurve ScalarMultiplication(BigInteger N, PointOnCurve P, bool Normalize)
Performs the scalar multiplication of N *P .
Integer arithmetic, modulus a prime.
static int CalcBits(BigInteger n)
Calculates the number of bits used.
Interface for digital signature algorithms.
delegate byte[] HashFunctionArray(byte[] Data)
Delegate to hash function.
HashFunction
Hash method enumeration.
Represents a point on a curve.