Search code examples
c#bouncycastleelliptic-curve

Bouncy Castle C#: How do I define a curve and points in order to test/play with EC point arithmetic?


I had a simple EC library for C#, but it is gone and I can't find it on the web. It was previously published on MSDN, but the link is now dead.

I am trying to use the Bouncy Castle Library to accomplish similar tasks. I want to Create a curve (secp256k1), and I want to be able to do point arithmetic and view the raw point data.

i.e.:

G + 3 * G = 4 * G

p + q

4 * G - G = 3 * G

etc.

What namespaces do I need to include, how do I define / declare the curve, and how do I define my points? I have successfully (I believe...) included the Bouncy Castle .dll in my C# project.

I am NOT interested in creating keys or anything of that sort. Just EC point arithmetic. A different (simple) library that would allow me to do the these same operations would be just as good or better.

Thanks for the help.

EDIT: I have continued to work on this, and my code looks like this:

    private static ECDomainParameters GetCurveParameters(string name)
    {
        X9ECParameters ecP = ECNamedCurveTable.GetByName(name);

        if (ecP == null)
            throw new Exception("unknown curve name: " + name);

        return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
    }

    private void btnTest2_Click(object sender, EventArgs e)
    {
        ECDomainParameters ecSpec = GetCurveParameters("secp256k1");
        ECCurve mycurve = ecSpec.Curve;

        ECPoint G, g2, twoG, threeG;

        G = ecSpec.G;
        g2 = ecSpec.G;

        twoG = G.Add(g2);
        threeG = G.Multiply(new BigInteger("3"));
    }

Now, I am able to run the code, and I am getting values back, but I'm not getting the correct points. G is correct, but all of the others are incorrect. i.e.:

2*G or G+G should =
c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,
  1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a

I am getting:
7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
  56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb

G * 3 is also incorrect.

(What I am calling correct is coming from the PyCoin application and can also be verified at this EC arithmetic website.)

Any suggestions?


Solution

  • Short answer: Use ECPoint.Normalize to return an ECPoint whose (X, Y) coordinates can be compared to PyCoin.

    Details: By default (BouncyCastle's) ECPoint operations are performed in projective coordinates; specifically what are usually called "Jacobian modified coordinates". This is for performance when performing a series of operations, especially a scalar multiplication. If you print out the value of e.g. twoG using the provided ECPoint.ToString method, you will see the extra coordinates present.

    When you want to compare an ECPoint to some (X, Y) value, you can call ECPoint.Normalize, which returns a new ECPoint where the Z coordinate is 1 and the X and Y coordinates are the affine values. It is a relatively expensive operation that is usually avoided until the final step of a larger calculation.