@@ -35,7 +35,7 @@ curve_data = { | |||||
"wnaf":wnaf_config(5,3), | "wnaf":wnaf_config(5,3), | ||||
"window_bits":4, | "window_bits":4, | ||||
"eddsa_hash": "sha3_512", # TODO: no, actually it's SHA2-512 | |||||
"eddsa_hash": "sha512", | |||||
"eddsa_supports_contexts": 0, | "eddsa_supports_contexts": 0, | ||||
"eddsa_dom": "" | "eddsa_dom": "" | ||||
}, | }, | ||||
@@ -1052,28 +1052,32 @@ void API_NS(point_encode_like_eddsa) ( | |||||
/* The point is now on the twisted curve. Move it to untwisted. */ | /* The point is now on the twisted curve. Move it to untwisted. */ | ||||
gf x, y, z, t; | gf x, y, z, t; | ||||
point_t q; | |||||
#if COFACTOR == 8 | |||||
API_NS(point_double)(q,p); | |||||
#else | |||||
API_NS(point_copy)(q,p); | |||||
#endif | |||||
#if IMAGINE_TWIST | #if IMAGINE_TWIST | ||||
{ | { | ||||
/* TODO: make sure cofactor is clear */ | /* TODO: make sure cofactor is clear */ | ||||
point_t q; | |||||
API_NS(point_double)(q,p); | |||||
API_NS(point_double)(q,q); | |||||
gf_div_qnr(x, q->x); | gf_div_qnr(x, q->x); | ||||
gf_copy(y, q->y); | gf_copy(y, q->y); | ||||
gf_copy(z, q->z); | gf_copy(z, q->z); | ||||
API_NS(point_destroy(q)); | |||||
} | } | ||||
#else | #else | ||||
{ | { | ||||
/* 4-isogeny: 2xy/(y^+x^2), (y^2-x^2)/(2z^2-y^2+x^2) */ | /* 4-isogeny: 2xy/(y^+x^2), (y^2-x^2)/(2z^2-y^2+x^2) */ | ||||
gf u; | gf u; | ||||
gf_sqr ( x, p->x ); | |||||
gf_sqr ( t, p->y ); | |||||
gf_sqr ( x, q->x ); | |||||
gf_sqr ( t, q->y ); | |||||
gf_add( u, x, t ); | gf_add( u, x, t ); | ||||
gf_add( z, p->y, p->x ); | |||||
gf_add( z, q->y, q->x ); | |||||
gf_sqr ( y, z); | gf_sqr ( y, z); | ||||
gf_sub ( y, y, u ); | gf_sub ( y, y, u ); | ||||
gf_sub ( z, t, x ); | gf_sub ( z, t, x ); | ||||
gf_sqr ( x, p->z ); | |||||
gf_sqr ( x, q->z ); | |||||
gf_add ( t, x, x); | gf_add ( t, x, x); | ||||
gf_sub ( t, t, z); | gf_sub ( t, t, z); | ||||
gf_mul ( x, t, y ); | gf_mul ( x, t, y ); | ||||
@@ -1096,6 +1100,7 @@ void API_NS(point_encode_like_eddsa) ( | |||||
decaf_bzero(y,sizeof(y)); | decaf_bzero(y,sizeof(y)); | ||||
decaf_bzero(z,sizeof(z)); | decaf_bzero(z,sizeof(z)); | ||||
decaf_bzero(t,sizeof(t)); | decaf_bzero(t,sizeof(t)); | ||||
API_NS(point_destroy)(q); | |||||
} | } | ||||
@@ -4,7 +4,8 @@ | |||||
*/ | */ | ||||
#include <decaf/eddsa_$(gf_bits).h> | #include <decaf/eddsa_$(gf_bits).h> | ||||
#include "decaf/shake.h" | |||||
#include <decaf/shake.h> | |||||
#include <decaf/sha512.h> | |||||
#include "word.h" | #include "word.h" | ||||
#include <string.h> | #include <string.h> | ||||
@@ -73,8 +74,10 @@ void API_NS(eddsa_derive_public_key) ( | |||||
API_NS(scalar_decode_long)(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser)); | API_NS(scalar_decode_long)(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser)); | ||||
/* TODO: write documentation for why (due to isogenies) this needs to be quartered */ | /* TODO: write documentation for why (due to isogenies) this needs to be quartered */ | ||||
API_NS(scalar_sub)(secret_scalar,API_NS(scalar_zero),secret_scalar); | API_NS(scalar_sub)(secret_scalar,API_NS(scalar_zero),secret_scalar); | ||||
API_NS(scalar_halve)(secret_scalar,secret_scalar); | |||||
API_NS(scalar_halve)(secret_scalar,secret_scalar); | |||||
for (unsigned int c = 1; c < $(cofactor); c <<= 1) { | |||||
API_NS(scalar_halve)(secret_scalar,secret_scalar); | |||||
} | |||||
API_NS(point_t) p; | API_NS(point_t) p; | ||||
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar); | API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar); | ||||
@@ -142,9 +145,12 @@ void API_NS(eddsa_sign) ( | |||||
{ | { | ||||
/* Scalarmul to create the nonce-point */ | /* Scalarmul to create the nonce-point */ | ||||
API_NS(scalar_t) nonce_scalar_2; | API_NS(scalar_t) nonce_scalar_2; | ||||
API_NS(scalar_halve)(nonce_scalar_2, nonce_scalar); | |||||
API_NS(scalar_halve)(nonce_scalar_2, nonce_scalar_2); | |||||
API_NS(scalar_sub)(nonce_scalar_2,API_NS(scalar_zero),nonce_scalar_2); | |||||
API_NS(scalar_sub)(nonce_scalar_2,API_NS(scalar_zero),nonce_scalar); | |||||
for (unsigned int c = 1; c < $(cofactor); c <<= 1) { | |||||
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2); | |||||
} | |||||
API_NS(point_t) p; | API_NS(point_t) p; | ||||
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2); | API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2); | ||||
API_NS(point_encode_like_eddsa)(nonce_point, p); | API_NS(point_encode_like_eddsa)(nonce_point, p); | ||||
@@ -480,7 +480,7 @@ static void test_cfrg_vectors() { | |||||
SecureBuffer eddsa_pk2 = EdDSA::generate_key(eddsa_sk); | SecureBuffer eddsa_pk2 = EdDSA::generate_key(eddsa_sk); | ||||
if (!memeq(SecureBuffer(eddsa_pk), eddsa_pk2)) { | if (!memeq(SecureBuffer(eddsa_pk), eddsa_pk2)) { | ||||
test.fail(); | test.fail(); | ||||
printf(" EdDSA vectors disagree."); | |||||
printf(" EdDSA PK vectors disagree."); | |||||
printf("\n Correct: "); | printf("\n Correct: "); | ||||
for (unsigned i=0; i<eddsa_pk.size(); i++) printf("%02x", eddsa_pk[i]); | for (unsigned i=0; i<eddsa_pk.size(); i++) printf("%02x", eddsa_pk[i]); | ||||
printf("\n Incorrect: "); | printf("\n Incorrect: "); | ||||
@@ -492,7 +492,7 @@ static void test_cfrg_vectors() { | |||||
if (!memeq(SecureBuffer(eddsa_sig0),sig)) { | if (!memeq(SecureBuffer(eddsa_sig0),sig)) { | ||||
test.fail(); | test.fail(); | ||||
printf(" EdDSA vectors disagree."); | |||||
printf(" EdDSA sig vectors disagree."); | |||||
printf("\n Correct: "); | printf("\n Correct: "); | ||||
for (unsigned i=0; i<eddsa_sig0.size(); i++) printf("%02x", eddsa_sig0[i]); | for (unsigned i=0; i<eddsa_sig0.size(); i++) printf("%02x", eddsa_sig0[i]); | ||||
printf("\n Incorrect: "); | printf("\n Incorrect: "); | ||||
@@ -685,9 +685,32 @@ template<> const Block Tests<Ed448Goldilocks>::eddsa_sk(ed448_eddsa_sk,57); | |||||
template<> const Block Tests<Ed448Goldilocks>::eddsa_pk(ed448_eddsa_pk,57); | template<> const Block Tests<Ed448Goldilocks>::eddsa_pk(ed448_eddsa_pk,57); | ||||
template<> const Block Tests<Ed448Goldilocks>::eddsa_sig0(ed448_eddsa_sig0,114); | template<> const Block Tests<Ed448Goldilocks>::eddsa_sig0(ed448_eddsa_sig0,114); | ||||
template<> const Block Tests<IsoEd25519>::eddsa_sk(NULL,0); /* TODO */ | |||||
template<> const Block Tests<IsoEd25519>::eddsa_pk(NULL,0); /* TODO */ | |||||
template<> const Block Tests<IsoEd25519>::eddsa_sig0(NULL,0); /* TODO */ | |||||
const uint8_t ed25519_eddsa_sk[32] = { | |||||
0x9d,0x61,0xb1,0x9d,0xef,0xfd,0x5a,0x60, | |||||
0xba,0x84,0x4a,0xf4,0x92,0xec,0x2c,0xc4, | |||||
0x44,0x49,0xc5,0x69,0x7b,0x32,0x69,0x19, | |||||
0x70,0x3b,0xac,0x03,0x1c,0xae,0x7f,0x60 | |||||
}; | |||||
const uint8_t ed25519_eddsa_pk[32] = { | |||||
0xd7,0x5a,0x98,0x01,0x82,0xb1,0x0a,0xb7, | |||||
0xd5,0x4b,0xfe,0xd3,0xc9,0x64,0x07,0x3a, | |||||
0x0e,0xe1,0x72,0xf3,0xda,0xa6,0x23,0x25, | |||||
0xaf,0x02,0x1a,0x68,0xf7,0x07,0x51,0x1a | |||||
}; | |||||
const uint8_t ed25518_eddsa_sig0[64] = { | |||||
0xe5,0x56,0x43,0x00,0xc3,0x60,0xac,0x72, | |||||
0x90,0x86,0xe2,0xcc,0x80,0x6e,0x82,0x8a, | |||||
0x84,0x87,0x7f,0x1e,0xb8,0xe5,0xd9,0x74, | |||||
0xd8,0x73,0xe0,0x65,0x22,0x49,0x01,0x55, | |||||
0x5f,0xb8,0x82,0x15,0x90,0xa3,0x3b,0xac, | |||||
0xc6,0x1e,0x39,0x70,0x1c,0xf9,0xb4,0x6b, | |||||
0xd2,0x5b,0xf5,0xf0,0x59,0x5b,0xbe,0x24, | |||||
0x65,0x51,0x41,0x43,0x8e,0x7a,0x10,0x0b | |||||
}; | |||||
template<> const Block Tests<IsoEd25519>::eddsa_sk(ed25519_eddsa_sk,32); | |||||
template<> const Block Tests<IsoEd25519>::eddsa_pk(ed25519_eddsa_pk,32); | |||||
template<> const Block Tests<IsoEd25519>::eddsa_sig0(ed25518_eddsa_sig0,64); | |||||
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||
(void) argc; (void) argv; | (void) argc; (void) argv; | ||||