Created
March 27, 2019 12:56
-
-
Save Geal/4418fdc7c938ecdfc9f27116f8869ad0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@0xa9970031d0caaf6d; | |
struct Biscuit { | |
authority @0 :Block; | |
blocks @1 :List(Block); | |
# each element must be 32 bytes | |
keys @2 :List(Data); | |
signature @3 :Signature; | |
} | |
struct Block { | |
index @0 :UInt32; | |
symbols @1 :List(Text); | |
facts @2 :List(Fact); | |
caveats @3 :List(Rule); | |
} | |
struct Fact { | |
predicate @0 :Predicate; | |
} | |
struct Rule { | |
head @0 :Predicate; | |
body @1 :List(Predicate); | |
constraints @2 :List(Constraint); | |
} | |
struct Predicate { | |
# symbol value | |
name @0 :UInt32; | |
ids @1 :List(ID); | |
} | |
struct Constraint { | |
id @0 :UInt32; | |
kind :union { | |
int @1 :IntConstraint; | |
str @2 :StringConstraint; | |
date @3 :DateConstraint; | |
symbol @4 :SymbolConstraint; | |
} | |
} | |
struct ID { | |
union { | |
symbol @0 :UInt32; | |
variable @1 :UInt32; | |
integer @2 :Int32; | |
str @3 :Text; | |
date @4 :UInt64; | |
} | |
} | |
struct IntConstraint { | |
union { | |
lower @0 :UInt64; | |
larger @1 :UInt64; | |
lowerOrEqual @2 :UInt64; | |
largeOrEqual @3 :UInt64; | |
equal @4 :UInt64; | |
# must be a set (no duplicates) | |
in @5 :List(UInt64); | |
# must be a set (no duplicates) | |
notIn @6 :List(UInt64); | |
} | |
} | |
struct StringConstraint { | |
union { | |
prefix @0 :Text; | |
suffix @1 :Text; | |
equal @2 :Text; | |
# must be a set (no duplicates) | |
in @3 :List(Text); | |
# must be a set (no duplicates) | |
notIn @4 :List(Text); | |
} | |
} | |
struct DateConstraint { | |
union { | |
before @0 :UInt64; | |
after @1 :UInt64; | |
} | |
} | |
struct SymbolConstraint { | |
union { | |
# must be a set (no duplicates) | |
in @0 :List(UInt64); | |
# must be a set (no duplicates) | |
notIn @1 :List(UInt64); | |
} | |
} | |
struct Signature { | |
# each element must be 32 bytes | |
gamma @0 :List(Data); | |
# each element must be 32 bytes | |
c @1 :List(Data); | |
#must be 32 bytes | |
w @2 :Data; | |
#must be 32 bytes | |
s @3 :Data; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use capnp::{message, serialize, serialize_packed, traits::{IntoInternalStructReader, IntoInternalListReader}, | |
raw::get_struct_data_section}; | |
use nom::HexDisplay; | |
mod generated; | |
use generated::{biscuit, block, constraint, fact, i_d, predicate, rule}; | |
#[test] | |
fn serialize() { | |
let mut message = ::capnp::message::Builder::new_default(); | |
let block_count = 2; | |
{ | |
let mut biscuit = message.init_root::<biscuit::Builder>(); | |
{ | |
let mut authority = biscuit.reborrow().init_authority(); | |
authority.set_index(0); | |
let mut symbols = authority.reborrow().init_symbols(4); | |
symbols.reborrow().set(0, "file1"); | |
symbols.reborrow().set(1, "file2"); | |
symbols.reborrow().set(2, "read"); | |
symbols.reborrow().set(3, "write"); | |
let mut facts = authority.reborrow().init_facts(3); | |
for fact_id in 0..3 { | |
let mut pred0 = facts.reborrow().get(fact_id).init_predicate(); | |
pred0.set_name(0); | |
let mut ids = pred0.init_ids(3); | |
ids.reborrow().get(0).set_symbol(0); | |
ids.reborrow().get(1).set_symbol(1); | |
ids.reborrow().get(2).set_symbol(2); | |
} | |
} | |
{ | |
let mut blocks = biscuit.reborrow().init_blocks(block_count); | |
for block_id in 0..block_count { | |
let mut block = blocks.reborrow().get(block_id); | |
block.set_index(1+block_id as u32); | |
let mut symbols = block.reborrow().init_symbols(1); | |
symbols.reborrow().set(0, "caveat1"); | |
let mut caveats = block.reborrow().init_caveats(1); | |
let mut caveat = caveats.reborrow().get(0); | |
{ | |
let mut head = caveat.reborrow().init_head(); | |
let mut ids = head.init_ids(1); | |
ids.reborrow().get(0).set_variable(0); | |
} | |
let mut preds = caveat.reborrow().init_body(3); | |
{ | |
let mut pred = preds.reborrow().get(0); | |
pred.set_name(0); | |
let mut ids = pred.init_ids(2); | |
ids.reborrow().get(0).set_symbol(0); | |
ids.reborrow().get(1).set_variable(1); | |
} | |
{ | |
let mut pred = preds.reborrow().get(1); | |
pred.set_name(1); | |
let mut ids = pred.init_ids(2); | |
ids.reborrow().get(0).set_symbol(0); | |
ids.reborrow().get(1).set_symbol(1); | |
} | |
{ | |
let mut pred = preds.reborrow().get(0); | |
pred.set_name(2); | |
let mut ids = pred.init_ids(3); | |
ids.reborrow().get(0).set_symbol(0); | |
ids.reborrow().get(1).set_variable(1); | |
ids.reborrow().get(2).set_symbol(2); | |
} | |
} | |
} | |
{ | |
let mut keys = biscuit.reborrow().init_keys(block_count + 1); | |
for block_id in 0..block_count + 1 { | |
let key = [0u8; 32]; | |
//keys.reborrow().get(block_id).set(&key[..]); | |
keys.reborrow().set(block_id, &key[..]); | |
} | |
} | |
{ | |
let mut signature = biscuit.reborrow().init_signature(); | |
let mut gamma = signature.reborrow().init_gamma(block_count + 1); | |
for block_id in 0..block_count + 1 { | |
let g = std::iter::repeat(b'a' + block_id as u8).take(32).collect::<Vec<_>>(); | |
gamma.reborrow().set(block_id, &g[..]); | |
} | |
let mut c = signature.reborrow().init_c(block_count + 1); | |
for block_id in 0..block_count + 1 { | |
let scalar = std::iter::repeat(b'A' + block_id as u8).take(32).collect::<Vec<_>>(); | |
c.reborrow().set(block_id, &scalar[..]); | |
} | |
let w = [b'='; 32]; | |
signature.set_w(&w[..]); | |
let s = [b'!'; 32]; | |
signature.set_s(&s[..]); | |
} | |
} | |
let mut v0: Vec<u8> = Vec::new(); | |
//serialize_packed::write_message(&mut ::std::io::stdout(), &message) | |
serialize::write_message(&mut v0, &message).unwrap(); | |
println!( | |
"basic serialized, {} blocks, {} bytes:\n{}", | |
block_count, | |
v0.len(), | |
(&v0[..]).to_hex(16) | |
); | |
let mut v1: Vec<u8> = Vec::new(); | |
//serialize_packed::write_message(&mut ::std::io::stdout(), &message) | |
serialize_packed::write_message(&mut v1, &message).unwrap(); | |
println!( | |
"packed serialized, {} blocks, {} bytes:\n{}", | |
block_count, | |
v1.len(), | |
(&v1[..]).to_hex(16) | |
); | |
let mut b = std::io::BufReader::new(&v1[..]); | |
let reader = serialize_packed::read_message(&mut b, ::capnp::message::ReaderOptions::new()).unwrap(); | |
let token = reader.get_root::<biscuit::Reader>().unwrap(); | |
{ | |
let block = token.reborrow().get_authority().unwrap(); | |
let r = block.reborrow().into_internal_struct_reader(); | |
println!("index: {}", block.get_index()); | |
println!("total_size: {:?}", r.total_size()); | |
println!("data section size: {:?}", r.get_data_section_size()); | |
println!("pointer section size: {:?}", r.get_pointer_section_size()); | |
println!("data:\n{}", (r.get_data_section_as_blob()).to_hex(16)); | |
//let canonicalized = block.canonicalize().unwrap(); | |
//println!("canonicalized:\n{}", canonicalized.to_hex(16)); | |
} | |
{ | |
for block in token.reborrow().get_blocks().unwrap().iter() { | |
let r = block.reborrow().into_internal_struct_reader(); | |
println!("index: {}", block.get_index()); | |
println!("total_size: {:?}", r.total_size()); | |
println!("data section size: {:?}", r.get_data_section_size()); | |
println!("pointer section size: {:?}", r.get_pointer_section_size()); | |
println!("pointer 0: {:?}", r.get_pointer_field(0).total_size()); | |
println!("pointer 1: {:?}", r.get_pointer_field(1).total_size()); | |
println!("pointer 2: {:?}", r.get_pointer_field(2).total_size()); | |
println!("data:\n{}", (r.get_data_section_as_blob()).to_hex(16)); | |
println!("data section:\n{}", get_struct_data_section(block.reborrow()).to_hex(16)); | |
//let canonicalized = block.canonicalize().unwrap(); | |
//println!("canonicalized:\n{}", canonicalized.to_hex(16)); | |
} | |
} | |
{ | |
let r = token.reborrow().get_blocks().unwrap().into_internal_list_reader(); | |
println!("list reader len: {}", r.len()); | |
for i in 0..r.len() { | |
let p = r.get_pointer_element(i); | |
println!("{}: size = {:?}", i, p.total_size().unwrap()); | |
} | |
} | |
panic!(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment