diff --git a/.gitignore b/.gitignore index 101f340c..6898147f 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ test/default/core3 test/default/core4 test/default/core5 test/default/core6 +test/default/ed25519_convert test/default/generichash test/default/generichash2 test/default/generichash3 diff --git a/builds/msvc/vs2010/test/test.vcxproj b/builds/msvc/vs2010/test/test.vcxproj index 2cd94c3c..c84b2d65 100644 --- a/builds/msvc/vs2010/test/test.vcxproj +++ b/builds/msvc/vs2010/test/test.vcxproj @@ -112,6 +112,9 @@ true + + true + true @@ -211,4 +214,4 @@ - \ No newline at end of file + diff --git a/builds/msvc/vs2010/test/test.vcxproj.filters b/builds/msvc/vs2010/test/test.vcxproj.filters index c0819e8e..e09eef9b 100644 --- a/builds/msvc/vs2010/test/test.vcxproj.filters +++ b/builds/msvc/vs2010/test/test.vcxproj.filters @@ -49,6 +49,9 @@ src + + src + src @@ -159,4 +162,4 @@ {5b5af4b5-c6aa-4b30-bdef-074b1bdc43ea} - \ No newline at end of file + diff --git a/builds/msvc/vs2012/test/test.vcxproj b/builds/msvc/vs2012/test/test.vcxproj index 65fd4d8f..40c2afaf 100644 --- a/builds/msvc/vs2012/test/test.vcxproj +++ b/builds/msvc/vs2012/test/test.vcxproj @@ -112,6 +112,9 @@ true + + true + true @@ -211,4 +214,4 @@ - \ No newline at end of file + diff --git a/builds/msvc/vs2012/test/test.vcxproj.filters b/builds/msvc/vs2012/test/test.vcxproj.filters index c0819e8e..e09eef9b 100644 --- a/builds/msvc/vs2012/test/test.vcxproj.filters +++ b/builds/msvc/vs2012/test/test.vcxproj.filters @@ -49,6 +49,9 @@ src + + src + src @@ -159,4 +162,4 @@ {5b5af4b5-c6aa-4b30-bdef-074b1bdc43ea} - \ No newline at end of file + diff --git a/builds/msvc/vs2013/test/test.vcxproj b/builds/msvc/vs2013/test/test.vcxproj index 780396e9..eff09cc2 100644 --- a/builds/msvc/vs2013/test/test.vcxproj +++ b/builds/msvc/vs2013/test/test.vcxproj @@ -112,6 +112,9 @@ true + + true + true @@ -211,4 +214,4 @@ - \ No newline at end of file + diff --git a/builds/msvc/vs2013/test/test.vcxproj.filters b/builds/msvc/vs2013/test/test.vcxproj.filters index c0819e8e..e09eef9b 100644 --- a/builds/msvc/vs2013/test/test.vcxproj.filters +++ b/builds/msvc/vs2013/test/test.vcxproj.filters @@ -49,6 +49,9 @@ src + + src + src @@ -159,4 +162,4 @@ {5b5af4b5-c6aa-4b30-bdef-074b1bdc43ea} - \ No newline at end of file + diff --git a/src/libsodium/crypto_sign/ed25519/ref10/keypair.c b/src/libsodium/crypto_sign/ed25519/ref10/keypair.c index 79556472..a83095b1 100644 --- a/src/libsodium/crypto_sign/ed25519/ref10/keypair.c +++ b/src/libsodium/crypto_sign/ed25519/ref10/keypair.c @@ -2,8 +2,11 @@ #include #include "api.h" -#include "randombytes.h" #include "crypto_hash_sha512.h" +#include "crypto_scalarmult_curve25519.h" +#include "randombytes.h" +#include "utils.h" +#include "fe.h" #include "ge.h" int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, @@ -31,3 +34,39 @@ int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) randombytes(seed,32); return crypto_sign_seed_keypair(pk,sk,seed); } + +int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk) +{ + ge_p3 A; + fe x; + fe one_minus_y; + + ge_frombytes_negate_vartime(&A, ed25519_pk); + fe_1(one_minus_y); + fe_sub(one_minus_y, one_minus_y, A.Y); + fe_invert(one_minus_y, one_minus_y); + fe_1(x); + fe_add(x, x, A.Y); + fe_mul(x, x, one_minus_y); + fe_tobytes(curve25519_pk, x); + + return 0; +} + +int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk) +{ + unsigned char h[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512(h, ed25519_sk, + crypto_sign_ed25519_SECRETKEYBYTES - + crypto_sign_ed25519_PUBLICKEYBYTES); + h[0] &= 248; + h[31] &= 127; + h[31] |= 64; + memcpy(curve25519_sk, h, crypto_scalarmult_curve25519_BYTES); + sodium_memzero(h, sizeof h); + + return 0; +} diff --git a/src/libsodium/include/sodium/crypto_sign_ed25519.h b/src/libsodium/include/sodium/crypto_sign_ed25519.h index 101b6c95..e1f93aad 100644 --- a/src/libsodium/include/sodium/crypto_sign_ed25519.h +++ b/src/libsodium/include/sodium/crypto_sign_ed25519.h @@ -57,6 +57,13 @@ SODIUM_EXPORT int crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed); +SODIUM_EXPORT +int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk); #ifdef __cplusplus } #endif diff --git a/test/default/Makefile.am b/test/default/Makefile.am index cafc782d..c25efe1b 100644 --- a/test/default/Makefile.am +++ b/test/default/Makefile.am @@ -23,6 +23,7 @@ EXTRA_DIST = \ core4.exp \ core5.exp \ core6.exp \ + ed25519_convert.exp \ generichash.exp \ generichash2.exp \ generichash3.exp \ @@ -77,6 +78,7 @@ DISTCLEANFILES = \ core4.res \ core5.res \ core6.res \ + ed25519_convert.res \ generichash.res \ generichash2.res \ generichash3.res \ @@ -139,6 +141,7 @@ TESTS_TARGETS = \ core4 \ core5 \ core6 \ + ed25519_convert \ generichash \ generichash2 \ generichash3 \ @@ -241,6 +244,9 @@ core5_LDADD = $(TESTS_LDADD) core6_SOURCE = cmptest.h core6.c core6_LDADD = $(TESTS_LDADD) +ed25519_convert_SOURCE = cmptest.h ed25519_convert.c +ed25519_convert_LDADD = $(TESTS_LDADD) + generichash_SOURCE = cmptest.h generichash.c generichash_LDADD = $(TESTS_LDADD) diff --git a/test/default/ed25519_convert.c b/test/default/ed25519_convert.c new file mode 100644 index 00000000..da0f2666 --- /dev/null +++ b/test/default/ed25519_convert.c @@ -0,0 +1,49 @@ +#include +#include + +#define TEST_NAME "ed25519_convert" +#include "cmptest.h" + +static const unsigned char keypair_seed[crypto_sign_ed25519_SEEDBYTES] = { + 0x42, 0x11, 0x51, 0xa4, 0x59, 0xfa, 0xea, 0xde, + 0x3d, 0x24, 0x71, 0x15, 0xf9, 0x4a, 0xed, 0xae, + 0x42, 0x31, 0x81, 0x24, 0x09, 0x5a, 0xfa, 0xbe, + 0x4d, 0x14, 0x51, 0xa5, 0x59, 0xfa, 0xed, 0xee +}; + +int main(void) +{ + unsigned char ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES]; + unsigned char ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES + + crypto_sign_ed25519_PUBLICKEYBYTES]; + unsigned char curve25519_pk[crypto_scalarmult_curve25519_BYTES]; + unsigned char curve25519_pk2[crypto_scalarmult_curve25519_BYTES]; + unsigned char curve25519_sk[crypto_scalarmult_curve25519_BYTES]; + char curve25519_pk_hex[crypto_scalarmult_curve25519_BYTES * 2 + 1]; + char curve25519_sk_hex[crypto_scalarmult_curve25519_BYTES * 2 + 1]; + unsigned int i; + + crypto_sign_ed25519_seed_keypair(ed25519_pk, ed25519_skpk, keypair_seed); + crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk); + crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk); + sodium_bin2hex(curve25519_pk_hex, sizeof curve25519_pk_hex, + curve25519_pk, sizeof curve25519_pk); + sodium_bin2hex(curve25519_sk_hex, sizeof curve25519_sk_hex, + curve25519_sk, sizeof curve25519_sk); + + printf("curve25519 pk: [%s]\n", curve25519_pk_hex); + printf("curve25519 sk: [%s]\n", curve25519_sk_hex); + + for (i = 0U; i < 500U; i++) { + crypto_sign_ed25519_keypair(ed25519_pk, ed25519_skpk); + crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk); + crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk); + crypto_scalarmult_curve25519_base(curve25519_pk2, curve25519_sk); + if (memcmp(curve25519_pk, curve25519_pk2, sizeof curve25519_pk) != 0) { + printf("conversion failed\n"); + } + } + printf("ok\n"); + + return 0; +} diff --git a/test/default/ed25519_convert.exp b/test/default/ed25519_convert.exp new file mode 100644 index 00000000..cba2b7b8 --- /dev/null +++ b/test/default/ed25519_convert.exp @@ -0,0 +1,3 @@ +curve25519 pk: [f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50] +curve25519 sk: [8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166] +ok