284 lines
8.4 KiB
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, ¶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
|
|
}
|
|
|
|
|
|
|