seekia/internal/parameters/readParameters/readParameters.go

284 lines
8.4 KiB
Go

// readParameters provides functions to read and verify parameters
package readParameters
import "seekia/internal/cryptography/blake3"
import "seekia/internal/cryptography/edwardsKeys"
import "seekia/internal/helpers"
import "seekia/internal/encoding"
import messagepack "github.com/vmihailenco/msgpack/v5"
import "strings"
import "slices"
func VerifyParametersType(parametersType string)bool{
allParametersTypesList := GetAllParametersTypesList()
isValid := slices.Contains(allParametersTypesList, parametersType)
if (isValid == true){
return true
}
return false
}
func VerifyParametersHash(inputHash [31]byte)bool{
metadataByte := inputHash[30]
if (metadataByte != 1){
return false
}
return true
}
func GetAllParametersTypesList()[]string{
//TODO: Add more
typesList := []string{"AdminPermissions", "GeneralParameters"}
return typesList
}
func VerifyParameters(inputParameters []byte)(bool, error){
ableToRead, _, _, _, _, _, _, err := ReadParameters(true, inputParameters)
if (err != nil) { return false, err }
if (ableToRead == false){
return false, nil
}
return true, nil
}
//Outputs:
// -bool: Parameters are valid
// -[31]byte: Parameters Hash
// -int: Parameters version
// -byte: Parameters network type byte (1 == Mainnet, 2 == Testnet1)
// -[][32]byte: List of admins who signed the parameters
// -string: Parameters type
// -int64: Parameters creation time
// -map[string]string: Parameters Map
// -error (will return error if there is a bug in the function)
func ReadParametersAndHash(verifyParameters bool, inputParameters []byte)(bool, [31]byte, int, byte, [][32]byte, string, int64, map[string]string, error){
ableToRead, parametersVersion, parametersNetworkType, parametersAuthorsList, parametersType, parametersCreationTime, parametersMap, err := ReadParameters(verifyParameters, inputParameters)
if (err != nil) { return false, [31]byte{}, 0, 0, nil, "", 0, nil, err }
if (ableToRead == false){
return false, [31]byte{}, 0, 0, nil, "", 0, nil, nil
}
parametersHashWithoutMetadataByte, err := blake3.GetBlake3HashAsBytes(30, inputParameters)
if (err != nil) { return false, [31]byte{}, 0, 0, nil, "", 0, nil, err }
//TODO: Use this byte for something useful
metadataByte := byte(1)
parametersHashSlice := append(parametersHashWithoutMetadataByte, metadataByte)
parametersHash := [31]byte(parametersHashSlice)
return true, parametersHash, parametersVersion, parametersNetworkType, parametersAuthorsList, parametersType, parametersCreationTime, parametersMap, nil
}
// This function reads the parameters without computing the hash, thus saving computational time.
//Outputs:
// -bool: Parameters are valid
// -int: Parameters version
// -byte: Parameters network type byte (1 == Mainnet, 2 == Testnet1)
// -[][32]byte: List of admins who signed the parameters
// -string: Parameters type
// -int64: Parameters creation time
// -map[string]string: Parameters Map
// -error (will return error if there is a bug in the function)
func ReadParameters(verifyParameters bool, inputParameters []byte)(bool, int, byte, [][32]byte, string, int64, map[string]string, error){
var parametersSlice []messagepack.RawMessage
err := encoding.DecodeMessagePackBytes(false, inputParameters, &parametersSlice)
if (err != nil){
// Invalid parameters: Invalid messagepack
return false, 0, 0, nil, "", 0, nil, nil
}
if (len(parametersSlice) != 2){
// Invalid parameters: Invalid messagepack
return false, 0, 0, nil, "", 0, nil, nil
}
parametersSignaturesEncoded := parametersSlice[0]
parametersContentMessagepack := parametersSlice[1]
var adminSignaturesList [][64]byte
err = encoding.DecodeMessagePackBytes(false, parametersSignaturesEncoded, &adminSignaturesList)
if (err != nil){
// Invalid parameters: Invalid parameters signatures
return false, 0, 0, nil, "", 0, nil, nil
}
rawParametersMap := make(map[int]messagepack.RawMessage)
err = encoding.DecodeMessagePackBytes(false, parametersContentMessagepack, &rawParametersMap)
if (err != nil){
// Invalid parameters: Invalid content
return false, 0, 0, nil, "", 0, nil, nil
}
parametersVersionEncoded, exists := rawParametersMap[1]
if (exists == false){
// Invalid parameters: Missing parameters version
return false, 0, 0, nil, "", 0, nil, nil
}
parametersVersion, err := encoding.DecodeRawMessagePackToInt(parametersVersionEncoded)
if (err != nil){
// Invalid parameters: Contains invalid parameters version
return false, 0, 0, nil, "", 0, nil, nil
}
if (parametersVersion != 1){
// Parameters must have been created by a different Seekia version. We cannot read them.
return false, 0, 0, nil, "", 0, nil, nil
}
networkTypeEncoded, exists := rawParametersMap[2]
if (exists == false){
// Invalid parameters: Missing network type
return false, 0, 0, nil, "", 0, nil, nil
}
networkTypeByte, err := encoding.DecodeRawMessagePackToByte(networkTypeEncoded)
if (err != nil){
// Invalid parameters: Contains invalid network type
return false, 0, 0, nil, "", 0, nil, nil
}
isValid := helpers.VerifyNetworkType(networkTypeByte)
if (isValid == false){
// Invalid parameters: Contains invalid network type
return false, 0, 0, nil, "", 0, nil, nil
}
adminPublicKeysListEncoded, exists := rawParametersMap[3]
if (exists == false){
// Invalid parameters: Missing admin public keys list
return false, 0, 0, nil, "", 0, nil, nil
}
var adminPublicKeysList [][32]byte
err = encoding.DecodeMessagePackBytes(false, adminPublicKeysListEncoded, &adminPublicKeysList)
if (err != nil){
// Invalid parameters: Invalid admin public keys list
return false, 0, 0, nil, "", 0, nil, nil
}
if (len(adminPublicKeysList) == 0){
return false, 0, 0, nil, "", 0, nil, nil
}
if (verifyParameters == true){
contentHash, err := blake3.Get32ByteBlake3Hash(parametersContentMessagepack)
if (err != nil) { return false, 0, 0, nil, "", 0, nil, err }
if (len(adminSignaturesList) != len(adminPublicKeysList)){
// Invalid parameters: Admin signatures do not match admin public keys.
return false, 0, 0, nil, "", 0, nil, nil
}
for index, adminPublicKey := range adminPublicKeysList{
if (len(adminPublicKey) != 32){
// Invalid parameters: Invalid admin public key
return false, 0, 0, nil, "", 0, nil, nil
}
keySignature := adminSignaturesList[index]
signatureIsValid := edwardsKeys.VerifySignature(adminPublicKey, keySignature, contentHash)
if (signatureIsValid == false){
// Cannot read parameters: Signature is invalid
return false, 0, 0, nil, "", 0, nil, nil
}
}
}
creationTimeEncoded, exists := rawParametersMap[4]
if (exists == false){
// Invalid parameters: Missing CreationTime
return false, 0, 0, nil, "", 0, nil, nil
}
creationTime, err := encoding.DecodeRawMessagePackToInt64(creationTimeEncoded)
if (err != nil){
// Invalid parameters: Contains invalid CreationTime
return false, 0, 0, nil, "", 0, nil, nil
}
parametersTypeEncoded, exists := rawParametersMap[5]
if (exists == false){
// Invalid parameters: Missing ParametersType
return false, 0, 0, nil, "", 0, nil, nil
}
parametersType, err := encoding.DecodeRawMessagePackToString(parametersTypeEncoded)
if (err != nil){
// Invalid parameters: Invalid ParametersType
return false, 0, 0, nil, "", 0, nil, nil
}
if (verifyParameters == true){
isValid := helpers.VerifyCreationTime(creationTime)
if (isValid == false){
// Invalid parameters: Invalid CreationTime
return false, 0, 0, nil, "", 0, nil, nil
}
isValid = VerifyParametersType(parametersType)
if (isValid == false){
// Invalid parameters: Invalid ParametersType
return false, 0, 0, nil, "", 0, nil, nil
}
}
networkTypeString := helpers.ConvertByteToString(networkTypeByte)
creationTimeString := helpers.ConvertInt64ToString(creationTime)
adminPublicKeyStringsList := make([]string, 0, len(adminPublicKeysList))
for _, adminPublicKeyBytes := range adminPublicKeysList{
adminPublicKeyString := encoding.EncodeBytesToHexString(adminPublicKeyBytes[:])
adminPublicKeyStringsList = append(adminPublicKeyStringsList, adminPublicKeyString)
}
adminPublicKeysJoined := strings.Join(adminPublicKeyStringsList, "+")
parametersMap := map[string]string{
"ParametersVersion": "1",
"NetworkType": networkTypeString,
"ParametersType": parametersType,
"CreationTime": creationTimeString,
"AdminPublicKeys": adminPublicKeysJoined,
}
//TODO: Add more
return true, parametersVersion, networkTypeByte, adminPublicKeysList, parametersType, creationTime, parametersMap, nil
}