/// <summary> /// Creates a token /// </summary> /// <param name="rng">random number generator</param> /// <param name="root">root private key</param> /// <param name="symbols">symbol table</param> /// <param name="authority">authority authority block</param> /// <returns></returns> static public Either <Error, Biscuit> Make(RNGCryptoServiceProvider rng, KeyPair root, SymbolTable symbols, Block authority) { if (!Collections.Disjoint(symbols.Symbols, authority.Symbols.Symbols)) { return(new Left(new SymbolTableOverlap())); } if (authority.Index != 0) { return(new Left(new InvalidAuthorityIndex(authority.Index))); } symbols.Symbols.AddRange(authority.Symbols.Symbols); List <Block> blocks = new List <Block>(); Either <FormatError, SerializedBiscuit> container = SerializedBiscuit.Make(rng, root, authority); if (container.IsLeft) { return(container.Left); } else { SerializedBiscuit s = container.Right; List <RevocationIdentifier> revocation_ids = s.RevocationIdentifiers(); Option <SerializedBiscuit> c = Option.Some(s); return(new Right(new Biscuit(authority, blocks, symbols, c, revocation_ids))); } }
/// <summary> /// Generates a new token from an existing one and a new block /// </summary> /// <param name="rng">random number generator</param> /// <param name="keypair">ephemeral key pair</param> /// <param name="block">new block(should be generated from a Block builder)</param> /// <returns></returns> public Either <Error, Biscuit> Attenuate(RNGCryptoServiceProvider rng, KeyPair keypair, Block block) { Either <Error, Biscuit> e = this.Copy(); if (e.IsLeft) { return(e.Left); } Biscuit copiedBiscuit = e.Right; if (!Collections.Disjoint(copiedBiscuit.Symbols.Symbols, block.Symbols.Symbols)) { return(new SymbolTableOverlap()); } if (block.Index != 1 + this.Blocks.Count) { return(new InvalidBlockIndex(1 + copiedBiscuit.Blocks.Count, block.Index)); } Either <FormatError, SerializedBiscuit> containerRes = copiedBiscuit.container.Get().Append(rng, keypair, block); if (containerRes.IsLeft) { FormatError error = containerRes.Left; return(new Left(error)); } SerializedBiscuit container = containerRes.Right; SymbolTable symbols = new SymbolTable(copiedBiscuit.Symbols); foreach (string s in block.Symbols.Symbols) { symbols.Add(s); } List <Block> blocks = new List <Block>(); foreach (Block b in copiedBiscuit.Blocks) { blocks.Add(b); } blocks.Add(block); List <RevocationIdentifier> revocation_ids = container.RevocationIdentifiers(); return(new Biscuit(copiedBiscuit.Authority, blocks, symbols, Option.Some(container), revocation_ids)); }