github.com/cloudflare/circl@v1.5.0/ecc/bls12381/pair_test.go (about)

     1  package bls12381
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"testing"
     7  
     8  	"github.com/cloudflare/circl/ecc/bls12381/ff"
     9  	"github.com/cloudflare/circl/internal/test"
    10  )
    11  
    12  func TestProdPair(t *testing.T) {
    13  	const testTimes = 1 << 5
    14  	const N = 3
    15  
    16  	listG1 := [N]*G1{}
    17  	listG2 := [N]*G2{}
    18  	listSc := [N]*Scalar{}
    19  	var ePQn, got Gt
    20  
    21  	for i := 0; i < testTimes; i++ {
    22  		got.SetIdentity()
    23  		for j := 0; j < N; j++ {
    24  			listG1[j] = randomG1(t)
    25  			listG2[j] = randomG2(t)
    26  			listSc[j] = randomScalar(t)
    27  
    28  			ePQ := Pair(listG1[j], listG2[j])
    29  			ePQn.Exp(ePQ, listSc[j])
    30  			got.Mul(&got, &ePQn)
    31  		}
    32  
    33  		want := ProdPair(listG1[:], listG2[:], listSc[:])
    34  
    35  		if !got.IsEqual(want) {
    36  			test.ReportError(t, got, want)
    37  		}
    38  	}
    39  }
    40  
    41  func TestProdPairFrac(t *testing.T) {
    42  	const testTimes = 1 << 5
    43  	const N = 5
    44  
    45  	listG1 := [N]*G1{}
    46  	listG2 := [N]*G2{}
    47  	listSc := [N]*Scalar{}
    48  	listSigns := [N]int{}
    49  	var ePQn, got Gt
    50  
    51  	for i := 0; i < testTimes; i++ {
    52  		got.SetIdentity()
    53  		for j := 0; j < N; j++ {
    54  			listG1[j] = randomG1(t)
    55  			listG2[j] = randomG2(t)
    56  			listSc[j] = &Scalar{}
    57  			coin := rand.Int31n(2) //nolint
    58  			switch coin {
    59  			case 0:
    60  				listSc[j].SetOne()
    61  				listSc[j].Neg()
    62  				listSigns[j] = -1
    63  
    64  			case 1:
    65  				listSc[j].SetOne()
    66  				listSigns[j] = 1
    67  			}
    68  
    69  			ePQ := Pair(listG1[j], listG2[j])
    70  			ePQn.Exp(ePQ, listSc[j])
    71  			got.Mul(&got, &ePQn)
    72  		}
    73  
    74  		want := ProdPairFrac(listG1[:], listG2[:], listSigns[:])
    75  
    76  		if !got.IsEqual(want) {
    77  			test.ReportError(t, got, want)
    78  		}
    79  	}
    80  }
    81  
    82  func TestInputs(t *testing.T) {
    83  	t.Run("Pair", func(t *testing.T) {
    84  		P := *randomG1(t)
    85  		Q := *randomG2(t)
    86  		oldP := P
    87  		oldQ := Q
    88  		_ = Pair(&P, &Q)
    89  		test.CheckOk(P == oldP, "the point P was overwritten", t)
    90  		test.CheckOk(Q == oldQ, "the point Q was overwritten", t)
    91  	})
    92  
    93  	t.Run("ProdPair", func(t *testing.T) {
    94  		P0, P1 := *randomG1(t), *randomG1(t)
    95  		Q0, Q1 := *randomG2(t), *randomG2(t)
    96  		n0, n1 := *randomScalar(t), *randomScalar(t)
    97  
    98  		oldP0, oldP1 := P0, P1
    99  		oldQ0, oldQ1 := Q0, Q1
   100  		oldn0, oldn1 := n0, n1
   101  
   102  		_ = ProdPair([]*G1{&P0, &P1}, []*G2{&Q0, &Q1}, []*Scalar{&n0, &n1})
   103  
   104  		test.CheckOk(P0 == oldP0, "the point P0 was overwritten", t)
   105  		test.CheckOk(P1 == oldP1, "the point P1 was overwritten", t)
   106  		test.CheckOk(Q0 == oldQ0, "the point Q0 was overwritten", t)
   107  		test.CheckOk(Q1 == oldQ1, "the point Q1 was overwritten", t)
   108  		test.CheckOk(n0 == oldn0, "the scalar n0 was overwritten", t)
   109  		test.CheckOk(n1 == oldn1, "the scalar n1 was overwritten", t)
   110  	})
   111  
   112  	t.Run("ProdPairFrac", func(t *testing.T) {
   113  		P0, P1 := *randomG1(t), *randomG1(t)
   114  		Q0, Q1 := *randomG2(t), *randomG2(t)
   115  
   116  		oldP0, oldP1 := P0, P1
   117  		oldQ0, oldQ1 := Q0, Q1
   118  
   119  		_ = ProdPairFrac([]*G1{&P0, &P1}, []*G2{&Q0, &Q1}, []int{1, -1})
   120  
   121  		test.CheckOk(P0 == oldP0, "the point P0 was overwritten", t)
   122  		test.CheckOk(P1 == oldP1, "the point P1 was overwritten", t)
   123  		test.CheckOk(Q0 == oldQ0, "the point Q0 was overwritten", t)
   124  		test.CheckOk(Q1 == oldQ1, "the point Q1 was overwritten", t)
   125  	})
   126  }
   127  
   128  func TestPairBilinear(t *testing.T) {
   129  	testTimes := 1 << 5
   130  	for i := 0; i < testTimes; i++ {
   131  		g1 := G1Generator()
   132  		g2 := G2Generator()
   133  		a := randomScalar(t)
   134  		b := randomScalar(t)
   135  
   136  		ab := &Scalar{}
   137  		ab.Mul(a, b)
   138  		p := &G1{}
   139  		q := &G2{}
   140  		p.ScalarMult(a, g1)
   141  		q.ScalarMult(b, g2)
   142  		lhs := Pair(p, q)
   143  		tmp := Pair(g1, g2)
   144  		rhs := &Gt{}
   145  		rhs.Exp(tmp, ab)
   146  		if !lhs.IsEqual(rhs) {
   147  			test.ReportError(t, lhs, rhs)
   148  		}
   149  	}
   150  }
   151  
   152  func TestPairIdentity(t *testing.T) {
   153  	g1id := &G1{}
   154  	g2id := &G2{}
   155  	g1 := G1Generator()
   156  	g2 := G2Generator()
   157  	g1id.SetIdentity()
   158  	g2id.SetIdentity()
   159  	one := &Gt{}
   160  	one.SetIdentity()
   161  	ans := Pair(g1id, g2)
   162  	if !ans.IsEqual(one) {
   163  		test.ReportError(t, ans, one)
   164  	}
   165  	ans = Pair(g1, g2id)
   166  	if !ans.IsEqual(one) {
   167  		test.ReportError(t, ans, one)
   168  	}
   169  }
   170  
   171  func BenchmarkMiller(b *testing.B) {
   172  	g1 := G1Generator()
   173  	g2 := G2Generator()
   174  	mi := new(ff.Fp12)
   175  	b.ResetTimer()
   176  	for i := 0; i < b.N; i++ {
   177  		miller(mi, g1, g2)
   178  	}
   179  }
   180  
   181  func BenchmarkFinalExpo(b *testing.B) {
   182  	g1 := G1Generator()
   183  	g2 := G2Generator()
   184  	mi := new(ff.Fp12)
   185  	miller(mi, g1, g2)
   186  	c := &ff.Cyclo6{}
   187  	u := &ff.URoot{}
   188  	g := &Gt{}
   189  
   190  	ff.EasyExponentiation(c, mi)
   191  
   192  	b.Run("EasyExp", func(b *testing.B) {
   193  		for i := 0; i < b.N; i++ {
   194  			ff.EasyExponentiation(c, mi)
   195  		}
   196  	})
   197  	b.Run("HardExp", func(b *testing.B) {
   198  		for i := 0; i < b.N; i++ {
   199  			ff.HardExponentiation(u, c)
   200  		}
   201  	})
   202  	b.Run("FinalExp", func(b *testing.B) {
   203  		for i := 0; i < b.N; i++ {
   204  			finalExp(g, mi)
   205  		}
   206  	})
   207  }
   208  
   209  func BenchmarkPair(b *testing.B) {
   210  	g1 := G1Generator()
   211  	g2 := G2Generator()
   212  
   213  	const N = 3
   214  	listG1 := [N]*G1{}
   215  	listG2 := [N]*G2{}
   216  	listExp := [N]*Scalar{}
   217  	for i := 0; i < N; i++ {
   218  		listG1[i] = new(G1)
   219  		*listG1[i] = *g1
   220  		listG2[i] = new(G2)
   221  		*listG2[i] = *g2
   222  		listExp[i] = randomScalar(b)
   223  	}
   224  
   225  	b.Run("Pair", func(b *testing.B) {
   226  		for i := 0; i < b.N; i++ {
   227  			Pair(g1, g2)
   228  		}
   229  	})
   230  	b.Run(fmt.Sprintf("ProdPair%v", N), func(b *testing.B) {
   231  		for i := 0; i < b.N; i++ {
   232  			ProdPair(listG1[:], listG2[:], listExp[:])
   233  		}
   234  	})
   235  }