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