1 | #include "crypto_sign.h" |
---|
2 | |
---|
3 | #include "crypto_verify_32.h" |
---|
4 | #include "sha512.h" |
---|
5 | |
---|
6 | #include "ge25519.h" |
---|
7 | |
---|
8 | static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) |
---|
9 | { |
---|
10 | unsigned long long i; |
---|
11 | |
---|
12 | for (i = 0;i < 32;++i) playground[i] = sm[i]; |
---|
13 | for (i = 32;i < 64;++i) playground[i] = pk[i-32]; |
---|
14 | for (i = 64;i < smlen;++i) playground[i] = sm[i]; |
---|
15 | |
---|
16 | crypto_hash_sha512(hram,playground,smlen); |
---|
17 | } |
---|
18 | |
---|
19 | |
---|
20 | int crypto_sign_publickey( |
---|
21 | unsigned char *pk, // write 32 bytes into this |
---|
22 | unsigned char *sk, // write 64 bytes into this (seed+pubkey) |
---|
23 | unsigned char *seed // 32 bytes |
---|
24 | ) |
---|
25 | { |
---|
26 | sc25519 scsk; |
---|
27 | ge25519 gepk; |
---|
28 | int i; |
---|
29 | |
---|
30 | crypto_hash_sha512(sk, seed, 32); |
---|
31 | sk[0] &= 248; |
---|
32 | sk[31] &= 127; |
---|
33 | sk[31] |= 64; |
---|
34 | |
---|
35 | sc25519_from32bytes(&scsk,sk); |
---|
36 | |
---|
37 | ge25519_scalarmult_base(&gepk, &scsk); |
---|
38 | ge25519_pack(pk, &gepk); |
---|
39 | for(i=0;i<32;i++) |
---|
40 | sk[32 + i] = pk[i]; |
---|
41 | for(i=0;i<32;i++) |
---|
42 | sk[i] = seed[i]; |
---|
43 | return 0; |
---|
44 | } |
---|
45 | |
---|
46 | int crypto_sign( |
---|
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_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 | int i, ret; |
---|
105 | unsigned char t2[32]; |
---|
106 | ge25519 get1, get2; |
---|
107 | sc25519 schram, scs; |
---|
108 | unsigned char hram[crypto_hash_sha512_BYTES]; |
---|
109 | |
---|
110 | if (ge25519_unpackneg_vartime(&get1, pk)) return -1; |
---|
111 | |
---|
112 | get_hram(hram,sm,pk,m,smlen); |
---|
113 | |
---|
114 | sc25519_from64bytes(&schram, hram); |
---|
115 | |
---|
116 | sc25519_from32bytes(&scs, sm+32); |
---|
117 | |
---|
118 | ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); |
---|
119 | ge25519_pack(t2, &get2); |
---|
120 | |
---|
121 | ret = crypto_verify_32(sm, t2); |
---|
122 | |
---|
123 | if (!ret) |
---|
124 | { |
---|
125 | for(i=0;i<smlen-64;i++) |
---|
126 | m[i] = sm[i + 64]; |
---|
127 | *mlen = smlen-64; |
---|
128 | } |
---|
129 | else |
---|
130 | { |
---|
131 | for(i=0;i<smlen-64;i++) |
---|
132 | m[i] = 0; |
---|
133 | *mlen = (unsigned long long) -1; |
---|
134 | } |
---|
135 | return ret; |
---|
136 | } |
---|