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

     1  package ff
     2  
     3  // Cyclo6 represents an element of the 6th cyclotomic group.
     4  type Cyclo6 Fp12
     5  
     6  func (z Cyclo6) String() string           { return (Fp12)(z).String() }
     7  func (z Cyclo6) IsEqual(x *Cyclo6) int    { return (Fp12)(z).IsEqual((*Fp12)(x)) }
     8  func (z Cyclo6) IsIdentity() int          { i := &Fp12{}; i.SetOne(); return z.IsEqual((*Cyclo6)(i)) }
     9  func (z *Cyclo6) Frob(x *Cyclo6)          { (*Fp12)(z).Frob((*Fp12)(x)) }
    10  func (z *Cyclo6) Mul(x, y *Cyclo6)        { (*Fp12)(z).Mul((*Fp12)(x), (*Fp12)(y)) }
    11  func (z *Cyclo6) Inv(x *Cyclo6)           { *z = *x; z[1].Neg() }
    12  func (z *Cyclo6) exp(x *Cyclo6, n []byte) { (*Fp12)(z).Exp((*Fp12)(x), n) }
    13  func (z *Cyclo6) Sqr(x *Cyclo6) {
    14  	// Method of Granger-Scott.
    15  	// Page 7 of "Faster Squaring in the Cyclotomic Subgroup of Sixth Degree Extensions"
    16  	// https://www.iacr.org/archive/pkc2010/60560212/60560212.pdf
    17  	var xx, zz Fp12Cubic
    18  	xx.FromFp12((*Fp12)(x))
    19  
    20  	a, b, c := &xx[0], &xx[1], &xx[2]
    21  	z0, z1, z2 := &zz[0], &zz[1], &zz[2]
    22  
    23  	var aa, bb, cc, tt Fp4
    24  	aa.Sqr(a)
    25  	bb.Sqr(b)
    26  	cc.Sqr(c)
    27  	cc.mulT(&cc)
    28  
    29  	z0.Add(&aa, &aa)
    30  	z0.Add(z0, &aa)
    31  	tt.Add(a, a)
    32  	tt.Cjg()
    33  	z0.Sub(z0, &tt)
    34  
    35  	z1.Add(&cc, &cc)
    36  	z1.Add(z1, &cc)
    37  	tt.Add(b, b)
    38  	tt.Cjg()
    39  	z1.Add(z1, &tt)
    40  
    41  	z2.Add(&bb, &bb)
    42  	z2.Add(z2, &bb)
    43  	tt.Add(c, c)
    44  	tt.Cjg()
    45  	z2.Sub(z2, &tt)
    46  
    47  	(*Fp12)(z).FromFp12Cubic(&zz)
    48  }
    49  
    50  // PowToX computes z = x^paramX, where paramX is the parameter of the BLS curve.
    51  func (z *Cyclo6) PowToX(x *Cyclo6) {
    52  	t := new(Cyclo6)
    53  	*t = *x
    54  	const lenX = 64
    55  	for i := lenX - 2; i >= 0; i-- {
    56  		t.Sqr(t)
    57  		// paramX is -2 ^ 63 - 2 ^ 62 - 2 ^ 60 - 2 ^ 57 - 2 ^ 48 - 2 ^ 16
    58  		if (i == 62) || (i == 60) || (i == 57) || (i == 48) || (i == 16) {
    59  			t.Mul(t, x)
    60  		}
    61  	}
    62  	z.Inv(t)
    63  }
    64  
    65  // EasyExponentiation calculates g = f^(p^6-1)(p^2+1), where g becomes an
    66  // element of the 6-th cyclotomic group.
    67  func EasyExponentiation(g *Cyclo6, f *Fp12) {
    68  	var t0, t1, p Fp12
    69  	p.Frob(f)        // p = f^(p)
    70  	p.Frob(&p)       // p = f^(p^2)
    71  	t0.Mul(&p, f)    // t0 = f^(p^2 + 1)
    72  	t1.Frob(&t0)     // t1 = f^(p^2 + 1)*(p)
    73  	t1.Frob(&t1)     // t1 = f^(p^2 + 1)*(p^2)
    74  	t1.Frob(&t1)     // t1 = f^(p^2 + 1)*(p^3)
    75  	t1.Frob(&t1)     // t1 = f^(p^2 + 1)*(p^4)
    76  	t1.Frob(&t1)     // t1 = f^(p^2 + 1)*(p^5)
    77  	t1.Frob(&t1)     // t1 = f^(p^2 + 1)*(p^6)
    78  	t0.Inv(&t0)      // t0 = f^-(p^2 + 1)
    79  	t0.Mul(&t0, &t1) // t0 = f^(p^2 + 1)*(p^6 - 1)
    80  
    81  	*g = (Cyclo6)(t0)
    82  }
    83  
    84  // HardExponentiation calculates u = g^(Cy_6(p)/r), where u is a root of unity.
    85  func HardExponentiation(u *URoot, g *Cyclo6) {
    86  	var t0, t1, _g, g3 Cyclo6
    87  	var c, a0, a1, a2, a3 Cyclo6
    88  	_g.Inv(g)        // _g = g^-1
    89  	g3.Sqr(g)        // g3 = g^2
    90  	g3.Mul(&g3, g)   // g3 = g^3
    91  	t0.PowToX(g)     // t0 = g^x
    92  	t0.Mul(&t0, &_g) // t0 = g^(x-1)
    93  	t1.PowToX(&t0)   // t1 = g^(x-1)*x
    94  	t0.Inv(&t0)      // t0 = g^-(x-1)
    95  	a3.Mul(&t1, &t0) // a3 = g^(x-1)*(x-1)
    96  	a2.Frob(&a3)     // a2 = a3*p
    97  	a1.Frob(&a2)     // a1 = a2*p = a3*p^2
    98  	t0.Inv(&a3)      // t0 = -a3
    99  	a1.Mul(&a1, &t0) // a1 = a3*p^2-a3
   100  	a0.Frob(&a1)     // a0 = a3*p^3-a3*p
   101  	a0.Mul(&a0, &g3) // a0 = a3*p^3-a3*p+3
   102  
   103  	c.PowToX(&a3)  // c = g^(a3*x)
   104  	c.Mul(&c, &a2) // c = g^(a3*x+a2)
   105  	c.PowToX(&c)   // c = g^(a3*x+a2)*x = g^(a3*x^2+a2*x)
   106  	c.Mul(&c, &a1) // c = g^(a3*x^2+a2*x+a1)
   107  	c.PowToX(&c)   // c = g^(a3*x^2+a2*x+a1)*x = g^(a3*x^3+a2*x^2+a1*x)
   108  	c.Mul(&c, &a0) // c = g^(a3*x^3+a2*x^2+a1*x+a0)
   109  
   110  	*u = (URoot)(c)
   111  }