Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an account contract with secp256r1 sig verification and test end-to-end #1402

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions soroban-env-host/src/builtin_contracts/testutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,25 @@ pub(crate) fn sign_payload_for_ed25519(
.unwrap()
}

#[allow(dead_code)]
pub(crate) fn sign_payload_for_secp256r1(
host: &Host,
signer: &p256::ecdsa::SigningKey,
payload: &[u8],
) -> BytesN<64> {
use p256::ecdsa::Signature;
let mut sig: Signature = signer.sign_prehash_recoverable(payload).unwrap().0;
sig = sig.normalize_s().unwrap_or(sig);
println!("produced signature {:x?}", sig.to_bytes());
BytesN::<64>::try_from_val(
host,
&host
.bytes_new_from_slice(sig.to_bytes().as_slice())
.unwrap(),
)
.unwrap()
}

#[allow(clippy::too_many_arguments)]
pub(crate) fn create_account(
host: &Host,
Expand Down
34 changes: 33 additions & 1 deletion soroban-env-host/src/test/invocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
budget::AsBudget, events::HostEvent, test::observe::ObservedHost, xdr::ScErrorType,
ContractFunctionSet, Error, Host, HostError, Symbol, Tag,
};
use soroban_test_wasms::{ADD_I32, ALLOC, ERR, INVOKE_CONTRACT, VEC};
use soroban_test_wasms::{ADD_I32, ALLOC, ERR, INVOKE_CONTRACT, STORAGE_LIST, VEC};

#[test]
fn invoke_single_contract_function() -> Result<(), HostError> {
Expand Down Expand Up @@ -44,6 +44,38 @@ fn invoke_single_contract_function() -> Result<(), HostError> {
Ok(())
}

#[test]
fn invoke_storage_list() -> Result<(), HostError> {
let host = observe_host!(Host::test_host_with_recording_footprint());
let contract_id_obj = host.register_test_contract_wasm(STORAGE_LIST);
let a = 4i32;
let b = 7i32;
let c = 0x7fffffff_i32;

let res = host.call(
contract_id_obj,
Symbol::try_from_small_str("add")?,
host.test_vec_obj(&[a, b])?,
)?;
assert_eq!(i32::try_from_val(&*host, &res)?, a + b);
// overflow
let res = host.call(
contract_id_obj,
Symbol::try_from_small_str("add")?,
host.test_vec_obj(&[a, c])?,
);
let code = (ScErrorType::WasmVm, ScErrorCode::InvalidAction);

eprintln!(
"time ellapsed in nano-seconds for VmInstantiation: {}",
host.as_budget()
.get_time(ContractCostType::VmInstantiation)?
);

assert!(HostError::result_matches_err(res, code));
Ok(())
}

#[test]
fn invoke_alloc() -> Result<(), HostError> {
let host = observe_host!(Host::test_host_with_recording_footprint());
Expand Down
61 changes: 60 additions & 1 deletion soroban-env-host/src/test/stellar_asset_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ use crate::{
Env, EnvBase, Host, HostError, LedgerInfo, Symbol, TryFromVal, TryIntoVal, Val,
};
use ed25519_dalek::SigningKey;
use hex_literal::hex;
use soroban_test_wasms::{
ERR, INVOKE_CONTRACT, SAC_REENTRY_TEST_CONTRACT, SIMPLE_ACCOUNT_CONTRACT,
ERR, INCREMENT, INVOKE_CONTRACT, SAC_REENTRY_TEST_CONTRACT, SIMPLE_ACCOUNT_CONTRACT,
};
use stellar_strkey::ed25519;

Expand Down Expand Up @@ -3060,6 +3061,64 @@ fn test_custom_account_auth() {
.is_err());
}

#[allow(clippy::type_complexity)]
fn secp256r1_sign_fn<'a>(
host: &'a Host,
signing_key: &'a p256::ecdsa::SigningKey,
) -> Box<dyn Fn(&[u8]) -> Val + 'a> {
use crate::builtin_contracts::testutils::sign_payload_for_secp256r1;
Box::new(|payload: &[u8]| -> Val {
sign_payload_for_secp256r1(host, signing_key, payload).into()
})
}

#[test]
fn test_account_with_p256_signer() -> Result<(), HostError> {
use p256::ecdsa::SigningKey;

let host = Host::test_host_with_recording_footprint();
host.set_ledger_info(LedgerInfo {
protocol_version: crate::meta::get_ledger_protocol_version(crate::meta::INTERFACE_VERSION),
sequence_number: 123,
timestamp: 123456,
network_id: [5; 32],
base_reserve: 5_000_000,
min_persistent_entry_ttl: 4096,
min_temp_entry_ttl: 16,
max_entry_ttl: 6_312_000,
})?;
host.enable_debug()?;

let contract_addr_obj = host.register_test_contract_wasm(INCREMENT);
let contract_addr: Address = contract_addr_obj.try_into_val(&host)?;
// key pair taken from RFC 6979 Appendix 2.5 (NIST P-256 + SHA-256)
// <https://tools.ietf.org/html/rfc6979#appendix-A.2.5>
let x = hex!("C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721");
let signing_key = SigningKey::from_bytes(&x.into()).unwrap();
let admin = TestSigner::AccountContract(AccountContractSigner {
address: contract_addr.clone(),
sign: secp256r1_sign_fn(&host, &signing_key),
});
// initialize the contract by calling its `init` with the secp256r1 public key
let verifying_key = host.bytes_new_from_slice(&hex!("0460FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB67903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"))?;
let _ = host.call(
contract_addr_obj.clone(),
Symbol::try_from_small_str("init")?,
test_vec!(&host, verifying_key).into(),
)?;

authorize_single_invocation(&host, &admin, &contract_addr, "increment", test_vec![&host]);

let v = host.call(
contract_addr_obj,
Symbol::try_from_small_str("increment")?,
test_vec![&host].into(),
)?;

assert_eq!(v.get_payload(), Val::from_u32(1).as_val().get_payload());
Ok(())
}

#[test]
fn test_recording_auth_for_stellar_asset_contract() {
let test = StellarAssetContractTest::setup(function_name!());
Expand Down
3 changes: 2 additions & 1 deletion soroban-env-host/src/vm/parsed_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ impl ParsedModule {
host,
(ScErrorType::WasmVm, ScErrorCode::InvalidInput),
"contract protocol number is newer than host",
got_proto
got_proto,
want_proto
));
}
Ok(())
Expand Down
5 changes: 5 additions & 0 deletions soroban-test-wasms/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,9 @@ mod curr {

pub const DEPLOYER_TEST_CONTRACT: &[u8] =
include_bytes!("../wasm-workspace/opt/curr/test_deployer.wasm").as_slice();

pub const INCREMENT: &[u8] =
include_bytes!("../wasm-workspace/opt/curr/increment.wasm").as_slice();
pub const STORAGE_LIST: &[u8] =
include_bytes!("../wasm-workspace/opt/curr/storage_list.wasm").as_slice();
}
Loading
Loading