Line data Source code
1 : #if !FD_HAS_HOSTED
2 : #error "This target requires FD_HAS_HOSTED"
3 : #endif
4 :
5 : #include <assert.h>
6 : #include <dlfcn.h>
7 : #include <stdio.h>
8 : #include <stdlib.h>
9 :
10 : #include "../../util/fd_util.h"
11 : #include "../../util/sanitize/fd_fuzz.h"
12 : #include "fd_ed25519.h"
13 :
14 : typedef int
15 : (* verify_fn_t)( uchar const * msg,
16 : ulong sz,
17 : uchar const * sig,
18 : uchar const * pub );
19 :
20 : static union {
21 : verify_fn_t fn;
22 : void * ptr;
23 : } verify_fn;
24 :
25 : typedef int
26 : (* sign_fn_t)( uchar * sig,
27 : uchar const * msg,
28 : ulong sz,
29 : uchar const * pub,
30 : uchar const * prv );
31 :
32 : static union {
33 : sign_fn_t fn;
34 : void * ptr;
35 : } sign_fn;
36 :
37 :
38 : int
39 : LLVMFuzzerInitialize( int * argc,
40 0 : char *** argv ) {
41 : /* Set up shell without signal handlers */
42 0 : putenv( "FD_LOG_BACKTRACE=0" );
43 0 : fd_boot( argc, argv );
44 0 : atexit( fd_halt );
45 :
46 0 : void * dalek = dlopen( "contrib/ed25519/dalek_target/target/x86_64-unknown-linux-gnu/release/libdalek_target.so", RTLD_LAZY );
47 0 : if( FD_UNLIKELY( !dalek ) )
48 0 : FD_LOG_CRIT(( "%s", dlerror() ));
49 :
50 0 : verify_fn.ptr = dlsym( dalek, "ed25519_dalek_verify" );
51 0 : if( FD_UNLIKELY( !verify_fn.ptr ) )
52 0 : FD_LOG_CRIT(( "%s", dlerror() ));
53 :
54 0 : sign_fn.ptr = dlsym( dalek, "ed25519_dalek_sign" );
55 0 : if( FD_UNLIKELY( !sign_fn.ptr ) )
56 0 : FD_LOG_CRIT(( "%s", dlerror() ));
57 :
58 0 : return 0;
59 0 : }
60 :
61 : struct verification_test {
62 : uchar prv[ 32 ];
63 : uchar sig[ 64 ];
64 : uchar msg[ ];
65 : };
66 : typedef struct verification_test verification_test_t;
67 :
68 : int
69 : LLVMFuzzerTestOneInput( uchar const * data,
70 : ulong size ) {
71 : if( FD_UNLIKELY( size<96UL ) ) return -1;
72 :
73 : verification_test_t * const test = ( verification_test_t * const ) data;
74 : ulong sz = size-96UL;
75 :
76 : fd_sha512_t _sha[1];
77 : fd_sha512_t *sha = fd_sha512_join( fd_sha512_new( _sha ) );
78 :
79 : uchar pub[ 32 ];
80 : fd_ed25519_public_from_private( pub, test->prv, sha );
81 :
82 : /* test that C and Rust create the same signature */
83 : uchar sigC[ 64 ];
84 : uchar sigR[ 64 ];
85 : uchar * sig_resultC = fd_ed25519_sign( sigC, test->msg, sz, pub, test->prv, sha );
86 : int sig_resultR = sign_fn.fn( sigR, test->msg, sz, pub, test->prv );
87 : assert( sig_resultC == sigC );
88 : assert( sig_resultR == 0 );
89 : assert( fd_memeq( sigC, sigR, 64UL ) );
90 :
91 : /* test that C and Rust successfully verify this signature */
92 : int ok0 = fd_ed25519_verify( test->msg, sz, sigC, pub, sha ) == FD_ED25519_SUCCESS;
93 : int ok1 = verify_fn.fn( test->msg, sz, sigC, pub ) == 0;
94 : assert( ok0 );
95 : assert( ok1 );
96 :
97 : /* test that C and Rust return the same result on a random sig */
98 : ok0 = fd_ed25519_verify( test->msg, sz, test->sig, pub, sha ) == FD_ED25519_SUCCESS;
99 : ok1 = verify_fn.fn( test->msg, sz, test->sig, pub ) == 0;
100 : assert( ok0==ok1 );
101 : return 0;
102 : }
|