diff --git a/signing/mcl/multisig/testData/data.go b/signing/mcl/multisig/testData/data.go new file mode 100644 index 0000000..e8ab225 --- /dev/null +++ b/signing/mcl/multisig/testData/data.go @@ -0,0 +1,54 @@ +package testData + +import ( + crypto "github.com/multiversx/mx-chain-crypto-go" +) + +// PredefinedTest defines the data used for testing +type PredefinedTest struct { + TestName string + Message string + ExpectedError string +} + +// predefinedAggregateSignaturesTests defines the scenarios for testing the AggregateSignatures +var predefinedAggregateSignaturesTests = []PredefinedTest{ + { + TestName: "TestShouldWork", + Message: "a predefined message to sign", + ExpectedError: "noError", + }, +} + +// KeyPair defines a pair of public key and private key +type KeyPair struct { + PublicKey string `json:"publicKey"` + PrivateKey string `json:"privateKey"` +} + +// SignaturePair defines a pair of signature and public key +type SignaturePair struct { + Signature string `json:"signature"` + PublicKey string `json:"publicKey"` +} + +// TestVectorElement defines the data for a test vector +type TestVectorElement struct { + Signatures []SignaturePair `json:"signatures"` + Message string `json:"message"` + AggregatedSignature string `json:"aggregatedSignature"` + ErrorMessage string `json:"errorMessage"` + TestName string `json:"testName"` +} + +// JSONFileContent defines the data for generating the json file +type JSONFileContent struct { + Keys []KeyPair `json:"keys"` + TestVectors []TestVectorElement `json:"testVectors"` +} + +// Key defines a tuple of public key and private key +type Key struct { + PubKey crypto.PublicKey + PrivateKey crypto.PrivateKey +} diff --git a/signing/mcl/multisig/testData/jsonGenerator.go b/signing/mcl/multisig/testData/jsonGenerator.go new file mode 100644 index 0000000..bf704f9 --- /dev/null +++ b/signing/mcl/multisig/testData/jsonGenerator.go @@ -0,0 +1,110 @@ +package testData + +import ( + "encoding/hex" + "encoding/json" + "os" + + crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-crypto-go/signing" + "github.com/multiversx/mx-chain-crypto-go/signing/mcl" +) + +const numKeys = 5 + +func createKeyPairs(grSize uint16, suite crypto.Suite) []Key { + kg := signing.NewKeyGenerator(suite) + keys := make([]Key, 0, grSize) + + for i := uint16(0); i < grSize; i++ { + sk, pk := kg.GeneratePair() + keys = append(keys, Key{ + PubKey: pk, + PrivateKey: sk, + }) + } + return keys +} + +// GenerateJSONFileKOSKForAggregateSignaturesTests for KOSK AggregateSignaturesTests +func GenerateJSONFileKOSKForAggregateSignaturesTests(signer crypto.LowLevelSignerBLS) error { + return generateJSONFile(signer, predefinedAggregateSignaturesTests, "testData/multisigKOSKAggSig.json") +} + +// GenerateJSONFileKOSKForVerifyAggregatedSigTests for KOSK VerifyAggregatedSigTests +func GenerateJSONFileKOSKForVerifyAggregatedSigTests(signer crypto.LowLevelSignerBLS) error { + return generateJSONFile(signer, predefinedAggregateSignaturesTests, "testData/multisigKOSKVerifyAggSig.json") +} + +// GenerateJSONFileNonKOSKForAggregateSignaturesTests for NonKOSK AggregateSignaturesTests +func GenerateJSONFileNonKOSKForAggregateSignaturesTests(signer crypto.LowLevelSignerBLS) error { + return generateJSONFile(signer, predefinedAggregateSignaturesTests, "testData/multisigNonKOSKAggSig.json") +} + +// GenerateJSONFileNonKOSKForVerifyAggregatedSigTests for NonKOSK VerifyAggregatedSigTests +func GenerateJSONFileNonKOSKForVerifyAggregatedSigTests(signer crypto.LowLevelSignerBLS) error { + return generateJSONFile(signer, predefinedAggregateSignaturesTests, "testData/multisigNonKOSKVerifyAggSig.json") +} + +// generateJSONFile generates the JSON file for KOSK/NonKOSK, should be used only once +func generateJSONFile(lls crypto.LowLevelSignerBLS, predefinedTests []PredefinedTest, filename string) error { + suite := mcl.NewSuiteBLS12() + + mapKeys := createKeyPairs(numKeys, suite) + + var jsonFileContent JSONFileContent + + var sigShares [][]byte + var pubKeys []crypto.PublicKey + + for _, key := range mapKeys { + pk, _ := key.PubKey.ToByteArray() + sk, _ := key.PubKey.ToByteArray() + + jsonFileContent.Keys = append(jsonFileContent.Keys, KeyPair{ + PublicKey: hex.EncodeToString(pk), + PrivateKey: hex.EncodeToString(sk), + }) + + pubKeys = append(pubKeys, key.PubKey) + } + + sigPairs := make([]SignaturePair, 0, numKeys*len(predefinedTests)) + for _, predefinedTest := range predefinedTests { + for _, key := range mapKeys { + pk, _ := key.PubKey.ToByteArray() + + sig, err := lls.SignShare(key.PrivateKey, []byte(predefinedTest.Message)) + if err != nil { + return err + } + + sigShares = append(sigShares, sig) + sigPairs = append(sigPairs, SignaturePair{ + Signature: hex.EncodeToString(sig), + PublicKey: hex.EncodeToString(pk), + }) + } + + aggregatedSig, _ := lls.AggregateSignatures(suite, sigShares, pubKeys) + sigShares = sigShares[:0] + + jsonFileContent.TestVectors = append(jsonFileContent.TestVectors, TestVectorElement{ + Signatures: sigPairs, + Message: hex.EncodeToString([]byte(predefinedTest.Message)), + AggregatedSignature: hex.EncodeToString(aggregatedSig), + ErrorMessage: predefinedTest.ExpectedError, + TestName: predefinedTest.TestName, + }) + sigPairs = sigPairs[:0] + } + + marshalledJsonFileContent, err := json.MarshalIndent(jsonFileContent, "", " ") + if err != nil { + return err + } + + err = os.WriteFile(filename, marshalledJsonFileContent, os.ModeAppend) + return err + +} diff --git a/signing/mcl/multisig/testData/multisigKOSKAggSig.json b/signing/mcl/multisig/testData/multisigKOSKAggSig.json new file mode 100644 index 0000000..f3c1d9d --- /dev/null +++ b/signing/mcl/multisig/testData/multisigKOSKAggSig.json @@ -0,0 +1,54 @@ +{ + "keys": [ + { + "publicKey": "d31b53ffdaea86f72ad8faf744a9a2a7e5293cd3b395bb605650d6a7a926fb3111ed1ae59982aff4fb758464802102049d7c8b55afa1fdc464284e0ad75e1e33251e4ac9db3bf6b80c79f5e992b6f1d7e08d592ffa53c792c347e002a0b81993", + "privateKey": "d31b53ffdaea86f72ad8faf744a9a2a7e5293cd3b395bb605650d6a7a926fb3111ed1ae59982aff4fb758464802102049d7c8b55afa1fdc464284e0ad75e1e33251e4ac9db3bf6b80c79f5e992b6f1d7e08d592ffa53c792c347e002a0b81993" + }, + { + "publicKey": "31d2a4541e73da3e82f9f827afe1ebf8417768eb970cc8079f6d819da7b96f3f9f2d8bf6dddf43c1e53a72011a067f07b52756f89338e07f23b8ec66243569dc840246bc8e3218c3269a77311bfade6c825f2459aad850a35976df49c586ff19", + "privateKey": "31d2a4541e73da3e82f9f827afe1ebf8417768eb970cc8079f6d819da7b96f3f9f2d8bf6dddf43c1e53a72011a067f07b52756f89338e07f23b8ec66243569dc840246bc8e3218c3269a77311bfade6c825f2459aad850a35976df49c586ff19" + }, + { + "publicKey": "5c5d23dffa673d8b700463c07cbac904628bd43dc24497f4dd3fa039ceb0e12ab700648726b669e08721e2089de178170a268481055d2b9e1a509fe9c85315ae29920d0dc42367ccf310df8fe4978493d7c24a93b3c423f0d087e67bbf9c3e86", + "privateKey": "5c5d23dffa673d8b700463c07cbac904628bd43dc24497f4dd3fa039ceb0e12ab700648726b669e08721e2089de178170a268481055d2b9e1a509fe9c85315ae29920d0dc42367ccf310df8fe4978493d7c24a93b3c423f0d087e67bbf9c3e86" + }, + { + "publicKey": "9e46c09d65d83034ad2be0d6797020ab408d2443d44b3d8c7352f7c266fd65697ac2bd3908f7bb070b8bb885daa2d4130be8956e19750ac810e1e5fb28f25ab20cf90277bbcd8f656225103b36049e08921a7b2e3bf32b93f2d5cc52c39d048b", + "privateKey": "9e46c09d65d83034ad2be0d6797020ab408d2443d44b3d8c7352f7c266fd65697ac2bd3908f7bb070b8bb885daa2d4130be8956e19750ac810e1e5fb28f25ab20cf90277bbcd8f656225103b36049e08921a7b2e3bf32b93f2d5cc52c39d048b" + }, + { + "publicKey": "ecba48713de85cca5303cc42658d099cf8f7371fe83ff3fc8985da2fb78ec3f640dfbf626624afbda92dd488221528019c91bca377e275c4eacf14d6d93a524d25207e2844c5e24f5ecedb1736e5138d9d010c9d588b32601452315db6051f08", + "privateKey": "ecba48713de85cca5303cc42658d099cf8f7371fe83ff3fc8985da2fb78ec3f640dfbf626624afbda92dd488221528019c91bca377e275c4eacf14d6d93a524d25207e2844c5e24f5ecedb1736e5138d9d010c9d588b32601452315db6051f08" + } + ], + "testVectors": [ + { + "signatures": [ + { + "signature": "cbda00694494050a84486c2e899a3c5c5d0abbec82e5820fd66268510fc6bae61031dae768aae3682ba61d144986220a", + "publicKey": "d31b53ffdaea86f72ad8faf744a9a2a7e5293cd3b395bb605650d6a7a926fb3111ed1ae59982aff4fb758464802102049d7c8b55afa1fdc464284e0ad75e1e33251e4ac9db3bf6b80c79f5e992b6f1d7e08d592ffa53c792c347e002a0b81993" + }, + { + "signature": "613cc33ea19960ff164d9fdd805e6fa0357da2a4529fc7e8bfee042f5a55b5299b8fca30bc2a0bccaee3a20417abfd8e", + "publicKey": "31d2a4541e73da3e82f9f827afe1ebf8417768eb970cc8079f6d819da7b96f3f9f2d8bf6dddf43c1e53a72011a067f07b52756f89338e07f23b8ec66243569dc840246bc8e3218c3269a77311bfade6c825f2459aad850a35976df49c586ff19" + }, + { + "signature": "b97beaef4e14f05b447fdc3b8d5b99ff14c9708b1df875e18ce9e4a05c6cee56bfe211317200078eb8df4d3f5bc8e90d", + "publicKey": "5c5d23dffa673d8b700463c07cbac904628bd43dc24497f4dd3fa039ceb0e12ab700648726b669e08721e2089de178170a268481055d2b9e1a509fe9c85315ae29920d0dc42367ccf310df8fe4978493d7c24a93b3c423f0d087e67bbf9c3e86" + }, + { + "signature": "e542147b506a1c07c5f2ca9b208876489f17a193ba17ac7016b515819ea4207b3c156f7b33a564842f1eece15f12b888", + "publicKey": "9e46c09d65d83034ad2be0d6797020ab408d2443d44b3d8c7352f7c266fd65697ac2bd3908f7bb070b8bb885daa2d4130be8956e19750ac810e1e5fb28f25ab20cf90277bbcd8f656225103b36049e08921a7b2e3bf32b93f2d5cc52c39d048b" + }, + { + "signature": "bcdb362b108434705986c319e7788d868e7cc7b255e36405d2b719417074bc2ff61dc1475f6e01a31c5957f1676f3c8d", + "publicKey": "ecba48713de85cca5303cc42658d099cf8f7371fe83ff3fc8985da2fb78ec3f640dfbf626624afbda92dd488221528019c91bca377e275c4eacf14d6d93a524d25207e2844c5e24f5ecedb1736e5138d9d010c9d588b32601452315db6051f08" + } + ], + "message": "6120707265646566696e6564206d65737361676520746f207369676e", + "aggregatedSignature": "8bf8e05c845712e63b6548e771c432382c977c41c4cb3590a6178ac542f6317f2ac5e47468b49f5d3070a742a75b7808", + "errorMessage": "noError", + "testName": "TestShouldWork" + } + ] +} \ No newline at end of file diff --git a/signing/mcl/multisig/testData/multisigKOSKVerifyAggSig.json b/signing/mcl/multisig/testData/multisigKOSKVerifyAggSig.json new file mode 100644 index 0000000..7f7fd0f --- /dev/null +++ b/signing/mcl/multisig/testData/multisigKOSKVerifyAggSig.json @@ -0,0 +1,54 @@ +{ + "keys": [ + { + "publicKey": "23c8dc504c80be9be8ea6a42d38a89e48f1755e92f1802cf2af28193f89d068d75af246ea6e8bacfc59b7c708aee82067bf1a89cb861276db4d110b78681f8285c1f39c4b236227a0e2855fdb1d145e1dacf1dbe51e6f70846a025a7e67a9207", + "privateKey": "23c8dc504c80be9be8ea6a42d38a89e48f1755e92f1802cf2af28193f89d068d75af246ea6e8bacfc59b7c708aee82067bf1a89cb861276db4d110b78681f8285c1f39c4b236227a0e2855fdb1d145e1dacf1dbe51e6f70846a025a7e67a9207" + }, + { + "publicKey": "adcbde71787900906b1bce50da5dc4a184821cc7a9544dbcd9452fde77703e93433de9a983dbaa7dcc2bca597ba0980c11c8b49eb81717e6adaead310fba9429d41988827ff8902d4ec56e55afe0b394e2a7c69ec0cc72d65ccf7c70cb20050a", + "privateKey": "adcbde71787900906b1bce50da5dc4a184821cc7a9544dbcd9452fde77703e93433de9a983dbaa7dcc2bca597ba0980c11c8b49eb81717e6adaead310fba9429d41988827ff8902d4ec56e55afe0b394e2a7c69ec0cc72d65ccf7c70cb20050a" + }, + { + "publicKey": "e91372594e7b304b27e0a8847fc066415fbbab7bc039ca455fdb1f6c1b206e4294e8adac7fda6f4df401ada18ef16c0552e1c0f21311e23c1e039f73bb8cbde8e4a33849634f9e5bc6c9667137dbc5d36fe2be8ba521c319d0174a7c41dd7807", + "privateKey": "e91372594e7b304b27e0a8847fc066415fbbab7bc039ca455fdb1f6c1b206e4294e8adac7fda6f4df401ada18ef16c0552e1c0f21311e23c1e039f73bb8cbde8e4a33849634f9e5bc6c9667137dbc5d36fe2be8ba521c319d0174a7c41dd7807" + }, + { + "publicKey": "85ccd78509295cd9ef3b05acb878fc812b702a1519c6f64e5be61605e838070fca1286f2f2b224e53f55a784dac942052ac8123e71bae79a2f20b3710e28b27bd42c17842aa8b5fac711e0b621cdbdefb505ba20e91121f9ae52f70aac9ba810", + "privateKey": "85ccd78509295cd9ef3b05acb878fc812b702a1519c6f64e5be61605e838070fca1286f2f2b224e53f55a784dac942052ac8123e71bae79a2f20b3710e28b27bd42c17842aa8b5fac711e0b621cdbdefb505ba20e91121f9ae52f70aac9ba810" + }, + { + "publicKey": "92c2a561b1fc888d28aac49cfde3815bc42f5dd0ec9dd823988ca5110841b4919903ecd1ff8f169dfc18b1919f4acd0c6ffc3e60546624f1b5cd29912eb26a88fcc6ac0818821a33a86014797b1adb70b006a7414c871ff9d87b4fbc25dabc0f", + "privateKey": "92c2a561b1fc888d28aac49cfde3815bc42f5dd0ec9dd823988ca5110841b4919903ecd1ff8f169dfc18b1919f4acd0c6ffc3e60546624f1b5cd29912eb26a88fcc6ac0818821a33a86014797b1adb70b006a7414c871ff9d87b4fbc25dabc0f" + } + ], + "testVectors": [ + { + "signatures": [ + { + "signature": "6fba93b89230062763a7e8056a74983ac0f139be2f2d8c2984629d6ae145393ff4897e71991ac3678ce9b3c52edc8918", + "publicKey": "23c8dc504c80be9be8ea6a42d38a89e48f1755e92f1802cf2af28193f89d068d75af246ea6e8bacfc59b7c708aee82067bf1a89cb861276db4d110b78681f8285c1f39c4b236227a0e2855fdb1d145e1dacf1dbe51e6f70846a025a7e67a9207" + }, + { + "signature": "9722c3144ddb07d1261cf01feb0c464f72042909d06fa283e4d7380cc0859a894ac406c8b9007046202674d0961fda0d", + "publicKey": "adcbde71787900906b1bce50da5dc4a184821cc7a9544dbcd9452fde77703e93433de9a983dbaa7dcc2bca597ba0980c11c8b49eb81717e6adaead310fba9429d41988827ff8902d4ec56e55afe0b394e2a7c69ec0cc72d65ccf7c70cb20050a" + }, + { + "signature": "bcf1af8b4f0e7297409080c4f120b2ae8916c51cdff64a56ca64795c6bde53ac4212760c652ee571cae8c37956ada601", + "publicKey": "e91372594e7b304b27e0a8847fc066415fbbab7bc039ca455fdb1f6c1b206e4294e8adac7fda6f4df401ada18ef16c0552e1c0f21311e23c1e039f73bb8cbde8e4a33849634f9e5bc6c9667137dbc5d36fe2be8ba521c319d0174a7c41dd7807" + }, + { + "signature": "4fbcc9df72906481bfea1a29d8da70ded5b5f86cfd3c2f1ae33b64eb69b007f7b1d9c9bee3216c8d6f570ec789a0348b", + "publicKey": "85ccd78509295cd9ef3b05acb878fc812b702a1519c6f64e5be61605e838070fca1286f2f2b224e53f55a784dac942052ac8123e71bae79a2f20b3710e28b27bd42c17842aa8b5fac711e0b621cdbdefb505ba20e91121f9ae52f70aac9ba810" + }, + { + "signature": "ade15c9344d91e28278357b3f5aebd1c7556026578f9df3735d54df9cfdf7b54f8142ef71d4d39f95bfdf2ea6263a093", + "publicKey": "92c2a561b1fc888d28aac49cfde3815bc42f5dd0ec9dd823988ca5110841b4919903ecd1ff8f169dfc18b1919f4acd0c6ffc3e60546624f1b5cd29912eb26a88fcc6ac0818821a33a86014797b1adb70b006a7414c871ff9d87b4fbc25dabc0f" + } + ], + "message": "6120707265646566696e6564206d65737361676520746f207369676e", + "aggregatedSignature": "be3ed6dbfdca8fe248c07790a36d5b1176a15a7f243039bcd4c383610c2bfcb9c606b8b03a6288904975d41e0e34598b", + "errorMessage": "noError", + "testName": "TestShouldWork" + } + ] +} \ No newline at end of file diff --git a/signing/mcl/multisig/testData/multisigNonKOSKAggSig.json b/signing/mcl/multisig/testData/multisigNonKOSKAggSig.json new file mode 100644 index 0000000..a8d0add --- /dev/null +++ b/signing/mcl/multisig/testData/multisigNonKOSKAggSig.json @@ -0,0 +1,54 @@ +{ + "keys": [ + { + "publicKey": "b407253a79083eec81abe6c30a694e038fb1ae07ea91055dc1d129fe042d152882334606b5d56460bacf54d5c203070cc7e271c7cae200fe31933d39dff721e219d30b811af2d9532ce9d8f71461f66ca696bc33864bb2e52c8ebe9af034e508", + "privateKey": "b407253a79083eec81abe6c30a694e038fb1ae07ea91055dc1d129fe042d152882334606b5d56460bacf54d5c203070cc7e271c7cae200fe31933d39dff721e219d30b811af2d9532ce9d8f71461f66ca696bc33864bb2e52c8ebe9af034e508" + }, + { + "publicKey": "9b376f4e05f6d578bfa196f442f23a2d2a2ef99c5534f8b6c15555e88c9e7a36f03a44ea4421523973f3cecb58e313189983fc3be003dfdda3bc958bbbae166b1be8882083b2d7b6f7f44d228733e7f5165a3132f36d13dcddf6c8daea6c9591", + "privateKey": "9b376f4e05f6d578bfa196f442f23a2d2a2ef99c5534f8b6c15555e88c9e7a36f03a44ea4421523973f3cecb58e313189983fc3be003dfdda3bc958bbbae166b1be8882083b2d7b6f7f44d228733e7f5165a3132f36d13dcddf6c8daea6c9591" + }, + { + "publicKey": "e6c61229ff98b2ce5dc5da841e4e0c733d10845efd138f71a6d38f0210c3dc40c7fc03f40074ccd25725327f28a3e814c09e556028b5b694083598e77957d4e3a999ebda9c74c068d6194603d4d3e3edba68a2ddf7b8b75bba1ca7ada42a158e", + "privateKey": "e6c61229ff98b2ce5dc5da841e4e0c733d10845efd138f71a6d38f0210c3dc40c7fc03f40074ccd25725327f28a3e814c09e556028b5b694083598e77957d4e3a999ebda9c74c068d6194603d4d3e3edba68a2ddf7b8b75bba1ca7ada42a158e" + }, + { + "publicKey": "16bd6ad223ca625be7e2fa1582f0fb54399cbbe323fb53a407712ff2d1f1b1f7e1a8ba642b3fb399f760b983115de60b123f6eab2b96a4ff68eb9273a1991740a98dac46bf3e695b292276487d6657faf2137744de5bbdea9f448b762b889693", + "privateKey": "16bd6ad223ca625be7e2fa1582f0fb54399cbbe323fb53a407712ff2d1f1b1f7e1a8ba642b3fb399f760b983115de60b123f6eab2b96a4ff68eb9273a1991740a98dac46bf3e695b292276487d6657faf2137744de5bbdea9f448b762b889693" + }, + { + "publicKey": "e533fc6c4dce5e9437a6dd828f8b77520e3b19ff61467d4db2dc9103a1e40f5fa5a94288d20e754c3864db1684ce3b14f4a5eb31179b04120d4d74c0bb3262320cdf4d29832c35d4668d177df76b8d971e704f2e0cb763cd82e3d4e355753683", + "privateKey": "e533fc6c4dce5e9437a6dd828f8b77520e3b19ff61467d4db2dc9103a1e40f5fa5a94288d20e754c3864db1684ce3b14f4a5eb31179b04120d4d74c0bb3262320cdf4d29832c35d4668d177df76b8d971e704f2e0cb763cd82e3d4e355753683" + } + ], + "testVectors": [ + { + "signatures": [ + { + "signature": "41ab319221f4fbfb8efff233e555dd54efd20417dc79618e086bc26bc2b542c2aa7f29695b09a538a719aaec79ae4b0a", + "publicKey": "b407253a79083eec81abe6c30a694e038fb1ae07ea91055dc1d129fe042d152882334606b5d56460bacf54d5c203070cc7e271c7cae200fe31933d39dff721e219d30b811af2d9532ce9d8f71461f66ca696bc33864bb2e52c8ebe9af034e508" + }, + { + "signature": "ef26de3e8b1707c9d933da0288df5794802491b25ed4c88da4508a29489679c737e62d4ec9fff33e9a75367f1055b890", + "publicKey": "9b376f4e05f6d578bfa196f442f23a2d2a2ef99c5534f8b6c15555e88c9e7a36f03a44ea4421523973f3cecb58e313189983fc3be003dfdda3bc958bbbae166b1be8882083b2d7b6f7f44d228733e7f5165a3132f36d13dcddf6c8daea6c9591" + }, + { + "signature": "f01ad74b05348ccf9faffbcb07229a37a2a7e428e485e1ff0226af1dfddddfedebd7008dead8a80ff3e7a416a76fa801", + "publicKey": "e6c61229ff98b2ce5dc5da841e4e0c733d10845efd138f71a6d38f0210c3dc40c7fc03f40074ccd25725327f28a3e814c09e556028b5b694083598e77957d4e3a999ebda9c74c068d6194603d4d3e3edba68a2ddf7b8b75bba1ca7ada42a158e" + }, + { + "signature": "6d7ffa5692a643120c8b448a798fea9b707afc5dce8c15365c4dea175e24226fa14841636fb74b2568f8f89d04cdf787", + "publicKey": "16bd6ad223ca625be7e2fa1582f0fb54399cbbe323fb53a407712ff2d1f1b1f7e1a8ba642b3fb399f760b983115de60b123f6eab2b96a4ff68eb9273a1991740a98dac46bf3e695b292276487d6657faf2137744de5bbdea9f448b762b889693" + }, + { + "signature": "91682cb5ca17527a221e6a308c58ca7e87f9ff5667b8bb1a2df76e82718f572f0210d32c51f078eef71a4083ae3f9011", + "publicKey": "e533fc6c4dce5e9437a6dd828f8b77520e3b19ff61467d4db2dc9103a1e40f5fa5a94288d20e754c3864db1684ce3b14f4a5eb31179b04120d4d74c0bb3262320cdf4d29832c35d4668d177df76b8d971e704f2e0cb763cd82e3d4e355753683" + } + ], + "message": "6120707265646566696e6564206d65737361676520746f207369676e", + "aggregatedSignature": "d5f1f76e64cf48a6b2a2e7af1739fc2257e8307cbc5c1729e4a3881f4c7146a54c76f8df385472fe728969803833bd0f", + "errorMessage": "noError", + "testName": "TestShouldWork" + } + ] +} \ No newline at end of file diff --git a/signing/mcl/multisig/testData/multisigNonKOSKVerifyAggSig.json b/signing/mcl/multisig/testData/multisigNonKOSKVerifyAggSig.json new file mode 100644 index 0000000..5e704e1 --- /dev/null +++ b/signing/mcl/multisig/testData/multisigNonKOSKVerifyAggSig.json @@ -0,0 +1,54 @@ +{ + "keys": [ + { + "publicKey": "e0ec2483c6911c62d00c6c82d72d11b35732d71c1e65974e0181a4eafc83fe79e8684ab8ebaf7e48777fd622854a0310f3ad7ca11a71b0c116d787a31f1487c61db0b5bcab0b1db25d9c48cbc7dfb7c551288a4d052cb52a1ed4ab0911719903", + "privateKey": "e0ec2483c6911c62d00c6c82d72d11b35732d71c1e65974e0181a4eafc83fe79e8684ab8ebaf7e48777fd622854a0310f3ad7ca11a71b0c116d787a31f1487c61db0b5bcab0b1db25d9c48cbc7dfb7c551288a4d052cb52a1ed4ab0911719903" + }, + { + "publicKey": "5ea3382c47ce05e0c3e424b9dc8383fc9a67f2ea29bf71f3b2b47f2687698a5faadd00a842a8d894331bde9f2d3e6810abe058658bc52ed643dffa535ab92ae9de5120f84aea38e400c7f1406a5223e0c320e2388d7cd54be75321f2fdbdd18e", + "privateKey": "5ea3382c47ce05e0c3e424b9dc8383fc9a67f2ea29bf71f3b2b47f2687698a5faadd00a842a8d894331bde9f2d3e6810abe058658bc52ed643dffa535ab92ae9de5120f84aea38e400c7f1406a5223e0c320e2388d7cd54be75321f2fdbdd18e" + }, + { + "publicKey": "15be2570b657f317775bb729d3b1fa9df4da0bc830de0239367161537bb8a276b2d428d84556bc3d1ba730fa0cdc6f026e5cb12eca554f27ecee3ea1927db625542f86a811f18b0bd131f66ffff7a8c0d0d3c80ecc3b3c3cdfadb393cb946309", + "privateKey": "15be2570b657f317775bb729d3b1fa9df4da0bc830de0239367161537bb8a276b2d428d84556bc3d1ba730fa0cdc6f026e5cb12eca554f27ecee3ea1927db625542f86a811f18b0bd131f66ffff7a8c0d0d3c80ecc3b3c3cdfadb393cb946309" + }, + { + "publicKey": "cc13d958a8f81f7e3c80b43eaab4585a9a13990e6e2f3a7e59f0fbb869e507d9a6c1c6fc380cbade96f54dfbd5f4e4132a907804f4016072c7cbd9c4e3ab6042811f8c6641880725e339bf57e16d521bc4c150ae4f5a212971c3c6cc1468f00e", + "privateKey": "cc13d958a8f81f7e3c80b43eaab4585a9a13990e6e2f3a7e59f0fbb869e507d9a6c1c6fc380cbade96f54dfbd5f4e4132a907804f4016072c7cbd9c4e3ab6042811f8c6641880725e339bf57e16d521bc4c150ae4f5a212971c3c6cc1468f00e" + }, + { + "publicKey": "441c77ac44a3d3389392f4fb8665016a0330de2b381dfa651b1f104de0eb27768b996009515e45bc680f16bf2a803f069735c66ea369211c09cb13d3d3e5ec05b60a004176d99ef21b4fea1caf9100bf0e141863f1d069e622a76ced81212493", + "privateKey": "441c77ac44a3d3389392f4fb8665016a0330de2b381dfa651b1f104de0eb27768b996009515e45bc680f16bf2a803f069735c66ea369211c09cb13d3d3e5ec05b60a004176d99ef21b4fea1caf9100bf0e141863f1d069e622a76ced81212493" + } + ], + "testVectors": [ + { + "signatures": [ + { + "signature": "cbe743bcda4e2c796a1aa93ae406c74a771ae26eb8c98f78db94a1ee4f684cdbdec0c94994daa1316afb7a70c5beaf8e", + "publicKey": "e0ec2483c6911c62d00c6c82d72d11b35732d71c1e65974e0181a4eafc83fe79e8684ab8ebaf7e48777fd622854a0310f3ad7ca11a71b0c116d787a31f1487c61db0b5bcab0b1db25d9c48cbc7dfb7c551288a4d052cb52a1ed4ab0911719903" + }, + { + "signature": "155a05969edc07a2e6810db455d8bb6c1030fff50cc58a58179631441a7388c56d0633ec0adb4ba453519c2fa2d4cf0d", + "publicKey": "5ea3382c47ce05e0c3e424b9dc8383fc9a67f2ea29bf71f3b2b47f2687698a5faadd00a842a8d894331bde9f2d3e6810abe058658bc52ed643dffa535ab92ae9de5120f84aea38e400c7f1406a5223e0c320e2388d7cd54be75321f2fdbdd18e" + }, + { + "signature": "7c516066c943f28a2cbf00f48ca76fca53635b47fa24fb55c691fda18a184479311cbf0a3b26b9a898eb044e0f93650a", + "publicKey": "15be2570b657f317775bb729d3b1fa9df4da0bc830de0239367161537bb8a276b2d428d84556bc3d1ba730fa0cdc6f026e5cb12eca554f27ecee3ea1927db625542f86a811f18b0bd131f66ffff7a8c0d0d3c80ecc3b3c3cdfadb393cb946309" + }, + { + "signature": "23259bab379dbbde08eb891193b164c4da957d05277c92b6a6b44bbaff53d0e5d80ed91154b859305a93d370bf8af98c", + "publicKey": "cc13d958a8f81f7e3c80b43eaab4585a9a13990e6e2f3a7e59f0fbb869e507d9a6c1c6fc380cbade96f54dfbd5f4e4132a907804f4016072c7cbd9c4e3ab6042811f8c6641880725e339bf57e16d521bc4c150ae4f5a212971c3c6cc1468f00e" + }, + { + "signature": "d99aa15c0536384b67d02a17ab6034d465643c51c16a3443a72148b5c4a9de6829978d142b398e992e8f14980e512708", + "publicKey": "441c77ac44a3d3389392f4fb8665016a0330de2b381dfa651b1f104de0eb27768b996009515e45bc680f16bf2a803f069735c66ea369211c09cb13d3d3e5ec05b60a004176d99ef21b4fea1caf9100bf0e141863f1d069e622a76ced81212493" + } + ], + "message": "6120707265646566696e6564206d65737361676520746f207369676e", + "aggregatedSignature": "f8a5eec45362673145078eae97831d8a658b953d500b62c4f3542294a10f84b49ffd0612212f315eedb391fce5c90a96", + "errorMessage": "noError", + "testName": "TestShouldWork" + } + ] +} \ No newline at end of file diff --git a/signing/mcl/multisig/vectors_test.go b/signing/mcl/multisig/vectors_test.go new file mode 100644 index 0000000..aef643b --- /dev/null +++ b/signing/mcl/multisig/vectors_test.go @@ -0,0 +1,195 @@ +package multisig + +import ( + "encoding/hex" + "encoding/json" + "errors" + "os" + "testing" + + "github.com/multiversx/mx-chain-core-go/hashing/blake2b" + "github.com/stretchr/testify/require" + + crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-crypto-go/signing" + "github.com/multiversx/mx-chain-crypto-go/signing/mcl" + "github.com/multiversx/mx-chain-crypto-go/signing/mcl/multisig/testData" +) + +const blsHashSize = 16 + +// TestVector defines the data structure used to unmarshal the JSON file +type TestVector struct { + testName string + message []byte + publicKeys []crypto.PublicKey + signatures [][]byte + aggregatedSig []byte + expectedError error +} + +func TestAggregateSignaturesKOSK(t *testing.T) { + t.Parallel() + + lls := &BlsMultiSignerKOSK{} + + err := testData.GenerateJSONFileKOSKForAggregateSignaturesTests(lls) + require.Nil(t, err) + + suite := mcl.NewSuiteBLS12() + testVectors, err := createTestSetup(suite, "testData/multisigKOSKAggSig.json") + require.Nil(t, err) + + for _, testVector := range testVectors { + testVectorCopy := testVector + + t.Run(testVectorCopy.testName, func(t *testing.T) { + returnedVal, err := lls.AggregateSignatures(suite, testVectorCopy.signatures, testVectorCopy.publicKeys) + require.Equal(t, testVectorCopy.expectedError, err) + require.Equal(t, testVectorCopy.aggregatedSig, returnedVal) + }) + } + +} + +func TestVerifyAggregatedSigKOSK(t *testing.T) { + t.Parallel() + + lls := &BlsMultiSignerKOSK{} + err := testData.GenerateJSONFileKOSKForVerifyAggregatedSigTests(lls) + require.Nil(t, err) + + suite := mcl.NewSuiteBLS12() + testVectors, err := createTestSetup(suite, "testData/multisigKOSKVerifyAggSig.json") + require.Nil(t, err) + + for _, testVector := range testVectors { + testVectorCopy := testVector + + t.Run(testVectorCopy.testName, func(t *testing.T) { + returnedErr := lls.VerifyAggregatedSig(suite, testVectorCopy.publicKeys, testVectorCopy.aggregatedSig, testVectorCopy.message) + require.Equal(t, testVectorCopy.expectedError, returnedErr) + + }) + } + +} + +func TestAggregateSignaturesNonKOSK(t *testing.T) { + t.Parallel() + + hasher, err := blake2b.NewBlake2bWithSize(blsHashSize) + lls := &BlsMultiSigner{ + Hasher: hasher, + } + require.Nil(t, err) + + err = testData.GenerateJSONFileNonKOSKForAggregateSignaturesTests(lls) + require.Nil(t, err) + + suite := mcl.NewSuiteBLS12() + testVectors, err := createTestSetup(suite, "testData/multisigNonKOSKAggSig.json") + require.Nil(t, err) + + for _, testVector := range testVectors { + testVectorCopy := testVector + + t.Run(testVectorCopy.testName, func(t *testing.T) { + returnedVal, err := lls.AggregateSignatures(suite, testVectorCopy.signatures, testVectorCopy.publicKeys) + require.Equal(t, testVectorCopy.expectedError, err) + require.Equal(t, testVectorCopy.aggregatedSig, returnedVal) + }) + } + +} + +func TestVerifyAggregatedSigNonKOSK(t *testing.T) { + t.Parallel() + + hasher, err := blake2b.NewBlake2bWithSize(blsHashSize) + require.Nil(t, err) + lls := &BlsMultiSigner{ + Hasher: hasher, + } + + err = testData.GenerateJSONFileNonKOSKForVerifyAggregatedSigTests(lls) + require.Nil(t, err) + + suite := mcl.NewSuiteBLS12() + testVectors, err := createTestSetup(suite, "testData/multisigNonKOSKVerifyAggSig.json") + require.Nil(t, err) + + for _, testVector := range testVectors { + testVectorCopy := testVector + + t.Run(testVectorCopy.testName, func(t *testing.T) { + returnedErr := lls.VerifyAggregatedSig(suite, testVectorCopy.publicKeys, testVectorCopy.aggregatedSig, testVectorCopy.message) + require.Equal(t, testVectorCopy.expectedError, returnedErr) + }) + } + +} + +func createTestSetup(suite crypto.Suite, filename string) ([]TestVector, error) { + var testVectors []TestVector + + content, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + var jsonContent testData.JSONFileContent + err = json.Unmarshal(content, &jsonContent) + if err != nil { + return nil, err + } + + for _, testVector := range jsonContent.TestVectors { + newTestVector := createNewTestVector(suite, testVector) + testVectors = append(testVectors, newTestVector) + + } + return testVectors, nil + +} + +func createNewTestVector(suite crypto.Suite, testVector testData.TestVectorElement) TestVector { + kg := signing.NewKeyGenerator(suite) + + testName := testVector.TestName + signatures := testVector.Signatures + aggregatedSig := testVector.AggregatedSignature + + message := testVector.Message + expectedError := errors.New(testVector.ErrorMessage) + if testVector.ErrorMessage == "noError" { + expectedError = nil + } + + pubKeys := make([]crypto.PublicKey, 0, len(signatures)) + sigs := make([][]byte, 0, len(signatures)) + for _, signature := range signatures { + decodedValue, _ := hex.DecodeString(signature.PublicKey) + pk, _ := kg.PublicKeyFromByteArray(decodedValue) + pubKeys = append(pubKeys, pk) + + decodedValue, _ = hex.DecodeString(signature.Signature) + sigs = append(sigs, decodedValue) + } + + var decodedAggregatedSig []byte + if len(aggregatedSig) > 0 { + decodedAggregatedSig, _ = hex.DecodeString(aggregatedSig) + } + + decodedMessage, _ := hex.DecodeString(message) + + return TestVector{ + testName: testName, + message: decodedMessage, + publicKeys: pubKeys, + signatures: sigs, + aggregatedSig: decodedAggregatedSig, + expectedError: expectedError, + } + +}