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

     1  package bls12381
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/cloudflare/circl/ecc/bls12381/ff"
     7  )
     8  
     9  func checkE(t *testing.T, x *ff.Fp12, y *ff.Fp12) {
    10  	four := &ff.Fp12{}
    11  	four[0][0][0].SetUint64(4)
    12  
    13  	xcube := &ff.Fp12{}
    14  	xcube.Mul(x, x)
    15  	xcube.Mul(xcube, x)
    16  
    17  	ysq := &ff.Fp12{}
    18  	ysq.Mul(y, y)
    19  
    20  	check := &ff.Fp12{}
    21  	check.Add(xcube, four)
    22  	if check.IsEqual(ysq) != 1 {
    23  		t.Log("failure of isogeny to E to verify")
    24  		t.Fail()
    25  	}
    26  }
    27  
    28  func checkEprime(t *testing.T, x *ff.Fp12, y *ff.Fp12) {
    29  	four := &ff.Fp12{}
    30  	four[0][0][0].SetUint64(4)
    31  	ysq := &ff.Fp12{}
    32  	xcube := &ff.Fp12{}
    33  	uplusOne := &ff.Fp12{}
    34  	uplusOne[0][0][1].SetOne()
    35  	uplusOne[0][0][0].SetOne()
    36  
    37  	b := &ff.Fp12{}
    38  	b.Mul(uplusOne, four)
    39  
    40  	check := &ff.Fp12{}
    41  	ysq.Mul(y, y)
    42  
    43  	xcube.Mul(x, x)
    44  	xcube.Mul(x, xcube)
    45  	check.Add(xcube, b)
    46  	if check.IsEqual(ysq) != 1 {
    47  		t.Log("failure to return to original curve")
    48  		t.Fail()
    49  	}
    50  }
    51  
    52  func TestPsi(t *testing.T) {
    53  	xp12 := &ff.Fp12{}
    54  	yp12 := &ff.Fp12{}
    55  	Q := &G2{}
    56  	P := randomG2(t)
    57  	*Q = *P
    58  	P.toAffine()
    59  	Q.psi()
    60  	Q.toAffine()
    61  	w := &ff.Fp12{}
    62  	w[1].SetOne()
    63  	wsq := &ff.Fp12{}
    64  	wsq.Sqr(w)
    65  	wcube := &ff.Fp12{}
    66  	wcube.Mul(wsq, w)
    67  	wsqInv := &ff.Fp12{}
    68  	wsqInv.Inv(wsq)
    69  	wcubInv := &ff.Fp12{}
    70  	wcubInv.Inv(wcube)
    71  
    72  	uplusOne := &ff.Fp12{}
    73  	uplusOne[0][0][1].SetOne()
    74  	uplusOne[0][0][0].SetOne()
    75  	wsix := &ff.Fp12{}
    76  	wsix.Mul(wcube, wcube)
    77  	if wsix.IsEqual(uplusOne) != 1 {
    78  		t.Log("w^6 is not u+1")
    79  		t.Fail()
    80  	}
    81  
    82  	xp12[0][0] = P.x
    83  	yp12[0][0] = P.y
    84  	// E' is yp^2=xp^3+4(u+1)
    85  	t.Log("testing input")
    86  	checkEprime(t, xp12, yp12)
    87  	// let x12 = xp/w^2
    88  	// let y12 = yp/w^3
    89  	// Then y12^2=x12^3+4
    90  
    91  	x12 := &ff.Fp12{}
    92  	y12 := &ff.Fp12{}
    93  
    94  	x12.Mul(xp12, wsqInv)
    95  	y12.Mul(yp12, wcubInv)
    96  	t.Log("testing intermediate")
    97  	checkE(t, x12, y12)
    98  	// Do Frobenius
    99  	x12.Frob(x12)
   100  	y12.Frob(y12)
   101  	t.Log("testing post frobenius")
   102  	checkE(t, x12, y12)
   103  	// And return to original
   104  	x12.Mul(x12, wsq)
   105  	y12.Mul(y12, wcube)
   106  
   107  	// Now we should have y^2=x^3+4(u+1)
   108  	checkEprime(t, x12, y12)
   109  	qx12 := &ff.Fp12{}
   110  	qx12[0][0] = Q.x
   111  	qy12 := &ff.Fp12{}
   112  	qy12[0][0] = Q.y
   113  	if x12.IsEqual(qx12) != 1 {
   114  		t.Log("failure in evaluation of x")
   115  		t.Fail()
   116  	}
   117  	if y12.IsEqual(qy12) != 1 {
   118  		t.Log("failure in evaluation of y")
   119  		t.Fail()
   120  	}
   121  }