如何执行ECKA并返回ECPoint?

时间:2015-04-14 15:41:35

标签: cryptography bouncycastle smartcard public-key-encryption elliptic-curve

我正在使用Bouncy Castle在智能卡相关软件中使用ECDH协议执行Elliptic Curve Key Aggreement,如BSI-TR-03111规范中所定义,§3.4

目的是在PACE协议中执行nonce的通用映射,如ICAO SAC技术报告,§3.4.2.1.1

中所定义

(我正在使用Java,但我认为语言并不重要)

KeyAgreement类使它变得非常简单(例如here),但它只允许输出生成的ECPoint的X坐标,即Z AB (通常,但并不总是需要的。)

有没有办法让实际的ECPoint(即S AB )返回而不必重新实现算法?即使这个公式本身很简单,也必须检查错误和异常并考虑变化(例如辅助因子乘法)

2 个答案:

答案 0 :(得分:1)

我完全忘记了这个问题。这是我实施的解决方案:

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类。

答案 1 :(得分:0)

解决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();
}