X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/blobdiff_plain/a4c6c9bad5c2965cf970071de0cb2f3179c22b50..a47ab75afd236ddb02ee467210cbdeeeba9dbff6:/ed25519-test.c diff --git a/ed25519-test.c b/ed25519-test.c new file mode 100644 index 0000000..b2a962b --- /dev/null +++ b/ed25519-test.c @@ -0,0 +1,147 @@ +/* + * xdh-test.c: test harness for elliptic-curve Diffie--Hellman + * + * (The implementations originally came with different test arrangements, + * with complicated external dependencies. This file replicates the original + * tests, but without the dependencies.) + */ +/* + * This file is Free Software. It was originally written for secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * You may redistribute this file and/or modify it under the terms of + * the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later + * version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ + +#include + +#include "secnet.h" + +#include "sha512.h" +#include "ed25519.h" + +#define GLUE(x, y) GLUE_(x, y) +#define GLUE_(x, y) x##y +#define XDHOP(op) GLUE(XDH, _##op) + +#include "crypto-test.h" + +enum { + RSIGOUT, RAOUT = RSIGOUT, RRC = RSIGOUT, NROUT, + RA = NROUT, RPH, RCTX, RM, RSIGIN, NREG +}; + +static void test_pubkey(struct reg *out, const struct reg *in, void *ctx) +{ + allocate_bytes(&out[RAOUT].v, ED25519_PUBSZ); + ed25519_pubkey(out[RAOUT].v.bytes.p, + in[RA].v.bytes.p, in[RA].v.bytes.sz); +} + +static void test_sign(struct reg *out, const struct reg *in, void *ctx) +{ + octet K[ED25519_PUBSZ]; + + allocate_bytes(&out[RSIGOUT].v, ED25519_SIGSZ); + ed25519_pubkey(K, in[RA].v.bytes.p, in[RA].v.bytes.sz); + ed25519_sign(out[RSIGOUT].v.bytes.p, + in[RA].v.bytes.p, in[RA].v.bytes.sz, K, + in[RM].v.bytes.p, in[RM].v.bytes.sz); +} + +static void test_sign_ctx(struct reg *out, const struct reg *in, void *ctx) +{ + octet K[ED25519_PUBSZ]; + const octet *m = in[RM].v.bytes.p; size_t msz = in[RM].v.bytes.sz; + octet h[SHA512_DIGEST_SIZE]; + struct sha512_ctx hctx; + + if (in[RPH].v.i) { + sha512_init_ctx(&hctx); + sha512_process_bytes(m, msz, &hctx); + sha512_finish_ctx(&hctx, h); + m = h; msz = sizeof(h); + } + + allocate_bytes(&out[RSIGOUT].v, ED25519_SIGSZ); + ed25519_pubkey(K, in[RA].v.bytes.p, in[RA].v.bytes.sz); + ed25519ctx_sign(out[RSIGOUT].v.bytes.p, + in[RA].v.bytes.p, in[RA].v.bytes.sz, K, + in[RPH].v.i, + in[RCTX].v.bytes.p, in[RCTX].v.bytes.sz, + m, msz); +} + +static void test_verify(struct reg *out, const struct reg *in, void *ctx) +{ + out[RRC].v.i = ed25519_verify(in[RA].v.bytes.p, + in[RM].v.bytes.p, in[RM].v.bytes.sz, + in[RSIGIN].v.bytes.p); +} + +static void test_verify_ctx(struct reg *out, const struct reg *in, void *ctx) +{ + const octet *m = in[RM].v.bytes.p; size_t msz = in[RM].v.bytes.sz; + octet h[SHA512_DIGEST_SIZE]; + struct sha512_ctx hctx; + + if (in[RPH].v.i) { + sha512_init_ctx(&hctx); + sha512_process_bytes(m, msz, &hctx); + sha512_finish_ctx(&hctx, h); + m = h; msz = sizeof(h); + } + + out[RRC].v.i = ed25519ctx_verify(in[RA].v.bytes.p, + in[RPH].v.i, + in[RCTX].v.bytes.p, in[RCTX].v.bytes.sz, + m, msz, in[RSIGIN].v.bytes.p); +} + +#define REG_A { "a", RA, ®ty_bytes, 0 } +#define REG_BIGA { "A", RA, ®ty_bytes, 0 } +#define REG_PH { "ph", RPH, ®ty_int, 0 } +#define REG_CTX { "ctx", RCTX, ®ty_bytes, 0 } +#define REG_M { "m", RM, ®ty_bytes, 0 } +#define REG_SIGIN { "sig", RSIGIN, ®ty_bytes, 0 } + +#define REG_SIGOUT { "sig", RSIGOUT, ®ty_bytes, 0 } +#define REG_AOUT { "A", RAOUT, ®ty_bytes, 0 } +#define REG_RC { "rc", RRC, ®ty_int, 0 } +static const struct regdef + pubkey_regs[] = { REG_A, REG_AOUT, REGLIST_END }, + sign_regs[] = { REG_A, REG_M, REG_SIGOUT, REGLIST_END }, + sign_ctx_regs[] = { REG_A, REG_PH, REG_CTX, + REG_M, REG_SIGOUT, REGLIST_END }, + verify_regs[] = { REG_BIGA, REG_M, REG_SIGIN, REG_RC, REGLIST_END }, + verify_ctx_regs[] = { REG_BIGA, REG_PH, REG_CTX, + REG_M, REG_SIGIN, REG_RC, REGLIST_END }; + +static const struct test tests[] = { + { "pubkey", run_test, pubkey_regs, test_pubkey }, + { "sign", run_test, sign_regs, test_sign }, + { "sign-ctx", run_test, sign_ctx_regs, test_sign_ctx }, + { "verify", run_test, verify_regs, test_verify }, + { "verify-ctx", run_test, verify_ctx_regs, test_verify_ctx }, + { 0 } +}; + +int main(void) + { return run_test_suite(NROUT, NREG, sizeof(struct reg), tests, stdin); }