@@ -4,7 +4,9 @@ use move_vm_runtime::native_functions::NativeFunction;
4
4
use move_vm_types:: { loaded_data:: runtime_types:: Type , values:: Value } ;
5
5
6
6
use 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 ,
8
10
} ;
9
11
10
12
use smallvec:: { smallvec, SmallVec } ;
@@ -33,6 +35,56 @@ fn read_hash(data: &[u8]) -> Result<[u8; MESSAGE_SIZE], TryFromSliceError> {
33
35
data. try_into ( )
34
36
}
35
37
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
+
36
88
pub fn native_recover_public_key (
37
89
context : & mut SafeNativeContext ,
38
90
_ty_args : Vec < Type > ,
@@ -102,7 +154,7 @@ pub fn native_recover_public_key(
102
154
use rand_core:: OsRng ;
103
155
104
156
#[ cfg( feature = "testing" ) ]
105
- use libsecp256k1:: { sign, PublicKey , SecretKey } ;
157
+ use libsecp256k1:: { sign, SecretKey } ;
106
158
107
159
#[ cfg( feature = "testing" ) ]
108
160
pub fn native_test_only_generate_keys (
@@ -151,18 +203,18 @@ pub fn make_all(
151
203
builder : & SafeNativeBuilder ,
152
204
) -> impl Iterator < Item = ( String , NativeFunction ) > + ' _ {
153
205
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
+ ] ) ;
158
210
159
211
#[ cfg( feature = "testing" ) ]
160
212
natives. extend ( [
161
213
(
162
214
"generate_keys" ,
163
215
native_test_only_generate_keys as RawSafeNative ,
164
216
) ,
165
- ( "sign" , native_test_only_sign as RawSafeNative ) ,
217
+ ( "sign" , native_test_only_sign) ,
166
218
] ) ;
167
219
168
220
builder. make_named_natives ( natives)
0 commit comments