Update attenuations

This commit is contained in:
Tony Garnock-Jones 2023-02-06 15:16:57 +01:00
parent 93fcebc4ce
commit 5030130aef
4 changed files with 35 additions and 25 deletions

View File

@ -3,7 +3,7 @@
import { IdentitySet, Value, embeddedId, is, fromJS, stringify } from '@preserves/core';
import { Cell, Field, Graph } from './dataflow.js';
import { Attenuation, runRewrites } from './rewrite.js';
import { Caveat, runRewrites } from './rewrite.js';
import { queueTask } from './task.js';
export type AnyValue = Value<Ref>;
@ -34,15 +34,15 @@ export type Cap = Ref;
export interface Ref {
readonly relay: Facet;
readonly target: Partial<Entity>;
readonly attenuation?: Attenuation;
readonly attenuation?: Caveat[];
}
export class RefImpl implements Ref {
readonly relay: Facet;
readonly target: Partial<Entity>;
readonly attenuation?: Attenuation;
readonly attenuation?: Caveat[];
constructor(relay: Facet, target: Partial<Entity>, attenuation?: Attenuation) {
constructor(relay: Facet, target: Partial<Entity>, attenuation?: Caveat[]) {
this.relay = relay;
this.target = target;
this.attenuation = attenuation;

View File

@ -8,7 +8,6 @@ import type { SturdyValue } from "../transport/sturdy.js";
import {
Alts,
Attenuation,
Caveat,
Lit,
PAnd,
@ -155,21 +154,30 @@ export function rewrite(r: Rewrite, v: Assertion): Assertion | null {
}
export function examineAlternatives(cav: Caveat, v: Assertion): Assertion | null {
if (cav._variant === 'Alts') {
for (const r of cav.value.alternatives) {
const w = rewrite(r, v);
if (w !== null) return w;
switch (cav._variant) {
case "Alts": {
for (const r of cav.value.alternatives) {
const w = rewrite(r, v);
if (w !== null) return w;
}
return null;
}
return null;
} else {
return rewrite(cav.value, v);
case "Rewrite":
return rewrite(cav.value, v);
case "Reject":
return (match(cav.value.pattern, v) !== null) ? null : v;
case "unknown":
return null;
default:
((_: never) => { throw new Error("bad caveat"); })(cav);
}
}
export function runRewrites(a: Attenuation | undefined, v: Assertion): Assertion | null {
export function runRewrites(a: Caveat[] | undefined, v: Assertion): Assertion | null {
if (a !== void 0) {
for (const stage of a) {
const w = examineAlternatives(stage, v);
for (let i = a.length - 1; i >= 0; i--) {
const caveat = a[i];
const w = examineAlternatives(caveat, v);
if (w === null) return null;
v = w;
}
@ -185,9 +193,9 @@ export function rfilter(... patterns: Pattern[]): Caveat {
return ps.length === 1 ? Caveat.Rewrite(ps[0]) : Caveat.Alts(Alts(ps));
}
export function attenuate(ref: Ref, ... a: Attenuation): Ref {
export function attenuate(ref: Ref, ... a: Caveat[]): Ref {
if (a.length === 0) return ref;
return { ... ref, attenuation: [... a, ... (ref.attenuation ?? [])] };
return { ... ref, attenuation: [... (ref.attenuation ?? []), ... a] };
}
export function forwarder(ref: Ref): { proxy: Ref, revoker: Ref } {

View File

@ -7,7 +7,7 @@ import * as IO from '../gen/protocol.js';
import { wireRefEmbeddedType } from './protocol.js';
import { queueTask } from '../runtime/task.js';
import { attenuate } from '../runtime/rewrite.js';
import { fromAttenuation, WireRef } from '../gen/sturdy.js';
import { fromCaveat, WireRef } from '../gen/sturdy.js';
export class WireSymbol {
count = 0;
@ -264,7 +264,7 @@ export class Relay {
if (ar.__attenuations === void 0) {
ar.__attenuations = new Dictionary();
}
return ar.__attenuations.getOrSet(fromAttenuation(n.attenuation), () =>
return ar.__attenuations.getOrSet(n.attenuation.map(fromCaveat), () =>
attenuate(r, ... n.attenuation));
}
}

View File

@ -45,17 +45,19 @@ export async function mint(oid: SturdyValue, secretKey: Bytes): Promise<S.Sturdy
});
}
export async function attenuate(r: S.SturdyRef, ... a: S.Attenuation): Promise<S.SturdyRef> {
async function chainMac(key: Bytes | Promise<Bytes>, caveats: S.Caveat[]): Promise<Bytes> {
return caveats.reduce(async (key, c) => mac(await key, sturdyEncode(S.fromCaveat(c))), key);
}
export async function attenuate(r: S.SturdyRef, ... a: S.Caveat[]): Promise<S.SturdyRef> {
return S.SturdyRef({
oid: r.oid,
caveatChain: [... r.caveatChain, a],
sig: await mac(r.sig, sturdyEncode(S.fromAttenuation(a)))
caveatChain: [... r.caveatChain, ... a],
sig: await chainMac(r.sig, a),
});
}
export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> {
const sig = await r.caveatChain.reduce(
async (sig, a) => mac(await sig, sturdyEncode(S.fromAttenuation(a))),
mac(secretKey, sturdyEncode(r.oid)));
const sig = await chainMac(await mac(secretKey, sturdyEncode(r.oid)), r.caveatChain);
return is(sig, r.sig);
}