Skip to content

Commit

Permalink
Implement contract spec for Hash
Browse files Browse the repository at this point in the history
  • Loading branch information
jayz22 committed Apr 12, 2024
1 parent 2f153f0 commit 04a24d4
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ rev = "a80c899c61e869fd00b7b475a4947ab6aaf9dcac"
#soroban-env-common = { path = "../rs-soroban-env/soroban-env-common" }
#soroban-env-guest = { path = "../rs-soroban-env/soroban-env-guest" }
#soroban-env-host = { path = "../rs-soroban-env/soroban-env-host/" }
#[patch."https://github.com/stellar/rs-stellar-xdr"]
#stellar-xdr = { path = "../rs-stellar-xdr/" }
[patch."https://github.com/stellar/rs-stellar-xdr"]
stellar-xdr = {git = "https://github.com/jayz22/rs-stellar-xdr", rev = "42784f87be643717f782c9d1e69832f992ae3d0b" }

[profile.dev]
overflow-checks = true
Expand Down
23 changes: 17 additions & 6 deletions soroban-sdk-macros/src/map_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use ::stellar_xdr::curr::ScSpectTypeHash;
use stellar_xdr::curr as stellar_xdr;
use stellar_xdr::{
ScSpecTypeBytesN, ScSpecTypeDef, ScSpecTypeMap, ScSpecTypeOption, ScSpecTypeResult,
Expand Down Expand Up @@ -104,14 +105,24 @@ pub fn map_type(t: &Type) -> Result<ScSpecTypeDef, Error> {
}
"BytesN" => {
let n = match args.as_slice() {
[GenericArgument::Const(Expr::Lit(ExprLit { lit: Lit::Int(int), .. }))] => int.base10_parse()?,
[..] => Err(Error::new(
t.span(),
"incorrect number of generic arguments, expect one for BytesN<N>",
))?,
};
[GenericArgument::Const(Expr::Lit(ExprLit { lit: Lit::Int(int), .. }))] => int.base10_parse()?,
[..] => Err(Error::new(
t.span(),
"incorrect number of generic arguments, expect one for BytesN<N>",
))?,
};
Ok(ScSpecTypeDef::BytesN(ScSpecTypeBytesN { n }))
}
"Hash" => {
let n = match args.as_slice() {
[GenericArgument::Const(Expr::Lit(ExprLit { lit: Lit::Int(int), .. }))] => int.base10_parse()?,
[..] => Err(Error::new(
t.span(),
"incorrect number of generic arguments, expect one for BytesN<N>",
))?,
};
Ok(ScSpecTypeDef::Hash(ScSpectTypeHash { n }))
}
_ => Err(Error::new(
angle_bracketed.span(),
"generics unsupported on user-defined types in contract functions",
Expand Down
4 changes: 2 additions & 2 deletions soroban-sdk/src/auth.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Auth contains types for building custom account contracts.

use crate::{contracttype, crypto::Digest, Address, BytesN, Env, Error, Symbol, Val, Vec};
use crate::{contracttype, crypto::Hash, Address, BytesN, Env, Error, Symbol, Val, Vec};

/// Context of a single authorized call performed by an address.
///
Expand Down Expand Up @@ -77,7 +77,7 @@ pub trait CustomAccountInterface {
/// Check that the signatures and auth contexts are valid.
fn __check_auth(
env: Env,
signature_payload: Digest,
signature_payload: Hash<32>,
signatures: Self::Signature,
auth_contexts: Vec<Context>,
) -> Result<(), Self::Error>;
Expand Down
40 changes: 20 additions & 20 deletions soroban-sdk/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,48 @@ use crate::{
TryFromVal, Val,
};

/// A wrapper type for a 32-byte cryptographic hash.
/// A wrapper type for a cryptographic hash.
///
/// This struct is designed to be used in contexts where a hash value generated
/// by a secure cryptographic function is required.
pub struct Digest(BytesN<32>);
pub struct Hash<const N: usize>(BytesN<N>);

impl Digest {
/// Constructs a new `Digest` from a fixed-length bytes array.
pub fn from_bytes(bytes: BytesN<32>) -> Self {
impl<const N: usize> Hash<N> {
/// Constructs a new `Hash` from a fixed-length bytes array.
pub fn from_bytes(bytes: BytesN<N>) -> Self {
Self(bytes)
}
}

impl IntoVal<Env, Val> for Digest {
impl<const N: usize> IntoVal<Env, Val> for Hash<N> {
fn into_val(&self, e: &Env) -> Val {
self.0.into_val(e)
}
}

impl IntoVal<Env, BytesN<32>> for Digest {
fn into_val(&self, _e: &Env) -> BytesN<32> {
impl<const N: usize> IntoVal<Env, BytesN<N>> for Hash<N> {
fn into_val(&self, _e: &Env) -> BytesN<N> {
self.0.clone()
}
}

impl Into<BytesN<32>> for Digest {
fn into(self) -> BytesN<32> {
impl<const N: usize> Into<BytesN<N>> for Hash<N> {
fn into(self) -> BytesN<N> {
self.0
}
}

impl Into<[u8; 32]> for Digest {
fn into(self) -> [u8; 32] {
impl<const N: usize> Into<[u8; N]> for Hash<N> {
fn into(self) -> [u8; N] {
self.0.into()
}
}

impl TryFromVal<Env, Val> for Digest {
impl<const N: usize> TryFromVal<Env, Val> for Hash<N> {
type Error = ConversionError;

fn try_from_val(env: &Env, v: &Val) -> Result<Self, Self::Error> {
Ok(Digest(BytesN::<32>::try_from_val(env, v)?))
Ok(Hash(BytesN::<N>::try_from_val(env, v)?))
}
}

Expand All @@ -65,17 +65,17 @@ impl Crypto {
}

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

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

/// Verifies an ed25519 signature.
Expand Down Expand Up @@ -103,7 +103,7 @@ impl Crypto {
/// for a given recovery_id byte.
pub fn secp256k1_recover(
&self,
message_digest: &Digest,
message_digest: &Hash<32>,
signature: &BytesN<64>,
recorvery_id: u32,
) -> BytesN<65> {
Expand All @@ -118,7 +118,7 @@ impl Crypto {
pub fn secp256r1_verify(
&self,
public_key: &BytesN<65>,
message_digest: &Digest,
message_digest: &Hash<32>,
signature: &BytesN<64>,
) {
let env = self.env();
Expand Down
4 changes: 2 additions & 2 deletions soroban-sdk/src/tests/crypto_secp256k1.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::{bytesn, crypto::Digest, Env};
use crate::{bytesn, crypto::Hash, 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 = Digest::from_bytes(bytesn!(
let message_digest = Hash::from_bytes(bytesn!(
&env,
0xce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008
));
Expand Down
4 changes: 2 additions & 2 deletions soroban-sdk/src/tests/crypto_secp256r1.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{bytesn, crypto::Digest, Env};
use crate::{bytesn, crypto::Hash, Env};

#[test]
fn test_recover_key_ecdsa_secp256r1() {
Expand All @@ -7,7 +7,7 @@ fn test_recover_key_ecdsa_secp256r1() {
// Test vector copied and adapted from
// https://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
// `SigVer.rsp` section [P-256,SHA-256]
let message_digest = Digest::from_bytes(bytesn!(
let message_digest = Hash::from_bytes(bytesn!(
&env,
0xd1b8ef21eb4182ee270638061063a3f3c16c114e33937f69fb232cc833965a94
));
Expand Down
4 changes: 4 additions & 0 deletions soroban-spec-rust/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ pub fn generate_type_ident(spec: &ScSpecTypeDef) -> TokenStream {
let n = Literal::u32_unsuffixed(b.n);
quote! { soroban_sdk::BytesN<#n> }
}
ScSpecTypeDef::Hash(b) => {
let n = Literal::u32_unsuffixed(b.n);
quote! { soroban_sdk::Hash<#n> }
}
ScSpecTypeDef::Udt(u) => {
let ident = format_ident!("{}", u.name.to_utf8_string().unwrap());
quote! { #ident }
Expand Down

0 comments on commit 04a24d4

Please sign in to comment.