Browse Source

Merge pull request #490 from libtom/improve/curve25519

Improve curve25519
Steffen Jaeckel 6 years ago
parent
commit
c23f4699fb

+ 207 - 1
doc/crypt.tex

@@ -4998,7 +4998,7 @@ done2:
 When the above code snippet is done (assuming all went well) there will be a shared 128-bit key in the ``key'' array
 passed to ``establish\_secure\_socket()''.
 
-\chapter{Elliptic Curve Cryptography}
+\chapter{Elliptic Curve Cryptography - $GF(p)$}
 
 \mysection{Introduction}
 
@@ -5715,6 +5715,212 @@ ECCEncrypt ::= SEQUENCE {
 }
 \end{verbatim}
 
+\chapter{Elliptic Curve Cryptography - $Montgomery/Twisted Edwards$}
+\mysection{Introduction}
+
+The library provides functionality for \textit{Curve25519}-based \textit{X25519} Diffie-Hellman shared secrets
+and \textit{EdDSA} a.k.a \textit{Ed25519} signature schemes.
+
+The implementation is based on the \textit{tweetnacl}\footnote{\url{https://tweetnacl.cr.yp.to/}} reference implementation
+as provided by Daniel J. Bernstein et.al. and only slightly modified to better fit in the library.
+
+Both algorithms share the key structure called \textit{curve25519\_key} which is used by all Curve25519 functions.
+
+As Curve25519 and Ed25519 are based on the same elliptic curve, but use different mathematics, the keys are not
+compatible to each other.
+
+It is possible to convert a Curve-Key to an Ed-Key and vice-versa, but this is not provided (yet).
+
+
+\mysection{Curve25519-based Diffie-Hellman Key Exchange - X25519}
+
+The library provides the Diffie-Hellman Key Exchange algorithm \textit{X25519} for curve25519 as specified in RFC 7748.
+
+\subsection{X25519 Key Operations}
+
+The \textit{X25519} algorithm API provides the following set of functions to create, import and export keys.
+
+\index{x25519\_make\_key}
+\begin{verbatim}
+int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
+\end{verbatim}
+
+To generate a fresh X25529 key, one can use \textit{x25519\_make\_key} which will create a private\&public key-pair.
+
+\index{x25519\_set\_key}
+\begin{verbatim}
+int x25519_set_key(const unsigned char *k,  unsigned long klen,
+                   const unsigned char *u,  unsigned long ulen,
+                        curve25519_key *key);
+\end{verbatim}
+
+To import a public or private key in raw format, one can use the function \textit{x25519\_set\_key}.
+In case both, the secret part \textit{k} and the public part \textit{u} are given, the operation validates that the given 
+public part fits to the secret part.
+
+\index{x25519\_import}
+\begin{verbatim}
+int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+The \textit{x25519\_import} function can be used to import a public key in DER-encoded \textit{SubjectPublicKeyInfo} format.
+
+\index{x25519\_import\_x509}
+\begin{verbatim}
+int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+To import a public key from a DER-encoded \textit{X.509} certificate, one can use the function \textit{x25519\_import\_x509}.
+
+\index{x25519\_import\_pkcs8}
+\begin{verbatim}
+int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                 const void *pwd, unsigned long pwdlen,
+                             curve25519_key *key);
+\end{verbatim}
+
+To import a private key in the \textit{OneAsymmetricKey} a.k.a \textit{PKCS \#8} format, either plain or PBES encrypted,
+one can use the function \textit{x25519\_import\_pkcs8}.
+
+\index{x25519\_export}
+\begin{verbatim}
+int x25519_export(       unsigned char *out, unsigned long *outlen,
+                                   int  which,
+                  const curve25519_key *key);
+\end{verbatim}
+
+To export a key, the function \textit{x25519\_export} is provided.
+
+It has support for the following output formats:
+
+\begin{figure}[H]
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline \textbf{which} & \textbf{output format} \\
+\hline PK\_PRIVATE & Raw \\
+\hline PK\_PRIVATE \& PK\_STD & PKCS \#8 \\
+\hline PK\_PUBLIC & Raw \\
+\hline PK\_PUBLIC \& PK\_STD & SubjectPublicKeyInfo \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Possible x25519\_export() output formats}
+\end{figure}
+
+\subsection{X25519 Cryptographic Operations}
+
+To construct a Diffie-Hellman shared secret with a private and a public X25519 key, use the following function:
+
+\index{x25519\_shared\_secret}
+\begin{verbatim}
+int x25519_shared_secret(const curve25519_key *private_key,
+                         const curve25519_key *public_key,
+                                unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+
+This will construct the shared secret between the private- and the public-key and store the result in \textit{out} of length \textit{outlen}.
+
+\mysection{Curve25519-based EdDSA Signature Scheme - Ed25519}
+
+The library provides the EdDSA algorithm for the edwards25519 curve in the PureEdDSA variant as specified in RFC 8032.
+
+\subsection{EdDSA Key Operations}
+
+The \textit{Ed25519} algorithm API provides the following set of functions to create, import and export keys.
+
+\index{ed25519\_make\_key}
+\begin{verbatim}
+int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
+\end{verbatim}
+
+To generate a fresh Ed25529 key, one can use \textit{ed25519\_make\_key} which will create a private\&public key-pair.
+
+\index{ed25519\_set\_key}
+\begin{verbatim}
+int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
+                    const unsigned char *pk, unsigned long pklen,
+                         curve25519_key *key);
+\end{verbatim}
+
+To import a public or private key in raw format, one can use the function \textit{ed25519\_set\_key}.
+In case both, the secret part \textit{sk} and the public part \textit{pk} are given, the operation validates that the given 
+public part fits to the secret part.
+
+\index{ed25519\_import}
+\begin{verbatim}
+int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+The \textit{ed25519\_import} function can be used to import a public key in DER-encoded \textit{SubjectPublicKeyInfo} format.
+
+\index{ed25519\_import\_x509}
+\begin{verbatim}
+int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+To import a public key from a DER-encoded \textit{X.509} certificate, one can use the function \textit{ed25519\_import\_x509}.
+
+\index{ed25519\_import\_pkcs8}
+\begin{verbatim}
+int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                  const void *pwd, unsigned long pwdlen,
+                              curve25519_key *key);
+\end{verbatim}
+
+To import a private key in the \textit{OneAsymmetricKey} a.k.a \textit{PKCS \#8} format, either plain or PBES encrypted,
+one can use the function \textit{ed25519\_import\_pkcs8}.
+
+\index{ed25519\_export}
+\begin{verbatim}
+int ed25519_export(       unsigned char *out, unsigned long *outlen,
+                                    int  which,
+                   const curve25519_key *key);
+\end{verbatim}
+
+To export a key, the function \textit{ed25519\_export} is provided.
+
+It has support for the following output formats:
+
+\begin{figure}[H]
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline \textbf{which} & \textbf{output format} \\
+\hline PK\_PRIVATE & Raw \\
+\hline PK\_PRIVATE \& PK\_STD & PKCS \#8 \\
+\hline PK\_PUBLIC & Raw \\
+\hline PK\_PUBLIC \& PK\_STD & SubjectPublicKeyInfo \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Possible ed25519\_export() output formats}
+\end{figure}
+
+\subsection{EdDSA Cryptographic Operations}
+
+To sign and/or verify a message use the following functions:
+
+\index{ed25519\_sign}
+\begin{verbatim}
+int ed25519_sign(const unsigned char  *msg, unsigned long msglen,
+                       unsigned char  *sig, unsigned long *siglen,
+                 const curve25519_key *private_key);
+\end{verbatim}
+
+This function will EdDSA sign the message stored in the array pointed to by \textit{msg} of length \textit{msglen} octets.  The signature
+will be stored in the array pointed to by \textit{sig} of length \textit{siglen} octets.
+
+\index{ed25519\_verify}
+\begin{verbatim}
+int ed25519_verify(const  unsigned char *msg, unsigned long msglen,
+                   const  unsigned char *sig, unsigned long siglen,
+                   int *stat, const curve25519_key *public_key);
+\end{verbatim}
+
+This function will verify the EdDSA signature in the array pointed to by \textit{sig} of length \textit{siglen} octets, against the message
+pointed to by the array \textit{msg} of length \textit{msglen}. It will store a non--zero value in \textit{stat} if the signature is valid.  Note:
+the function will not return an error if the signature is invalid. It will return an error, if the actual signature payload is an invalid format.
+
+
 \chapter{Digital Signature Algorithm}
 \mysection{Introduction}
 The Digital Signature Algorithm (or DSA) is a variant of the ElGamal Signature scheme which has been modified to

+ 17 - 1
libtomcrypt_VS2008.vcproj

@@ -2314,6 +2314,14 @@
 			<Filter
 				Name="ec25519"
 				>
+				<File
+					RelativePath="src\pk\ec25519\ec25519_export.c"
+					>
+				</File>
+				<File
+					RelativePath="src\pk\ec25519\ec25519_import_pkcs8.c"
+					>
+				</File>
 				<File
 					RelativePath="src\pk\ec25519\tweetnacl.c"
 					>
@@ -2486,6 +2494,10 @@
 					RelativePath="src\pk\ed25519\ed25519_import.c"
 					>
 				</File>
+				<File
+					RelativePath="src\pk\ed25519\ed25519_import_pkcs8.c"
+					>
+				</File>
 				<File
 					RelativePath="src\pk\ed25519\ed25519_import_x509.c"
 					>
@@ -2618,6 +2630,10 @@
 					RelativePath="src\pk\x25519\x25519_import.c"
 					>
 				</File>
+				<File
+					RelativePath="src\pk\x25519\x25519_import_pkcs8.c"
+					>
+				</File>
 				<File
 					RelativePath="src\pk\x25519\x25519_import_x509.c"
 					>
@@ -2627,7 +2643,7 @@
 					>
 				</File>
 				<File
-					RelativePath="src\pk\x25519\x25519_set_ku.c"
+					RelativePath="src\pk\x25519\x25519_set_key.c"
 					>
 				</File>
 				<File

+ 38 - 36
makefile.mingw

@@ -179,46 +179,48 @@ src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
-src/pk/dsa/dsa_verify_key.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
-src/pk/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o \
-src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o \
-src/pk/ecc/ecc_find_curve.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o \
-src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o \
-src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
-src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o \
-src/pk/ecc/ecc_set_key.o src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o \
-src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \
-src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
+src/pk/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_export.o src/pk/ec25519/ec25519_import_pkcs8.o \
+src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o src/pk/ecc/ecc_ansi_x963_export.o \
+src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o \
+src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o src/pk/ecc/ecc_find_curve.o \
+src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/pk/ecc/ecc_get_size.o \
+src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \
+src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_key.o \
+src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o src/pk/ecc/ecc_set_key.o \
+src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_export_point.o \
+src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
 src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \
 src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
 src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
 src/pk/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
-src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o \
-src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.o \
-src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
-src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
-src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o \
-src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o \
-src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o \
-src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \
-src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o src/pk/x25519/x25519_import.o \
-src/pk/x25519/x25519_import_x509.o src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_ku.o \
-src/pk/x25519/x25519_shared_secret.o src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o \
-src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \
-src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
-src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
-src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_x509.o \
+src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o \
+src/pk/ed25519/ed25519_verify.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
+src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
+src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \
+src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
+src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o \
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
+src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
+src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_x509.o \
+src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_key.o src/pk/x25519/x25519_shared_secret.o \
+src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
+src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o \
+src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o src/stream/chacha/chacha_ivctr32.o \
+src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \
+src/stream/chacha/chacha_memory.o src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o \
+src/stream/rabbit/rabbit.o src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o \
+src/stream/rc4/rc4_stream_memory.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 #List of test objects to compile
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \

+ 38 - 36
makefile.msvc

@@ -172,46 +172,48 @@ src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_exp
 src/pk/dsa/dsa_generate_key.obj src/pk/dsa/dsa_generate_pqg.obj src/pk/dsa/dsa_import.obj \
 src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_set.obj src/pk/dsa/dsa_set_pqg_dsaparam.obj \
 src/pk/dsa/dsa_shared_secret.obj src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj \
-src/pk/dsa/dsa_verify_key.obj src/pk/ec25519/tweetnacl.obj src/pk/ecc/ecc.obj \
-src/pk/ecc/ecc_ansi_x963_export.obj src/pk/ecc/ecc_ansi_x963_import.obj src/pk/ecc/ecc_decrypt_key.obj \
-src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_export_openssl.obj \
-src/pk/ecc/ecc_find_curve.obj src/pk/ecc/ecc_free.obj src/pk/ecc/ecc_get_key.obj src/pk/ecc/ecc_get_oid_str.obj \
-src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_import_openssl.obj \
-src/pk/ecc/ecc_import_pkcs8.obj src/pk/ecc/ecc_import_x509.obj src/pk/ecc/ecc_make_key.obj \
-src/pk/ecc/ecc_recover_key.obj src/pk/ecc/ecc_set_curve.obj src/pk/ecc/ecc_set_curve_internal.obj \
-src/pk/ecc/ecc_set_key.obj src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj \
-src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.obj \
-src/pk/ecc/ltc_ecc_export_point.obj src/pk/ecc/ltc_ecc_import_point.obj src/pk/ecc/ltc_ecc_is_point.obj \
+src/pk/dsa/dsa_verify_key.obj src/pk/ec25519/ec25519_export.obj src/pk/ec25519/ec25519_import_pkcs8.obj \
+src/pk/ec25519/tweetnacl.obj src/pk/ecc/ecc.obj src/pk/ecc/ecc_ansi_x963_export.obj \
+src/pk/ecc/ecc_ansi_x963_import.obj src/pk/ecc/ecc_decrypt_key.obj src/pk/ecc/ecc_encrypt_key.obj \
+src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_export_openssl.obj src/pk/ecc/ecc_find_curve.obj \
+src/pk/ecc/ecc_free.obj src/pk/ecc/ecc_get_key.obj src/pk/ecc/ecc_get_oid_str.obj src/pk/ecc/ecc_get_size.obj \
+src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_import_openssl.obj src/pk/ecc/ecc_import_pkcs8.obj \
+src/pk/ecc/ecc_import_x509.obj src/pk/ecc/ecc_make_key.obj src/pk/ecc/ecc_recover_key.obj \
+src/pk/ecc/ecc_set_curve.obj src/pk/ecc/ecc_set_curve_internal.obj src/pk/ecc/ecc_set_key.obj \
+src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ltc_ecc_export_point.obj \
+src/pk/ecc/ltc_ecc_import_point.obj src/pk/ecc/ltc_ecc_is_point.obj \
 src/pk/ecc/ltc_ecc_is_point_at_infinity.obj src/pk/ecc/ltc_ecc_map.obj src/pk/ecc/ltc_ecc_mul2add.obj \
 src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \
 src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \
 src/pk/ecc/ltc_ecc_verify_key.obj src/pk/ed25519/ed25519_export.obj src/pk/ed25519/ed25519_import.obj \
-src/pk/ed25519/ed25519_import_x509.obj src/pk/ed25519/ed25519_make_key.obj \
-src/pk/ed25519/ed25519_set_key.obj src/pk/ed25519/ed25519_sign.obj src/pk/ed25519/ed25519_verify.obj \
-src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj \
-src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj \
-src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v1_5_decode.obj src/pk/pkcs1/pkcs_1_v1_5_encode.obj \
-src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj src/pk/rsa/rsa_export.obj \
-src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_get_size.obj src/pk/rsa/rsa_import.obj \
-src/pk/rsa/rsa_import_pkcs8.obj src/pk/rsa/rsa_import_x509.obj src/pk/rsa/rsa_make_key.obj \
-src/pk/rsa/rsa_set.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_sign_saltlen_get.obj \
-src/pk/rsa/rsa_verify_hash.obj src/pk/x25519/x25519_export.obj src/pk/x25519/x25519_import.obj \
-src/pk/x25519/x25519_import_x509.obj src/pk/x25519/x25519_make_key.obj src/pk/x25519/x25519_set_ku.obj \
-src/pk/x25519/x25519_shared_secret.obj src/prngs/chacha20.obj src/prngs/fortuna.obj src/prngs/rc4.obj \
-src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj \
-src/prngs/yarrow.obj src/stream/chacha/chacha_crypt.obj src/stream/chacha/chacha_done.obj \
-src/stream/chacha/chacha_ivctr32.obj src/stream/chacha/chacha_ivctr64.obj \
-src/stream/chacha/chacha_keystream.obj src/stream/chacha/chacha_memory.obj \
-src/stream/chacha/chacha_setup.obj src/stream/chacha/chacha_test.obj src/stream/rabbit/rabbit.obj \
-src/stream/rabbit/rabbit_memory.obj src/stream/rc4/rc4_stream.obj src/stream/rc4/rc4_stream_memory.obj \
-src/stream/rc4/rc4_test.obj src/stream/salsa20/salsa20_crypt.obj src/stream/salsa20/salsa20_done.obj \
-src/stream/salsa20/salsa20_ivctr64.obj src/stream/salsa20/salsa20_keystream.obj \
-src/stream/salsa20/salsa20_memory.obj src/stream/salsa20/salsa20_setup.obj \
-src/stream/salsa20/salsa20_test.obj src/stream/salsa20/xsalsa20_memory.obj \
-src/stream/salsa20/xsalsa20_setup.obj src/stream/salsa20/xsalsa20_test.obj \
-src/stream/sober128/sober128_stream.obj src/stream/sober128/sober128_stream_memory.obj \
-src/stream/sober128/sober128_test.obj src/stream/sosemanuk/sosemanuk.obj \
-src/stream/sosemanuk/sosemanuk_memory.obj src/stream/sosemanuk/sosemanuk_test.obj
+src/pk/ed25519/ed25519_import_pkcs8.obj src/pk/ed25519/ed25519_import_x509.obj \
+src/pk/ed25519/ed25519_make_key.obj src/pk/ed25519/ed25519_set_key.obj src/pk/ed25519/ed25519_sign.obj \
+src/pk/ed25519/ed25519_verify.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \
+src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \
+src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v1_5_decode.obj \
+src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \
+src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_get_size.obj \
+src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_import_pkcs8.obj src/pk/rsa/rsa_import_x509.obj \
+src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_set.obj src/pk/rsa/rsa_sign_hash.obj \
+src/pk/rsa/rsa_sign_saltlen_get.obj src/pk/rsa/rsa_verify_hash.obj src/pk/x25519/x25519_export.obj \
+src/pk/x25519/x25519_import.obj src/pk/x25519/x25519_import_pkcs8.obj src/pk/x25519/x25519_import_x509.obj \
+src/pk/x25519/x25519_make_key.obj src/pk/x25519/x25519_set_key.obj src/pk/x25519/x25519_shared_secret.obj \
+src/prngs/chacha20.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \
+src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj \
+src/stream/chacha/chacha_crypt.obj src/stream/chacha/chacha_done.obj src/stream/chacha/chacha_ivctr32.obj \
+src/stream/chacha/chacha_ivctr64.obj src/stream/chacha/chacha_keystream.obj \
+src/stream/chacha/chacha_memory.obj src/stream/chacha/chacha_setup.obj src/stream/chacha/chacha_test.obj \
+src/stream/rabbit/rabbit.obj src/stream/rabbit/rabbit_memory.obj src/stream/rc4/rc4_stream.obj \
+src/stream/rc4/rc4_stream_memory.obj src/stream/rc4/rc4_test.obj src/stream/salsa20/salsa20_crypt.obj \
+src/stream/salsa20/salsa20_done.obj src/stream/salsa20/salsa20_ivctr64.obj \
+src/stream/salsa20/salsa20_keystream.obj src/stream/salsa20/salsa20_memory.obj \
+src/stream/salsa20/salsa20_setup.obj src/stream/salsa20/salsa20_test.obj \
+src/stream/salsa20/xsalsa20_memory.obj src/stream/salsa20/xsalsa20_setup.obj \
+src/stream/salsa20/xsalsa20_test.obj src/stream/sober128/sober128_stream.obj \
+src/stream/sober128/sober128_stream_memory.obj src/stream/sober128/sober128_test.obj \
+src/stream/sosemanuk/sosemanuk.obj src/stream/sosemanuk/sosemanuk_memory.obj \
+src/stream/sosemanuk/sosemanuk_test.obj
 
 #List of test objects to compile
 TOBJECTS=tests/base16_test.obj tests/base32_test.obj tests/base64_test.obj tests/cipher_hash_test.obj \

+ 38 - 36
makefile.unix

@@ -189,46 +189,48 @@ src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
-src/pk/dsa/dsa_verify_key.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
-src/pk/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o \
-src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o \
-src/pk/ecc/ecc_find_curve.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o \
-src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o \
-src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
-src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o \
-src/pk/ecc/ecc_set_key.o src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o \
-src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \
-src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
+src/pk/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_export.o src/pk/ec25519/ec25519_import_pkcs8.o \
+src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o src/pk/ecc/ecc_ansi_x963_export.o \
+src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o \
+src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o src/pk/ecc/ecc_find_curve.o \
+src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/pk/ecc/ecc_get_size.o \
+src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \
+src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_key.o \
+src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o src/pk/ecc/ecc_set_key.o \
+src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_export_point.o \
+src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
 src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \
 src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
 src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
 src/pk/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
-src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o \
-src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.o \
-src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
-src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
-src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o \
-src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o \
-src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o \
-src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \
-src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o src/pk/x25519/x25519_import.o \
-src/pk/x25519/x25519_import_x509.o src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_ku.o \
-src/pk/x25519/x25519_shared_secret.o src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o \
-src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \
-src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
-src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
-src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_x509.o \
+src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o \
+src/pk/ed25519/ed25519_verify.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
+src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
+src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \
+src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
+src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o \
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
+src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
+src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_x509.o \
+src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_key.o src/pk/x25519/x25519_shared_secret.o \
+src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
+src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o \
+src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o src/stream/chacha/chacha_ivctr32.o \
+src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \
+src/stream/chacha/chacha_memory.o src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o \
+src/stream/rabbit/rabbit.o src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o \
+src/stream/rc4/rc4_stream_memory.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 #List of test objects to compile (all goes to libtomcrypt_prof.a)
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \

+ 38 - 36
makefile_include.mk

@@ -349,46 +349,48 @@ src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
-src/pk/dsa/dsa_verify_key.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
-src/pk/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o \
-src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o \
-src/pk/ecc/ecc_find_curve.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o \
-src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o \
-src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
-src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o \
-src/pk/ecc/ecc_set_key.o src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o \
-src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \
-src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
+src/pk/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_export.o src/pk/ec25519/ec25519_import_pkcs8.o \
+src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o src/pk/ecc/ecc_ansi_x963_export.o \
+src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o \
+src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o src/pk/ecc/ecc_find_curve.o \
+src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/pk/ecc/ecc_get_size.o \
+src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \
+src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_key.o \
+src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o src/pk/ecc/ecc_set_key.o \
+src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_export_point.o \
+src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
 src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \
 src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
 src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
 src/pk/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
-src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o \
-src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.o \
-src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
-src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
-src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o \
-src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o \
-src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o \
-src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \
-src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o src/pk/x25519/x25519_import.o \
-src/pk/x25519/x25519_import_x509.o src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_ku.o \
-src/pk/x25519/x25519_shared_secret.o src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o \
-src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \
-src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
-src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
-src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_x509.o \
+src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o \
+src/pk/ed25519/ed25519_verify.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
+src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
+src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \
+src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
+src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o \
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
+src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
+src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_x509.o \
+src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_key.o src/pk/x25519/x25519_shared_secret.o \
+src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
+src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o \
+src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o src/stream/chacha/chacha_ivctr32.o \
+src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \
+src/stream/chacha/chacha_memory.o src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o \
+src/stream/rabbit/rabbit.o src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o \
+src/stream/rc4/rc4_stream_memory.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 # List of test objects to compile (all goes to libtomcrypt_prof.a)
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \

+ 16 - 12
src/headers/tomcrypt_pk.h

@@ -346,20 +346,22 @@ typedef struct {
 } curve25519_key;
 
 
-/* Ed25519 Signature API */
+/** Ed25519 Signature API */
 int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
 
+int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
+                    const unsigned char *pk, unsigned long pklen,
+                         curve25519_key *key);
+
 int ed25519_export(       unsigned char *out, unsigned long *outlen,
                                     int  which,
                    const curve25519_key *key);
 
 int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
 int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
-int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
-                    const unsigned char *pk, unsigned long pklen,
-                         curve25519_key *key);
+int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                  const void *pwd, unsigned long pwdlen,
+                              curve25519_key *key);
 
 int ed25519_sign(const unsigned char  *msg, unsigned long msglen,
                        unsigned char  *sig, unsigned long *siglen,
@@ -369,20 +371,22 @@ int ed25519_verify(const  unsigned char *msg, unsigned long msglen,
                    const  unsigned char *sig, unsigned long siglen,
                    int *stat, const curve25519_key *public_key);
 
-/* X25519 Key-Exchange API */
+/** X25519 Key-Exchange API */
 int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
 
+int x25519_set_key(const unsigned char *k,  unsigned long klen,
+                   const unsigned char *u,  unsigned long ulen,
+                        curve25519_key *key);
+
 int x25519_export(       unsigned char *out, unsigned long *outlen,
                                    int  which,
                   const curve25519_key *key);
 
 int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
 int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
-int x25519_set_ku(const unsigned char *k,  unsigned long klen,
-                  const unsigned char *u,  unsigned long ulen,
-                       curve25519_key *key);
+int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                 const void *pwd, unsigned long pwdlen,
+                             curve25519_key *key);
 
 int x25519_shared_secret(const curve25519_key *private_key,
                          const curve25519_key *public_key,

+ 16 - 7
src/headers/tomcrypt_private.h

@@ -302,19 +302,28 @@ int dsa_int_validate_primes(const dsa_key *key, int *stat);
 
 #ifdef LTC_CURVE25519
 
-int crypto_sign(
+int tweetnacl_crypto_sign(
   unsigned char *sm,unsigned long long *smlen,
   const unsigned char *m,unsigned long long mlen,
   const unsigned char *sk, const unsigned char *pk);
-int crypto_sign_open(
+int tweetnacl_crypto_sign_open(
+  int *stat,
   unsigned char *m,unsigned long long *mlen,
   const unsigned char *sm,unsigned long long smlen,
   const unsigned char *pk);
-int crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
-int crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
-int crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
-int crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
-
+int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
+int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
+int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
+int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
+
+typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
+int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                       const void *pwd, unsigned long pwdlen,
+                       enum ltc_oid_id id, sk_to_pk fp,
+                       curve25519_key *key);
+int ec25519_export(       unsigned char *out, unsigned long *outlen,
+                                    int  which,
+                   const curve25519_key *key);
 #endif /* LTC_CURVE25519 */
 
 #ifdef LTC_DER

+ 100 - 0
src/pk/ec25519/ec25519_export.c

@@ -0,0 +1,100 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file ec25519_export.c
+  Generic export of a Curve/Ed25519 key to a binary packet, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+   Generic export of a Curve/Ed25519 key to a binary packet
+   @param out    [out] The destination for the key
+   @param outlen [in/out] The max size and resulting size of the Ed25519 key
+   @param type   Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
+   @param key    The key you wish to export
+   @return CRYPT_OK if successful
+*/
+int ec25519_export(       unsigned char *out, unsigned long *outlen,
+                                    int  which,
+                   const curve25519_key *key)
+{
+   int err, std;
+   const char* OID;
+   unsigned long oid[16], oidlen;
+   ltc_asn1_list alg_id[1];
+   unsigned char private_key[34];
+   unsigned long version, private_key_len = sizeof(private_key);
+
+   LTC_ARGCHK(out       != NULL);
+   LTC_ARGCHK(outlen    != NULL);
+   LTC_ARGCHK(key       != NULL);
+
+   std = which & PK_STD;
+   which &= ~PK_STD;
+
+   if (which == PK_PRIVATE) {
+      if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
+
+      if (std == PK_STD) {
+         if ((err = pk_get_oid(key->algo, &OID)) != CRYPT_OK) {
+            return err;
+         }
+         oidlen = sizeof(oid)/sizeof(oid[0]);
+         if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
+            return err;
+         }
+
+         LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
+
+         /* encode private key as PKCS#8 */
+         if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
+            return err;
+         }
+
+         version = 0;
+         err = der_encode_sequence_multi(out, outlen,
+                                   LTC_ASN1_SHORT_INTEGER,            1uL, &version,
+                                   LTC_ASN1_SEQUENCE,                 1uL, alg_id,
+                                   LTC_ASN1_OCTET_STRING, private_key_len, private_key,
+                                   LTC_ASN1_EOL,                      0uL, NULL);
+      } else {
+         if (*outlen < sizeof(key->priv)) {
+            err = CRYPT_BUFFER_OVERFLOW;
+         } else {
+            XMEMCPY(out, key->priv, sizeof(key->priv));
+            err = CRYPT_OK;
+         }
+         *outlen = sizeof(key->priv);
+      }
+   } else {
+      if (std == PK_STD) {
+         /* encode public key as SubjectPublicKeyInfo */
+         err = x509_encode_subject_public_key_info(out, outlen, key->algo, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0);
+      } else {
+         if (*outlen < sizeof(key->pub)) {
+            err = CRYPT_BUFFER_OVERFLOW;
+         } else {
+            XMEMCPY(out, key->pub, sizeof(key->pub));
+            err = CRYPT_OK;
+         }
+         *outlen = sizeof(key->pub);
+      }
+   }
+
+   return err;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 97 - 0
src/pk/ec25519/ec25519_import_pkcs8.c

@@ -0,0 +1,97 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file ec25519_import_pkcs8.c
+  Generic import of a Curve/Ed25519 private key in PKCS#8 format, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+  Generic import of a Curve/Ed25519 private key in PKCS#8 format
+  @param in        The DER-encoded PKCS#8-formatted private key
+  @param inlen     The length of the input data
+  @param passwd    The password to decrypt the private key
+  @param passwdlen Password's length (octets)
+  @param key       [out] Where to import the key to
+  @return CRYPT_OK if successful, on error all allocated memory is freed automatically
+*/
+int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                       const void *pwd, unsigned long pwdlen,
+                       enum ltc_oid_id id, sk_to_pk fp,
+                       curve25519_key *key)
+{
+   int err = CRYPT_INVALID_ARG;
+   ltc_asn1_list *l = NULL;
+   const char *oid;
+   ltc_asn1_list alg_id[1];
+   unsigned char private_key[34];
+   unsigned long version, key_len;
+   unsigned long tmpoid[16];
+
+   LTC_ARGCHK(in  != NULL);
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(fp != NULL);
+
+   if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) {
+
+      LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid) / sizeof(tmpoid[0]));
+
+      key_len = sizeof(private_key);
+      if ((err = der_decode_sequence_multi(l->data, l->size,
+                                           LTC_ASN1_SHORT_INTEGER,      1uL, &version,
+                                           LTC_ASN1_SEQUENCE,           1uL, alg_id,
+                                           LTC_ASN1_OCTET_STRING,   key_len, private_key,
+                                           LTC_ASN1_EOL,                0uL, NULL))
+          != CRYPT_OK) {
+         /* If there are attributes added after the private_key it is tagged with version 1 and
+          * we get an 'input too long' error but the rest is already decoded and can be
+          * handled the same as for version 0
+          */
+         if ((err == CRYPT_INPUT_TOO_LONG) && (version == 1)) {
+            version = 0;
+         } else {
+            goto out;
+         }
+      }
+
+      if ((err = pk_get_oid(id, &oid)) != CRYPT_OK) {
+         goto out;
+      }
+      if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
+         goto out;
+      }
+
+      if (version == 0) {
+         key_len = sizeof(key->priv);
+         if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
+            fp(key->pub, key->priv);
+            key->type = PK_PRIVATE;
+            key->algo = id;
+         }
+      } else {
+         err = CRYPT_PK_INVALID_TYPE;
+      }
+   }
+out:
+   if (l) der_free_sequence_flexi(l);
+#ifdef LTC_CLEAN_STACK
+   zeromem(private_key, sizeof(private_key));
+#endif
+
+   return err;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 30 - 149
src/pk/ec25519/tweetnacl.c

@@ -31,22 +31,6 @@ static const gf
   Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
   I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
 
-static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
-
-static u32 ld32(const u8 *x)
-{
-  u32 u = x[3];
-  u = (u<<8)|x[2];
-  u = (u<<8)|x[1];
-  return (u<<8)|x[0];
-}
-
-sv st32(u8 *x,u32 u)
-{
-  int i;
-  FOR(i,4) { x[i] = u; u >>= 8; }
-}
-
 static int vn(const u8 *x,const u8 *y,int n)
 {
   int i;
@@ -55,116 +39,11 @@ static int vn(const u8 *x,const u8 *y,int n)
   return (1 & ((d - 1) >> 8)) - 1;
 }
 
-int crypto_verify_16(const u8 *x,const u8 *y)
-{
-  return vn(x,y,16);
-}
-
-int crypto_verify_32(const u8 *x,const u8 *y)
+static int tweetnacl_crypto_verify_32(const u8 *x,const u8 *y)
 {
   return vn(x,y,32);
 }
 
-sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
-{
-  u32 w[16],x[16],y[16],t[4];
-  int i,j,m;
-
-  FOR(i,4) {
-    x[5*i] = ld32(c+4*i);
-    x[1+i] = ld32(k+4*i);
-    x[6+i] = ld32(in+4*i);
-    x[11+i] = ld32(k+16+4*i);
-  }
-
-  FOR(i,16) y[i] = x[i];
-
-  FOR(i,20) {
-    FOR(j,4) {
-      FOR(m,4) t[m] = x[(5*j+4*m)%16];
-      t[1] ^= L32(t[0]+t[3], 7);
-      t[2] ^= L32(t[1]+t[0], 9);
-      t[3] ^= L32(t[2]+t[1],13);
-      t[0] ^= L32(t[3]+t[2],18);
-      FOR(m,4) w[4*j+(j+m)%4] = t[m];
-    }
-    FOR(m,16) x[m] = w[m];
-  }
-
-  if (h) {
-    FOR(i,16) x[i] += y[i];
-    FOR(i,4) {
-      x[5*i] -= ld32(c+4*i);
-      x[6+i] -= ld32(in+4*i);
-    }
-    FOR(i,4) {
-      st32(out+4*i,x[5*i]);
-      st32(out+16+4*i,x[6+i]);
-    }
-  } else
-    FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
-}
-
-int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
-{
-  core(out,in,k,c,0);
-  return 0;
-}
-
-int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
-{
-  core(out,in,k,c,1);
-  return 0;
-}
-
-static const u8 sigma[16] = "expand 32-byte k";
-
-int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
-{
-  u8 z[16],x[64];
-  u32 u,i;
-  if (!b) return 0;
-  FOR(i,16) z[i] = 0;
-  FOR(i,8) z[i] = n[i];
-  while (b >= 64) {
-    crypto_core_salsa20(x,z,k,sigma);
-    FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
-    u = 1;
-    for (i = 8;i < 16;++i) {
-      u += (u32) z[i];
-      z[i] = u;
-      u >>= 8;
-    }
-    b -= 64;
-    c += 64;
-    if (m) m += 64;
-  }
-  if (b) {
-    crypto_core_salsa20(x,z,k,sigma);
-    FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
-  }
-  return 0;
-}
-
-int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
-{
-  return crypto_stream_salsa20_xor(c,0,d,n,k);
-}
-
-int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
-{
-  u8 s[32];
-  crypto_core_hsalsa20(s,n,k,sigma);
-  return crypto_stream_salsa20(c,d,n+16,s);
-}
-
-int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
-{
-  u8 s[32];
-  crypto_core_hsalsa20(s,n,k,sigma);
-  return crypto_stream_salsa20_xor(c,m,d,n+16,s);
-}
-
 sv set25519(gf r, const gf a)
 {
   int i;
@@ -223,7 +102,7 @@ static int neq25519(const gf a, const gf b)
   u8 c[32],d[32];
   pack25519(c,a);
   pack25519(d,b);
-  return crypto_verify_32(c,d);
+  return tweetnacl_crypto_verify_32(c,d);
 }
 
 static u8 par25519(const gf a)
@@ -292,7 +171,7 @@ sv pow2523(gf o,const gf i)
   FOR(a,16) o[a]=c[a];
 }
 
-int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
+int tweetnacl_crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
 {
   u8 z[32];
   i64 x[80],r,i;
@@ -343,12 +222,12 @@ int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
   return 0;
 }
 
-int crypto_scalarmult_base(u8 *q,const u8 *n)
+int tweetnacl_crypto_scalarmult_base(u8 *q,const u8 *n)
 {
-  return crypto_scalarmult(q,n,_9);
+  return tweetnacl_crypto_scalarmult(q,n,_9);
 }
 
-static int crypto_hash(u8 *out,const u8 *m,u64 n)
+static int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
 {
   unsigned long len;
   int err, hash_idx;
@@ -430,11 +309,11 @@ sv scalarbase(gf p[4],const u8 *s)
   scalarmult(p,q,s);
 }
 
-int crypto_sk_to_pk(u8 *pk, const u8 *sk)
+int tweetnacl_crypto_sk_to_pk(u8 *pk, const u8 *sk)
 {
   u8 d[64];
   gf p[4];
-  crypto_hash(d, sk, 32);
+  tweetnacl_crypto_hash(d, sk, 32);
   d[0] &= 248;
   d[31] &= 127;
   d[31] |= 64;
@@ -445,7 +324,7 @@ int crypto_sk_to_pk(u8 *pk, const u8 *sk)
   return 0;
 }
 
-int crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk)
+int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk)
 {
   int err;
 
@@ -458,7 +337,7 @@ int crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk)
      return CRYPT_ERROR_READPRNG;
   }
 
-  if ((err = crypto_sk_to_pk(pk, sk)) != CRYPT_OK) {
+  if ((err = tweetnacl_crypto_sk_to_pk(pk, sk)) != CRYPT_OK) {
      return err;
   }
 
@@ -503,28 +382,28 @@ sv reduce(u8 *r)
   modL(r,x);
 }
 
-int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk,const u8 *pk)
+int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk)
 {
   u8 d[64],h[64],r[64];
   i64 i,j,x[64];
   gf p[4];
 
-  crypto_hash(d, sk, 32);
+  tweetnacl_crypto_hash(d, sk, 32);
   d[0] &= 248;
   d[31] &= 127;
   d[31] |= 64;
 
-  *smlen = n+64;
-  FOR(i,(i64)n) sm[64 + i] = m[i];
+  *smlen = mlen+64;
+  FOR(i,(i64)mlen) sm[64 + i] = m[i];
   FOR(i,32) sm[32 + i] = d[32 + i];
 
-  crypto_hash(r, sm+32, n+32);
+  tweetnacl_crypto_hash(r, sm+32, mlen+32);
   reduce(r);
   scalarbase(p,r);
   pack(sm,p);
 
   FOR(i,32) sm[i+32] = pk[i];
-  crypto_hash(h,sm,n + 64);
+  tweetnacl_crypto_hash(h,sm,mlen + 64);
   reduce(h);
 
   FOR(i,64) x[i] = 0;
@@ -571,22 +450,23 @@ static int unpackneg(gf r[4],const u8 p[32])
   return 0;
 }
 
-int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
+int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *pk)
 {
   u64 i;
   u8 s[32],t[32],h[64];
   gf p[4],q[4];
 
-  if (*mlen < n) return CRYPT_BUFFER_OVERFLOW;
+  *stat = 0;
+  if (*mlen < smlen) return CRYPT_BUFFER_OVERFLOW;
   *mlen = -1;
-  if (n < 64) return CRYPT_INVALID_ARG;
+  if (smlen < 64) return CRYPT_INVALID_ARG;
 
   if (unpackneg(q,pk)) return CRYPT_ERROR;
 
-  XMEMMOVE(m,sm,n);
+  XMEMMOVE(m,sm,smlen);
   XMEMMOVE(s,m + 32,32);
   XMEMMOVE(m + 32,pk,32);
-  crypto_hash(h,m,n);
+  tweetnacl_crypto_hash(h,m,smlen);
   reduce(h);
   scalarmult(p,q,h);
 
@@ -594,15 +474,16 @@ int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
   add(p,q);
   pack(t,p);
 
-  n -= 64;
-  if (crypto_verify_32(sm, t)) {
-    FOR(i,n) m[i] = 0;
-    zeromem(m, n);
-    return CRYPT_INVALID_PACKET;
+  smlen -= 64;
+  if (tweetnacl_crypto_verify_32(sm, t)) {
+    FOR(i,smlen) m[i] = 0;
+    zeromem(m, smlen);
+    return CRYPT_OK;
   }
 
-  XMEMMOVE(m,m + 64,n);
-  *mlen = n;
+  *stat = 1;
+  XMEMMOVE(m,m + 64,smlen);
+  *mlen = smlen;
   return CRYPT_OK;
 }
 

+ 4 - 55
src/pk/ed25519/ed25519_export.c

@@ -10,13 +10,13 @@
 
 /**
   @file ed25519_export.c
-  Export a Ed25519 key to a binary packet, Steffen Jaeckel
+  Export an Ed25519 key to a binary packet, Steffen Jaeckel
 */
 
 #ifdef LTC_CURVE25519
 
 /**
-   Export a Ed25519 key to a binary packet
+   Export an Ed25519 key to a binary packet
    @param out    [out] The destination for the key
    @param outlen [in/out] The max size and resulting size of the Ed25519 key
    @param type   Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
@@ -27,62 +27,11 @@ int ed25519_export(       unsigned char *out, unsigned long *outlen,
                                     int  which,
                    const curve25519_key *key)
 {
-   int err, std;
-   const char* OID;
-   unsigned long oid[16], oidlen;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, private_key_len = sizeof(private_key);
-
-   LTC_ARGCHK(out       != NULL);
-   LTC_ARGCHK(outlen    != NULL);
-   LTC_ARGCHK(key       != NULL);
+   LTC_ARGCHK(key != NULL);
 
    if (key->algo != PKA_ED25519) return CRYPT_PK_INVALID_TYPE;
 
-   std = which & PK_STD;
-   which &= ~PK_STD;
-
-   if (which == PK_PRIVATE) {
-      if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
-
-      if ((err = pk_get_oid(PKA_ED25519, &OID)) != CRYPT_OK) {
-         return err;
-      }
-      oidlen = sizeof(oid)/sizeof(oid[0]);
-      if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
-         return err;
-      }
-
-      LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
-
-      /* encode private key as PKCS#8 */
-      if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
-         return err;
-      }
-
-      version = 0;
-      err = der_encode_sequence_multi(out, outlen,
-                                LTC_ASN1_SHORT_INTEGER,            1uL, &version,
-                                LTC_ASN1_SEQUENCE,                 1uL, alg_id,
-                                LTC_ASN1_OCTET_STRING, private_key_len, private_key,
-                                LTC_ASN1_EOL,                      0uL, NULL);
-   } else {
-      if (std == PK_STD) {
-         /* encode public key as SubjectPublicKeyInfo */
-         err = x509_encode_subject_public_key_info(out, outlen, PKA_ED25519, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0);
-      } else {
-         if (*outlen < sizeof(key->pub)) {
-            err = CRYPT_BUFFER_OVERFLOW;
-         } else {
-            XMEMCPY(out, key->pub, sizeof(key->pub));
-            err = CRYPT_OK;
-         }
-         *outlen = sizeof(key->pub);
-      }
-   }
-
-   return err;
+   return ec25519_export(out, outlen, which, key);
 }
 
 #endif

+ 2 - 57
src/pk/ed25519/ed25519_import.c

@@ -16,7 +16,7 @@
 #ifdef LTC_CURVE25519
 
 /**
-  Import a Ed25519 key from a binary packet
+  Import an Ed25519 public key
   @param in     The packet to read
   @param inlen  The length of the input packet
   @param key    [out] Where to import the key to
@@ -25,71 +25,16 @@
 int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
 {
    int err;
-   const char* oid;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, key_len;
-   unsigned long tmpoid[16];
+   unsigned long key_len;
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
 
-   /* There's only one case where the inlen is equal to the pubkey-size
-    * and that's a raw pubkey, so let's just do a raw import.
-    */
-   if (inlen == sizeof(key->pub)) {
-      XMEMCPY(key->pub, in, sizeof(key->pub));
-      key->type = PK_PUBLIC;
-      key->algo = PKA_ED25519;
-      return CRYPT_OK;
-   }
-
    key_len = sizeof(key->pub);
    if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_ED25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
       key->type = PK_PUBLIC;
       key->algo = PKA_ED25519;
-      return CRYPT_OK;
    }
-
-   LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
-
-   key_len = sizeof(private_key);
-   err = der_decode_sequence_multi(in, inlen,
-                                LTC_ASN1_SHORT_INTEGER,    1uL, &version,
-                                LTC_ASN1_SEQUENCE,         1uL, alg_id,
-                                LTC_ASN1_OCTET_STRING, key_len, private_key,
-                                LTC_ASN1_EOL,              0uL, NULL);
-   if (err != CRYPT_OK) {
-      if ((err == CRYPT_INPUT_TOO_LONG) && (version == 1)) {
-         version = 0;
-      } else {
-         goto out;
-      }
-   }
-
-   if ((err = pk_get_oid(PKA_ED25519, &oid)) != CRYPT_OK) {
-      goto out;
-   }
-   if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
-      goto out;
-   }
-
-   if (version == 0) {
-      key_len = sizeof(key->priv);
-      if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
-         crypto_sk_to_pk(key->pub, key->priv);
-         key->type = PK_PRIVATE;
-         key->algo = PKA_ED25519;
-      }
-   } else {
-      err = CRYPT_PK_INVALID_TYPE;
-   }
-
-out:
-#ifdef LTC_CLEAN_STACK
-   zeromem(private_key, sizeof(private_key));
-#endif
-
    return err;
 }
 

+ 38 - 0
src/pk/ed25519/ed25519_import_pkcs8.c

@@ -0,0 +1,38 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file ed25519_import_pkcs8.c
+  Import an Ed25519 key in PKCS#8 format, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+  Import an Ed25519 private key in PKCS#8 format
+  @param in        The DER-encoded PKCS#8-formatted private key
+  @param inlen     The length of the input data
+  @param passwd    The password to decrypt the private key
+  @param passwdlen Password's length (octets)
+  @param key       [out] Where to import the key to
+  @return CRYPT_OK if successful, on error all allocated memory is freed automatically
+*/
+int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                  const void *pwd, unsigned long pwdlen,
+                              curve25519_key *key)
+{
+   return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_ED25519, tweetnacl_crypto_sk_to_pk, key);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 2 - 2
src/pk/ed25519/ed25519_import_x509.c

@@ -10,7 +10,7 @@
 
 /**
   @file ed25519_import_x509.c
-  Import a Ed25519 key from a X.509 certificate, Steffen Jaeckel
+  Import an Ed25519 key from a X.509 certificate, Steffen Jaeckel
 */
 
 #ifdef LTC_CURVE25519
@@ -23,7 +23,7 @@ static int _ed25519_decode(const unsigned char *in, unsigned long inlen, curve25
 }
 
 /**
-  Import a Ed25519 public key from a X.509 certificate
+  Import an Ed25519 public key from a X.509 certificate
   @param in     The DER encoded X.509 certificate
   @param inlen  The length of the certificate
   @param key    [out] Where to import the key to

+ 3 - 3
src/pk/ed25519/ed25519_make_key.c

@@ -10,13 +10,13 @@
 
 /**
   @file ed25519_make_key.c
-  Create a Ed25519 key, Steffen Jaeckel
+  Create an Ed25519 key, Steffen Jaeckel
 */
 
 #ifdef LTC_CURVE25519
 
 /**
-   Create a Ed25519 key
+   Create an Ed25519 key
    @param prng     An active PRNG state
    @param wprng    The index of the PRNG desired
    @param key      [out] Destination of a newly created private key pair
@@ -29,7 +29,7 @@ int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key)
    LTC_ARGCHK(prng != NULL);
    LTC_ARGCHK(key  != NULL);
 
-   if ((err = crypto_sign_keypair(prng, wprng, key->pub, key->priv)) != CRYPT_OK) {
+   if ((err = tweetnacl_crypto_sign_keypair(prng, wprng, key->pub, key->priv)) != CRYPT_OK) {
       return err;
    }
 

+ 3 - 3
src/pk/ed25519/ed25519_set_key.c

@@ -10,13 +10,13 @@
 
 /**
   @file ed25519_set_ku.c
-  Set the parameters of a Ed25519 key, Steffen Jaeckel
+  Set the parameters of an Ed25519 key, Steffen Jaeckel
 */
 
 #ifdef LTC_CURVE25519
 
 /**
-   Set the parameters of a Ed25519 key
+   Set the parameters of an Ed25519 key
 
    In case sk and pk are given it is validated that pk is really the
    corresponding public part of the key pair.
@@ -37,7 +37,7 @@ int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
    if (sk != NULL) {
       LTC_ARGCHK(sklen == 32uL);
       XMEMCPY(key->priv, sk, sizeof(key->priv));
-      crypto_sk_to_pk(key->pub, key->priv);
+      tweetnacl_crypto_sk_to_pk(key->pub, key->priv);
       if (pk != NULL) {
          LTC_ARGCHK(pklen == 32uL);
          if (XMEM_NEQ(pk, key->pub, sizeof(key->pub)) != 0) {

+ 7 - 7
src/pk/ed25519/ed25519_sign.c

@@ -10,15 +10,15 @@
 
 /**
   @file ed25519_shared_secret.c
-  Create a Ed25519 signature, Steffen Jaeckel
+  Create an Ed25519 signature, Steffen Jaeckel
 */
 
 #ifdef LTC_CURVE25519
 
 /**
-   Create a Ed25519 signature.
-   @param private_key     The private ed25519 key in the pair
-   @param public_key      The public ed25519 key in the pair
+   Create an Ed25519 signature.
+   @param private_key     The private Ed25519 key in the pair
+   @param public_key      The public Ed25519 key in the pair
    @param out             [out] The destination of the shared data
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @return CRYPT_OK if successful
@@ -48,9 +48,9 @@ int ed25519_sign(const unsigned char  *msg, unsigned long msglen,
    s = XMALLOC(smlen);
    if (s == NULL) return CRYPT_MEM;
 
-   err = crypto_sign(s, &smlen,
-                     msg, msglen,
-                     private_key->priv, private_key->pub);
+   err = tweetnacl_crypto_sign(s, &smlen,
+                               msg, msglen,
+                               private_key->priv, private_key->pub);
 
    XMEMCPY(sig, s, 64uL);
    *siglen = 64uL;

+ 8 - 11
src/pk/ed25519/ed25519_verify.c

@@ -10,15 +10,15 @@
 
 /**
   @file ed25519_verify.c
-  Verify a Ed25519 signature, Steffen Jaeckel
+  Verify an Ed25519 signature, Steffen Jaeckel
 */
 
 #ifdef LTC_CURVE25519
 
 /**
-   Verify a Ed25519 signature.
-   @param private_key     The private curve25519 key in the pair
-   @param public_key      The public curve25519 key in the pair
+   Verify an Ed25519 signature.
+   @param private_key     The private Ed25519 key in the pair
+   @param public_key      The public Ed25519 key in the pair
    @param out             [out] The destination of the shared data
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @param stat            [out] The result of the signature verification, 1==valid, 0==invalid
@@ -51,19 +51,16 @@ int ed25519_verify(const  unsigned char *msg, unsigned long msglen,
    XMEMCPY(m, sig, siglen);
    XMEMCPY(m + siglen, msg, msglen);
 
-   err = crypto_sign_open(m, &mlen,
-                          m, mlen,
-                          public_key->pub);
+   err = tweetnacl_crypto_sign_open(stat,
+                                    m, &mlen,
+                                    m, mlen,
+                                    public_key->pub);
 
 #ifdef LTC_CLEAN_STACK
    zeromem(m, mlen);
 #endif
    XFREE(m);
 
-   if (err == CRYPT_OK) {
-      *stat = 1;
-   }
-
    return err;
 }
 

+ 2 - 2
src/pk/rsa/rsa_import_pkcs8.c

@@ -39,10 +39,10 @@
  */
 
 /**
-  Import an RSAPublicKey or RSAPrivateKey in PKCS#8 format
+  Import an RSAPrivateKey in PKCS#8 format
   @param in        The packet to import from
   @param inlen     It's length (octets)
-  @param passwd    The password for decrypting privkey (NOT SUPPORTED YET)
+  @param passwd    The password for decrypting privkey
   @param passwdlen Password's length (octets)
   @param key       [out] Destination for newly imported key
   @return CRYPT_OK if successful, upon error allocated memory is freed

+ 2 - 53
src/pk/x25519/x25519_export.c

@@ -27,62 +27,11 @@ int x25519_export(      unsigned char *out, unsigned long *outlen,
                                   int  which,
                   const    curve25519_key *key)
 {
-   int err, std;
-   const char* OID;
-   unsigned long oid[16], oidlen;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, private_key_len = sizeof(private_key);
-
-   LTC_ARGCHK(out       != NULL);
-   LTC_ARGCHK(outlen    != NULL);
-   LTC_ARGCHK(key       != NULL);
+   LTC_ARGCHK(key != NULL);
 
    if (key->algo != PKA_X25519) return CRYPT_PK_INVALID_TYPE;
 
-   std = which & PK_STD;
-   which &= ~PK_STD;
-
-   if (which == PK_PRIVATE) {
-      if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
-
-      if ((err = pk_get_oid(PKA_X25519, &OID)) != CRYPT_OK) {
-         return err;
-      }
-      oidlen = sizeof(oid)/sizeof(oid[0]);
-      if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
-         return err;
-      }
-
-      LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
-
-      /* encode private key as PKCS#8 */
-      if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
-         return err;
-      }
-
-      version = 0;
-      err = der_encode_sequence_multi(out, outlen,
-                                LTC_ASN1_SHORT_INTEGER,            1uL, &version,
-                                LTC_ASN1_SEQUENCE,                 1uL, alg_id,
-                                LTC_ASN1_OCTET_STRING, private_key_len, private_key,
-                                LTC_ASN1_EOL,                      0uL, NULL);
-   } else {
-      if (std == PK_STD) {
-         /* encode public key as SubjectPublicKeyInfo */
-         err = x509_encode_subject_public_key_info(out, outlen, PKA_X25519, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0uL);
-      } else {
-         if (*outlen < sizeof(key->pub)) {
-            err = CRYPT_BUFFER_OVERFLOW;
-         } else {
-            XMEMCPY(out, key->pub, sizeof(key->pub));
-            err = CRYPT_OK;
-         }
-         *outlen = sizeof(key->pub);
-      }
-   }
-
-   return err;
+   return ec25519_export(out, outlen, which, key);
 }
 
 #endif

+ 1 - 41
src/pk/x25519/x25519_import.c

@@ -25,11 +25,7 @@
 int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
 {
    int err;
-   const char *oid;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, key_len;
-   unsigned long tmpoid[16];
+   unsigned long key_len;
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
@@ -48,43 +44,7 @@ int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *
    if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_X25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
       key->type = PK_PUBLIC;
       key->algo = PKA_X25519;
-      return CRYPT_OK;
-   }
-
-   LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
-
-   key_len = sizeof(private_key);
-   if ((err = der_decode_sequence_multi(in, inlen,
-                             LTC_ASN1_SHORT_INTEGER,    1uL, &version,
-                             LTC_ASN1_SEQUENCE,         1uL, alg_id,
-                             LTC_ASN1_OCTET_STRING, key_len, private_key,
-                             LTC_ASN1_EOL,              0uL, NULL)) != CRYPT_OK) {
-      goto out;
-   }
-
-   if ((err = pk_get_oid(PKA_X25519, &oid)) != CRYPT_OK) {
-      goto out;
    }
-   if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
-      goto out;
-   }
-
-   if (version == 0) {
-      key_len = sizeof(key->priv);
-      if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
-         crypto_scalarmult_base(key->pub, key->priv);
-         key->type = PK_PRIVATE;
-         key->algo = PKA_X25519;
-      }
-   } else {
-      err = CRYPT_PK_INVALID_TYPE;
-   }
-
-out:
-#ifdef LTC_CLEAN_STACK
-   zeromem(private_key, sizeof(private_key));
-#endif
-
    return err;
 }
 

+ 38 - 0
src/pk/x25519/x25519_import_pkcs8.c

@@ -0,0 +1,38 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file x25519_import_pkcs8.c
+  Import a X25519 key in PKCS#8 format, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+  Import a X25519 private key in PKCS#8 format
+  @param in        The DER-encoded PKCS#8-formatted private key
+  @param inlen     The length of the input data
+  @param passwd    The password to decrypt the private key
+  @param passwdlen Password's length (octets)
+  @param key       [out] Where to import the key to
+  @return CRYPT_OK if successful, on error all allocated memory is freed automatically
+*/
+int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                       const void *pwd, unsigned long pwdlen,
+                       curve25519_key *key)
+{
+   return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_X25519, tweetnacl_crypto_scalarmult_base, key);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 1 - 1
src/pk/x25519/x25519_make_key.c

@@ -37,7 +37,7 @@ int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key)
       return CRYPT_ERROR_READPRNG;
    }
 
-   crypto_scalarmult_base(key->pub, key->priv);
+   tweetnacl_crypto_scalarmult_base(key->pub, key->priv);
 
    key->type = PK_PRIVATE;
    key->algo = PKA_X25519;

+ 4 - 4
src/pk/x25519/x25519_set_ku.c → src/pk/x25519/x25519_set_key.c

@@ -28,16 +28,16 @@
    @param key      [out] Destination of the key
    @return CRYPT_OK if successful
 */
-int x25519_set_ku(const unsigned char *k, unsigned long klen,
-                  const unsigned char *u, unsigned long ulen,
-                           curve25519_key *key)
+int x25519_set_key(const unsigned char *k, unsigned long klen,
+                   const unsigned char *u, unsigned long ulen,
+                        curve25519_key *key)
 {
    LTC_ARGCHK(key != NULL);
 
    if (k != NULL) {
       LTC_ARGCHK(klen == 32uL);
       XMEMCPY(key->priv, k, sizeof(key->priv));
-      crypto_scalarmult_base(key->pub, key->priv);
+      tweetnacl_crypto_scalarmult_base(key->pub, key->priv);
       if (u != NULL) {
          LTC_ARGCHK(ulen == 32uL);
          if (XMEM_NEQ(u, key->pub, sizeof(key->pub)) != 0) {

+ 3 - 3
src/pk/x25519/x25519_shared_secret.c

@@ -17,8 +17,8 @@
 
 /**
    Create a X25519 shared secret.
-   @param private_key     The private Curve25519 key in the pair
-   @param public_key      The public Curve25519 key in the pair
+   @param private_key     The private X25519 key in the pair
+   @param public_key      The public X25519 key in the pair
    @param out             [out] The destination of the shared data
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @return CRYPT_OK if successful
@@ -39,7 +39,7 @@ int x25519_shared_secret(const    curve25519_key *private_key,
       return CRYPT_BUFFER_OVERFLOW;
    }
 
-   crypto_scalarmult(out, private_key->priv, public_key->pub);
+   tweetnacl_crypto_scalarmult(out, private_key->priv, public_key->pub);
    *outlen = 32uL;
 
    return CRYPT_OK;

+ 28 - 4
tests/ed25519_test.c

@@ -43,6 +43,13 @@ static int _rfc_8410_10_test(void)
                        { "MHICAQEwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC"
                          "oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB"
                          "Z9w7lshQhqowtrbLDFw4rXAxZuE=", -1 },
+                         /* Another self-created testvector.
+                          * `openssl genpkey -algorithm ed25519 -pass stdin -aes128`
+                          */
+                       { "MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAiFflnrBOdwjwICCAAw"
+                         "DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEMzFYoqiT6gxwFx2EA55MUYEQFD1"
+                         "ZLxPNhm4YAsMZaxu5qpLjiZbkWsTHxURb6WhSW8GAbNbTwxeOaA02sUhJg8rx44/"
+                         "N9PzN2QGzIQ1Yv/vHqQ=", -1 },
    };
    unsigned n;
    curve25519_key key;
@@ -52,10 +59,22 @@ static int _rfc_8410_10_test(void)
    for (n = 0; n < sizeof(rfc_8410_10)/sizeof(rfc_8410_10[0]); ++n) {
       buflen = sizeof(buf);
       DO(base64_decode(rfc_8410_10[n].b64, strlen(rfc_8410_10[n].b64), buf, &buflen));
-      if (rfc_8410_10[n].type == -2) {
-         DO(ed25519_import_x509(buf, buflen, &key));
-      } else {
-         DO(ed25519_import(buf, buflen, &key));
+      switch (n) {
+         case 0:
+            DO(ed25519_import(buf, buflen, &key));
+            break;
+         case 1:
+            DO(ed25519_import_x509(buf, buflen, &key));
+            break;
+         case 2:
+         case 3:
+            DO(ed25519_import_pkcs8(buf, buflen, NULL, 0, &key));
+            break;
+         case 4:
+            DO(ed25519_import_pkcs8(buf, buflen, "123456", 6, &key));
+            break;
+         default:
+            return CRYPT_FAIL_TESTVECTOR;
       }
       zeromem(buf, sizeof(buf));
       if (rfc_8410_10[n].type > 0) {
@@ -212,6 +231,11 @@ static int _rfc_8032_7_1_test(void)
 int ed25519_test(void)
 {
    int ret;
+   curve25519_key key;
+
+   if ((ret = ed25519_make_key(&yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
+      return ret;
+   }
 
    if (ltc_mp.name == NULL) return CRYPT_NOP;
 

+ 47 - 9
tests/x25519_test.c

@@ -56,7 +56,7 @@ static int _rfc_7748_5_2_test(void)
    unsigned long n;
 
    for (n = 0; n < sizeof(rfc_7748_5_2)/sizeof(rfc_7748_5_2[0]); ++n) {
-      crypto_scalarmult(out, rfc_7748_5_2[n].scalar, rfc_7748_5_2[n].u_in);
+      tweetnacl_crypto_scalarmult(out, rfc_7748_5_2[n].scalar, rfc_7748_5_2[n].u_in);
       if (compare_testvector(out, sizeof(out), rfc_7748_5_2[n].u_out, sizeof(rfc_7748_5_2[n].u_out), "x25519 RFC 7748 Ch. 5.2", n) != 0) {
          return CRYPT_FAIL_TESTVECTOR;
       }
@@ -101,10 +101,10 @@ static int _rfc_7748_6_test(void)
    unsigned char buf[32];
    unsigned long buflen = sizeof(buf);
 
-   DO(x25519_set_ku(alice_private, sizeof(alice_private), alice_public, sizeof(alice_public), &alice_priv));
-   DO(x25519_set_ku(bob_private, sizeof(bob_private), bob_public, sizeof(bob_public), &bob_priv));
-   DO(x25519_set_ku(NULL, 0, alice_public, sizeof(alice_public), &alice_pub));
-   DO(x25519_set_ku(NULL, 0, bob_public, sizeof(bob_public), &bob_pub));
+   DO(x25519_set_key(alice_private, sizeof(alice_private), alice_public, sizeof(alice_public), &alice_priv));
+   DO(x25519_set_key(bob_private, sizeof(bob_private), bob_public, sizeof(bob_public), &bob_priv));
+   DO(x25519_set_key(NULL, 0, alice_public, sizeof(alice_public), &alice_pub));
+   DO(x25519_set_key(NULL, 0, bob_public, sizeof(bob_public), &bob_pub));
 
    DO(x25519_shared_secret(&alice_priv, &bob_pub, buf, &buflen));
    DO(compare_testvector(buf, buflen, shared_secret, sizeof(shared_secret), "x25519 - RFC 7748 Ch. 6", 0));
@@ -120,7 +120,7 @@ static int _rfc_7748_6_test(void)
 static int _rfc_8410_10_test(void)
 {
    const struct {
-      const char* b64;
+      const char *b64;
    } rfc_8410_10[] = {
                          /* RFC 8410 - 10.2.  Example X25519 Certificate */
                        { "MIIBLDCB36ADAgECAghWAUdKKo3DMDAFBgMrZXAwGTEXMBUGA1UEAwwOSUVURiBUZX"
@@ -129,7 +129,8 @@ static int _rfc_8410_10_test(void)
                          "ga9OukqY6qm05qo0UwQzAPBgNVHRMBAf8EBTADAQEAMA4GA1UdDwEBAAQEAwIDCDAg"
                          "BgNVHQ4BAQAEFgQUmx9e7e0EM4Xk97xiPFl1uQvIuzswBQYDK2VwA0EAryMB/t3J5v"
                          "/BzKc9dNZIpDmAgs3babFOTQbs+BolzlDUwsPrdGxO3YNGhW7Ibz3OGhhlxXrCe1Cg"
-                         "w1AH9efZBw==" },
+                         "w1AH9efZBw=="
+                       },
    };
    unsigned n;
    curve25519_key key;
@@ -144,6 +145,40 @@ static int _rfc_8410_10_test(void)
    return CRYPT_OK;
 }
 
+static int _x25519_pkcs8_test(void)
+{
+   const struct {
+      const char *b64, *pass;
+   } _x25519_pkcs8[] = {
+                          /* `openssl genpkey -algorithm x25519 -pass stdin -aes128` */
+                          {
+                            "MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjG5kRkEihOvQICCAAw"
+                            "DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEHPLHLoCvesRyeToyMtGHWcEQM1+"
+                            "FMpSO5DplX3d+YGTAvf0WxWaBff1q4bfKDn/7IoWQT1e4Fe6Psj62Vy9T69o3+Uy"
+                            "VM6mdIOXGOkAtaMSsSk=",
+                            "123456"
+                          },
+                          /* `openssl genpkey -algorithm x25519 -pass stdin` */
+                          {
+                            "MC4CAQAwBQYDK2VuBCIEIEAInaUdx+fQFfghpCzw/WdItRT3+FnPSkrU9TcIZTZW",
+                            NULL
+                          },
+   };
+   unsigned n;
+   curve25519_key key;
+   unsigned char buf[1024];
+   unsigned long buflen, passlen;
+   for (n = 0; n < sizeof(_x25519_pkcs8)/sizeof(_x25519_pkcs8[0]); ++n) {
+      buflen = sizeof(buf);
+      DO(base64_decode(_x25519_pkcs8[n].b64, strlen(_x25519_pkcs8[n].b64), buf, &buflen));
+      if (_x25519_pkcs8[n].pass != NULL) passlen = strlen(_x25519_pkcs8[n].pass);
+      else passlen = 0;
+      DO(x25519_import_pkcs8(buf, buflen, _x25519_pkcs8[n].pass, passlen, &key));
+      zeromem(buf, sizeof(buf));
+   }
+   return CRYPT_OK;
+}
+
 static int _x25519_compat_test(void)
 {
    curve25519_key priv, pub, imported;
@@ -157,8 +192,8 @@ static int _x25519_compat_test(void)
 
    DO(x25519_make_key(&yarrow_prng, prng_idx, &priv));
 
-   DO(x25519_export(buf, &buflen, PK_PRIVATE, &priv));
-   DO(x25519_import(buf, buflen, &imported));
+   DO(x25519_export(buf, &buflen, PK_PRIVATE | PK_STD, &priv));
+   DO(x25519_import_pkcs8(buf, buflen, NULL, 0, &imported));
    DO(do_compare_testvector(&priv, sizeof(priv), &imported, sizeof(imported), "priv after ex-&import", __LINE__));
    XMEMSET(&imported, 0, sizeof(imported));
 
@@ -201,6 +236,9 @@ int x25519_test(void)
    if ((ret = _rfc_8410_10_test()) != CRYPT_OK) {
       return ret;
    }
+   if ((ret = _x25519_pkcs8_test()) != CRYPT_OK) {
+      return ret;
+   }
    if ((ret = _x25519_compat_test()) != CRYPT_OK) {
       return ret;
    }