252 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			252 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package bls12381
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"bytes"
							 | 
						||
| 
								 | 
							
									"crypto/rand"
							 | 
						||
| 
								 | 
							
									"math/big"
							 | 
						||
| 
								 | 
							
									"testing"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestFieldElementValidation(t *testing.T) {
							 | 
						||
| 
								 | 
							
									zero := new(fe).zero()
							 | 
						||
| 
								 | 
							
									if !zero.isValid() {
							 | 
						||
| 
								 | 
							
										t.Fatal("zero must be valid")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one := new(fe).one()
							 | 
						||
| 
								 | 
							
									if !one.isValid() {
							 | 
						||
| 
								 | 
							
										t.Fatal("one must be valid")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if modulus.isValid() {
							 | 
						||
| 
								 | 
							
										t.Fatal("modulus must be invalid")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									n := modulus.big()
							 | 
						||
| 
								 | 
							
									n.Add(n, big.NewInt(1))
							 | 
						||
| 
								 | 
							
									if new(fe).setBig(n).isValid() {
							 | 
						||
| 
								 | 
							
										t.Fatal("number greater than modulus must be invalid")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestFieldElementEquality(t *testing.T) {
							 | 
						||
| 
								 | 
							
									// fe
							 | 
						||
| 
								 | 
							
									zero := new(fe).zero()
							 | 
						||
| 
								 | 
							
									if !zero.equal(zero) {
							 | 
						||
| 
								 | 
							
										t.Fatal("0 == 0")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one := new(fe).one()
							 | 
						||
| 
								 | 
							
									if !one.equal(one) {
							 | 
						||
| 
								 | 
							
										t.Fatal("1 == 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a, _ := new(fe).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									if !a.equal(a) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a == a")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									b := new(fe)
							 | 
						||
| 
								 | 
							
									add(b, a, one)
							 | 
						||
| 
								 | 
							
									if a.equal(b) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a != a + 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// fe2
							 | 
						||
| 
								 | 
							
									zero2 := new(fe2).zero()
							 | 
						||
| 
								 | 
							
									if !zero2.equal(zero2) {
							 | 
						||
| 
								 | 
							
										t.Fatal("0 == 0")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one2 := new(fe2).one()
							 | 
						||
| 
								 | 
							
									if !one2.equal(one2) {
							 | 
						||
| 
								 | 
							
										t.Fatal("1 == 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a2, _ := new(fe2).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									if !a2.equal(a2) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a == a")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									b2 := new(fe2)
							 | 
						||
| 
								 | 
							
									fp2 := newFp2()
							 | 
						||
| 
								 | 
							
									fp2.add(b2, a2, one2)
							 | 
						||
| 
								 | 
							
									if a2.equal(b2) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a != a + 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// fe6
							 | 
						||
| 
								 | 
							
									zero6 := new(fe6).zero()
							 | 
						||
| 
								 | 
							
									if !zero6.equal(zero6) {
							 | 
						||
| 
								 | 
							
										t.Fatal("0 == 0")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one6 := new(fe6).one()
							 | 
						||
| 
								 | 
							
									if !one6.equal(one6) {
							 | 
						||
| 
								 | 
							
										t.Fatal("1 == 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a6, _ := new(fe6).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									if !a6.equal(a6) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a == a")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									b6 := new(fe6)
							 | 
						||
| 
								 | 
							
									fp6 := newFp6(fp2)
							 | 
						||
| 
								 | 
							
									fp6.add(b6, a6, one6)
							 | 
						||
| 
								 | 
							
									if a6.equal(b6) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a != a + 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// fe12
							 | 
						||
| 
								 | 
							
									zero12 := new(fe12).zero()
							 | 
						||
| 
								 | 
							
									if !zero12.equal(zero12) {
							 | 
						||
| 
								 | 
							
										t.Fatal("0 == 0")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one12 := new(fe12).one()
							 | 
						||
| 
								 | 
							
									if !one12.equal(one12) {
							 | 
						||
| 
								 | 
							
										t.Fatal("1 == 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a12, _ := new(fe12).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									if !a12.equal(a12) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a == a")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									b12 := new(fe12)
							 | 
						||
| 
								 | 
							
									fp12 := newFp12(fp6)
							 | 
						||
| 
								 | 
							
									fp12.add(b12, a12, one12)
							 | 
						||
| 
								 | 
							
									if a12.equal(b12) {
							 | 
						||
| 
								 | 
							
										t.Fatal("a != a + 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestFieldElementHelpers(t *testing.T) {
							 | 
						||
| 
								 | 
							
									// fe
							 | 
						||
| 
								 | 
							
									zero := new(fe).zero()
							 | 
						||
| 
								 | 
							
									if !zero.isZero() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'zero' is not zero")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one := new(fe).one()
							 | 
						||
| 
								 | 
							
									if !one.isOne() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'one' is not one")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									odd := new(fe).setBig(big.NewInt(1))
							 | 
						||
| 
								 | 
							
									if !odd.isOdd() {
							 | 
						||
| 
								 | 
							
										t.Fatal("1 must be odd")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if odd.isEven() {
							 | 
						||
| 
								 | 
							
										t.Fatal("1 must not be even")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									even := new(fe).setBig(big.NewInt(2))
							 | 
						||
| 
								 | 
							
									if !even.isEven() {
							 | 
						||
| 
								 | 
							
										t.Fatal("2 must be even")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if even.isOdd() {
							 | 
						||
| 
								 | 
							
										t.Fatal("2 must not be odd")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// fe2
							 | 
						||
| 
								 | 
							
									zero2 := new(fe2).zero()
							 | 
						||
| 
								 | 
							
									if !zero2.isZero() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'zero' is not zero, 2")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one2 := new(fe2).one()
							 | 
						||
| 
								 | 
							
									if !one2.isOne() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'one' is not one, 2")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// fe6
							 | 
						||
| 
								 | 
							
									zero6 := new(fe6).zero()
							 | 
						||
| 
								 | 
							
									if !zero6.isZero() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'zero' is not zero, 6")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one6 := new(fe6).one()
							 | 
						||
| 
								 | 
							
									if !one6.isOne() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'one' is not one, 6")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// fe12
							 | 
						||
| 
								 | 
							
									zero12 := new(fe12).zero()
							 | 
						||
| 
								 | 
							
									if !zero12.isZero() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'zero' is not zero, 12")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									one12 := new(fe12).one()
							 | 
						||
| 
								 | 
							
									if !one12.isOne() {
							 | 
						||
| 
								 | 
							
										t.Fatal("'one' is not one, 12")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestFieldElementSerialization(t *testing.T) {
							 | 
						||
| 
								 | 
							
									t.Run("zero", func(t *testing.T) {
							 | 
						||
| 
								 | 
							
										in := make([]byte, 48)
							 | 
						||
| 
								 | 
							
										fe := new(fe).setBytes(in)
							 | 
						||
| 
								 | 
							
										if !fe.isZero() {
							 | 
						||
| 
								 | 
							
											t.Fatal("bad serialization")
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if !bytes.Equal(in, fe.bytes()) {
							 | 
						||
| 
								 | 
							
											t.Fatal("bad serialization")
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									t.Run("bytes", func(t *testing.T) {
							 | 
						||
| 
								 | 
							
										for i := 0; i < fuz; i++ {
							 | 
						||
| 
								 | 
							
											a, _ := new(fe).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
											b := new(fe).setBytes(a.bytes())
							 | 
						||
| 
								 | 
							
											if !a.equal(b) {
							 | 
						||
| 
								 | 
							
												t.Fatal("bad serialization")
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									t.Run("big", func(t *testing.T) {
							 | 
						||
| 
								 | 
							
										for i := 0; i < fuz; i++ {
							 | 
						||
| 
								 | 
							
											a, _ := new(fe).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
											b := new(fe).setBig(a.big())
							 | 
						||
| 
								 | 
							
											if !a.equal(b) {
							 | 
						||
| 
								 | 
							
												t.Fatal("bad encoding or decoding")
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									t.Run("string", func(t *testing.T) {
							 | 
						||
| 
								 | 
							
										for i := 0; i < fuz; i++ {
							 | 
						||
| 
								 | 
							
											a, _ := new(fe).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
											b, err := new(fe).setString(a.string())
							 | 
						||
| 
								 | 
							
											if err != nil {
							 | 
						||
| 
								 | 
							
												t.Fatal(err)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if !a.equal(b) {
							 | 
						||
| 
								 | 
							
												t.Fatal("bad encoding or decoding")
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestFieldElementByteInputs(t *testing.T) {
							 | 
						||
| 
								 | 
							
									zero := new(fe).zero()
							 | 
						||
| 
								 | 
							
									in := make([]byte, 0)
							 | 
						||
| 
								 | 
							
									a := new(fe).setBytes(in)
							 | 
						||
| 
								 | 
							
									if !a.equal(zero) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad serialization")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									in = make([]byte, 48)
							 | 
						||
| 
								 | 
							
									a = new(fe).setBytes(in)
							 | 
						||
| 
								 | 
							
									if !a.equal(zero) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad serialization")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									in = make([]byte, 64)
							 | 
						||
| 
								 | 
							
									a = new(fe).setBytes(in)
							 | 
						||
| 
								 | 
							
									if !a.equal(zero) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad serialization")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									in = make([]byte, 49)
							 | 
						||
| 
								 | 
							
									in[47] = 1
							 | 
						||
| 
								 | 
							
									normalOne := &fe{1, 0, 0, 0, 0, 0}
							 | 
						||
| 
								 | 
							
									a = new(fe).setBytes(in)
							 | 
						||
| 
								 | 
							
									if !a.equal(normalOne) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad serialization")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestFieldElementCopy(t *testing.T) {
							 | 
						||
| 
								 | 
							
									a, _ := new(fe).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									b := new(fe).set(a)
							 | 
						||
| 
								 | 
							
									if !a.equal(b) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad copy, 1")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a2, _ := new(fe2).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									b2 := new(fe2).set(a2)
							 | 
						||
| 
								 | 
							
									if !a2.equal(b2) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad copy, 2")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a6, _ := new(fe6).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									b6 := new(fe6).set(a6)
							 | 
						||
| 
								 | 
							
									if !a6.equal(b6) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad copy, 6")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a12, _ := new(fe12).rand(rand.Reader)
							 | 
						||
| 
								 | 
							
									b12 := new(fe12).set(a12)
							 | 
						||
| 
								 | 
							
									if !a12.equal(b12) {
							 | 
						||
| 
								 | 
							
										t.Fatal("bad copy, 12")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |