Curve25519 in library crypto

In one of my projects, I would need to generate a private/public key pair using curve25519 (RFC 7748). This one seems missing in library crypto (and openssl as well!)
So far I could generate a private key (easy!), but spent a lot of time trying to “decode/understand” procedural algorithms for deriving a public key.
Does anybody know if there is a prolog implementation of this?
Thanks

In doing some quick searching found Elliptic curves

HTH

Thanks for this. I visited that as well. This page is a rough overview of the “crypto-process”.
You also get “crypto_name_curve” which seems to be a wrapper around openssl (https://www.swi-prolog.org/pldoc/man?section=crypto-ec). But apparently, openssl does not implement EC curve25519.

From elliptic curves - curve25519 by openSSL - Cryptography Stack Exchange, I understand you needs at least OpenSSL 1.1.1. So, it depends on the OpenSSL lib SWI-Prolog is linked to, and that depends on how and where it was built.

I have:
openssl version
LibreSSL 2.8.3
Isn’t that better than 1.1.1?
BTW I am using SWI-Prolog (threaded, 64 bits, version 8.1.31) on a mac

I don’t know … If it doesn’t provide what you need and it is in OpenSSL 1.1.1, I’d say “no” :slight_smile:

When you say “linked” do you mean, link against openssl on my machine, or do you mean a library shipped with SWI-Prolog?

That depends. The Macport version is probably built with the Macport Open/Libre SSL library. The packaged binaries (MacOS bundles in a .dmg file available from the download page) used to link against the MacOS ssl library, but as Apple doesn’t maintain these the bundle now includes some version of OpenSSL. The current releases include OpenSSL 1.1.1f. To find out (this on my current Ubuntu 20.04):

101 ?- [library(ssl)].
true.

102 ?- current_prolog_flag(ssl_library_version, X).
X = 'OpenSSL 1.1.1f  31 Mar 2020'.

The Mac version produces the same output, i.e. uses the same version

?- current_prolog_flag(ssl_library_version, X).
X = ‘OpenSSL 1.1.1f 31 Mar 2020’.

However, I am looking into library crypto providing crypto_name_curve/2

?- [library(crypto)].
true.

?- crypto_name_curve(x25519, N).

ERROR: SSL(00000000) func(0): reason(0)
ERROR: In:
ERROR: [10] crypto:crypto_name_curve(x25519,_24070)
ERROR: [9]

?- crypto_name_curve(curve25519, N).

ERROR: SSL(00000000) func(0): reason(0)
ERROR: In:
ERROR: [10] crypto:crypto_name_curve(curve25519,_25328)
ERROR: [9] **

This also happens on my Linux box. If you want to puzzle, the source is in packages/ssl/crypto4pl.c, function pl_crypto_name_curve(), which calls EC_GROUP_new_by_curve_name().

I have now come a bit further with openssl:

openssl genpkey -algorithm x25519 > key.pem

-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIIi4uhhOCvU8v4Vi7+qORXuIUYlaz+nlPQs8ubkgwnpy
-----END PRIVATE KEY-----

openssl pkey -in key.pem -pubout

-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEACkVQ78NAnw4QtUeCJjROvObTuYP8CvuHxzWQP8GsmVc=
-----END PUBLIC KEY-----

This was on a Linux box with openssl version OpenSSL 1.1.1d 10 Sep 2019. On a mac (version LibreSSL 2.8.3) algorithm x25519 is not implemented!

Back to prolog is the question, if openssl’s genpkey and pkey subcommands have been made available in library crypto, which does not seem to be the case.
I’d then suggest 2 new predicates in library crypto, eg.

crypto_make_privkey(+Algorithm, -PrivateKey, Options), and
crypto_make_pubkey(+PrivateKey, -PublicKey

I’m not much of an SSL expert. You could raise this as an issue on the packages-ssl git. I think Markus Triska listens there and may comment. It does make sense to me (except that I’d vote to remove the make_). So, please check the repo and depending on response make a PR.

Issue raised in packages-ssl: https://github.com/SWI-Prolog/packages-ssl/issues/156

1 Like