/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c * * Modified to use lws genhash by Andy Green */ #include #include #include "ge25519.h" int crypto_hash_sha512(uint8_t *hash64, const uint8_t *data, size_t len) { struct lws_genhash_ctx ctx; int ret; if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA512)) { lwsl_notice("Failed to init SHA512\n"); return 0; } ret = lws_genhash_update(&ctx, data, len); if (lws_genhash_destroy(&ctx, hash64)) lwsl_notice("genhash destroy failed\n"); return ret ? 0 : 64; } static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, size_t smlen) { unsigned long long i; for (i = 0; i < 32; ++i) playground[i] = sm[i]; for (i = 32; i < 64; ++i) playground[i] = pk[i-32]; for (i = 64; i < smlen; ++i) playground[i] = sm[i]; crypto_hash_sha512(hram, playground, smlen); } int crypto_sign_ed25519_keypair( struct lws_context *context, unsigned char *pk, unsigned char *sk ) { sc25519 scsk; ge25519 gepk; unsigned char extsk[64]; int i; lws_get_random(context, sk, 32); crypto_hash_sha512(extsk, sk, 32); extsk[0] &= 248; extsk[31] &= 127; extsk[31] |= 64; sc25519_from32bytes(&scsk,extsk); ge25519_scalarmult_base(&gepk, &scsk); ge25519_pack(pk, &gepk); for(i=0;i<32;i++) sk[32 + i] = pk[i]; return 0; } int crypto_sign_ed25519( unsigned char *sm, unsigned long long *smlen, const unsigned char *m, size_t mlen, const unsigned char *sk ) { sc25519 sck, scs, scsk; ge25519 ger; unsigned char r[32]; unsigned char s[32]; unsigned char extsk[64]; unsigned long long i; unsigned char hmg[crypto_hash_sha512_BYTES]; unsigned char hram[crypto_hash_sha512_BYTES]; crypto_hash_sha512(extsk, sk, 32); extsk[0] &= 248; extsk[31] &= 127; extsk[31] |= 64; *smlen = mlen+64; for(i=0;i> 8)) - 1; } int crypto_sign_ed25519_open( unsigned char *m,unsigned long long *mlen, const unsigned char *sm,unsigned long long smlen, const unsigned char *pk ) { unsigned int i; int ret; unsigned char t2[32]; ge25519 get1, get2; sc25519 schram, scs; unsigned char hram[crypto_hash_sha512_BYTES]; *mlen = (unsigned long long) -1; if (smlen < 64) { lwsl_notice("a\n"); return -1; } if (ge25519_unpackneg_vartime(&get1, pk)) { lwsl_notice("b\n"); return -1; } get_hram(hram,sm,pk,m, (size_t)smlen); sc25519_from64bytes(&schram, hram); sc25519_from32bytes(&scs, sm+32); ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); ge25519_pack(t2, &get2); ret = crypto_verify_32(sm, t2); lwsl_notice("vf says %d\n", ret); if (!ret) { for(i=0;i