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 }