Reputation: 23
How can I convert these 192-ECDSA curve parameters for use in Java Card?
p = 6277101735386680763835789423207666416083908700390324961279
n = 6277101735386680763835789423176059013767194773182842284081
SEED = 3045ae6f c8422f64 ed579528 d38120ea e12196d5
c = 3099d2bb bfcb2538 542dcd5f b078b6ef 5f3d6fe2 c745de65
b = 64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1
Gx = 188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012
Gy = 07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811
Upvotes: 2
Views: 518
Reputation: 5651
You have to map your values to Java Card parameters, which is more difficult than it seems to be because of lack of naming conventions. Moreover, some of your parameters are decimal, but you need them to be hexadecimal for Java Card.
Let's solve this step by step for a Java Card ECKey
you want to init with your parameters:
Field prime p
corresponds to key.setFieldFP
of the key. Your value is decimal, but you need it to be hexadecimal:
private final static byte[] fp = new byte[] {
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFE, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF
};
Order n
corresponds to key.setR
of the key. Your value is decimal, but you need it to be hexadecimal:
private final static byte[] r = new byte[] {
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x99, (byte)0xDE, (byte)0xF8, (byte)0x36, (byte)0x14, (byte)0x6B, (byte)0xC9, (byte)0xB1, (byte)0xB4, (byte)0xD2, (byte)0x28, (byte)0x31
};
Coefficient a
is set to -3
(modulo p
) in order to make computation with prime192v1
effective. This is just a fact you need to know. Hexadecimally, it is:
private final static byte[] a = new byte[] {
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFE, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFC
};
Coefficient b
is easy, because it is key.setB
in Java Card. You have it as a hexadecimal string = no conversion needed:
private final static byte[] b = new byte[] {
(byte)0x64, (byte)0x21, (byte)0x05, (byte)0x19, (byte)0xE5, (byte)0x9C, (byte)0x80, (byte)0xE7, (byte)0x0F, (byte)0xA7, (byte)0xE9, (byte)0xAB, (byte)0x72, (byte)0x24, (byte)0x30, (byte)0x49, (byte)0xFE, (byte)0xB8, (byte)0xDE, (byte)0xEC, (byte)0xC1, (byte)0x46, (byte)0xB9, (byte)0xB1
};
Generator point G
is tricky, because you have to concatenate both coordinates, convert them to the uncompressed form and prepend a prefix 04
(indicator of the uncompressed form). Some cards support other formats, but it is not guaranteed, so it is wiser to use the uncompressed form. Your coordinates are already hexadecimal = no conversion needed:
private final static byte[] g = new byte[] {
(byte)0x04, (byte)0x18, (byte)0x8D, (byte)0xA8, (byte)0x0E, (byte)0xB0, (byte)0x30, (byte)0x90, (byte)0xF6, (byte)0x7C, (byte)0xBF, (byte)0x20, (byte)0xEB, (byte)0x43, (byte)0xA1, (byte)0x88, (byte)0x00, (byte)0xF4, (byte)0xFF, (byte)0x0A, (byte)0xFD, (byte)0x82, (byte)0xFF, (byte)0x10, (byte)0x12, (byte)0x07, (byte)0x19, (byte)0x2B, (byte)0x95, (byte)0xFF, (byte)0xC8, (byte)0xDA, (byte)0x78, (byte)0x63, (byte)0x10, (byte)0x11, (byte)0xED, (byte)0x6B, (byte)0x24, (byte)0xCD, (byte)0xD5, (byte)0x73, (byte)0xF9, (byte)0x77, (byte)0xA1, (byte)0x1E, (byte)0x79, (byte)0x48, (byte)0x11
};
Cofactor h
corresponds to key.setK
of the key. Usually, this parameter is omitted and the default value 1
is used.
Key initialisation:
Provided you declared the parameters as private static final byte
arrays as described above, you can init your ECkey
this way:
key.setFieldFP(fp, (short)0, (short)fp.length);
key.setR(r, (short)0, (short)r.length);
key.setA(a, (short)0, (short)a.length);
key.setB(b, (short)0, (short)b.length);
key.setG(g, (short)0, (short)g.length);
You may be wondering what SEED
and c
values are and what they mean, because I didn't use them to compute Java Card parameters at all.
SEED is a random value, that was used to generate other parameters. SHA-1 hash was computed from SEED
. That is the c
in your notation. Values a
and b
were derived from c
.
That is the most problematic point of the whole EC cryptography: did NIST choose the seed as truly random? We don't know. They might have chosen it in order to get some advantage for decryption or signature forgery, because the resulting curve can be "easy" in some way.
Upvotes: 5