diff --git a/Cargo.toml b/Cargo.toml index 0e5cc95..133d4f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,8 @@ rand = "0.8.5" serde = "1" sha2 = "0.10.2" thiserror = "1" -tls_codec = "0.4.0" -tls_codec_derive = "0.4.0" +tls_codec = { version = "0.4.2-pre.1", git = "https://github.com/rustcrypto/formats" } +tls_codec_derive = "0.4.1" voprf = { version = "0.5", features = ["serde"] } p384 = { version = "0.13.0", default-features = false, features = [ "hash2curve", diff --git a/benches/batched.rs b/benches/batched_p384.rs similarity index 55% rename from benches/batched.rs rename to benches/batched_p384.rs index 9d5e903..87af113 100644 --- a/benches/batched.rs +++ b/benches/batched_p384.rs @@ -1,3 +1,4 @@ +#[allow(clippy::duplicate_mod)] #[path = "../tests/batched_memory_stores.rs"] mod batched_memory_stores; @@ -7,17 +8,17 @@ use tokio::runtime::Runtime; use privacypass::{auth::authenticate::TokenChallenge, TokenType}; async fn create_batched_keypair( - key_store: batched_memory_stores::MemoryKeyStore, - server: privacypass::batched_tokens::server::Server, + key_store: batched_memory_stores::MemoryKeyStoreP384, + server: privacypass::batched_tokens_p384::server::Server, ) { let _public_key = server.create_keypair(&key_store).await.unwrap(); } async fn issue_batched_token_response( - key_store: batched_memory_stores::MemoryKeyStore, - server: privacypass::batched_tokens::server::Server, - token_request: privacypass::batched_tokens::TokenRequest, -) -> privacypass::batched_tokens::TokenResponse { + key_store: batched_memory_stores::MemoryKeyStoreP384, + server: privacypass::batched_tokens_p384::server::Server, + token_request: privacypass::batched_tokens_p384::TokenRequest, +) -> privacypass::batched_tokens_p384::TokenResponse { server .issue_token_response(&key_store, token_request) .await @@ -25,10 +26,10 @@ async fn issue_batched_token_response( } async fn redeem_batched_token( - key_store: batched_memory_stores::MemoryKeyStore, + key_store: batched_memory_stores::MemoryKeyStoreP384, nonce_store: batched_memory_stores::MemoryNonceStore, - token: privacypass::batched_tokens::BatchedToken, - server: privacypass::batched_tokens::server::Server, + token: privacypass::batched_tokens_p384::BatchedToken, + server: privacypass::batched_tokens_p384::server::Server, ) { server .redeem_token(&key_store, &nonce_store, token) @@ -36,14 +37,14 @@ async fn redeem_batched_token( .unwrap(); } -pub fn criterion_batched_benchmark(c: &mut Criterion) { +pub fn criterion_batched_p384_benchmark(c: &mut Criterion) { const NR: u16 = 100; // Key pair generation - c.bench_function("BATCHED SERVER: Generate key pair", move |b| { + c.bench_function("BATCHED P384 SERVER: Generate key pair", move |b| { b.to_async(FuturesExecutor).iter_with_setup( || { - let key_store = batched_memory_stores::MemoryKeyStore::default(); - let server = privacypass::batched_tokens::server::Server::new(); + let key_store = batched_memory_stores::MemoryKeyStoreP384::default(); + let server = privacypass::batched_tokens_p384::server::Server::new(); (key_store, server) }, |(key_store, server)| create_batched_keypair(key_store, server), @@ -52,18 +53,18 @@ pub fn criterion_batched_benchmark(c: &mut Criterion) { // Issue token request c.bench_function( - &format!("BATCHED CLIENT: Issue token request for {NR} tokens"), + &format!("BATCHED P384 CLIENT: Issue token request for {NR} tokens"), move |b| { b.iter_with_setup( || { - let key_store = batched_memory_stores::MemoryKeyStore::default(); - let server = privacypass::batched_tokens::server::Server::new(); + let key_store = batched_memory_stores::MemoryKeyStoreP384::default(); + let server = privacypass::batched_tokens_p384::server::Server::new(); let rt = Runtime::new().unwrap(); let public_key = rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); - let client = privacypass::batched_tokens::client::Client::new(public_key); + let client = privacypass::batched_tokens_p384::client::Client::new(public_key); let challenge = TokenChallenge::new( - TokenType::Batched, + TokenType::BatchedTokenP384, "example.com", None, &["example.com".to_string()], @@ -79,18 +80,18 @@ pub fn criterion_batched_benchmark(c: &mut Criterion) { // Issue token response c.bench_function( - &format!("BATCHED SERVER: Issue token response for {NR} tokens"), + &format!("BATCHED P384 SERVER: Issue token response for {NR} tokens"), move |b| { b.to_async(FuturesExecutor).iter_with_setup( || { - let key_store = batched_memory_stores::MemoryKeyStore::default(); - let server = privacypass::batched_tokens::server::Server::new(); + let key_store = batched_memory_stores::MemoryKeyStoreP384::default(); + let server = privacypass::batched_tokens_p384::server::Server::new(); let rt = Runtime::new().unwrap(); let public_key = rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); - let client = privacypass::batched_tokens::client::Client::new(public_key); + let client = privacypass::batched_tokens_p384::client::Client::new(public_key); let challenge = TokenChallenge::new( - TokenType::Batched, + TokenType::BatchedTokenP384, "example.com", None, &["example.com".to_string()], @@ -107,50 +108,53 @@ pub fn criterion_batched_benchmark(c: &mut Criterion) { ); // Issue token - c.bench_function(&format!("BATCHED CLIENT: Issue {NR} tokens"), move |b| { - b.iter_with_setup( - || { - let key_store = batched_memory_stores::MemoryKeyStore::default(); - let server = privacypass::batched_tokens::server::Server::new(); - let rt = Runtime::new().unwrap(); - let public_key = - rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); - let client = privacypass::batched_tokens::client::Client::new(public_key); - let challenge = TokenChallenge::new( - TokenType::Batched, - "example.com", - None, - &["example.com".to_string()], - ); - let (token_request, token_states) = - client.issue_token_request(&challenge, NR).unwrap(); - let token_response = rt.block_on(async { - server - .issue_token_response(&key_store, token_request) - .await - .unwrap() - }); - (client, token_response, token_states) - }, - |(client, token_response, token_states)| { - client.issue_tokens(&token_response, &token_states).unwrap(); - }, - ); - }); + c.bench_function( + &format!("BATCHED P384 CLIENT: Issue {NR} tokens"), + move |b| { + b.iter_with_setup( + || { + let key_store = batched_memory_stores::MemoryKeyStoreP384::default(); + let server = privacypass::batched_tokens_p384::server::Server::new(); + let rt = Runtime::new().unwrap(); + let public_key = + rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); + let client = privacypass::batched_tokens_p384::client::Client::new(public_key); + let challenge = TokenChallenge::new( + TokenType::BatchedTokenP384, + "example.com", + None, + &["example.com".to_string()], + ); + let (token_request, token_states) = + client.issue_token_request(&challenge, NR).unwrap(); + let token_response = rt.block_on(async { + server + .issue_token_response(&key_store, token_request) + .await + .unwrap() + }); + (client, token_response, token_states) + }, + |(client, token_response, token_states)| { + client.issue_tokens(&token_response, &token_states).unwrap(); + }, + ); + }, + ); // Redeem token - c.bench_function("BATCHED SERVER: Redeem token", move |b| { + c.bench_function("BATCHED P384 SERVER: Redeem token", move |b| { b.to_async(FuturesExecutor).iter_with_setup( || { - let key_store = batched_memory_stores::MemoryKeyStore::default(); + let key_store = batched_memory_stores::MemoryKeyStoreP384::default(); let nonce_store = batched_memory_stores::MemoryNonceStore::default(); - let server = privacypass::batched_tokens::server::Server::new(); + let server = privacypass::batched_tokens_p384::server::Server::new(); let rt = Runtime::new().unwrap(); let public_key = rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); - let client = privacypass::batched_tokens::client::Client::new(public_key); + let client = privacypass::batched_tokens_p384::client::Client::new(public_key); let challenge = TokenChallenge::new( - TokenType::Batched, + TokenType::BatchedTokenP384, "example.com", None, &["example.com".to_string()], diff --git a/benches/batched_ristretto255.rs b/benches/batched_ristretto255.rs new file mode 100644 index 0000000..36a8174 --- /dev/null +++ b/benches/batched_ristretto255.rs @@ -0,0 +1,182 @@ +#[allow(clippy::duplicate_mod)] +#[path = "../tests/batched_memory_stores.rs"] +mod batched_memory_stores; + +use criterion::{async_executor::FuturesExecutor, Criterion}; +use tokio::runtime::Runtime; + +use privacypass::{auth::authenticate::TokenChallenge, TokenType}; + +async fn create_batched_keypair( + key_store: batched_memory_stores::MemoryKeyStoreRistretto255, + server: privacypass::batched_tokens_ristretto255::server::Server, +) { + let _public_key = server.create_keypair(&key_store).await.unwrap(); +} + +async fn issue_batched_token_response( + key_store: batched_memory_stores::MemoryKeyStoreRistretto255, + server: privacypass::batched_tokens_ristretto255::server::Server, + token_request: privacypass::batched_tokens_ristretto255::TokenRequest, +) -> privacypass::batched_tokens_ristretto255::TokenResponse { + server + .issue_token_response(&key_store, token_request) + .await + .unwrap() +} + +async fn redeem_batched_token( + key_store: batched_memory_stores::MemoryKeyStoreRistretto255, + nonce_store: batched_memory_stores::MemoryNonceStore, + token: privacypass::batched_tokens_ristretto255::BatchedToken, + server: privacypass::batched_tokens_ristretto255::server::Server, +) { + server + .redeem_token(&key_store, &nonce_store, token) + .await + .unwrap(); +} + +pub fn criterion_batched_ristretto255_benchmark(c: &mut Criterion) { + const NR: u16 = 100; + // Key pair generation + c.bench_function("BATCHED RISTRETTO255 SERVER: Generate key pair", move |b| { + b.to_async(FuturesExecutor).iter_with_setup( + || { + let key_store = batched_memory_stores::MemoryKeyStoreRistretto255::default(); + let server = privacypass::batched_tokens_ristretto255::server::Server::new(); + (key_store, server) + }, + |(key_store, server)| create_batched_keypair(key_store, server), + ); + }); + + // Issue token request + c.bench_function( + &format!("BATCHED RISTRETTO255 CLIENT: Issue token request for {NR} tokens"), + move |b| { + b.iter_with_setup( + || { + let key_store = batched_memory_stores::MemoryKeyStoreRistretto255::default(); + let server = privacypass::batched_tokens_ristretto255::server::Server::new(); + let rt = Runtime::new().unwrap(); + let public_key = + rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); + let client = + privacypass::batched_tokens_ristretto255::client::Client::new(public_key); + let challenge = TokenChallenge::new( + TokenType::BatchedTokenRistretto255, + "example.com", + None, + &["example.com".to_string()], + ); + (client, challenge) + }, + |(client, challenge)| { + client.issue_token_request(&challenge, NR).unwrap(); + }, + ); + }, + ); + + // Issue token response + c.bench_function( + &format!("BATCHED RISTRETTO255 SERVER: Issue token response for {NR} tokens"), + move |b| { + b.to_async(FuturesExecutor).iter_with_setup( + || { + let key_store = batched_memory_stores::MemoryKeyStoreRistretto255::default(); + let server = privacypass::batched_tokens_ristretto255::server::Server::new(); + let rt = Runtime::new().unwrap(); + let public_key = + rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); + let client = + privacypass::batched_tokens_ristretto255::client::Client::new(public_key); + let challenge = TokenChallenge::new( + TokenType::BatchedTokenRistretto255, + "example.com", + None, + &["example.com".to_string()], + ); + let (token_request, _token_states) = + client.issue_token_request(&challenge, NR).unwrap(); + (key_store, server, token_request) + }, + |(key_store, server, token_request)| { + issue_batched_token_response(key_store, server, token_request) + }, + ); + }, + ); + + // Issue token + c.bench_function( + &format!("BATCHED RISTRETTO255 CLIENT: Issue {NR} tokens"), + move |b| { + b.iter_with_setup( + || { + let key_store = batched_memory_stores::MemoryKeyStoreRistretto255::default(); + let server = privacypass::batched_tokens_ristretto255::server::Server::new(); + let rt = Runtime::new().unwrap(); + let public_key = + rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); + let client = + privacypass::batched_tokens_ristretto255::client::Client::new(public_key); + let challenge = TokenChallenge::new( + TokenType::BatchedTokenRistretto255, + "example.com", + None, + &["example.com".to_string()], + ); + let (token_request, token_states) = + client.issue_token_request(&challenge, NR).unwrap(); + let token_response = rt.block_on(async { + server + .issue_token_response(&key_store, token_request) + .await + .unwrap() + }); + (client, token_response, token_states) + }, + |(client, token_response, token_states)| { + client.issue_tokens(&token_response, &token_states).unwrap(); + }, + ); + }, + ); + + // Redeem token + c.bench_function("BATCHED RISTRETTO255 SERVER: Redeem token", move |b| { + b.to_async(FuturesExecutor).iter_with_setup( + || { + let key_store = batched_memory_stores::MemoryKeyStoreRistretto255::default(); + let nonce_store = batched_memory_stores::MemoryNonceStore::default(); + let server = privacypass::batched_tokens_ristretto255::server::Server::new(); + let rt = Runtime::new().unwrap(); + let public_key = + rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); + let client = + privacypass::batched_tokens_ristretto255::client::Client::new(public_key); + let challenge = TokenChallenge::new( + TokenType::BatchedTokenRistretto255, + "example.com", + None, + &["example.com".to_string()], + ); + let (token_request, token_state) = + client.issue_token_request(&challenge, NR).unwrap(); + let token_response = rt.block_on(async { + server + .issue_token_response(&key_store, token_request) + .await + .unwrap() + }); + let tokens = client.issue_tokens(&token_response, &token_state).unwrap(); + (key_store, nonce_store, tokens, server) + }, + |(key_store, nonce_store, tokens, server)| { + redeem_batched_token(key_store, nonce_store, tokens[0].clone(), server) + }, + ); + }); +} diff --git a/benches/benchmark.rs b/benches/benchmark.rs index eef2f77..c279418 100644 --- a/benches/benchmark.rs +++ b/benches/benchmark.rs @@ -1,17 +1,20 @@ -mod batched; +mod batched_p384; +mod batched_ristretto255; mod private; mod public; use criterion::{criterion_group, criterion_main}; -use batched::*; -use private::*; -use public::*; +use batched_p384::criterion_batched_p384_benchmark; +use batched_ristretto255::criterion_batched_ristretto255_benchmark; +use private::criterion_private_benchmark; +use public::criterion_public_benchmark; criterion_group!( benches, criterion_private_benchmark, criterion_public_benchmark, - criterion_batched_benchmark + criterion_batched_ristretto255_benchmark, + criterion_batched_p384_benchmark ); criterion_main!(benches); diff --git a/benches/private.rs b/benches/private.rs index 7bfc102..0b66f73 100644 --- a/benches/private.rs +++ b/benches/private.rs @@ -61,7 +61,7 @@ pub fn criterion_private_benchmark(c: &mut Criterion) { rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); let client = privacypass::private_tokens::client::Client::new(public_key); let challenge = TokenChallenge::new( - TokenType::Private, + TokenType::PrivateToken, "example.com", None, &["example.com".to_string()], @@ -85,7 +85,7 @@ pub fn criterion_private_benchmark(c: &mut Criterion) { rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); let client = privacypass::private_tokens::client::Client::new(public_key); let challenge = TokenChallenge::new( - TokenType::Private, + TokenType::PrivateToken, "example.com", None, &["example.com".to_string()], @@ -110,7 +110,7 @@ pub fn criterion_private_benchmark(c: &mut Criterion) { rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); let client = privacypass::private_tokens::client::Client::new(public_key); let challenge = TokenChallenge::new( - TokenType::Private, + TokenType::PrivateToken, "example.com", None, &["example.com".to_string()], @@ -142,7 +142,7 @@ pub fn criterion_private_benchmark(c: &mut Criterion) { rt.block_on(async { server.create_keypair(&key_store).await.unwrap() }); let client = privacypass::private_tokens::client::Client::new(public_key); let challenge = TokenChallenge::new( - TokenType::Private, + TokenType::PrivateToken, "example.com", None, &["example.com".to_string()], diff --git a/benches/public.rs b/benches/public.rs index 7d43e9d..3d63f3c 100644 --- a/benches/public.rs +++ b/benches/public.rs @@ -69,7 +69,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { .block_on(async { server.create_keypair(&mut rng, &key_store).await.unwrap() }); let client = privacypass::public_tokens::client::Client::new(key_pair.pk); let token_challenge = TokenChallenge::new( - TokenType::Public, + TokenType::PublicToken, "example.com", None, &["example.com".to_string()], @@ -97,7 +97,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { rt.block_on(async { server.create_keypair(rng, &key_store).await.unwrap() }); let mut client = privacypass::public_tokens::client::Client::new(key_pair.pk); let token_challenge = TokenChallenge::new( - TokenType::Public, + TokenType::PublicToken, "example.com", None, &["example.com".to_string()], @@ -125,7 +125,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { rt.block_on(async { server.create_keypair(rng, &key_store).await.unwrap() }); let mut client = privacypass::public_tokens::client::Client::new(key_pair.pk); let token_challenge = TokenChallenge::new( - TokenType::Public, + TokenType::PublicToken, "example.com", None, &["example.com".to_string()], @@ -175,7 +175,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { let mut client = privacypass::public_tokens::client::Client::new(key_pair.pk); let token_challenge = TokenChallenge::new( - TokenType::Public, + TokenType::PublicToken, "example.com", None, &["example.com".to_string()], diff --git a/src/auth/authenticate.rs b/src/auth/authenticate.rs index 730ef28..ac1c7dc 100644 --- a/src/auth/authenticate.rs +++ b/src/auth/authenticate.rs @@ -268,8 +268,12 @@ fn parse_private_tokens(input: &str) -> IResult<&str, Vec> { #[test] fn builder_test() { let token_key = b"sample token key".to_vec(); - let token_challenge = - TokenChallenge::new(TokenType::Private, "issuer", None, &["origin".to_string()]); + let token_challenge = TokenChallenge::new( + TokenType::PrivateToken, + "issuer", + None, + &["origin".to_string()], + ); let serialized_token_challenge = token_challenge.to_base64().unwrap(); let max_age = 100; @@ -292,14 +296,14 @@ fn parser_test() { let token_key2 = b"sample token key 2".to_vec(); let challenge1 = TokenChallenge::new( - TokenType::Private, + TokenType::PrivateToken, "issuer1", None, &["origin1".to_string()], ); let challenge2 = TokenChallenge::new( - TokenType::Private, + TokenType::PrivateToken, "issuer2", None, &["origin2".to_string()], @@ -334,13 +338,19 @@ fn parser_test() { #[test] fn builder_parser_test() { - use crate::batched_tokens::server::{deserialize_public_key, serialize_public_key}; + use crate::batched_tokens_ristretto255::server::{ + deserialize_public_key, serialize_public_key, + }; use voprf::{Group, Ristretto255}; let public_key = Ristretto255::base_elem(); let token_key = serialize_public_key(public_key); - let token_challenge = - TokenChallenge::new(TokenType::Private, "issuer", None, &["origin".to_string()]); + let token_challenge = TokenChallenge::new( + TokenType::PrivateToken, + "issuer", + None, + &["origin".to_string()], + ); let max_age = 100u32; let (_header_name, header_value) = build_www_authenticate_header(&token_challenge, &token_key, Some(max_age)).unwrap(); diff --git a/src/auth/authorize.rs b/src/auth/authorize.rs index 92cdc76..cf154a5 100644 --- a/src/auth/authorize.rs +++ b/src/auth/authorize.rs @@ -258,7 +258,7 @@ fn builder_parser_test() { let token_key_id = [3u8; 32]; let authenticator = [4u8; 32]; let token = Token::::new( - TokenType::Private, + TokenType::PrivateToken, nonce, challenge_digest, token_key_id, @@ -269,7 +269,7 @@ fn builder_parser_test() { assert_eq!(header_name, http::header::AUTHORIZATION); let token = parse_authorization_header::(&header_value).unwrap(); - assert_eq!(token.token_type(), TokenType::Private); + assert_eq!(token.token_type(), TokenType::PrivateToken); assert_eq!(token.nonce(), nonce); assert_eq!(token.challenge_digest(), &challenge_digest); assert_eq!(token.token_key_id(), &token_key_id); diff --git a/src/batched_tokens_p384/client.rs b/src/batched_tokens_p384/client.rs new file mode 100644 index 0000000..0f34cb2 --- /dev/null +++ b/src/batched_tokens_p384/client.rs @@ -0,0 +1,213 @@ +//! Client-side implementation of the Batched Tokens protocol. + +use p384::NistP384; +use rand::{rngs::OsRng, Rng}; +use thiserror::Error; +use voprf::{EvaluationElement, Proof, Result, VoprfClient}; + +use crate::{ + auth::{authenticate::TokenChallenge, authorize::Token}, + ChallengeDigest, KeyId, TokenInput, TokenType, +}; + +use super::{ + key_id_to_token_key_id, public_key_to_key_id, BatchedToken, Nonce, PublicKey, TokenRequest, + TokenResponse, +}; + +/// Client-side state that is kept between the token requests and token responses. +#[derive(Debug)] +pub struct TokenState { + client: VoprfClient, + token_input: TokenInput, + challenge_digest: ChallengeDigest, +} + +/// Errors that can occur when issuing token requests. +#[derive(Error, Debug, PartialEq, Eq)] +pub enum IssueTokenRequestError { + #[error("Token blinding error")] + /// Error when blinding the token. + BlindingError, + #[error("Invalid TokenChallenge")] + /// Error when the token challenge is invalid. + InvalidTokenChallenge, +} + +/// Errors that can occur when issuing tokens. +#[derive(Error, Debug, PartialEq, Eq)] +pub enum IssueTokenError { + #[error("Invalid TokenResponse")] + /// Error when the token response is invalid. + InvalidTokenResponse, +} + +/// The client side of the batched token issuance protocol. +#[derive(Debug)] +pub struct Client { + key_id: KeyId, + public_key: PublicKey, +} + +impl Client { + /// Create a new client from a public key. + #[must_use] + pub fn new(public_key: PublicKey) -> Self { + let key_id = public_key_to_key_id(&public_key); + + Self { key_id, public_key } + } + + /// Issue a token request. + /// + /// # Errors + /// Returns an error if the token blinding fails. + pub fn issue_token_request( + &self, + challenge: &TokenChallenge, + nr: u16, + ) -> Result<(TokenRequest, Vec), IssueTokenRequestError> { + let mut nonces = Vec::with_capacity(nr as usize); + + for _ in 0..nr { + let nonce: Nonce = OsRng.gen(); + nonces.push(nonce); + } + + self.issue_token_request_internal(challenge, nonces, None) + } + + /// Issue a token request. + fn issue_token_request_internal( + &self, + challenge: &TokenChallenge, + nonces: Vec, + _blinds: Option::Scalar>>, + ) -> Result<(TokenRequest, Vec), IssueTokenRequestError> { + let challenge_digest = challenge + .digest() + .map_err(|_| IssueTokenRequestError::InvalidTokenChallenge)?; + + let mut blinded_elements = Vec::new(); + let mut token_states = Vec::new(); + + #[cfg(feature = "kat")] + let mut blinds_iter = _blinds.iter().flatten(); + + for nonce in nonces { + // nonce = random(32) + // challenge_digest = SHA256(challenge) + // token_input = concat(0xF901, nonce, challenge_digest, key_id) + // blind, blinded_element = client_context.Blind(token_input) + + let token_input = TokenInput::new( + TokenType::BatchedTokenP384, + nonce, + challenge_digest, + self.key_id, + ); + + let blinded_element = + VoprfClient::::blind(&token_input.serialize(), &mut OsRng) + .map_err(|_| IssueTokenRequestError::BlindingError)?; + + #[cfg(feature = "kat")] + let blinded_element = if _blinds.is_some() { + VoprfClient::::deterministic_blind_unchecked( + &token_input.serialize(), + *blinds_iter.next().unwrap(), + ) + .map_err(|_| IssueTokenRequestError::BlindingError)? + } else { + blinded_element + }; + + let token_state = TokenState { + client: blinded_element.state, + token_input, + challenge_digest, + }; + + let blinded_element = super::BlindedElement { + blinded_element: blinded_element.message.serialize().into(), + }; + + blinded_elements.push(blinded_element); + token_states.push(token_state); + } + + let token_request = TokenRequest { + token_type: TokenType::BatchedTokenP384, + token_key_id: key_id_to_token_key_id(&self.key_id), + blinded_elements: blinded_elements.into(), + }; + + Ok((token_request, token_states)) + } + + #[cfg(feature = "kat")] + /// Issue a token request. + pub fn issue_token_request_with_params( + &self, + challenge: &TokenChallenge, + nonces: Vec, + blind: Vec<::Scalar>, + ) -> Result<(TokenRequest, Vec), IssueTokenRequestError> { + self.issue_token_request_internal(challenge, nonces, Some(blind)) + } + + /// Issue a token. + /// + /// # Errors + /// Returns an error if the token response is invalid. + pub fn issue_tokens( + &self, + token_response: &TokenResponse, + token_states: &[TokenState], + ) -> Result, IssueTokenError> { + let mut evaluated_elements = Vec::new(); + for element in token_response.evaluated_elements.iter() { + let evaluated_element = + EvaluationElement::::deserialize(&element.evaluated_element) + .map_err(|_| IssueTokenError::InvalidTokenResponse)?; + evaluated_elements.push(evaluated_element); + } + + let proof = Proof::deserialize(&token_response.evaluated_proof) + .map_err(|_| IssueTokenError::InvalidTokenResponse)?; + + let client_batch_finalize_result = VoprfClient::batch_finalize( + &token_states + .iter() + .map(|token_state| token_state.token_input.serialize()) + .collect::>(), + &token_states + .iter() + .map(|token_state| token_state.client.clone()) + .collect::>(), + &evaluated_elements, + &proof, + self.public_key, + ) + .map_err(|_| IssueTokenError::InvalidTokenResponse)? + .collect::>>() + .map_err(|_| IssueTokenError::InvalidTokenResponse)?; + + let mut tokens = Vec::new(); + + for (authenticator, token_state) in + client_batch_finalize_result.iter().zip(token_states.iter()) + { + let token = Token::new( + TokenType::BatchedTokenP384, + token_state.token_input.nonce, + token_state.challenge_digest, + token_state.token_input.key_id, + *authenticator, + ); + tokens.push(token); + } + + Ok(tokens) + } +} diff --git a/src/batched_tokens_p384/mod.rs b/src/batched_tokens_p384/mod.rs new file mode 100644 index 0000000..2b51fec --- /dev/null +++ b/src/batched_tokens_p384/mod.rs @@ -0,0 +1,121 @@ +//! # Batched tokens + +pub mod client; +pub mod server; + +use p384::NistP384; +use sha2::{Digest, Sha256}; +use thiserror::Error; +use tls_codec::{Deserialize, TlsVecU16}; +use tls_codec_derive::{TlsDeserialize, TlsSerialize, TlsSize}; +use typenum::U48; +pub use voprf::*; + +use crate::{auth::authorize::Token, KeyId, Nonce, TokenKeyId, TokenType}; + +use self::server::serialize_public_key; + +/// Size of serialized element +pub const NE: usize = 49; +/// Size of serializes scalar +pub const NS: usize = 48; +/// Size of the authenticator +pub const NK: usize = 48; + +/// Batched token alias +pub type BatchedToken = Token; +/// Public key alias +pub type PublicKey = ::Elem; + +fn public_key_to_key_id(public_key: &PublicKey) -> KeyId { + let public_key = serialize_public_key(*public_key); + + Sha256::digest(public_key).into() +} + +fn key_id_to_token_key_id(key_id: &KeyId) -> TokenKeyId { + *key_id.iter().last().unwrap_or(&0) +} + +/// Serialization error +#[derive(Error, Debug)] +pub enum SerializationError { + #[error("Invalid serialized data")] + /// Invalid serialized data + InvalidData, +} + +/// Blinded element as specified in the spec: +/// +/// ```c +/// struct { +/// uint8_t blinded_element[Ne]; +/// } BlindedElement; +/// ``` +#[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] +pub struct BlindedElement { + blinded_element: [u8; NE], +} + +/// Token request as specified in the spec: +/// +/// ```c +/// struct { +/// uint16_t token_type = 0xF901; +/// uint8_t token_key_id; +/// BlindedElement blinded_element[Nr]; +/// } TokenRequest; +/// ``` +#[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] +pub struct TokenRequest { + token_type: TokenType, + token_key_id: TokenKeyId, + blinded_elements: TlsVecU16, +} + +impl TokenRequest { + /// Returns the number of blinded elements + #[must_use] + pub fn nr(&self) -> usize { + self.blinded_elements.len() + } +} + +/// Evaluated element as specified in the spec: +/// +/// ```c +/// struct { +/// uint8_t evaluated_element[Ne]; +/// } EvaluatedElement; +/// ``` + +#[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] +pub struct EvaluatedElement { + evaluated_element: [u8; NE], +} + +/// Token response as specified in the spec: +/// +/// ```c +/// struct { +/// EvaluatedElement evaluated_elements[Nr]; +/// uint8_t evaluated_proof[Ns + Ns]; +/// } TokenResponse; +/// ``` +#[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] +pub struct TokenResponse { + evaluated_elements: TlsVecU16, + evaluated_proof: [u8; NS + NS], +} + +impl TokenResponse { + /// Create a new `TokenResponse` from a byte slice. + /// + /// # Errors + /// Returns `SerializationError::InvalidData` if the byte slice is not a + /// valid `TokenResponse`. + pub fn try_from_bytes(bytes: &[u8]) -> Result { + let mut bytes = bytes; + Self::tls_deserialize(&mut bytes).map_err(|_| SerializationError::InvalidData) + } +} diff --git a/src/batched_tokens_p384/server.rs b/src/batched_tokens_p384/server.rs new file mode 100644 index 0000000..116fe14 --- /dev/null +++ b/src/batched_tokens_p384/server.rs @@ -0,0 +1,239 @@ +//! Server-side implementation of the Batched Tokens protocol. + +use async_trait::async_trait; +use generic_array::GenericArray; +use p384::NistP384; +use rand::{rngs::OsRng, RngCore}; +use thiserror::Error; +use voprf::{ + BlindedElement, Error, Group, Result, VoprfServer, VoprfServerBatchEvaluateFinishResult, +}; + +use crate::{NonceStore, TokenInput, TokenKeyId, TokenType}; + +use super::{ + key_id_to_token_key_id, public_key_to_key_id, BatchedToken, PublicKey, TokenRequest, + TokenResponse, NK, NS, +}; + +/// Errors that can occur when creating a keypair. +#[derive(Error, Debug, PartialEq, Eq)] +pub enum CreateKeypairError { + #[error("Seed is too long")] + /// Error when the seed is too long. + SeedError, +} + +/// Errors that can occur when issuing the token response. +#[derive(Error, Debug, PartialEq, Eq)] +pub enum IssueTokenResponseError { + #[error("Key ID not found")] + /// Error when the key ID is not found. + KeyIdNotFound, + #[error("Invalid TokenRequest")] + /// Error when the token request is invalid. + InvalidTokenRequest, + #[error("Invalid toke type")] + /// Error when the token type is invalid. + InvalidTokenType, +} + +/// Errors that can occur when redeeming the token. +#[derive(Error, Debug, PartialEq, Eq)] +pub enum RedeemTokenError { + #[error("Key ID not found")] + /// Error when the key ID is not found. + KeyIdNotFound, + #[error("The token has already been redeemed")] + /// Error when the token has already been redeemed. + DoubleSpending, + #[error("The token is invalid")] + /// Error when the token is invalid. + InvalidToken, +} + +/// Minimal trait for a key store to store key material on the server-side. Note +/// that the store requires inner mutability. +#[async_trait] +pub trait BatchedKeyStore: Send + Sync { + /// Inserts a keypair with a given `token_key_id` into the key store. + async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer); + /// Returns a keypair with a given `token_key_id` from the key store. + async fn get(&self, token_key_id: &TokenKeyId) -> Option>; +} + +/// Serializes a public key. +#[must_use] +pub fn serialize_public_key(public_key: PublicKey) -> Vec { + ::serialize_elem(public_key).to_vec() +} + +/// Deserializes a public key from a slice of bytes. +/// +/// # Errors +/// Returns an error if the slice is not a valid public key. +pub fn deserialize_public_key(slice: &[u8]) -> Result { + ::deserialize_elem(slice) +} + +/// Server-side component of the batched token issuance protocol. +#[derive(Default, Debug)] +pub struct Server {} + +impl Server { + /// Create a new server. The new server does not contain any key material. + #[must_use] + pub const fn new() -> Self { + Self {} + } + + /// Creates a new keypair and inserts it into the key store. + /// + /// # Errors + /// Returns an error if the seed is too long. + pub async fn create_keypair( + &self, + key_store: &BKS, + ) -> Result { + let mut seed = GenericArray::<_, ::ScalarLen>::default(); + OsRng.fill_bytes(&mut seed); + self.create_keypair_internal(key_store, &seed, b"PrivacyPass") + .await + } + + /// Creates a new keypair and inserts it into the key store. + async fn create_keypair_internal( + &self, + key_store: &BKS, + seed: &[u8], + info: &[u8], + ) -> Result { + let server = VoprfServer::::new_from_seed(seed, info) + .map_err(|_| CreateKeypairError::SeedError)?; + let public_key = server.get_public_key(); + let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); + key_store.insert(token_key_id, server).await; + Ok(public_key) + } + + /// Creates a new keypair with explicit parameters and inserts it into the + /// key store. + #[cfg(feature = "kat")] + pub async fn create_keypair_with_params( + &self, + key_store: &BKS, + seed: &[u8], + info: &[u8], + ) -> Result { + self.create_keypair_internal(key_store, seed, info).await + } + + /// Issues a token response. + /// + /// # Errors + /// Returns an error if the token request is invalid. + pub async fn issue_token_response( + &self, + key_store: &BKS, + token_request: TokenRequest, + ) -> Result { + if token_request.token_type != TokenType::BatchedTokenP384 { + return Err(IssueTokenResponseError::InvalidTokenType); + } + let server = key_store + .get(&token_request.token_key_id) + .await + .ok_or(IssueTokenResponseError::KeyIdNotFound)?; + + let mut blinded_elements = Vec::new(); + for element in token_request.blinded_elements.iter() { + let blinded_element = BlindedElement::::deserialize(&element.blinded_element) + .map_err(|_| IssueTokenResponseError::InvalidTokenRequest)?; + blinded_elements.push(blinded_element); + } + + let prepared_elements = server + .batch_blind_evaluate_prepare(blinded_elements.iter()) + .collect::>(); + let VoprfServerBatchEvaluateFinishResult { messages, proof } = server + .batch_blind_evaluate_finish(&mut OsRng, blinded_elements.iter(), &prepared_elements) + .map_err(|_| IssueTokenResponseError::InvalidTokenRequest)?; + let evaluated_elements = messages + .map(|m| super::EvaluatedElement { + evaluated_element: m.serialize().into(), + }) + .collect(); + + let mut evaluated_proof = [0u8; NS + NS]; + evaluated_proof[..(NS + NS)].copy_from_slice(&proof.serialize()); + + Ok(TokenResponse { + evaluated_elements, + evaluated_proof, + }) + } + + /// Redeems a token. + /// + /// # Errors + /// Returns an error if the token is invalid. + pub async fn redeem_token( + &self, + key_store: &BKS, + nonce_store: &NS, + token: BatchedToken, + ) -> Result<(), RedeemTokenError> { + if token.token_type() != TokenType::BatchedTokenP384 { + return Err(RedeemTokenError::InvalidToken); + } + if token.authenticator().len() != (NK) { + return Err(RedeemTokenError::InvalidToken); + } + if nonce_store.exists(&token.nonce()).await { + return Err(RedeemTokenError::DoubleSpending); + } + let token_input = TokenInput { + token_type: token.token_type(), + nonce: token.nonce(), + challenge_digest: *token.challenge_digest(), + key_id: *token.token_key_id(), + }; + let server = key_store + .get(&key_id_to_token_key_id(token.token_key_id())) + .await + .ok_or(RedeemTokenError::KeyIdNotFound)?; + let token_authenticator = server + .evaluate(&token_input.serialize()) + .map_err(|_| RedeemTokenError::InvalidToken)? + .to_vec(); + if token.authenticator() == token_authenticator { + nonce_store.insert(token.nonce()).await; + Ok(()) + } else { + Err(RedeemTokenError::InvalidToken) + } + } + + /// Sets a keypair with a given `private_key` into the key store. + #[cfg(feature = "kat")] + pub async fn set_key( + &self, + key_store: &BKS, + private_key: &[u8], + ) -> Result { + let server = VoprfServer::::new_with_key(private_key) + .map_err(|_| CreateKeypairError::SeedError)?; + let public_key = server.get_public_key(); + let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); + key_store.insert(token_key_id, server).await; + Ok(public_key) + } +} + +#[test] +fn key_serialization() { + let pk = NistP384::base_elem(); + let bytes = serialize_public_key(pk); + let pk2 = deserialize_public_key(&bytes).unwrap(); + assert_eq!(pk, pk2); +} diff --git a/src/batched_tokens/client.rs b/src/batched_tokens_ristretto255/client.rs similarity index 93% rename from src/batched_tokens/client.rs rename to src/batched_tokens_ristretto255/client.rs index 555f93c..859f510 100644 --- a/src/batched_tokens/client.rs +++ b/src/batched_tokens_ristretto255/client.rs @@ -10,8 +10,8 @@ use crate::{ }; use super::{ - key_id_to_token_key_id, public_key_to_key_id, BatchedToken, BlindedElement, Nonce, PublicKey, - TokenRequest, TokenResponse, + key_id_to_token_key_id, public_key_to_key_id, BatchedToken, Nonce, PublicKey, TokenRequest, + TokenResponse, }; /// Client-side state that is kept between the token requests and token responses. @@ -99,8 +99,12 @@ impl Client { // token_input = concat(0xF91A, nonce, challenge_digest, key_id) // blind, blinded_element = client_context.Blind(token_input) - let token_input = - TokenInput::new(TokenType::Batched, nonce, challenge_digest, self.key_id); + let token_input = TokenInput::new( + TokenType::BatchedTokenRistretto255, + nonce, + challenge_digest, + self.key_id, + ); let blinded_element = VoprfClient::::blind(&token_input.serialize(), &mut OsRng) @@ -123,7 +127,7 @@ impl Client { challenge_digest, }; - let blinded_element = BlindedElement { + let blinded_element = super::BlindedElement { blinded_element: blinded_element.message.serialize().into(), }; @@ -132,7 +136,7 @@ impl Client { } let token_request = TokenRequest { - token_type: TokenType::Batched, + token_type: TokenType::BatchedTokenRistretto255, token_key_id: key_id_to_token_key_id(&self.key_id), blinded_elements: blinded_elements.into(), }; @@ -194,7 +198,7 @@ impl Client { client_batch_finalize_result.iter().zip(token_states.iter()) { let token = Token::new( - TokenType::Batched, + TokenType::BatchedTokenRistretto255, token_state.token_input.nonce, token_state.challenge_digest, token_state.token_input.key_id, diff --git a/src/batched_tokens/mod.rs b/src/batched_tokens_ristretto255/mod.rs similarity index 100% rename from src/batched_tokens/mod.rs rename to src/batched_tokens_ristretto255/mod.rs diff --git a/src/batched_tokens/server.rs b/src/batched_tokens_ristretto255/server.rs similarity index 96% rename from src/batched_tokens/server.rs rename to src/batched_tokens_ristretto255/server.rs index fcf0f77..24f949c 100644 --- a/src/batched_tokens/server.rs +++ b/src/batched_tokens_ristretto255/server.rs @@ -9,7 +9,9 @@ use voprf::{ VoprfServerBatchEvaluateFinishResult, }; -use crate::{batched_tokens::EvaluatedElement, NonceStore, TokenInput, TokenKeyId, TokenType}; +use crate::{ + batched_tokens_ristretto255::EvaluatedElement, NonceStore, TokenInput, TokenKeyId, TokenType, +}; use super::{ key_id_to_token_key_id, public_key_to_key_id, BatchedToken, PublicKey, TokenRequest, @@ -137,7 +139,7 @@ impl Server { key_store: &BKS, token_request: TokenRequest, ) -> Result { - if token_request.token_type != TokenType::Batched { + if token_request.token_type != TokenType::BatchedTokenRistretto255 { return Err(IssueTokenResponseError::InvalidTokenType); } let server = key_store @@ -181,7 +183,7 @@ impl Server { nonce_store: &NS, token: BatchedToken, ) -> Result<(), RedeemTokenError> { - if token.token_type() != TokenType::Batched { + if token.token_type() != TokenType::BatchedTokenRistretto255 { return Err(RedeemTokenError::InvalidToken); } if token.authenticator().len() != (NK) { diff --git a/src/lib.rs b/src/lib.rs index 97a5615..af2aa67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,8 @@ #![deny(unsafe_code)] pub mod auth; -pub mod batched_tokens; +pub mod batched_tokens_p384; +pub mod batched_tokens_ristretto255; pub mod private_tokens; pub mod public_tokens; @@ -32,11 +33,13 @@ pub use tls_codec::{Deserialize, Serialize}; #[repr(u16)] pub enum TokenType { /// Privately verifiable token - Private = 1, + PrivateToken = 1, /// Publicly verifiable token - Public = 2, + PublicToken = 2, /// Batched token - Batched = 0xF91A, + BatchedTokenRistretto255 = 0xF91A, + /// Batched token 2 + BatchedTokenP384 = 0xF901, } /// Token key ID diff --git a/src/private_tokens/client.rs b/src/private_tokens/client.rs index d4c2b95..fc96db7 100644 --- a/src/private_tokens/client.rs +++ b/src/private_tokens/client.rs @@ -87,7 +87,12 @@ impl Client { // token_input = concat(0x0001, nonce, challenge_digest, key_id) // blind, blinded_element = client_context.Blind(token_input) - let token_input = TokenInput::new(TokenType::Private, nonce, challenge_digest, self.key_id); + let token_input = TokenInput::new( + TokenType::PrivateToken, + nonce, + challenge_digest, + self.key_id, + ); let blinded_element = VoprfClient::::blind(&token_input.serialize(), &mut OsRng) .map_err(|_| IssueTokenRequestError::BlindingError)?; @@ -101,7 +106,7 @@ impl Client { }; let token_request = TokenRequest { - token_type: TokenType::Private, + token_type: TokenType::PrivateToken, token_key_id: key_id_to_token_key_id(&self.key_id), blinded_msg: blinded_element.message.serialize().into(), }; @@ -145,7 +150,7 @@ impl Client { .map_err(|_| IssueTokenError::InvalidTokenResponse)?; Ok(Token::new( - TokenType::Private, + TokenType::PrivateToken, token_state.token_input.nonce, token_state.challenge_digest, token_state.token_input.key_id, diff --git a/src/private_tokens/server.rs b/src/private_tokens/server.rs index 052a293..bc6d759 100644 --- a/src/private_tokens/server.rs +++ b/src/private_tokens/server.rs @@ -136,7 +136,7 @@ impl Server { key_store: &PKS, token_request: TokenRequest, ) -> Result { - if token_request.token_type != TokenType::Private { + if token_request.token_type != TokenType::PrivateToken { return Err(IssueTokenResponseError::InvalidTokenType); } let server = key_store @@ -164,7 +164,7 @@ impl Server { nonce_store: &NS, token: Token, ) -> Result<(), RedeemTokenError> { - if token.token_type() != TokenType::Private { + if token.token_type() != TokenType::PrivateToken { return Err(RedeemTokenError::InvalidToken); } if token.authenticator().len() != NK { diff --git a/src/public_tokens/client.rs b/src/public_tokens/client.rs index 5c8c45c..2913f21 100644 --- a/src/public_tokens/client.rs +++ b/src/public_tokens/client.rs @@ -76,7 +76,8 @@ impl Client { // token_input = concat(0x0002, nonce, challenge_digest, token_key_id) // blinded_msg, blind_inv = rsabssa_blind(pkI, token_input) - let token_input = TokenInput::new(TokenType::Public, nonce, challenge_digest, self.key_id); + let token_input = + TokenInput::new(TokenType::PublicToken, nonce, challenge_digest, self.key_id); let options = Options::default(); let blinding_result = self @@ -89,7 +90,7 @@ impl Client { blinded_msg.copy_from_slice(blinding_result.blind_msg.as_slice()); let token_request = TokenRequest { - token_type: TokenType::Public, + token_type: TokenType::PublicToken, token_key_id: key_id_to_token_key_id(&self.key_id), blinded_msg, }; @@ -128,7 +129,7 @@ impl Client { let authenticator: GenericArray = GenericArray::clone_from_slice(&signature[0..256]); Ok(Token::new( - TokenType::Public, + TokenType::PublicToken, token_state.token_input.nonce, token_state.challenge_digest, token_state.token_input.key_id, diff --git a/src/public_tokens/server.rs b/src/public_tokens/server.rs index 6cf90d0..9f09585 100644 --- a/src/public_tokens/server.rs +++ b/src/public_tokens/server.rs @@ -114,7 +114,7 @@ impl IssuerServer { token_request: TokenRequest, ) -> Result { let rng = &mut OsRng; - if token_request.token_type != TokenType::Public { + if token_request.token_type != TokenType::PublicToken { return Err(IssueTokenResponseError::InvalidTokenType); } let key_pair = key_store @@ -165,7 +165,7 @@ impl OriginServer { nonce_store: &NS, token: Token, ) -> Result<(), RedeemTokenError> { - if token.token_type() != TokenType::Public { + if token.token_type() != TokenType::PublicToken { return Err(RedeemTokenError::InvalidToken); } if token.authenticator().len() != KEYSIZE_IN_BYTES { diff --git a/tests/batched_memory_stores.rs b/tests/batched_memory_stores.rs index 5d10391..120e904 100644 --- a/tests/batched_memory_stores.rs +++ b/tests/batched_memory_stores.rs @@ -1,9 +1,11 @@ use async_trait::async_trait; +use p384::NistP384; use std::collections::{HashMap, HashSet}; use tokio::sync::Mutex; use voprf::*; -use privacypass::batched_tokens::server::*; +//use privacypass::batched_tokens::server::BatchedKeyStore; +//use privacypass::batched_tokens_2::server; use privacypass::{Nonce, NonceStore, TokenKeyId}; #[derive(Default)] @@ -25,12 +27,14 @@ impl NonceStore for MemoryNonceStore { } #[derive(Default)] -pub struct MemoryKeyStore { +pub struct MemoryKeyStoreRistretto255 { keys: Mutex>>, } #[async_trait] -impl BatchedKeyStore for MemoryKeyStore { +impl privacypass::batched_tokens_ristretto255::server::BatchedKeyStore + for MemoryKeyStoreRistretto255 +{ async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer) { let mut keys = self.keys.lock().await; keys.insert(token_key_id, server); @@ -40,3 +44,20 @@ impl BatchedKeyStore for MemoryKeyStore { self.keys.lock().await.get(token_key_id).cloned() } } + +#[derive(Default)] +pub struct MemoryKeyStoreP384 { + keys: Mutex>>, +} + +#[async_trait] +impl privacypass::batched_tokens_p384::server::BatchedKeyStore for MemoryKeyStoreP384 { + async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer) { + let mut keys = self.keys.lock().await; + keys.insert(token_key_id, server); + } + + async fn get(&self, token_key_id: &TokenKeyId) -> Option> { + self.keys.lock().await.get(token_key_id).cloned() + } +} diff --git a/tests/batched_tokens.rs b/tests/batched_tokens_p384.rs similarity index 91% rename from tests/batched_tokens.rs rename to tests/batched_tokens_p384.rs index 7da1c84..e9d0002 100644 --- a/tests/batched_tokens.rs +++ b/tests/batched_tokens_p384.rs @@ -4,17 +4,17 @@ use batched_memory_stores::*; use privacypass::{ auth::authenticate::TokenChallenge, - batched_tokens::{client::*, server::*}, + batched_tokens_p384::{client::*, server::*}, TokenType, }; #[tokio::test] -async fn batched_tokens_cycle() { +async fn batched_tokens_p384_cycle() { // Number of tokens to issue let nr = 100; // Server: Instantiate in-memory keystore and nonce store. - let key_store = MemoryKeyStore::default(); + let key_store = MemoryKeyStoreP384::default(); let nonce_store = MemoryNonceStore::default(); // Server: Create server @@ -28,7 +28,7 @@ async fn batched_tokens_cycle() { // Generate a challenge let challenge = TokenChallenge::new( - TokenType::Batched, + TokenType::BatchedTokenP384, "example.com", None, &["example.com".to_string()], diff --git a/tests/batched_tokens_ristretto255.rs b/tests/batched_tokens_ristretto255.rs new file mode 100644 index 0000000..f37c8fe --- /dev/null +++ b/tests/batched_tokens_ristretto255.rs @@ -0,0 +1,71 @@ +mod batched_memory_stores; + +use batched_memory_stores::*; + +use privacypass::{ + auth::authenticate::TokenChallenge, + batched_tokens_ristretto255::{client::*, server::*}, + TokenType, +}; + +#[tokio::test] +async fn batched_tokens_ristretto255_cycle() { + // Number of tokens to issue + let nr = 100; + + // Server: Instantiate in-memory keystore and nonce store. + let key_store = MemoryKeyStoreRistretto255::default(); + let nonce_store = MemoryNonceStore::default(); + + // Server: Create server + let server = Server::new(); + + // Server: Create a new keypair + let public_key = server.create_keypair(&key_store).await.unwrap(); + + // Client: Create client + let client = Client::new(public_key); + + // Generate a challenge + let challenge = TokenChallenge::new( + TokenType::BatchedTokenRistretto255, + "example.com", + None, + &["example.com".to_string()], + ); + + // Client: Prepare a TokenRequest after having received a challenge + let (token_request, token_states) = client.issue_token_request(&challenge, nr).unwrap(); + + // Server: Issue a TokenResponse + let token_response = server + .issue_token_response(&key_store, token_request) + .await + .unwrap(); + + // Client: Turn the TokenResponse into a Token + let tokens = client.issue_tokens(&token_response, &token_states).unwrap(); + + // Server: Compare the challenge digest + for token in &tokens { + assert_eq!(token.challenge_digest(), &challenge.digest().unwrap()); + } + + // Server: Redeem the token + for token in &tokens { + assert!(server + .redeem_token(&key_store, &nonce_store, token.clone()) + .await + .is_ok()); + } + + // Server: Test double spend protection + for token in &tokens { + assert_eq!( + server + .redeem_token(&key_store, &nonce_store, token.clone()) + .await, + Err(RedeemTokenError::DoubleSpending) + ); + } +} diff --git a/tests/kat_batched.rs b/tests/kat_batched_ristretto255.rs similarity index 90% rename from tests/kat_batched.rs rename to tests/kat_batched_ristretto255.rs index 9ed9ced..cc896a2 100644 --- a/tests/kat_batched.rs +++ b/tests/kat_batched_ristretto255.rs @@ -12,7 +12,7 @@ use voprf::{derive_key, Group, Mode, Ristretto255}; use privacypass::{ auth::authenticate::TokenChallenge, - batched_tokens::{client::*, server::*, NE}, + batched_tokens_ristretto255::{client::*, server::*, NE}, }; #[derive(Serialize, Deserialize)] @@ -42,30 +42,33 @@ struct HexBlind(#[serde(with = "hex")] Vec); struct HexToken(#[serde(with = "hex")] Vec); #[tokio::test] -async fn read_kat_batched_token() { +async fn read_kat_batched_token_ristretto255() { // Check own KAT vectors - let list: Vec = - serde_json::from_str(include_str!("kat_vectors/batched_vectors_privacypass.json").trim()) - .unwrap(); + let list: Vec = serde_json::from_str( + include_str!("kat_vectors/batched_ristretto255_vectors_privacypass.json").trim(), + ) + .unwrap(); evaluate_kat(list).await; // Check KAT vectors from the Go implementation - let list: Vec = - serde_json::from_str(include_str!("kat_vectors/batched_vectors_go.json").trim()).unwrap(); + let list: Vec = serde_json::from_str( + include_str!("kat_vectors/batched_ristretto255_vectors_go.json").trim(), + ) + .unwrap(); evaluate_kat(list).await; } async fn evaluate_kat(list: Vec) { - for (_, vector) in list.iter().enumerate() { + for vector in list { // Make sure we have the same amount of nonces and blinds assert_eq!(vector.blinds.len(), vector.nonces.len()); let nr = vector.blinds.len(); // Server: Instantiate in-memory keystore and nonce store. - let key_store = MemoryKeyStore::default(); + let key_store = MemoryKeyStoreRistretto255::default(); let nonce_store = MemoryNonceStore::default(); // Server: Create server @@ -138,13 +141,13 @@ async fn evaluate_kat(list: Vec) { } #[tokio::test] -async fn write_kat_batched_token() { +async fn write_kat_batched_token_ristretto255() { let nr = 5u16; let mut elements = Vec::with_capacity(nr as usize); for _ in 0..5 { // Server: Instantiate in-memory keystore and nonce store. - let key_store = MemoryKeyStore::default(); + let key_store = MemoryKeyStoreRistretto255::default(); let nonce_store = MemoryNonceStore::default(); // Server: Create server @@ -180,7 +183,7 @@ async fn write_kat_batched_token() { }; let kat_token_challenge = TokenChallenge::new( - privacypass::TokenType::Batched, + privacypass::TokenType::BatchedTokenP384, "Issuer Name", redemption_context, &["a".to_string(), "b".to_string(), "c".to_string()], @@ -266,6 +269,8 @@ async fn write_kat_batched_token() { evaluate_kat(elements).await; - let mut file = File::create("tests/kat_vectors/batched_vectors_privacypass-new.json").unwrap(); + let mut file = + File::create("tests/kat_vectors/batched_ristretto255_vectors_privacypass-new.json") + .unwrap(); file.write_all(data.as_bytes()).unwrap(); } diff --git a/tests/kat_batched_rp384.rs b/tests/kat_batched_rp384.rs new file mode 100644 index 0000000..108100a --- /dev/null +++ b/tests/kat_batched_rp384.rs @@ -0,0 +1,270 @@ +mod batched_memory_stores; + +use std::{fs::File, io::Write}; + +use generic_array::GenericArray; +use p384::{elliptic_curve::Field, NistP384}; +use rand::{rngs::OsRng, RngCore}; +use serde::{Deserialize, Serialize}; + +use batched_memory_stores::*; +use tls_codec::Serialize as TlsSerializeTrait; +use voprf::{derive_key, Group, Mode}; + +use privacypass::{ + auth::authenticate::TokenChallenge, + batched_tokens_p384::{client::*, server::*, NE}, +}; + +#[derive(Serialize, Deserialize)] +struct BatchedTokenTestVector { + #[serde(with = "hex", alias = "skS")] + sk_s: Vec, + #[serde(with = "hex", alias = "pkS")] + pk_s: Vec, + #[serde(with = "hex")] + token_challenge: Vec, + nonces: Vec, + blinds: Vec, + #[serde(with = "hex")] + token_request: Vec, + #[serde(with = "hex")] + token_response: Vec, + tokens: Vec, +} + +#[derive(Serialize, Deserialize)] +struct HexNonce(#[serde(with = "hex")] Vec); + +#[derive(Serialize, Deserialize)] +struct HexBlind(#[serde(with = "hex")] Vec); + +#[derive(Serialize, Deserialize)] +struct HexToken(#[serde(with = "hex")] Vec); + +#[tokio::test] +async fn read_kat_batched_token_ristretto255() { + // Check own KAT vectors + let list: Vec = serde_json::from_str( + include_str!("kat_vectors/batched_p384_vectors_privacypass.json").trim(), + ) + .unwrap(); + + evaluate_kat(list).await; + + // Check KAT vectors from the Go implementation (TODO) +} + +async fn evaluate_kat(list: Vec) { + for vector in list { + // Make sure we have the same amount of nonces and blinds + assert_eq!(vector.blinds.len(), vector.nonces.len()); + + let nr = vector.blinds.len(); + + // Server: Instantiate in-memory keystore and nonce store. + let key_store = MemoryKeyStoreP384::default(); + let nonce_store = MemoryNonceStore::default(); + + // Server: Create server + let server = Server::new(); + + // Server: Create a new keypair + let public_key = server.set_key(&key_store, &vector.sk_s).await.unwrap(); + + // KAT: Check public key + assert_eq!(serialize_public_key(public_key), vector.pk_s); + + // Client: Create client + let client = Client::new(public_key); + + // Convert parameters + let token_challenge = + TokenChallenge::deserialize(vector.token_challenge.as_slice()).unwrap(); + let challenge_digest: [u8; 32] = token_challenge.digest().unwrap(); + let nonces: Vec<[u8; 32]> = vector + .nonces + .iter() + .map(|nonce| <[u8; 32]>::try_from(nonce.0.clone()).unwrap()) + .collect(); + let blinds = vector + .blinds + .iter() + .map(|blind| NistP384::deserialize_scalar(&blind.0).unwrap()) + .collect(); + + // Client: Prepare a TokenRequest after having received a challenge + let (token_request, token_states) = client + .issue_token_request_with_params(&token_challenge, nonces, blinds) + .unwrap(); + + // KAT: Check token request + assert_eq!( + token_request.tls_serialize_detached().unwrap(), + vector.token_request + ); + + // Server: Issue a TokenResponse + let token_response = server + .issue_token_response(&key_store, token_request) + .await + .unwrap(); + + // KAT: Check token response + assert_eq!( + token_response.tls_serialize_detached().unwrap()[..NE], + vector.token_response[..NE] + ); + + // Client: Turn the TokenResponse into a Token + let tokens = client.issue_tokens(&token_response, &token_states).unwrap(); + + // Server: Compare the challenge digest + for (i, token) in tokens.iter().enumerate().take(nr) { + assert_eq!(token.challenge_digest(), &challenge_digest); + + // Server: Redeem the token + assert!(server + .redeem_token(&key_store, &nonce_store, token.clone()) + .await + .is_ok()); + + // KAT: Check token + assert_eq!(token.tls_serialize_detached().unwrap(), vector.tokens[i].0); + } + } +} + +#[tokio::test] +async fn write_kat_batched_token_p384() { + let nr = 5u16; + let mut elements = Vec::with_capacity(nr as usize); + + for _ in 0..5 { + // Server: Instantiate in-memory keystore and nonce store. + let key_store = MemoryKeyStoreP384::default(); + let nonce_store = MemoryNonceStore::default(); + + // Server: Create server + let server = Server::new(); + + // Server: Create a new keypair + let mut seed = GenericArray::<_, ::ScalarLen>::default(); + OsRng.fill_bytes(&mut seed); + + let info = b"PrivacyPass"; + + let public_key = server + .create_keypair_with_params(&key_store, &seed, info) + .await + .unwrap(); + + let sk_s = derive_key::(&seed, info, Mode::Voprf) + .unwrap() + .to_bytes() + .to_vec(); + + let pk_s = serialize_public_key(public_key); + + // Client: Create client + let client = Client::new(public_key); + + let redemption_context = if OsRng.next_u32() % 2 == 0 { + let mut bytes = [0u8; 32]; + OsRng.fill_bytes(&mut bytes); + Some(bytes) + } else { + None + }; + + let kat_token_challenge = TokenChallenge::new( + privacypass::TokenType::BatchedTokenP384, + "Issuer Name", + redemption_context, + &["a".to_string(), "b".to_string(), "c".to_string()], + ); + + // Create a TokenChallenge + let token_challenge = kat_token_challenge.tls_serialize_detached().unwrap(); + + let challenge_digest: [u8; 32] = kat_token_challenge.digest().unwrap(); + + let mut kat_nonces = Vec::with_capacity(nr as usize); + + for _ in 0..nr { + let mut nonce = [0u8; 32]; + OsRng.fill_bytes(&mut nonce); + kat_nonces.push(nonce); + } + + let nonces = kat_nonces + .iter() + .map(|nonce| HexNonce(nonce.clone().to_vec())) + .collect(); + + let kat_blinds = (0..nr) + .map(|_| ::Scalar::random(&mut OsRng)) + .collect::>(); + + let blinds = kat_blinds + .iter() + .map(|blind| HexBlind(blind.to_bytes().to_vec())) + .collect::>(); + + // Client: Prepare a TokenRequest after having received a challenge + let (kat_token_request, token_states) = client + .issue_token_request_with_params(&kat_token_challenge, kat_nonces, kat_blinds) + .unwrap(); + + let token_request = kat_token_request.tls_serialize_detached().unwrap(); + + // Server: Issue a TokenResponse + let kat_token_response = server + .issue_token_response(&key_store, kat_token_request) + .await + .unwrap(); + + let token_response = kat_token_response.tls_serialize_detached().unwrap(); + + // Client: Turn the TokenResponse into a Token + let kat_tokens = client + .issue_tokens(&kat_token_response, &token_states) + .unwrap(); + + for token in kat_tokens.iter().take(nr as usize) { + assert_eq!(token.challenge_digest(), &challenge_digest); + + // Server: Redeem the token + assert!(server + .redeem_token(&key_store, &nonce_store, token.clone()) + .await + .is_ok()); + } + + let tokens = kat_tokens + .into_iter() + .map(|token| HexToken(token.tls_serialize_detached().unwrap())) + .collect::>(); + + let vector = BatchedTokenTestVector { + sk_s, + pk_s, + token_challenge, + nonces, + blinds, + token_request, + token_response, + tokens, + }; + + elements.push(vector); + } + + let data = serde_json::to_string_pretty(&elements).unwrap(); + + evaluate_kat(elements).await; + + let mut file = + File::create("tests/kat_vectors/batched_p384_vectors_privacypass-new.json").unwrap(); + file.write_all(data.as_bytes()).unwrap(); +} diff --git a/tests/kat_private.rs b/tests/kat_private.rs index 608e8f9..1c7f6ef 100644 --- a/tests/kat_private.rs +++ b/tests/kat_private.rs @@ -45,7 +45,7 @@ async fn read_kat_private_token() { } async fn evaluate_kat(list: Vec) { - for (_, vector) in list.iter().enumerate() { + for vector in list { // Server: Instantiate in-memory keystore and nonce store. let key_store = MemoryKeyStore::default(); let nonce_store = MemoryNonceStore::default(); @@ -151,7 +151,7 @@ async fn write_kat_private_token() { }; let kat_token_challenge = TokenChallenge::new( - privacypass::TokenType::Private, + privacypass::TokenType::PrivateToken, "Issuer Name", redemption_context, &["a".to_string(), "b".to_string(), "c".to_string()], diff --git a/tests/kat_public.rs b/tests/kat_public.rs index 5c959de..9579594 100644 --- a/tests/kat_public.rs +++ b/tests/kat_public.rs @@ -47,7 +47,7 @@ async fn read_kat_public_token() { } async fn evaluate_kat(list: Vec) { - for (_, vector) in list.iter().enumerate() { + for vector in list { // Server: Instantiate in-memory keystore and nonce store. let issuer_key_store = IssuerMemoryKeyStore::default(); let origin_key_store = OriginMemoryKeyStore::default(); @@ -193,7 +193,7 @@ async fn write_kat_public_token() { }; let kat_token_challenge = TokenChallenge::new( - privacypass::TokenType::Public, + privacypass::TokenType::PublicToken, "Issuer Name", redemption_context, &["a".to_string(), "b".to_string(), "c".to_string()], diff --git a/tests/kat_vectors/batched_p384_vectors_privacypass.json b/tests/kat_vectors/batched_p384_vectors_privacypass.json new file mode 100644 index 0000000..f10f8c4 --- /dev/null +++ b/tests/kat_vectors/batched_p384_vectors_privacypass.json @@ -0,0 +1,142 @@ +[ + { + "sk_s": "a6cc76ac4eeab993c9fd1a54461b70d71a812b1c81a856da36b435141998cc659f989c7ed07e719a953506f08ee57579", + "pk_s": "02ae0a316b04482d2bef06e077f9a6984b001cb3120e36acd2b8c3b6d93207a9dc92c5e6f77bbbb7fab2b94a283bd253c1", + "token_challenge": "f901000b497373756572204e616d652008fcf5f691d0bccfcb08a566e4380de6963e57299acd5bc18e632b20d0d6cd800005612c622c63", + "nonces": [ + "e54330e99663c7eb6bc1c51f5da4d5cd480cedcb477b3ce15ad76e456e90f2d3", + "6e3b10bac01119abd5edb032624ac227dced1ce34909d83006e128eb892ca9dc", + "f40a92c6261f6b0fef28f5bc7f355b83cba36eb0d6fe53bfd7953a914a09bb40", + "8c7881d31a747f1ae13e16e6eb013e5505a51d633273d83f5fa13e9c7bf1ce1c", + "d200f303871a919fa47fad633e658dc717efbb80cc422a569db756a02b33165f" + ], + "blinds": [ + "9e0b9e02d71bc172427227cb251adcbd10401228e365ef28c850e6ff6347bd993dd5758144293cbef9ac3ff3d2bee67d", + "050de1c26cad010b5b6df43444ec9b65a42a6731017b33250ce13eda0ef828b7ff13894d8fc71bebe5389df1572a0887", + "3715c483a36b05856615bc2c6b2f486accafdedc87d83cb78de1ae56af18b77dc00dd4171afd361b290fbe39b0e50f83", + "d2e3ac61f36da08e1280212eb4502656d0167acd0f35aeb1fe823420ca8bcb553beaa6804b4aef3f8a14cd917ee19706", + "cf19824cfcecbb9347e63b7e6e27d33c5589514213f94069b78c84fa99304cfc8d23a33c8e9b31819a20421b9c34daf7" + ], + "token_request": "f9017600f50204c502e98009179713446623f365d13a55df0061d84ce3f6c34a525a8d5806182c680e300b6ff5dbc7f2bcc46b5bf390021e94f053ddac1c8b3216f06a9cc077f3991f69d3e5c5edbeb30f4cb919c44ded4261ca050fd86b399e6402c198beacf1021551c73543831aa239edd6e544fc5fb653e6c83b01b04be6e7720ea55ff6add7ce1c29685f82289e985a8931b6cdc38702cc092df8a3cbb6dff87ceffa29e23120ccc66b5ca469eb5084afc663d5186971178cb4e7eaedbd70b7d78d0678ffa5a1020fb2ad1085fb32e12530712d5f9ff124b3edb875f54266ac7eaba60e9f0cefb032b5e0965b058a61834fc179234ac911", + "token_response": "00f5035ecc09e4efa0d58e16900a999fe3179a34658c176ecab614684c5ba5185a725e3ca51b5ab111ed1b7ccb3aae5360e77b02d6d69ac80d50656e33b8944400232a465303cd8647321bb9d8e146ce336ab57ad27460e42ae2708dbe76896192a172690328cb778a9fab28d6e1ea1b52fc0d0e523a1e7e6859930dbb2508c74482511f64017ca5536da0ebf22aa1c4b6b1a575d803157f8f050e6c65f1ec9f8619774b441b99c2e26c4a69a4a14b6e97cc344ce3b9a6f2237c724d34838fe484fc21641264029be3f90a27cf9a7dc99ed9dbfe05db97475c57445c1ad94e614e8d05b0b4c790b6959e0faf0d27e481d898e440b7ebdb8247ef1ebc61109477133c400dca02225e362f1368178fd3c5cf204dc5a6e9c66532efde24539ff05254da25a395a33da4ab1366889015dea208ddb31de98d950d6e7d893eab2379aca67a5ced59586721b331fb8dde242eb3043caa643c68d8", + "tokens": [ + "f901e54330e99663c7eb6bc1c51f5da4d5cd480cedcb477b3ce15ad76e456e90f2d3b07c404e77e0a7c61522c0bb5725d8bf9d5938609303c91da2d6854c5706ba326cd50b94f166541a6e3d9960719c2b3a67fa8b02bf37972171a0a8d85d883576bfe26afe7f32f7fad21846a28017bc3b4ab4a2584b7ab94c68f0f5dee38715c9a9cc4651312ddec28b72cd425a4452d4", + "f9016e3b10bac01119abd5edb032624ac227dced1ce34909d83006e128eb892ca9dcb07c404e77e0a7c61522c0bb5725d8bf9d5938609303c91da2d6854c5706ba326cd50b94f166541a6e3d9960719c2b3a67fa8b02bf37972171a0a8d85d883576deaab35761e50c4285674f6a93f29394bb64baa57ee259c0375922f976d76d1ca2e56f74d7142f2e0f6fa8bdf8eab625", + "f901f40a92c6261f6b0fef28f5bc7f355b83cba36eb0d6fe53bfd7953a914a09bb40b07c404e77e0a7c61522c0bb5725d8bf9d5938609303c91da2d6854c5706ba326cd50b94f166541a6e3d9960719c2b3a67fa8b02bf37972171a0a8d85d883576aeca434259731ad386520f8d12617f0e60d4c72afdd99d326c6c6650db22e355db93a7146101797676bb2feddfc8ba2d", + "f9018c7881d31a747f1ae13e16e6eb013e5505a51d633273d83f5fa13e9c7bf1ce1cb07c404e77e0a7c61522c0bb5725d8bf9d5938609303c91da2d6854c5706ba326cd50b94f166541a6e3d9960719c2b3a67fa8b02bf37972171a0a8d85d88357678b5297742b4d87708aee241ba65b2b23c12920a37469646e33fd3c38fd617d8b80929912343079f1dabe000000cb2db", + "f901d200f303871a919fa47fad633e658dc717efbb80cc422a569db756a02b33165fb07c404e77e0a7c61522c0bb5725d8bf9d5938609303c91da2d6854c5706ba326cd50b94f166541a6e3d9960719c2b3a67fa8b02bf37972171a0a8d85d8835761798aa0cb226503d4c98ddf74a72f6f699c06d5df95c2a631c0e6e891ed895fb255eaa3ba42daded6d184b8b817e6579" + ] + }, + { + "sk_s": "87f67bd56a480c960c40544d31ba6fef5e1e86934c8fa22829b2b60a4d88aa1672ebc161390dfec22969ca4b6fdcc410", + "pk_s": "035838bbb8c75d646afd6232e29e1d8e68c1b6733c28772ee7f4565b09352fdfda6b4538277f26c306c5eb52b560c124fa", + "token_challenge": "f901000b497373756572204e616d65000005612c622c63", + "nonces": [ + "f1c5c33d1781ccb32cd9f2e8a41381a146a3674c31481b6cbf3a7e278079f899", + "2f4dccf2b27d54ba5857abc946dc46a65f15a13d09887d8d63dc5720866c7d2d", + "be83ae3faded3c9d5dbbbe4c3fd815e57516fef6f1495952761a17055027520a", + "b9237bb08983b501e72b66b3ad4249d29f16964f0dd3c12b91acafdab9563903", + "335d6a764ce3aa422006a4b1df29d8d9c9d637d4d57f95bf678af665b200f28d" + ], + "blinds": [ + "a7dbce521f61c377432806554966129d8a6e5751f67507edc6da26c9001400c818c3665ca286e35418abc3aba02394d1", + "be6377f5191f32397d07f4e1c1b2b1a7299c7ace91644b6e39c4bf4311ef1ab9edd6aaa5ba1339e4b814b5cb56df8752", + "4ae9628b50a815ff3f2db19e140d91b0d5483fb1b29a337997f473893e822d165b8bf26a0105b81b36a973480293dd5a", + "934fe5fd945d37aedb4898977f46ff2dfb19d07e2c2cbbd0d1011621dea06d847e603ca86a5a49ea9ffc584facbfc81b", + "b2400c6c5c3fba0e15ecc35f08ddad31beb32181399204af8a1ac70df3e9edd775fff16bb2b2365ac39039f9da13664e" + ], + "token_request": "f9011e00f5028da2a279c0754b2b96dd07bb8a46922b1980ae294eb49b7c0a89581ffa67c82a0eaba186748739a6bec1ff38ff1cdcdc02c5ea0364be784224b7589becf5495dd2c6f7fadedad02fc7eae60fd4026944a637f906e65fc2667f50497e393578de0103a0c88aac8f452e1dd8d7c6348f7fd46c10652dfcf5dbdf767a8fcde3a97832140270a9e477abc0a0d49d00c5a3e79e63031dbb0ad82d0011dce5e5f82e2485c9621471b33009fa15f9cc3bba6ce4110a418cfd527ef6426ea0ce1112f881d0cf82039ba18b397555c67dc2093464595738bda4b264df0dc4fbbec65a2ab8c02caefdca133c34f6f27b7d8c81001656d9bf5f", + "token_response": "00f502a31f53f6f782e58d3493d89a4ee99921ed88f9567091187b03f914925265676843dc5672b07ff60a748ba1363cff1268029accb3b1f80431fd5283cd8c84b80b93d6b82289133325d035f3917a6e94a97933cfd15b0f3d83976425143f89bacf930379f31485aa94bcde3c3bef3d185612363a3ae12e13d893a022d0a8676a8cf6549ffaac9aa65e9f39ab12cadf6165ca24033391025c4c15e8e169118e05ba28a7da1747fd8e5e0714d7a53a2c671ac1da395b8f67e9172fc911028df2f73579f7380366a4599b54a447e295e15f5607901fe5f5b4448fcf12ffa2dc8c9c9f72abf19767c0b4ef9d22421cfacc78cc6e95ca83894e10e78a58e384fe4ef800f8e3ae5274ef7acf590f172cb6f20901272033cc329b28cf919ff30e6e06439d7147e522eb3fc229371cb3dddee40f8e0673f5185b112922ac161be839ffda827b95d32f265160e2b29bc4d46064e2ea5986f058", + "tokens": [ + "f901f1c5c33d1781ccb32cd9f2e8a41381a146a3674c31481b6cbf3a7e278079f899085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b074511c6e2ed16eaba18ddc32d7311bce8944c6bf2dc7a7d69e111c0fdf03221e7443e102f19242347cafd72de424face2150a67900d7aa9525d715188742ce7c24a370b62e56bad64c8afe7c508574b2", + "f9012f4dccf2b27d54ba5857abc946dc46a65f15a13d09887d8d63dc5720866c7d2d085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b074511c6e2ed16eaba18ddc32d7311bce8944c6bf2dc7a7d69e111c0fdf03221e5926d32c08303065c308986ec89694cdd6f5bc36f3cf6da2007eba3fa91c6456a1ca763eef0c0a66e6d16db9112e2e20", + "f901be83ae3faded3c9d5dbbbe4c3fd815e57516fef6f1495952761a17055027520a085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b074511c6e2ed16eaba18ddc32d7311bce8944c6bf2dc7a7d69e111c0fdf03221ed74d82569002bace148e48c6429c364de90d7cf0024b88e6457067a072f75256e3dc2f777f9e36e968b44b93ad72567c", + "f901b9237bb08983b501e72b66b3ad4249d29f16964f0dd3c12b91acafdab9563903085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b074511c6e2ed16eaba18ddc32d7311bce8944c6bf2dc7a7d69e111c0fdf03221e656e8fa6ab439fa74cc45a39ac43e2f6bee3b8a389d04ab63b4112303c8bd97b57d3d7dabe97bed3e6274260872c4808", + "f901335d6a764ce3aa422006a4b1df29d8d9c9d637d4d57f95bf678af665b200f28d085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b074511c6e2ed16eaba18ddc32d7311bce8944c6bf2dc7a7d69e111c0fdf03221e517c750ebf0cd357417c6c3400e1ff5b47d1e44cd7b0da3cf9ff8b6f049e84e871c617cd960ee3ad0c3a88ad16a148e0" + ] + }, + { + "sk_s": "a1284254fa38ae150fb53d5cebe1b8c4e7e24f275dcb5f1647e1ad9ba5502facbaa75fbb08d64b2c4816e938ad56a7a0", + "pk_s": "03da46cfef80b0c543c1a39a5c70f05e81fb71655a233d180f41b5292994083e21cd874c3039c1f00cc3a3752e2dacebc4", + "token_challenge": "f901000b497373756572204e616d65202ac77a9e4011ea93c1795c001de6663a18551a2e31a1a2d38d15915f3eb034fa0005612c622c63", + "nonces": [ + "0b64466941cb7fbbe714224db26568a3f469f50de700ae15d147fe769e6c5ee8", + "e0c960896005316ebaad68340884728a01692dfb093a6f3a2ea2e1af26100062", + "95573a604cdd6c337a6732195df6b5dab7c5d7623f18b2f2959762cac8fbc989", + "7bd0494f35b3368874460ee2ad67b6dd727ad0798b6b4cdabe1fd30a0cb4547d", + "0f171905ad6e4d172a4abf311ffd1b02a62fe0560792529d053a7e51e8e5aefb" + ], + "blinds": [ + "c8da2e13bf1eb83aede75fe7b74b3c8f24a8f9c99a8f8dae33a90f1450c630f754a2286bc22e916c51f5244ced23c687", + "0671803f5591f70150bdea4ac941c403438faaa384ec699d2d8da5fa00eb67058445e7f2cc7a7e3b573fcf2752a20e8a", + "9cdaa0953a82191ac80f9367804dbf655766b26c7a8a0aca2380a20bd8e7321c3c008a62f449205493a351cc44bc8a91", + "5782e4f0ef94c0a2dea7e2ff6c168be236c0fe9724ccc53137ee2a679591c6e9abbc5a58bc7273683bb68c6825c36487", + "860211f46827545db73605d8a64cb61e88003128e28d8abea933f65a9c772c8df57a94c0345d96802f3df07d8bc93667" + ], + "token_request": "f9012f00f502fca99214eadca090691195438de6743206920039a12f62e5f88d07697d2b33df845d9be588419d148e5e55e6e1336dcf03d71e09cef8a2ad2d909d8fb120bbd492da0e9d8dccf1856c2986a4ebe1194c47ee2c7a8162d80675ff0ecd2952126ab2023603a7efed936e5fa1ac27d66798392705a8eeaca35913228ac4a181cf840f9bc1309e30e85ff746b48153e3a1ffe27b035fb2731e99f28858ea668f4c0de54d2e82b6fd3fa23cfb0b0e4d94f79a85bc5122b842b1ec70568e3fa2398ffd4380e702759b3d5ed1e10ece3a0b46e492f18c9dc966eb97ba7fb3f53697d72a48e344ef4a25a1f945c1c509b8b10fb2083cb3e7", + "token_response": "00f502223f67a2c247d7dc1bab5915b6ca8c7eb5f07b54fc9c0b6ee4e7f37fef5166735624149c768c23ddfdedbff145807f040284f04dc40a701e01f6a476ab515f0cc455f3618ddac17a9d5a794f6cc4d4c44241d912da80b71bb72d0bd408c8d62b4e021f66c0a97504e8fc5b4eaf9140f83d2ce1a88ed71d4afe8e2a0b5ca9b37a68d08d916e226cb41168f96f87045452618202b4ad78fc2e980db23850ab33b92bc61b3bbd2a77bb0dbac7e6cd010a23154fedeb193faeccde271c23249f08d95fcd1503791429741c2ca3e85c00fd7491de474d4698451a4c11be3d04094575da92d965d09d4da7fc56fa4173a8b784b38576873ee8d577b7412aa4206d94d25769d9565bbfa95f05b109d9944a6a5f6a475ff4be0822f335d37500d11d98a4c774d065c44f30340c92196d4834a34b19ac34838d167afb147e46780f7653eb804717367538bf5ba6a0fc16803e9d9e1b0c3ce9", + "tokens": [ + "f9010b64466941cb7fbbe714224db26568a3f469f50de700ae15d147fe769e6c5ee88955a2c71ce6efd396fd69a5477b1d9526abba84aba52277ff9ddda3b217dca7c4747eef8797fdd845702b81a1b6941f92cefe8598e39c3a452ccebd8059e72f3592f0e2f47a25a05bb1badc4caa6bb5fb088c8ccbd3d12f640c3e30885cbb797b51895da43a554438f7f4f0d96b4a1c", + "f901e0c960896005316ebaad68340884728a01692dfb093a6f3a2ea2e1af261000628955a2c71ce6efd396fd69a5477b1d9526abba84aba52277ff9ddda3b217dca7c4747eef8797fdd845702b81a1b6941f92cefe8598e39c3a452ccebd8059e72f60b98cb3617a7a02ba6c1f319d76731efd2f05482f3faa7255ce1a57c5758e23d7d15e616bf569eb243bf5e5da59e1e1", + "f90195573a604cdd6c337a6732195df6b5dab7c5d7623f18b2f2959762cac8fbc9898955a2c71ce6efd396fd69a5477b1d9526abba84aba52277ff9ddda3b217dca7c4747eef8797fdd845702b81a1b6941f92cefe8598e39c3a452ccebd8059e72f5aebc808f9e685b5e3b802ee858eb96152f05f0133d81a339947bfc11458eee5d2e9d1bd7ce228baec432b3c02b4c9c2", + "f9017bd0494f35b3368874460ee2ad67b6dd727ad0798b6b4cdabe1fd30a0cb4547d8955a2c71ce6efd396fd69a5477b1d9526abba84aba52277ff9ddda3b217dca7c4747eef8797fdd845702b81a1b6941f92cefe8598e39c3a452ccebd8059e72f02158770c9c07fbc8a578f00a87e118bfbab9fca4deae47684033646676377879dcd814dd27b57854c944b139b9213e5", + "f9010f171905ad6e4d172a4abf311ffd1b02a62fe0560792529d053a7e51e8e5aefb8955a2c71ce6efd396fd69a5477b1d9526abba84aba52277ff9ddda3b217dca7c4747eef8797fdd845702b81a1b6941f92cefe8598e39c3a452ccebd8059e72fe135f94b40cad3cb181c8572a8961a905c12eb70b4b1a8bcd7375f939d7217f75fd1f6e1a3e399529034dbb644d27b1c" + ] + }, + { + "sk_s": "89fadb6b551bdddc89fd5899ae61eaa3d62db9ac875ee3ab8c909dc59ed53279e9a78e48c24e3653191e74e1b68cb67c", + "pk_s": "02bd580cfe3c9645842c9548dbbb29d5b3291ea9a4bc7cbdff67cc59a3cbc7dd464a1569da649918eb8796bacdb0401cdf", + "token_challenge": "f901000b497373756572204e616d65000005612c622c63", + "nonces": [ + "35d0dc6f8292b3d3e123d5de265c406ed9a04c7ad2185014b21efdd509d302a8", + "335540b8d6b63bfd2546543aea0b0f47ac1ee69697636d3b17e23bf81f2f9406", + "8a4349457a84abd59f1136beec51894319f2bd56457e265670a6f40465e31da6", + "eabb9853f957f5ae21ea892eae0f9f304444b2ec540d0c9ba534b1f806538b33", + "91dfe5bb7d392a39fd3f25df511049a9fb5a6f129dc1cb48658dfb17fa47d32e" + ], + "blinds": [ + "cca8ef44fcc889c79406bb85a14d2ee25bd0ae491fd76159da8380bd541001d6472cf20a5a726869dd503283a041a0a9", + "db0fb7b2e27d2d5acfaa28ba42e5afbd45a8b0a4e8db0a044d7746d277cd0488205932a9a2f46eb6b1cd5bf72bbb96fc", + "b4aeb60c6b04aa6c12ccbf339ea66cd4c4919f8ce3c8a85d832f4aa1fab3510a8bfa9f1dbf53513ff8469af87af2f6a3", + "f964fd79a789c693f1a72d5018a17f418db2ae206901c34ee1794204f7f357aee3a5836b0206f784818b131c0a386780", + "1e27a3eb87a7d87707174a0b10b4ab08d20248c3a900993b35dd221c701bc67370fbfe9640df060de409931fb484222e" + ], + "token_request": "f9011b00f503d6ba1ac3708a41400374bd8084258609eadfd1ca048249b61a052cac3f28156cdfe55ef118adab47a450f99926a846de02c14b5051911eda1c5da16d9242aa30aa15aec5bc3f460f5e713ed2b30e21565d2828c671205b1815e0963b017d354ab003d81f9962c515d644328399450ce33a2284b325530ac2069bc24c606b82cca9d5bf05d4079df9a2879ecae69eed7dfc9c0296928394668d9c82658958d36b945ff24fad805474aa137e806412314de0bd1d160f5074be9e4b658939833592eadebb03cc45d5671b1f240255c59ef7aa50705a3cbd97de071f744a7f9ecb93c086cf549665a6b3380f1aa726fa7befeb2224b8", + "token_response": "00f5022f029296373ad550413e5067a6630f0543c8effa83877da62002c86ec3a059c0491758a2ce6ce998c9e59ff70164a97703ac2e645ac15abdb7007076de25cbdcac6346d6776057e57349ea075bff118be5cdd6c103384ff54e9d9a7c8719770fae021b05fe1d02fb861013eed16c03e16f55cdef15a0aa36f60b2b5373804e021def7120d3c5a6b51ebf1509222e8cf62447030a03708b0acb060a083d8021ec460391273f2d01bb8a57cb151fcf32f466a5f81205da66772a3f2fd617d9a87b30ca4a030f0539b2dab46567bf8a6c36b9f6ea31afa0f0fc2d66e4600d3310b1887304f5a778bc608443dbc66ffa58dd660b663e54ec1030f77d23a78df844dac32eae534d8f98148e488f74750e0ecfa1944c770e657f93838940116015c177687718ac470b723d2880ca2b1fbfab2119779e79e9745a1c3e807bfff161df73d5374d49b20ea2896f949e642fa2d48e4309b560", + "tokens": [ + "f90135d0dc6f8292b3d3e123d5de265c406ed9a04c7ad2185014b21efdd509d302a8085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0cef2d0579c167b7f88f50fedd656fe9f9e343bfb2c2b5daf85a430001e44fc1b2a066dc525df92bd48e97dc658236520dbe73fa2a66e6557b222b082ca88519b986344895015882ff0c94f2477244b57", + "f901335540b8d6b63bfd2546543aea0b0f47ac1ee69697636d3b17e23bf81f2f9406085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0cef2d0579c167b7f88f50fedd656fe9f9e343bfb2c2b5daf85a430001e44fc1bb72a7f3dc117bafca79a5110cc0c05b87f2968d2a6f8de92f4e2a799d5fd036838a5514286ad97e3dd823b9dfca603d5", + "f9018a4349457a84abd59f1136beec51894319f2bd56457e265670a6f40465e31da6085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0cef2d0579c167b7f88f50fedd656fe9f9e343bfb2c2b5daf85a430001e44fc1ba7e7f3f636e21f07604cdc1dda07eaa4766c0f1fd8f6d3186298f41cbf3b80087125a9cb3f2e477d4767a2eecc3a622a", + "f901eabb9853f957f5ae21ea892eae0f9f304444b2ec540d0c9ba534b1f806538b33085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0cef2d0579c167b7f88f50fedd656fe9f9e343bfb2c2b5daf85a430001e44fc1bc60bf4df727d971f88bb9e0be79288c20a74e776cbebc406a0317d983df26b391468247b025292b7771da8c315fffdb2", + "f90191dfe5bb7d392a39fd3f25df511049a9fb5a6f129dc1cb48658dfb17fa47d32e085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0cef2d0579c167b7f88f50fedd656fe9f9e343bfb2c2b5daf85a430001e44fc1ba3aa4c234c5d681d2d5cd01c69eb7e729df8c80fb97e6fd3d241c414610c14d122ba6d89835379f46fdd2e4eb714171e" + ] + }, + { + "sk_s": "96b476c722f9eb6debe4da6e21b851355124ce498d69f044550688ad5f5064fed74e7bec9787fb47f543ff2dbc48b4a1", + "pk_s": "02c37baa35b4b8c65303223e9108ba3b55050f483eef09cb10fa5f477b388dde7fe4ee9b4acebf627a8b306fff8ec38006", + "token_challenge": "f901000b497373756572204e616d6520e851f635e4b70527d91039c1fa1df34dcd378c5dc40d53c63ea19b2d61ee79430005612c622c63", + "nonces": [ + "f1ea952b18c763df523bf2c99d8bfe406f916e81bdc8c73220a98c639addeb54", + "f6b7b7f3addc6c4350d6da45c70947ff7c68b14fbc23879fbd45b743f8bf9021", + "553d93d7e4f323a6731a9df77f9cf8c16309bb7542cc3818edf2de26ed35922c", + "450679542798ec2c3ff9d6320652bee427225a5e85405edb3782b435f1f69bf8", + "9af7f91c8fe53b43875c20831299ab34f60d73e1142b884a8b4f850e77976141" + ], + "blinds": [ + "4d97c566febe50e63c29fa8ec40a041fa4df9df4536b6546dd3dfe15adbd7fe45e3aae0fe6737d17dbc803951886f208", + "816d4d4937e24744c12da4ff300747b7637176ab743aeb102b4131d09358b0d11a31ef26e89c68a217a0c0ef2b4fc418", + "3c47322b0ae6d45cccd874a9b4b1f3f5b1a65f128b9f0c088fa6982017e6fdc800799cc3e31f5f08fe780a9b05a23d9e", + "eb3faf3bdcd334b233e8c37eb351f8019065003ee36a307b884b9d5c06fdd65f7026488c7c31359e0c48ee0b7ebb66fa", + "5f305455c56bc265ce9248e3c69cabe80b284656b1c49fd47cd33fd30b2346242ba3a38ac7d76d377ecfd13c123ec523" + ], + "token_request": "f9010c00f5031a38f4c16ad8468a0cc8d790ce94235cfdc360f19b2d0f8f52fe81997ef4e58040c427f560c1da1c190f731f7611f1d402c078ea9dfaa6ad8508f8f6052c2256bcd06551abf0648d961e2e562e578583b3d771f2f14ca6189ce5b7ccf4528362cf02d7c7bbfa0ac56151633dcd837b13b6c20992aef8da4aa63a881283a9511ef73b41276d0cec63683cc23b0c3eb1dd6b5002705db2ee95ce4910a637d05663abe55a8749a69cf3675dbc72e8fe26b672d92043bbbf4a57e4f3813fe5269cb553cea4031a22036f5d59e9842f0d53ddd2825399fa481d03da0adc914c7578ba30d46a93db52d044b8838089cbebae57a4949593", + "token_response": "00f503fd4e5d77789d5b00289ffa92b6e90de193059ae21d6e66e1e25026414f127ae2432261cf3a75ea4bd2a86c7ae1a770fc02e16d25cc5d5df6db98fbc488719ef9f2f0074c1d4238d51832b682883a37747aef72e23c1aa60bf813067287bbf8d43402366251ad82d1e3425fe939bd934d974f8ea4ef4d7376333c37c8b540967ec5975c8519647b4b4cc3a40f7d11bcfd1e4403b45b94fab8b726f0931c102bbca151b13800e3abf25dd3eb9c85d11beeef2598e26e7fb7e6b42e24bb5e8102908ce5f802b167b563d0b1f11165a5943376457f29fe213b4f19c81160f7cf04106423342c91dd6f36d1c3901d8aa3d42e2adafbc69367b349dcd0d209422dae11c8bd25e705369ae6dad7c28046fe485fb52727829dfcb2f62dbd3c0b067e41806a98699325e8d06315de5c06dfb45e44a3e1c83e8955ef9ac8459511191f7d3c5ca740d1385c4be884bfc4fc7a95cbb4ab4ab20d", + "tokens": [ + "f901f1ea952b18c763df523bf2c99d8bfe406f916e81bdc8c73220a98c639addeb54043a6f2e95897320c56bc2f26ec84995c545c4d297fd21c75a791c0d8e0fb83dbf6095d194341c414605e92ac84b46714d4d498c32eba032509f865171e1630cff1a51b9ace93f1ddccf21749c930ef52ab0555d6a9e1c1af42844cc31448a1f92e987975c5f3fae6acde55ebf528316", + "f901f6b7b7f3addc6c4350d6da45c70947ff7c68b14fbc23879fbd45b743f8bf9021043a6f2e95897320c56bc2f26ec84995c545c4d297fd21c75a791c0d8e0fb83dbf6095d194341c414605e92ac84b46714d4d498c32eba032509f865171e1630cd0de5022f12417b8ec7971f6d813fa62abd26770ac5c2e0f0ea12d108e5269894cdff356792c7fb5e6a133b2b15881cd", + "f901553d93d7e4f323a6731a9df77f9cf8c16309bb7542cc3818edf2de26ed35922c043a6f2e95897320c56bc2f26ec84995c545c4d297fd21c75a791c0d8e0fb83dbf6095d194341c414605e92ac84b46714d4d498c32eba032509f865171e1630c783c091123046828480b5e9ec92f55fd0ae99ee29a3a51f77a5a605e7a4cfec363192a5620fdd619e7b57762552fb8de", + "f901450679542798ec2c3ff9d6320652bee427225a5e85405edb3782b435f1f69bf8043a6f2e95897320c56bc2f26ec84995c545c4d297fd21c75a791c0d8e0fb83dbf6095d194341c414605e92ac84b46714d4d498c32eba032509f865171e1630c5eb5381394ad80d92e8f6859c25794cd0ffff34d92e94ff90106b6d1451660ff7eb2521290658208c3e14d909d421765", + "f9019af7f91c8fe53b43875c20831299ab34f60d73e1142b884a8b4f850e77976141043a6f2e95897320c56bc2f26ec84995c545c4d297fd21c75a791c0d8e0fb83dbf6095d194341c414605e92ac84b46714d4d498c32eba032509f865171e1630c5728756bab4abc1953b1c3b96de3e96eafc4260df42ca2475219c3984d088fa3c22fa0b3d90ca91fb5475c1d32e9182c" + ] + } +] \ No newline at end of file diff --git a/tests/kat_vectors/batched_vectors_go.json b/tests/kat_vectors/batched_ristretto255_vectors_go.json similarity index 100% rename from tests/kat_vectors/batched_vectors_go.json rename to tests/kat_vectors/batched_ristretto255_vectors_go.json diff --git a/tests/kat_vectors/batched_ristretto255_vectors_privacypass.json b/tests/kat_vectors/batched_ristretto255_vectors_privacypass.json new file mode 100644 index 0000000..bf04b91 --- /dev/null +++ b/tests/kat_vectors/batched_ristretto255_vectors_privacypass.json @@ -0,0 +1,142 @@ +[ + { + "sk_s": "dd250ea692d60516da19174113400111eb7348fb842779ca3c77bca2fbf78f05", + "pk_s": "b2eb1e5b6d466cc70e625b79001edea54dcee9aee0690b5cf980f83b9e684172", + "token_challenge": "f901000b497373756572204e616d65000005612c622c63", + "nonces": [ + "4b52784f93e0a62da0d1749af08bc0603b9165be786491e265be71da07086678", + "02b17926e6b75137e9706019e6327b6879e6bb2e44791ed900360698ee467744", + "764afc50a46ff84d4f04d6ac1acaac1ca3c2c1566baa7700a49c1eebeb16941d", + "ac0ad2266d360450d9df4df592d2a31c8dd8cc3c069e500866e97be465ddd742", + "efeffd3d33f9aaec9f66346dc996dd6ecb17d8ffb2f82c3d2b6021337f6dbcdb" + ], + "blinds": [ + "7aa8f36e97f6aa2d8262a67a48e9fbf4f80dac9a2ba4129a5a150b5479cb350e", + "7c852ab9676f6eba67bab00709999fe4ba0c5f5c5c4cd077f1feada6a0336802", + "b91ffbad1a261fa6b187dc6dcdc95bda04e1e1c083dab705c0b89c14a6f65e0d", + "bdc5884179ebe34087bac614d3c14bec558b83affdff7c6ecf06d9f7157b1e0a", + "23f7c6f78e1d0f7025c1a8c3b4d949d6314bc1bf87c96ef23058dbc0a4be6708" + ], + "token_request": "f91ab800a03af38273121e353cf9046fc26d01b9194d1b21536a98016b0275f96a265fad5824a73a365863afb8d2a420ea30ded811ad6ba5d10881a9c9f9eaf3ebfdc13967e4b76c2da0b09dcbc35182406b9b55c69cfa19496cbc7c29bf437316468f1e1b86c8189ad09f3f3efccd4f92986feaea16227a24b758ad073edc3edbbcb22201bc5caaa4d21bc36512d50bb20c7c9abc686a4926226bbd1988945adb6af6e67b", + "token_response": "00a0d2ae5d29a2c8355579758ece5aad9ae58eff80308ccb18b36674b0c1f9e0f854b053c2e1dd2fbb773c458f34cde10d3c95384296dede50361a2fb6cf575bc168c4c245673e4b85e8a9de1c62ac1f16550b696719acf38c254727d5e7da8f1c478e7e385fe4f45d37db06eb42405e5a4ff5825066dc90114413f7b20cc1cba4438a6c48393b7d77846ab6f31cdf2e407755b1088e05d324c283ddd716923b001968b6888c37e14a2becc1bb004f73cdc5367f0bfe778cbec06be8779d350a8b0bb32236e5af49de78d90884c0a514e332a7d3b4631b4d14ded3b6022a7c756e0b", + "tokens": [ + "f91a4b52784f93e0a62da0d1749af08bc0603b9165be786491e265be71da07086678085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0e1acce20306e617d4e7f8ef43b3dfda8613d40f02964bac09ce041ede369b0b8468476d1fc4a4b9741b5b92cd9bdab9c7ed32fdcd4d86c481287745050abd7e9d5de8df14b6625f281c84a0a985656e7807a801a9cd0fad555a2be0df241ee2a", + "f91a02b17926e6b75137e9706019e6327b6879e6bb2e44791ed900360698ee467744085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0e1acce20306e617d4e7f8ef43b3dfda8613d40f02964bac09ce041ede369b0b8a835927bfc52b66e7a738cf517be0ab9a6b4c8ae153b955992b7ae40143386750a01b5be5cdac5236ad8d01f1ff09f6020b493e6f9bef1dca5edcac92772ce54", + "f91a764afc50a46ff84d4f04d6ac1acaac1ca3c2c1566baa7700a49c1eebeb16941d085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0e1acce20306e617d4e7f8ef43b3dfda8613d40f02964bac09ce041ede369b0b8527cd89ccd7358342d7d996790ebdbd0fcff4f7219c566d5f06db104700239903d203c4725e628692456bc69dc18e39873c0c50d37dfbc4c898157f9efe9652d", + "f91aac0ad2266d360450d9df4df592d2a31c8dd8cc3c069e500866e97be465ddd742085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0e1acce20306e617d4e7f8ef43b3dfda8613d40f02964bac09ce041ede369b0b814aa9168bcef5c1e91cae51240d24a142fb8e192ee090230121386fac5b97add8849a563e0a2ea5e081a7fe48557644fc6cf556799a15f0f9c3f83777d2b410e", + "f91aefeffd3d33f9aaec9f66346dc996dd6ecb17d8ffb2f82c3d2b6021337f6dbcdb085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0e1acce20306e617d4e7f8ef43b3dfda8613d40f02964bac09ce041ede369b0b883269cfe0908cda62eb314c7f6026a0669f69e68d344856199e973bb394fcb19aa4f7a97d65061b2484177b67e160d7a56e3efc2bc8efa0f203e457167fe99db" + ] + }, + { + "sk_s": "730970ef6e15a40e41b4c9ffb27e5b7c6a5219cc8d5d6b6409434ab78a9ab709", + "pk_s": "625ebea59d8e330ef06306d0e078790c83f4cf0837ddf1136e20b8b3e28ebb1b", + "token_challenge": "f901000b497373756572204e616d65000005612c622c63", + "nonces": [ + "3ebeb7328408633171365eb34330c91e18f18a62972c52b83807ece0307375bb", + "a64cfbb7abf628c2111a7bc20bdf8989d2ef945b3a6b483eded0adc5263099a5", + "0d25aa5fa185292c0b412e8a1783009a455f7ab0a87add9d6650879b0ab3641d", + "b548ad508b273ca70073c962d0dc23082a913214ae5ebe07cfcf4a93ada81939", + "bf3e2bb99961255b397b5460ce3bb3fa5979fe1dfc8dc6f719745ee7d1ce52a0" + ], + "blinds": [ + "fc1b1fe1db5c816bc7f6a1f6fd368a9478ffccf59d4e6438ba475cc21897dd06", + "bccbc9d3dbf1d3accb05d5e546d0c404e7eca1ae6dfa6dbd1494c65347db7400", + "08b75a4b6a969e4fb47f0c149ade74505d3ba8635f4de05b36fdd0710a6e9205", + "b7d9c32893e5c22ea4fb80e834f3cbd0a926c0f0e28181845fbd0afca34c1102", + "31eabc4e43cc08fc57a7a6710c8ef0561880e84f36bbe9e41484dd2ef873ca0a" + ], + "token_request": "f91a1c00a08c3e861182b1b3635462cb8df7f96dbd3aa8ceed0783b42de6c507426fc65248b429a4a3a7d0deb6ba3ba722a7c8a851b9c49274fee81165067d07536b6c0c6aac435e66e05d0796362774db64656ed321ec87b5519af2f73437a10a5c611a08f2707ea79cea9bacc968d5485452a5c497556f47efc95b7eb58b6783e833a6656e42f8a71e5c88febbd88158f75f652cc316cc6ad56ea82e2d2812729311fb1d", + "token_response": "00a082c8d135062246b10fb75d568292f2d34930f9b6b4a13d322f723aeb8a423e44eeb728594df7474af474bd7101f75d952c8d8ac55c321a7833d7962c9b26f160fe853a6c0373324836962e71b7f58a5d5c53e07dce2efd86bdcf1cd9f249e335b257905739d56bb35badb42363adddbfd092866b3229f010f18badae36fd803158291f4e5a424892a40d577543c7aa4237b5caf60a8569eb15cf0d067f73f4036bc17c2848509c35ecb0482aaebe80ee722224a98bd1e132a83e7fcb07446800c27855784653ec80523842b53c5cb5c9b2410d121d4688c31168f85446ef050c", + "tokens": [ + "f91a3ebeb7328408633171365eb34330c91e18f18a62972c52b83807ece0307375bb085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0ccd46907be2b7d9280b92502e893973d6b72de5ca44dfc7337024990ebc9671c0b3b5a9c3fe56856a934559c38d3953c893ed5554075216f63017af3519a0ab6c46d909263a7d04715dcf6a50e7011f01a83afbdeb0a9a32e2b9f73c07791d67", + "f91aa64cfbb7abf628c2111a7bc20bdf8989d2ef945b3a6b483eded0adc5263099a5085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0ccd46907be2b7d9280b92502e893973d6b72de5ca44dfc7337024990ebc9671cd5fe6e9eebe3e490c3a15cc55d8a6e507a907366bca1450c2ed09ff617a4bd82eb7579020e7ba751a7c41bb9c563e932c02d0314280c99bdf01a3cb19bab0818", + "f91a0d25aa5fa185292c0b412e8a1783009a455f7ab0a87add9d6650879b0ab3641d085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0ccd46907be2b7d9280b92502e893973d6b72de5ca44dfc7337024990ebc9671c1a8c0f570a017ba6069d67fad08afb92daffd6d4347d3e29eec6bdc2bd00058bc9481318a7c21ffbc9c4756161acb1372e7f4ed0ffe8fa758321b8b56864f854", + "f91ab548ad508b273ca70073c962d0dc23082a913214ae5ebe07cfcf4a93ada81939085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0ccd46907be2b7d9280b92502e893973d6b72de5ca44dfc7337024990ebc9671cbe3799a53f972cf03168d7cda71f06cbf985f56314d7c8f0494d9de1da07a0862b195ffa220612ce9cf85e081ff6faa8d9132e818a5994458a5ba7bb921bc93c", + "f91abf3e2bb99961255b397b5460ce3bb3fa5979fe1dfc8dc6f719745ee7d1ce52a0085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b0ccd46907be2b7d9280b92502e893973d6b72de5ca44dfc7337024990ebc9671c00b662e4e4268474f18cd810484669d33b2b6610ce7ee0378fd3e77353538653c6b87be88f814e0ef1e995317d765873995efa18f1f3ab984f3794dc030a7ad7" + ] + }, + { + "sk_s": "f60de62591ab639754399f470a8fd7a7511604d2b02171082624e6e1af8d7101", + "pk_s": "761e66cfa03486c9a7520a3e72637605c551e4e6ff84e5cdcc943ae9a3ce4945", + "token_challenge": "f901000b497373756572204e616d65000005612c622c63", + "nonces": [ + "5f3c9ef89db9896d05f8f2aa0c2f04914cd6e023eea8e8a6cbee48ef8c41d163", + "cbbb0bd982d0b3685e97040ec3d96319b7c985dec3b580a539fef946824a266c", + "e6c8bd0d63a3d5eacac6df4b26bdd778f636729f03fc427f2e9c657b250f2f70", + "b628355cd2abb3c0166519b3088e2f9da52c161739e9821bfd30d6baabe66dd0", + "d9864bfa8b9dfe4dd357a576ede8cc6ea31f824c3bb77768e0187411b5ce4e1e" + ], + "blinds": [ + "7dfea2127ef4c7b5dfb0723db02c92edd2bd123c6db63d7c89d5397e2c456c0b", + "e1b2a8b487d79f7e8a0b4ae1e5ced58f5d2b8b0eaf20511b85632fee192ff502", + "51d1e0eee1c5ae203c2eddd9a63b082b7941e0d84abd08473302b394f8d1b903", + "9d5588217bce298ecc4d8aed9fee926f380f7005df22ac04a65557f8ca508409", + "6146e8c58145a6f1d3aaf7b01e851d7f526ba55146ae3d157239f8a2d90b1606" + ], + "token_request": "f91a8800a034f4546037c714c443f352b84ac1e5defb7d82f59cadb89d6241a3709f59aa14d8fa178e6b2c250faf3f43b8b4b127930d71c8283f15880f35a9201a6f31525318b05099c776a85413a3193b74619293641e8b38b03bdda3606bfe1f55015d2622993cf7bbc75fdccdb2689a7a7def1c8b3692232d421ef6c3d0bba118d68b3ac0b85fdb931aa1620a81c2a23add737fcec2d5f68786ff8264de0937d01b6905", + "token_response": "00a05c291a2f0006c4195dd5471155aa178c40e5179c563026c23f09cde5d4575952c03ca4b42849c621d451a18a57190d2f9e47b119ccf72dfd31dc7cffae6afd635211a0cd5ec57b19d58d45108ab6ba9c3af8cc2f8808c45c1bbae1201309a0543288aedcc9b11f79c3e31fc84c7b05f20a3990d9ba2446e22579147b504fda54cefcd607b8977bcc1d2d46ec302c7b97b53d7c3b2374a06477ba2d01189b153665b8aa02441717da07e18a48f56aec1be75d04447f6df34179f1f09eabe68e092209e89516eb224a2b00edc332e57fed093d72d2a630df93243fee6be799eb08", + "tokens": [ + "f91a5f3c9ef89db9896d05f8f2aa0c2f04914cd6e023eea8e8a6cbee48ef8c41d163085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b07428affe8a27c99e3dcb1b01d393d4367fed6b2eae8cd7afa6194ae6a2e6dd8872ea1efe3c87e09aafef3d4cdcad2bcf2273cf6fe9d43f57f1291fb69735ff95916337728b34410b8ef12b7743c2eba44e4a63b20405bf1db61361baf233fa0b", + "f91acbbb0bd982d0b3685e97040ec3d96319b7c985dec3b580a539fef946824a266c085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b07428affe8a27c99e3dcb1b01d393d4367fed6b2eae8cd7afa6194ae6a2e6dd8837ed48aea7a4cab63af9261444021cb136c31d4e5994612916868a7389d0c68baa50e3b7f755dab8f23ba76fe33741bd6e831febbf36e31451ad406eb0054675", + "f91ae6c8bd0d63a3d5eacac6df4b26bdd778f636729f03fc427f2e9c657b250f2f70085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b07428affe8a27c99e3dcb1b01d393d4367fed6b2eae8cd7afa6194ae6a2e6dd88774c4a4ab619a9e4bf9f92e81e569f4717031c8c5289dc124dbee0c7e6a1e656b8bcf7afb196992b353f80f834de4b645952508890f6611cdf3ea61e2f693cda", + "f91ab628355cd2abb3c0166519b3088e2f9da52c161739e9821bfd30d6baabe66dd0085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b07428affe8a27c99e3dcb1b01d393d4367fed6b2eae8cd7afa6194ae6a2e6dd88c5e9ddea1e451ce7f71720648928c5caa26c70d474ad618d3d256f95b9751c9b0bde0eb4ed124ec9342883655c9936647cd0da63dacbdd0946cf34db9d2b923a", + "f91ad9864bfa8b9dfe4dd357a576ede8cc6ea31f824c3bb77768e0187411b5ce4e1e085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b07428affe8a27c99e3dcb1b01d393d4367fed6b2eae8cd7afa6194ae6a2e6dd88f3f9faeeab4c3f3ccc1937fee2ab5a560c5709fee20320252e65049de8cbfa5249bf29148e002c7fc51a749c0db0e3f46ba12eb01ae17023dfdb66adb558d92b" + ] + }, + { + "sk_s": "aefdb15522e80fa860bc933474c61eb193dd624969f89309693f9eff17ea0301", + "pk_s": "0ac754a9697f5f92bd41594b1c3c4cd6049ae1086d164bf363616e269e0b9d5a", + "token_challenge": "f901000b497373756572204e616d65000005612c622c63", + "nonces": [ + "9120a020d13f07aeeacb8a4e302b58665f63e7ff759e0dd3f83dc5e2d37f8f84", + "343e037c5c440777c29257f71182a6d5a4a906497a7f6125e0646065fc006747", + "a1faf0b19f937c3add0c3afb959aaf260ffb73cbec070df9641a6f16aa2127fe", + "00ddef017ca1bb59b176a4f5e4346dfd70f5d9beb2993c9b829d0682cf706bd0", + "55a7fc0ef9679eba908eb91743bd81d1cd2ba7c9c1a9da9d023c9fca8d9d58c1" + ], + "blinds": [ + "178e503c2f36dcf13fca719dd65fa43de3461a60c18464bb88ab515aabd4040f", + "5f7c268e020171c39bb281fa019ad6975b77bb24bec0aff5efe77ec3566fe703", + "28d4f51ab4eed49dcd143123787351f894099fa659ee34e252ee14e30774130e", + "f97444d40cee4bfa37355bb67aa399dcd7bc3645242b15503fa72e7a2d3d4006", + "ee08793d3e8d88649b1e675a1fcd6188bcce74de474dccf1e6a246c768bf140f" + ], + "token_request": "f91a3d00a04a02f7dc2b4cc0cbb5756633bb6800a165d307d293997e4136bd7f1d6e66211e3caf5e80ed8a5fb8851c291d3fb6e88d79295aa689d80365eb019651e1b94e3768bf1b69058668d6682b16a94519776a65e18871b1fd5f718e151363b69c594cfa6600bf29a48edbf697e3c697a94821b0a82fc81d6e90d763a928e6210de9138c58b1c6e92dac57cc5e03d3f1f2f910d742d49640342c789e385c8ab720f627", + "token_response": "00a0bcdad9c510cd841f42a048fb9620b62b179497cec64de282e158c05e220c4526c8721a14e9f87fb4b63f36a48499f987a4f12ea507882e565e43e98256a169647ab29101e08df9df8a5cfac38fafa2eec731f9a5bf34d04e904e8d0055a14f0a2a33bb5b1a709bf78734157aec45643f2095cad2e0d69e51d83b2ccc1ba5637570a148c19966d61f3942363e0dfff37ce31868caf89f250c753ea4f326715551c161d0c9b549e5913367080c2d9e65633b3a7f9d38863743d3ef61ab0b22510271488c0d31f3c8009bbab0326e773176f00a190c5017c9c7a1f058bd5788a708", + "tokens": [ + "f91a9120a020d13f07aeeacb8a4e302b58665f63e7ff759e0dd3f83dc5e2d37f8f84085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b079ab2e2ffc4e493a64a6d6bb8d56ba577bd875aca3e9ec09f6b1d0a91cf0fe3d157896c746f8a44f7e3db70f3cc90aea022c0931eaf704e1a1c6e486c3ca8427c62f98d82a6b8aaa8d14da218c8830ec54f29addf4356ead552d5a0a587b606c", + "f91a343e037c5c440777c29257f71182a6d5a4a906497a7f6125e0646065fc006747085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b079ab2e2ffc4e493a64a6d6bb8d56ba577bd875aca3e9ec09f6b1d0a91cf0fe3d92bd631b7b6ece15321934ea8b66c8de1bea827966233831150df05c6c245d23a19a4624e04c1fff3603b577e8f9ccf5679c1e047802cb2985fdee8d0ca4eb6c", + "f91aa1faf0b19f937c3add0c3afb959aaf260ffb73cbec070df9641a6f16aa2127fe085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b079ab2e2ffc4e493a64a6d6bb8d56ba577bd875aca3e9ec09f6b1d0a91cf0fe3d4901bea44c90a568fbf60618e1a5bd05b325d088c07f50bd34f4277450563020b19791c269455d431ed48f23bfdac21272806552fd0ae8a39a135d00aa670f3a", + "f91a00ddef017ca1bb59b176a4f5e4346dfd70f5d9beb2993c9b829d0682cf706bd0085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b079ab2e2ffc4e493a64a6d6bb8d56ba577bd875aca3e9ec09f6b1d0a91cf0fe3db638587d20e277049dd6246e5f41ecf52fd34988ba0d99dc62ee10ba6d58898be2015c0e7ed0ddf592b501db360ff7ace037cf373fce3c56b42e5a4233d79996", + "f91a55a7fc0ef9679eba908eb91743bd81d1cd2ba7c9c1a9da9d023c9fca8d9d58c1085629ebf8ac78268495177e73be13fd92a87c8f07a707bb6000eb41f58279b079ab2e2ffc4e493a64a6d6bb8d56ba577bd875aca3e9ec09f6b1d0a91cf0fe3d7ce3ea1de21d2b861735a85016191f552a6d20fd99ba379636d8c1cd74cb17b9696470bf467a43f80b13fd0ba135f14397e25df897fe6124911ed46545535bae" + ] + }, + { + "sk_s": "c93465f46feba7c4508d2b54caba6c2f1ea8a4e2751b6c892b8acf096e597d09", + "pk_s": "f28ed1e1c2182b9d864065f5ccfb9740bac78dc33b18ace780beae4a47e03750", + "token_challenge": "f901000b497373756572204e616d65209f791cc98d69e9367ee0bd449866aadebb16721d5ce50e0ae46d4a6a26149d040005612c622c63", + "nonces": [ + "7b4d3d2be7395e91e5765b4bdbf7a4cefa82f1b5ad1bdc856ab88e54d9e0b783", + "7453774b0d40edb95712ff70ead8f32bad91fbd77820c1638379caf744ead022", + "a419878faa1eb228f43bca17874285ac9f17855aee53118c5e0a64ca380c9215", + "52e19a5a758e853cc7e60b7bf3645da3f628277388cf565f98e085e45bec4503", + "7b88405924fe9f688dad53cf683539bd092da7acab9928411eb338239edcc6d0" + ], + "blinds": [ + "e245b518d3e9c34f981d0d1d1a76e6b175456298ff6d23c53dd6748ae06f7a05", + "018e1cb21f0076cbc2356749778483c6adbd702787a2a41fb38552e627288109", + "1c22bc6e9fc8f375918261fd4312b55292d4653d385cf0b2b42a81bfd0c1cf04", + "d848c7507952fbe782dc1aab4473cc34a6b95e58cbb6ff0adddb7c7a29798907", + "cbfeb51bdc8fcf35dc00738bc6ef3eeffd46593e4ff425881db6dd274025a901" + ], + "token_request": "f91a9400a080c7f067277c5787f384e6fb7891e0b1d53c0ddae91c6724f24128c957e10d02dc0d76462f58cc8c862a867304525ff2fdd73485af42efc21d06294a48235e671007c76cc0bbc10da94ba78af14c3a6eeb40e3b480c36672516faa24164ce85a2c4ef1164447e5ee8d6cdc59805fe8bfa281e3ad8a84b50f56b2a16d28a92942dacc82ff589ab35cd31b4e7cc05196555a698d760bec441bbd3facddaf97eb7a", + "token_response": "00a074ddbd72a1a223fbea20badeaf52836d32f948b9fd3135447959c6d5d80ca92f282974a6541ecb43841e12a7382d990c3f61ca77b9e582394b41a941055745271a89f657163158e6999003979cccca089af50a167c3d6760f3e02a1a48b99465644890ed8831f058dba343d962903247c44185267c8ee1ce161a62ebe420a018464037bb2c79fc2c9935862ce8bffb947ad94236204b8595e4d3b76e0fbae25b0f1297b5101f49c08ade649d67557baad6ded4cacba45e9d406f7bbb657113025802225f3871c467f7bce12ab48bf630df7fe4d586a95214723aa742dfb1d80a", + "tokens": [ + "f91a7b4d3d2be7395e91e5765b4bdbf7a4cefa82f1b5ad1bdc856ab88e54d9e0b783bbf623f0ecbddd9a32348cca39da744cbca18006f94c7115a7de587c988ee756d9b74a3a6ecc92af260534740bb9b0f183827e2f0fa66720656b012c7d6a4b94e62770767ec2de335e9c598541bb9043c066f2f6f21ab8b9cdd6145da15271f20411252ff4e5ea32bf38db3e4c6b8ffe56b5108cd8b78922c8a84bad999a1b65", + "f91a7453774b0d40edb95712ff70ead8f32bad91fbd77820c1638379caf744ead022bbf623f0ecbddd9a32348cca39da744cbca18006f94c7115a7de587c988ee756d9b74a3a6ecc92af260534740bb9b0f183827e2f0fa66720656b012c7d6a4b940b38c30ed39f180cf9f49116b31068a32a7cad1395dd2cba777af4f19359ca817e28f57e02e742667a2a2e58ec11787ac882daaf9d89e6eaaa9c7cf68f3f683e", + "f91aa419878faa1eb228f43bca17874285ac9f17855aee53118c5e0a64ca380c9215bbf623f0ecbddd9a32348cca39da744cbca18006f94c7115a7de587c988ee756d9b74a3a6ecc92af260534740bb9b0f183827e2f0fa66720656b012c7d6a4b947f18346046a11404b12f79484e05dd80baa2fb98183242c1c649e60bd0d120caead7779821bd90fe8c6c5eb3b21bf0918d391f3edefc5de5dd6828c5721acca9", + "f91a52e19a5a758e853cc7e60b7bf3645da3f628277388cf565f98e085e45bec4503bbf623f0ecbddd9a32348cca39da744cbca18006f94c7115a7de587c988ee756d9b74a3a6ecc92af260534740bb9b0f183827e2f0fa66720656b012c7d6a4b948da352a1d236a42a1a1ac7ba891b8759350449e9d40894d6a329b5835a54c0a135a0a6aa609007c641afe17c1092c7b905c9f1af19c40419956270855991caf8", + "f91a7b88405924fe9f688dad53cf683539bd092da7acab9928411eb338239edcc6d0bbf623f0ecbddd9a32348cca39da744cbca18006f94c7115a7de587c988ee756d9b74a3a6ecc92af260534740bb9b0f183827e2f0fa66720656b012c7d6a4b9457b5c214f8126f2378e39f546e697d13f095962b879b2e038e070302199c4946f9dcda3157c2844c6077d8061d5d50605a4ad5fe49acb7cbf50d10f8a169ba8b" + ] + } +] \ No newline at end of file diff --git a/tests/kat_vectors/batched_vectors_privacypass.json b/tests/kat_vectors/batched_vectors_privacypass.json deleted file mode 100644 index e0f798b..0000000 --- a/tests/kat_vectors/batched_vectors_privacypass.json +++ /dev/null @@ -1,142 +0,0 @@ -[ - { - "sk_s": "00099749166e6377bbdd1e24aaac3c4c7080f9f2e51bc67377801d6d6f7f5b0d", - "pk_s": "fec3e2ca79653b05423f97041d18a042feda860cc1e49f5c8d74c047bb5fe160", - "token_challenge": "f91a000b497373756572204e616d65000005612c622c63", - "nonces": [ - "a85ced4a79d27cb29410e11c6264c9b1858f9211a68cfe83b6fd9387f0329196", - "ef916e8abfe1ed00aa524f3eb782cd27a6eb6bb0e776365a89c1de35000ce0eb", - "87930bbb25067eb50cda7e6fb41e722ef369f10914387f3330751298e7713af4", - "9fee2b658decbeb563936a9a33c3a52338d8c1b76fbaf8f9619bd5f4f165f5fc", - "6c2b0263e0734a629f5549df3353a7717aa3ddb9f52fe24efd8931857690004e" - ], - "blinds": [ - "d15012e063bec57a9b1042d504fb8af8d7b8735698b980f9cc3af36faf776904", - "13971ff9954a70e0443a19bde71426d11259ffb9a0ac77acc7d19083c0126c05", - "631f830ea13f176227a8e599d282b55d223324afb04a31f20a742f09300c940c", - "a8cd8a4d170fb088976b55ff85763155d9f1d427ae88eeb5845202b007cca603", - "674c58b5b227bbed8329bf686b38b950d7dc7e4cbf05cfdfbaac046283645a04" - ], - "token_request": "f91a3f00a044220559db2a9be0255b1f2edc1a7a1b9116addf192a6dd4065ff47d50fac31e9a3c2c8fcffbdf309cc69200a08744bcd8e02ad13cf5f207658c8eed4ad7af1e42c01678352abb182c5f5ee158a5f8dab7de8260e450c353fc64b94db3feaf012a0e8bd936076960c31b58c6b308e9cd95278453ff83ac1b890388ac87f18a292c987233466f3df186613ac4e7535da93f5550e491c31b842df601ce100a4e1e", - "token_response": "00a0a88dbca07f4b518b8cf9c53f622aef4f353a96094cb6b7c983a16d4fcdbf3e08a603c6fb0949ce1a24dc8a18e97a0fc1cf4ca94c65557f06a70ddc2d319f90271a3e02e9532ae10d0c6cbd0a5f02a9b8dff47254a74e893ca3a8a2425cbe4537208f202be6547f3db14d5e3876942c0d63918121f7c27e215581e193190588222cc5e9f0f408f9f080f955bd29bac158849b31da340a316a208147c0b1d4cf0b7389dd0897e59e17603c81c2ca23509f1208ddadd8a3042e5333f90cb3d4ba06424c54f8ed6b387881ac863312ffbcff6b13224eddc80f64ea6e7df8b772920d", - "tokens": [ - "f91aa85ced4a79d27cb29410e11c6264c9b1858f9211a68cfe83b6fd9387f0329196d7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e07922a11ee9fb60aa6cbf42f566cb409db51aa94e12fa12c12cbfb8bfd9b576dabf3fde88a52783077f46eeb6707cb83ec3988a4c573bb57d10484bb872d655c6e4bba2a12f9fc41800a1ee72c5329cd75aac8c44df46ee73e2fc79c6c780fac85d35", - "f91aef916e8abfe1ed00aa524f3eb782cd27a6eb6bb0e776365a89c1de35000ce0ebd7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e07922a11ee9fb60aa6cbf42f566cb409db51aa94e12fa12c12cbfb8bfd9b576dabf3f63d899fe99672ca3bf2c5de677e99558335b57d32f28d8d52f41fce322fc42dcdf6ea269b8d53d53fd30e1a80996631f75ff98cc2c26cfd4a3c4bb67bdae4229", - "f91a87930bbb25067eb50cda7e6fb41e722ef369f10914387f3330751298e7713af4d7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e07922a11ee9fb60aa6cbf42f566cb409db51aa94e12fa12c12cbfb8bfd9b576dabf3f6101c9bc1675b5c9b4206daee8bf298bb3fa52b82e6579f1cde39623f5a2249f5366c3f63166abfeeca4e530be246ebb713d88d1a2ecdb1b311e1706ccd8bbae", - "f91a9fee2b658decbeb563936a9a33c3a52338d8c1b76fbaf8f9619bd5f4f165f5fcd7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e07922a11ee9fb60aa6cbf42f566cb409db51aa94e12fa12c12cbfb8bfd9b576dabf3f870dd021dae215e3b44748238a80c512169e129907eb95e4efe599583221ef93d260a645c342fc9b34e229f7b66e4b48022e8bcd661754c1f84be50b4da123a5", - "f91a6c2b0263e0734a629f5549df3353a7717aa3ddb9f52fe24efd8931857690004ed7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e07922a11ee9fb60aa6cbf42f566cb409db51aa94e12fa12c12cbfb8bfd9b576dabf3ff8cc99011a384d84a6b215ee531463419a39750c3cb92c4261f77ddfb5860ee50ba1da53ea6e023e113b709635e7bbad2eb66d99b2c5d6a1e051c57ccf96e938" - ] - }, - { - "sk_s": "c881869c0a8a275c1db11218b9b0d1dc0160284061bd427e6591d5a46cf3210f", - "pk_s": "4e99b2cabf7806c902b63e6da99075e74d73486578484526675c30047997984c", - "token_challenge": "f91a000b497373756572204e616d65000005612c622c63", - "nonces": [ - "73fdbd8b5554ef19e65a21b5c8ab800692b0114101ad2b0a332098eab0850f1d", - "00d5106f96ec202033c93e349f97126edb1c76d751bb86f27bbdbb9629744315", - "b954933ee934535bbc14af324bd9af21074c229b2ac87e76664297045ae1b965", - "16e8a03cacc00841d0e74ea0fcd55b5005c90d10c29c0707715449ac346636dc", - "f735f2bbc5c6fec78cb0deff6fcabe627c95ef0ea56129780619245260f9e827" - ], - "blinds": [ - "6ba70a7bbf4ded28646ea24c1ca83e3996be04e9ae0c44d3d32d2cde5dc59303", - "7371995192aad3eb005953bc2cb0f53f95f84bea1f4a539c6764c4721bd26304", - "ed7fef5e124add7c09ca43318a0630592e31694fc80d167e3e49b1a00a4f3501", - "abe71871c4d39b086181a47863a9ad4c698e3d123e7123721e75fbc43f8bc001", - "2fb1280f0e2f2a02e60b123b93afd36f8e0bbaeb66853c6036fac35c3658f703" - ], - "token_request": "f91ac600a0f0c7ab422e06b0ac3f0cd8c38c63f00a434544d92fa9de21927526c12385be2d523aa75582b4b822c1f4cd79047208d7b5b263dc7000e7ceff1574a7b53d962c7aff97e8606428b40d38d71f6857880cc62d550b72b076c5f038b790ff447f6756444538195b6691e24ce436310e49e7af0e2ee78358f5069561e82dcfa17174e61c2636531e419aa4deec11b1140b049bdcb3c37ed401c976d4a1127427a455", - "token_response": "00a0565a485c36862caf04795029e1b7d9f8f6600bfbf4a2a2527b5c6ecc72327a04c4547a038fc1e2daf532a45f1debf221d3ced2df82738ecabae7aed47ab54159a2e0574398cde4852b2307a81f8bc498577f4644adc4817183b5a144e527e313a00874f889705a69788874d715e9e9c2069eada805347c3cf1738dfe5f6da4364031f00cb9a6263faa7db9c99b3a6910bd9f1953127f8d8d6de064c3c2718904e2422f92cdff6bc622eca360a8b6bfe79d218a2e32cfdd416aa4f320205e010847e245bd2b863828241be75a7a1c17fb02493cda0a0c3a5040e8747f0da1f409", - "tokens": [ - "f91a73fdbd8b5554ef19e65a21b5c8ab800692b0114101ad2b0a332098eab0850f1dd7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e079223fff337292864c73efe14afde3a7e0f6d438c995ba96401245c527700694e2c62ddc0f1c2b6f74bc5aca8064eb6a9947f2bb9d4560635bd790f54e0ab2cbda6ed9212ec025be5038b1826cc8fbeac5f4000b99564f77f2c4fc80bc5d5c139129", - "f91a00d5106f96ec202033c93e349f97126edb1c76d751bb86f27bbdbb9629744315d7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e079223fff337292864c73efe14afde3a7e0f6d438c995ba96401245c527700694e2c65dcf15d8442a454074f6052178c2d7591c197b217a717c0b16360d56ea1c76bbfa52d5c279e3bba337f27165226b6f707d3274a019120196729087056413b237", - "f91ab954933ee934535bbc14af324bd9af21074c229b2ac87e76664297045ae1b965d7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e079223fff337292864c73efe14afde3a7e0f6d438c995ba96401245c527700694e2c621cc9e6ae22620a1d3e041a4ec387252f73a121f4c22699659fd7e767bbe4eccf93d92ab209d1dc41f0afea11486bdaeae49c893269bb23c3beaf1c9ef8756b3", - "f91a16e8a03cacc00841d0e74ea0fcd55b5005c90d10c29c0707715449ac346636dcd7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e079223fff337292864c73efe14afde3a7e0f6d438c995ba96401245c527700694e2c66d1c9d7312e0ea5fcc39504cf65638cce0742f78b101a56db968cc40b3d032f7f9b6a89f1ac420ee9a37cf75425309cc593b7a311799773139297ab319d13cb3", - "f91af735f2bbc5c6fec78cb0deff6fcabe627c95ef0ea56129780619245260f9e827d7fe7b88d0a789e1b15aea3ddd21e9d04528bf9818b8b5687d7f3b7c30e079223fff337292864c73efe14afde3a7e0f6d438c995ba96401245c527700694e2c6c800ed76bce0b425c85e93ed61e5d423ed7bd4eb5ed86fe9e5309ba868ef8a667c0a80c1e7710de130e0fd1c85030f6dbd9141b8dc06c9eeadd3238eb8be6844" - ] - }, - { - "sk_s": "b881947830376d773c5d6369b09c52e52604db4abf616ac8a2121204af58100f", - "pk_s": "80e35a010e072e93dec2a9c0616cf40cf6aefd458baee098e26dbc92168e8f35", - "token_challenge": "f91a000b497373756572204e616d65208b0924afac992e626ed70d49c46b2dc93745bbc4a9906b5b0e0e5ca1ffc80c310005612c622c63", - "nonces": [ - "ea1caaf88fd91ed5dbc684c495d2eeca7f4c81d567a5f10fb8e6f5ae1d26bf6d", - "a2d1d0a61904cf63007e4a96ca5989cd01fa70c0a531d1fe9bbe8876f4e65d0b", - "b91b874e2da110cc0997fb242f772804f8130b636789fc48549ed4fa1a1c39e0", - "7315f30fcc964c66457e207a2d32b8ce5e16c369009d1e611d069183676a6958", - "fa9c4a7c832d24567f6017a9b1df22abab8fdfcb414f5dd42f8fb544f9a5aae1" - ], - "blinds": [ - "37d9b39f458c4b4ac5b71f09d86463a701a71ff4246cfdc364f44629e204e904", - "7f73c1cfd7e2598031aba2cfbea5503d91afe90af8acb686db24d95a14056e09", - "49b57435b7fed2ff265023acaf6f2e5af94354826b49f9a24f4951e156278803", - "74c6eae24279411043ad9566446dd4ac0bfa677ca119937af86b25980321e405", - "3e73eb47fce62a54deae0a6df2fdd783ad9a18018066ab98650c241520bab107" - ], - "token_request": "f91a9300a08c5dfe4026465c645ce67593bbd7ff6db7bfacea689d81b7c9a1d2dad245c25040c697c9a78f8919c56e24d31ecdc07b560e64be300ecf69b0538d50f1c9864d327f63a652ddbf4180b924bbff8dabfd6025fa6c4c9b2b3f6a9c85c699fb8850027e257a00d6a2ebcfac72ca16124709819598f1635e4b1e342e588943e12a6a64124065865beb8b426d9ab4121c1f0f2fc75a448cc17d06796796e90ec17761", - "token_response": "00a0b22e8b4b4c4c7f33500f941ee16f3dcc44533d8e1a469b873fcc4706c988164c068b99edad878cae45c7c306d2082ee56d122a79286c077a5cd99195d4e5302c4cbb19abf409f0736ed6318d51b58a6617204d095a190589df0a7c4b2618c85eb00dc1c02f3549799109de4f66999d6daacebd462092db3d62060c37ffbfba6900f3f4a6a8b564ee2654687cf2d441aef61176eb49e369924afd92bee348494f8a630b1056f1d6e1b154ce652bede73f7aa039501188d70abe097208285c59057d3b4ff80d2fe324cd0525ce8f180340186fcb81d6fdd64805fd32cfa7144b03", - "tokens": [ - "f91aea1caaf88fd91ed5dbc684c495d2eeca7f4c81d567a5f10fb8e6f5ae1d26bf6df1a29327781131b8ab32b7753be11fad865cb3dd0fe20ee228e70a82d13b5fad2f73ac8c76425b8344579269a6c17b937e37d538dceb5e1f05d05e312d1102937d82a3727786ca4b7996cd7848d1ba23feb211e8f6925a41733fd8addd46448a036d713aa436b0a1583ed3591469a247b2e6ac9afed912f06dac3bfee0151b7a", - "f91aa2d1d0a61904cf63007e4a96ca5989cd01fa70c0a531d1fe9bbe8876f4e65d0bf1a29327781131b8ab32b7753be11fad865cb3dd0fe20ee228e70a82d13b5fad2f73ac8c76425b8344579269a6c17b937e37d538dceb5e1f05d05e312d11029360bc032cabd7220009e17d938d35ce4a8769358d62ee00e67df57f8ea3328e67692a9364c54d68b656ab53d7db371bfd2beb14236b157fb7a36afecabb2c807b", - "f91ab91b874e2da110cc0997fb242f772804f8130b636789fc48549ed4fa1a1c39e0f1a29327781131b8ab32b7753be11fad865cb3dd0fe20ee228e70a82d13b5fad2f73ac8c76425b8344579269a6c17b937e37d538dceb5e1f05d05e312d110293a1736ad0ea74210d1859d2e9df87544e83bb5edccc6e3f6c23656667e7309641417aeca1979bdf2bbe206f5c7f774b9533a23e900f1216093fe5a4443166c6b8", - "f91a7315f30fcc964c66457e207a2d32b8ce5e16c369009d1e611d069183676a6958f1a29327781131b8ab32b7753be11fad865cb3dd0fe20ee228e70a82d13b5fad2f73ac8c76425b8344579269a6c17b937e37d538dceb5e1f05d05e312d11029337ba23d0a83dffea63578495c569bf500fd5f6b24cc7a34edae8ed6dbd4131912aed4ee42eb9a12e3dac3e80739970c594e8bac3143c50cc9058fc8829764b88", - "f91afa9c4a7c832d24567f6017a9b1df22abab8fdfcb414f5dd42f8fb544f9a5aae1f1a29327781131b8ab32b7753be11fad865cb3dd0fe20ee228e70a82d13b5fad2f73ac8c76425b8344579269a6c17b937e37d538dceb5e1f05d05e312d110293d143e09b310e9bd4420ad8347deca838c7ecafa41af125ee8bd11afba774eb4ea24100a3cae062e9f0b315a2ee98ef136c60b7747d12d7d06b42993e02b94ddb" - ] - }, - { - "sk_s": "a58683abf72963f7e5c88ec11f0c5ec87891ab9b87e33e848a44bec790abe609", - "pk_s": "d482ac71d0d6291dc3c8d63e30a128c9d9ad2100e18b4cd2e982f80a1fe3b642", - "token_challenge": "f91a000b497373756572204e616d6520008a10ddef970bb378e878ada121088d378c87c8d818b2803c3e84d6a1337c8c0005612c622c63", - "nonces": [ - "9d5f6e4a785e9b4f421bb238242eabc94ebb1f43a035dbf57d20be2ab0d0ecc5", - "26aa0a5e9ac6f53374db443827ce20ffb75c8498c67a9f3d683334c92a7a05e3", - "1e0feded4fd6a7c04245978c79a22a894f8be4bf2d175062afbf55e16785fdfb", - "38cb75e7288366fc23091879502399bd760741f6faf7df25ef8b63fd41ce0107", - "81f4d9c80c88511538efd1f150f848ba150f2476a1242fbb8ec09568eb3169f6" - ], - "blinds": [ - "f2062b4bb720b84f601aa7aa01e4ad85774b726f7d26200a19e9bc232820dd0b", - "34288bee3cd984894b6c221da21dc75b634e7ee5a563711135570a13e35c270a", - "4c262ebcd27c8efe132669d4b54e4164b0b70db563c0686f1dffda1ba64a4b0a", - "18e3d60e6a4175e7d674cb5d45d2c0be3c3d11ef3b7dbdd47bdd6b6329e31f03", - "97180be9267f2cf283f2a3e3c391a372862d6c7a0e1075004c4e486657e2d409" - ], - "token_request": "f91a2500a07c8f701ed314ee3e2c124130a6ad0ce33dd134e62b43398a6a9ea7d16b339551b095e22caac1e57bf6b738e49c2cb29fe5a419ec74c5c2702c8338714bb6c90dfe93e0250ad4f61b55ac6c45ae11f6e6fb75ad04caa87cbd276f04d92a0805107857a1517d28860f73f90018a40ac78d6a2b41fc2d0dc9812dbe9a27d9cd8b45a821a028cc2124369447d637c9fd76bbb5c8c73f5e0f8d41f0202f2f08af7f46", - "token_response": "00a0007bee5575370f944d92bba213c3db615b195ad148a91a4936e1e3380973d428e4c22cbe357493229a57a63b309098d8c081ef57152d10fea3d0d47d435ae160da0846612f5470aef35a6a0c7fe06fefcb770299f4bf0c78fec1947b28966d72a6b655c9aa57e4a349a3eedcc43c09cef34bba52aba9ca58f225c16b575d550a12bd0a9e41df179b2a2fabbf332a7dbc09aa36317078c2d9c76cae730e9a44314b0888d26cc59c83d83496d1150ade3744e4b6a9e77a6444211c79060ebf720861cd185698bfa216f74a1cb26e899da6d06efe69d08f2efa31ec2a7a2752d40e", - "tokens": [ - "f91a9d5f6e4a785e9b4f421bb238242eabc94ebb1f43a035dbf57d20be2ab0d0ecc5270b2dc2fe7293ed65638ac340b4ea29c3a13de6f0f19873b7db79a2f1cce57a43c0460ac8922488c644ad3cfa8d7f42d15112935d11ffa744aef0236bd138251512d6f62c0e735c8ce0748e1ab957388d999ec467e656713e6b284ccf8dd45a0eb4d5855cea7a5a312737b44fe9d1b5763cfcfc268ec38538858671ec7233d2", - "f91a26aa0a5e9ac6f53374db443827ce20ffb75c8498c67a9f3d683334c92a7a05e3270b2dc2fe7293ed65638ac340b4ea29c3a13de6f0f19873b7db79a2f1cce57a43c0460ac8922488c644ad3cfa8d7f42d15112935d11ffa744aef0236bd13825fee6508e23385b0c0ea1988b0cbb3e28f1f2d7d22501b5ecff79572bc5e2c009d9c6460c77a14ec69e1bd108b87a7df0310e2bd5bece697294cb38a32573c445", - "f91a1e0feded4fd6a7c04245978c79a22a894f8be4bf2d175062afbf55e16785fdfb270b2dc2fe7293ed65638ac340b4ea29c3a13de6f0f19873b7db79a2f1cce57a43c0460ac8922488c644ad3cfa8d7f42d15112935d11ffa744aef0236bd13825c0918d569b80fc4061bd6dd566854852b2a7e36c04c7d6e1c7424bfe6b3a5a9f321671c59e600ce894a639afc58116df8970c9fca826f233797f0de9bf55ea68", - "f91a38cb75e7288366fc23091879502399bd760741f6faf7df25ef8b63fd41ce0107270b2dc2fe7293ed65638ac340b4ea29c3a13de6f0f19873b7db79a2f1cce57a43c0460ac8922488c644ad3cfa8d7f42d15112935d11ffa744aef0236bd138256af5a9d761af576f8cbc8d6dbfec6f9f796954b8cfab759e1e85b8b46c4531ab9e6ab3729539f5d719931569eccff9c9bcaafecfd221e4fd0c37bd42bf0c8479", - "f91a81f4d9c80c88511538efd1f150f848ba150f2476a1242fbb8ec09568eb3169f6270b2dc2fe7293ed65638ac340b4ea29c3a13de6f0f19873b7db79a2f1cce57a43c0460ac8922488c644ad3cfa8d7f42d15112935d11ffa744aef0236bd13825ad861f72a7ab5d71521cef69d21e32f91de9e13a3d2dbc85ca4a475fff68c504f745fc468fb9c9c39e766f25d379e95201e2ca13019f32def8f818277cc2b776" - ] - }, - { - "sk_s": "570611aabab4f3f7e06cc542f8f80297f3a316923bf5654287a4b51ceb510103", - "pk_s": "9e5b246c7db965161b4da219f87febded80973cf0278576625425f68c5861d64", - "token_challenge": "f91a000b497373756572204e616d65209c7f16d47b0c09a6893d89d6e4c4a87da44576668b64b38beda62a51adea0f470005612c622c63", - "nonces": [ - "43610c936290280ffbe9b4c76c0d893fe6a6f97fd2ee02b2cd48b64f735a0f7f", - "3652b0805611cc7c98222e269f274d5318abdf2de00e14d4bca7864367310858", - "b40b98545d9cce3aadb6b838915366e83568e26b111f4ab5b379ddbb0e96adc8", - "0d409c46538d2a9c916133a9b770511f4d9911b045378a354625eeaccaef6c55", - "a09440d522335927d070102c736ac79575943830f6afaa0034d05d668fc3b27f" - ], - "blinds": [ - "b86a17cb0fab23ed9719dfa2f5078819ea080b4523b3a6fe4ad69d467e436e02", - "70aa8e41dbffe5c288c4e4f516f8a4576538a970d640fb86c220f2c89f294f0f", - "2dbf0a51dc906f8fc9bb2dad0e9b753cd479eee5b99edc09a4173264d4885b07", - "3f18448baeb7a6aa5edeab3a3204bfe4f3f0d2195db18eba939ced3369f01303", - "16adfa916828611e732858028b8fa663474bfbec0a614785896f53a821aa5c0f" - ], - "token_request": "f91a0300a092d8b37f01d34d7a9815e00ac07b35f976adbccb7d4b4892c5bead99dd9309028278bd8b76a3166096bf8ed60f29fc79cad77555d3bd2f5797b480abd29dd150e8e1aba162e1a3a409d876a6d8b6a928cebdb85169b7347887e23b8fa8867619e02f9e7177dbb07e124352bb7edbbb9ae9b9754a321187c231588fe514ee611784be5049d7d227ac4d7b6e69882d0b39087e48a8779679c97c690c5b6b7ac53c", - "token_response": "00a070060c391e2cebc40e173582efc87a82ffeb127cae9e6df65819a7c3c25fe423284ee18abddfe299775cb239d7a09b854f13afcb48216a672fd945cf19127b60622b9879768b1c4fa2902da65f1029b97a0e65ef10a3e710d097cb07e386d62a728a80d8b3d8d019f88bb858eb90af4dea43b3577275121b853bb21f92a9984fbe86796ba1e3da9ee0897c496344bc795cb525841ec572b73fb8fa85b816c0070abc411ce888cc2d2e0e37410f0843531fdc2abe28b850d5190146ad8554100b800cc59942b54f8fa8f96d407bc61ee4b8bb2a85af847bc68d32f090b8d7b40b", - "tokens": [ - "f91a43610c936290280ffbe9b4c76c0d893fe6a6f97fd2ee02b2cd48b64f735a0f7fb231df8b341a0a55f9fa72dd80f9766006daf40004af93b5b070005e9841ac39f850a84ee1f65d1740cc77e5cc12632c35659942673c60894dd5267f8ecdab03a91c4266807ed74a1e440560a9ec9010dd3281cc1244a84cd77ab25edd284b7774c6a41ed5ebb3b107ca2ca7376d68f1cb52295cf5731a11f6aecfe8fecfb2b7", - "f91a3652b0805611cc7c98222e269f274d5318abdf2de00e14d4bca7864367310858b231df8b341a0a55f9fa72dd80f9766006daf40004af93b5b070005e9841ac39f850a84ee1f65d1740cc77e5cc12632c35659942673c60894dd5267f8ecdab0391c2081ea6811c3c0b5ccf2adf3dde94b29141d3c4a017b4ffe05485f2f4b3597e7cf9f14c6647b29798fa66c3689d2e7d624f97cb5154ddfb69642213a05b80", - "f91ab40b98545d9cce3aadb6b838915366e83568e26b111f4ab5b379ddbb0e96adc8b231df8b341a0a55f9fa72dd80f9766006daf40004af93b5b070005e9841ac39f850a84ee1f65d1740cc77e5cc12632c35659942673c60894dd5267f8ecdab03e68ef51ce3aca71dd9d15b7c39076713393686de1bdf5b39f504c3c0ae91963e908e3ab0597c508825f70039e8b68f41dd94daa2a3df6f7ae37de09aa124048b", - "f91a0d409c46538d2a9c916133a9b770511f4d9911b045378a354625eeaccaef6c55b231df8b341a0a55f9fa72dd80f9766006daf40004af93b5b070005e9841ac39f850a84ee1f65d1740cc77e5cc12632c35659942673c60894dd5267f8ecdab037d0d6ade19eab2338dd933be9a8c593c9d6446df79d49f021a15f3c80e58f28f3714d78b5baf6f39a51046a7305285c9c2ed88f1b517dd375eb85c6b85a72bcb", - "f91aa09440d522335927d070102c736ac79575943830f6afaa0034d05d668fc3b27fb231df8b341a0a55f9fa72dd80f9766006daf40004af93b5b070005e9841ac39f850a84ee1f65d1740cc77e5cc12632c35659942673c60894dd5267f8ecdab03e20fe4c6245aefa54cb00b34f4b903d0e67e4918399d8c6fefdbbb3fa18c2588fe301986ce6281572659419431451eea2c5b641acbc97ed4e85b1c1363643d2d" - ] - } -] \ No newline at end of file diff --git a/tests/private_tokens.rs b/tests/private_tokens.rs index 8f3cc50..6a5a178 100644 --- a/tests/private_tokens.rs +++ b/tests/private_tokens.rs @@ -25,7 +25,7 @@ async fn private_tokens_cycle() { // Generate a challenge let challenge = TokenChallenge::new( - TokenType::Private, + TokenType::PrivateToken, "example.com", None, &["example.com".to_string()], diff --git a/tests/public_tokens.rs b/tests/public_tokens.rs index 5700c2a..a2fb340 100644 --- a/tests/public_tokens.rs +++ b/tests/public_tokens.rs @@ -39,7 +39,7 @@ async fn public_tokens_cycle() { // Generate a challenge let token_challenge = TokenChallenge::new( - TokenType::Public, + TokenType::PublicToken, "example.com", None, &["example.com".to_string()],