Line data Source code
1 : #include "fd_secp256r1_private.h" 2 : 3 : int 4 : fd_secp256r1_verify( uchar const msg[], /* msg_sz */ 5 : ulong msg_sz, 6 : uchar const sig[ 64 ], 7 : uchar const public_key[ 33 ], 8 4035 : fd_sha256_t * sha ) { 9 4035 : fd_secp256r1_scalar_t r[1], s[1], u1[1], u2[1]; 10 4035 : fd_secp256r1_point_t pub[1], Rcmp[1]; 11 : 12 : /* Deserialize signature. 13 : Note: we enforce 0 < r < n, 0 < s <= (n-1)/2. 14 : The condition on s is required to avoid signature malleability. */ 15 4035 : if( FD_UNLIKELY( !fd_secp256r1_scalar_frombytes( r, sig ) ) ) { 16 102 : return FD_SECP256R1_FAILURE; 17 102 : } 18 3933 : if( FD_UNLIKELY( !fd_secp256r1_scalar_frombytes_positive( s, sig+32 ) ) ) { 19 387 : return FD_SECP256R1_FAILURE; 20 387 : } 21 3546 : if( FD_UNLIKELY( fd_secp256r1_scalar_is_zero( r ) || fd_secp256r1_scalar_is_zero( s ) ) ) { 22 24 : return FD_SECP256R1_FAILURE; 23 24 : } 24 : 25 : /* Deserialize public key. */ 26 3522 : if( FD_UNLIKELY( !fd_secp256r1_point_frombytes( pub, public_key ) ) ) { 27 15 : return FD_SECP256R1_FAILURE; 28 15 : } 29 : 30 : /* Hash message. */ 31 3507 : uchar hash[ FD_SHA256_HASH_SZ ]; 32 3507 : fd_sha256_fini( fd_sha256_append( fd_sha256_init( sha ), msg, msg_sz ), hash ); 33 3507 : fd_secp256r1_scalar_from_digest( u1, hash ); 34 : 35 : /* ECDSA sig verify. */ 36 3507 : fd_secp256r1_scalar_inv( s, s ); 37 3507 : fd_secp256r1_scalar_mul( u1, u1, s ); 38 3507 : fd_secp256r1_scalar_mul( u2, r, s ); 39 3507 : fd_secp256r1_double_scalar_mul_base( Rcmp, u1, pub, u2 ); 40 3507 : if( FD_LIKELY( fd_secp256r1_point_eq_x( Rcmp, r ) ) ) { 41 3432 : return FD_SECP256R1_SUCCESS; 42 3432 : } 43 : 44 75 : return FD_SECP256R1_FAILURE; 45 3507 : }