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

     1  package ff
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/cloudflare/circl/internal/test"
     8  )
     9  
    10  func randomFp2(t testing.TB) *Fp2 { return &Fp2{*randomFp(t), *randomFp(t)} }
    11  
    12  func TestFp2(t *testing.T) {
    13  	const testTimes = 1 << 9
    14  	t.Run("no_alias", func(t *testing.T) {
    15  		var want, got Fp2
    16  		x := randomFp2(t)
    17  		got = *x
    18  		got.Sqr(&got)
    19  		want = *x
    20  		want.Mul(&want, &want)
    21  		if got.IsEqual(&want) == 0 {
    22  			test.ReportError(t, got, want, x)
    23  		}
    24  	})
    25  	t.Run("mul_inv", func(t *testing.T) {
    26  		var z Fp2
    27  		for i := 0; i < testTimes; i++ {
    28  			x := randomFp2(t)
    29  			y := randomFp2(t)
    30  
    31  			// x*y*x^1 - y = 0
    32  			z.Inv(x)
    33  			z.Mul(&z, y)
    34  			z.Mul(&z, x)
    35  			z.Sub(&z, y)
    36  			got := z.IsZero()
    37  			want := 1
    38  			if got != want {
    39  				test.ReportError(t, got, want, x, y, z)
    40  			}
    41  		}
    42  	})
    43  	t.Run("mul_sqr", func(t *testing.T) {
    44  		var l0, l1, r0, r1 Fp2
    45  		for i := 0; i < testTimes; i++ {
    46  			x := randomFp2(t)
    47  			y := randomFp2(t)
    48  
    49  			// (x+y)(x-y) = (x^2-y^2)
    50  			l0.Add(x, y)
    51  			l1.Sub(x, y)
    52  			l0.Mul(&l0, &l1)
    53  			r0.Sqr(x)
    54  			r1.Sqr(y)
    55  			r0.Sub(&r0, &r1)
    56  			got := &l0
    57  			want := &r0
    58  			if got.IsEqual(want) == 0 {
    59  				test.ReportError(t, got, want, x, y)
    60  			}
    61  		}
    62  	})
    63  	t.Run("sqrt", func(t *testing.T) {
    64  		var r, notRoot, got Fp2
    65  		// Check when x has square-root.
    66  		for i := 0; i < testTimes; i++ {
    67  			x := randomFp2(t)
    68  			x.Sqr(x)
    69  
    70  			// let x is QR and r = sqrt(x); check (+r)^2 = (-r)^2 = x.
    71  			isQR := r.Sqrt(x)
    72  			test.CheckOk(isQR == 1, fmt.Sprintf("should be a QR: %v", x), t)
    73  			rNeg := r
    74  			rNeg.Neg()
    75  
    76  			want := x
    77  			for _, root := range []*Fp2{&r, &rNeg} {
    78  				got.Sqr(root)
    79  				if got.IsEqual(want) == 0 {
    80  					test.ReportError(t, got, want, x, root)
    81  				}
    82  			}
    83  		}
    84  		// Check when x has not square-root.
    85  		var uPlus1 Fp2
    86  		uPlus1[0].SetUint64(1)
    87  		uPlus1[1].SetUint64(1)
    88  		for i := 0; i < testTimes; i++ {
    89  			want := randomFp2(t)
    90  			x := randomFp2(t)
    91  			x.Sqr(x)
    92  			x.Mul(x, &uPlus1) // x = (u+1)*(x^2), since u+1 is not QR in Fp2.
    93  
    94  			// let x is not QR and r = sqrt(x); check that r was not modified.
    95  			got := want
    96  			isQR := got.Sqrt(x)
    97  			test.CheckOk(isQR == 0, fmt.Sprintf("shouldn't be a QR: %v", x), t)
    98  
    99  			if got.IsEqual(want) != 1 {
   100  				test.ReportError(t, got, want, x, notRoot)
   101  			}
   102  		}
   103  	})
   104  	t.Run("marshal", func(t *testing.T) {
   105  		var b Fp2
   106  		for i := 0; i < testTimes; i++ {
   107  			a := randomFp2(t)
   108  			s, err := a.MarshalBinary()
   109  			test.CheckNoErr(t, err, "MarshalBinary failed")
   110  			err = b.UnmarshalBinary(s)
   111  			test.CheckNoErr(t, err, "UnmarshalBinary failed")
   112  			if b.IsEqual(a) == 0 {
   113  				test.ReportError(t, a, b)
   114  			}
   115  		}
   116  	})
   117  }
   118  
   119  func BenchmarkFp2(b *testing.B) {
   120  	x := randomFp2(b)
   121  	y := randomFp2(b)
   122  	z := randomFp2(b)
   123  	b.Run("Add", func(b *testing.B) {
   124  		for i := 0; i < b.N; i++ {
   125  			z.Add(x, y)
   126  		}
   127  	})
   128  	b.Run("Mul", func(b *testing.B) {
   129  		for i := 0; i < b.N; i++ {
   130  			z.Mul(x, y)
   131  		}
   132  	})
   133  	b.Run("Sqr", func(b *testing.B) {
   134  		for i := 0; i < b.N; i++ {
   135  			z.Sqr(x)
   136  		}
   137  	})
   138  	b.Run("Inv", func(b *testing.B) {
   139  		for i := 0; i < b.N; i++ {
   140  			z.Inv(x)
   141  		}
   142  	})
   143  }