Line data Source code
1 : #ifndef HEADER_fd_src_ballet_ed25519_fd_ed25519_h
2 : #define HEADER_fd_src_ballet_ed25519_fd_ed25519_h
3 :
4 : /* fd_ed25519 provides APIs for ED25519 signature computations */
5 :
6 : #include "../sha512/fd_sha512.h"
7 :
8 : /* FD_ED25519_ERR_* gives a number of error codes used by fd_ed25519
9 : APIs. */
10 :
11 2269 : #define FD_ED25519_SUCCESS ( 0) /* Operation was successful */
12 972 : #define FD_ED25519_ERR_SIG (-1) /* Operation failed because the signature was obviously invalid */
13 1070 : #define FD_ED25519_ERR_PUBKEY (-2) /* Operation failed because the public key was obviously invalid */
14 141 : #define FD_ED25519_ERR_MSG (-3) /* Operation failed because the message didn't match the signature for the given key */
15 :
16 : /* FD_ED25519_SIG_SZ: the size of an Ed25519 signature in bytes. */
17 150897 : #define FD_ED25519_SIG_SZ (64UL)
18 :
19 : /* An Ed25519 signature. */
20 : typedef uchar fd_ed25519_sig_t[ FD_ED25519_SIG_SZ ];
21 :
22 : FD_PROTOTYPES_BEGIN
23 :
24 : /* fd_ed25519_public_from_private computes the public_key corresponding
25 : to the given private key.
26 :
27 : public_key is assumed to point to the first byte of a 32-byte memory
28 : region which will hold the public key on return.
29 :
30 : private_key assumed to point to first byte of a 32-byte memory region
31 : private key for which the public key is desired.
32 :
33 : sha is a handle of a local join to a sha512 calculator.
34 :
35 : Does no input argument checking. The caller takes a write interest
36 : in public_key and sha and a read interest in public_key for the
37 : duration the call. Sanitizes the sha and stack to minimize risk of
38 : leaking private key info before returning. Returns public_key. */
39 :
40 : uchar * FD_FN_SENSITIVE
41 : fd_ed25519_public_from_private( uchar public_key [ 32 ],
42 : uchar const private_key[ 32 ],
43 : fd_sha512_t * sha );
44 :
45 : /* fd_ed25519_sign signs a message according to the ED25519 standard.
46 :
47 : sig is assumed to point to the first byte of a 64-byte memory region
48 : which will hold the signature on return.
49 :
50 : msg is assumed to point to the first byte of a sz byte memory region
51 : which holds the message to sign (sz==0 fine, msg==NULL fine if
52 : sz==0).
53 :
54 : public_key is assumed to point to first byte of a 32-byte memory
55 : region that holds the public key to use to sign this message.
56 :
57 : private_key is assumed to point to first byte of a 32-byte memory
58 : region that holds the private key to use to sign this message.
59 :
60 : sha is a handle of a local join to a sha512 calculator.
61 :
62 : Does no input argument checking. Sanitizes the sha and stack to
63 : minimize risk of leaking private key info after return. The caller
64 : takes a write interest in sig and sha and a read interest in msg,
65 : public_key and private_key for the duration the call. Returns sig. */
66 :
67 : uchar * FD_FN_SENSITIVE
68 : fd_ed25519_sign( uchar sig[ 64 ],
69 : uchar const msg[], /* msg_sz */
70 : ulong msg_sz,
71 : uchar const public_key[ 32 ],
72 : uchar const private_key[ 32 ],
73 : fd_sha512_t * sha );
74 :
75 : /* FD_ED25519_SIGN_BATCH_MSG_MAX is the largest supported per-message
76 : size for the batched signing path below (covers the largest messages
77 : the validator signs; shred and transaction MTUs are ~1.2 KiB). */
78 :
79 : #define FD_ED25519_SIGN_BATCH_MSG_MAX (2048UL)
80 :
81 : /* fd_ed25519_sign_batch8 signs n independent messages, n in [1,8]
82 : (asserted). Each signature is bit-identical to
83 : fd_ed25519_sign of the same (msg, key) pair, all signed with the
84 : single (public_key, private_key) identity. For n>=2 the
85 : signatures share batched SHA-512 computations and a single field
86 : inversion for the point compressions, so per-signature cost is lower
87 : than fd_ed25519_sign.
88 :
89 : sig is assumed to point to the first byte of an n*64-byte memory
90 : region which will hold the n signatures on return (signature i at
91 : sig+64*i).
92 :
93 : msg[i] is assumed to point to the first byte of a msg_sz[i] byte
94 : memory region which holds message i (msg_sz[i]==0 fine, msg[i]==NULL
95 : fine if msg_sz[i]==0, msg_sz[i] at most
96 : FD_ED25519_SIGN_BATCH_MSG_MAX).
97 :
98 : public_key and private_key are each a single 32-byte key, shared by
99 : all n messages (this is a shared-identity batch signer).
100 :
101 : Sanitizes internal state to minimize risk of leaking private key
102 : info after return. The caller takes a write interest in sig and a
103 : read interest in the messages and keys for the duration the call.
104 : Returns sig. */
105 :
106 : uchar * FD_FN_SENSITIVE
107 : fd_ed25519_sign_batch8( uchar sig[], /* n*64 */
108 : uchar const * const msg[], /* n */
109 : ulong const msg_sz[], /* n */
110 : uchar const public_key[ 32 ],
111 : uchar const private_key[ 32 ],
112 : ulong n );
113 :
114 : /* fd_ed25519_verify verifies message according to the ED25519 standard.
115 :
116 : msg is assumed to point to the first byte of a sz byte memory region
117 : which holds the message to verify (sz==0 fine, msg==NULL fine if
118 : sz==0).
119 :
120 : sig is assumed to point to the first byte of a 64 byte memory region
121 : which holds the signature of the message.
122 :
123 : public_key is assumed to point to first byte of a 32-byte memory
124 : region that holds the public key to use to verify this message.
125 :
126 : sha is a handle of a local join to a sha512 calculator.
127 :
128 : Does no input argument checking. This function takes a write
129 : interest in sha and a read interest in msg, sig and public_key for
130 : the duration of the call. Returns
131 : FD_ED25519_SUCCESS (0) if the message verified successfully or a
132 : FD_ED25519_ERR_* code indicating the failure reason otherwise. */
133 :
134 : int
135 : fd_ed25519_verify( uchar const msg[], /* msg_sz */
136 : ulong msg_sz,
137 : uchar const sig[ 64 ],
138 : uchar const public_key[ 32 ],
139 : fd_sha512_t * sha );
140 :
141 : /* fd_ed25519_verify_batch_single_msg verifies a batch of signatures
142 : over a single message, according to the ED25519 standard.
143 :
144 : msg is assumed to point to the first byte of a msg_sz byte memory region
145 : which holds the message to verify (msg_sz==0 fine, msg==NULL fine if
146 : msg_sz==0).
147 :
148 : signatures is assumed to point to the first byte of a memory region
149 : which holds the signatures of the message. Each signature is 64-byte long.
150 :
151 : pubkeys is assumed to point to first byte of a memory region
152 : that holds the public keys to use to verify these signatures.
153 : Each public key is 32 bytes long.
154 :
155 : shas is an array of handles of a local join to sha512 calculators.
156 :
157 : batch_sz is the size of signatures, pubkeys and shas.
158 : batch_sz must be greater than zero.
159 :
160 : See fd_ed25519_verify for more details. */
161 :
162 : int
163 : fd_ed25519_verify_batch_single_msg( uchar const msg[], /* msg_sz */
164 : ulong const msg_sz,
165 : uchar const signatures[ 64 ], /* 64 * batch_sz */
166 : uchar const pubkeys[ 32 ], /* 32 * batch_sz */
167 : fd_sha512_t * shas[ 1 ], /* batch_sz */
168 : uchar const batch_sz );
169 :
170 : /* fd_ed25519_cache_t is a bounded cache of per public key
171 : precomputation used to speed up verifying signatures of repeated
172 : public keys. An entry holds a split table of odd multiples of -A
173 : (see fd_ed25519_double_scalar_mul_base_split), keyed by the full
174 : 32-byte public key encoding. The cache is 4-way set associative
175 : with LRU replacement. A key is inserted when a signature by it
176 : verifies successfully for the second time within a window of recent
177 : misses (tracked by a small tag filter), so only valid, not small
178 : order keys are cached and one-time keys don't evict useful entries.
179 : Table builds are rate limited relative to the verify rate.
180 :
181 : The results (including error codes) of the cached verify APIs are
182 : identical to the uncached ones for all inputs and cache states; the
183 : cache only changes how long a verify takes. A cache is not thread
184 : safe and is typically owned by a single tile. The footprint is
185 : ~6.2 KiB per entry (AVX-512 build) plus ~170 KiB of fixed tables. */
186 :
187 : struct fd_ed25519_cache;
188 : typedef struct fd_ed25519_cache fd_ed25519_cache_t;
189 :
190 14980 : #define FD_ED25519_CACHE_ALIGN (128UL)
191 :
192 : /* fd_ed25519_cache_{align,footprint} give the required alignment and
193 : footprint of a memory region suitable for a cache with ent_cnt
194 : entries. ent_cnt must be a power of 2 in [4,2^20]. footprint
195 : returns 0 for an invalid ent_cnt. */
196 :
197 : FD_FN_CONST ulong
198 : fd_ed25519_cache_align( void );
199 :
200 : FD_FN_CONST ulong
201 : fd_ed25519_cache_footprint( ulong ent_cnt );
202 :
203 : /* fd_ed25519_cache_new formats mem as a cache with ent_cnt entries,
204 : seeded with seed (the seed randomizes set placement). Returns mem on
205 : success and NULL on failure (logs details). fd_ed25519_cache_join
206 : joins the caller to the cache. fd_ed25519_cache_leave and
207 : fd_ed25519_cache_delete are the usual inverses. */
208 :
209 : void *
210 : fd_ed25519_cache_new( void * mem,
211 : ulong ent_cnt,
212 : ulong seed );
213 :
214 : fd_ed25519_cache_t *
215 : fd_ed25519_cache_join( void * shcache );
216 :
217 : void *
218 : fd_ed25519_cache_leave( fd_ed25519_cache_t * cache );
219 :
220 : void *
221 : fd_ed25519_cache_delete( void * shcache );
222 :
223 : /* fd_ed25519_cache_{hit,miss,insert}_cnt return the number of public
224 : key lookups that hit, the number that missed and the number of
225 : entries inserted, since the cache was created. */
226 :
227 : ulong fd_ed25519_cache_hit_cnt ( fd_ed25519_cache_t const * cache );
228 : ulong fd_ed25519_cache_miss_cnt ( fd_ed25519_cache_t const * cache );
229 : ulong fd_ed25519_cache_insert_cnt( fd_ed25519_cache_t const * cache );
230 :
231 : /* fd_ed25519_verify_cached is fd_ed25519_verify using cache. Returns
232 : exactly what fd_ed25519_verify returns for the same msg, sig and
233 : public_key. */
234 :
235 : int
236 : fd_ed25519_verify_cached( uchar const msg[], /* msg_sz */
237 : ulong msg_sz,
238 : uchar const sig[ 64 ],
239 : uchar const public_key[ 32 ],
240 : fd_sha512_t * sha,
241 : fd_ed25519_cache_t * cache );
242 :
243 : /* fd_ed25519_verify_batch_single_msg_cached is
244 : fd_ed25519_verify_batch_single_msg using cache. Returns exactly what
245 : fd_ed25519_verify_batch_single_msg returns for the same arguments. */
246 :
247 : int
248 : fd_ed25519_verify_batch_single_msg_cached( uchar const msg[], /* msg_sz */
249 : ulong const msg_sz,
250 : uchar const signatures[ 64 ], /* 64 * batch_sz */
251 : uchar const pubkeys[ 32 ], /* 32 * batch_sz */
252 : fd_sha512_t * shas[ 1 ], /* batch_sz */
253 : uchar const batch_sz,
254 : fd_ed25519_cache_t * cache );
255 :
256 : /* fd_ed25519_strerror converts an FD_ED25519_SUCCESS / FD_ED25519_ERR_*
257 : code into a human readable cstr. The lifetime of the returned
258 : pointer is infinite. The returned pointer is always to a non-NULL
259 : cstr. */
260 :
261 : FD_FN_CONST char const *
262 : fd_ed25519_strerror( int err );
263 :
264 : FD_PROTOTYPES_END
265 :
266 : #endif /* HEADER_fd_src_ballet_ed25519_fd_ed25519_h */
|