ted25519.c - sick - sign and check files using ed25519
(HTM) git clone git://z3bra.org/sick
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
ted25519.c (2950B)
---
1 /*
2 * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
3 * Peter Schwabe, Bo-Yin Yang.
4 * Adapted from supercop-20230530/crypto_sign/ed25519/ref/keypair.c
5 * supercop-20230530/crypto_sign/ed25519/ref/sign.c
6 * supercop-20230530/crypto_sign/ed25519/ref/open.c
7 */
8
9 #include <stdlib.h>
10
11 #include "string.h"
12 #include "crypto_api.h"
13 #include "ge25519.h"
14
15 int crypto_sign_ed25519_keypair(unsigned char *pk,unsigned char *sk)
16 {
17 unsigned char az[64];
18 sc25519 scsk;
19 ge25519 gepk;
20
21 randombytes(sk,32);
22 crypto_hash_sha512(az,sk,32);
23 az[0] &= 248;
24 az[31] &= 127;
25 az[31] |= 64;
26
27 sc25519_from32bytes(&scsk,az);
28
29 ge25519_scalarmult_base(&gepk, &scsk);
30 ge25519_pack(pk, &gepk);
31 memmove(sk + 32,pk,32);
32 return 0;
33 }
34
35 int crypto_sign_ed25519(
36 unsigned char *sm,unsigned long long *smlen,
37 const unsigned char *m,unsigned long long mlen,
38 const unsigned char *sk
39 )
40 {
41 unsigned char pk[32];
42 unsigned char az[64];
43 unsigned char nonce[64];
44 unsigned char hram[64];
45 sc25519 sck, scs, scsk;
46 ge25519 ger;
47
48 memmove(pk,sk + 32,32);
49 /* pk: 32-byte public key A */
50
51 crypto_hash_sha512(az,sk,32);
52 az[0] &= 248;
53 az[31] &= 127;
54 az[31] |= 64;
55 /* az: 32-byte scalar a, 32-byte randomizer z */
56
57 *smlen = mlen + 64;
58 memmove(sm + 64,m,mlen);
59 memmove(sm + 32,az + 32,32);
60 /* sm: 32-byte uninit, 32-byte z, mlen-byte m */
61
62 crypto_hash_sha512(nonce, sm+32, mlen+32);
63 /* nonce: 64-byte H(z,m) */
64
65 sc25519_from64bytes(&sck, nonce);
66 ge25519_scalarmult_base(&ger, &sck);
67 ge25519_pack(sm, &ger);
68 /* sm: 32-byte R, 32-byte z, mlen-byte m */
69
70 memmove(sm + 32,pk,32);
71 /* sm: 32-byte R, 32-byte A, mlen-byte m */
72
73 crypto_hash_sha512(hram,sm,mlen + 64);
74 /* hram: 64-byte H(R,A,m) */
75
76 sc25519_from64bytes(&scs, hram);
77 sc25519_from32bytes(&scsk, az);
78 sc25519_mul(&scs, &scs, &scsk);
79 sc25519_add(&scs, &scs, &sck);
80 /* scs: S = nonce + H(R,A,m)a */
81
82 sc25519_to32bytes(sm + 32,&scs);
83 /* sm: 32-byte R, 32-byte S, mlen-byte m */
84
85 return 0;
86 }
87
88
89 int crypto_sign_ed25519_open(
90 unsigned char *m,unsigned long long *mlen,
91 const unsigned char *sm,unsigned long long smlen,
92 const unsigned char *pk
93 )
94 {
95 unsigned char pkcopy[32];
96 unsigned char rcopy[32];
97 unsigned char hram[64];
98 unsigned char rcheck[32];
99 ge25519 get1, get2;
100 sc25519 schram, scs;
101
102 if (smlen < 64) goto badsig;
103 if (sm[63] & 224) goto badsig;
104 if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig;
105
106 memmove(pkcopy,pk,32);
107 memmove(rcopy,sm,32);
108
109 sc25519_from32bytes(&scs, sm+32);
110
111 memmove(m,sm,smlen);
112 memmove(m + 32,pkcopy,32);
113 crypto_hash_sha512(hram,m,smlen);
114
115 sc25519_from64bytes(&schram, hram);
116
117 ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
118 ge25519_pack(rcheck, &get2);
119
120 if (crypto_verify_32(rcopy,rcheck) == 0) {
121 memmove(m,m + 64,smlen - 64);
122 memset(m + smlen - 64,0,64);
123 *mlen = smlen - 64;
124 return 0;
125 }
126
127 badsig:
128 *mlen = (unsigned long long) -1;
129 memset(m,0,smlen);
130 return -1;
131 }