diff options
Diffstat (limited to 'ed25519.c')
-rw-r--r-- | ed25519.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/ed25519.c b/ed25519.c new file mode 100644 index 000000000..767ec24d6 --- /dev/null +++ b/ed25519.c | |||
@@ -0,0 +1,144 @@ | |||
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 | } | ||