// 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, ¶metersSlice) 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 }