Commit fffb77ac authored by Michael Hamburg's avatar Michael Hamburg

eddsa sign seems to work for ed448. needs more testing of course

parent d0e74a58
......@@ -45,7 +45,7 @@ typedef struct gf_$(gf_shortname)_s {
#define $(C_NS)_EDDSA_PRIVATE_BYTES $(C_NS)_EDDSA_PUBLIC_BYTES /* TODO: change name? */
/** Number of bytes in an EdDSA private key. */
#define $(C_NS)_EDDSA_SIGNATURE_BYTES ($(C_NS)_PUBLIC_BYTES + $(C_NS)_PRIVATE_BYTES) /* TODO: change name? */
#define $(C_NS)_EDDSA_SIGNATURE_BYTES ($(C_NS)_EDDSA_PUBLIC_BYTES + $(C_NS)_EDDSA_PRIVATE_BYTES) /* TODO: change name? */
/** Number of bytes in an x$(gf_shortname) public key */
#define X$(gf_shortname)_PUBLIC_BYTES $((gf_bits-1)/8 + 1)
......@@ -425,6 +425,29 @@ void $(c_ns)_eddsa_derive_public_key (
uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES],
const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES]
) API_VIS NONNULL NOINLINE;
/**
* @brief EdDSA signing.
*
* @param [out] The signature.
* @param [in] privkey The private key.
* @param [in] pubkey The public key.
* @param [in] context A "context" for this signature of up to 255 bytes.
* @param [in] context_len Length of the context.
* @param [in] message The message to sign.
* @param [in] message_len The length of the message.
* @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign.
*/
void $(c_ns)_eddsa_sign (
uint8_t signature[$(C_NS)_EDDSA_SIGNATURE_BYTES],
const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES],
const uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES],
const uint8_t *context,
uint8_t context_len,
const uint8_t *message,
size_t message_len,
uint8_t prehashed
) API_VIS NONNULL NOINLINE;
/**
* @brief EdDSA point encoding.
......
......@@ -658,12 +658,37 @@ public:
/** The size of a private key */
static const size_t PRIVATE_BYTES = $(C_NS)_EDDSA_PRIVATE_BYTES;
/** The size of a private key */
static const size_t SIGNATURE_BYTES = $(C_NS)_EDDSA_SIGNATURE_BYTES;
/* TODO: make into a nice class. Change name. Possibly move to another include file. */
static inline SecureBuffer generate_key (
const FixedBlock<PRIVATE_BYTES> &secret
const FixedBlock<PRIVATE_BYTES> &priv
) {
SecureBuffer out(PUBLIC_BYTES);
$(c_ns)_eddsa_derive_public_key(out.data(), secret.data());
$(c_ns)_eddsa_derive_public_key(out.data(), priv.data());
return out;
}
static inline SecureBuffer sign (
const FixedBlock<PRIVATE_BYTES> &priv,
const FixedBlock<PUBLIC_BYTES> &pub,
const Block &context,
const Block &message,
bool prehashed = false
) throw(LengthException) {
if (context.size() > 255) { throw LengthException(); }
SecureBuffer out(SIGNATURE_BYTES);
$(c_ns)_eddsa_sign (
out.data(),
priv.data(),
pub.data(),
context.data(),
context.size(),
message.data(),
message.size(),
prehashed
);
return out;
}
};
......
......@@ -456,7 +456,7 @@ static void test_cfrg_crypto() {
}
}
static const Block eddsa_sk, eddsa_pk;
static const Block eddsa_sk, eddsa_pk, eddsa_sig0;
static void test_cfrg_vectors() {
Test test("CFRG test vectors");
......@@ -465,8 +465,6 @@ static void test_cfrg_vectors() {
int the_ntests = (NTESTS < 1000000) ? 1000 : 1000000;
/* EdDSA */
if (eddsa_sk.size()) {
SecureBuffer eddsa_pk2 = EdDSA::generate_key(eddsa_sk);
......@@ -477,7 +475,19 @@ static void test_cfrg_vectors() {
for (unsigned i=0; i<eddsa_pk.size(); i++) printf("%02x", eddsa_pk[i]);
printf("\n Incorrect: ");
for (unsigned i=0; i<eddsa_pk.size(); i++) printf("%02x", eddsa_pk2[i]);
for (unsigned i=0; i<eddsa_pk2.size(); i++) printf("%02x", eddsa_pk2[i]);
printf("\n");
}
SecureBuffer sig = EdDSA::sign(eddsa_sk,eddsa_pk,Block(NULL,0),Block(NULL,0));
if (!memeq(SecureBuffer(eddsa_sig0),sig)) {
test.fail();
printf(" EdDSA vectors disagree.");
printf("\n Correct: ");
for (unsigned i=0; i<eddsa_sig0.size(); i++) printf("%02x", eddsa_sig0[i]);
printf("\n Incorrect: ");
for (unsigned i=0; i<sig.size(); i++) printf("%02x", sig[i]);
printf("\n");
}
}
......@@ -619,15 +629,33 @@ const uint8_t ed448_eddsa_pk[57] = {
0xd1,0xfa,0x1a,0xbe,0xaf,0xe8,0x25,0x61,
0x80
};
const uint8_t ed448_eddsa_sig0[114] = {
0x53,0x3a,0x37,0xf6,0xbb,0xe4,0x57,0x25,
0x1f,0x02,0x3c,0x0d,0x88,0xf9,0x76,0xae,
0x2d,0xfb,0x50,0x4a,0x84,0x3e,0x34,0xd2,
0x07,0x4f,0xd8,0x23,0xd4,0x1a,0x59,0x1f,
0x2b,0x23,0x3f,0x03,0x4f,0x62,0x82,0x81,
0xf2,0xfd,0x7a,0x22,0xdd,0xd4,0x7d,0x78,
0x28,0xc5,0x9b,0xd0,0xa2,0x1b,0xfd,0x39,
0x80,0xff,0x0d,0x20,0x28,0xd4,0xb1,0x8a,
0x9d,0xf6,0x3e,0x00,0x6c,0x5d,0x1c,0x2d,
0x34,0x5b,0x92,0x5d,0x8d,0xc0,0x0b,0x41,
0x04,0x85,0x2d,0xb9,0x9a,0xc5,0xc7,0xcd,
0xda,0x85,0x30,0xa1,0x13,0xa0,0xf4,0xdb,
0xb6,0x11,0x49,0xf0,0x5a,0x73,0x63,0x26,
0x8c,0x71,0xd9,0x58,0x08,0xff,0x2e,0x65,
0x26,0x00
};
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_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 */
int main(int argc, char **argv) {
(void) argc; (void) argv;
run_for_all_curves<Tests>();
if (passing) printf("Passed all tests.\n");
return passing ? 0 : 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment