Question

I try to use an ECKey (http://www.win.tue.nl/pinpasjc/docs/apis/jc222/javacard/security/ECKey.html) with the P-256 curve defined by NIST on a Java Card:

Curve P-256

p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
r = 115792089210356248762697446949407573529996955224135760342422259061068512044369
s = c49d3608 86e70493 6a6678e1 139d26b7 819f7e90
c = 7efba166 2985be94 03cb055c 75d4f7e0 ce8d84a9 c5114abc af317768 0104fa0d
b = 5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b
Gx = 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296
Gy = 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5

with y²= x³ -3x + b (mod p)

As far as I understand it I use

  • p for setFieldFP(), prime p corresponding to the field GF(p)
  • r for setR(), order of the fixed point G of the curve,
  • b for setB(), second coefficient of the curve,
  • Gx and Gy for setG(), fixed point of the curve (after encoding them as ANSI X9.62),
  • cofactor of the order of the fixed point G is 1, so setK(1)

The coefficient A is -3 (according to the definition of the curve). But how do I have to encode -3 (as a byte[]), so that I can set it with setA()?

Was it helpful?

Solution 2

I guess it is easiest to look at existing libraries. P-256 is identical to secp256r1, and can be found in the Bouncy Castle source code. Alternatively, NIST has also published a document called Mathematical routines for the NIST prime elliptic curves which contain the parameters in hexadecimals. Thanks go to this excelent answer on the OTN discussion forums.

Code paste from Bouncy Castle, please respect the Bouncy Castle license.

/*
 * secp256r1
 */
static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
{
    protected X9ECParameters createParameters()
    {
        // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1
        BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
        BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
        BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
        byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90");
        BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
        BigInteger h = BigInteger.valueOf(1);

        ECCurve curve = new ECCurve.Fp(p, a, b);
        //ECPoint G = curve.decodePoint(Hex.decode("03"
        //+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
        ECPoint G = curve.decodePoint(Hex.decode("04"
            + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
            + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));

        return new X9ECParameters(curve, G, n, h, S);
    }
};

Note that n in this code is the order and h (of course) the co-factor. The seed S should not be required.

OTHER TIPS

Since calculation is done modulo p, you are free to add p whereever you please.

a = -3 -> a= -3 + p -> a = p - 3

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top