sui_move_natives_latest/crypto/
bls12381.rs1use fastcrypto::{
4 bls12381::{min_pk, min_sig},
5 traits::{ToFromBytes, VerifyingKey},
6};
7use move_binary_format::errors::PartialVMResult;
8use move_core_types::gas_algebra::InternalGas;
9use move_vm_runtime::natives::functions::{NativeContext, NativeResult};
10use move_vm_runtime::{execution::values::VectorRef, native_charge_gas_early_exit};
11use move_vm_runtime::{
12 execution::{Type, values::Value},
13 pop_arg,
14};
15use smallvec::smallvec;
16use std::collections::VecDeque;
17
18use crate::{NativesCostTable, get_extension};
19
20const BLS12381_BLOCK_SIZE: usize = 64;
21
22#[derive(Clone)]
23pub struct Bls12381Bls12381MinSigVerifyCostParams {
24 pub bls12381_bls12381_min_sig_verify_cost_base: InternalGas,
26 pub bls12381_bls12381_min_sig_verify_msg_cost_per_byte: InternalGas,
28 pub bls12381_bls12381_min_sig_verify_msg_cost_per_block: InternalGas,
30}
31pub fn bls12381_min_sig_verify(
41 context: &mut NativeContext,
42 ty_args: Vec<Type>,
43 mut args: VecDeque<Value>,
44) -> PartialVMResult<NativeResult> {
45 debug_assert!(ty_args.is_empty());
46 debug_assert!(args.len() == 3);
47
48 let bls12381_bls12381_min_sig_verify_cost_params = get_extension!(context, NativesCostTable)?
50 .bls12381_bls12381_min_sig_verify_cost_params
51 .clone();
52 native_charge_gas_early_exit!(
54 context,
55 bls12381_bls12381_min_sig_verify_cost_params.bls12381_bls12381_min_sig_verify_cost_base
56 );
57
58 let msg = pop_arg!(args, VectorRef);
59 let public_key_bytes = pop_arg!(args, VectorRef);
60 let signature_bytes = pop_arg!(args, VectorRef);
61
62 let msg_ref = msg.as_bytes_ref()?;
63 let public_key_bytes_ref = public_key_bytes.as_bytes_ref()?;
64 let signature_bytes_ref = signature_bytes.as_bytes_ref()?;
65
66 native_charge_gas_early_exit!(
68 context,
69 bls12381_bls12381_min_sig_verify_cost_params
70 .bls12381_bls12381_min_sig_verify_msg_cost_per_byte
71 * (msg_ref.len() as u64).into()
72 + bls12381_bls12381_min_sig_verify_cost_params
73 .bls12381_bls12381_min_sig_verify_msg_cost_per_block
74 * (msg_ref.len().div_ceil(BLS12381_BLOCK_SIZE) as u64).into()
75 );
76
77 let cost = context.gas_used();
78
79 let Ok(signature) =
80 <min_sig::BLS12381Signature as ToFromBytes>::from_bytes(&signature_bytes_ref)
81 else {
82 return Ok(NativeResult::ok(cost, smallvec![Value::bool(false)]));
83 };
84
85 let public_key =
86 match <min_sig::BLS12381PublicKey as ToFromBytes>::from_bytes(&public_key_bytes_ref) {
87 Ok(public_key) => match public_key.validate() {
88 Ok(_) => public_key,
89 Err(_) => return Ok(NativeResult::ok(cost, smallvec![Value::bool(false)])),
90 },
91 Err(_) => return Ok(NativeResult::ok(cost, smallvec![Value::bool(false)])),
92 };
93
94 Ok(NativeResult::ok(
95 cost,
96 smallvec![Value::bool(public_key.verify(&msg_ref, &signature).is_ok())],
97 ))
98}
99
100#[derive(Clone)]
101pub struct Bls12381Bls12381MinPkVerifyCostParams {
102 pub bls12381_bls12381_min_pk_verify_cost_base: InternalGas,
104 pub bls12381_bls12381_min_pk_verify_msg_cost_per_byte: InternalGas,
106 pub bls12381_bls12381_min_pk_verify_msg_cost_per_block: InternalGas,
108}
109pub fn bls12381_min_pk_verify(
119 context: &mut NativeContext,
120 ty_args: Vec<Type>,
121 mut args: VecDeque<Value>,
122) -> PartialVMResult<NativeResult> {
123 debug_assert!(ty_args.is_empty());
124 debug_assert!(args.len() == 3);
125
126 let bls12381_bls12381_min_pk_verify_cost_params = get_extension!(context, NativesCostTable)?
128 .bls12381_bls12381_min_pk_verify_cost_params
129 .clone();
130
131 native_charge_gas_early_exit!(
133 context,
134 bls12381_bls12381_min_pk_verify_cost_params.bls12381_bls12381_min_pk_verify_cost_base
135 );
136
137 let msg = pop_arg!(args, VectorRef);
138 let public_key_bytes = pop_arg!(args, VectorRef);
139 let signature_bytes = pop_arg!(args, VectorRef);
140
141 let msg_ref = msg.as_bytes_ref()?;
142 let public_key_bytes_ref = public_key_bytes.as_bytes_ref()?;
143 let signature_bytes_ref = signature_bytes.as_bytes_ref()?;
144
145 native_charge_gas_early_exit!(
147 context,
148 bls12381_bls12381_min_pk_verify_cost_params
149 .bls12381_bls12381_min_pk_verify_msg_cost_per_byte
150 * (msg_ref.len() as u64).into()
151 + bls12381_bls12381_min_pk_verify_cost_params
152 .bls12381_bls12381_min_pk_verify_msg_cost_per_block
153 * (msg_ref.len().div_ceil(BLS12381_BLOCK_SIZE) as u64).into()
154 );
155
156 let cost = context.gas_used();
157
158 let signature =
159 match <min_pk::BLS12381Signature as ToFromBytes>::from_bytes(&signature_bytes_ref) {
160 Ok(signature) => signature,
161 Err(_) => return Ok(NativeResult::ok(cost, smallvec![Value::bool(false)])),
162 };
163
164 let public_key =
165 match <min_pk::BLS12381PublicKey as ToFromBytes>::from_bytes(&public_key_bytes_ref) {
166 Ok(public_key) => match public_key.validate() {
167 Ok(_) => public_key,
168 Err(_) => return Ok(NativeResult::ok(cost, smallvec![Value::bool(false)])),
169 },
170 Err(_) => return Ok(NativeResult::ok(cost, smallvec![Value::bool(false)])),
171 };
172
173 Ok(NativeResult::ok(
174 cost,
175 smallvec![Value::bool(public_key.verify(&msg_ref, &signature).is_ok())],
176 ))
177}