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 |
|
10 |
sc25519 scsk; |
31 |
|
5 |
ge25519 gepk; |
32 |
|
5 |
unsigned char extsk[64]; |
33 |
|
|
int i; |
34 |
|
|
|
35 |
|
5 |
randombytes(sk, 32); |
36 |
|
5 |
crypto_hash_sha512(extsk, sk, 32); |
37 |
|
5 |
extsk[0] &= 248; |
38 |
|
5 |
extsk[31] &= 127; |
39 |
|
5 |
extsk[31] |= 64; |
40 |
|
|
|
41 |
|
5 |
sc25519_from32bytes(&scsk,extsk); |
42 |
|
|
|
43 |
|
5 |
ge25519_scalarmult_base(&gepk, &scsk); |
44 |
|
5 |
ge25519_pack(pk, &gepk); |
45 |
✓✓ |
330 |
for(i=0;i<32;i++) |
46 |
|
160 |
sk[32 + i] = pk[i]; |
47 |
|
5 |
return 0; |
48 |
|
5 |
} |
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 |
|
|
} |