seekia/internal/messaging/inbox/inbox.go

127 lines
4 KiB
Go
Raw Normal View History

// inbox provides functions to read inboxes, create random inboxes, and to derive inboxes and sealer keys
package inbox
import "seekia/internal/cryptography/blake3"
import "seekia/internal/encoding"
import "seekia/internal/identity"
import "crypto/rand"
import "slices"
import "errors"
func GetNewRandomInbox()([10]byte, error){
var inboxArray [10]byte
_, err := rand.Read(inboxArray[:])
if (err != nil) { return [10]byte{}, err }
return inboxArray, nil
}
func GetNewRandomSecretInboxSeed()([22]byte, error){
var newSecretInboxSeed [22]byte
_, err := rand.Read(newSecretInboxSeed[:])
if (err != nil) { return [22]byte{}, err }
return newSecretInboxSeed, nil
}
func ReadInboxString(inputInbox string)([10]byte, error){
inboxBytes, err := encoding.DecodeBase32StringToBytes(inputInbox)
if (err != nil){
return [10]byte{}, errors.New("ReadInboxString called with invalid inbox: " + inputInbox + ". Not Base32: " + err.Error())
}
if (len(inboxBytes) != 10){
return [10]byte{}, errors.New("ReadInboxString called with invalid inbox: " + inputInbox + ". Invalid length.")
}
inboxArray := [10]byte(inboxBytes)
return inboxArray, nil
}
func GetPublicInboxFromIdentityHash(inputIdentityHash [16]byte)([10]byte, error){
identityType, err := identity.GetIdentityTypeFromIdentityHash(inputIdentityHash)
if (err != nil) {
identityHashHex := encoding.EncodeBytesToHexString(inputIdentityHash[:])
return [10]byte{}, errors.New("GetPublicInboxFromIdentityHash called with invalid identity hash: " + identityHashHex)
}
if (identityType != "Mate" && identityType != "Moderator"){
return [10]byte{}, errors.New("GetPublicInboxFromIdentityHash called with Host identity hash.")
}
// This sequence of bytes is the string "identitypubinbox" decoded from base32 to bytes
hashInputSuffix := []byte{64, 200, 217, 162, 120, 125, 2, 134, 133, 215}
hashInput := slices.Concat(inputIdentityHash[:], hashInputSuffix)
inboxBytes, err := blake3.GetBlake3HashAsBytes(10, hashInput)
if (err != nil) { return [10]byte{}, err }
inboxArray := [10]byte(inboxBytes)
return inboxArray, nil
}
// Messages sent to a user's public inbox use a doublesealedkeys sealer key that is derived from the user's identity hash
func GetPublicInboxSealerKeyFromIdentityHash(inputIdentityHash [16]byte)([32]byte, error){
identityType, err := identity.GetIdentityTypeFromIdentityHash(inputIdentityHash)
if (err != nil) {
inputIdentityHashHex := encoding.EncodeBytesToHexString(inputIdentityHash[:])
return [32]byte{}, errors.New("GetPublicInboxSealerKeyFromIdentityHash called with invalid identity hash: " + inputIdentityHashHex)
}
if (identityType != "Mate" && identityType != "Moderator"){
return [32]byte{}, errors.New("GetPublicInboxSealerKeyFromIdentityHash called with Host identityType identity hash.")
}
// This sequence of bytes is the string "identityhashpublicinboxsealerkey" decoded from base32 to bytes
hashInputSuffix := []byte{64, 200, 217, 162, 120, 56, 36, 119, 208, 43, 64, 144, 208, 186, 242, 32, 22, 72, 168, 152}
hashInput := slices.Concat(inputIdentityHash[:], hashInputSuffix)
doubleSealedKeysSealerKey, err := blake3.GetBlake3HashAsBytes(32, hashInput)
if (err != nil) { return [32]byte{}, err }
doubleSealedKeysSealerKeyArray := [32]byte(doubleSealedKeysSealerKey)
return doubleSealedKeysSealerKeyArray, nil
}
// Outputs:
// -[10]byte: Secret inbox
// -[32]byte: Secret inbox doubleSealedKeys sealer key
// -error
func GetSecretInboxAndSealerKeyFromSecretInboxSeed(inputSecretInboxSeed [22]byte)([10]byte, [32]byte, error){
secretInboxHashInput := append(inputSecretInboxSeed[:], 1)
sealerKeyHashInput := append(inputSecretInboxSeed[:], 2)
secretInbox, err := blake3.GetBlake3HashAsBytes(10, secretInboxHashInput)
if (err != nil) { return [10]byte{}, [32]byte{}, err }
secretInboxArray := [10]byte(secretInbox)
sealerKey, err := blake3.GetBlake3HashAsBytes(32, sealerKeyHashInput)
if (err != nil) { return [10]byte{}, [32]byte{}, err }
sealerKeyArray := [32]byte(sealerKey)
return secretInboxArray, sealerKeyArray, nil
}