Encryption 如何在X25519中为PrivateKey生成公钥?

Encryption 如何在X25519中为PrivateKey生成公钥?,encryption,Encryption,目前我正在使用基于X25519密钥的加密 基本上,我的问题是如何从现有的X25519PrivateKey派生出PublicKey 我尝试了以下方法: protected PublicKey generatePublicKeyFromPrivate(PrivateKey privateKey) throws GeneralSecurityException { PublicKey basePublicKey = generatePublicKey(BigInteger.va

目前我正在使用基于X25519密钥的加密

基本上,我的问题是如何从现有的X25519
PrivateKey
派生出
PublicKey

我尝试了以下方法:

    protected PublicKey generatePublicKeyFromPrivate(PrivateKey privateKey) throws GeneralSecurityException {
        PublicKey basePublicKey = generatePublicKey(BigInteger.valueOf(9));
        KeyAgreement keyAgreement = KeyAgreement.getInstance(X25519);
        keyAgreement.init(privateKey, new ECGenParameterSpec(X25519));
        keyAgreement.doPhase(basePublicKey, true);
        byte[] bytes = keyAgreement.generateSecret();
        return generatePublicKey(new BigInteger(bytes));
    }
公钥已成功生成。我甚至将此方法与第三方库方法()进行了比较:生成PubliKeys匹配

然而,当我尝试使用Java的
KeyPairGenerator
同时获取PrivateKey和PubliKey,然后尝试自己为该PrivateKey生成公钥时,它们是不同的

    public KeyPair generateX25519KeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(X25519);
        return keyPairGenerator.generateKeyPair();
    }
我决定查找
KeyPairGenerator
XDHKeyPairGenerator
实现)的源代码,并找到它们执行乘法时的部分:

    /**
     *
     * Multiply an encoded scalar with a point as a BigInteger and return an
     * encoded point. The array k holding the scalar will be pruned by
     * modifying it in place.
     *
     * @param k an encoded scalar
     * @param u the u-coordinate of a point as a BigInteger
     * @return the encoded product
     */
    public byte[] encodedPointMultiply(byte[] k, BigInteger u) {
        pruneK(k);
        ImmutableIntegerModuloP elemU = field.getElement(u);
        return pointMultiply(k, elemU).asByteArray(params.getBytes());
    }
    /**
     * Compute a public key from an encoded private key. This method will
     * modify the supplied array in order to prune it.
     */
    public BigInteger computePublic(byte[] k) {
        pruneK(k);
        return pointMultiply(k, this.basePoint).asBigInteger();
    }
但是,用于单独生成PubliKey的方法使用另一种乘法:

    /**
     *
     * Multiply an encoded scalar with a point as a BigInteger and return an
     * encoded point. The array k holding the scalar will be pruned by
     * modifying it in place.
     *
     * @param k an encoded scalar
     * @param u the u-coordinate of a point as a BigInteger
     * @return the encoded product
     */
    public byte[] encodedPointMultiply(byte[] k, BigInteger u) {
        pruneK(k);
        ImmutableIntegerModuloP elemU = field.getElement(u);
        return pointMultiply(k, elemU).asByteArray(params.getBytes());
    }
    /**
     * Compute a public key from an encoded private key. This method will
     * modify the supplied array in order to prune it.
     */
    public BigInteger computePublic(byte[] k) {
        pruneK(k);
        return pointMultiply(k, this.basePoint).asBigInteger();
    }
如您所见,区别在于,在第一种情况下,它们将
asByteArray()
方法应用于结果:

     * Returns the little-endian encoding of this' % 2^(8 * len), where this'
     * is the canonical integer value equivalent to this.
     *
     * @param len the length of the desired array
     * @return a byte array of length len containing the result
     */
    default byte[] asByteArray(int len) {
        byte[] result = new byte[len];
        asByteArray(result);
        return result;
    }

所以我的问题是:他们为什么这样做?为什么在使用
KeyPairGenerator
时将此“小端编码”应用于公钥,但在公钥分别从私钥派生时不应用此编码。

通过将基点乘以“钳制”秘密标量并返回编码的X坐标来计算公钥

箝位意味着屏蔽3个最低有效位,屏蔽顶部位,并设置第二个顶部位

有关详细信息,请参阅


但看起来这更像是一个编程问题,实际问题可能与X25519无关。对于给定的秘密,将从该代码获得的输出与使用不同库实现的相同操作进行比较。如果公钥匹配,则问题出在其他地方。

通过将基点乘以“钳制”秘密标量并返回编码的X坐标来计算公钥

箝位意味着屏蔽3个最低有效位,屏蔽顶部位,并设置第二个顶部位

有关详细信息,请参阅


但看起来这更像是一个编程问题,实际问题可能与X25519无关。对于给定的秘密,将从该代码获得的输出与使用不同库实现的相同操作进行比较。如果公钥匹配,问题就出在其他地方。

这实际上是一个编程问题,关于特定的库。BouncyCastle邮件列表()将是一个更好的提问位置。这是否回答了您的问题?这实际上是一个关于特定库的编程问题。BouncyCastle邮件列表()将是一个更好的提问位置。这是否回答了您的问题?对不起,我没有意识到我的问题有点含糊。我补充了一些细节。对不起,我没有意识到我的问题有点含糊。我添加了一些细节。