Add function to turn theta into bytes and from bytes

This commit is contained in:
aniampio
2021-11-12 11:04:19 +00:00
parent c49498a669
commit 802449d8af
3 changed files with 98 additions and 3 deletions
+51
View File
@@ -477,6 +477,57 @@ impl ProofKappa {
challenge == self.challenge
}
pub(crate) fn to_bytes(&self) -> Vec<u8> {
let attributes_len = self.response_attributes.len() as u64;
let mut bytes = Vec::with_capacity(8 + (attributes_len + 2) as usize * 32);
bytes.extend_from_slice(&self.challenge.to_bytes());
bytes.extend_from_slice(&self.response_blinder.to_bytes());
bytes.extend_from_slice(&attributes_len.to_le_bytes());
for rm in &self.response_attributes {
bytes.extend_from_slice(&rm.to_bytes());
}
bytes
}
pub(crate) fn from_bytes(bytes: &[u8]) -> Result<Self> {
// at the very minimum there must be a single attribute being proven
if bytes.len() < 32 * 2 + 8 || (bytes.len() - 8) % 32 != 0 {
return Err(
CoconutError::Deserialization(
"tried to deserialize proof of ciphertexts and commitment with bytes of invalid length".to_string())
);
}
let challenge_bytes = bytes[..32].try_into().unwrap();
let challenge = try_deserialize_scalar(
&challenge_bytes,
CoconutError::Deserialization("Failed to deserialize challenge".to_string()),
)?;
let blinder_bytes = bytes[32..64].try_into().unwrap();
let response_blinder = try_deserialize_scalar(
&blinder_bytes,
CoconutError::Deserialization("failed to deserialize the blinder".to_string()),
)?;
let rm_len = u64::from_le_bytes(bytes[64..64 + 8].try_into().unwrap());
let response_attributes = try_deserialize_scalar_vec(
rm_len,
&bytes[64 + 8..],
CoconutError::Deserialization("Failed to deserialize attributes response".to_string()),
)?;
Ok(ProofKappa {
challenge,
response_attributes,
response_blinder,
})
}
}
#[derive(Debug)]
@@ -58,6 +58,45 @@ impl ThetaCovid {
timestamp,
)
}
// kappa || credential || proof
pub fn to_bytes(&self) -> Vec<u8> {
let blinded_message_bytes = self.blinded_message.to_affine().to_compressed();
let credential_bytes = self.credential.to_bytes();
let proof_bytes = self.pi_v.to_bytes();
let mut bytes = Vec::with_capacity(192 + proof_bytes.len());
bytes.extend_from_slice(&blinded_message_bytes);
bytes.extend_from_slice(&credential_bytes);
bytes.extend_from_slice(&proof_bytes);
bytes
}
pub fn from_bytes(bytes: &[u8]) -> Result<ThetaCovid> {
if bytes.len() < 192 {
return Err(
CoconutError::Deserialization(
format!("Tried to deserialize theta with insufficient number of bytes, expected >= 192, got {}", bytes.len()),
));
}
let blinded_message_bytes = bytes[..96].try_into().unwrap();
let blinded_message = try_deserialize_g2_projective(
&blinded_message_bytes,
CoconutError::Deserialization("failed to deserialize kappa".to_string()),
)?;
let credential = Signature::try_from(&bytes[96..192])?;
let pi_v = ProofKappa::from_bytes(&bytes[192..])?;
Ok(ThetaCovid {
blinded_message,
credential,
pi_v,
})
}
}
#[derive(Debug)]
+8 -3
View File
@@ -1,4 +1,4 @@
use crate::scheme::verification::{prove_covid_credential, verify_covid_credential};
use crate::scheme::verification::{prove_covid_credential, verify_covid_credential, ThetaCovid};
use crate::{
aggregate_signature_shares, aggregate_verification_keys, blind_sign, elgamal_keygen,
hash_to_scalar, prepare_blind_sign, setup, ttp_keygen, CoconutError, Signature, SignatureShare,
@@ -7,7 +7,7 @@ use crate::{
#[test]
fn main() -> Result<(), CoconutError> {
let params = setup(10)?;
let params = setup(15)?;
// validators keys
let coconut_keypairs = ttp_keygen(&params, 2, 3)?;
@@ -133,12 +133,17 @@ fn main() -> Result<(), CoconutError> {
&timestamp,
)?;
let theta_covid_bytes = theta_covid.to_bytes();
println!("Length of theta in bytes: {:?}", theta_covid_bytes.len());
let theta_covid_from_bytes = ThetaCovid::from_bytes(&*theta_covid_bytes).unwrap();
// Verify covid credentials
let disclosed_attributes = vec![is_vaccinated, is_over_18, is_over_21];
assert!(verify_covid_credential(
&params,
&verification_key,
&theta_covid,
&theta_covid_from_bytes,
disclosed_attributes.as_ref(),
&verifier_id,
&timestamp,