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

Expose secp256k1 and keccak256 in the SDK #1028

Merged
merged 6 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
29 changes: 29 additions & 0 deletions soroban-sdk/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ impl Crypto {
unsafe { BytesN::unchecked_new(env.clone(), bin) }
}

/// Returns the Keccak-256 hash of the data.
pub fn keccak256(&self, data: &Bytes) -> BytesN<32> {
let env = self.env();
let bin = internal::Env::compute_hash_keccak256(env, data.into()).unwrap_infallible();
unsafe { BytesN::unchecked_new(env.clone(), bin) }
}

/// Verifies an ed25519 signature.
///
/// The signature is verified as a valid signature of the message by the
Expand All @@ -39,4 +46,26 @@ impl Crypto {
signature.to_object(),
);
}

/// Recovers the ECDSA secp256k1 public key.
///
/// The public key returned is the SEC-1-encoded ECDSA secp256k1 public key
/// that produced the 64-byte signature over a given 32-byte message digest,
/// for a given recovery_id byte.
pub fn ecdsa_secp256k1_recover_public_key(
&self,
message_digest: &BytesN<32>,
signature: &BytesN<64>,
recorvery_id: u32,
) -> BytesN<65> {
let env = self.env();
let bytes = internal::Env::recover_key_ecdsa_secp256k1(
env,
message_digest.to_object(),
signature.to_object(),
recorvery_id.into(),
)
.unwrap_infallible();
unsafe { BytesN::unchecked_new(env.clone(), bytes) }
}
}
2 changes: 2 additions & 0 deletions soroban-sdk/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ mod contract_udt_struct_tuple;
mod contractimport;
mod contractimport_with_error;
mod crypto_ed25519;
mod crypto_keccak256;
mod crypto_secp256k1;
mod crypto_sha256;
mod env;
mod prng;
Expand Down
13 changes: 13 additions & 0 deletions soroban-sdk/src/tests/crypto_keccak256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use crate::{bytesn, Env, IntoVal};

#[test]
fn test_keccak256() {
let env = Env::default();

let bytes = b"test vector for soroban".into_val(&env);
let expect = bytesn!(
&env,
0x352fe2eaddf44eb02eb3eab1f8d6ff4ba426df4f1734b1e3f210d621ee8853d9
);
assert_eq!(env.crypto().keccak256(&bytes), expect);
}
26 changes: 26 additions & 0 deletions soroban-sdk/src/tests/crypto_secp256k1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::{bytesn, Env};

#[test]
fn test_recover_key_ecdsa_secp256k1() {
let env = Env::default();

// From: https://github.com/ethereum/go-ethereum/blob/90d5bd85bcf2919ac2735a47fde675213348a0a6/crypto/secp256k1/secp256_test.go#L204-L217
let message_digest = bytesn!(
&env,
0xce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008
);
let signature = bytesn!(
&env,
0x90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc93
);
let recovery_id = 1;
let expected_public_key = bytesn!(
&env,
0x04e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652
);
assert_eq!(
env.crypto()
.ecdsa_secp256k1_recover_public_key(&message_digest, &signature, recovery_id),
expected_public_key
);
}