diff options
author | Oren Novotny <oren@novotny.org> | 2015-04-25 13:39:23 -0400 |
---|---|---|
committer | Oren Novotny <oren@novotny.org> | 2015-04-25 13:39:23 -0400 |
commit | 8178b78a3532383ed12bb22d092f1d6cb1842c17 (patch) | |
tree | a68d57a8d1dd5e8f1154291b5d5b0b4a10630226 /crypto/src/math/ec/custom/sec/SecT283K1Curve.cs | |
parent | Merge remote-tracking branch 'upstream/master' into master-vs12 (diff) | |
parent | Update version to 1.8.0-RC.1 prior to release (diff) | |
download | BouncyCastle.NET-ed25519-8178b78a3532383ed12bb22d092f1d6cb1842c17.tar.xz |
Merge branch 'master' into master-vs12
Diffstat (limited to 'crypto/src/math/ec/custom/sec/SecT283K1Curve.cs')
-rw-r--r-- | crypto/src/math/ec/custom/sec/SecT283K1Curve.cs | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs new file mode 100644 index 000000000..42414401f --- /dev/null +++ b/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs @@ -0,0 +1,194 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283K1Curve + : AbstractF2mCurve + { + private const int SecT283K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT283K1Point m_infinity; + + public SecT283K1Curve() + : base(283, 5, 7, 12) + { + this.m_infinity = new SecT283K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SecT283K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT283K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 283; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT283FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT283K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT283K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + /** + * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2). + * + * @param yTilde + * ~yp, an indication bit for the decompression of yp. + * @param X1 + * The field element xp. + * @return the decompressed point. + */ + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) + { + ECFieldElement x = FromBigInteger(X1), y = null; + if (x.IsZero) + { + y = B.Sqrt(); + } + else + { + ECFieldElement beta = x.Square().Invert().Multiply(B).Add(A).Add(x); + ECFieldElement z = SolveQuadraticEquation(beta); + if (z != null) + { + if (z.TestBitZero() != (yTilde == 1)) + { + z = z.AddOne(); + } + + switch (this.CoordinateSystem) + { + case COORD_LAMBDA_AFFINE: + case COORD_LAMBDA_PROJECTIVE: + { + y = z.Add(x); + break; + } + default: + { + y = z.Multiply(x); + break; + } + } + } + } + + if (y == null) + throw new ArgumentException("Invalid point compression"); + + return this.CreateRawPoint(x, y, true); + } + + /** + * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62 + * D.1.6) The other solution is <code>z + 1</code>. + * + * @param beta + * The value to solve the quadratic equation for. + * @return the solution for <code>z<sup>2</sup> + z = beta</code> or + * <code>null</code> if no solution exists. + */ + private ECFieldElement SolveQuadraticEquation(ECFieldElement beta) + { + if (beta.IsZero) + return beta; + + ECFieldElement zeroElement = FromBigInteger(BigInteger.Zero); + + ECFieldElement z = null; + ECFieldElement gamma = null; + + Random rand = new Random(); + do + { + ECFieldElement t = FromBigInteger(new BigInteger(283, rand)); + z = zeroElement; + ECFieldElement w = beta; + for (int i = 1; i < 283; i++) + { + ECFieldElement w2 = w.Square(); + z = z.Square().Add(w2.Multiply(t)); + w = w2.Add(beta); + } + if (!w.IsZero) + return null; + gamma = z.Square().Add(z); + } + while (gamma.IsZero); + + return z; + } + + public virtual int M + { + get { return 283; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 5; } + } + + public virtual int K2 + { + get { return 7; } + } + + public virtual int K3 + { + get { return 12; } + } + } +} |