Skip to content

Commit 20d9235

Browse files
committed
mock signature verification
1 parent 202e670 commit 20d9235

File tree

8 files changed

+94
-25
lines changed

8 files changed

+94
-25
lines changed

bin/full-node/src/run/consensus_service.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ impl ConsensusService {
237237
heap_pages,
238238
exec_hint: executor::vm::ExecHint::CompileAheadOfTime, // TODO: probably should be decided by the optimisticsync
239239
allow_unresolved_imports: false,
240+
mock_signature_verification_host_functions: false,
240241
})
241242
.unwrap()
242243
},

src/chain_spec.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ impl ChainSpec {
105105
heap_pages,
106106
exec_hint: executor::vm::ExecHint::Oneshot,
107107
allow_unresolved_imports: true,
108+
mock_signature_verification_host_functions: false,
108109
})
109110
.map_err(FromGenesisStorageError::VmInitialization)?;
110111

src/executor/host/host_vm.rs

Lines changed: 73 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -656,10 +656,19 @@ impl ReadyToRun {
656656
expect_pointer_constant_size!(2, 32),
657657
);
658658
if let Ok(public_key) = public_key {
659-
let signature =
660-
ed25519_zebra::Signature::from(expect_pointer_constant_size!(0, 64));
659+
let signature = expect_pointer_constant_size!(0, 64);
661660
let message = expect_pointer_size!(1);
662-
public_key.verify(&signature, message.as_ref()).is_ok()
661+
662+
if self.inner.mock_signature_verification_host_functions {
663+
is_magic_signature(signature.as_ref())
664+
} else {
665+
public_key
666+
.verify(
667+
&ed25519_zebra::Signature::from(signature),
668+
message.as_ref(),
669+
)
670+
.is_ok()
671+
}
663672
} else {
664673
false
665674
}
@@ -684,13 +693,17 @@ impl ReadyToRun {
684693
let signature = expect_pointer_constant_size!(0, 64);
685694
let message = expect_pointer_size!(1);
686695

687-
signing_public_key
688-
.verify_simple_preaudit_deprecated(
689-
b"substrate",
690-
message.as_ref(),
691-
&signature,
692-
)
693-
.is_ok()
696+
if self.inner.mock_signature_verification_host_functions {
697+
is_magic_signature(signature.as_ref())
698+
} else {
699+
signing_public_key
700+
.verify_simple_preaudit_deprecated(
701+
b"substrate",
702+
message.as_ref(),
703+
&signature,
704+
)
705+
.is_ok()
706+
}
694707
};
695708

696709
HostVm::ReadyToRun(ReadyToRun {
@@ -705,13 +718,21 @@ impl ReadyToRun {
705718
let signing_public_key =
706719
schnorrkel::PublicKey::from_bytes(&expect_pointer_constant_size!(2, 32))
707720
.unwrap();
708-
let signature =
709-
schnorrkel::Signature::from_bytes(&expect_pointer_constant_size!(0, 64))
710-
.unwrap();
721+
let signature = expect_pointer_constant_size!(0, 64);
711722

712-
signing_public_key
713-
.verify_simple(b"substrate", expect_pointer_size!(1).as_ref(), &signature)
714-
.is_ok()
723+
if self.inner.mock_signature_verification_host_functions {
724+
is_magic_signature(signature.as_ref())
725+
} else {
726+
let signature = schnorrkel::Signature::from_bytes(&signature).unwrap();
727+
728+
signing_public_key
729+
.verify_simple(
730+
b"substrate",
731+
expect_pointer_size!(1).as_ref(),
732+
&signature,
733+
)
734+
.is_ok()
735+
}
715736
};
716737

717738
HostVm::ReadyToRun(ReadyToRun {
@@ -759,20 +780,25 @@ impl ReadyToRun {
759780

760781
// signature (64 bytes) + recovery ID (1 byte)
761782
let sig_bytes = expect_pointer_constant_size!(0, 65);
762-
if let Ok(sig) = libsecp256k1::Signature::parse_standard_slice(&sig_bytes[..64])
763-
{
764-
if let Ok(ri) = libsecp256k1::RecoveryId::parse(sig_bytes[64]) {
765-
if let Ok(actual) = libsecp256k1::recover(&message, &sig, &ri) {
766-
expect_pointer_constant_size!(2, 33)[..]
767-
== actual.serialize_compressed()[..]
783+
if self.inner.mock_signature_verification_host_functions {
784+
is_magic_signature(sig_bytes.as_ref())
785+
} else {
786+
if let Ok(sig) =
787+
libsecp256k1::Signature::parse_standard_slice(&sig_bytes[..64])
788+
{
789+
if let Ok(ri) = libsecp256k1::RecoveryId::parse(sig_bytes[64]) {
790+
if let Ok(actual) = libsecp256k1::recover(&message, &sig, &ri) {
791+
expect_pointer_constant_size!(2, 33)[..]
792+
== actual.serialize_compressed()[..]
793+
} else {
794+
false
795+
}
768796
} else {
769797
false
770798
}
771799
} else {
772800
false
773801
}
774-
} else {
775-
false
776802
}
777803
};
778804

@@ -2113,6 +2139,8 @@ pub struct Inner {
21132139

21142140
/// Memory allocator in order to answer the calls to `malloc` and `free`.
21152141
pub(crate) allocator: allocator::FreeingBumpHeapAllocator,
2142+
2143+
pub(crate) mock_signature_verification_host_functions: bool,
21162144
}
21172145

21182146
impl Inner {
@@ -2278,6 +2306,8 @@ impl Inner {
22782306
heap_pages: self.heap_pages,
22792307
allow_unresolved_imports: self.allow_unresolved_imports,
22802308
memory_total_pages: self.memory_total_pages,
2309+
mock_signature_verification_host_functions: self
2310+
.mock_signature_verification_host_functions,
22812311
}
22822312
}
22832313
}
@@ -2551,13 +2581,31 @@ impl<'a> allocator::Memory for MemAccess<'a> {
25512581
}
25522582
}
25532583

2584+
fn is_magic_signature(signature: &[u8]) -> bool {
2585+
signature.starts_with(&[0xde, 0xad, 0xbe, 0xef]) && signature[4..].iter().all(|&b| b == 0xcd)
2586+
}
2587+
25542588
#[cfg(test)]
25552589
mod tests {
2556-
use super::HostVm;
2590+
use super::{is_magic_signature, HostVm};
25572591

25582592
#[test]
25592593
fn is_send() {
25602594
fn req<T: Send>() {}
25612595
req::<HostVm>();
25622596
}
2597+
2598+
#[test]
2599+
fn is_magic_signature_works() {
2600+
assert!(is_magic_signature(&[0xde, 0xad, 0xbe, 0xef, 0xcd, 0xcd]));
2601+
assert!(is_magic_signature(&[
2602+
0xde, 0xad, 0xbe, 0xef, 0xcd, 0xcd, 0xcd, 0xcd
2603+
]));
2604+
assert!(!is_magic_signature(&[
2605+
0xde, 0xad, 0xbe, 0xef, 0xcd, 0xcd, 0xcd, 0x00
2606+
]));
2607+
assert!(!is_magic_signature(&[
2608+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2609+
]));
2610+
}
25632611
}

src/executor/host/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ pub struct Config<TModule> {
228228
/// a [`Error::UnresolvedFunctionCalled`] error will be generated if the module tries to call
229229
/// an unresolved function.
230230
pub allow_unresolved_imports: bool,
231+
232+
/// Replace the signature verification related host functions with a mock implementation.
233+
/// The mock implementation will return true IF the signature is true OR the signature is
234+
/// magic value `0xdeadbeef` follow by `0xcd` filling the rest of bytes.
235+
/// NOTE: This should only enabled for testing purposes.
236+
pub mock_signature_verification_host_functions: bool,
231237
}
232238

233239
/// Prototype for an [`HostVm`].
@@ -269,6 +275,12 @@ pub struct HostVmPrototype {
269275
/// Total number of pages of Wasm memory. This is equal to `heap_base / 64k` (rounded up) plus
270276
/// `heap_pages`.
271277
memory_total_pages: HeapPages,
278+
279+
/// Replace the signature verification related host functions with a mock implementation.
280+
/// The mock implementation will return true IF the signature is true OR the signature is
281+
/// magic value `0xdeadbeef` follow by `0xcd`.
282+
/// NOTE: This should only enabled for testing purposes.
283+
mock_signature_verification_host_functions: bool,
272284
}
273285

274286
impl HostVmPrototype {
@@ -353,6 +365,7 @@ impl HostVmPrototype {
353365
heap_pages,
354366
allow_unresolved_imports,
355367
memory_total_pages,
368+
mock_signature_verification_host_functions: false,
356369
};
357370

358371
// Call `Core_version` if no runtime version is known yet.
@@ -484,6 +497,8 @@ impl HostVmPrototype {
484497
registered_functions: self.registered_functions,
485498
storage_transaction_depth: 0,
486499
allocator,
500+
mock_signature_verification_host_functions: self
501+
.mock_signature_verification_host_functions,
487502
},
488503
})
489504
}

src/executor/read_only_runtime_host.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ impl Inner {
304304
heap_pages: executor::DEFAULT_HEAP_PAGES,
305305
exec_hint: vm::ExecHint::Oneshot,
306306
allow_unresolved_imports: false, // TODO: what is a correct value here?
307+
mock_signature_verification_host_functions: false,
307308
}) {
308309
Ok(w) => w,
309310
Err(_) => {

src/executor/runtime_host.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ impl Inner {
668668
heap_pages: executor::DEFAULT_HEAP_PAGES,
669669
exec_hint: vm::ExecHint::Oneshot,
670670
allow_unresolved_imports: false, // TODO: what is a correct value here?
671+
mock_signature_verification_host_functions: false,
671672
}) {
672673
Ok(w) => w,
673674
Err(_) => {

src/sync/warp_sync.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,7 @@ impl<TSrc, TRq> BuildRuntime<TSrc, TRq> {
11051105
heap_pages: decoded_heap_pages,
11061106
exec_hint,
11071107
allow_unresolved_imports,
1108+
mock_signature_verification_host_functions: false,
11081109
}) {
11091110
Ok(runtime) => runtime,
11101111
Err(err) => {

src/verify/header_body.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ impl RuntimeCompilation {
675675
heap_pages: self.heap_pages,
676676
exec_hint: vm::ExecHint::CompileAheadOfTime,
677677
allow_unresolved_imports: false,
678+
mock_signature_verification_host_functions: false,
678679
}) {
679680
Ok(vm) => vm,
680681
Err(err) => {

0 commit comments

Comments
 (0)