Skip to content

Commit 048cd1e

Browse files
Use hooks to implement field operations oracle for secp256k1
1 parent fcac9d2 commit 048cd1e

File tree

15 files changed

+461
-92
lines changed

15 files changed

+461
-92
lines changed

basic_bootloader/src/bootloader/transaction/authorization_list.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use zk_ee::system::Ergs;
1717
use zk_ee::system::IOSubsystem;
1818
use zk_ee::system::NonceError;
1919
use zk_ee::system::Resource;
20+
use zk_ee::system::SystemFunctionsExt;
2021
use zk_ee::system::{AccountDataRequest, EthereumLikeTypes, IOSubsystemExt, Resources, System};
2122
use zk_ee::system_log;
2223
use zk_ee::{internal_error, wrap_error};
@@ -234,8 +235,10 @@ fn recover_authority<S: EthereumLikeTypes>(
234235
resources: &mut S::Resources,
235236
auth_sig_data: (u8, &[u8], &[u8]),
236237
msg: &[u8; 32],
237-
) -> Result<Option<B160>, TxError> {
238-
use zk_ee::system::SystemFunctions;
238+
) -> Result<Option<B160>, TxError>
239+
where
240+
S::IO: IOSubsystemExt,
241+
{
239242
let mut ecrecover_input = [0u8; 128];
240243
let (parity, r, s) = auth_sig_data;
241244
if parity > 1 {
@@ -246,14 +249,18 @@ fn recover_authority<S: EthereumLikeTypes>(
246249
ecrecover_input[64..96][(32 - r.len())..].copy_from_slice(r);
247250
ecrecover_input[96..128][(32 - s.len())..].copy_from_slice(s);
248251
let mut ecrecover_output = ArrayBuilder::default();
252+
let mut logger = system.get_logger();
253+
let allocator = system.get_allocator();
249254
// Recover is counted in intrinsic gas
250255
resources
251256
.with_infinite_ergs(|inf_ergs| {
252-
S::SystemFunctions::secp256k1_ec_recover(
257+
S::SystemFunctionsExt::secp256k1_ec_recover(
253258
ecrecover_input.as_slice(),
254259
&mut ecrecover_output,
255260
inf_ergs,
256-
system.get_allocator(),
261+
system.io.oracle(),
262+
&mut logger,
263+
allocator,
257264
)
258265
})
259266
.map_err(SystemError::from)?;

basic_bootloader/src/bootloader/transaction_flow/zk/validation_impl.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use zk_ee::system::metadata::zk_metadata::TxLevelMetadata;
2323
use zk_ee::system::resources::Computational;
2424
use zk_ee::system::tracer::Tracer;
2525
use zk_ee::system::{errors::system::SystemError, EthereumLikeTypes, System};
26-
use zk_ee::system::{AccountDataRequest, SystemFunctions, VERSIONED_HASH_VERSION_KZG};
26+
use zk_ee::system::{AccountDataRequest, SystemFunctionsExt, VERSIONED_HASH_VERSION_KZG};
2727
use zk_ee::system::{Ergs, IOSubsystemExt, Resources};
2828
use zk_ee::system::{IOSubsystem, NonceError};
2929
use zk_ee::system::{Resource, SystemTypes};
@@ -187,14 +187,18 @@ where
187187

188188
let mut ecrecover_output = ArrayBuilder::default();
189189
// We already charged gas for ecrecover in intrinsic cost, so we only need to charge native resources here.
190+
let mut logger = system.get_logger();
191+
let allocator = system.get_allocator();
190192
tx_resources
191193
.main_resources
192194
.with_infinite_ergs(|resources| {
193-
S::SystemFunctions::secp256k1_ec_recover(
195+
S::SystemFunctionsExt::secp256k1_ec_recover(
194196
ecrecover_input.as_slice(),
195197
&mut ecrecover_output,
196198
resources,
197-
system.get_allocator(),
199+
system.io.oracle(),
200+
&mut logger,
201+
allocator,
198202
)
199203
.map_err(SystemError::from)
200204
})?;

basic_system/src/system_functions/ecrecover.rs

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,52 @@
11
use super::*;
22
use crate::cost_constants::{ECRECOVER_COST_ERGS, ECRECOVER_NATIVE_COST};
3+
use crypto::secp256k1::hooks::DefaultSecp256k1Hooks;
4+
use field_ops::Secp256k1HooksWithOracle;
35
use zk_ee::common_traits::TryExtend;
6+
use zk_ee::oracle::IOOracle;
47
use zk_ee::out_of_return_memory;
5-
use zk_ee::system::base_system_functions::{Secp256k1ECRecoverErrors, SystemFunction};
8+
use zk_ee::system::base_system_functions::Secp256k1ECRecoverErrors;
69
use zk_ee::system::errors::{subsystem::SubsystemError, system::SystemError};
7-
use zk_ee::system::Computational;
10+
use zk_ee::system::{Computational, SystemFunctionExt};
811

912
///
1013
/// ecrecover system function implementation.
1114
///
1215
pub struct EcRecoverImpl;
1316

14-
impl<R: Resources> SystemFunction<R, Secp256k1ECRecoverErrors> for EcRecoverImpl {
17+
impl<R: Resources> SystemFunctionExt<R, Secp256k1ECRecoverErrors> for EcRecoverImpl {
1518
/// If the input size is less than expected - it will be padded with zeroes.
1619
/// If the input size is greater - redundant bytes will be ignored.
1720
/// If the input is invalid(v != 27|28 or failed to recover signer) returns `Ok(0)`.
1821
///
1922
/// Returns `OutOfGas` if not enough resources provided.
20-
fn execute<D: TryExtend<u8> + ?Sized, A: core::alloc::Allocator + Clone>(
23+
fn execute<O: IOOracle, L, D: TryExtend<u8> + ?Sized, A: core::alloc::Allocator + Clone>(
2124
input: &[u8],
2225
output: &mut D,
2326
resources: &mut R,
27+
oracle: &mut O,
28+
_logger: &mut L,
2429
_allocator: A,
2530
) -> Result<(), SubsystemError<Secp256k1ECRecoverErrors>> {
2631
Ok(cycle_marker::wrap_with_resources!(
2732
"ecrecover",
2833
resources,
29-
{ ecrecover_as_system_function_inner(input, output, resources) }
34+
// TODO: reconsider if we actually want to use the oracle based version here
35+
{ ecrecover_as_system_function_inner(input, output, resources, Some(oracle)) }
3036
)?)
3137
}
3238
}
3339

3440
fn ecrecover_as_system_function_inner<
41+
O: IOOracle,
3542
S: ?Sized + MinimalByteAddressableSlice,
3643
D: ?Sized + TryExtend<u8>,
3744
R: Resources,
3845
>(
3946
src: &S,
4047
dst: &mut D,
4148
resources: &mut R,
49+
oracle: Option<&mut O>,
4250
) -> Result<(), SystemError> {
4351
resources.charge(&R::from_ergs_and_native(
4452
ECRECOVER_COST_ERGS,
@@ -68,7 +76,14 @@ fn ecrecover_as_system_function_inner<
6876
return Ok(());
6977
}
7078

71-
let Ok(pk_bytes) = ecrecover_inner(digest, r, s, rec_id) else {
79+
// on forward run we do not support oracle-based hooks
80+
let oracle = if cfg!(target_arch = "riscv32") {
81+
oracle
82+
} else {
83+
None
84+
};
85+
86+
let Ok(pk_bytes) = ecrecover_inner(digest, r, s, rec_id, oracle) else {
7287
return Ok(());
7388
};
7489

@@ -85,11 +100,12 @@ fn ecrecover_as_system_function_inner<
85100
Ok(())
86101
}
87102

88-
pub fn ecrecover_inner(
103+
pub fn ecrecover_inner<O: IOOracle>(
89104
digest: &[u8; 32],
90105
r: &[u8; 32],
91106
s: &[u8; 32],
92107
rec_id: u8,
108+
oracle: Option<&mut O>,
93109
) -> Result<crypto::k256::EncodedPoint, ()> {
94110
use crypto::k256::{
95111
ecdsa::{hazmat::bits2field, RecoveryId, Signature},
@@ -104,7 +120,22 @@ pub fn ecrecover_inner(
104120
&bits2field::<crypto::k256::Secp256k1>(digest).map_err(|_| ())?,
105121
);
106122

107-
let Ok(pk) = crypto::secp256k1::recover(&message, &signature, &recovery_id) else {
123+
let res = match oracle {
124+
Some(oracle) => crypto::secp256k1::recover(
125+
&message,
126+
&signature,
127+
&recovery_id,
128+
&mut Secp256k1HooksWithOracle::new(oracle),
129+
),
130+
None => crypto::secp256k1::recover(
131+
&message,
132+
&signature,
133+
&recovery_id,
134+
&mut DefaultSecp256k1Hooks,
135+
),
136+
};
137+
138+
let Ok(pk) = res else {
108139
return Err(());
109140
};
110141

@@ -117,6 +148,7 @@ pub fn ecrecover_inner(
117148
#[cfg(test)]
118149
mod test {
119150
use super::*;
151+
use crate::system_implementation::flat_storage_model::TestingTree;
120152
use hex;
121153
use zk_ee::reference_implementations::BaseResources;
122154
use zk_ee::reference_implementations::DecreasingNative;
@@ -140,8 +172,13 @@ mod test {
140172

141173
let mut resources = <BaseResources<DecreasingNative> as Resource>::FORMAL_INFINITE;
142174

143-
ecrecover_as_system_function_inner(input.as_slice(), &mut pubkey, &mut resources)
144-
.expect("ecrecover");
175+
ecrecover_as_system_function_inner::<TestingTree<false>, _, _, _>(
176+
input.as_slice(),
177+
&mut pubkey,
178+
&mut resources,
179+
None,
180+
)
181+
.expect("ecrecover");
145182
assert_eq!(pubkey.len(), 32, "Size should be 32");
146183
assert_eq!(
147184
pubkey, expected_pubkey,
@@ -156,8 +193,13 @@ mod test {
156193

157194
let mut resources = <BaseResources<DecreasingNative> as Resource>::FORMAL_INFINITE;
158195

159-
ecrecover_as_system_function_inner(input.as_slice(), &mut pubkey, &mut resources)
160-
.expect("ecrecover");
196+
ecrecover_as_system_function_inner::<TestingTree<false>, _, _, _>(
197+
input.as_slice(),
198+
&mut pubkey,
199+
&mut resources,
200+
None,
201+
)
202+
.expect("ecrecover");
161203
assert_eq!(pubkey.len(), 0, "Size should be 0");
162204
}
163205

@@ -173,8 +215,13 @@ mod test {
173215

174216
let mut resources = <BaseResources<DecreasingNative> as Resource>::FORMAL_INFINITE;
175217

176-
ecrecover_as_system_function_inner(input.as_slice(), &mut pubkey, &mut resources)
177-
.expect("ecrecover");
218+
ecrecover_as_system_function_inner::<TestingTree<false>, _, _, _>(
219+
input.as_slice(),
220+
&mut pubkey,
221+
&mut resources,
222+
None,
223+
)
224+
.expect("ecrecover");
178225
assert_eq!(pubkey.len(), 0, "Size should be 0 in case of error");
179226
}
180227

@@ -190,8 +237,13 @@ mod test {
190237

191238
let mut resources = <BaseResources<DecreasingNative> as Resource>::FORMAL_INFINITE;
192239

193-
ecrecover_as_system_function_inner(input.as_slice(), &mut pubkey, &mut resources)
194-
.expect("ecrecover");
240+
ecrecover_as_system_function_inner::<TestingTree<false>, _, _, _>(
241+
input.as_slice(),
242+
&mut pubkey,
243+
&mut resources,
244+
None,
245+
)
246+
.expect("ecrecover");
195247
assert_eq!(pubkey.len(), 0, "Size should be 0 in case of error");
196248
}
197249

@@ -213,9 +265,13 @@ mod test {
213265
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 249, 114, 95, 16, 115, 88, 201, 17, 91, 201,
214266
216, 108, 114, 221, 88, 35, 233, 177, 230,
215267
];
216-
217-
ecrecover_as_system_function_inner(input.as_slice(), &mut pubkey, &mut resources)
218-
.expect("ecrecover");
268+
ecrecover_as_system_function_inner::<TestingTree<false>, _, _, _>(
269+
input.as_slice(),
270+
&mut pubkey,
271+
&mut resources,
272+
None,
273+
)
274+
.expect("ecrecover");
219275
assert_eq!(pubkey.len(), 32, "Size should be 32");
220276
assert_eq!(
221277
pubkey, expected_pubkey,

0 commit comments

Comments
 (0)