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 345 : fd_sha256_t * sha ) { 9 345 : fd_secp256r1_scalar_t r[1], s[1], u1[1], u2[1]; 10 345 : 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 345 : if( FD_UNLIKELY( !fd_secp256r1_scalar_frombytes( r, sig ) ) ) { 16 34 : return FD_SECP256R1_FAILURE; 17 34 : } 18 311 : if( FD_UNLIKELY( !fd_secp256r1_scalar_frombytes_positive( s, sig+32 ) ) ) { 19 128 : return FD_SECP256R1_FAILURE; 20 128 : } 21 183 : if( FD_UNLIKELY( fd_secp256r1_scalar_is_zero( r ) || fd_secp256r1_scalar_is_zero( s ) ) ) { 22 8 : return FD_SECP256R1_FAILURE; 23 8 : } 24 : 25 : /* Deserialize public key. */ 26 175 : if( FD_UNLIKELY( !fd_secp256r1_point_frombytes( pub, public_key ) ) ) { 27 5 : return FD_SECP256R1_FAILURE; 28 5 : } 29 : 30 : /* Hash message. */ 31 170 : uchar hash[ FD_SHA256_HASH_SZ ]; 32 170 : fd_sha256_fini( fd_sha256_append( fd_sha256_init( sha ), msg, msg_sz ), hash ); 33 170 : fd_secp256r1_scalar_from_digest( u1, hash ); 34 : 35 : /* ECDSA sig verify. */ 36 170 : fd_secp256r1_scalar_inv( s, s ); 37 170 : fd_secp256r1_scalar_mul( u1, u1, s ); 38 170 : fd_secp256r1_scalar_mul( u2, r, s ); 39 170 : fd_secp256r1_double_scalar_mul_base( Rcmp, u1, pub, u2 ); 40 170 : if( FD_LIKELY( fd_secp256r1_point_eq_x( Rcmp, r ) ) ) { 41 145 : return FD_SECP256R1_SUCCESS; 42 145 : } 43 : 44 25 : return FD_SECP256R1_FAILURE; 45 170 : }