use super::types::Attribute;
use crate::{
common::{
Buffer, Deserial, Get, ParseResult, Put, ReadBytesExt, SerdeDeserialize, SerdeSerialize,
Serial,
},
curve_arithmetic::{arkworks_instances::ArkGroup, Curve, Pairing},
};
use anyhow::bail;
use ark_bls12_381::{G1Projective, G2Projective};
use ark_ec::bls12::Bls12;
use serde::{
de::{self, Visitor},
Deserializer, Serializer,
};
use std::{fmt, io::Cursor, str::FromStr};
use thiserror::Error;
pub type ArCurve = ArkGroup<G1Projective>;
pub type BlsG2 = ArkGroup<G2Projective>;
pub type IpPairing = Bls12<ark_bls12_381::Config>;
pub type BaseField = <IpPairing as Pairing>::ScalarField;
pub const INITIAL_CREDENTIAL_INDEX: u8 = 0;
const MAX_ATTRIBUTE_LENGTH: u8 = 31;
#[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
pub struct AttributeKind(String);
impl AttributeKind {
pub fn try_new(value: String) -> Result<Self, AttributeValueTooLong> {
if value.len() > MAX_ATTRIBUTE_LENGTH as usize {
Err(AttributeValueTooLong)
} else {
Ok(Self(value))
}
}
}
#[derive(Debug, Error)]
#[error("attribute value too long")]
pub struct AttributeValueTooLong;
impl SerdeSerialize for AttributeKind {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
ser.serialize_str(&self.0)
}
}
impl<'de> SerdeDeserialize<'de> for AttributeKind {
fn deserialize<D: Deserializer<'de>>(des: D) -> Result<Self, D::Error> {
struct AttributeKindVisitor;
impl<'de> Visitor<'de> for AttributeKindVisitor {
type Value = AttributeKind;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "A string less than 31 bytes when decoded.")
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
AttributeKind::try_new(v.to_string())
.map_err(|_| de::Error::custom("Value too big."))
}
}
des.deserialize_str(AttributeKindVisitor)
}
}
impl Deserial for AttributeKind {
fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
let len: u8 = source.get()?;
if len <= MAX_ATTRIBUTE_LENGTH {
let mut buf = vec![0u8; len as usize];
source.read_exact(&mut buf)?;
Ok(AttributeKind(String::from_utf8(buf)?))
} else {
bail!("Attributes can be at most 31 bytes.")
}
}
}
impl Serial for AttributeKind {
fn serial<B: Buffer>(&self, out: &mut B) {
out.put(&(self.0.as_bytes().len() as u8));
out.write_all(self.0.as_bytes())
.expect("Writing to buffer should succeed.");
}
}
#[derive(Debug, Error)]
pub enum ParseAttributeError {
#[error("Value out of range.")]
ValueTooLarge,
}
impl FromStr for AttributeKind {
type Err = ParseAttributeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::try_new(s.to_string()).map_err(|_| ParseAttributeError::ValueTooLarge)
}
}
impl fmt::Display for AttributeKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl AsRef<str> for AttributeKind {
fn as_ref(&self) -> &str {
&self.0
}
}
impl From<AttributeKind> for String {
fn from(value: AttributeKind) -> Self {
value.0
}
}
impl From<u64> for AttributeKind {
fn from(x: u64) -> Self {
AttributeKind(x.to_string())
}
}
impl Attribute<<ArkGroup<G1Projective> as Curve>::Scalar> for AttributeKind {
fn to_field_element(&self) -> <ArkGroup<G1Projective> as Curve>::Scalar {
let mut buf = [0u8; 32];
let len = self.0.as_bytes().len();
buf[1 + (31 - len)..].copy_from_slice(self.0.as_bytes());
buf[0] = len as u8; <<ArkGroup<G1Projective> as Curve>::Scalar as Deserial>::deserial(&mut Cursor::new(&buf))
.expect("31 bytes + length fits into a scalar.")
}
}
#[cfg(test)]
mod test {
use crate::common;
use crate::id::constants::AttributeKind;
use nom::AsBytes;
use std::str::FromStr;
#[test]
fn test_attribute_kind_try_new() {
let attr = AttributeKind::try_new("".to_string()).expect("try_new");
assert_eq!(attr.as_ref(), "");
let attr = AttributeKind::try_new("abc".to_string()).expect("try_new");
assert_eq!(attr.as_ref(), "abc");
let attr = AttributeKind::try_new("a".repeat(31)).expect("try_new");
assert_eq!(attr.as_ref(), "a".repeat(31));
AttributeKind::try_new("a".repeat(32)).expect_err("try_new");
}
#[test]
fn test_attribute_kind_from_str() {
let attr = AttributeKind::from_str("").expect("from_str");
assert_eq!(attr.as_ref(), "");
let attr = AttributeKind::from_str("abc").expect("from_str");
assert_eq!(attr.as_ref(), "abc");
let attr = AttributeKind::from_str(&"a".repeat(31)).expect("from_str");
assert_eq!(attr.as_ref(), "a".repeat(31));
AttributeKind::from_str(&"a".repeat(32)).expect_err("from_str");
}
#[test]
fn test_attribute_kind_serial_deserial() {
let attr = AttributeKind::try_new("".to_string()).unwrap();
let bytes_hex = hex::encode(common::to_bytes(&attr));
assert_eq!(bytes_hex, "00");
let attr_deserial: AttributeKind =
common::from_bytes(&mut hex::decode(bytes_hex).unwrap().as_bytes()).expect("deserial");
assert_eq!(attr_deserial, attr);
let attr = AttributeKind::try_new("abc".to_string()).unwrap();
let bytes_hex = hex::encode(common::to_bytes(&attr));
assert_eq!(bytes_hex, "03616263");
let attr_deserial: AttributeKind =
common::from_bytes(&mut hex::decode(bytes_hex).unwrap().as_bytes()).expect("deserial");
assert_eq!(attr_deserial, attr);
let attr = AttributeKind::try_new("a".repeat(31)).unwrap();
let bytes_hex = hex::encode(common::to_bytes(&attr));
assert_eq!(
bytes_hex,
"1f61616161616161616161616161616161616161616161616161616161616161"
);
let attr_deserial: AttributeKind =
common::from_bytes(&mut hex::decode(bytes_hex).unwrap().as_bytes()).expect("deserial");
assert_eq!(attr_deserial, attr);
let bytes_hex = "206161616161616161616161616161616161616161616161616161616161616161";
let err =
common::from_bytes::<AttributeKind, _>(&mut hex::decode(bytes_hex).unwrap().as_bytes())
.expect_err("deserial");
assert!(
err.to_string().contains("Attributes can be at most"),
"message: {}",
err
);
}
#[test]
fn test_attribute_kind_serde_serialize_deserialize() {
let attr = AttributeKind::try_new("".to_string()).unwrap();
let json = serde_json::to_string(&attr).expect("serialize");
assert_eq!(json, r#""""#);
let attr_deserialized: AttributeKind = serde_json::from_str(&json).expect("deserialize");
assert_eq!(attr_deserialized, attr);
let attr = AttributeKind::try_new("abc".to_string()).unwrap();
let json = serde_json::to_string(&attr).expect("serialize");
assert_eq!(json, r#""abc""#);
let attr_deserialized: AttributeKind = serde_json::from_str(&json).expect("deserialize");
assert_eq!(attr_deserialized, attr);
let attr = AttributeKind::try_new("a".repeat(31)).unwrap();
let json = serde_json::to_string(&attr).expect("serialize");
assert_eq!(json, r#""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa""#);
let attr_deserialized: AttributeKind = serde_json::from_str(&json).expect("deserialize");
assert_eq!(attr_deserialized, attr);
let json = r#""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa""#;
let err = serde_json::from_str::<AttributeKind>(&json).expect_err("deserial");
assert!(
err.to_string().contains("Value too big"),
"message: {}",
err
);
}
}