diff --git a/src/keri/app/controller.ts b/src/keri/app/controller.ts index 57697fd6..49639c6a 100644 --- a/src/keri/app/controller.ts +++ b/src/keri/app/controller.ts @@ -89,17 +89,67 @@ export class Agent { * signing key represents the Account for the client on the agent */ export class Controller { + /* + The bran is the combination of the first 21 characters of the passcode passed in prefixed with 'A' and '0A'. + Looks like: '0A' + 'A' + 'thisismysecretkeyseed' + Or: "0AAthisismysecretkeyseed" + + This is interpreted as encoded Base64URLSafe characters when used as the salt for key generation. + */ private bran: string; + /** + * The stem is the prefix for the stretched input bytes the controller's cryptographic + * key pairs are derived from. + */ public stem: string; + /** + * The security tier for the identifiers created by this Controller. + */ public tier: Tier; + /** + * The rotation index used during key generation by this Controller. + */ public ridx: number; + /** + * The salter is a cryptographic salt used to derive the controller's cryptographic key pairs + * and is deterministically derived from the bran and the security tier. + */ public salter: any; + /** + * The current signing key used to sign requests for this controller. + */ public signer: any; + /** + * The next signing key of which a digest is committed to in an establishment event (inception or rotation) to become the + * signing key after the next rotation. + * @private + */ private nsigner: any; + /** + * Either the current establishment event, inception or rotation, or the interaction event used for delegation approval. + */ public serder: Serder; + /** + * Current public keys formatted in fully-qualified Base64. + * @private + */ private keys: string[]; + /** + * Digests of the next public keys formatted in fully-qualified Base64. + */ public ndigs: string[]; + /** + * Creates a Signify Controller starting at key index 0 that generates keys in + * memory based on the provided seed, or bran, the tier, and the rotation index. + * + * The rotation index is used as follows: + * + * @param bran + * @param tier + * @param ridx + * @param state + */ constructor( bran: string, tier: Tier, @@ -110,6 +160,13 @@ export class Controller { this.stem = 'signify:controller'; this.tier = tier; this.ridx = ridx; + const codes = undefined; // Defines the types of seeds that the SaltyCreator will create. Defaults to undefined. + const keyCount = 1; // The number of keys to create. Defaults to 1. + const transferable = true; // Whether the keys are transferable. Defaults to true. + const code = MtrDex.Ed25519_Seed; // The type cryptographic seed to create by default when not overiddeen by "codes". + const pidx = 0; // The index of this identifier prefix of all managed identifiers created for this SignifyClient Controller. Defaults to 0. + const kidx = 0; // The overall starting key index for the first key this rotation set of keys. This is not a local index to this set of keys but an index in the overall set of keys for all keys in this sequence. + // Defaults to 0. Multiply rotation index (ridx) times key count to get the overall key index. this.salter = new Salter({ qb64: this.bran, tier: this.tier }); @@ -119,30 +176,34 @@ export class Controller { this.stem ); + // Creates the first key pair used to sign the inception event. + // noinspection UnnecessaryLocalVariableJS + const initialKeyIndex = ridx; // will be zero for inception this.signer = creator .create( - undefined, - 1, - MtrDex.Ed25519_Seed, - true, - 0, - this.ridx, - 0, - false + codes, + keyCount, + code, + transferable, + pidx, + initialKeyIndex, + kidx ) - .signers.pop(); + .signers.pop(); // assumes only one key pair is created because keyCount is 1 + + // Creates the second key pair which a digest of the public key is committed to in the inception event. + const nextKeyIndex = ridx + 1; this.nsigner = creator .create( - undefined, - 1, - MtrDex.Ed25519_Seed, - true, - 0, - this.ridx + 1, - 0, - false + codes, + keyCount, + code, + transferable, + pidx, + nextKeyIndex, + kidx ) - .signers.pop(); + .signers.pop(); // assumes only one key pair is created because keyCount is 1 this.keys = [this.signer.verfer.qb64]; this.ndigs = [ new Diger({ code: MtrDex.Blake3_256 }, this.nsigner.verfer.qb64b) diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index 89f423bd..9d8fdf4a 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -332,7 +332,7 @@ export class Credentials { } /** - * Issue a credential + * Creates a credential in the specified registry to be GRANTed with IPEX to the intended recipient */ async issue( name: string, diff --git a/src/keri/core/httping.ts b/src/keri/core/httping.ts index 46e3ac14..9106dbf6 100644 --- a/src/keri/core/httping.ts +++ b/src/keri/core/httping.ts @@ -33,9 +33,16 @@ export interface SiginputArgs { context?: string; } +/** + * Generates, serializes, and signs a Signature-Input HTTP header value as a structured header + * @param signer + * @param sigInputArgs + */ export function siginput( signer: Signer, - { + sigInputArgs: SiginputArgs +): [Map, Siger | Cigar] { + const { name, method, path, @@ -46,8 +53,7 @@ export function siginput( alg, keyid, context, - }: SiginputArgs -): [Map, Siger | Cigar] { + } = sigInputArgs; const items = new Array(); const ifields = new Array<[string, Map]>(); diff --git a/src/keri/core/manager.ts b/src/keri/core/manager.ts index 6b40b7ee..88b7a6e4 100644 --- a/src/keri/core/manager.ts +++ b/src/keri/core/manager.ts @@ -205,14 +205,23 @@ export class RandyCreator implements Creator { return new Keys(signers); } + /** + * Unused for random key generation. + */ get salt(): string { return ''; } + /** + * Unused for random key generation. + */ get stem(): string { return ''; } + /** + * Unused for random key generation. + */ get tier(): Tier { return '' as Tier; } diff --git a/src/keri/core/salter.ts b/src/keri/core/salter.ts index e96af4aa..b6652558 100644 --- a/src/keri/core/salter.ts +++ b/src/keri/core/salter.ts @@ -127,8 +127,19 @@ export class Salter extends Matter { } /** - * Returns Signer with .raw secret derived from code size, path, .raw salt, and tier. - * The signer's public key for its .verfer is derived from code and transferable. + * Returns Signer with the private key secret derived from code the path, the user entered passcode as a salt, + * and the security tier sized by the CESR cryptographic seed size indicated by the code. See the example below. + * The Signer's public key for its .verfer is derived from its private key, the Matter code, and the transferable boolean. + * + * The construction of the raw hash bytes used looks like this: + * ( size, password, salt ) + * where + * ( code size, path, Base64Decode(passcode) ) + * for example, for the initial inception signing key the following parameters are used: + * ( 32, "signify:controller00", Base64Decode("Athisismysecretkeyseed") ) + * and for the initial rotation key pair the following parameters are used: + * ( 32, "signify:controller01", Base64Decode("Athisismysecretkeyseed") ) + * * @param code derivation code indicating seed type * @param transferable whether or not the key is for a transferable or non-transferable identifier. * @param path string of bytes prepended (prefixed) to the salt before stretching @@ -145,7 +156,7 @@ export class Salter extends Matter { const seed = this.stretch(Matter._rawSize(code), path, tier, temp); return new Signer({ - raw: seed, + raw: seed, // private key code: code, transferable: transferable, });