Skip to content

Commit

Permalink
Add an account contract with secp256r1 sig verification and test it e…
Browse files Browse the repository at this point in the history
…nd-to-end
  • Loading branch information
jayz22 committed Apr 12, 2024
1 parent 4d9b102 commit be6a5a6
Show file tree
Hide file tree
Showing 11 changed files with 414 additions and 253 deletions.
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
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
3 changes: 3 additions & 0 deletions soroban-test-wasms/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,7 @@ 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();
}
Loading

0 comments on commit be6a5a6

Please sign in to comment.