From a47ab75afd236ddb02ee467210cbdeeeba9dbff6 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 25 Sep 2019 21:13:09 +0100 Subject: [PATCH] @@@ ed25519 --- Makefile.in | 11 ++++- crypto-test.c | 5 ++ ed25519-test.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 ed25519-test.c diff --git a/Makefile.in b/Makefile.in index 7b58f75..4ec557f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,7 +62,7 @@ OBJECTS:=secnet.o util.o conffile.yy.o conffile.tab.o conffile.o modules.o \ resolver.o random.o udp.o site.o transform-cbcmac.o transform-eax.o \ comm-common.o polypath.o \ netlink.o rsa.o dh.o xdh.o serpent.o serpentbe.o \ - f25519.o x25519.o fgoldi.o x448.o \ + scaf.o f25519.o x25519.o ed25519.o fgoldi.o x448.o \ md5.o sha512.o tun.o slip.o sha1.o ipaddr.o log.o \ process.o @LIBOBJS@ \ hackypar.o @@ -147,7 +147,7 @@ endif check: eax-aes-test.confirm eax-serpent-test.confirm \ eax-serpentbe-test.confirm check-ipaddrset \ msgcode-test.confirm \ - f25519-test.confirm x25519-test.confirm \ + f25519-test.confirm x25519-test.confirm ed25519-test.confirm \ fgoldi-test.confirm x448-test.confirm version.c: Makefile @@ -202,6 +202,13 @@ $(addsuffix -test.confirm, $(XDH_FUNCS) $(XDH_FIELDS)): \ ./$*-test <$(srcdir)/$*-tests.in touch $@ +ed25519-test: ed25519-test.o sha512.o f25519.o scaf.o ed25519.o crypto-test.o + $(CC) $(LDFLAGS) $(ALL_CFLAGS) -o $@ $^ + +ed25519-test.confirm: ed25519-test ed25519-tests.in + ./ed25519-test <$(srcdir)/ed25519-tests.in + touch $@ + check-ipaddrset: ipaddrset-test.py ipaddrset.py ipaddrset-test.expected $(srcdir)/ipaddrset-test.py >ipaddrset-test.new diff -u $(srcdir)/ipaddrset-test.expected ipaddrset-test.new diff --git a/crypto-test.c b/crypto-test.c index 137f7a3..cb081de 100644 --- a/crypto-test.c +++ b/crypto-test.c @@ -146,6 +146,11 @@ void trivial_regty_release(union regval *v) { ; } uint64_t now_global; struct timeval tv_now_global; +/* Bletch. sha512.c wants to drag in the world. */ +void *safe_malloc(size_t size, const char *message) { return xmalloc(size); } +list_t *new_closure(closure_t *cl) { abort(); } +void dict_add(dict_t *dict, cstring_t key, list_t *val) { abort(); } + /* Bletch. util.c is a mess of layers. */ int consttime_memeq(const void *s1in, const void *s2in, size_t n) { 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); } -- 2.11.0