diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-26 17:49:58 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-26 17:49:58 +0700 |
commit | 2cf78b09633f6f993b03a544abf2ee28fb592ce4 (patch) | |
tree | 77ac09df09038ddf58a1b4b08d09b25467d43a8b /crypto/src/math/ec/custom/sec/SecP256R1Curve.cs | |
parent | Tidy up comments (diff) | |
download | BouncyCastle.NET-ed25519-2cf78b09633f6f993b03a544abf2ee28fb592ce4.tar.xz |
Port custom curve for secp256r1 from Java
Diffstat (limited to 'crypto/src/math/ec/custom/sec/SecP256R1Curve.cs')
-rw-r--r-- | crypto/src/math/ec/custom/sec/SecP256R1Curve.cs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs new file mode 100644 index 000000000..252ec345f --- /dev/null +++ b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs @@ -0,0 +1,95 @@ +using System; + +using Org.BouncyCastle.Math.Field; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1Curve + : ECCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")); + + private const int SecP256R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP256R1Point m_infinity; + + public SecP256R1Curve() + : base(FiniteFields.GetPrimeField(q)) + { + this.m_infinity = new SecP256R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"))); + //this.order = new BigInteger(1, Hex.decode("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")); + //this.cofactor = BigInteger.valueOf(1); + this.m_coord = SecP256R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP256R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP256R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP256R1Point(this, x, y, withCompression); + } + + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) + { + ECFieldElement x = FromBigInteger(X1); + ECFieldElement alpha = x.Square().Add(m_a).Multiply(x).Add(m_b); + ECFieldElement beta = alpha.Sqrt(); + + // + // if we can't find a sqrt we haven't got a point on the + // curve - run! + // + if (beta == null) + throw new ArithmeticException("Invalid point compression"); + + if (beta.TestBitZero() != (yTilde == 1)) + { + // Use the other root + beta = beta.Negate(); + } + + return new SecP256R1Point(this, x, beta, true); + } + } +} |