chore: remove notarize methods for prover and verifier (#952)

* feat: remove notarize methods for prover and verifier

* clean up imports

* remove remaining notarize methods

* clean up imports

* remove wasm attestation bindings

---------

Co-authored-by: sinu <65924192+sinui0@users.noreply.github.com>
This commit is contained in:
th4s
2025-08-06 18:38:43 +02:00
committed by GitHub
parent 2f072b2578
commit 657838671a
8 changed files with 5 additions and 608 deletions

View File

@@ -32,20 +32,16 @@ use crate::{
use futures::{AsyncRead, AsyncWrite, TryFutureExt};
use mpc_tls::{LeaderCtrl, MpcTlsLeader, SessionKeys};
use rand::Rng;
use serio::{SinkExt, stream::IoStreamExt};
use serio::SinkExt;
use std::sync::Arc;
use tls_client::{ClientConnection, ServerName as TlsServerName};
use tls_client_async::{TlsConnection, bind_client};
use tls_core::msgs::enums::ContentType;
use tlsn_attestation::{
Attestation, CryptoProvider, Secrets,
request::{Request, RequestConfig},
};
use tlsn_core::{
ProvePayload,
connection::ServerCertData,
hash::{Blake3, HashAlgId, HashAlgorithm, Keccak256, Sha256},
transcript::{Direction, TlsTranscript, Transcript, TranscriptCommitment, TranscriptSecret},
transcript::{TlsTranscript, Transcript, TranscriptCommitment, TranscriptSecret},
};
use tlsn_deap::Deap;
use tokio::sync::Mutex;
@@ -458,118 +454,6 @@ impl Prover<state::Committed> {
Ok(output)
}
/// Requests an attestation from the verifier.
///
/// # Arguments
///
/// * `config` - The attestation request configuration.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
#[deprecated(
note = "attestation functionality will be removed from this API in future releases."
)]
pub async fn notarize(
&mut self,
config: &RequestConfig,
) -> Result<(Attestation, Secrets), ProverError> {
#[allow(deprecated)]
self.notarize_with_provider(config, &CryptoProvider::default())
.await
}
/// Requests an attestation from the verifier.
///
/// # Arguments
///
/// * `config` - The attestation request configuration.
/// * `provider` - Cryptography provider.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
#[deprecated(
note = "attestation functionality will be removed from this API in future releases."
)]
pub async fn notarize_with_provider(
&mut self,
config: &RequestConfig,
provider: &CryptoProvider,
) -> Result<(Attestation, Secrets), ProverError> {
let mut builder = ProveConfig::builder(self.transcript());
if let Some(config) = config.transcript_commit() {
// Temporarily, we reject attestation requests which contain hash commitments to
// subsets of the transcript. We do this because we want to preserve the
// obliviousness of the reference notary, and hash commitments currently leak
// the ranges which are being committed.
for ((direction, idx), _) in config.iter_hash() {
let len = match direction {
Direction::Sent => self.transcript().sent().len(),
Direction::Received => self.transcript().received().len(),
};
if idx.start() > 0 || idx.end() < len || idx.count() != 1 {
return Err(ProverError::attestation(
"hash commitments to subsets of the transcript are currently not supported in attestation requests",
));
}
}
builder.transcript_commit(config.clone());
}
let disclosure_config = builder.build().map_err(ProverError::attestation)?;
let ProverOutput {
transcript_commitments,
transcript_secrets,
..
} = self.prove(&disclosure_config).await?;
let state::Committed {
mux_fut,
ctx,
tls_transcript,
transcript,
..
} = &mut self.state;
let mut builder = Request::builder(config);
builder
.server_name(self.config.server_name().clone())
.server_cert_data(ServerCertData {
certs: tls_transcript
.server_cert_chain()
.expect("server cert chain is present")
.to_vec(),
sig: tls_transcript
.server_signature()
.expect("server signature is present")
.clone(),
handshake: tls_transcript.handshake_data().clone(),
})
.transcript(transcript.clone())
.transcript_commitments(transcript_secrets, transcript_commitments);
let (request, secrets) = builder.build(provider).map_err(ProverError::attestation)?;
let attestation = mux_fut
.poll_with(async {
debug!("sending attestation request");
ctx.io_mut().send(request.clone()).await?;
let attestation: Attestation = ctx.io_mut().expect_next().await?;
Ok::<_, ProverError>(attestation)
})
.await?;
// Check the attestation is consistent with the Prover's view.
request
.validate(&attestation)
.map_err(ProverError::attestation)?;
Ok((attestation, secrets))
}
/// Closes the connection with the verifier.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
pub async fn close(self) -> Result<(), ProverError> {

View File

@@ -49,13 +49,6 @@ impl ProverError {
{
Self::new(ErrorKind::Commit, source)
}
pub(crate) fn attestation<E>(source: E) -> Self
where
E: Into<Box<dyn Error + Send + Sync + 'static>>,
{
Self::new(ErrorKind::Attestation, source)
}
}
#[derive(Debug)]
@@ -65,7 +58,6 @@ enum ErrorKind {
Zk,
Config,
Commit,
Attestation,
}
impl fmt::Display for ProverError {
@@ -78,7 +70,6 @@ impl fmt::Display for ProverError {
ErrorKind::Zk => f.write_str("zk error")?,
ErrorKind::Config => f.write_str("config error")?,
ErrorKind::Commit => f.write_str("commit error")?,
ErrorKind::Attestation => f.write_str("attestation error")?,
}
if let Some(source) = &self.source {

View File

@@ -30,12 +30,11 @@ use mpz_common::Context;
use mpz_core::Block;
use mpz_garble_core::Delta;
use mpz_vm_core::prelude::*;
use serio::{SinkExt, stream::IoStreamExt};
use serio::stream::IoStreamExt;
use tls_core::{msgs::enums::ContentType, verify::WebPkiVerifier};
use tlsn_attestation::{Attestation, AttestationConfig, CryptoProvider, request::Request};
use tlsn_core::{
ProvePayload,
connection::{ConnectionInfo, ServerName, TranscriptLength},
connection::{ConnectionInfo, ServerName},
transcript::{TlsTranscript, TranscriptCommitment},
};
use tlsn_deap::Deap;
@@ -152,59 +151,6 @@ impl Verifier<state::Initialized> {
})
}
/// Runs the verifier to completion and attests to the TLS session.
///
/// This is a convenience method which runs all the steps needed for
/// notarization.
///
/// # Arguments
///
/// * `socket` - The socket to the prover.
/// * `config` - The attestation configuration.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
#[deprecated(
note = "attestation functionality will be removed from this API in future releases."
)]
pub async fn notarize<S: AsyncWrite + AsyncRead + Send + Unpin + 'static>(
self,
socket: S,
config: &AttestationConfig,
) -> Result<Attestation, VerifierError> {
#[allow(deprecated)]
self.notarize_with_provider(socket, config, &CryptoProvider::default())
.await
}
/// Runs the verifier to completion and attests to the TLS session.
///
/// This is a convenience method which runs all the steps needed for
/// notarization.
///
/// # Arguments
///
/// * `socket` - The socket to the prover.
/// * `config` - The attestation configuration.
/// * `provider` - Cryptography provider.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
#[deprecated(
note = "attestation functionality will be removed from this API in future releases."
)]
pub async fn notarize_with_provider<S: AsyncWrite + AsyncRead + Send + Unpin + 'static>(
self,
socket: S,
config: &AttestationConfig,
provider: &CryptoProvider,
) -> Result<Attestation, VerifierError> {
let mut verifier = self.setup(socket).await?.run().await?;
#[allow(deprecated)]
let attestation = verifier.notarize_with_provider(config, provider).await?;
verifier.close().await?;
Ok(attestation)
}
/// Runs the TLS verifier to completion, verifying the TLS session.
///
/// This is a convenience method which runs all the steps needed for
@@ -472,123 +418,6 @@ impl Verifier<state::Committed> {
})
}
/// Attests to the TLS session.
///
/// # Arguments
///
/// * `config` - Attestation configuration.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
#[deprecated(
note = "attestation functionality will be removed from this API in future releases."
)]
pub async fn notarize(
&mut self,
config: &AttestationConfig,
) -> Result<Attestation, VerifierError> {
#[allow(deprecated)]
self.notarize_with_provider(config, &CryptoProvider::default())
.await
}
/// Attests to the TLS session.
///
/// # Arguments
///
/// * `config` - Attestation configuration.
/// * `provider` - Cryptography provider.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
#[deprecated(
note = "attestation functionality will be removed from this API in future releases."
)]
pub async fn notarize_with_provider(
&mut self,
config: &AttestationConfig,
provider: &CryptoProvider,
) -> Result<Attestation, VerifierError> {
let VerifierOutput {
server_name,
transcript,
transcript_commitments,
} = self.verify(&VerifyConfig::default()).await?;
if server_name.is_some() {
return Err(VerifierError::attestation(
"server name can not be revealed to a verifier",
));
} else if transcript.is_some() {
return Err(VerifierError::attestation(
"transcript data can not be revealed to a verifier",
));
}
let state::Committed {
mux_fut,
ctx,
tls_transcript,
..
} = &mut self.state;
let sent_len = tls_transcript
.sent()
.iter()
.filter_map(|record| {
if let ContentType::ApplicationData = record.typ {
Some(record.ciphertext.len())
} else {
None
}
})
.sum::<usize>();
let recv_len = tls_transcript
.recv()
.iter()
.filter_map(|record| {
if let ContentType::ApplicationData = record.typ {
Some(record.ciphertext.len())
} else {
None
}
})
.sum::<usize>();
let request: Request = mux_fut
.poll_with(ctx.io_mut().expect_next().map_err(VerifierError::from))
.await?;
let mut builder = Attestation::builder(config)
.accept_request(request)
.map_err(VerifierError::attestation)?;
builder
.connection_info(ConnectionInfo {
time: tls_transcript.time(),
version: (*tls_transcript.version()),
transcript_length: TranscriptLength {
sent: sent_len as u32,
received: recv_len as u32,
},
})
.server_ephemeral_key(tls_transcript.server_ephemeral_key().clone())
.transcript_commitments(transcript_commitments);
let attestation = builder
.build(provider)
.map_err(VerifierError::attestation)?;
mux_fut
.poll_with(
ctx.io_mut()
.send(attestation.clone())
.map_err(VerifierError::from),
)
.await?;
info!("Sent attestation");
Ok(attestation)
}
/// Closes the connection with the prover.
#[instrument(parent = &self.span, level = "info", skip_all, err)]
pub async fn close(self) -> Result<(), VerifierError> {

View File

@@ -34,13 +34,6 @@ impl VerifierError {
Self::new(ErrorKind::Zk, source)
}
pub(crate) fn attestation<E>(source: E) -> Self
where
E: Into<Box<dyn Error + Send + Sync + 'static>>,
{
Self::new(ErrorKind::Attestation, source)
}
pub(crate) fn verify<E>(source: E) -> Self
where
E: Into<Box<dyn Error + Send + Sync + 'static>>,
@@ -56,7 +49,6 @@ enum ErrorKind {
Mpc,
Zk,
Commit,
Attestation,
Verify,
}
@@ -70,7 +62,6 @@ impl fmt::Display for VerifierError {
ErrorKind::Mpc => f.write_str("mpc error")?,
ErrorKind::Zk => f.write_str("zk error")?,
ErrorKind::Commit => f.write_str("commit error")?,
ErrorKind::Attestation => f.write_str("attestation error")?,
ErrorKind::Verify => f.write_str("verification error")?,
}

View File

@@ -14,12 +14,9 @@ pub mod verifier;
pub use log::{LoggingConfig, LoggingLevel};
use tlsn::{attestation::CryptoProvider, transcript::Direction};
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::JsFuture;
use crate::types::{Attestation, Presentation, Reveal, Secrets};
#[cfg(feature = "test")]
pub use tests::*;
@@ -46,34 +43,3 @@ pub async fn initialize(
Ok(())
}
/// Builds a presentation.
#[wasm_bindgen]
pub fn build_presentation(
attestation: &Attestation,
secrets: &Secrets,
reveal: Reveal,
) -> Result<Presentation, JsError> {
let provider = CryptoProvider::default();
let mut builder = attestation.0.presentation_builder(&provider);
builder.identity_proof(secrets.0.identity_proof());
let mut proof_builder = secrets.0.transcript_proof_builder();
for range in reveal.sent.iter() {
proof_builder.reveal(range, Direction::Sent)?;
}
for range in reveal.recv.iter() {
proof_builder.reveal(range, Direction::Received)?;
}
builder.transcript_proof(proof_builder.build()?);
builder
.build()
.map(Presentation::from)
.map_err(JsError::from)
}

View File

@@ -7,11 +7,7 @@ use futures::TryFutureExt;
use http_body_util::{BodyExt, Full};
use hyper::body::Bytes;
use tls_client_async::TlsConnection;
use tlsn::{
attestation::request::RequestConfig,
prover::{state, ProveConfig, Prover},
transcript::TranscriptCommitConfigBuilder,
};
use tlsn::prover::{state, ProveConfig, Prover};
use tracing::info;
use wasm_bindgen::{prelude::*, JsError};
use wasm_bindgen_futures::spawn_local;
@@ -108,44 +104,6 @@ impl JsProver {
Ok(Transcript::from(prover.transcript()))
}
/// Runs the notarization protocol.
pub async fn notarize(&mut self, commit: Commit) -> Result<NotarizationOutput> {
let mut prover = self.state.take().try_into_committed()?;
info!("starting notarization");
let mut builder = TranscriptCommitConfigBuilder::new(prover.transcript());
for range in commit.sent {
builder.commit_sent(&range)?;
}
for range in commit.recv {
builder.commit_recv(&range)?;
}
let transcript_commit = builder.build()?;
let mut builder = RequestConfig::builder();
builder.transcript_commit(transcript_commit);
let request_config = builder.build()?;
#[allow(deprecated)]
let (attestation, secrets) = prover.notarize(&request_config).await?;
prover.close().await?;
info!("notarization complete");
self.state = State::Complete;
Ok(NotarizationOutput {
attestation: attestation.into(),
secrets: secrets.into(),
})
}
/// Reveals data to the verifier and finalizes the protocol.
pub async fn reveal(&mut self, reveal: Reveal) -> Result<()> {
let mut prover = self.state.take().try_into_committed()?;

View File

@@ -78,83 +78,6 @@ pub async fn test_prove() -> Result<(), JsValue> {
Ok(())
}
#[wasm_bindgen]
pub async fn test_notarize() -> Result<(), JsValue> {
let mut root_store = tls_core::anchors::RootCertStore::empty();
root_store
.add(&tls_core::key::Certificate(CA_CERT_DER.to_vec()))
.unwrap();
let provider = CryptoProvider {
cert: WebPkiVerifier::new(root_store, None),
..Default::default()
};
let prover = Prover::new(
ProverConfig::builder()
.server_name(SERVER_DOMAIN)
.protocol_config(
ProtocolConfig::builder()
.max_sent_data(1024)
.max_recv_data(1024)
.build()
.unwrap(),
)
.crypto_provider(provider)
.build()
.unwrap(),
);
let mut prover = JsProver::from(prover);
let uri = format!("https://{SERVER_DOMAIN}/bytes?size=512");
prover
.setup("ws://localhost:8080/tcp?addr=localhost%3A8011")
.await?;
prover
.send_request(
"ws://localhost:8080/tcp?addr=localhost%3A8083",
HttpRequest {
method: Method::GET,
uri,
headers: HashMap::from([("Accept".to_string(), b"*".to_vec())]),
body: None,
},
)
.await?;
let _ = prover.transcript()?;
let NotarizationOutput {
attestation,
secrets,
} = prover
.notarize(Commit {
sent: vec![0..10],
recv: vec![0..10],
})
.await?;
let attestation = Attestation::deserialize(attestation.serialize())?;
let secrets = Secrets::deserialize(secrets.serialize())?;
let presentation = build_presentation(
&attestation,
&secrets,
Reveal {
sent: vec![(0..10)],
recv: vec![(0..10)],
server_identity: false,
},
)?;
let _ = Presentation::deserialize(presentation.serialize())?;
Ok(())
}
#[wasm_bindgen]
pub async fn test_verifier() -> Result<(), JsValue> {
let mut root_store = tls_core::anchors::RootCertStore::empty();

View File

@@ -4,7 +4,6 @@ use http_body_util::Full;
use hyper::body::Bytes;
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use tlsn::attestation::CryptoProvider;
use tsify_next::Tsify;
use wasm_bindgen::prelude::*;
@@ -174,134 +173,6 @@ pub struct Reveal {
pub server_identity: bool,
}
#[derive(Debug, Tsify, Deserialize)]
#[tsify(from_wasm_abi)]
pub enum KeyType {
P256,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[wasm_bindgen]
#[serde(transparent)]
pub struct Attestation(pub(crate) tlsn::attestation::Attestation);
#[wasm_bindgen]
impl Attestation {
pub fn verifying_key(&self) -> VerifyingKey {
self.0.body.verifying_key().into()
}
/// Serializes to a byte array.
pub fn serialize(&self) -> Vec<u8> {
bincode::serialize(self).expect("Attestation should be serializable")
}
/// Deserializes from a byte array.
pub fn deserialize(bytes: Vec<u8>) -> Result<Attestation, JsError> {
Ok(bincode::deserialize(&bytes)?)
}
}
impl From<tlsn::attestation::Attestation> for Attestation {
fn from(value: tlsn::attestation::Attestation) -> Self {
Self(value)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[wasm_bindgen]
#[serde(transparent)]
pub struct Secrets(pub(crate) tlsn::attestation::Secrets);
#[wasm_bindgen]
impl Secrets {
/// Returns the transcript.
pub fn transcript(&self) -> Transcript {
self.0.transcript().into()
}
/// Serializes to a byte array.
pub fn serialize(&self) -> Vec<u8> {
bincode::serialize(self).expect("Secrets should be serializable")
}
/// Deserializes from a byte array.
pub fn deserialize(bytes: Vec<u8>) -> Result<Secrets, JsError> {
Ok(bincode::deserialize(&bytes)?)
}
}
impl From<tlsn::attestation::Secrets> for Secrets {
fn from(value: tlsn::attestation::Secrets) -> Self {
Self(value)
}
}
#[derive(Debug, Serialize, Deserialize)]
#[wasm_bindgen]
#[serde(transparent)]
pub struct Presentation(tlsn::attestation::presentation::Presentation);
#[wasm_bindgen]
impl Presentation {
/// Returns the verifying key.
pub fn verifying_key(&self) -> VerifyingKey {
self.0.verifying_key().into()
}
/// Verifies the presentation.
pub fn verify(&self) -> Result<PresentationOutput, JsError> {
let provider = CryptoProvider::default();
self.0
.clone()
.verify(&provider)
.map(PresentationOutput::from)
.map_err(JsError::from)
}
pub fn serialize(&self) -> Vec<u8> {
bincode::serialize(self).expect("Presentation should be serializable")
}
pub fn deserialize(bytes: Vec<u8>) -> Result<Presentation, JsError> {
Ok(bincode::deserialize(&bytes)?)
}
}
impl From<tlsn::attestation::presentation::Presentation> for Presentation {
fn from(value: tlsn::attestation::presentation::Presentation) -> Self {
Self(value)
}
}
#[derive(Debug, Tsify, Serialize)]
#[tsify(into_wasm_abi)]
pub struct PresentationOutput {
pub attestation: Attestation,
pub server_name: Option<String>,
pub connection_info: ConnectionInfo,
pub transcript: Option<PartialTranscript>,
}
impl From<tlsn::attestation::presentation::PresentationOutput> for PresentationOutput {
fn from(value: tlsn::attestation::presentation::PresentationOutput) -> Self {
Self {
attestation: value.attestation.into(),
server_name: value.server_name.map(|name| name.as_str().to_string()),
connection_info: value.connection_info.into(),
transcript: value.transcript.map(PartialTranscript::from),
}
}
}
#[derive(Debug, Serialize)]
#[wasm_bindgen(getter_with_clone)]
pub struct NotarizationOutput {
pub attestation: Attestation,
pub secrets: Secrets,
}
#[derive(Debug, Tsify, Serialize)]
#[tsify(into_wasm_abi)]
pub struct VerifierOutput {
@@ -310,22 +181,6 @@ pub struct VerifierOutput {
pub transcript: Option<PartialTranscript>,
}
#[derive(Debug, Tsify, Serialize)]
#[tsify(into_wasm_abi)]
pub struct VerifyingKey {
pub alg: u8,
pub data: Vec<u8>,
}
impl From<&tlsn::attestation::signing::VerifyingKey> for VerifyingKey {
fn from(value: &tlsn::attestation::signing::VerifyingKey) -> Self {
Self {
alg: value.alg.as_u8(),
data: value.data.clone(),
}
}
}
#[derive(Debug, Tsify, Deserialize)]
#[tsify(from_wasm_abi)]
pub enum NetworkSetting {