LCOV - code coverage report
Current view: top level - ballet/ed25519 - fd_ed25519.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 6 6 100.0 %
Date: 2026-11-11 12:40:43 Functions: 0 0 -

          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 */

Generated by: LCOV version 1.14