commit 7f47ca2eed13f20ef4344115bf927f776aacba2e Author: Harald Wolff Date: Tue Oct 17 21:53:04 2017 +0200 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4e82d27 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Autosave files +*~ + +# build +[Oo]bj/ +[Bb]in/ +packages/ +TestResults/ + +# globs +Makefile.in +*.DS_Store +*.sln.cache +*.suo +*.cache +*.pidb +*.userprefs +*.usertasks +config.log +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.user +*.tar.gz +tarballs/ +test-results/ +Thumbs.db + +# Mac bundle stuff +*.dmg +*.app + +# resharper +*_Resharper.* +*.Resharper + +# dotCover +*.dotCover diff --git a/Crypto.csproj b/Crypto.csproj new file mode 100644 index 0000000..9a6f38c --- /dev/null +++ b/Crypto.csproj @@ -0,0 +1,52 @@ + + + + Debug + AnyCPU + {15D8398F-01EB-4280-8E2E-B03417DD3215} + Library + Crypto + Crypto + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + + {97CA3CA9-98B3-4492-B072-D7A5995B68E9} + sharp.extensions + + + {E745E261-9E3E-4401-B3BA-78B38753A82E} + BigInt + + + + \ No newline at end of file diff --git a/EC/CurvePoint.cs b/EC/CurvePoint.cs new file mode 100644 index 0000000..62b8974 --- /dev/null +++ b/EC/CurvePoint.cs @@ -0,0 +1,89 @@ +using System; +using BigInt; +using System.Text; +using System.Runtime.CompilerServices; + +namespace Crypto.EC +{ + public class CurvePoint + { + public CurvePoint(EllipticCurve curve,UInteger x,UInteger y){ + Curve = curve; + X = x; + Y = y; + } + + public string toHexString(){ + StringBuilder sb = new StringBuilder(); + sb.Append(X.toHexString()); + sb.Append("."); + sb.Append(Y.toHexString()); + return sb.ToString(); + } + + public EllipticCurve Curve { get; private set; } + public UInteger X { get; private set; } + public UInteger Y { get; private set; } + + public bool isOnCurve(){ + return this.Curve.isOnCurve(this); + } + + public static CurvePoint operator +(CurvePoint p1, CurvePoint p2) + { + return p1.Curve.Add(p1,p2); + } + public static CurvePoint operator *(CurvePoint p1, UInteger n) + { + if (p1.Y == UInteger.ZERO){ + throw new NotImplementedException("Eternity point not implemented"); + } + + CurvePoint result = null; + CurvePoint p = p1; + + int i; + + for (i = 0; i < 256; i++) + { + if (n[i]){ + result = p; + break; + } + p += p; + } + for (; i < 256; i++) + { + p += p; + if (n[i]){ + result += p; + } + } + + return result; + } + + public static bool operator ==(CurvePoint p1, CurvePoint p2) + { + if (((object)p1 == null)||((object)p2==null)){ + return false; + } + return (p1.X == p2.X) && (p1.Y == p2.Y); + } + public static bool operator !=(CurvePoint p1, CurvePoint p2) + { + return (p1.X != p2.X) || (p1.Y != p2.Y); + } + + public override bool Equals(object obj) + { + if (this.GetType().IsInstanceOfType(obj)){ + return (this == (CurvePoint)obj); + } else { + return false; + } + } + + + } +} diff --git a/EC/EllipticCurve.cs b/EC/EllipticCurve.cs new file mode 100644 index 0000000..f0c8982 --- /dev/null +++ b/EC/EllipticCurve.cs @@ -0,0 +1,146 @@ +using System; +using BigInt; +using System.Text; +using sharp.extensions; + +namespace Crypto.EC +{ + public class EllipticCurve + { + public UInteger a { get; private set; } + public UInteger b { get; private set; } + public UInteger n { get; private set; } + public int h { get; private set; } + + public CurvePoint G { get; private set; } + public IntField Fp { get; private set; } + + public EllipticCurve(UInteger p,UInteger a,UInteger b,UInteger xG,UInteger yG,UInteger n,int h) + { + this.Fp = new IntField(p); + this.a = a; + this.b = b; + this.n = n; + this.h = h; + this.G = new CurvePoint(this, xG, yG); + + if (!isOnCurve(this.G)){ + throw new ArgumentException("G is not part of the curve"); + } + } + + public UInteger Y2(UInteger x){ + + UInteger yy = x; + + Console.WriteLine("Y(x): X = {0}",x.toHexString()); + Console.WriteLine("Y(x): x^2 = {0}",yy.Pow(2).toHexString()); + + yy = yy.Pow(3); + + Console.WriteLine("Y(x): x^3 = {0}",yy.toHexString()); + + yy += (a * x); + + Console.WriteLine("Y(x): x^3 + ax = {0}",yy.toHexString()); + + yy += b; + + Console.WriteLine("Y(x) x^3 + ax + b = {0}",yy.toHexString()); + + yy %= this.Fp.FieldModulo; + + Console.WriteLine("Y(x) mod p = {0}",yy.toHexString()); + + return yy; + } + + public bool isOnCurve(CurvePoint p){ + UInteger py2 = p.Y.Pow(2); + UInteger pcy2 = Y2(p.X); + + Console.WriteLine("CHECK A: {0}",py2.toHexString()); + Console.WriteLine("CHECK B: {0}",pcy2.toHexString()); + + return (py2 == pcy2); + } + + public CurvePoint Add(CurvePoint p1, CurvePoint p2) + { + if (((object)p1 == null) || ((object)p2 == null)) + { + throw new ArgumentException("CurvePoints to be added must not be null"); + } + + if (p1.Curve != p2.Curve) + { + throw new ArgumentException("Curvepoints to be added must belong to the same curve!"); + } + + if (p1 == p2) + { + UInteger s = p1.X.Pow(2); + s *= 3; + s += p1.Curve.a; + s /= (p1.Y << 1); + + //(((p1.X.Pow(2) * 3) + p1.Curve.a) / (p1.Y << 1)); + + UInteger xR = (s.Pow(2) - (p1.X << 1)); + UInteger yR = ((s * (p1.X - xR)) - p1.Y); + + return new CurvePoint(p1.Curve, xR, yR); + } + + if (p1.X == p2.X) + { + throw new NotImplementedException("Eternity point not implemented"); + } + else + { + UInteger s = (((p1.Y - p2.Y) / (p1.X - p2.X))); + UInteger xR = (s.Pow(2) - p1.X - p2.X); + UInteger yR = ((s * (p1.X - xR)) - p1.Y); + + return new CurvePoint(p1.Curve, xR, yR); + } + + throw new NotImplementedException("Point addition not yet implemented"); + } + +/* public CurvePoint getPoint(T x){ + x = new T(x, this.Fp); + return new CurvePoint(this,x,Y(x)); + } +*/ + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("[EllipticCurve] Fp={0}\n",(Fp == null) ? "" : Fp.ToString()); + sb.AppendFormat("[EllipticCurve] a={0}\n",a.toHexString()); + sb.AppendFormat("[EllipticCurve] b={0}\n",b.toHexString()); + sb.AppendFormat("[EllipticCurve] Gx={0}\n",G.X.toHexString()); + sb.AppendFormat("[EllipticCurve] Gy={0}\n",G.Y.toHexString()); + sb.AppendFormat("[EllipticCurve] G on curve? {0}",isOnCurve(G)); + + return sb.ToString(); + } + + public static EllipticCurve createSecp256k1(){ + UInteger p = (UInteger.ONE << 256); + p -= UInteger.ONE; + p -= (UInteger.ONE << 32); + p -= (UInteger.ONE << 9); + p -= (UInteger.ONE << 8); + p -= (UInteger.ONE << 7); + p -= (UInteger.ONE << 6); + p -= (UInteger.ONE << 4); + + UInteger xG = UInteger.fromHexString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"); + UInteger yG = UInteger.fromHexString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); + + UInteger n = UInteger.fromHexString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); + return new EllipticCurve(p, new UInteger(0), new UInteger(7), xG, yG, n, 1); + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..942664d --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("Crypto")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")]