github.com/ethw3/go-ethereuma@v0.0.0-20221013053120-c14602a4c23c/crypto/bls12381/g2_test.go (about)

     1  package bls12381
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"math/big"
     7  	"testing"
     8  
     9  	"github.com/ethw3/go-ethereuma/common"
    10  )
    11  
    12  func (g *G2) one() *PointG2 {
    13  	one, _ := g.fromBytesUnchecked(
    14  		common.FromHex("" +
    15  			"13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e" +
    16  			"024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8" +
    17  			"0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be" +
    18  			"0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801",
    19  		),
    20  	)
    21  	return one
    22  }
    23  
    24  func (g *G2) rand() *PointG2 {
    25  	k, err := rand.Int(rand.Reader, q)
    26  	if err != nil {
    27  		panic(err)
    28  	}
    29  	return g.MulScalar(&PointG2{}, g.one(), k)
    30  }
    31  
    32  func TestG2Serialization(t *testing.T) {
    33  	g2 := NewG2()
    34  	for i := 0; i < fuz; i++ {
    35  		a := g2.rand()
    36  		buf := g2.ToBytes(a)
    37  		b, err := g2.FromBytes(buf)
    38  		if err != nil {
    39  			t.Fatal(err)
    40  		}
    41  		if !g2.Equal(a, b) {
    42  			t.Fatal("bad serialization from/to")
    43  		}
    44  	}
    45  	for i := 0; i < fuz; i++ {
    46  		a := g2.rand()
    47  		encoded := g2.EncodePoint(a)
    48  		b, err := g2.DecodePoint(encoded)
    49  		if err != nil {
    50  			t.Fatal(err)
    51  		}
    52  		if !g2.Equal(a, b) {
    53  			t.Fatal("bad serialization encode/decode")
    54  		}
    55  	}
    56  }
    57  
    58  func TestG2IsOnCurve(t *testing.T) {
    59  	g := NewG2()
    60  	zero := g.Zero()
    61  	if !g.IsOnCurve(zero) {
    62  		t.Fatal("zero must be on curve")
    63  	}
    64  	one := new(fe2).one()
    65  	p := &PointG2{*one, *one, *one}
    66  	if g.IsOnCurve(p) {
    67  		t.Fatal("(1, 1) is not on curve")
    68  	}
    69  }
    70  
    71  func TestG2AdditiveProperties(t *testing.T) {
    72  	g := NewG2()
    73  	t0, t1 := g.New(), g.New()
    74  	zero := g.Zero()
    75  	for i := 0; i < fuz; i++ {
    76  		a, b := g.rand(), g.rand()
    77  		_, _, _ = b, t1, zero
    78  		g.Add(t0, a, zero)
    79  		if !g.Equal(t0, a) {
    80  			t.Fatal("a + 0 == a")
    81  		}
    82  		g.Add(t0, zero, zero)
    83  		if !g.Equal(t0, zero) {
    84  			t.Fatal("0 + 0 == 0")
    85  		}
    86  		g.Sub(t0, a, zero)
    87  		if !g.Equal(t0, a) {
    88  			t.Fatal("a - 0 == a")
    89  		}
    90  		g.Sub(t0, zero, zero)
    91  		if !g.Equal(t0, zero) {
    92  			t.Fatal("0 - 0 == 0")
    93  		}
    94  		g.Neg(t0, zero)
    95  		if !g.Equal(t0, zero) {
    96  			t.Fatal("- 0 == 0")
    97  		}
    98  		g.Sub(t0, zero, a)
    99  		g.Neg(t0, t0)
   100  		if !g.Equal(t0, a) {
   101  			t.Fatal(" - (0 - a) == a")
   102  		}
   103  		g.Double(t0, zero)
   104  		if !g.Equal(t0, zero) {
   105  			t.Fatal("2 * 0 == 0")
   106  		}
   107  		g.Double(t0, a)
   108  		g.Sub(t0, t0, a)
   109  		if !g.Equal(t0, a) || !g.IsOnCurve(t0) {
   110  			t.Fatal(" (2 * a) - a == a")
   111  		}
   112  		g.Add(t0, a, b)
   113  		g.Add(t1, b, a)
   114  		if !g.Equal(t0, t1) {
   115  			t.Fatal("a + b == b + a")
   116  		}
   117  		g.Sub(t0, a, b)
   118  		g.Sub(t1, b, a)
   119  		g.Neg(t1, t1)
   120  		if !g.Equal(t0, t1) {
   121  			t.Fatal("a - b == - ( b - a )")
   122  		}
   123  		c := g.rand()
   124  		g.Add(t0, a, b)
   125  		g.Add(t0, t0, c)
   126  		g.Add(t1, a, c)
   127  		g.Add(t1, t1, b)
   128  		if !g.Equal(t0, t1) {
   129  			t.Fatal("(a + b) + c == (a + c ) + b")
   130  		}
   131  		g.Sub(t0, a, b)
   132  		g.Sub(t0, t0, c)
   133  		g.Sub(t1, a, c)
   134  		g.Sub(t1, t1, b)
   135  		if !g.Equal(t0, t1) {
   136  			t.Fatal("(a - b) - c == (a - c) -b")
   137  		}
   138  	}
   139  }
   140  
   141  func TestG2MultiplicativeProperties(t *testing.T) {
   142  	g := NewG2()
   143  	t0, t1 := g.New(), g.New()
   144  	zero := g.Zero()
   145  	for i := 0; i < fuz; i++ {
   146  		a := g.rand()
   147  		s1, s2, s3 := randScalar(q), randScalar(q), randScalar(q)
   148  		sone := big.NewInt(1)
   149  		g.MulScalar(t0, zero, s1)
   150  		if !g.Equal(t0, zero) {
   151  			t.Fatal(" 0 ^ s == 0")
   152  		}
   153  		g.MulScalar(t0, a, sone)
   154  		if !g.Equal(t0, a) {
   155  			t.Fatal(" a ^ 1 == a")
   156  		}
   157  		g.MulScalar(t0, zero, s1)
   158  		if !g.Equal(t0, zero) {
   159  			t.Fatal(" 0 ^ s == a")
   160  		}
   161  		g.MulScalar(t0, a, s1)
   162  		g.MulScalar(t0, t0, s2)
   163  		s3.Mul(s1, s2)
   164  		g.MulScalar(t1, a, s3)
   165  		if !g.Equal(t0, t1) {
   166  			t.Errorf(" (a ^ s1) ^ s2 == a ^ (s1 * s2)")
   167  		}
   168  		g.MulScalar(t0, a, s1)
   169  		g.MulScalar(t1, a, s2)
   170  		g.Add(t0, t0, t1)
   171  		s3.Add(s1, s2)
   172  		g.MulScalar(t1, a, s3)
   173  		if !g.Equal(t0, t1) {
   174  			t.Errorf(" (a ^ s1) + (a ^ s2) == a ^ (s1 + s2)")
   175  		}
   176  	}
   177  }
   178  
   179  func TestG2MultiExpExpected(t *testing.T) {
   180  	g := NewG2()
   181  	one := g.one()
   182  	var scalars [2]*big.Int
   183  	var bases [2]*PointG2
   184  	scalars[0] = big.NewInt(2)
   185  	scalars[1] = big.NewInt(3)
   186  	bases[0], bases[1] = new(PointG2).Set(one), new(PointG2).Set(one)
   187  	expected, result := g.New(), g.New()
   188  	g.MulScalar(expected, one, big.NewInt(5))
   189  	_, _ = g.MultiExp(result, bases[:], scalars[:])
   190  	if !g.Equal(expected, result) {
   191  		t.Fatal("bad multi-exponentiation")
   192  	}
   193  }
   194  
   195  func TestG2MultiExpBatch(t *testing.T) {
   196  	g := NewG2()
   197  	one := g.one()
   198  	n := 1000
   199  	bases := make([]*PointG2, n)
   200  	scalars := make([]*big.Int, n)
   201  	// scalars: [s0,s1 ... s(n-1)]
   202  	// bases: [P0,P1,..P(n-1)] = [s(n-1)*G, s(n-2)*G ... s0*G]
   203  	for i, j := 0, n-1; i < n; i, j = i+1, j-1 {
   204  		scalars[j], _ = rand.Int(rand.Reader, big.NewInt(100000))
   205  		bases[i] = g.New()
   206  		g.MulScalar(bases[i], one, scalars[j])
   207  	}
   208  	// expected: s(n-1)*P0 + s(n-2)*P1 + s0*P(n-1)
   209  	expected, tmp := g.New(), g.New()
   210  	for i := 0; i < n; i++ {
   211  		g.MulScalar(tmp, bases[i], scalars[i])
   212  		g.Add(expected, expected, tmp)
   213  	}
   214  	result := g.New()
   215  	_, _ = g.MultiExp(result, bases, scalars)
   216  	if !g.Equal(expected, result) {
   217  		t.Fatal("bad multi-exponentiation")
   218  	}
   219  }
   220  
   221  func TestG2MapToCurve(t *testing.T) {
   222  	for i, v := range []struct {
   223  		u        []byte
   224  		expected []byte
   225  	}{
   226  		{
   227  			u:        make([]byte, 96),
   228  			expected: common.FromHex("0a67d12118b5a35bb02d2e86b3ebfa7e23410db93de39fb06d7025fa95e96ffa428a7a27c3ae4dd4b40bd251ac658892" + "018320896ec9eef9d5e619848dc29ce266f413d02dd31d9b9d44ec0c79cd61f18b075ddba6d7bd20b7ff27a4b324bfce" + "04c69777a43f0bda07679d5805e63f18cf4e0e7c6112ac7f70266d199b4f76ae27c6269a3ceebdae30806e9a76aadf5c" + "0260e03644d1a2c321256b3246bad2b895cad13890cbe6f85df55106a0d334604fb143c7a042d878006271865bc35941"),
   229  		},
   230  		{
   231  			u:        common.FromHex("025fbc07711ba267b7e70c82caa70a16fbb1d470ae24ceef307f5e2000751677820b7013ad4e25492dcf30052d3e5eca" + "0e775d7827adf385b83e20e4445bd3fab21d7b4498426daf3c1d608b9d41e9edb5eda0df022e753b8bb4bc3bb7db4914"),
   232  			expected: common.FromHex("0d4333b77becbf9f9dfa3ca928002233d1ecc854b1447e5a71f751c9042d000f42db91c1d6649a5e0ad22bd7bf7398b8" + "027e4bfada0b47f9f07e04aec463c7371e68f2fd0c738cd517932ea3801a35acf09db018deda57387b0f270f7a219e4d" + "0cc76dc777ea0d447e02a41004f37a0a7b1fafb6746884e8d9fc276716ccf47e4e0899548a2ec71c2bdf1a2a50e876db" + "053674cba9ef516ddc218fedb37324e6c47de27f88ab7ef123b006127d738293c0277187f7e2f80a299a24d84ed03da7"),
   233  		},
   234  		{
   235  			u:        common.FromHex("1870a7dbfd2a1deb74015a3546b20f598041bf5d5202997956a94a368d30d3f70f18cdaa1d33ce970a4e16af961cbdcb" + "045ab31ce4b5a8ba7c4b2851b64f063a66cd1223d3c85005b78e1beee65e33c90ceef0244e45fc45a5e1d6eab6644fdb"),
   236  			expected: common.FromHex("18f0f87b40af67c056915dbaf48534c592524e82c1c2b50c3734d02c0172c80df780a60b5683759298a3303c5d942778" + "09349f1cb5b2e55489dcd45a38545343451cc30a1681c57acd4fb0a6db125f8352c09f4a67eb7d1d8242cb7d3405f97b" + "10a2ba341bc689ab947b7941ce6ef39be17acaab067bd32bd652b471ab0792c53a2bd03bdac47f96aaafe96e441f63c0" + "02f2d9deb2c7742512f5b8230bf0fd83ea42279d7d39779543c1a43b61c885982b611f6a7a24b514995e8a098496b811"),
   237  		},
   238  		{
   239  			u:        common.FromHex("088fe329b054db8a6474f21a7fbfdf17b4c18044db299d9007af582c3d5f17d00e56d99921d4b5640fce44b05219b5de" + "0b6e6135a4cd31ba980ddbd115ac48abef7ec60e226f264d7befe002c165f3a496f36f76dd524efd75d17422558d10b4"),
   240  			expected: common.FromHex("19808ec5930a53c7cf5912ccce1cc33f1b3dcff24a53ce1cc4cba41fd6996dbed4843ccdd2eaf6a0cd801e562718d163" + "149fe43777d34f0d25430dea463889bd9393bdfb4932946db23671727081c629ebb98a89604f3433fba1c67d356a4af7" + "04783e391c30c83f805ca271e353582fdf19d159f6a4c39b73acbb637a9b8ac820cfbe2738d683368a7c07ad020e3e33" + "04c0d6793a766233b2982087b5f4a254f261003ccb3262ea7c50903eecef3e871d1502c293f9e063d7d293f6384f4551"),
   241  		},
   242  		{
   243  			u:        common.FromHex("03df16a66a05e4c1188c234788f43896e0565bfb64ac49b9639e6b284cc47dad73c47bb4ea7e677db8d496beb907fbb6" + "0f45b50647d67485295aa9eb2d91a877b44813677c67c8d35b2173ff3ba95f7bd0806f9ca8a1436b8b9d14ee81da4d7e"),
   244  			expected: common.FromHex("0b8e0094c886487870372eb6264613a6a087c7eb9804fab789be4e47a57b29eb19b1983a51165a1b5eb025865e9fc63a" + "0804152cbf8474669ad7d1796ab92d7ca21f32d8bed70898a748ed4e4e0ec557069003732fc86866d938538a2ae95552" + "14c80f068ece15a3936bb00c3c883966f75b4e8d9ddde809c11f781ab92d23a2d1d103ad48f6f3bb158bf3e3a4063449" + "09e5c8242dd7281ad32c03fe4af3f19167770016255fb25ad9b67ec51d62fade31a1af101e8f6172ec2ee8857662be3a"),
   245  		},
   246  	} {
   247  		g := NewG2()
   248  		p0, err := g.MapToCurve(v.u)
   249  		if err != nil {
   250  			t.Fatal("map to curve fails", i, err)
   251  		}
   252  		if !bytes.Equal(g.ToBytes(p0), v.expected) {
   253  			t.Fatal("map to curve fails", i)
   254  		}
   255  	}
   256  }
   257  
   258  func BenchmarkG2Add(t *testing.B) {
   259  	g2 := NewG2()
   260  	a, b, c := g2.rand(), g2.rand(), PointG2{}
   261  	t.ResetTimer()
   262  	for i := 0; i < t.N; i++ {
   263  		g2.Add(&c, a, b)
   264  	}
   265  }
   266  
   267  func BenchmarkG2Mul(t *testing.B) {
   268  	g2 := NewG2()
   269  	a, e, c := g2.rand(), q, PointG2{}
   270  	t.ResetTimer()
   271  	for i := 0; i < t.N; i++ {
   272  		g2.MulScalar(&c, a, e)
   273  	}
   274  }
   275  
   276  func BenchmarkG2SWUMap(t *testing.B) {
   277  	a := make([]byte, 96)
   278  	g2 := NewG2()
   279  	t.ResetTimer()
   280  	for i := 0; i < t.N; i++ {
   281  		_, err := g2.MapToCurve(a)
   282  		if err != nil {
   283  			t.Fatal(err)
   284  		}
   285  	}
   286  }