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 974 : #define FD_ED25519_ERR_SIG (-1) /* Operation failed because the signature was obviously invalid */
13 1071 : #define FD_ED25519_ERR_PUBKEY (-2) /* Operation failed because the public key was obviously invalid */
14 143 : #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 0 : #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 sig and sha and a read interest in msg, public_key and
130 : private_key for the duration the call. Sanitizes the sha and stack
131 : to minimize risk of leaking private key info after return. Returns
132 : FD_ED25519_SUCCESS (0) if the message verified successfully or a
133 : FD_ED25519_ERR_* code indicating the failure reason otherwise. */
134 :
135 : int
136 : fd_ed25519_verify( uchar const msg[], /* msg_sz */
137 : ulong msg_sz,
138 : uchar const sig[ 64 ],
139 : uchar const public_key[ 32 ],
140 : fd_sha512_t * sha );
141 :
142 : /* fd_ed25519_verify_batch_single_msg verifies a batch of signatures
143 : over a single message, according to the ED25519 standard.
144 :
145 : msg is assumed to point to the first byte of a msg_sz byte memory region
146 : which holds the message to verify (msg_sz==0 fine, msg==NULL fine if
147 : msg_sz==0).
148 :
149 : signatures is assumed to point to the first byte of a memory region
150 : which holds the signatures of the message. Each signature is 64-byte long.
151 :
152 : pubkeys is assumed to point to first byte of a memory region
153 : that holds the public keys to use to verify these signatures.
154 : Each public key is 64-byte long.
155 :
156 : shas is an array of handles of a local join to sha512 calculators.
157 :
158 : batch_sz is the size of signatures, pubkeys and shas.
159 : batch_sz must be greater than zero.
160 :
161 : See fd_ed25519_verify for more details. */
162 :
163 : int
164 : fd_ed25519_verify_batch_single_msg( uchar const msg[], /* msg_sz */
165 : ulong const msg_sz,
166 : uchar const signatures[ 64 ], /* 64 * batch_sz */
167 : uchar const pubkeys[ 32 ], /* 32 * batch_sz */
168 : fd_sha512_t * shas[ 1 ], /* batch_sz */
169 : uchar const batch_sz );
170 :
171 : /* fd_ed25519_cache_t is a bounded cache of per public key
172 : precomputation used to speed up verifying signatures of repeated
173 : public keys. An entry holds a split table of odd multiples of -A
174 : (see fd_ed25519_double_scalar_mul_base_split), keyed by the full
175 : 32-byte public key encoding. The cache is 4-way set associative
176 : with LRU replacement. A key is inserted when a signature by it
177 : verifies successfully for the second time within a window of recent
178 : misses (tracked by a small tag filter), so only valid, not small
179 : order keys are cached and one-time keys don't evict useful entries.
180 : Table builds are rate limited relative to the verify rate.
181 :
182 : The results (including error codes) of the cached verify APIs are
183 : identical to the uncached ones for all inputs and cache states; the
184 : cache only changes how long a verify takes. A cache is not thread
185 : safe and is typically owned by a single tile. The footprint is
186 : ~6.2 KiB per entry (AVX-512 build) plus ~170 KiB of fixed tables. */
187 :
188 : struct fd_ed25519_cache;
189 : typedef struct fd_ed25519_cache fd_ed25519_cache_t;
190 :
191 0 : #define FD_ED25519_CACHE_ALIGN (128UL)
192 :
193 : /* fd_ed25519_cache_{align,footprint} give the required alignment and
194 : footprint of a memory region suitable for a cache with ent_cnt
195 : entries. ent_cnt must be a power of 2 in [4,2^20]. footprint
196 : returns 0 for an invalid ent_cnt. */
197 :
198 : FD_FN_CONST ulong
199 : fd_ed25519_cache_align( void );
200 :
201 : FD_FN_CONST ulong
202 : fd_ed25519_cache_footprint( ulong ent_cnt );
203 :
204 : /* fd_ed25519_cache_new formats mem as a cache with ent_cnt entries,
205 : seeded with seed (the seed randomizes set placement). Returns mem on
206 : success and NULL on failure (logs details). fd_ed25519_cache_join
207 : joins the caller to the cache. fd_ed25519_cache_leave and
208 : fd_ed25519_cache_delete are the usual inverses. */
209 :
210 : void *
211 : fd_ed25519_cache_new( void * mem,
212 : ulong ent_cnt,
213 : ulong seed );
214 :
215 : fd_ed25519_cache_t *
216 : fd_ed25519_cache_join( void * shcache );
217 :
218 : void *
219 : fd_ed25519_cache_leave( fd_ed25519_cache_t * cache );
220 :
221 : void *
222 : fd_ed25519_cache_delete( void * shcache );
223 :
224 : /* fd_ed25519_cache_{hit,miss,insert}_cnt return the number of public
225 : key lookups that hit, the number that missed and the number of
226 : entries inserted, since the cache was created. */
227 :
228 : ulong fd_ed25519_cache_hit_cnt ( fd_ed25519_cache_t const * cache );
229 : ulong fd_ed25519_cache_miss_cnt ( fd_ed25519_cache_t const * cache );
230 : ulong fd_ed25519_cache_insert_cnt( fd_ed25519_cache_t const * cache );
231 :
232 : /* fd_ed25519_verify_cached is fd_ed25519_verify using cache. Returns
233 : exactly what fd_ed25519_verify returns for the same msg, sig and
234 : public_key. */
235 :
236 : int
237 : fd_ed25519_verify_cached( uchar const msg[], /* msg_sz */
238 : ulong msg_sz,
239 : uchar const sig[ 64 ],
240 : uchar const public_key[ 32 ],
241 : fd_sha512_t * sha,
242 : fd_ed25519_cache_t * cache );
243 :
244 : /* fd_ed25519_verify_batch_single_msg_cached is
245 : fd_ed25519_verify_batch_single_msg using cache. Returns exactly what
246 : fd_ed25519_verify_batch_single_msg returns for the same arguments. */
247 :
248 : int
249 : fd_ed25519_verify_batch_single_msg_cached( uchar const msg[], /* msg_sz */
250 : ulong const msg_sz,
251 : uchar const signatures[ 64 ], /* 64 * batch_sz */
252 : uchar const pubkeys[ 32 ], /* 32 * batch_sz */
253 : fd_sha512_t * shas[ 1 ], /* batch_sz */
254 : uchar const batch_sz,
255 : fd_ed25519_cache_t * cache );
256 :
257 : /* fd_ed25519_strerror converts an FD_ED25519_SUCCESS / FD_ED25519_ERR_*
258 : code into a human readable cstr. The lifetime of the returned
259 : pointer is infinite. The returned pointer is always to a non-NULL
260 : cstr. */
261 :
262 : FD_FN_CONST char const *
263 : fd_ed25519_strerror( int err );
264 :
265 : FD_PROTOTYPES_END
266 :
267 : #endif /* HEADER_fd_src_ballet_ed25519_fd_ed25519_h */
|