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