pymensago/keycard.py
def chain(self, key: CryptoString, rotate_optional: bool) -> RetVal:
		'''Creates a new OrgEntry object with new keys and a custody signature. The keys are 
		returned in CryptoString format using the following fields:
		entry
		sign.public / sign.private -- primary signing keypair
		sign.pubhash / sign.privhash -- hashes of the corresponding keys
		altsign.public / altsign.private -- contact request signing keypair
		altsign.pubhash / altsign.privhash -- hashes of the corresponding keys
		encrypt.public / encrypt.private -- general-purpose public encryption keypair
		encrypt.pubhash / encrypt.privhash -- hashes of the corresponding keys

		Full SigningPair / EncryptionPair objects can be found in
		sign
		encrypt

		Because the alternate signing private key is not available, a full Pair field is not
		available, either.

		For organization entries, rotating optional keys works a little differently: the primary 
		signing key becomes the secondary signing key in the new entry. When rotation is False, 
		which is recommended only in instances of revocation, the secondary key is removed. Only 
		when rotate_optional is True is the field altsign.private returned.
		'''
		if key.prefix != 'ED25519':
			return RetVal(ErrBadValue, f'wrong key type {key.prefix}')
		
		status = self.is_compliant()
		if status.error():
			return status
		
		new_entry = OrgEntry()
		new_entry.fields = self.fields.copy()

		try:
			index = int(new_entry.fields['Index'])
			new_entry.fields['Index'] = str(index + 1)
		except Exception:
			return RetVal(ErrBadData, 'invalid entry index')
		
		out = RetVal()

		skey = SigningPair()
		ekey = EncryptionPair()

		out['sign'] = skey
		out['sign.public'] = skey.get_public_key()
		out['sign.pubhash'] = skey.get_public_hash()
		out['sign.private'] = skey.get_private_key()
		out['sign.privhash'] = skey.get_private_hash()
		out['encrypt'] = ekey
		out['encrypt.public'] = ekey.get_public_key()
		out['encrypt.pubhash'] = ekey.get_public_hash()
		out['encrypt.private'] = ekey.get_private_key()
		out['encrypt.privhash'] = ekey.get_private_hash()
		

		new_entry.fields['Primary-Verification-Key'] = skey.get_public_key()
		new_entry.fields['Encryption-Key'] = ekey.get_public_key()

		if rotate_optional:
			altskey = SigningPair()
			out['altsign.public'] = altskey.get_public_key()
			out['altsign.pubhash'] = altskey.get_public_hash()
			out['altsign.private'] = altskey.get_private_key()
			out['altsign.privhash'] = altskey.get_private_hash()
			new_entry.fields['Secondary-Verification-Key'] = altskey.get_public_key()
		else:
			out['altsign.public'] = self.fields['Primary-Verification-Key']
			out['altsign.pubhash'] = blake2hash(self.fields['Primary-Verification-Key'].encode())
			out['altsign.private'] = ''
			new_entry.fields['Secondary-Verification-Key'] = self.fields['Primary-Verification-Key']

		status = new_entry.sign(key, 'Custody')
		if status.error():
			return status

		out['entry'] = new_entry
		return out
Creates a new OrgEntry object with new keys and a custody signature. The keys are 
		returned in CryptoString format using the following fields:
		entry
		sign.public / sign.private -- primary signing keypair
		sign.pubhash / sign.privhash -- hashes of the corresponding keys
		altsign.public / altsign.private -- contact request signing keypair
		altsign.pubhash / altsign.privhash -- hashes of the corresponding keys
		encrypt.public / encrypt.private -- general-purpose public encryption keypair
		encrypt.pubhash / encrypt.privhash -- hashes of the corresponding keys

		Full SigningPair / EncryptionPair objects can be found in
		sign
		encrypt

		Because the alternate signing private key is not available, a full Pair field is not
		available, either.

		For organization entries, rotating optional keys works a little differently: the primary 
		signing key becomes the secondary signing key in the new entry. When rotation is False, 
		which is recommended only in instances of revocation, the secondary key is removed. Only 
		when rotate_optional is True is the field altsign.private returned.
		
Creates a new OrgEntry object with new keys and a custody signature.

Full SigningPair / EncryptionPair objects can be found in
sign
encrypt

Because the alternate signing private key is not available, a full Pair field is not
available, either.

For organization entries, rotating optional keys works a little differently: the primary
signing key becomes the secondary signing key in the new entry. When rotation is False,
which is recommended only in instances of revocation, the secondary key is removed. Only
when rotate_optional is True is the field altsign.private returned.
Creates a new OrgEntry object with new keys and a custody signature . Full SigningPair / EncryptionPair objects can be found in sign encrypt Because the alternate signing private key is not available a full Pair field is not available either . For organization entries rotating optional keys works a little differently : the primary signing key becomes the secondary signing key in the new entry . When rotation is False which is recommended only in instances of revocation the secondary key is removed . Only when rotate_optional is True is the field altsign . private returned .
def chain(self, key: CryptoString, rotate_optional: bool) -> RetVal:
		if key.prefix != 'ED25519':
			return RetVal(ErrBadValue, f'wrong key type {key.prefix}')
		status = self.is_compliant()
		if status.error():
			return status
		new_entry = OrgEntry()
		new_entry.fields = self.fields.copy()
		try:
			index = int(new_entry.fields['Index'])
			new_entry.fields['Index'] = str(index + 1)
		except Exception:
			return RetVal(ErrBadData, 'invalid entry index')
		out = RetVal()
		skey = SigningPair()
		ekey = EncryptionPair()
		out['sign'] = skey
		out['sign.public'] = skey.get_public_key()
		out['sign.pubhash'] = skey.get_public_hash()
		out['sign.private'] = skey.get_private_key()
		out['sign.privhash'] = skey.get_private_hash()
		out['encrypt'] = ekey
		out['encrypt.public'] = ekey.get_public_key()
		out['encrypt.pubhash'] = ekey.get_public_hash()
		out['encrypt.private'] = ekey.get_private_key()
		out['encrypt.privhash'] = ekey.get_private_hash()
		new_entry.fields['Primary-Verification-Key'] = skey.get_public_key()
		new_entry.fields['Encryption-Key'] = ekey.get_public_key()
		if rotate_optional:
			altskey = SigningPair()
			out['altsign.public'] = altskey.get_public_key()
			out['altsign.pubhash'] = altskey.get_public_hash()
			out['altsign.private'] = altskey.get_private_key()
			out['altsign.privhash'] = altskey.get_private_hash()
			new_entry.fields['Secondary-Verification-Key'] = altskey.get_public_key()
		else:
			out['altsign.public'] = self.fields['Primary-Verification-Key']
			out['altsign.pubhash'] = blake2hash(self.fields['Primary-Verification-Key'].encode())
			out['altsign.private'] = ''
			new_entry.fields['Secondary-Verification-Key'] = self.fields['Primary-Verification-Key']
		status = new_entry.sign(key, 'Custody')
		if status.error():
			return status
		out['entry'] = new_entry
		return out
def chain ( self , key : CryptoString , rotate_optional : bool ) -> RetVal : if key . prefix != 'ED25519' : return RetVal ( ErrBadValue , f'wrong key type {key.prefix}' ) status = self . is_compliant ( ) if status . error ( ) : return status new_entry = OrgEntry ( ) new_entry . fields = self . fields . copy ( ) try : index = int ( new_entry . fields [ 'Index' ] ) new_entry . fields [ 'Index' ] = str ( index + 1 ) except Exception : return RetVal ( ErrBadData , 'invalid entry index' ) out = RetVal ( ) skey = SigningPair ( ) ekey = EncryptionPair ( ) out [ 'sign' ] = skey out [ 'sign.public' ] = skey . get_public_key ( ) out [ 'sign.pubhash' ] = skey . get_public_hash ( ) out [ 'sign.private' ] = skey . get_private_key ( ) out [ 'sign.privhash' ] = skey . get_private_hash ( ) out [ 'encrypt' ] = ekey out [ 'encrypt.public' ] = ekey . get_public_key ( ) out [ 'encrypt.pubhash' ] = ekey . get_public_hash ( ) out [ 'encrypt.private' ] = ekey . get_private_key ( ) out [ 'encrypt.privhash' ] = ekey . get_private_hash ( ) new_entry . fields [ 'Primary-Verification-Key' ] = skey . get_public_key ( ) new_entry . fields [ 'Encryption-Key' ] = ekey . get_public_key ( ) if rotate_optional : altskey = SigningPair ( ) out [ 'altsign.public' ] = altskey . get_public_key ( ) out [ 'altsign.pubhash' ] = altskey . get_public_hash ( ) out [ 'altsign.private' ] = altskey . get_private_key ( ) out [ 'altsign.privhash' ] = altskey . get_private_hash ( ) new_entry . fields [ 'Secondary-Verification-Key' ] = altskey . get_public_key ( ) else : out [ 'altsign.public' ] = self . fields [ 'Primary-Verification-Key' ] out [ 'altsign.pubhash' ] = blake2hash ( self . fields [ 'Primary-Verification-Key' ] . encode ( ) ) out [ 'altsign.private' ] = '' new_entry . fields [ 'Secondary-Verification-Key' ] = self . fields [ 'Primary-Verification-Key' ] status = new_entry . sign ( key , 'Custody' ) if status . error ( ) : return status out [ 'entry' ] = new_entry return out
Creates a new OrgEntry object with new keys and a custody signature.
Creates a new OrgEntry object with new keys and a custody signature .
'''Creates a new OrgEntry object with new keys and a custody signature. The keys are 
		returned in CryptoString format using the following fields:
		entry
		sign.public / sign.private -- primary signing keypair
		sign.pubhash / sign.privhash -- hashes of the corresponding keys
		altsign.public / altsign.private -- contact request signing keypair
		altsign.pubhash / altsign.privhash -- hashes of the corresponding keys
		encrypt.public / encrypt.private -- general-purpose public encryption keypair
		encrypt.pubhash / encrypt.privhash -- hashes of the corresponding keys

		Full SigningPair / EncryptionPair objects can be found in
		sign
		encrypt

		Because the alternate signing private key is not available, a full Pair field is not
		available, either.

		For organization entries, rotating optional keys works a little differently: the primary 
		signing key becomes the secondary signing key in the new entry. When rotation is False, 
		which is recommended only in instances of revocation, the secondary key is removed. Only 
		when rotate_optional is True is the field altsign.private returned.
		'''
self
key
CryptoString
rotate_optional
bool