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 |
} |