ed25519.c revision 1.2
1/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ 2 3/* 4 * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 * Peter Schwabe, Bo-Yin Yang. 6 * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c 7 */ 8#include "includes.h" 9__RCSID("$NetBSD: ed25519.c,v 1.2 2014/10/19 16:30:58 christos Exp $"); 10 11#include "crypto_api.h" 12 13#include "ge25519.h" 14 15static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) 16{ 17 unsigned long long i; 18 19 for (i = 0;i < 32;++i) playground[i] = sm[i]; 20 for (i = 32;i < 64;++i) playground[i] = pk[i-32]; 21 for (i = 64;i < smlen;++i) playground[i] = sm[i]; 22 23 crypto_hash_sha512(hram,playground,smlen); 24} 25 26 27int crypto_sign_ed25519_keypair( 28 unsigned char *pk, 29 unsigned char *sk 30 ) 31{ 32 sc25519 scsk; 33 ge25519 gepk; 34 unsigned char extsk[64]; 35 int i; 36 37 randombytes(sk, 32); 38 crypto_hash_sha512(extsk, sk, 32); 39 extsk[0] &= 248; 40 extsk[31] &= 127; 41 extsk[31] |= 64; 42 43 sc25519_from32bytes(&scsk,extsk); 44 45 ge25519_scalarmult_base(&gepk, &scsk); 46 ge25519_pack(pk, &gepk); 47 for(i=0;i<32;i++) 48 sk[32 + i] = pk[i]; 49 return 0; 50} 51 52int crypto_sign_ed25519( 53 unsigned char *sm,unsigned long long *smlen, 54 const unsigned char *m,unsigned long long mlen, 55 const unsigned char *sk 56 ) 57{ 58 sc25519 sck, scs, scsk; 59 ge25519 ger; 60 unsigned char r[32]; 61 unsigned char s[32]; 62 unsigned char extsk[64]; 63 unsigned long long i; 64 unsigned char hmg[crypto_hash_sha512_BYTES]; 65 unsigned char hram[crypto_hash_sha512_BYTES]; 66 67 crypto_hash_sha512(extsk, sk, 32); 68 extsk[0] &= 248; 69 extsk[31] &= 127; 70 extsk[31] |= 64; 71 72 *smlen = mlen+64; 73 for(i=0;i<mlen;i++) 74 sm[64 + i] = m[i]; 75 for(i=0;i<32;i++) 76 sm[32 + i] = extsk[32+i]; 77 78 crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */ 79 80 /* Computation of R */ 81 sc25519_from64bytes(&sck, hmg); 82 ge25519_scalarmult_base(&ger, &sck); 83 ge25519_pack(r, &ger); 84 85 /* Computation of s */ 86 for(i=0;i<32;i++) 87 sm[i] = r[i]; 88 89 get_hram(hram, sm, sk+32, sm, mlen+64); 90 91 sc25519_from64bytes(&scs, hram); 92 sc25519_from32bytes(&scsk, extsk); 93 sc25519_mul(&scs, &scs, &scsk); 94 95 sc25519_add(&scs, &scs, &sck); 96 97 sc25519_to32bytes(s,&scs); /* cat s */ 98 for(i=0;i<32;i++) 99 sm[32 + i] = s[i]; 100 101 return 0; 102} 103 104int crypto_sign_ed25519_open( 105 unsigned char *m,unsigned long long *mlen, 106 const unsigned char *sm,unsigned long long smlen, 107 const unsigned char *pk 108 ) 109{ 110 unsigned int i; 111 int ret; 112 unsigned char t2[32]; 113 ge25519 get1, get2; 114 sc25519 schram, scs; 115 unsigned char hram[crypto_hash_sha512_BYTES]; 116 117 *mlen = (unsigned long long) -1; 118 if (smlen < 64) return -1; 119 120 if (ge25519_unpackneg_vartime(&get1, pk)) return -1; 121 122 get_hram(hram,sm,pk,m,smlen); 123 124 sc25519_from64bytes(&schram, hram); 125 126 sc25519_from32bytes(&scs, sm+32); 127 128 ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); 129 ge25519_pack(t2, &get2); 130 131 ret = crypto_verify_32(sm, t2); 132 133 if (!ret) 134 { 135 for(i=0;i<smlen-64;i++) 136 m[i] = sm[i + 64]; 137 *mlen = smlen-64; 138 } 139 else 140 { 141 for(i=0;i<smlen-64;i++) 142 m[i] = 0; 143 } 144 return ret; 145} 146