github.com/emmansun/gmsm@v0.29.1/sm9/bn256/gfp12_test.go (about)

     1  package bn256
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  )
     7  
     8  var testdataP4 = gfP4{
     9  	gfP2{
    10  		*fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")),
    11  		*fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")),
    12  	},
    13  	gfP2{
    14  		*fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")),
    15  		*fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")),
    16  	},
    17  }
    18  
    19  func TestGfp12BasicOperations(t *testing.T) {
    20  	x := &gfP12{
    21  		testdataP4,
    22  		testdataP4,
    23  		*(&gfP4{}).SetOne(),
    24  	}
    25  	y := &gfP12{
    26  		testdataP4,
    27  		testdataP4,
    28  		*(&gfP4{}).SetZero(),
    29  	}
    30  
    31  	t.Parallel()
    32  	t.Run("Add", func(t *testing.T) {
    33  		expectedAdd := "(((6a6225e56e1acd7c5ae45b0f1b63733de799936987c8f38dd16bcddc6b500bcf, 0db9e03175ebe2b21be74db56d03e143dbd835729d7291fa6694b22536746fa1), (4d8891878c3113b4665011d7b24f278d4c1b54a22ec093840a00c030b5c239f9, 21092bc181ec5d9c488aac3c5feef9b725f7568b42b4794f807e271f22e38494)), ((6a6225e56e1acd7c5ae45b0f1b63733de799936987c8f38dd16bcddc6b500bcf, 0db9e03175ebe2b21be74db56d03e143dbd835729d7291fa6694b22536746fa1), (4d8891878c3113b4665011d7b24f278d4c1b54a22ec093840a00c030b5c239f9, 21092bc181ec5d9c488aac3c5feef9b725f7568b42b4794f807e271f22e38494)), ((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 49bffffffd5c590e29fc54b00a7138bade0d6cb4e58511241a9064d81caeba83)))"
    34  		got := &gfP12{}
    35  		got.Set(x)
    36  		got.Add(got, y)
    37  
    38  		if got.String() != expectedAdd {
    39  			t.Errorf("got %v, expected %v", got, expectedAdd)
    40  		}
    41  	})
    42  
    43  	t.Run("Sub", func(t *testing.T) {
    44  		expectedSub := "(((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000)), ((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000)), ((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 49bffffffd5c590e29fc54b00a7138bade0d6cb4e58511241a9064d81caeba83)))"
    45  		got := &gfP12{}
    46  		got.Set(x)
    47  		got.Sub(got, y)
    48  
    49  		if got.String() != expectedSub {
    50  			t.Errorf("got %v, expected %v", got, expectedSub)
    51  		}
    52  	})
    53  
    54  	t.Run("Mul", func(t *testing.T) {
    55  		expectedMul := "(((2302538ca37ab5cf8c253b56ece9734f92e31f026e5bea5f178828769a8e2322, 96fe2ddc0dda2779d93b9d8560eebd91bb61e659c81a9936dac9a2bcc3f8ab86), (2c371ba768b6f660eaba367b2c444295e529efc2a5ad95d8f80265235ad4c6c9, 4f24d79c798eb4d8c2005bf43cb955f5420baf40650c750f4f0f1c0a11882a1c)), ((3aa3e5d659abd344e5045b16e0ce686e32e90f265231c5dddbb7ebf9359bafb4, a09d31d474e04adc96b08258be0b2d5e2df568599fa8f8d2b4d22f210cf94261), (00a5868716591909286c54468e0599715190e2a67646ab1fc7100e9aa04e4b35, 34e214ace81b90ab66df3a7f7188097a54cf00aa4c6b5b77629a907ec7a587d5)), ((0ae5a5c7453cd90d6f245b1ea6395d9e7e388ae31c9a982de6040a15ffe75399, 7d40837771310c153b760bac1983b2335e2007f5876470cf1da010f5002ccfa4), (6a027b86a324c54fc08c42055f4ad29a78f903f5d847b197698ef82c6e2ba1ee, 48bafd984e4ac3ba8533c8c28321193d83a6aac956223d9f44b6f9de6c678b16)))"
    56  		got := &gfP12{}
    57  		got.Set(x)
    58  		got.Mul(got, y)
    59  
    60  		if got.String() != expectedMul {
    61  			t.Errorf("got %v, expected %v", got, expectedMul)
    62  		}
    63  	})
    64  
    65  	t.Run("Square", func(t *testing.T) {
    66  		got := &gfP12{}
    67  		got.Set(x)
    68  		got.Square(got)
    69  
    70  		expected := (&gfP12{}).Mul(x, x)
    71  
    72  		if *expected != *got {
    73  			t.Errorf("got %v, expected %v", got, expected)
    74  		}
    75  	})
    76  }
    77  
    78  func TestGfp12Order(t *testing.T) {
    79  	in := &gfP12{
    80  		testdataP4,
    81  		testdataP4,
    82  		*(&gfP4{}).SetOne(),
    83  	}
    84  
    85  	p6 := (&gfP12{}).FrobeniusP6(in)
    86  	p12 := (&gfP12{}).FrobeniusP6(p6)
    87  	if *p12 != *in {
    88  		t.Errorf("in^(p^12) not equal with in")
    89  	}
    90  
    91  	p2 := (&gfP12{}).FrobeniusP2(in)
    92  	p4 := (&gfP12{}).FrobeniusP2(p2)
    93  	p6_1 := (&gfP12{}).FrobeniusP2(p4)
    94  	p8 := (&gfP12{}).FrobeniusP2(p6_1)
    95  	p10 := (&gfP12{}).FrobeniusP2(p8)
    96  	p12_1 := (&gfP12{}).FrobeniusP2(p10)
    97  	if *p12_1 != *in {
    98  		t.Errorf("in^(p^12) not equal with in")
    99  	}
   100  
   101  	p3 := (&gfP12{}).FrobeniusP3(in)
   102  	p6_2 := (&gfP12{}).FrobeniusP3(p3)
   103  	p9 := (&gfP12{}).FrobeniusP3(p6_2)
   104  	p12_2 := (&gfP12{}).FrobeniusP3(p9)
   105  	if *p12_2 != *in {
   106  		t.Errorf("in^(p^12) not equal with in")
   107  	}
   108  }
   109  
   110  func TestCyclo6Square(t *testing.T) {
   111  	in := &gfP12{
   112  		testdataP4,
   113  		testdataP4,
   114  		*(&gfP4{}).SetOne(),
   115  	}
   116  
   117  	// This is the p^6-Frobenius
   118  	t1 := (&gfP12{}).FrobeniusP6(in)
   119  
   120  	inv := (&gfP12{}).Invert(in)
   121  	t1.Mul(t1, inv)
   122  
   123  	t2 := inv.FrobeniusP2(t1) // reuse inv
   124  	t1.Mul(t1, t2)            // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation
   125  
   126  	one := (&gfP12{}).SetOne()
   127  	t3 := (&gfP12{}).FrobeniusP2(t1)
   128  	t4 := (&gfP12{}).FrobeniusP2(t3)
   129  	t5 := (&gfP12{}).Invert(t3)
   130  	t5.Mul(t4, t5).Mul(t1, t5)
   131  	if *t5 != *one {
   132  		t.Errorf("t1 should be in Cyclotomic Subgroup")
   133  	}
   134  
   135  	got := &gfP12{}
   136  	expected := &gfP12{}
   137  	got.Cyclo6Square(t1)
   138  	expected.Square(t1)
   139  	if *got != *expected {
   140  		t.Errorf("not same got=%v, expected=%v", got, expected)
   141  	}
   142  }
   143  
   144  func BenchmarkGfP12Square(b *testing.B) {
   145  	x := &gfP12{
   146  		testdataP4,
   147  		testdataP4,
   148  		*(&gfP4{}).SetOne(),
   149  	}
   150  	x2 := &gfP12{}
   151  	b.ReportAllocs()
   152  	b.ResetTimer()
   153  	for i := 0; i < b.N; i++ {
   154  		x2.Square(x)
   155  	}
   156  }
   157  
   158  func BenchmarkGfP12Cyclo6Square(b *testing.B) {
   159  	in := &gfP12{
   160  		testdataP4,
   161  		testdataP4,
   162  		*(&gfP4{}).SetOne(),
   163  	}
   164  
   165  	// This is the p^6-Frobenius
   166  	t1 := (&gfP12{}).FrobeniusP6(in)
   167  
   168  	inv := (&gfP12{}).Invert(in)
   169  	t1.Mul(t1, inv)
   170  
   171  	t2 := inv.FrobeniusP2(t1) // reuse inv
   172  	t1.Mul(t1, t2)            // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation
   173  	x2 := &gfP12{}
   174  	b.ReportAllocs()
   175  	b.ResetTimer()
   176  	for i := 0; i < b.N; i++ {
   177  		x2.Cyclo6Square(t1)
   178  	}
   179  }
   180  
   181  func BenchmarkGfP12SpecialSqures(b *testing.B) {
   182  	in := &gfP12{
   183  		testdataP4,
   184  		testdataP4,
   185  		*(&gfP4{}).SetOne(),
   186  	}
   187  
   188  	// This is the p^6-Frobenius
   189  	t1 := (&gfP12{}).FrobeniusP6(in)
   190  
   191  	inv := (&gfP12{}).Invert(in)
   192  	t1.Mul(t1, inv)
   193  
   194  	t2 := inv.FrobeniusP2(t1) // reuse inv
   195  	t1.Mul(t1, t2)            // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation
   196  	got := &gfP12{}
   197  	b.ReportAllocs()
   198  	b.ResetTimer()
   199  	for i := 0; i < b.N; i++ {
   200  		got.Cyclo6Squares(in, 61)
   201  	}
   202  }
   203  
   204  func testGfP12Invert(t *testing.T, x *gfP12) {
   205  	xInv := &gfP12{}
   206  	xInv.Invert(x)
   207  
   208  	y := &gfP12{}
   209  	y.Mul(x, xInv)
   210  	if !y.IsOne() {
   211  		t.Fail()
   212  	}
   213  }
   214  
   215  func Test_gfP12Invert(t *testing.T) {
   216  	x := &gfP12{
   217  		testdataP4,
   218  		testdataP4,
   219  		*(&gfP4{}).SetOne(),
   220  	}
   221  	testGfP12Invert(t, x)
   222  	x = &gfP12{
   223  		testdataP4,
   224  		testdataP4,
   225  		*(&gfP4{}).SetZero(),
   226  	}
   227  	testGfP12Invert(t, x)
   228  	x = &gfP12{
   229  		testdataP4,
   230  		testdataP4,
   231  		testdataP4,
   232  	}
   233  	testGfP12Invert(t, x)
   234  }
   235  
   236  // Generate wToPMinus1
   237  func Test_gfP12Frobenius_Case1(t *testing.T) {
   238  	expected := &gfP12{}
   239  	i := &gfP12{}
   240  	i.SetW()
   241  	pMinus1 := new(big.Int).Sub(p, big.NewInt(1))
   242  	i.Exp(i, pMinus1)
   243  	i = gfP12Decode(i)
   244  	expected.z.x.SetZero()
   245  	expected.z.y.x.Set(zero)
   246  	expected.z.y.y.Set(fromBigInt(bigFromHex("3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698b")))
   247  	expected.x.SetZero()
   248  	expected.y.SetZero()
   249  	expected = gfP12Decode(expected)
   250  	if expected.x != i.x || expected.y != i.y || expected.z != i.z {
   251  		t.Errorf("got %v, expected %v", i, expected)
   252  	}
   253  }
   254  
   255  // Generate w2ToPMinus1
   256  func Test_gfP12Frobenius_Case2(t *testing.T) {
   257  	expected := &gfP12{}
   258  	i := &gfP12{}
   259  	i.SetW2()
   260  	pMinus1 := new(big.Int).Sub(p, big.NewInt(1))
   261  	i.Exp(i, pMinus1)
   262  	i = gfP12Decode(i)
   263  	expected.z.x.SetZero()
   264  	expected.z.y.x.Set(zero)
   265  	expected.z.y.y.Set(fromBigInt(bigFromHex("0000000000000000f300000002a3a6f2780272354f8b78f4d5fc11967be65334")))
   266  	expected.x.SetZero()
   267  	expected.y.SetZero()
   268  	expected = gfP12Decode(expected)
   269  	if expected.x != i.x || expected.y != i.y || expected.z != i.z {
   270  		t.Errorf("got %v, expected %v", i, expected)
   271  	}
   272  }
   273  
   274  // Generate wToP2Minus1
   275  func Test_gfP12FrobeniusP2_Case1(t *testing.T) {
   276  	expected := &gfP12{}
   277  	i := &gfP12{}
   278  	i.SetW()
   279  	p2 := new(big.Int).Mul(p, p)
   280  	p2 = new(big.Int).Sub(p2, big.NewInt(1))
   281  	i.Exp(i, p2)
   282  	i = gfP12Decode(i)
   283  	expected.z.x.SetZero()
   284  	expected.z.y.x.Set(zero)
   285  	expected.z.y.y.Set(fromBigInt(bigFromHex("0000000000000000f300000002a3a6f2780272354f8b78f4d5fc11967be65334")))
   286  	expected.x.SetZero()
   287  	expected.y.SetZero()
   288  	expected = gfP12Decode(expected)
   289  	if expected.x != i.x || expected.y != i.y || expected.z != i.z {
   290  		t.Errorf("got %v, expected %v", i, expected)
   291  	}
   292  }
   293  
   294  // Generate w2ToP2Minus1
   295  func Test_gfP12FrobeniusP2_Case2(t *testing.T) {
   296  	expected := &gfP12{}
   297  	i := &gfP12{}
   298  	i.SetW2()
   299  	p2 := new(big.Int).Mul(p, p)
   300  	p2 = new(big.Int).Sub(p2, big.NewInt(1))
   301  	i.Exp(i, p2)
   302  	i = gfP12Decode(i)
   303  	expected.z.x.SetZero()
   304  	expected.z.y.x.Set(zero)
   305  	expected.z.y.y.Set(fromBigInt(bigFromHex("0000000000000000f300000002a3a6f2780272354f8b78f4d5fc11967be65333")))
   306  	expected.x.SetZero()
   307  	expected.y.SetZero()
   308  	expected = gfP12Decode(expected)
   309  	if expected.x != i.x || expected.y != i.y || expected.z != i.z {
   310  		t.Errorf("got %v, expected %v", i, expected)
   311  	}
   312  }
   313  
   314  // Generate wToP3Minus1
   315  func Test_gfP12FrobeniusP3_Case1(t *testing.T) {
   316  	expected := &gfP12{}
   317  	i := &gfP12{}
   318  	i.SetW()
   319  	p3 := new(big.Int).Mul(p, p)
   320  	p3.Mul(p3, p)
   321  	p3 = new(big.Int).Sub(p3, big.NewInt(1))
   322  	i.Exp(i, p3)
   323  	i = gfP12Decode(i)
   324  	expected.z.x.SetZero()
   325  	expected.z.y.x.Set(zero)
   326  	expected.z.y.y.Set(fromBigInt(bigFromHex("6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011")))
   327  	expected.x.SetZero()
   328  	expected.y.SetZero()
   329  	expected = gfP12Decode(expected)
   330  	if expected.x != i.x || expected.y != i.y || expected.z != i.z {
   331  		t.Errorf("got %v, expected %v", i, expected)
   332  	}
   333  }
   334  
   335  // Generate w2ToP3minus1
   336  func Test_gfP12FrobeniusP3_Case2(t *testing.T) {
   337  	expected := &gfP12{}
   338  	i := &gfP12{}
   339  	i.SetW2()
   340  	p3 := new(big.Int).Mul(p, p)
   341  	p3.Mul(p3, p)
   342  	p3 = new(big.Int).Sub(p3, big.NewInt(1))
   343  	i.Exp(i, p3)
   344  	i = gfP12Decode(i)
   345  	expected.z.x.SetZero()
   346  	expected.z.y.x.Set(zero)
   347  	expected.z.y.y.Set(fromBigInt(bigFromHex("b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457c"))) // -1
   348  	expected.x.SetZero()
   349  	expected.y.SetZero()
   350  	expected = gfP12Decode(expected)
   351  	if expected.x != i.x || expected.y != i.y || expected.z != i.z {
   352  		t.Errorf("got %v, expected %v", i, expected)
   353  	}
   354  }
   355  
   356  func Test_gfP12Frobenius(t *testing.T) {
   357  	x := &gfP12{
   358  		testdataP4,
   359  		testdataP4,
   360  		testdataP4,
   361  	}
   362  	expected := &gfP12{}
   363  	expected.Exp(x, p)
   364  	got := &gfP12{}
   365  	got.Frobenius(x)
   366  	if expected.x != got.x || expected.y != got.y || expected.z != got.z {
   367  		t.Errorf("got %v, expected %v", got, expected)
   368  	}
   369  }
   370  
   371  func Test_gfP12FrobeniusP2(t *testing.T) {
   372  	x := &gfP12{
   373  		testdataP4,
   374  		testdataP4,
   375  		testdataP4,
   376  	}
   377  	expected := &gfP12{}
   378  	p2 := new(big.Int).Mul(p, p)
   379  	expected.Exp(x, p2)
   380  	got := &gfP12{}
   381  	got.FrobeniusP2(x)
   382  	if expected.x != got.x || expected.y != got.y || expected.z != got.z {
   383  		t.Errorf("got %v, expected %v", got, expected)
   384  	}
   385  }
   386  
   387  func Test_gfP12FrobeniusP3(t *testing.T) {
   388  	x := &gfP12{
   389  		testdataP4,
   390  		testdataP4,
   391  		testdataP4,
   392  	}
   393  	expected := &gfP12{}
   394  	p3 := new(big.Int).Mul(p, p)
   395  	p3.Mul(p3, p)
   396  	expected.Exp(x, p3)
   397  	got := &gfP12{}
   398  	got.FrobeniusP3(x)
   399  	if expected.x != got.x || expected.y != got.y || expected.z != got.z {
   400  		t.Errorf("got %v, expected %v", got, expected)
   401  	}
   402  }
   403  
   404  func Test_gfP12FrobeniusP6(t *testing.T) {
   405  	x := &gfP12{
   406  		testdataP4,
   407  		testdataP4,
   408  		testdataP4,
   409  	}
   410  	expected := &gfP12{}
   411  	p6 := new(big.Int).Mul(p, p)
   412  	p6.Mul(p6, p)
   413  	p6.Mul(p6, p6)
   414  	expected.Exp(x, p6)
   415  	got := &gfP12{}
   416  	got.FrobeniusP6(x)
   417  	if expected.x != got.x || expected.y != got.y || expected.z != got.z {
   418  		t.Errorf("got %v, expected %v", got, expected)
   419  	}
   420  }
   421  
   422  func Test_W3(t *testing.T) {
   423  	w1 := (&gfP12{}).SetW()
   424  	w2 := (&gfP12{}).SetW2()
   425  
   426  	w1.Mul(w2, w1)
   427  	w1 = gfP12Decode(w1)
   428  	gfp4zero := (&gfP4{}).SetZero()
   429  	gfp4v := (&gfP4{}).SetV()
   430  	gfp4v = gfP4Decode(gfp4v)
   431  	if w1.x != *gfp4zero || w1.y != *gfp4zero || w1.z != *gfp4v {
   432  		t.Errorf("not expected")
   433  	}
   434  }
   435  
   436  func BenchmarkGfP12Invert(b *testing.B) {
   437  	x := &gfP12{
   438  		testdataP4,
   439  		testdataP4,
   440  		testdataP4,
   441  	}
   442  	got := &gfP12{}
   443  	b.ReportAllocs()
   444  	b.ResetTimer()
   445  	for i := 0; i < b.N; i++ {
   446  		got.Invert(x)
   447  	}
   448  }
   449  
   450  func BenchmarkGfP12Frobenius(b *testing.B) {
   451  	x := &gfP12{
   452  		testdataP4,
   453  		testdataP4,
   454  		testdataP4,
   455  	}
   456  	expected := &gfP12{}
   457  	expected.Exp(x, p)
   458  	got := &gfP12{}
   459  	b.ReportAllocs()
   460  	b.ResetTimer()
   461  	for i := 0; i < b.N; i++ {
   462  		got.Frobenius(x)
   463  		if *expected != *got {
   464  			b.Errorf("got %v, expected %v", got, expected)
   465  		}
   466  	}
   467  }
   468  
   469  func BenchmarkGfP12Mul(b *testing.B) {
   470  	x := &gfP12{
   471  		testdataP4,
   472  		testdataP4,
   473  		testdataP4,
   474  	}
   475  	got := &gfP12{}
   476  	b.ReportAllocs()
   477  	b.ResetTimer()
   478  	for i := 0; i < b.N; i++ {
   479  		got.Mul(x, x)
   480  	}
   481  }
   482  
   483  func BenchmarkGfP12Squre(b *testing.B) {
   484  	x := &gfP12{
   485  		testdataP4,
   486  		testdataP4,
   487  		testdataP4,
   488  	}
   489  	got := &gfP12{}
   490  	b.ReportAllocs()
   491  	b.ResetTimer()
   492  	for i := 0; i < b.N; i++ {
   493  		got.Square(x)
   494  	}
   495  }
   496  
   497  func BenchmarkGfP12Squres(b *testing.B) {
   498  	x := &gfP12{
   499  		testdataP4,
   500  		testdataP4,
   501  		testdataP4,
   502  	}
   503  	got := &gfP12{}
   504  	b.ReportAllocs()
   505  	b.ResetTimer()
   506  	for i := 0; i < b.N; i++ {
   507  		got.Squares(x, 61)
   508  	}
   509  }
   510  
   511  func BenchmarkGfP12ExpU(b *testing.B) {
   512  	x := &gfP12{
   513  		testdataP4,
   514  		testdataP4,
   515  		testdataP4,
   516  	}
   517  	// This is the p^6-Frobenius
   518  	t1 := (&gfP12{}).FrobeniusP6(x)
   519  
   520  	inv := (&gfP12{}).Invert(x)
   521  	t1.Mul(t1, inv)
   522  
   523  	t2 := inv.FrobeniusP2(t1) // reuse inv
   524  	t1.Mul(t1, t2)            // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation
   525  
   526  	got := &gfP12{}
   527  	b.ReportAllocs()
   528  	b.ResetTimer()
   529  	for i := 0; i < b.N; i++ {
   530  		got.Cyclo6PowToU(t1)
   531  		got.Cyclo6PowToU(t1)
   532  		got.Cyclo6PowToU(t1)
   533  	}
   534  }
   535  
   536  func BenchmarkGfP12ExpU2(b *testing.B) {
   537  	x := &gfP12{
   538  		testdataP4,
   539  		testdataP4,
   540  		testdataP4,
   541  	}
   542  	got := &gfP12{}
   543  	b.ReportAllocs()
   544  	b.ResetTimer()
   545  	for i := 0; i < b.N; i++ {
   546  		got.Exp(x, u)
   547  		got.Exp(x, u)
   548  		got.Exp(x, u)
   549  	}
   550  }