Damien Miller | 8a56dc2 | 2013-12-18 17:48:11 +1100 | [diff] [blame] | 1 | /* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ |
Damien Miller | 5be9d9e | 2013-12-07 11:24:01 +1100 | [diff] [blame] | 2 | |
Damien Miller | 8a56dc2 | 2013-12-18 17:48:11 +1100 | [diff] [blame] | 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 | */ |
Damien Miller | 5be9d9e | 2013-12-07 11:24:01 +1100 | [diff] [blame] | 8 | |
Damien Miller | f104da2 | 2013-12-07 12:37:53 +1100 | [diff] [blame] | 9 | #include "includes.h" |
Damien Miller | 5be9d9e | 2013-12-07 11:24:01 +1100 | [diff] [blame] | 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 | } |