Split out sturdy-demo.ts

This commit is contained in:
Tony Garnock-Jones 2021-03-04 21:11:58 +01:00
parent e7ebf8e821
commit 1c7e68f461
3 changed files with 41 additions and 39 deletions

View File

@ -1,5 +1,5 @@
export default {
input: 'lib/sturdy.js',
input: 'lib/sturdy-demo.js',
output: {
file: 'index.js',
format: 'umd',

30
src/sturdy-demo.ts Normal file
View File

@ -0,0 +1,30 @@
import { newKey } from './cryptography.js';
import { attenuate, KEY_LENGTH, mint, Rewrite, sturdyEncode, validate } from './sturdy.js';
import * as RW from './rewrite.js';
import { Bytes, Dictionary } from 'preserves';
async function main() {
const m1 = await mint('hello world', new Bytes(KEY_LENGTH));
console.log(m1.asPreservesText());
const m2 = await attenuate(m1, Rewrite(RW.PBind('a',
RW.PCompound(RW.CRec(Symbol.for('says'), 2),
new Dictionary<RW.Pattern, never>([
[0, RW.Lit('Tony')]]))),
RW.TRef('a')));
console.log(m2.asPreservesText());
console.log('should be true:', await validate(m1, new Bytes(KEY_LENGTH)));
console.log('should be true:', await validate(m2, new Bytes(KEY_LENGTH)));
console.log('should be false:', await validate(m2, Bytes.of(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)));
m2[0] = 'hello world2';
console.log(m2.asPreservesText());
console.log('should be false:', await validate(m2, new Bytes(KEY_LENGTH)));
m2[0] = 'hello world';
console.log(m2.asPreservesText());
console.log('should be true:', await validate(m2, new Bytes(KEY_LENGTH)));
console.log('should be false:', await validate(m2, await newKey()));
console.log((await newKey()).asPreservesText());
console.log((await newKey()).asPreservesText());
console.log(sturdyEncode(m2).asPreservesText());
}
main();

View File

@ -6,10 +6,9 @@
// In Network and Distributed System Security Symposium. San Diego,
// California: Internet Society, 2014.
import { mac, newKey } from './cryptography.js';
import { Bytes, Dictionary, encode, is, Record, Value } from 'preserves';
import { mac } from './cryptography.js';
import { Bytes, encode, is, Record, Value } from 'preserves';
import type { Pattern, Template } from './rewrite.js';
import * as RW from './rewrite.js';
export type EmbeddedRef = { ref: SturdyRef };
export type SturdyValue = Value<EmbeddedRef>;
@ -17,12 +16,11 @@ export type SturdyValue = Value<EmbeddedRef>;
export const _SturdyRef = Symbol.for('sturdyref');
export const SturdyRef = Record.makeConstructor<{
oid: SturdyValue, // (arbitrary) name of the ultimate target of the ref
attenuations: Attenuation[], // caveats/rewrites, evaluated RIGHT-TO-LEFT
sig: Bytes, // *keyed* signature of canonicalEncode of rightmost item in [oid, ... attenuations]
}, EmbeddedRef>()(_SturdyRef, ['oid', 'attenuations', 'sig']);
export type SturdyRef = [SturdyValue, Attenuation[], Bytes] & { label: typeof _SturdyRef };
export type Attenuation = Array<Caveat>; // chain, evaluated left-to-right
caveatChain: Array<Caveat>[],
// ^ caveats/rewrites. Evaluated RIGHT-TO-LEFT; each Array<Caveat> is evaluated LEFT-TO-RIGHT
sig: Bytes, // *keyed* signature of canonicalEncode of rightmost item in [oid, ... caveatChain]
}, EmbeddedRef>()(_SturdyRef, ['oid', 'caveatChain', 'sig']);
export type SturdyRef = [SturdyValue, Array<Caveat>[], Bytes] & { label: typeof _SturdyRef };
export type Caveat = Or<Rewrite>;
// ^ embodies 1st-party caveats over assertion structure, but nothing else
@ -54,43 +52,17 @@ export async function mint(oid: SturdyValue, secretKey: Bytes): Promise<SturdyRe
return SturdyRef(oid, [], await mac(secretKey, sturdyEncode(oid)));
}
export async function attenuate(r: SturdyRef, ... a: Attenuation): Promise<SturdyRef> {
export async function attenuate(r: SturdyRef, ... a: Array<Caveat>): Promise<SturdyRef> {
return SturdyRef(
SturdyRef._.oid(r),
[... SturdyRef._.attenuations(r), a],
[... SturdyRef._.caveatChain(r), a],
await mac(SturdyRef._.sig(r), sturdyEncode(a))
);
}
export async function validate(r: SturdyRef, secretKey: Bytes): Promise<boolean> {
const sig = await SturdyRef._.attenuations(r).reduce(
const sig = await SturdyRef._.caveatChain(r).reduce(
async (sig, a) => mac(await sig, sturdyEncode(a)),
mac(secretKey, sturdyEncode(SturdyRef._.oid(r))));
return is(sig, SturdyRef._.sig(r));
}
async function main() {
const m1 = await mint('hello world', new Bytes(KEY_LENGTH));
console.log(m1.asPreservesText());
const m2 = await attenuate(m1, Rewrite(RW.PBind('a',
RW.PCompound(RW.CRec(Symbol.for('says'), 2),
new Dictionary<Pattern, never>([
[0, RW.Lit('Tony')]]))),
RW.TRef('a')));
console.log(m2.asPreservesText());
console.log('should be true:', await validate(m1, new Bytes(KEY_LENGTH)));
console.log('should be true:', await validate(m2, new Bytes(KEY_LENGTH)));
console.log('should be false:', await validate(m2, Bytes.of(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)));
m2[0] = 'hello world2';
console.log(m2.asPreservesText());
console.log('should be false:', await validate(m2, new Bytes(KEY_LENGTH)));
m2[0] = 'hello world';
console.log(m2.asPreservesText());
console.log('should be true:', await validate(m2, new Bytes(KEY_LENGTH)));
console.log('should be false:', await validate(m2, await newKey()));
console.log((await newKey()).asPreservesText());
console.log((await newKey()).asPreservesText());
console.log(sturdyEncode(m2).asPreservesText());
}
main();