Skip to content

Commit

Permalink
Add testutils to build ed25519 keypairs (#764)
Browse files Browse the repository at this point in the history
### What

Test utils to build ed25519 keypairs from a Stellar public key and
secret key.

### Why

There currently is no way to build signatures for existing ed25519
keypairs, so if I wanted to generate signatures in tests or in a script
to use them later with the CLI, I'd have to build the keypair and strkey
decoding myself. With this PR users are provided with a function to
build the keypair from a Stellar public and secret key (as you can see
in tests).

### Known limitations

N/A

Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com>
  • Loading branch information
heytdep and leighmcculloch authored Dec 2, 2022
1 parent 2c9d157 commit efeed7d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions soroban-auth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rand = { version = "0.7.3", optional = true }

[dev_dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }
stellar-strkey = { workspace = true }
ed25519-dalek = { version = "1.0.1" }
rand = { version = "0.7.3" }

Expand Down
42 changes: 41 additions & 1 deletion soroban-auth/src/tests/test_ed25519.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
extern crate std;

use core::str::FromStr;

use soroban_sdk::{
contractimpl, symbol,
testutils::{Ledger, LedgerInfo},
BytesN, Env,
};

use crate::{
testutils::ed25519::{generate, sign},
testutils::ed25519::{generate, sign, signer},
verify, Signature,
};

Expand Down Expand Up @@ -58,3 +60,41 @@ fn test() {

client.examplefn(&sig, &1, &2);
}

#[test]
fn test_build_keypair() {
let env = Env::default();
let contract_id = BytesN::from_array(&env, &[0; 32]);
env.register_contract(&contract_id, ExampleContract);
let client = ExampleContractClient::new(&env, &contract_id);

env.ledger().set(LedgerInfo {
base_reserve: 0,
network_passphrase: "soroban-auth test".as_bytes().to_vec(),
protocol_version: 0,
sequence_number: 0,
timestamp: 0,
});

std::println!("network: {:?}", env.ledger().network_passphrase());
std::println!("contract id: {:?}", contract_id);
std::println!("name: {:?}", symbol!("examplefn"));

let key = stellar_strkey::StrkeyPrivateKeyEd25519::from_str(
"SC24O4H2LT4PVOYCWMKUSD2DL4UL26IYGPFKANDH7S4MU6JVQEFOS7DC",
)
.unwrap();
let (id, signer) = signer(&env, &key.0);
std::println!("signer: {:?}", signer);
std::println!("id: {:?}", id);
let sig = sign(
&env,
&signer,
&contract_id,
symbol!("examplefn"),
(&id, &1, &2),
);
std::println!("signature: {:?}", sig);

client.examplefn(&sig, &1, &2);
}
19 changes: 19 additions & 0 deletions soroban-auth/src/testutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,25 @@ pub mod ed25519 {
(signer.identifier(env), signer)
}

/// Create a signer from a ed25519 secret key.
pub fn signer(
env: &Env,
secret_key: &[u8; 32],
) -> (
IdentifierValue,
impl Identifier + Sign<SignaturePayload, Signature = [u8; 64]> + Debug,
) {
let secret = ed25519_dalek::SecretKey::from_bytes(secret_key).unwrap();
let public = ed25519_dalek::PublicKey::from(&secret);
let signer = ed25519_dalek::Keypair { secret, public };
(signer.identifier(env), signer)
}

/// Create an identifier from a ed25519 public key.
pub fn identifier(env: &Env, public_key: &[u8; 32]) -> IdentifierValue {
IdentifierValue::Ed25519(public_key.into_val(env))
}

/// Sign a [`SignaturePayload`] constructed using the arguments.
///
/// The returned [`Signature`] can be verified by [`verify`](crate::verify)
Expand Down

0 comments on commit efeed7d

Please sign in to comment.