Как выполнить ECKA и вернуть ECPoint?

Я использую Bouncy Castle для выполнения соглашения о ключе эллиптической кривой с использованием протокола ECDH в программном обеспечении, связанном со смарт-картой, как определено в спецификации BSI-TR-03111, §3.4, с

Цель состоит в том, чтобы выполнить общее отображение одноразового номера в протоколе PACE, как определено в Техническом отчете SAC ИКАО, §3.4.2.1.1

(Я использую Java, но язык не является существенным в этом вопросе, я думаю)

KeyAgreement класс делает это очень простым (как показано здесь), но он позволяет только выводить координату X сгенерированного ECPoint, то есть Z AB (что часто, но не всегда то, что требуется.)

Есть ли способ получить актуальный ECPoint (то есть S AB) возвращается без переопределения алгоритма? Даже если формула сама по себе проста, нужно проверять ошибки и аномалии и учитывать вариации (например, умножение кофактора)

2 ответа

Я полностью забыл об этом вопросе. Это было решение, которое я реализовал:

package com.arjowiggins.arjonaut.crypto.ec;

import org.bouncycastle.crypto.BasicAgreement;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;

import java.math.BigInteger;

/**
 * Created by Salvatore on 22/04/2015.
 */
public class ECDHPointAgreement implements BasicAgreement {

    private ECPrivateKeyParameters key;

    public void init(CipherParameters key) {
        this.key = (ECPrivateKeyParameters) key;
    }

    public int getFieldSize() {
        return (key.getParameters().getCurve().getFieldSize() + 7) / 8;
    }

    public BigInteger calculateAgreement(CipherParameters pubKey) {
        ECPoint P = calculatePoint(pubKey);
        return P.getAffineXCoord().toBigInteger();
    }

    public ECPoint calculatePoint(CipherParameters pubKey) {
        ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey;
        ECPoint P = pub.getQ().multiply(key.getD()).normalize();

        if (P.isInfinity()) {
            throw new IllegalStateException("Infinity is not a valid agreement value for ECDH");
        }
        return P;
    }

}

Большая часть кода взята из BouncyCastle KeyAgreement учебный класс.

Решение уравнения кривой для Y - это именно то, что я сделал.

public static BigInteger computeAffineY(BigInteger affineX, ECParameterSpec params) {
    ECCurve bcCurve = toBouncyCastleECCurve(params);
    ECFieldElement a = bcCurve.getA();
    ECFieldElement b = bcCurve.getB();
    ECFieldElement x = bcCurve.fromBigInteger(affineX);     
    ECFieldElement y = x.multiply(x).add(a).multiply(x).add(b).sqrt();
    return y.toBigInteger();
}
Другие вопросы по тегам