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 0 : fd_log_level_core_set(3); /* crash on warning log */
46 :
47 0 : void * dalek = dlopen( "contrib/ed25519/dalek_target/target/x86_64-unknown-linux-gnu/release/libdalek_target.so", RTLD_LAZY );
48 0 : if( FD_UNLIKELY( !dalek ) )
49 0 : FD_LOG_CRIT(( "%s", dlerror() ));
50 :
51 0 : verify_fn.ptr = dlsym( dalek, "ed25519_dalek_verify" );
52 0 : if( FD_UNLIKELY( !verify_fn.ptr ) )
53 0 : FD_LOG_CRIT(( "%s", dlerror() ));
54 :
55 0 : sign_fn.ptr = dlsym( dalek, "ed25519_dalek_sign" );
56 0 : if( FD_UNLIKELY( !sign_fn.ptr ) )
57 0 : FD_LOG_CRIT(( "%s", dlerror() ));
58 :
59 0 : return 0;
60 0 : }
61 :
62 : struct verification_test {
63 : uchar prv[ 32 ];
64 : uchar sig[ 64 ];
65 : uchar msg[ ];
66 : };
67 : typedef struct verification_test verification_test_t;
68 :
69 : int
70 : LLVMFuzzerTestOneInput( uchar const * data,
71 : ulong size ) {
72 : if( FD_UNLIKELY( size<96UL ) ) return -1;
73 :
74 : verification_test_t * const test = ( verification_test_t * const ) data;
75 : ulong sz = size-96UL;
76 :
77 : fd_sha512_t _sha[1];
78 : fd_sha512_t *sha = fd_sha512_join( fd_sha512_new( _sha ) );
79 :
80 : uchar pub[ 32 ];
81 : fd_ed25519_public_from_private( pub, test->prv, sha );
82 :
83 : /* test that C and Rust create the same signature */
84 : uchar sigC[ 64 ];
85 : uchar sigR[ 64 ];
86 : uchar * sig_resultC = fd_ed25519_sign( sigC, test->msg, sz, pub, test->prv, sha );
87 : int sig_resultR = sign_fn.fn( sigR, test->msg, sz, pub, test->prv );
88 : assert( sig_resultC == sigC );
89 : assert( sig_resultR == 0 );
90 : assert( fd_memeq( sigC, sigR, 64UL ) );
91 :
92 : /* test that C and Rust successfully verify this signature */
93 : int ok0 = fd_ed25519_verify( test->msg, sz, sigC, pub, sha ) == FD_ED25519_SUCCESS;
94 : int ok1 = verify_fn.fn( test->msg, sz, sigC, pub ) == 0;
95 : assert( ok0 );
96 : assert( ok1 );
97 :
98 : /* test that C and Rust return the same result on a random sig */
99 : ok0 = fd_ed25519_verify( test->msg, sz, test->sig, pub, sha ) == FD_ED25519_SUCCESS;
100 : ok1 = verify_fn.fn( test->msg, sz, test->sig, pub ) == 0;
101 : assert( ok0==ok1 );
102 : return 0;
103 : }
|