Source file src/crypto/elliptic/p256_test.go

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package elliptic
     6  
     7  import (
     8  	"math/big"
     9  	"testing"
    10  )
    11  
    12  type scalarMultTest struct {
    13  	k          string
    14  	xIn, yIn   string
    15  	xOut, yOut string
    16  }
    17  
    18  var p256MultTests = []scalarMultTest{
    19  	{
    20  		"2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737",
    21  		"023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882ea",
    22  		"f93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad",
    23  		"4d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3",
    24  		"a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0",
    25  	},
    26  	{
    27  		"313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd",
    28  		"cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06",
    29  		"a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031",
    30  		"831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f17991",
    31  		"93f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684",
    32  	},
    33  }
    34  
    35  func TestP256BaseMult(t *testing.T) {
    36  	p256 := P256()
    37  	p256Generic := genericParamsForCurve(p256)
    38  
    39  	scalars := make([]*big.Int, 0, len(p224BaseMultTests)+1)
    40  	for _, e := range p224BaseMultTests {
    41  		k, _ := new(big.Int).SetString(e.k, 10)
    42  		scalars = append(scalars, k)
    43  	}
    44  	k := new(big.Int).SetInt64(1)
    45  	k.Lsh(k, 500)
    46  	scalars = append(scalars, k)
    47  
    48  	for i, k := range scalars {
    49  		x, y := p256.ScalarBaseMult(k.Bytes())
    50  		x2, y2 := p256Generic.ScalarBaseMult(k.Bytes())
    51  		if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 {
    52  			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, x, y, x2, y2)
    53  		}
    54  
    55  		if testing.Short() && i > 5 {
    56  			break
    57  		}
    58  	}
    59  }
    60  
    61  func TestP256Mult(t *testing.T) {
    62  	p256 := P256()
    63  	for i, e := range p256MultTests {
    64  		x, _ := new(big.Int).SetString(e.xIn, 16)
    65  		y, _ := new(big.Int).SetString(e.yIn, 16)
    66  		k, _ := new(big.Int).SetString(e.k, 16)
    67  		expectedX, _ := new(big.Int).SetString(e.xOut, 16)
    68  		expectedY, _ := new(big.Int).SetString(e.yOut, 16)
    69  
    70  		xx, yy := p256.ScalarMult(x, y, k.Bytes())
    71  		if xx.Cmp(expectedX) != 0 || yy.Cmp(expectedY) != 0 {
    72  			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, expectedX, expectedY)
    73  		}
    74  	}
    75  }
    76  
    77  type synthCombinedMult struct {
    78  	Curve
    79  }
    80  
    81  func (s synthCombinedMult) CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) {
    82  	x1, y1 := s.ScalarBaseMult(baseScalar)
    83  	x2, y2 := s.ScalarMult(bigX, bigY, scalar)
    84  	return s.Add(x1, y1, x2, y2)
    85  }
    86  
    87  func TestP256CombinedMult(t *testing.T) {
    88  	type combinedMult interface {
    89  		Curve
    90  		CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int)
    91  	}
    92  
    93  	p256, ok := P256().(combinedMult)
    94  	if !ok {
    95  		p256 = &synthCombinedMult{P256()}
    96  	}
    97  
    98  	gx := p256.Params().Gx
    99  	gy := p256.Params().Gy
   100  
   101  	zero := make([]byte, 32)
   102  	one := make([]byte, 32)
   103  	one[31] = 1
   104  	two := make([]byte, 32)
   105  	two[31] = 2
   106  
   107  	// 0×G + 0×G = ∞
   108  	x, y := p256.CombinedMult(gx, gy, zero, zero)
   109  	if x.Sign() != 0 || y.Sign() != 0 {
   110  		t.Errorf("0×G + 0×G = (%d, %d), should be ∞", x, y)
   111  	}
   112  
   113  	// 1×G + 0×G = G
   114  	x, y = p256.CombinedMult(gx, gy, one, zero)
   115  	if x.Cmp(gx) != 0 || y.Cmp(gy) != 0 {
   116  		t.Errorf("1×G + 0×G = (%d, %d), should be (%d, %d)", x, y, gx, gy)
   117  	}
   118  
   119  	// 0×G + 1×G = G
   120  	x, y = p256.CombinedMult(gx, gy, zero, one)
   121  	if x.Cmp(gx) != 0 || y.Cmp(gy) != 0 {
   122  		t.Errorf("0×G + 1×G = (%d, %d), should be (%d, %d)", x, y, gx, gy)
   123  	}
   124  
   125  	// 1×G + 1×G = 2×G
   126  	x, y = p256.CombinedMult(gx, gy, one, one)
   127  	ggx, ggy := p256.ScalarBaseMult(two)
   128  	if x.Cmp(ggx) != 0 || y.Cmp(ggy) != 0 {
   129  		t.Errorf("1×G + 1×G = (%d, %d), should be (%d, %d)", x, y, ggx, ggy)
   130  	}
   131  
   132  	minusOne := new(big.Int).Sub(p256.Params().N, big.NewInt(1))
   133  	// 1×G + (-1)×G = ∞
   134  	x, y = p256.CombinedMult(gx, gy, one, minusOne.Bytes())
   135  	if x.Sign() != 0 || y.Sign() != 0 {
   136  		t.Errorf("1×G + (-1)×G = (%d, %d), should be ∞", x, y)
   137  	}
   138  }
   139  
   140  func TestIssue52075(t *testing.T) {
   141  	Gx, Gy := P256().Params().Gx, P256().Params().Gy
   142  	scalar := make([]byte, 33)
   143  	scalar[32] = 1
   144  	x, y := P256().ScalarBaseMult(scalar)
   145  	if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
   146  		t.Errorf("unexpected output (%v,%v)", x, y)
   147  	}
   148  	x, y = P256().ScalarMult(Gx, Gy, scalar)
   149  	if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
   150  		t.Errorf("unexpected output (%v,%v)", x, y)
   151  	}
   152  }
   153  

View as plain text