From 291ec1805b09efb2d62caafa6685198f0c03d86d Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Thu, 21 Mar 2024 21:27:23 +0100 Subject: [PATCH] Synchronous cryptography; convenient `mint` overload for producing a ref and a bind at once --- packages/core/src/transport/cryptography.ts | 2 +- packages/core/src/transport/sturdy.ts | 53 ++++++++++++++++----- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/packages/core/src/transport/cryptography.ts b/packages/core/src/transport/cryptography.ts index 7e2a01b..2faeecc 100644 --- a/packages/core/src/transport/cryptography.ts +++ b/packages/core/src/transport/cryptography.ts @@ -18,6 +18,6 @@ export const newKey: () => Promise = const HMAC_BLAKE2s = makeHMAC(BLAKE2s); -export async function mac(secretKey: Bytes, data: Bytes): Promise { +export function mac(secretKey: Bytes, data: Bytes): Bytes { return Bytes.from(HMAC_BLAKE2s(underlying(secretKey), underlying(data))); } diff --git a/packages/core/src/transport/sturdy.ts b/packages/core/src/transport/sturdy.ts index 778a649..9a8ee1e 100644 --- a/packages/core/src/transport/sturdy.ts +++ b/packages/core/src/transport/sturdy.ts @@ -10,8 +10,9 @@ // California: Internet Society, 2014. import { mac } from './cryptography.js'; -import { Bytes, decode, encode, is, neverEmbeddedType, Value } from '@preserves/core'; +import { Bytes, decode, encode, is, neverEmbeddedType, Value, fromJS } from '@preserves/core'; import * as S from '../gen/sturdy.js'; +import * as G from '../gen/gatekeeper.js'; export * from '../gen/sturdy.js'; export type SturdyValue = Value; @@ -37,16 +38,42 @@ export function sturdyDecode(bs: Bytes): SturdyValue { }); } -export async function mint(oid: SturdyValue, secretKey: Bytes): Promise { - return S.SturdyRef(S.Parameters({ - oid, - sig: await mac(secretKey, sturdyEncode(oid)), - caveats: S.CaveatsField.absent(), - })); +export function sturdyBind( + oid: SturdyValue, + secretKey: Bytes, + target: S._embedded, + observer?: S._embedded, +): G.Bind { + return G.Bind({ + description: G.Description({ + stepType: fromJS(S.SturdyStepType()) as symbol, + detail: fromJS(S.SturdyDescriptionDetail({ oid, key: secretKey })), + }), + target, + observer: (observer === void 0) ? G.BindObserver.absent() : G.BindObserver.present(observer), + }); } -async function chainMac(key: Bytes | Promise, caveats: S.Caveat[]): Promise { - return caveats.reduce(async (key, c) => mac(await key, sturdyEncode(S.fromCaveat(c))), key); +type RefAndBind = { ref: S.SturdyRef, bind: G.Bind }; +export function mint(oid: SturdyValue, secretKey: Bytes): S.SturdyRef; +export function mint(oid: SturdyValue, secretKey: Bytes, target: S._embedded, observer?: S._embedded): RefAndBind; +export function mint( + oid: SturdyValue, + secretKey: Bytes, + target?: S._embedded, + observer?: S._embedded, +): S.SturdyRef | RefAndBind { + const ref = S.SturdyRef(S.Parameters({ + oid, + sig: mac(secretKey, sturdyEncode(oid)), + caveats: S.CaveatsField.absent(), + })); + if (target === void 0) return ref; + return { ref, bind: sturdyBind(oid, secretKey, target, observer) }; +} + +function chainMac(key: Bytes, caveats: S.Caveat[]): Bytes { + return caveats.reduce((key, c) => mac(key, sturdyEncode(S.fromCaveat(c))), key); } export function caveatChain(r: S.SturdyRef): S.Caveat[] { @@ -57,16 +84,16 @@ export function caveatChain(r: S.SturdyRef): S.Caveat[] { } } -export async function attenuate(r: S.SturdyRef, ... a: S.Caveat[]): Promise { +export function attenuate(r: S.SturdyRef, ... a: S.Caveat[]): S.SturdyRef { if (a.length === 0) return r; return S.SturdyRef(S.Parameters({ oid: r.parameters.oid, caveats: S.CaveatsField.present([... caveatChain(r), ... a]), - sig: await chainMac(r.parameters.sig, a), + sig: chainMac(r.parameters.sig, a), })); } -export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise { - const sig = await chainMac(await mac(secretKey, sturdyEncode(r.parameters.oid)), caveatChain(r)); +export function validate(r: S.SturdyRef, secretKey: Bytes): boolean { + const sig = chainMac(mac(secretKey, sturdyEncode(r.parameters.oid)), caveatChain(r)); return is(sig, r.parameters.sig); }