# SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense from std/sequtils import toSeq import hashlib/misc/blake2 import preserves import ./protocols/sturdy from ./actors import Ref export `$` proc hmac(key, data: openarray[byte]): seq[byte] = count[Hmac[BLAKE2S_256]](key, data).data[0..15].toSeq proc mint*[T](key: openarray[byte]; oid: Preserve[T]): SturdyRef[T] = SturdyRef[T](oid: oid, sig: hmac(key, encode oid)) proc mint*[T](key: openarray[byte]; oid: T; E = void): SturdyRef[E] = var oidPr = toPreserve(oid, E) SturdyRef[E](oid: oidPr, sig: hmac(key, encode oidPr)) proc mint*(): SturdyRef[Ref] = var key: array[16, byte] cast[SturdyRef[Ref]](mint(key, "syndicate", Ref)) proc attenuate*[T](r: SturdyRef[T]; caveats: Attenuation): SturdyRef[T] = result = SturdyRef[T]( oid: r.oid, caveatChain: r.caveatChain, sig: hmac(r.sig, encode caveats)) result.caveatChain.add caveats proc validate*[T](key: openarray[byte]; r: SturdyRef[T]): bool = var sig = hmac(key, encode r.oid) for a in r.caveatChain: sig = hmac(sig, encode a) r.sig == sig when isMainModule: from os import commandLineParams var key: array[16, byte] case readBytes(stdin, key, 0, 16) of 16: discard of 0: stderr.writeLine "using null key" else: quit "expected sixteen bytes of key from stdin" var oids: seq[Preserve[void]] for p in commandLineParams(): add(oids, parsePreserves p) if oids.len == 0: oids.add(toPreserve "syndicate") for oid in oids: let sturdy = mint(key, oid) doAssert validate(key, sturdy) stdout.writeLine(sturdy)