До сих пор я обнаружил только один способ сделать это через интерфейсы, предоставляемые JDK (без использования дополнительных библиотек, таких как Bouncy Castle или Google Tink):
public class StaticSecureRandom extends SecureRandom {
private final byte[] privateKey;
public StaticSecureRandom(byte[] privateKey) {
this.privateKey = privateKey.clone();
}
@Override
public void nextBytes(byte[] bytes) {
System.arraycopy(privateKey, 0, bytes, 0, privateKey.length);
}
}
public PublicKey generatePublicKeyFromPrivate(PrivateKey privateKey) throws GeneralSecurityException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(X25519);
keyPairGenerator.initialize(new NamedParameterSpec(X25519), new StaticSecureRandom(getScalar(privateKey)));
return keyPairGenerator.generateKeyPair().getPublic();
}
Это не оченьэлегантное решение, но оно работает без каких-либо сторонних библиотек, и я не мог найти другого способа.