Files
voprf-vx/src/tests/voprf_test_vectors.rs
T

359 lines
12 KiB
Rust
Raw Normal View History

2021-09-09 01:56:54 -07:00
// Copyright (c) Facebook, Inc. and its affiliates.
//
2021-09-27 18:53:06 -07:00
// This source code is licensed under both the MIT license found in the
// LICENSE-MIT file in the root directory of this source tree and the Apache
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
// of this source tree.
2021-09-09 01:56:54 -07:00
2021-12-21 20:17:02 +01:00
use alloc::string::{String, ToString};
use alloc::vec;
2021-09-09 01:56:54 -07:00
use alloc::vec::Vec;
2021-12-29 09:14:28 +01:00
use core::ops::Add;
2021-12-23 01:17:03 +01:00
2021-12-23 21:58:00 +01:00
use digest::core_api::BlockSizeUser;
2022-01-21 22:52:09 +01:00
use digest::OutputSizeUser;
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, U256};
2022-01-28 01:38:17 +01:00
use generic_array::ArrayLength;
use json::JsonValue;
2021-09-09 01:56:54 -07:00
2021-12-23 01:17:03 +01:00
use crate::tests::mock_rng::CycleRng;
use crate::tests::parser::*;
2021-12-25 22:54:27 +01:00
use crate::{
2022-01-21 22:52:09 +01:00
BlindedElement, CipherSuite, EvaluationElement, Group, NonVerifiableClient,
NonVerifiableServer, Proof, Result, VerifiableClient, VerifiableServer,
2021-12-23 01:17:03 +01:00
};
#[derive(Debug)]
2021-09-09 01:56:54 -07:00
struct VOPRFTestVectorParameters {
seed: Vec<u8>,
2021-09-09 01:56:54 -07:00
sksm: Vec<u8>,
pksm: Vec<u8>,
input: Vec<Vec<u8>>,
info: Vec<u8>,
blind: Vec<Vec<u8>>,
blinded_element: Vec<Vec<u8>>,
evaluation_element: Vec<Vec<u8>>,
proof: Vec<u8>,
proof_random_scalar: Vec<u8>,
output: Vec<Vec<u8>>,
2021-09-09 01:56:54 -07:00
}
2021-09-15 17:49:31 -07:00
fn populate_test_vectors(values: &JsonValue) -> VOPRFTestVectorParameters {
VOPRFTestVectorParameters {
seed: decode(values, "seed"),
sksm: decode(values, "skSm"),
pksm: decode(values, "pkSm"),
2021-10-06 00:19:20 +02:00
input: decode_vec(values, "Input"),
2021-09-15 17:49:31 -07:00
info: decode(values, "Info"),
2021-10-06 00:19:20 +02:00
blind: decode_vec(values, "Blind"),
blinded_element: decode_vec(values, "BlindedElement"),
evaluation_element: decode_vec(values, "EvaluationElement"),
2021-09-15 17:49:31 -07:00
proof: decode(values, "Proof"),
proof_random_scalar: decode(values, "ProofRandomScalar"),
2021-10-06 00:19:20 +02:00
output: decode_vec(values, "Output"),
2021-09-15 17:49:31 -07:00
}
}
2021-09-15 17:49:31 -07:00
fn decode(values: &JsonValue, key: &str) -> Vec<u8> {
2021-09-09 01:56:54 -07:00
values[key]
.as_str()
.and_then(|s| hex::decode(&s.to_string()).ok())
2021-10-06 00:19:20 +02:00
.unwrap_or_default()
2021-09-09 01:56:54 -07:00
}
2021-09-15 17:49:31 -07:00
fn decode_vec(values: &JsonValue, key: &str) -> Vec<Vec<u8>> {
let s = values[key].as_str().unwrap();
2021-09-15 17:49:31 -07:00
let res = match s.contains(',') {
true => Some(
s.split(',')
.map(|x| hex::decode(&x.to_string()).unwrap())
.collect(),
),
false => Some(vec![hex::decode(&s.to_string()).unwrap()]),
2021-09-15 17:49:31 -07:00
};
res.unwrap()
}
2021-09-15 17:49:31 -07:00
macro_rules! json_to_test_vectors {
( $v:ident, $cs:expr, $mode:expr ) => {
$v[$cs][$mode]
.members()
.map(|x| populate_test_vectors(&x))
.collect::<Vec<VOPRFTestVectorParameters>>()
};
2021-09-09 01:56:54 -07:00
}
#[test]
2021-12-25 22:54:27 +01:00
fn test_vectors() -> Result<()> {
2022-01-21 22:52:09 +01:00
use p256::NistP256;
2021-09-15 17:49:31 -07:00
let rfc = json::parse(rfc_to_json(super::voprf_vectors::VECTORS).as_str())
.expect("Could not parse json");
2021-12-23 07:50:48 +01:00
#[cfg(feature = "ristretto255")]
{
2022-01-18 12:34:28 +01:00
use crate::Ristretto255;
2021-12-21 20:17:02 +01:00
let ristretto_base_tvs = json_to_test_vectors!(
rfc,
String::from("ristretto255, SHA-512"),
String::from("Base")
);
2021-12-21 20:17:02 +01:00
let ristretto_verifiable_tvs = json_to_test_vectors!(
rfc,
String::from("ristretto255, SHA-512"),
String::from("Verifiable")
);
2022-01-21 22:52:09 +01:00
test_base_seed_to_key::<Ristretto255>(&ristretto_base_tvs)?;
test_base_blind::<Ristretto255>(&ristretto_base_tvs)?;
test_base_evaluate::<Ristretto255>(&ristretto_base_tvs)?;
test_base_finalize::<Ristretto255>(&ristretto_base_tvs)?;
2022-01-21 22:52:09 +01:00
test_verifiable_seed_to_key::<Ristretto255>(&ristretto_verifiable_tvs)?;
test_verifiable_blind::<Ristretto255>(&ristretto_verifiable_tvs)?;
test_verifiable_evaluate::<Ristretto255>(&ristretto_verifiable_tvs)?;
test_verifiable_finalize::<Ristretto255>(&ristretto_verifiable_tvs)?;
2021-12-23 07:50:48 +01:00
}
2021-09-09 01:56:54 -07:00
2022-01-21 22:52:09 +01:00
let p256base_tvs =
json_to_test_vectors!(rfc, String::from("P-256, SHA-256"), String::from("Base"));
2022-01-21 22:52:09 +01:00
let p256verifiable_tvs = json_to_test_vectors!(
rfc,
String::from("P-256, SHA-256"),
String::from("Verifiable")
);
2022-01-21 22:52:09 +01:00
test_base_seed_to_key::<NistP256>(&p256base_tvs)?;
test_base_blind::<NistP256>(&p256base_tvs)?;
test_base_evaluate::<NistP256>(&p256base_tvs)?;
test_base_finalize::<NistP256>(&p256base_tvs)?;
2022-01-21 22:52:09 +01:00
test_verifiable_seed_to_key::<NistP256>(&p256verifiable_tvs)?;
test_verifiable_blind::<NistP256>(&p256verifiable_tvs)?;
test_verifiable_evaluate::<NistP256>(&p256verifiable_tvs)?;
test_verifiable_finalize::<NistP256>(&p256verifiable_tvs)?;
2021-09-09 01:56:54 -07:00
Ok(())
}
2022-01-21 22:52:09 +01:00
fn test_base_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
for parameters in tvs {
2022-01-21 22:52:09 +01:00
let server = NonVerifiableServer::<CS>::new_from_seed(&parameters.seed)?;
2021-09-09 01:56:54 -07:00
assert_eq!(
&parameters.sksm,
2022-01-21 22:52:09 +01:00
&CS::Group::serialize_scalar(server.get_private_key()).to_vec()
2021-09-09 01:56:54 -07:00
);
}
Ok(())
}
2022-01-21 22:52:09 +01:00
fn test_verifiable_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
for parameters in tvs {
2022-01-21 22:52:09 +01:00
let server = VerifiableServer::<CS>::new_from_seed(&parameters.seed)?;
2021-09-09 01:56:54 -07:00
assert_eq!(
&parameters.sksm,
2022-01-21 22:52:09 +01:00
&CS::Group::serialize_scalar(server.get_private_key()).to_vec()
2022-01-18 12:34:28 +01:00
);
assert_eq!(
&parameters.pksm,
2022-01-21 22:52:09 +01:00
CS::Group::serialize_elem(server.get_public_key()).as_slice()
2021-09-09 01:56:54 -07:00
);
}
Ok(())
}
// Tests input -> blind, blinded_element
2022-01-21 22:52:09 +01:00
fn test_base_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
for parameters in tvs {
for i in 0..parameters.input.len() {
2022-01-28 01:38:17 +01:00
let blind = CS::Group::deserialize_scalar(&parameters.blind[i])?;
2022-01-21 22:52:09 +01:00
let client_result = NonVerifiableClient::<CS>::deterministic_blind_unchecked(
2021-12-23 21:03:38 +01:00
&parameters.input[i],
blind,
)?;
assert_eq!(
&parameters.blind[i],
2022-01-21 22:52:09 +01:00
&CS::Group::serialize_scalar(client_result.state.blind).to_vec()
2021-09-20 00:17:53 -07:00
);
assert_eq!(
2021-12-23 21:03:38 +01:00
parameters.blinded_element[i].as_slice(),
client_result.message.serialize().as_slice(),
);
}
}
Ok(())
}
// Tests input -> blind, blinded_element
2022-01-21 22:52:09 +01:00
fn test_verifiable_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
for parameters in tvs {
for i in 0..parameters.input.len() {
2022-01-28 01:38:17 +01:00
let blind = CS::Group::deserialize_scalar(&parameters.blind[i])?;
2022-01-21 22:52:09 +01:00
let client_blind_result =
VerifiableClient::<CS>::deterministic_blind_unchecked(&parameters.input[i], blind)?;
assert_eq!(
&parameters.blind[i],
2022-01-21 22:52:09 +01:00
&CS::Group::serialize_scalar(client_blind_result.state.get_blind()).to_vec()
2021-09-20 00:17:53 -07:00
);
assert_eq!(
2021-12-23 21:03:38 +01:00
parameters.blinded_element[i].as_slice(),
client_blind_result.message.serialize().as_slice(),
);
}
2021-09-09 01:56:54 -07:00
}
Ok(())
}
// Tests sksm, blinded_element -> evaluation_element
2022-01-21 22:52:09 +01:00
fn test_base_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
for parameters in tvs {
for i in 0..parameters.input.len() {
2022-01-21 22:52:09 +01:00
let server = NonVerifiableServer::<CS>::new_with_key(&parameters.sksm)?;
2022-01-28 01:38:17 +01:00
let message = server.evaluate(
2021-12-21 20:17:02 +01:00
&BlindedElement::deserialize(&parameters.blinded_element[i])?,
Some(&parameters.info),
)?;
assert_eq!(
&parameters.evaluation_element[i],
2022-01-28 01:38:17 +01:00
&message.serialize().as_slice()
);
}
}
Ok(())
}
2022-01-21 22:52:09 +01:00
fn test_verifiable_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
2021-12-23 21:03:38 +01:00
where
2022-01-21 22:52:09 +01:00
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ScalarLen>: ArrayLength<u8>,
2021-12-23 21:03:38 +01:00
{
2021-12-29 09:14:28 +01:00
use crate::{
VerifiableServerBatchEvaluateFinishResult, VerifiableServerBatchEvaluatePrepareResult,
};
for parameters in tvs {
let mut rng = CycleRng::new(parameters.proof_random_scalar.clone());
2022-01-21 22:52:09 +01:00
let server = VerifiableServer::<CS>::new_with_key(&parameters.sksm)?;
2021-09-15 17:49:31 -07:00
let mut blinded_elements = vec![];
for blinded_element_bytes in &parameters.blinded_element {
2021-10-06 00:19:20 +02:00
blinded_elements.push(BlindedElement::deserialize(blinded_element_bytes)?);
2021-09-15 17:49:31 -07:00
}
2021-12-29 09:14:28 +01:00
let VerifiableServerBatchEvaluatePrepareResult {
prepared_evaluation_elements,
t,
} = server.batch_evaluate_prepare(blinded_elements.iter(), Some(&parameters.info))?;
let prepared_elements: Vec<_> = prepared_evaluation_elements.collect();
let VerifiableServerBatchEvaluateFinishResult { messages, proof } =
VerifiableServer::batch_evaluate_finish(
&mut rng,
blinded_elements.iter(),
&prepared_elements,
&t,
)?;
let messages: Vec<_> = messages.collect();
2021-09-09 01:56:54 -07:00
2021-12-29 09:14:28 +01:00
for (parameter, message) in parameters.evaluation_element.iter().zip(messages) {
assert_eq!(&parameter, &message.serialize().as_slice(),);
}
2021-12-29 09:14:28 +01:00
assert_eq!(&parameters.proof, &proof.serialize().as_slice());
2021-09-09 01:56:54 -07:00
}
Ok(())
}
// Tests input, blind, evaluation_element -> output
2022-01-21 22:52:09 +01:00
fn test_base_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
for parameters in tvs {
for i in 0..parameters.input.len() {
2022-01-21 22:52:09 +01:00
let client = NonVerifiableClient::<CS>::from_blind(CS::Group::deserialize_scalar(
2022-01-28 01:38:17 +01:00
&parameters.blind[i],
2021-12-23 21:03:38 +01:00
)?);
2021-09-20 00:17:53 -07:00
let client_finalize_result = client.finalize(
2021-12-23 21:03:38 +01:00
&parameters.input[i],
2021-12-21 20:17:02 +01:00
&EvaluationElement::deserialize(&parameters.evaluation_element[i])?,
Some(&parameters.info),
)?;
2021-10-06 00:53:18 +02:00
assert_eq!(&parameters.output[i], &client_finalize_result.to_vec());
}
}
Ok(())
}
2021-09-09 01:56:54 -07:00
2022-01-21 22:52:09 +01:00
fn test_verifiable_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
for parameters in tvs {
let mut clients = vec![];
for i in 0..parameters.input.len() {
2022-01-21 22:52:09 +01:00
let client = VerifiableClient::<CS>::from_blind_and_element(
2022-01-28 01:38:17 +01:00
CS::Group::deserialize_scalar(&parameters.blind[i])?,
CS::Group::deserialize_elem(&parameters.blinded_element[i])?,
);
clients.push(client.clone());
}
let messages: Vec<_> = parameters
.evaluation_element
.iter()
.map(|x| EvaluationElement::deserialize(x).unwrap())
.collect();
2021-09-20 00:17:53 -07:00
let batch_result = VerifiableClient::batch_finalize(
2021-12-23 21:03:38 +01:00
&parameters.input,
&clients,
&messages,
2021-12-21 20:17:02 +01:00
&Proof::deserialize(&parameters.proof)?,
2022-01-28 01:38:17 +01:00
CS::Group::deserialize_elem(&parameters.pksm)?,
Some(&parameters.info),
)?;
2021-09-09 01:56:54 -07:00
assert_eq!(
parameters.output,
2021-09-20 00:17:53 -07:00
batch_result
2021-12-23 21:03:38 +01:00
.map(|arr| arr.map(|message| message.to_vec()))
2021-12-25 22:54:27 +01:00
.collect::<Result<Vec<_>>>()?
);
2021-09-09 01:56:54 -07:00
}
Ok(())
}