@@ -4,7 +4,9 @@ use move_vm_runtime::native_functions::NativeFunction;
44use move_vm_types:: { loaded_data:: runtime_types:: Type , values:: Value } ;
55
66use libsecp256k1:: {
7- recover, util:: MESSAGE_SIZE , util:: SIGNATURE_SIZE , Message , RecoveryId , Signature ,
7+ recover,
8+ util:: { COMPRESSED_PUBLIC_KEY_SIZE , MESSAGE_SIZE , SIGNATURE_SIZE } ,
9+ verify, Message , PublicKey , RecoveryId , Signature ,
810} ;
911
1012use smallvec:: { smallvec, SmallVec } ;
@@ -33,6 +35,56 @@ fn read_hash(data: &[u8]) -> Result<[u8; MESSAGE_SIZE], TryFromSliceError> {
3335 data. try_into ( )
3436}
3537
38+ fn read_pubkey ( data : & [ u8 ] ) -> Result < [ u8 ; COMPRESSED_PUBLIC_KEY_SIZE ] , TryFromSliceError > {
39+ data. try_into ( )
40+ }
41+
42+ pub fn native_verify (
43+ context : & mut SafeNativeContext ,
44+ _ty_args : Vec < Type > ,
45+ mut arguments : VecDeque < Value > ,
46+ ) -> SafeNativeResult < SmallVec < [ Value ; 1 ] > > {
47+ let gas_params = & context. native_gas_params . initia_stdlib ;
48+ context. charge ( gas_params. crypto_secp256k1_base ) ?;
49+
50+ debug_assert ! ( _ty_args. is_empty( ) ) ;
51+ debug_assert ! ( arguments. len( ) == 3 ) ;
52+
53+ let signature = safely_pop_arg ! ( arguments, Vec <u8 >) ;
54+ let pubkey = safely_pop_arg ! ( arguments, Vec <u8 >) ;
55+ let message = safely_pop_arg ! ( arguments, Vec <u8 >) ;
56+
57+ let msg = match read_hash ( & message) {
58+ Ok ( mh) => Message :: parse ( & mh) ,
59+ Err ( _) => {
60+ return Err ( SafeNativeError :: Abort {
61+ abort_code : UNABLE_TO_DESERIALIZE ,
62+ } ) ;
63+ }
64+ } ;
65+
66+ context. charge ( gas_params. crypto_secp256k1_per_pubkey_deserialize * NumArgs :: one ( ) ) ?;
67+ let pk = match read_pubkey ( & pubkey) {
68+ Ok ( pk) => match PublicKey :: parse_compressed ( & pk) {
69+ Ok ( pk) => pk,
70+ Err ( _) => return Ok ( smallvec ! [ Value :: bool ( false ) ] ) ,
71+ } ,
72+ Err ( _) => return Ok ( smallvec ! [ Value :: bool ( false ) ] ) ,
73+ } ;
74+
75+ context. charge ( gas_params. crypto_secp256k1_per_sig_deserialize * NumArgs :: one ( ) ) ?;
76+ let sig = match read_signature ( & signature) {
77+ Ok ( sig) => match Signature :: parse_standard ( & sig) {
78+ Ok ( sig) => sig,
79+ Err ( _) => return Ok ( smallvec ! [ Value :: bool ( false ) ] ) ,
80+ } ,
81+ Err ( _) => return Ok ( smallvec ! [ Value :: bool ( false ) ] ) ,
82+ } ;
83+
84+ context. charge ( gas_params. crypto_secp256k1_per_sig_verify * NumArgs :: one ( ) ) ?;
85+ Ok ( smallvec ! [ Value :: bool ( verify( & msg, & sig, & pk) ) ] )
86+ }
87+
3688pub fn native_recover_public_key (
3789 context : & mut SafeNativeContext ,
3890 _ty_args : Vec < Type > ,
@@ -102,7 +154,7 @@ pub fn native_recover_public_key(
102154use rand_core:: OsRng ;
103155
104156#[ cfg( feature = "testing" ) ]
105- use libsecp256k1:: { sign, PublicKey , SecretKey } ;
157+ use libsecp256k1:: { sign, SecretKey } ;
106158
107159#[ cfg( feature = "testing" ) ]
108160pub fn native_test_only_generate_keys (
@@ -151,18 +203,18 @@ pub fn make_all(
151203 builder : & SafeNativeBuilder ,
152204) -> impl Iterator < Item = ( String , NativeFunction ) > + ' _ {
153205 let mut natives = vec ! [ ] ;
154- natives. extend ( [ (
155- "recover_public_key_internal" ,
156- native_recover_public_key as RawSafeNative ,
157- ) ] ) ;
206+ natives. extend ( [
207+ ( "verify_internal" , native_verify as RawSafeNative ) ,
208+ ( "recover_public_key_internal" , native_recover_public_key ) ,
209+ ] ) ;
158210
159211 #[ cfg( feature = "testing" ) ]
160212 natives. extend ( [
161213 (
162214 "generate_keys" ,
163215 native_test_only_generate_keys as RawSafeNative ,
164216 ) ,
165- ( "sign" , native_test_only_sign as RawSafeNative ) ,
217+ ( "sign" , native_test_only_sign) ,
166218 ] ) ;
167219
168220 builder. make_named_natives ( natives)
0 commit comments