// Copyright 2017-2018 DERO Project. All rights reserved. // Use of this source code in any form is governed by RESEARCH license. // license can be found in the LICENSE file. // GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package crypto //import "fmt" import "testing" import "bufio" import "log" import "os" import "strings" import "strconv" import "encoding/hex" // these tests, specifically "tests_data.txt" are available in the monero project and used here to verify whether we implement everything func Test_Crypto(t *testing.T) { file, err := os.Open("tests_data.txt") if err != nil { log.Fatalf("Test file tests_data is missing, err %s ", err) } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { // parse the line line := scanner.Text() words := strings.Fields(line) if len(words) < 2 { continue } switch words[0] { case "check_scalar": scalar := HexToKey(words[1]) expected := "true" == words[2] actual := ScValid(&scalar) == true if actual != expected { t.Fatalf("Failed %s: Expected %v, got %v.", words[0], expected, actual) } case "check_key": public_key := HexToKey(words[1]) expected := "true" == words[2] actual := public_key.Public_Key_Valid() == true if actual != expected { t.Logf("Failed %s: Expected %v, got %v %s", words[0], expected, actual, public_key) } case "random_scalar": // ignore them case "hash_to_scalar": data, _ := hex.DecodeString(words[1]) expected := HexToKey(words[2]) actual := HashToScalar(data) if *actual != expected { t.Fatalf("Failed %s: Expected %v, got %v.", words[0], expected, actual) } //t.Logf("executing %s\n", expected) case "generate_keys": // this test is meant to test RNG ?? key_secret := HexToKey(words[2]) key_public := HexToKey(words[1]) if key_public != *(key_secret.PublicKey()) { t.Errorf("Failed %s key generation testing failed %s ", words[0], key_secret) } case "secret_key_to_public_key": key_secret := HexToKey(words[1]) expected := "true" == words[2] actual := key_secret.Private_Key_Valid() if expected != actual { t.Fatalf("Failed %s: Expected %v, got %v. %s", words[0], expected, actual, key_secret) } if actual { // test only if required key_public := HexToKey(words[3]) if key_public != *(key_secret.PublicKey()) { t.Errorf("Failed %s key generation testing failed %s ", words[0], key_secret) } } case "generate_key_derivation": public_key := HexToKey(words[1]) private_key := HexToKey(words[2]) expected := "true" == words[3] actual := public_key.Public_Key_Valid() if expected != actual { t.Fatalf(" Failed %s: Expected %v, got %v. %s", words[0], expected, actual, public_key) } if expected == true { // yes knowingly using the same variables expected := HexToKey(words[4]) actual := KeyDerivation(&public_key, &private_key) if expected != actual { t.Fatalf("Failed %s: Expected %v, got %v. %s", words[0], expected, actual, public_key) } } case "derive_public_key": kd := HexToKey(words[1]) // outIdx, _ := strconv.ParseUint(words[2], 10, 0) base := HexToKey(words[3]) var expected1, actual1 bool var expected2, actual2 Key expected1 = words[4] == "true" if expected1 { expected2 = HexToKey(words[5]) } actual1 = base.Public_Key_Valid() if actual1 != expected1 { t.Fatalf("%s: Expected %v, got %v.", words[0], expected1, actual1) } if expected1 { actual2 = kd.KeyDerivation_To_PublicKey(outIdx, base) if actual2 != expected2 { t.Fatalf("%s: Expected %v, got %v.", words[0], expected2, actual2) } } case "derive_secret_key": kd := HexToKey(words[1]) // outIdx, _ := strconv.ParseUint(words[2], 10, 0) base := HexToKey(words[3]) expected := HexToKey(words[4]) actual := kd.KeyDerivation_To_PrivateKey(outIdx, base) if actual != expected { t.Fatalf("%s: Expected %v, got %v.", words[0], expected, actual) } case "hash_to_point": // this is different check than HashToPoint hash := HexToKey(words[1]) expected := HexToKey(words[2]) var actual Key var p1 ProjectiveGroupElement p1.FromBytes(&hash) p1.ToBytes(&actual) if actual != expected { t.Logf("%s: Expected %v, got %v.", words[0], expected, actual) } case "hash_to_ec": pub := HexToKey(words[1]) expected := HexToKey(words[2]) var actual Key ex := pub.HashToEC() ex.ToBytes(&actual) if actual != expected { t.Fatalf("%s: Expected %s, got %s.", words[0], expected, actual) } case "generate_key_image": public_key := HexToKey(words[1]) private_key := HexToKey(words[2]) expected := HexToKey(words[3]) actual := GenerateKeyImage(public_key, private_key) if actual != expected { t.Fatalf("%s: Expected %s, got %s.", words[0], expected, actual) } // these are ignored because they are not required DERO project is based on ringct+ case "generate_signature": case "check_signature": case "generate_ring_signature": case "check_ring_signature": default: t.Fatalf("This test is not handled %s: ", words[0]) } } }