github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/crypto/crypto_test.go (about)

     1  // Copyright 2017-2018 DERO Project. All rights reserved.
     2  // Use of this source code in any form is governed by RESEARCH license.
     3  // license can be found in the LICENSE file.
     4  // GPG: 0F39 E425 8C65 3947 702A  8234 08B2 0360 A03A 9DE8
     5  //
     6  //
     7  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
     8  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     9  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    10  // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    11  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    12  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    13  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    14  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
    15  // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    16  
    17  package crypto
    18  
    19  //import "fmt"
    20  import "testing"
    21  import "bufio"
    22  import "log"
    23  import "os"
    24  import "strings"
    25  import "strconv"
    26  import "encoding/hex"
    27  
    28  // these tests, specifically "tests_data.txt" are available in the monero  project and used here to verify whether we implement everything
    29  
    30  func Test_Crypto(t *testing.T) {
    31  
    32  	file, err := os.Open("tests_data.txt")
    33  	if err != nil {
    34  		log.Fatalf("Test file tests_data is missing, err %s ", err)
    35  	}
    36  	defer file.Close()
    37  
    38  	scanner := bufio.NewScanner(file)
    39  	for scanner.Scan() {
    40  		// parse the line
    41  		line := scanner.Text()
    42  		words := strings.Fields(line)
    43  
    44  		if len(words) < 2 {
    45  			continue
    46  		}
    47  		switch words[0] {
    48  		case "check_scalar":
    49  			scalar := HexToKey(words[1])
    50  			expected := "true" == words[2]
    51  			actual := ScValid(&scalar)
    52  			if actual != expected {
    53  				t.Fatalf("Failed %s: Expected %v, got %v.", words[0], expected, actual)
    54  			}
    55  		case "check_key":
    56  			public_key := HexToKey(words[1])
    57  			expected := "true" == words[2]
    58  			actual := public_key.Public_Key_Valid()
    59  			if actual != expected {
    60  				t.Fatalf("Failed %s: Expected %v, got %v %s", words[0], expected, actual, public_key)
    61  			}
    62  
    63  		case "random_scalar": // ignore them
    64  		case "hash_to_scalar":
    65  			data, _ := hex.DecodeString(words[1])
    66  			expected := HexToKey(words[2])
    67  			actual := HashToScalar(data)
    68  			if *actual != expected {
    69  				t.Fatalf("Failed %s: Expected %v, got %v.", words[0], expected, actual)
    70  			}
    71  			//t.Logf("executing %s\n", expected)
    72  		case "generate_keys": // this test is meant to test RNG ??
    73  			key_secret := HexToKey(words[2])
    74  			key_public := HexToKey(words[1])
    75  
    76  			if key_public != *(key_secret.PublicKey()) {
    77  				t.Errorf("Failed %s key generation testing failed %s ", words[0], key_secret)
    78  			}
    79  		case "secret_key_to_public_key":
    80  			key_secret := HexToKey(words[1])
    81  
    82  			expected := "true" == words[2]
    83  			actual := key_secret.Private_Key_Valid()
    84  
    85  			if expected != actual {
    86  				t.Fatalf("Failed %s: Expected %v, got %v.  %s", words[0], expected, actual, key_secret)
    87  			}
    88  
    89  			if actual { // test only if required
    90  				key_public := HexToKey(words[3])
    91  				if key_public != *(key_secret.PublicKey()) {
    92  					t.Errorf("Failed %s key generation testing failed %s ", words[0], key_secret)
    93  				}
    94  			}
    95  
    96  		case "generate_key_derivation":
    97  			public_key := HexToKey(words[1])
    98  			private_key := HexToKey(words[2])
    99  
   100  			expected := "true" == words[3]
   101  			actual := public_key.Public_Key_Valid()
   102  
   103  			if expected != actual {
   104  				t.Fatalf(" Failed %s: Expected %v, got %v.  %s", words[0], expected, actual, public_key)
   105  			}
   106  
   107  			if expected == true { // yes knowingly using the same variables
   108  				expected := HexToKey(words[4])
   109  				actual := KeyDerivation(&public_key, &private_key)
   110  
   111  				if expected != actual {
   112  					t.Fatalf("1Failed %s: Expected %v, got %v.  %s", words[0], expected, actual, public_key)
   113  				}
   114  			}
   115  
   116  		case "derive_public_key":
   117  			kd := HexToKey(words[1]) //
   118  			outIdx, _ := strconv.ParseUint(words[2], 10, 0)
   119  			base := HexToKey(words[3])
   120  			var expected1, actual1 bool
   121  			var expected2, actual2 Key
   122  			expected1 = words[4] == "true"
   123  			if expected1 {
   124  				expected2 = HexToKey(words[5])
   125  			}
   126  
   127  			actual1 = base.Public_Key_Valid()
   128  			if actual1 != expected1 {
   129  				t.Fatalf("%s: Expected %v, got %v.", words[0], expected1, actual1)
   130  			}
   131  
   132  			if expected1 {
   133  				actual2 = kd.KeyDerivation_To_PublicKey(outIdx, base)
   134  				if actual2 != expected2 {
   135  					t.Fatalf("%s: Expected %v, got %v.", words[0], expected2, actual2)
   136  				}
   137  			}
   138  		case "derive_secret_key":
   139  			kd := HexToKey(words[1]) //
   140  			outIdx, _ := strconv.ParseUint(words[2], 10, 0)
   141  			base := HexToKey(words[3])
   142  			expected := HexToKey(words[4])
   143  
   144  			actual := kd.KeyDerivation_To_PrivateKey(outIdx, base)
   145  			if actual != expected {
   146  				t.Fatalf("%s: Expected %v, got %v.", words[0], expected, actual)
   147  			}
   148  
   149  		case "hash_to_point": // this is different check than HashToPoint
   150  
   151  			hash := HexToKey(words[1])
   152  			expected := HexToKey(words[2])
   153  
   154  			var actual Key
   155  			var p1 ProjectiveGroupElement
   156  			p1.FromBytes(&hash)
   157  			p1.ToBytes(&actual)
   158  
   159  			if actual != expected {
   160  				t.Fatalf("%s: Expected %v, got %v.", words[0], expected, actual)
   161  			}
   162  		case "hash_to_ec":
   163  			pub := HexToKey(words[1])
   164  			expected := HexToKey(words[2])
   165  
   166  			var actual Key
   167  			ex := pub.HashToEC()
   168  			ex.ToBytes(&actual)
   169  
   170  			if actual != expected {
   171  				t.Fatalf("%s: Expected %s, got %s.", words[0], expected, actual)
   172  			}
   173  
   174  		case "generate_key_image":
   175  			public_key := HexToKey(words[1])
   176  			private_key := HexToKey(words[2])
   177  			expected := HexToKey(words[3])
   178  
   179  			actual := GenerateKeyImage(public_key, private_key)
   180  			if actual != expected {
   181  				t.Fatalf("%s: Expected %s, got %s.", words[0], expected, actual)
   182  			}
   183  
   184  		// these are ignored because they are not required DERO project is based on ringct+
   185  		case "generate_signature":
   186  		case "check_signature":
   187  		case "generate_ring_signature":
   188  		case "check_ring_signature":
   189  
   190  		default:
   191  
   192  			t.Fatalf("This test is not handled %s: ", words[0])
   193  
   194  		}
   195  	}
   196  
   197  }
   198  
   199  // test whether H generation is alright
   200  func TestH(t *testing.T) {
   201  	G := ScalarmultBase(*(d2h(1)))
   202  	//	t.Logf("G %s \nH %s", G, H)
   203  	actual := G.HashToPointSimple()
   204  	if actual != H {
   205  		t.Fatalf("H generation failed Actual %s expected %s", actual, H)
   206  	}
   207  }