Использование Curve25519 на javacard
Я изучаю использование кривой25519 на javacard 3.0.4, но я застрял и у меня есть следующие вопросы:
Поддерживает ли javacard 3.0.4 такую кривую?
До сих пор я пытался преобразовать уравнение Монтгомери в уравнение Вейерштрасса. Делая это и используя сайт Бернштейна, я получил следующие параметры:
p = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed
a = 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa984914a144
b = 0x7b425ed097b425ed097b425ed097b425ed097b425ed097b4260b5e9c7710c864
r = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
Gx = 0x9
Gy = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9
Как я нашел некоторые другие значения в Интернете, я также попытался с
Gx: 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad245a
Затем я проследил реализацию из ykneo-кривых и в итоге получил следующее:
public class Curve25519 {
public final static byte[] p = { // 32 bytes
(byte) 0x7f, (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) 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) 0xed };
public final static byte[] a = { // 32 bytes
(byte) 0x2a, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa,
(byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa,
(byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa,
(byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0x98, (byte) 0x49, (byte) 0x14, (byte) 0xa1, (byte) 0x44 };
public final static byte[] b = { // 32 bytes
(byte) 0x7b, (byte) 0x42, (byte) 0x5e, (byte) 0xd0, (byte) 0x97, (byte) 0xb4, (byte) 0x25, (byte) 0xed,
(byte) 0x09, (byte) 0x7b, (byte) 0x42, (byte) 0x5e, (byte) 0xd0, (byte) 0x97, (byte) 0xb4, (byte) 0x25,
(byte) 0xed, (byte) 0x09, (byte) 0x7b, (byte) 0x42, (byte) 0x5e, (byte) 0xd0, (byte) 0x97, (byte) 0xb4,
(byte) 0x26, (byte) 0x0b, (byte) 0x5e, (byte) 0x9c, (byte) 0x77, (byte) 0x10, (byte) 0xc8, (byte) 0x64 };
public final static byte[] G = { // 65 bytes
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x09, (byte) 0x20, (byte) 0xae, (byte) 0x19, (byte) 0xa1, (byte) 0xb8, (byte) 0xa0, (byte) 0x86,
(byte) 0xb4, (byte) 0xe0, (byte) 0x1e, (byte) 0xdd, (byte) 0x2c, (byte) 0x77, (byte) 0x48, (byte) 0xd1,
(byte) 0x4c, (byte) 0x92, (byte) 0x3d, (byte) 0x4d, (byte) 0x7e, (byte) 0x6d, (byte) 0x7c, (byte) 0x61,
(byte) 0xb2, (byte) 0x29, (byte) 0xe9, (byte) 0xc5, (byte) 0xa2, (byte) 0x7e, (byte) 0xce, (byte) 0xd3,
(byte) 0xd9 };
public final static byte[] r = { // 32 bytes
(byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x14, (byte) 0xde, (byte) 0xf9, (byte) 0xde, (byte) 0xa2, (byte) 0xf7, (byte) 0x9c, (byte) 0xd6,
(byte) 0x58, (byte) 0x12, (byte) 0x63, (byte) 0x1a, (byte) 0x5c, (byte) 0xf5, (byte) 0xd3, (byte) 0xed };
static public KeyPair newKeyPair() {
KeyPair kp = new KeyPair(KeyPair.ALG_EC_FP, (short) 256);
ECPrivateKey ecPrv = (ECPrivateKey) kp.getPrivate();
ECPublicKey ecPub = (ECPublicKey) kp.getPublic();
ecPrv.setFieldFP(p, (short) 0, (short) p.length);
ecPrv.setA(a, (short) 0, (short) a.length);
ecPrv.setB(b, (short) 0, (short) b.length);
ecPrv.setG(G, (short) 0, (short) G.length);
ecPrv.setR(r, (short) 0, (short) r.length);
ecPub.setFieldFP(p, (short) 0, (short) p.length);
ecPub.setA(a, (short) 0, (short) a.length);
ecPub.setB(b, (short) 0, (short) b.length);
ecPub.setG(G, (short) 0, (short) G.length);
ecPub.setR(r, (short) 0, (short) r.length);
return kp;
}
}
В апплете у меня есть следующий код:
private MyApplet(byte[] bArray, short bOffset, byte bLength) {
ecKeyPair = Curve25519.newKeyPair();
ecKeyPair.genKeyPair();
register();
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
new MyApplet(bArray, bOffset, bLength);
}
Когда я пытаюсь установить его на javacard, используя GPP, я получаю следующее исключение:
pro.javacard.gp.GPException: Install for Install and make selectable failed SW: 6F00
at pro.javacard.gp.GlobalPlatform.check(GlobalPlatform.java:1092)
at pro.javacard.gp.GlobalPlatform.installAndMakeSelectable(GlobalPlatform.java:798
)
at pro.javacard.gp.GPTool.main(GPTool.java:478)
Могу ли я использовать пары ключей Curve25519 для подписи ECDSA javacard?
2 ответа
Нет, такие кривые не поддерживаются напрямую.
Все средства Java Card Elliptic Curve используют уравнение Вейерштрасса, которое
у ^2 = х ^3 + а * х + б мод р
Кривая 25519 основана на
у ^2 = х ^3 + 486662* х ^ 2 + х мод р
К сожалению, невозможно напрямую поддерживать такие кривые Монтгомери.
Не совсем. Формы Монтгомери и Вейерштрасса могут быть преобразованы друг в друга: http://samuelkerr.com/?p=431
Тем не менее, существуют различные предостережения, заставляющие это работать на Javacards, и часть операций с кривыми / преобразования должна выполняться на ПК, разговаривающем с картой. В настоящее время я работаю над этим, и я рад поделиться кодом, как только это будет сделано.
ОБНОВЛЕНИЕ: я загрузил соответствующий код здесь: https://github.com/david-oswald/jc_curve25519