Annotation of src/usr.bin/ssh/ed25519.c, Revision 1.2
1.2 ! djm 1: /* $OpenBSD$ */
1.1 markus 2:
3: /* Public Domain, from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c */
4:
5: #include "crypto_api.h"
6:
7: #include "ge25519.h"
8:
9: static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
10: {
11: unsigned long long i;
12:
13: for (i = 0;i < 32;++i) playground[i] = sm[i];
14: for (i = 32;i < 64;++i) playground[i] = pk[i-32];
15: for (i = 64;i < smlen;++i) playground[i] = sm[i];
16:
17: crypto_hash_sha512(hram,playground,smlen);
18: }
19:
20:
21: int crypto_sign_ed25519_keypair(
22: unsigned char *pk,
23: unsigned char *sk
24: )
25: {
26: sc25519 scsk;
27: ge25519 gepk;
28: unsigned char extsk[64];
29: int i;
30:
31: randombytes(sk, 32);
32: crypto_hash_sha512(extsk, sk, 32);
33: extsk[0] &= 248;
34: extsk[31] &= 127;
35: extsk[31] |= 64;
36:
37: sc25519_from32bytes(&scsk,extsk);
38:
39: ge25519_scalarmult_base(&gepk, &scsk);
40: ge25519_pack(pk, &gepk);
41: for(i=0;i<32;i++)
42: sk[32 + i] = pk[i];
43: return 0;
44: }
45:
46: int crypto_sign_ed25519(
47: unsigned char *sm,unsigned long long *smlen,
48: const unsigned char *m,unsigned long long mlen,
49: const unsigned char *sk
50: )
51: {
52: sc25519 sck, scs, scsk;
53: ge25519 ger;
54: unsigned char r[32];
55: unsigned char s[32];
56: unsigned char extsk[64];
57: unsigned long long i;
58: unsigned char hmg[crypto_hash_sha512_BYTES];
59: unsigned char hram[crypto_hash_sha512_BYTES];
60:
61: crypto_hash_sha512(extsk, sk, 32);
62: extsk[0] &= 248;
63: extsk[31] &= 127;
64: extsk[31] |= 64;
65:
66: *smlen = mlen+64;
67: for(i=0;i<mlen;i++)
68: sm[64 + i] = m[i];
69: for(i=0;i<32;i++)
70: sm[32 + i] = extsk[32+i];
71:
72: crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */
73:
74: /* Computation of R */
75: sc25519_from64bytes(&sck, hmg);
76: ge25519_scalarmult_base(&ger, &sck);
77: ge25519_pack(r, &ger);
78:
79: /* Computation of s */
80: for(i=0;i<32;i++)
81: sm[i] = r[i];
82:
83: get_hram(hram, sm, sk+32, sm, mlen+64);
84:
85: sc25519_from64bytes(&scs, hram);
86: sc25519_from32bytes(&scsk, extsk);
87: sc25519_mul(&scs, &scs, &scsk);
88:
89: sc25519_add(&scs, &scs, &sck);
90:
91: sc25519_to32bytes(s,&scs); /* cat s */
92: for(i=0;i<32;i++)
93: sm[32 + i] = s[i];
94:
95: return 0;
96: }
97:
98: int crypto_sign_ed25519_open(
99: unsigned char *m,unsigned long long *mlen,
100: const unsigned char *sm,unsigned long long smlen,
101: const unsigned char *pk
102: )
103: {
104: unsigned int i;
105: int ret;
106: unsigned char t2[32];
107: ge25519 get1, get2;
108: sc25519 schram, scs;
109: unsigned char hram[crypto_hash_sha512_BYTES];
110:
111: *mlen = (unsigned long long) -1;
112: if (smlen < 64) return -1;
113:
114: if (ge25519_unpackneg_vartime(&get1, pk)) return -1;
115:
116: get_hram(hram,sm,pk,m,smlen);
117:
118: sc25519_from64bytes(&schram, hram);
119:
120: sc25519_from32bytes(&scs, sm+32);
121:
122: ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
123: ge25519_pack(t2, &get2);
124:
125: ret = crypto_verify_32(sm, t2);
126:
127: if (!ret)
128: {
129: for(i=0;i<smlen-64;i++)
130: m[i] = sm[i + 64];
131: *mlen = smlen-64;
132: }
133: else
134: {
135: for(i=0;i<smlen-64;i++)
136: m[i] = 0;
137: }
138: return ret;
139: }