Skip to content

Commit

Permalink
Add attest endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ameba23 committed Aug 12, 2024
1 parent 142648d commit 11f4b39
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 3 deletions.
3 changes: 2 additions & 1 deletion crates/threshold-signature-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ sha1 ="0.10.6"
sha2 ="0.10.8"
hkdf ="0.12.4"
project-root ={ version="0.2.2", optional=true }
tdx-quote ={ git="https://github.com/entropyxyz/tdx-quote", optional=true, features=["mock"] }

[dev-dependencies]
serial_test ="3.1.1"
Expand Down Expand Up @@ -102,7 +103,7 @@ vergen={ version="8.3.2", features=["build", "git", "gitcl"] }
default =['std']
std =["sp-core/std"]
test_helpers=["dep:project-root"]
unsafe =[]
unsafe =["dep:tdx-quote"]
alice =[]
bob =[]
# Enable this feature to run the integration tests for the wasm API of entropy-protocol
Expand Down
3 changes: 2 additions & 1 deletion crates/threshold-signature-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ use crate::{
r#unsafe::api::{delete, put, remove_keys, unsafe_get},
signing_client::{api::*, ListenerState},
user::api::*,
validator::api::new_reshare,
validator::api::{attest, new_reshare},
};

#[derive(Clone)]
Expand All @@ -178,6 +178,7 @@ pub fn app(app_state: AppState) -> Router {
.route("/user/sign_tx", post(sign_tx))
.route("/signer/proactive_refresh", post(proactive_refresh))
.route("/validator/reshare", post(new_reshare))
.route("/attest", post(attest))
.route("/healthz", get(healthz))
.route("/version", get(get_version))
.route("/hashes", get(hashes))
Expand Down
59 changes: 59 additions & 0 deletions crates/threshold-signature-server/src/validator/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::{
AppState,
};
use axum::{body::Bytes, extract::State, http::StatusCode};
use blake2::{Blake2b512, Digest};
use entropy_kvdb::kv_manager::{helpers::serialize as key_serialize, KvManager};
use entropy_protocol::Subsession;
pub use entropy_protocol::{
Expand Down Expand Up @@ -360,3 +361,61 @@ pub async fn prune_old_holders(
validators_info.clone()
})
}

#[cfg(not(feature = "unsafe"))]
pub async fn attest(
State(_app_state): State<AppState>,
_input: Bytes,
) -> Result<StatusCode, ValidatorErr> {
// Non-mock attestation (the real thing) will go here
Err(ValidatorErr::NotImplemented)
}

#[cfg(feature = "unsafe")]
pub async fn attest(
State(app_state): State<AppState>,
input: Bytes,
) -> Result<(StatusCode, String), ValidatorErr> {
let nonce = input[..].try_into()?;

let rpc = get_rpc(&app_state.configuration.endpoint).await?;

let block_number = rpc
.chain_get_header(None)
.await?
.ok_or_else(|| ValidatorErr::OptionUnwrapError("Failed to get block number".to_string()))?
.number;

// In the real thing this is the hardware key used in the quoting enclave
let signing_key = tdx_quote::SigningKey::random(&mut OsRng);

let (signer, x25519_secret) = get_signer_and_x25519_secret(&app_state.kv_store).await?;
let public_key = x25519_dalek::PublicKey::from(&x25519_secret);

let input_data =
QuoteInputData::new(signer.signer().public().into(), public_key, nonce, block_number);

let quote = tdx_quote::Quote::mock(signing_key.clone(), input_data.0);
// Here we would submit an attest extrinsic to the chain - but for now we just include it in the
// response
Ok((StatusCode::OK, format!("{:?}", quote)))
}

/// Input data to be included in a TDX attestation
pub struct QuoteInputData(pub [u8; 64]);

impl QuoteInputData {
pub fn new(
account_id: AccountId32,
x25519_public_key: x25519_dalek::PublicKey,
nonce: [u8; 32],
block_number: u32,
) -> Self {
let mut hasher = Blake2b512::new();
hasher.update(account_id.0);
hasher.update(x25519_public_key.as_bytes());
hasher.update(nonce);
hasher.update(block_number.to_be_bytes());
Self(hasher.finalize().into())
}
}
6 changes: 5 additions & 1 deletion crates/threshold-signature-server/src/validator/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use std::string::FromUtf8Error;
use std::{array::TryFromSliceError, string::FromUtf8Error};

use crate::signing_client::ProtocolErr;
use axum::{
Expand Down Expand Up @@ -93,6 +93,10 @@ pub enum ValidatorErr {
InvalidData,
#[error("Data is repeated")]
RepeatedData,
#[error("Not yet implemented")]
NotImplemented,
#[error("Input must be 32 bytes: {0}")]
TryFromSlice(#[from] TryFromSliceError),
}

impl IntoResponse for ValidatorErr {
Expand Down
15 changes: 15 additions & 0 deletions crates/threshold-signature-server/src/validator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,18 @@ async fn test_forbidden_keys() {
let should_pass = check_forbidden_key("test");
assert_eq!(should_pass.unwrap(), ());
}

#[tokio::test]
#[serial]
async fn test_attest() {
initialize_test_logger().await;
clean_tests();

// let cxt = test_node_process_testing_state(false).await;
let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await;

let client = reqwest::Client::new();
let res =
client.post(format!("http://127.0.0.1:3001/attest")).body(Vec::new()).send().await.unwrap();
println!("{:?}", res.text().await);
}

0 comments on commit 11f4b39

Please sign in to comment.