1*1c60b9acSAndroid Build Coastguard Worker /* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard Worker /*
4*1c60b9acSAndroid Build Coastguard Worker * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
5*1c60b9acSAndroid Build Coastguard Worker * Peter Schwabe, Bo-Yin Yang.
6*1c60b9acSAndroid Build Coastguard Worker * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c
7*1c60b9acSAndroid Build Coastguard Worker *
8*1c60b9acSAndroid Build Coastguard Worker * Modified to use lws genhash by Andy Green <[email protected]>
9*1c60b9acSAndroid Build Coastguard Worker */
10*1c60b9acSAndroid Build Coastguard Worker
11*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
12*1c60b9acSAndroid Build Coastguard Worker #include <lws-ssh.h>
13*1c60b9acSAndroid Build Coastguard Worker #include "ge25519.h"
14*1c60b9acSAndroid Build Coastguard Worker
15*1c60b9acSAndroid Build Coastguard Worker int
crypto_hash_sha512(uint8_t * hash64,const uint8_t * data,size_t len)16*1c60b9acSAndroid Build Coastguard Worker crypto_hash_sha512(uint8_t *hash64, const uint8_t *data, size_t len)
17*1c60b9acSAndroid Build Coastguard Worker {
18*1c60b9acSAndroid Build Coastguard Worker struct lws_genhash_ctx ctx;
19*1c60b9acSAndroid Build Coastguard Worker int ret;
20*1c60b9acSAndroid Build Coastguard Worker
21*1c60b9acSAndroid Build Coastguard Worker if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA512)) {
22*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("Failed to init SHA512\n");
23*1c60b9acSAndroid Build Coastguard Worker return 0;
24*1c60b9acSAndroid Build Coastguard Worker }
25*1c60b9acSAndroid Build Coastguard Worker
26*1c60b9acSAndroid Build Coastguard Worker ret = lws_genhash_update(&ctx, data, len);
27*1c60b9acSAndroid Build Coastguard Worker
28*1c60b9acSAndroid Build Coastguard Worker if (lws_genhash_destroy(&ctx, hash64))
29*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("genhash destroy failed\n");
30*1c60b9acSAndroid Build Coastguard Worker
31*1c60b9acSAndroid Build Coastguard Worker return ret ? 0 : 64;
32*1c60b9acSAndroid Build Coastguard Worker }
33*1c60b9acSAndroid Build Coastguard Worker
34*1c60b9acSAndroid Build Coastguard Worker
35*1c60b9acSAndroid Build Coastguard Worker static void
get_hram(unsigned char * hram,const unsigned char * sm,const unsigned char * pk,unsigned char * playground,size_t smlen)36*1c60b9acSAndroid Build Coastguard Worker get_hram(unsigned char *hram, const unsigned char *sm,
37*1c60b9acSAndroid Build Coastguard Worker const unsigned char *pk, unsigned char *playground,
38*1c60b9acSAndroid Build Coastguard Worker size_t smlen)
39*1c60b9acSAndroid Build Coastguard Worker {
40*1c60b9acSAndroid Build Coastguard Worker unsigned long long i;
41*1c60b9acSAndroid Build Coastguard Worker
42*1c60b9acSAndroid Build Coastguard Worker for (i = 0; i < 32; ++i)
43*1c60b9acSAndroid Build Coastguard Worker playground[i] = sm[i];
44*1c60b9acSAndroid Build Coastguard Worker for (i = 32; i < 64; ++i)
45*1c60b9acSAndroid Build Coastguard Worker playground[i] = pk[i-32];
46*1c60b9acSAndroid Build Coastguard Worker for (i = 64; i < smlen; ++i)
47*1c60b9acSAndroid Build Coastguard Worker playground[i] = sm[i];
48*1c60b9acSAndroid Build Coastguard Worker
49*1c60b9acSAndroid Build Coastguard Worker crypto_hash_sha512(hram, playground, smlen);
50*1c60b9acSAndroid Build Coastguard Worker }
51*1c60b9acSAndroid Build Coastguard Worker
52*1c60b9acSAndroid Build Coastguard Worker
crypto_sign_ed25519_keypair(struct lws_context * context,unsigned char * pk,unsigned char * sk)53*1c60b9acSAndroid Build Coastguard Worker int crypto_sign_ed25519_keypair(
54*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context,
55*1c60b9acSAndroid Build Coastguard Worker unsigned char *pk,
56*1c60b9acSAndroid Build Coastguard Worker unsigned char *sk
57*1c60b9acSAndroid Build Coastguard Worker )
58*1c60b9acSAndroid Build Coastguard Worker {
59*1c60b9acSAndroid Build Coastguard Worker sc25519 scsk;
60*1c60b9acSAndroid Build Coastguard Worker ge25519 gepk;
61*1c60b9acSAndroid Build Coastguard Worker unsigned char extsk[64];
62*1c60b9acSAndroid Build Coastguard Worker int i;
63*1c60b9acSAndroid Build Coastguard Worker
64*1c60b9acSAndroid Build Coastguard Worker lws_get_random(context, sk, 32);
65*1c60b9acSAndroid Build Coastguard Worker crypto_hash_sha512(extsk, sk, 32);
66*1c60b9acSAndroid Build Coastguard Worker extsk[0] &= 248;
67*1c60b9acSAndroid Build Coastguard Worker extsk[31] &= 127;
68*1c60b9acSAndroid Build Coastguard Worker extsk[31] |= 64;
69*1c60b9acSAndroid Build Coastguard Worker
70*1c60b9acSAndroid Build Coastguard Worker sc25519_from32bytes(&scsk,extsk);
71*1c60b9acSAndroid Build Coastguard Worker
72*1c60b9acSAndroid Build Coastguard Worker ge25519_scalarmult_base(&gepk, &scsk);
73*1c60b9acSAndroid Build Coastguard Worker ge25519_pack(pk, &gepk);
74*1c60b9acSAndroid Build Coastguard Worker for(i=0;i<32;i++)
75*1c60b9acSAndroid Build Coastguard Worker sk[32 + i] = pk[i];
76*1c60b9acSAndroid Build Coastguard Worker return 0;
77*1c60b9acSAndroid Build Coastguard Worker }
78*1c60b9acSAndroid Build Coastguard Worker
crypto_sign_ed25519(unsigned char * sm,unsigned long long * smlen,const unsigned char * m,size_t mlen,const unsigned char * sk)79*1c60b9acSAndroid Build Coastguard Worker int crypto_sign_ed25519(
80*1c60b9acSAndroid Build Coastguard Worker unsigned char *sm,
81*1c60b9acSAndroid Build Coastguard Worker unsigned long long *smlen,
82*1c60b9acSAndroid Build Coastguard Worker const unsigned char *m, size_t mlen,
83*1c60b9acSAndroid Build Coastguard Worker const unsigned char *sk
84*1c60b9acSAndroid Build Coastguard Worker )
85*1c60b9acSAndroid Build Coastguard Worker {
86*1c60b9acSAndroid Build Coastguard Worker sc25519 sck, scs, scsk;
87*1c60b9acSAndroid Build Coastguard Worker ge25519 ger;
88*1c60b9acSAndroid Build Coastguard Worker unsigned char r[32];
89*1c60b9acSAndroid Build Coastguard Worker unsigned char s[32];
90*1c60b9acSAndroid Build Coastguard Worker unsigned char extsk[64];
91*1c60b9acSAndroid Build Coastguard Worker unsigned long long i;
92*1c60b9acSAndroid Build Coastguard Worker unsigned char hmg[crypto_hash_sha512_BYTES];
93*1c60b9acSAndroid Build Coastguard Worker unsigned char hram[crypto_hash_sha512_BYTES];
94*1c60b9acSAndroid Build Coastguard Worker
95*1c60b9acSAndroid Build Coastguard Worker crypto_hash_sha512(extsk, sk, 32);
96*1c60b9acSAndroid Build Coastguard Worker extsk[0] &= 248;
97*1c60b9acSAndroid Build Coastguard Worker extsk[31] &= 127;
98*1c60b9acSAndroid Build Coastguard Worker extsk[31] |= 64;
99*1c60b9acSAndroid Build Coastguard Worker
100*1c60b9acSAndroid Build Coastguard Worker *smlen = mlen+64;
101*1c60b9acSAndroid Build Coastguard Worker for(i=0;i<mlen;i++)
102*1c60b9acSAndroid Build Coastguard Worker sm[64 + i] = m[i];
103*1c60b9acSAndroid Build Coastguard Worker for(i=0;i<32;i++)
104*1c60b9acSAndroid Build Coastguard Worker sm[32 + i] = extsk[32+i];
105*1c60b9acSAndroid Build Coastguard Worker
106*1c60b9acSAndroid Build Coastguard Worker crypto_hash_sha512(hmg, sm+32, mlen+32);
107*1c60b9acSAndroid Build Coastguard Worker /* Generate k as h(extsk[32],...,extsk[63],m) */
108*1c60b9acSAndroid Build Coastguard Worker
109*1c60b9acSAndroid Build Coastguard Worker /* Computation of R */
110*1c60b9acSAndroid Build Coastguard Worker sc25519_from64bytes(&sck, hmg);
111*1c60b9acSAndroid Build Coastguard Worker ge25519_scalarmult_base(&ger, &sck);
112*1c60b9acSAndroid Build Coastguard Worker ge25519_pack(r, &ger);
113*1c60b9acSAndroid Build Coastguard Worker
114*1c60b9acSAndroid Build Coastguard Worker /* Computation of s */
115*1c60b9acSAndroid Build Coastguard Worker for (i = 0; i < 32; i++)
116*1c60b9acSAndroid Build Coastguard Worker sm[i] = r[i];
117*1c60b9acSAndroid Build Coastguard Worker
118*1c60b9acSAndroid Build Coastguard Worker get_hram(hram, sm, sk + 32, sm, (size_t)mlen + 64);
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker sc25519_from64bytes(&scs, hram);
121*1c60b9acSAndroid Build Coastguard Worker sc25519_from32bytes(&scsk, extsk);
122*1c60b9acSAndroid Build Coastguard Worker sc25519_mul(&scs, &scs, &scsk);
123*1c60b9acSAndroid Build Coastguard Worker
124*1c60b9acSAndroid Build Coastguard Worker sc25519_add(&scs, &scs, &sck);
125*1c60b9acSAndroid Build Coastguard Worker
126*1c60b9acSAndroid Build Coastguard Worker sc25519_to32bytes(s,&scs); /* cat s */
127*1c60b9acSAndroid Build Coastguard Worker for (i = 0; i < 32; i++)
128*1c60b9acSAndroid Build Coastguard Worker sm[32 + i] = s[i];
129*1c60b9acSAndroid Build Coastguard Worker
130*1c60b9acSAndroid Build Coastguard Worker return 0;
131*1c60b9acSAndroid Build Coastguard Worker }
132*1c60b9acSAndroid Build Coastguard Worker
crypto_verify_32(const unsigned char * x,const unsigned char * y)133*1c60b9acSAndroid Build Coastguard Worker int crypto_verify_32(const unsigned char *x,const unsigned char *y)
134*1c60b9acSAndroid Build Coastguard Worker {
135*1c60b9acSAndroid Build Coastguard Worker unsigned int differentbits = 0;
136*1c60b9acSAndroid Build Coastguard Worker #define F(i) differentbits |= x[i] ^ y[i];
137*1c60b9acSAndroid Build Coastguard Worker F(0)
138*1c60b9acSAndroid Build Coastguard Worker F(1)
139*1c60b9acSAndroid Build Coastguard Worker F(2)
140*1c60b9acSAndroid Build Coastguard Worker F(3)
141*1c60b9acSAndroid Build Coastguard Worker F(4)
142*1c60b9acSAndroid Build Coastguard Worker F(5)
143*1c60b9acSAndroid Build Coastguard Worker F(6)
144*1c60b9acSAndroid Build Coastguard Worker F(7)
145*1c60b9acSAndroid Build Coastguard Worker F(8)
146*1c60b9acSAndroid Build Coastguard Worker F(9)
147*1c60b9acSAndroid Build Coastguard Worker F(10)
148*1c60b9acSAndroid Build Coastguard Worker F(11)
149*1c60b9acSAndroid Build Coastguard Worker F(12)
150*1c60b9acSAndroid Build Coastguard Worker F(13)
151*1c60b9acSAndroid Build Coastguard Worker F(14)
152*1c60b9acSAndroid Build Coastguard Worker F(15)
153*1c60b9acSAndroid Build Coastguard Worker F(16)
154*1c60b9acSAndroid Build Coastguard Worker F(17)
155*1c60b9acSAndroid Build Coastguard Worker F(18)
156*1c60b9acSAndroid Build Coastguard Worker F(19)
157*1c60b9acSAndroid Build Coastguard Worker F(20)
158*1c60b9acSAndroid Build Coastguard Worker F(21)
159*1c60b9acSAndroid Build Coastguard Worker F(22)
160*1c60b9acSAndroid Build Coastguard Worker F(23)
161*1c60b9acSAndroid Build Coastguard Worker F(24)
162*1c60b9acSAndroid Build Coastguard Worker F(25)
163*1c60b9acSAndroid Build Coastguard Worker F(26)
164*1c60b9acSAndroid Build Coastguard Worker F(27)
165*1c60b9acSAndroid Build Coastguard Worker F(28)
166*1c60b9acSAndroid Build Coastguard Worker F(29)
167*1c60b9acSAndroid Build Coastguard Worker F(30)
168*1c60b9acSAndroid Build Coastguard Worker F(31)
169*1c60b9acSAndroid Build Coastguard Worker return (int)((1 & ((differentbits - 1) >> 8)) - 1);
170*1c60b9acSAndroid Build Coastguard Worker }
171*1c60b9acSAndroid Build Coastguard Worker
crypto_sign_ed25519_open(unsigned char * m,unsigned long long * mlen,const unsigned char * sm,unsigned long long smlen,const unsigned char * pk)172*1c60b9acSAndroid Build Coastguard Worker int crypto_sign_ed25519_open(
173*1c60b9acSAndroid Build Coastguard Worker unsigned char *m,unsigned long long *mlen,
174*1c60b9acSAndroid Build Coastguard Worker const unsigned char *sm,unsigned long long smlen,
175*1c60b9acSAndroid Build Coastguard Worker const unsigned char *pk
176*1c60b9acSAndroid Build Coastguard Worker )
177*1c60b9acSAndroid Build Coastguard Worker {
178*1c60b9acSAndroid Build Coastguard Worker unsigned int i;
179*1c60b9acSAndroid Build Coastguard Worker int ret;
180*1c60b9acSAndroid Build Coastguard Worker unsigned char t2[32];
181*1c60b9acSAndroid Build Coastguard Worker ge25519 get1, get2;
182*1c60b9acSAndroid Build Coastguard Worker sc25519 schram, scs;
183*1c60b9acSAndroid Build Coastguard Worker unsigned char hram[crypto_hash_sha512_BYTES];
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker *mlen = (unsigned long long) -1;
186*1c60b9acSAndroid Build Coastguard Worker if (smlen < 64) {
187*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("a\n");
188*1c60b9acSAndroid Build Coastguard Worker
189*1c60b9acSAndroid Build Coastguard Worker return -1;
190*1c60b9acSAndroid Build Coastguard Worker }
191*1c60b9acSAndroid Build Coastguard Worker
192*1c60b9acSAndroid Build Coastguard Worker if (ge25519_unpackneg_vartime(&get1, pk)) {
193*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("b\n");
194*1c60b9acSAndroid Build Coastguard Worker return -1;
195*1c60b9acSAndroid Build Coastguard Worker }
196*1c60b9acSAndroid Build Coastguard Worker
197*1c60b9acSAndroid Build Coastguard Worker get_hram(hram,sm,pk,m, (size_t)smlen);
198*1c60b9acSAndroid Build Coastguard Worker
199*1c60b9acSAndroid Build Coastguard Worker sc25519_from64bytes(&schram, hram);
200*1c60b9acSAndroid Build Coastguard Worker
201*1c60b9acSAndroid Build Coastguard Worker sc25519_from32bytes(&scs, sm+32);
202*1c60b9acSAndroid Build Coastguard Worker
203*1c60b9acSAndroid Build Coastguard Worker ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
204*1c60b9acSAndroid Build Coastguard Worker ge25519_pack(t2, &get2);
205*1c60b9acSAndroid Build Coastguard Worker
206*1c60b9acSAndroid Build Coastguard Worker ret = crypto_verify_32(sm, t2);
207*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("vf says %d\n", ret);
208*1c60b9acSAndroid Build Coastguard Worker
209*1c60b9acSAndroid Build Coastguard Worker if (!ret)
210*1c60b9acSAndroid Build Coastguard Worker {
211*1c60b9acSAndroid Build Coastguard Worker for(i=0;i<smlen-64;i++)
212*1c60b9acSAndroid Build Coastguard Worker m[i] = sm[i + 64];
213*1c60b9acSAndroid Build Coastguard Worker *mlen = smlen-64;
214*1c60b9acSAndroid Build Coastguard Worker }
215*1c60b9acSAndroid Build Coastguard Worker else
216*1c60b9acSAndroid Build Coastguard Worker {
217*1c60b9acSAndroid Build Coastguard Worker for(i=0;i<smlen-64;i++)
218*1c60b9acSAndroid Build Coastguard Worker m[i] = 0;
219*1c60b9acSAndroid Build Coastguard Worker }
220*1c60b9acSAndroid Build Coastguard Worker return ret;
221*1c60b9acSAndroid Build Coastguard Worker }
222