UNPKG

signify-ts

Version:

Signing at the edge for KERI, ACDC, and KERIA

274 lines (239 loc) 8.17 kB
import { Codex, Sizage } from './matter'; import { b, b64ToInt, d, intToB64 } from './core'; export interface CounterArgs { code?: string; count?: number; countB64?: string; qb64b?: Uint8Array; qb64?: string; qb2?: Uint8Array; strip?: boolean; } export class CounterCodex extends Codex { public ControllerIdxSigs: string = '-A'; // Qualified Base64 Indexed Signature. public WitnessIdxSigs: string = '-B'; // Qualified Base64 Indexed Signature. public NonTransReceiptCouples: string = '-C'; // Composed Base64 Couple, pre+cig. public TransReceiptQuadruples: string = '-D'; // Composed Base64 Quadruple, pre+snu+dig+sig. public FirstSeenReplayCouples: string = '-E'; // Composed Base64 Couple, fnu+dts. public TransIdxSigGroups: string = '-F'; // Composed Base64 Group, pre+snu+dig+ControllerIdxSigs group. public SealSourceCouples: string = '-G'; // Composed Base64 couple, snu+dig of given delegators or issuers event public TransLastIdxSigGroups: string = '-H'; // Composed Base64 Group, pre+ControllerIdxSigs group. public SealSourceTriples: string = '-I'; // Composed Base64 triple, pre+snu+dig of anchoring source event public SadPathSig: string = '-J'; // Composed Base64 Group path+TransIdxSigGroup of SAID of content public SadPathSigGroup: string = '-K'; // Composed Base64 Group, root(path)+SaidPathCouples public PathedMaterialQuadlets: string = '-L'; // Composed Grouped Pathed Material Quadlet (4 char each) public AttachedMaterialQuadlets: string = '-V'; // Composed Grouped Attached Material Quadlet (4 char each) public BigAttachedMaterialQuadlets: string = '-0V'; // Composed Grouped Attached Material Quadlet (4 char each) public KERIProtocolStack: string = '--AAA'; // KERI ACDC Protocol Stack CESR Version } export const CtrDex = new CounterCodex(); export class Counter { static Sizes = new Map( Object.entries({ '-A': new Sizage(2, 2, 4, 0), '-B': new Sizage(2, 2, 4, 0), '-C': new Sizage(2, 2, 4, 0), '-D': new Sizage(2, 2, 4, 0), '-E': new Sizage(2, 2, 4, 0), '-F': new Sizage(2, 2, 4, 0), '-G': new Sizage(2, 2, 4, 0), '-H': new Sizage(2, 2, 4, 0), '-I': new Sizage(2, 2, 4, 0), '-J': new Sizage(2, 2, 4, 0), '-K': new Sizage(2, 2, 4, 0), '-L': new Sizage(2, 2, 4, 0), '-V': new Sizage(2, 2, 4, 0), '-0V': new Sizage(3, 5, 8, 0), '--AAA': new Sizage(5, 3, 8, 0), }) ); static Hards = new Map<string, number>([ ['-A', 2], ['-B', 2], ['-C', 2], ['-D', 2], ['-E', 2], ['-F', 2], ['-G', 2], ['-H', 2], ['-I', 2], ['-J', 2], ['-K', 2], ['-L', 2], ['-M', 2], ['-N', 2], ['-O', 2], ['-P', 2], ['-Q', 2], ['-R', 2], ['-S', 2], ['-T', 2], ['-U', 2], ['-V', 2], ['-W', 2], ['-X', 2], ['-Y', 2], ['-Z', 2], ['-a', 2], ['-b', 2], ['-c', 2], ['-d', 2], ['-e', 2], ['-f', 2], ['-g', 2], ['-h', 2], ['-i', 2], ['-j', 2], ['-k', 2], ['-l', 2], ['-m', 2], ['-n', 2], ['-o', 2], ['-p', 2], ['-q', 2], ['-r', 2], ['-s', 2], ['-t', 2], ['-u', 2], ['-v', 2], ['-w', 2], ['-x', 2], ['-y', 2], ['-z', 2], ['-0', 3], ['--', 5], ]); private _code: string = ''; private _count: number = -1; constructor({ code, count, countB64, qb64b, qb64, qb2 }: CounterArgs) { if (code != undefined) { if (!Counter.Sizes.has(code)) { throw new Error(`"Unsupported code=${code}.`); } const sizage = Counter.Sizes.get(code)!; const cs = sizage.hs + sizage.ss; if (sizage.fs != cs || cs % 4 != 0) { throw new Error( `Whole code size not full size or not multiple of 4. cs=${cs} fs=${sizage.fs}.` ); } if (count == undefined) { count = countB64 == undefined ? 1 : b64ToInt(countB64); } if (count < 0 || count > 64 ** sizage.ss - 1) { throw new Error(`Invalid count=${count} for code=${code}.`); } this._code = code; this._count = count; } else if (qb64b != undefined) { const qb64 = d(qb64b); this._exfil(qb64); } else if (qb64 != undefined) { this._exfil(qb64); } else if (qb2 != undefined) { } else { throw new Error( `Improper initialization need either (code and count) or qb64b or qb64 or qb2.` ); } } get code(): string { return this._code; } get count() { return this._count; } get qb64() { return this._infil(); } get qb64b() { return b(this.qb64); } countToB64(l?: number): string { if (l == undefined) { const sizage = Counter.Sizes.get(this.code)!; l = sizage.ss; } return intToB64(this.count, l); } static semVerToB64( version: string = '', major: number = 0, minor: number = 0, patch: number = 0 ): string { let parts = [major, minor, patch]; if (version != '') { const ssplits = version.split('.'); const splits = ssplits.map((x) => { if (x == '') return 0; return parseInt(x); }); const off = splits.length; const x = 3 - off; for (let i = 0; i < x; i++) { splits.push(parts[i + off]); } parts = splits; } parts.forEach((p) => { if (p < 0 || p > 63) { throw new Error( `Out of bounds semantic version. Part=${p} is < 0 or > 63.` ); } }); return parts .map((p) => { return intToB64(p, 1); }) .join(''); } private _infil(): string { const code = this.code; const count = this.count; const sizage = Counter.Sizes.get(code)!; const cs = sizage.hs + sizage.ss; if (sizage.fs != cs || cs % 4 != 0) { throw new Error( `Whole code size not full size or not multiple of 4. cs=${cs} fs=${sizage.fs}.` ); } if (count < 0 || count > 64 ** sizage.ss - 1) { throw new Error(`Invalid count=${count} for code=${code}.`); } const both = `${code}${intToB64(count, sizage.ss)}`; if (both.length % 4) { throw new Error( `Invalid size = ${both.length} of ${both} not a multiple of 4.` ); } return both; } private _exfil(qb64: string) { if (qb64.length == 0) { throw new Error('Empty Material'); } const first = qb64.slice(0, 2); if (!Counter.Hards.has(first)) { throw new Error(`Unexpected code ${first}`); } const hs = Counter.Hards.get(first)!; if (qb64.length < hs) { throw new Error(`Need ${hs - qb64.length} more characters.`); } const hard = qb64.slice(0, hs); if (!Counter.Sizes.has(hard)) { throw new Error(`Unsupported code ${hard}`); } const sizage = Counter.Sizes.get(hard)!; const cs = sizage!.hs + sizage!.ss; if (qb64.length < cs) { throw new Error(`Need ${cs - qb64.length} more chars.`); } const scount = qb64.slice(sizage.hs, sizage.hs + sizage.ss); const count = b64ToInt(scount); this._code = hard; this._count = count; } }