#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
extern crate core;
use alloc::vec::Vec;
use core::{fmt::Debug, ops::Range};
use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, FullCodec, MaxEncodedLen};
use scale_info::*;
pub mod demo_impls;
pub mod ring_vrf_impl;
pub type Alias = [u8; 32];
pub type Entropy = [u8; 32];
pub trait GenerateVerifiable {
type Members: Clone + Eq + PartialEq + FullCodec + Debug + TypeInfo + MaxEncodedLen;
type Intermediate: Clone + Eq + PartialEq + FullCodec + Debug + TypeInfo + MaxEncodedLen;
type Member: Clone + Eq + PartialEq + FullCodec + Debug + TypeInfo + MaxEncodedLen;
type Secret: Clone;
type Commitment: FullCodec;
type Proof: Clone + Eq + PartialEq + FullCodec + Debug + TypeInfo;
type Signature: Clone + Eq + PartialEq + FullCodec + Debug + TypeInfo;
type StaticChunk: Clone + Eq + PartialEq + FullCodec + Debug + TypeInfo + MaxEncodedLen;
fn start_members() -> Self::Intermediate;
fn push_members(
intermediate: &mut Self::Intermediate,
members: impl Iterator<Item = Self::Member>,
lookup: impl Fn(Range<usize>) -> Result<Vec<Self::StaticChunk>, ()>,
) -> Result<(), ()>;
fn finish_members(inter: Self::Intermediate) -> Self::Members;
fn new_secret(entropy: Entropy) -> Self::Secret;
fn member_from_secret(secret: &Self::Secret) -> Self::Member;
fn open(
member: &Self::Member,
members_iter: impl Iterator<Item = Self::Member>,
) -> Result<Self::Commitment, ()>;
fn create(
commitment: Self::Commitment,
secret: &Self::Secret,
context: &[u8],
message: &[u8],
) -> Result<(Self::Proof, Alias), ()>;
fn sign(_secret: &Self::Secret, _message: &[u8]) -> Result<Self::Signature, ()> {
Err(())
}
fn is_valid(
proof: &Self::Proof,
members: &Self::Members,
context: &[u8],
alias: &Alias,
message: &[u8],
) -> bool {
match Self::validate(proof, members, context, message) {
Ok(a) => &a == alias,
Err(()) => false,
}
}
fn alias_in_context(secret: &Self::Secret, context: &[u8]) -> Result<Alias, ()>;
fn validate(
_proof: &Self::Proof,
_members: &Self::Members,
_context: &[u8],
_message: &[u8],
) -> Result<Alias, ()> {
Err(())
}
fn verify_signature(
_signature: &Self::Signature,
_message: &[u8],
_member: &Self::Member,
) -> bool {
false
}
fn is_member_valid(_member: &Self::Member) -> bool;
}
#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, DecodeWithMemTracking)]
pub struct Receipt<Gen: GenerateVerifiable> {
proof: Gen::Proof,
alias: Alias,
message: Vec<u8>,
}
impl<Gen: GenerateVerifiable> Receipt<Gen> {
pub fn create<'a>(
secret: &Gen::Secret,
members: impl Iterator<Item = Gen::Member>,
context: &[u8],
message: Vec<u8>,
) -> Result<Self, ()>
where
Gen::Member: 'a,
{
let commitment = Gen::open(&Gen::member_from_secret(secret), members)?;
let (proof, alias) = Gen::create(commitment, secret, context, &message)?;
Ok(Self {
proof,
alias,
message,
})
}
pub fn alias(&self) -> &Alias {
&self.alias
}
pub fn message(&self) -> &[u8] {
&self.message
}
pub fn into_parts(self) -> (Alias, Vec<u8>) {
(self.alias, self.message)
}
pub fn verify(self, members: &Gen::Members, context: &[u8]) -> Result<(Alias, Vec<u8>), Self> {
match Gen::validate(&self.proof, members, context, &self.message) {
Ok(alias) => Ok((alias, self.message)),
Err(()) => {
if self.is_valid(members, context) {
Ok(self.into_parts())
} else {
Err(self)
}
}
}
}
pub fn is_valid(&self, members: &Gen::Members, context: &[u8]) -> bool {
Gen::is_valid(&self.proof, members, context, &self.alias, &self.message)
}
}