Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement openssl's GENPKEY and PKEY subcommands in library crypto #156

Open
remys opened this issue Jun 26, 2020 · 5 comments
Open

implement openssl's GENPKEY and PKEY subcommands in library crypto #156

remys opened this issue Jun 26, 2020 · 5 comments

Comments

@remys
Copy link

remys commented Jun 26, 2020

openssl provides 2 subcommands GENPKEY and PKEY which can be used to generate a private and public key pair, eg. using algorithm x25519
e.g.

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

library crypto does currently not provide any predicates for private/public key generation.
I'd then suggest to add 2 new predicates in library crypto
e.g

%% crypto_private_key(+Algo, -PrivateKey, +Options) is nondet
% where PrivateKey is a random private key generated by openssl using algorithm Algo
% generates an infinite number of keys on backtracking

and
%% crypto_public_key(-PrivateKey, +PublicKey, +Options) is det
% where PublicKey is the public key associated with PrivateKey

For reference, see discussion in Curve25519 in library crypto

@JanWielemaker
Copy link
Member

This issue has been mentioned on SWI-Prolog. There might be relevant details there:

https://swi-prolog.discourse.group/t/curve25519-in-library-crypto/2564/13

@erlanger
Copy link

erlanger commented Jun 26, 2020

Support for curve 25519 was also mentioned here:

SWI-Prolog/swipl-devel#514

@erlanger
Copy link

%% crypto_private_key(+Algo, -PrivateKey, +Options) is nondet
% where PrivateKey is a random private key generated by openssl using algorithm Algo
% generates an infinite number of keys on backtracking

and
%% crypto_public_key(-PrivateKey, +PublicKey, +Options) is det
% where PublicKey is the public key associated with PrivateKey

@triska , what do you think about this API? Does it seem reasonable to you?

@triska
Copy link
Member

triska commented Jan 31, 2021

No, this API does not seem good to me, for three reasons:

First, it depends on the OpenSSL-specific idiosyncrasy of making a private key also "contain" the public key, or at least assuming that the public key can always be derived from the private key alone. I think this is not a particularly sensible way to look at the situation.

Second, personally, I do not like exposing too many different algorithms, using an Algorithm parameter. I understand that it is tempting to try to expose, on the Prolog level, whatever OpenSSL provides. However, the reality of the situation is that of all the things OpenSSL provides, only a very tiny subset is completely safe to use from a cryptographic and implementational perspective. For this reason, I rather have a single set of predicates dealing specifically with Curve25519, because this is an algorithm that is comparatively easy to implement safely and reliably, and has many desirable cryptographic properties. It should be used while others should be avoided and ideally not be exposed at all.

Third, for Curve25519, this API is not as useful and general as possible as can be had with two predicates. For example, in Scryer Prolog, I have implemented key exchange with Curve25519 by providing two predicates that in total expose more functionality. One, curve25519_generator/1, is implemented entirely in Prolog as follows:

curve25519_generator(Gs) :-
        length(Gs0, 32),
        Gs0 = [9|Zs],
        maplist(=(0), Zs),
        maplist(char_code, Gs, Gs0).

The other, curve25519_scalar_mult/3, computes a scalar multiplication of a point on the curve. This can be combined with the already available predicate crypto_n_random_bytes/2, yielding a private key.

@erlanger
Copy link

erlanger commented Feb 1, 2021

For example, in Scryer Prolog, I have implemented key exchange with Curve25519 by providing two predicates that in total expose more functionality.

I see, do you plan to add this to SWI-Prolog's package?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants