...
1 package bls12381
2
3 import "github.com/cloudflare/circl/ecc/bls12381/ff"
4
5
6 func Pair(P *G1, Q *G2) *Gt {
7 P.toAffine()
8 mi := &ff.Fp12{}
9 miller(mi, P, Q)
10 e := &Gt{}
11 finalExp(e, mi)
12 return e
13 }
14
15 func miller(f *ff.Fp12, P *G1, Q *G2) {
16 g := &ff.LineValue{}
17 acc := &ff.Fp12Cubic{}
18 acc.SetOne()
19 T := &G2{}
20 *T = *Q
21 l := &line{}
22 const lenX = 64
23 for i := lenX - 2; i >= 0; i-- {
24 acc.Sqr(acc)
25 doubleAndLine(T, l)
26 evalLine(g, l, P)
27 acc.MulLine(acc, g)
28
29 if (i == 62) || (i == 60) || (i == 57) || (i == 48) || (i == 16) {
30 addAndLine(T, T, Q, l)
31 evalLine(g, l, P)
32 acc.MulLine(acc, g)
33 }
34 }
35 f.FromFp12Alt(acc)
36 f.Cjg()
37 }
38
39
40
41
42
43 type line [3]ff.Fp2
44
45
46
47 func evalLine(f *ff.LineValue, l *line, P *G1) {
48
49
50
51
52
53
54
55
56 var xP, yP ff.Fp2
57 xP[0] = P.x
58 yP[0] = P.y
59 f[1].Mul(&l[0], &xP)
60 f[2].Mul(&l[1], &yP)
61 f[0] = l[2]
62
63 if f.IsZero() == 1 {
64 f.SetOne()
65 }
66 }
67
68 func finalExp(g *Gt, f *ff.Fp12) {
69 c := &ff.Cyclo6{}
70 ff.EasyExponentiation(c, f)
71 ff.HardExponentiation(&g.i, c)
72 }
73
74
75 func ProdPair(P []*G1, Q []*G2, n []*Scalar) *Gt {
76 if len(P) != len(Q) || len(P) != len(n) {
77 panic("mismatch length of inputs")
78 }
79
80 ei := new(ff.Fp12)
81 mi := new(ff.Fp12)
82 out := new(ff.Fp12)
83 out.SetOne()
84
85 affinize(P)
86 for i := range P {
87 miller(mi, P[i], Q[i])
88 nb, _ := n[i].MarshalBinary()
89 ei.Exp(mi, nb)
90 out.Mul(out, ei)
91 }
92
93 e := &Gt{}
94 finalExp(e, out)
95 return e
96 }
97
98
99 func ProdPairFrac(P []*G1, Q []*G2, signs []int) *Gt {
100 if len(P) != len(Q) || len(P) != len(signs) {
101 panic("mismatch length of inputs")
102 }
103
104 mi := new(ff.Fp12)
105 out := new(ff.Fp12)
106 out.SetOne()
107
108 affinize(P)
109 for i := range P {
110 g := *P[i]
111 if signs[i] == -1 {
112 g.Neg()
113 }
114 miller(mi, &g, Q[i])
115 out.Mul(mi, out)
116 }
117
118 e := &Gt{}
119 finalExp(e, out)
120 return e
121 }
122
View as plain text