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

Remove the lifetime in EcdsaXi2023. #2

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
62 changes: 26 additions & 36 deletions src/ecdsa_xi_2023.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,25 @@ use ssi::{
rdf::{AnyLdEnvironment, LdEnvironment},
verification_methods::{multikey, Multikey},
};
use std::marker::PhantomData;

/// The `ecdsa-xi-2023` cryptosuite.
///
/// See: <https://w3c-ccg.github.io/vc-barcodes/#ecdsa-xi-2023>
#[derive(Debug, Default, Clone, Copy)]
pub struct EcdsaXi2023<X = &'static [u8]>(PhantomData<X>);
pub struct EcdsaXi2023;

impl<X> TryFrom<Type> for EcdsaXi2023<X> {
impl TryFrom<Type> for EcdsaXi2023 {
type Error = UnsupportedProofSuite;

fn try_from(value: Type) -> Result<Self, Self::Error> {
match value {
Type::DataIntegrityProof(cryptosuite) if cryptosuite == "ecdsa-xi-2023" => {
Ok(Self(PhantomData))
}
Type::DataIntegrityProof(cryptosuite) if cryptosuite == "ecdsa-xi-2023" => Ok(Self),
other => Err(UnsupportedProofSuite::Compact(other)),
}
}
}

impl<'a> StandardCryptographicSuite for EcdsaXi2023<&'a [u8]> {
impl StandardCryptographicSuite for EcdsaXi2023 {
type Configuration = EcdsaXi2023ConfigurationAlgorithm;

type Transformation = EcdsaXi2023TransformationAlgorithm;
Expand All @@ -61,64 +58,57 @@ impl<'a> StandardCryptographicSuite for EcdsaXi2023<&'a [u8]> {
}
}

#[derive(Debug, Clone, Copy)]
pub struct ExtraInformation<'a>(pub &'a [u8]);
#[derive(Debug, Clone)]
pub struct ExtraInformation(pub Vec<u8>);

pub struct EcdsaXi2023ConfigurationAlgorithm;

impl<'a> ConfigurationAlgorithm<EcdsaXi2023<&'a [u8]>> for EcdsaXi2023ConfigurationAlgorithm {
impl ConfigurationAlgorithm<EcdsaXi2023> for EcdsaXi2023ConfigurationAlgorithm {
type InputVerificationMethod = Multikey;
type InputSuiteOptions = ();
type InputSignatureOptions = ExtraInformation<'a>;
type InputVerificationOptions = ExtraInformation<'a>;
type TransformationOptions = ExtraInformation<'a>;
type InputSignatureOptions = ExtraInformation;
type InputVerificationOptions = ExtraInformation;
type TransformationOptions = ExtraInformation;

fn configure_signature(
suite: &EcdsaXi2023<&'a [u8]>,
suite: &EcdsaXi2023,
proof_options: ProofOptions<Multikey, ()>,
signature_options: ExtraInformation<'a>,
) -> Result<
(
ProofConfiguration<EcdsaXi2023<&'a [u8]>>,
ExtraInformation<'a>,
),
ConfigurationError,
> {
signature_options: ExtraInformation,
) -> Result<(ProofConfiguration<EcdsaXi2023>, ExtraInformation), ConfigurationError> {
let configuration = proof_options.into_configuration(*suite)?;
Ok((configuration, signature_options))
}

fn configure_verification(
_suite: &EcdsaXi2023<&'a [u8]>,
verification_options: &ExtraInformation<'a>,
) -> Result<ExtraInformation<'a>, ConfigurationError> {
Ok(*verification_options)
_suite: &EcdsaXi2023,
verification_options: &ExtraInformation,
) -> Result<ExtraInformation, ConfigurationError> {
Ok(verification_options.clone())
}
}

pub struct WithExtraInformation<'a, T> {
pub struct WithExtraInformation<T> {
data: T,
extra_information: &'a [u8],
extra_information: Vec<u8>,
}

pub struct EcdsaXi2023TransformationAlgorithm;

impl<'a> TransformationAlgorithm<EcdsaXi2023<&'a [u8]>> for EcdsaXi2023TransformationAlgorithm {
type Output = WithExtraInformation<'a, CanonicalClaimsAndConfiguration>;
impl TransformationAlgorithm<EcdsaXi2023> for EcdsaXi2023TransformationAlgorithm {
type Output = WithExtraInformation<CanonicalClaimsAndConfiguration>;
}

impl<'a, T, C> TypedTransformationAlgorithm<EcdsaXi2023<&'a [u8]>, T, C>
for EcdsaXi2023TransformationAlgorithm
impl<T, C> TypedTransformationAlgorithm<EcdsaXi2023, T, C> for EcdsaXi2023TransformationAlgorithm
where
T: JsonLdNodeObject + Expandable,
C: JsonLdLoaderProvider,
{
async fn transform(
context: &C,
data: &T,
proof_configuration: ProofConfigurationRef<'_, EcdsaXi2023<&'a [u8]>>,
proof_configuration: ProofConfigurationRef<'_, EcdsaXi2023>,
_verification_method: &Multikey,
transformation_options: ExtraInformation<'a>,
transformation_options: ExtraInformation,
) -> Result<Self::Output, TransformationError> {
let mut ld = LdEnvironment::default();

Expand All @@ -145,12 +135,12 @@ where

pub struct EcdsaXi2023HashingAlgorithm;

impl<'a> HashingAlgorithm<EcdsaXi2023<&'a [u8]>> for EcdsaXi2023HashingAlgorithm {
impl HashingAlgorithm<EcdsaXi2023> for EcdsaXi2023HashingAlgorithm {
type Output = EcdsaXi2023Hash;

fn hash(
input: WithExtraInformation<CanonicalClaimsAndConfiguration>,
_proof_configuration: ProofConfigurationRef<EcdsaXi2023<&'a [u8]>>,
_proof_configuration: ProofConfigurationRef<EcdsaXi2023>,
verification_method: &Multikey,
) -> Result<Self::Output, HashingError> {
match verification_method
Expand Down
8 changes: 4 additions & 4 deletions src/optical_barcode_credential/compression/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ fn encode_options() -> EncodeOptions {
}
}

pub async fn encode<'a, T>(
vc: &DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'a [u8]>>,
pub async fn encode<T>(
vc: &DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023>,
) -> cbor_ld::CborValue
where
T: OpticalBarcodeCredentialSubject,
Expand All @@ -26,8 +26,8 @@ where
.unwrap()
}

pub async fn encode_to_bytes<'a, T>(
vc: &DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'a [u8]>>,
pub async fn encode_to_bytes<T>(
vc: &DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023>,
) -> Vec<u8>
where
T: OpticalBarcodeCredentialSubject,
Expand Down
26 changes: 0 additions & 26 deletions src/optical_barcode_credential/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,29 +53,3 @@ pub unsafe trait OpticalBarcodeCredentialSubject: Serialize + DeserializeOwned {

fn create_optical_data(&self, xi: &Self::ExtraInformation) -> [u8; 32];
}

pub fn change_xi_lifetime<'a, 'b, T: OpticalBarcodeCredentialSubject>(
vc: DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'a [u8]>>,
) -> DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'b [u8]>> {
unsafe {
// SAFETY: the lifetime in `EcdsaXi2023` is completely unused,
// it does not refer any data stored in `vc`.
std::mem::transmute::<
DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'a [u8]>>,
DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'b [u8]>>,
>(vc)
}
}

pub fn change_xi_lifetime_ref<'r, 'a, 'b, T: OpticalBarcodeCredentialSubject>(
vc: &'r DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'a [u8]>>,
) -> &'r DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'b [u8]>> {
unsafe {
// SAFETY: the lifetime in `EcdsaXi2023` is completely unused,
// it does not refer any data stored in `vc`.
std::mem::transmute::<
&'r DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'a [u8]>>,
&'r DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023<&'b [u8]>>,
>(vc)
}
}
59 changes: 50 additions & 9 deletions src/optical_barcode_credential/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ use crate::{
terse_bitstring_status_list_entry::TerseBitstringStatusListEntry,
};

use super::{
change_xi_lifetime, OpticalBarcodeCredential, OpticalBarcodeCredentialSubject, CONTEXT_LOADER,
};
use super::{OpticalBarcodeCredential, OpticalBarcodeCredentialSubject, CONTEXT_LOADER};

/// Optical barcode credential signature parameters.
pub struct SignatureParameters<R, S> {
Expand Down Expand Up @@ -100,7 +98,7 @@ where

pub async fn sign_from_optical_data<T, R, S>(
mut unsigned: OpticalBarcodeCredential<T>,
optical_data: &[u8],
optical_data: impl Into<Vec<u8>>,
options: ProofOptions<ssi::verification_methods::Multikey, ()>,
params: SignatureParameters<R, S>,
) -> Result<DataIntegrity<OpticalBarcodeCredential<T>, EcdsaXi2023>, SignatureError>
Expand All @@ -120,18 +118,16 @@ where
)
}

let vc = EcdsaXi2023::<&[u8]>::default()
EcdsaXi2023
.sign_with(
XiSignatureEnvironment(&*CONTEXT_LOADER),
unsigned,
params.resolver,
params.signer,
options,
ExtraInformation(optical_data),
ExtraInformation(optical_data.into()),
)
.await?;

Ok(change_xi_lifetime(vc))
.await
}

struct XiSignatureEnvironment<'a, L>(&'a L);
Expand All @@ -148,3 +144,48 @@ pub struct Status {
entry: BitstringStatusListEntry,
list_len: usize,
}

#[cfg(test)]
mod tests {
use ssi::{
claims::data_integrity::ProofOptions,
dids::{AnyDidMethod, DIDKey, DIDResolver},
verification_methods::SingleSecretSigner,
JWK,
};
use static_iref::uri;

use crate::{create, MachineReadableZone, MRZ};

use super::SignatureParameters;

fn assert_send(_: impl Send) {}

const MRZ_DATA: MRZ = [
*b"IAUTO0000007010SRC0000000701<<",
*b"8804192M2601058NOT<<<<<<<<<<<5",
*b"SMITH<<JOHN<<<<<<<<<<<<<<<<<<<",
];

#[async_std::test]
async fn create_is_send() {
let jwk = JWK::generate_p256();

let vm = DIDKey::generate_url(&jwk).unwrap();
let options = ProofOptions::from_method(vm.into_iri().into());

let params = SignatureParameters::new(
AnyDidMethod::default().into_vm_resolver(),
SingleSecretSigner::new(jwk),
None,
);

assert_send(create(
&MRZ_DATA,
uri!("http://example.org/issuer").to_owned(),
MachineReadableZone {},
options,
params,
))
}
}
Loading