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