elliptic
elliptic copied to clipboard
Montgomery Curve25519 is not openssl compatible
import * as elliptic from 'elliptic';
const ec = new elliptic.ec('curve25519');
const privateKey = ec.keyFromPrivate('0843f2237a9597939c62512ab405e1d92838044b757e1395dbc8e3deeb4e9f9c', 'hex');
/*
It is converted as below. (See You can check it through https://lapo.it/asn1js/ )
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIAhD8iN6lZeTnGJRKrQF4dkoOARLdX4TldvI497rTp+c
-----END PRIVATE KEY-----
Expected Output (OpenSSL's Output)
$ openssl pkey -in a.pem -pubout
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAYt0EgkDficTmquiGJommRI6zRhxIFJkSgnfWjFtUIRM=
-----END PUBLIC KEY-----
=> 0062dd048240df89c4e6aae8862689a6448eb3461c481499128277d68c5b542113
*/
const publicKey = privateKey.getPublic();
console.log('public key : ' + publicKey.encode('hex', false));
// public key : 79a24c01a2fa3db176de2c27dc57856abfb2eb25634abe803e7d940399f8fc98
// != 62dd048240df89c4e6aae8862689a6448eb3461c481499128277d68c5b542113
Java(Bouncycastle) also same
import org.bouncycastle.jcajce.interfaces.XDHPublicKey;
import org.bouncycastle.jcajce.provider.asymmetric.edec.BCXDHPrivateKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
public class Main {
public static String toHex(byte[] data) {
StringBuilder sb = new StringBuilder();
sb.append(data.length + " : ");
for (byte b: data) sb.append(String.format("%02x", b&0xff));
return sb.toString();
}
public static void main(String[] args) throws Exception {
BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider();
KeyFactory keyFactory = KeyFactory.getInstance("X25519", bouncyCastleProvider);
BCXDHPrivateKey privateKey = (BCXDHPrivateKey)keyFactory.generatePrivate(new PKCS8EncodedKeySpec(
Base64.getDecoder().decode("MC4CAQAwBQYDK2VuBCIEIAhD8iN6lZeTnGJRKrQF4dkoOARLdX4TldvI497rTp+c")
));
XDHPublicKey publicKey = privateKey.getPublicKey();
System.out.println("publicKey = " + publicKey);
// System.out.println("publicKey = " + toHex(publicKey.getEncoded()));
}
}
// OUTPUT:
// publicKey = X25519 Public Key [86:4a:7f:9b:bd:8e:ad:81:53:96:cd:49:6e:e0:e1:6e:29:d6:70:9c]
// public data: 62dd048240df89c4e6aae8862689a6448eb3461c481499128277d68c5b542113
The value obtained by changing the private key to public key through OpenSSL and the value obtained by obtaining the public key through elliptic library are different. So ECDH also fails.
Note: This is different from the issue in #122.
It seems to be related to #94 issue. Currently, the above test fails. Isn't this repo's X25519 implementation not standard?