pub fn finish(
        self,
        credential_response: CredentialResponse<CS>,
        params: ClientLoginFinishParameters<CS>,
    ) -> Result<ClientLoginFinishResult<CS>, ProtocolError> {
        // Check if beta value from server is equal to alpha value from client
        let credential_request =
            CredentialRequest::<CS>::deserialize(&self.serialized_credential_request[..])?;
        if credential_request
            .blinded_element
            .value()
            .ct_eq(&credential_response.evaluation_element.value())
            .into()
        {
            return Err(ProtocolError::ReflectedValueError);
        }

        let (_, randomized_pwd_hasher) = get_password_derived_key::<CS>(
            self.oprf_client.clone(),
            credential_response.evaluation_element.clone(),
            params.slow_hash,
        )?;

        let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
        randomized_pwd_hasher
            .expand(STR_MASKING_KEY, &mut masking_key)
            .map_err(|_| InternalError::HkdfError)?;

        let (server_s_pk, envelope) = unmask_response::<CS>(
            &masking_key,
            &credential_response.masking_nonce,
            &credential_response.masked_response,
        )
        .map_err(|e| match e {
            ProtocolError::SerializationError => ProtocolError::InvalidLoginError,
            err => err,
        })?;
        let server_s_pk_bytes = server_s_pk.to_arr().to_vec();

        let opened_envelope = &envelope
            .open(
                randomized_pwd_hasher,
                &server_s_pk_bytes,
                &params.identifiers,
            )
            .map_err(|e| match e {
                ProtocolError::LibraryError(InternalError::SealOpenHmacError) => {
                    ProtocolError::InvalidLoginError
                }
                err => err,
            })?;

        let credential_response_component = CredentialResponse::<CS>::serialize_without_ke(
            &credential_response.evaluation_element.value(),
            &credential_response.masking_nonce,
            &credential_response.masked_response,
        );

        let result = CS::KeyExchange::generate_ke3(
            credential_response_component,
            credential_response.ke2_message,
            &self.ke1_state,
            &self.serialized_credential_request,
            server_s_pk.clone(),
            opened_envelope.client_static_keypair.private().clone(),
            opened_envelope.id_u.clone(),
            opened_envelope.id_s.clone(),
            params.context.unwrap_or_default(),
        )?;

        Ok(ClientLoginFinishResult {
            message: CredentialFinalization {
                ke3_message: result.1,
            },
            session_key: result.0,
            export_key: opened_envelope.export_key.clone(),
            server_s_pk,
            #[cfg(test)]
            state: self,
            #[cfg(test)]
            handshake_secret: result.2,
            #[cfg(test)]
            client_mac_key: result.3,
        })
    }
/// "Unblinds" the server's answer and returns the opened assets from
/// the server
"Unblinds" the server's answer and returns the opened assets from
the server
" Unblinds " the server ' s answer and returns the opened assets from the server
pub fn finish(
        self,
        credential_response: CredentialResponse<CS>,
        params: ClientLoginFinishParameters<CS>,
    ) -> Result<ClientLoginFinishResult<CS>, ProtocolError> {
        // Check if beta value from server is equal to alpha value from client
        let credential_request =
            CredentialRequest::<CS>::deserialize(&self.serialized_credential_request[..])?;
        if credential_request
            .blinded_element
            .value()
            .ct_eq(&credential_response.evaluation_element.value())
            .into()
        {
            return Err(ProtocolError::ReflectedValueError);
        }
        let (_, randomized_pwd_hasher) = get_password_derived_key::<CS>(
            self.oprf_client.clone(),
            credential_response.evaluation_element.clone(),
            params.slow_hash,
        )?;
        let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
        randomized_pwd_hasher
            .expand(STR_MASKING_KEY, &mut masking_key)
            .map_err(|_| InternalError::HkdfError)?;
        let (server_s_pk, envelope) = unmask_response::<CS>(
            &masking_key,
            &credential_response.masking_nonce,
            &credential_response.masked_response,
        )
        .map_err(|e| match e {
            ProtocolError::SerializationError => ProtocolError::InvalidLoginError,
            err => err,
        })?;
        let server_s_pk_bytes = server_s_pk.to_arr().to_vec();
        let opened_envelope = &envelope
            .open(
                randomized_pwd_hasher,
                &server_s_pk_bytes,
                &params.identifiers,
            )
            .map_err(|e| match e {
                ProtocolError::LibraryError(InternalError::SealOpenHmacError) => {
                    ProtocolError::InvalidLoginError
                }
                err => err,
            })?;
        let credential_response_component = CredentialResponse::<CS>::serialize_without_ke(
            &credential_response.evaluation_element.value(),
            &credential_response.masking_nonce,
            &credential_response.masked_response,
        );
        let result = CS::KeyExchange::generate_ke3(
            credential_response_component,
            credential_response.ke2_message,
            &self.ke1_state,
            &self.serialized_credential_request,
            server_s_pk.clone(),
            opened_envelope.client_static_keypair.private().clone(),
            opened_envelope.id_u.clone(),
            opened_envelope.id_s.clone(),
            params.context.unwrap_or_default(),
        )?;
        Ok(ClientLoginFinishResult {
            message: CredentialFinalization {
                ke3_message: result.1,
            },
            session_key: result.0,
            export_key: opened_envelope.export_key.clone(),
            server_s_pk,
            #[cfg(test)]
            state: self,
            #[cfg(test)]
            handshake_secret: result.2,
            #[cfg(test)]
            client_mac_key: result.3,
        })
    }
pub fn finish ( self , credential_response : CredentialResponse < CS > , params : ClientLoginFinishParameters < CS > , ) -> Result < ClientLoginFinishResult < CS > , ProtocolError > { // Check if beta value from server is equal to alpha value from client let credential_request = CredentialRequest :: < CS > :: deserialize ( & self . serialized_credential_request [ .. ] ) ? ; if credential_request . blinded_element . value ( ) . ct_eq ( & credential_response . evaluation_element . value ( ) ) . into ( ) { return Err ( ProtocolError :: ReflectedValueError ) ; } let ( _ , randomized_pwd_hasher ) = get_password_derived_key :: < CS > ( self . oprf_client . clone ( ) , credential_response . evaluation_element . clone ( ) , params . slow_hash , ) ? ; let mut masking_key = vec ! [ 0u8 CS Hash as Digest OutputSize USIZE ] ; randomized_pwd_hasher . expand ( STR_MASKING_KEY , & mut masking_key ) . map_err ( | _ | InternalError :: HkdfError ) ? ; let ( server_s_pk , envelope ) = unmask_response :: < CS > ( & masking_key , & credential_response . masking_nonce , & credential_response . masked_response , ) . map_err ( | e | match e { ProtocolError :: SerializationError => ProtocolError :: InvalidLoginError , err => err , } ) ? ; let server_s_pk_bytes = server_s_pk . to_arr ( ) . to_vec ( ) ; let opened_envelope = & envelope . open ( randomized_pwd_hasher , & server_s_pk_bytes , & params . identifiers , ) . map_err ( | e | match e { ProtocolError :: LibraryError ( InternalError :: SealOpenHmacError ) => { ProtocolError :: InvalidLoginError } err => err , } ) ? ; let credential_response_component = CredentialResponse :: < CS > :: serialize_without_ke ( & credential_response . evaluation_element . value ( ) , & credential_response . masking_nonce , & credential_response . masked_response , ) ; let result = CS :: KeyExchange :: generate_ke3 ( credential_response_component , credential_response . ke2_message , & self . ke1_state , & self . serialized_credential_request , server_s_pk . clone ( ) , opened_envelope . client_static_keypair . private ( ) . clone ( ) , opened_envelope . id_u . clone ( ) , opened_envelope . id_s . clone ( ) , params . context . unwrap_or_default ( ) , ) ? ; Ok ( ClientLoginFinishResult { message : CredentialFinalization { ke3_message : result . 1 , } , session_key : result . 0 , export_key : opened_envelope . export_key . clone ( ) , server_s_pk , # [ cfg ( test ) ] state : self , # [ cfg ( test ) ] handshake_secret : result . 2 , # [ cfg ( test ) ] client_mac_key : result . 3 , } ) }
"Unblinds" the server's answer and returns the opened assets from
the server
" Unblinds " the server ' s answer and returns the opened assets from the server
self
credential_response
CredentialResponse<CS>
params
ClientLoginFinishParameters<CS>
self
credential_response
CredentialResponse<CS>
params
ClientLoginFinishParameters<CS>