github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/zkp/aggregaterange/aggregaterange_test.go (about)

     1  package aggregaterange
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/incognitochain/go-incognito-sdk/common"
     6  	"github.com/incognitochain/go-incognito-sdk/privacy"
     7  	"github.com/stretchr/testify/assert"
     8  	"io/ioutil"
     9  	"log"
    10  	"math/rand"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  func TestMain(m *testing.M) {
    16  	log.SetOutput(ioutil.Discard)
    17  	m.Run()
    18  }
    19  
    20  var _ = func() (_ struct{}) {
    21  	fmt.Println("This runs before init()!")
    22  	return
    23  }()
    24  
    25  func TestPad(t *testing.T) {
    26  	data := []struct {
    27  		number       int
    28  		paddedNumber int
    29  	}{
    30  		{1000, 1024},
    31  		{3, 4},
    32  		{5, 8},
    33  	}
    34  
    35  	for _, item := range data {
    36  		num := pad(item.number)
    37  		assert.Equal(t, item.paddedNumber, num)
    38  	}
    39  }
    40  
    41  func TestPowerVector(t *testing.T) {
    42  	twoVector := powerVector(new(privacy.Scalar).FromUint64(2), 5)
    43  	assert.Equal(t, 5, len(twoVector))
    44  }
    45  
    46  func TestInnerProduct(t *testing.T) {
    47  	for j := 0; j < 100; j++ {
    48  		n := maxExp
    49  		a := make([]*privacy.Scalar, n)
    50  		b := make([]*privacy.Scalar, n)
    51  		uinta := make([]uint64, n)
    52  		uintb := make([]uint64, n)
    53  		uintc := uint64(0)
    54  		for i := 0; i < n; i++ {
    55  			uinta[i] = uint64(rand.Intn(100000000))
    56  			uintb[i] = uint64(rand.Intn(100000000))
    57  			a[i] = new(privacy.Scalar).FromUint64(uinta[i])
    58  			b[i] = new(privacy.Scalar).FromUint64(uintb[i])
    59  			uintc += uinta[i] * uintb[i]
    60  		}
    61  
    62  		c, _ := innerProduct(a, b)
    63  		assert.Equal(t, new(privacy.Scalar).FromUint64(uintc), c)
    64  	}
    65  }
    66  
    67  func TestEncodeVectors(t *testing.T) {
    68  	for i := 0; i < 100; i++ {
    69  		var AggParam = newBulletproofParams(1)
    70  		n := maxExp
    71  		a := make([]*privacy.Scalar, n)
    72  		b := make([]*privacy.Scalar, n)
    73  		G := make([]*privacy.Point, n)
    74  		H := make([]*privacy.Point, n)
    75  
    76  		for i := range a {
    77  			a[i] = privacy.RandomScalar()
    78  			b[i] = privacy.RandomScalar()
    79  			G[i] = new(privacy.Point).Set(AggParam.g[i])
    80  			H[i] = new(privacy.Point).Set(AggParam.h[i])
    81  		}
    82  
    83  		actualRes, err := encodeVectors(a, b, G, H)
    84  		if err != nil {
    85  			fmt.Printf("Err: %v\n", err)
    86  		}
    87  
    88  		expectedRes := new(privacy.Point).Identity()
    89  		for i := 0; i < n; i++ {
    90  			expectedRes.Add(expectedRes, new(privacy.Point).ScalarMult(G[i], a[i]))
    91  			expectedRes.Add(expectedRes, new(privacy.Point).ScalarMult(H[i], b[i]))
    92  		}
    93  
    94  		assert.Equal(t, expectedRes, actualRes)
    95  	}
    96  }
    97  
    98  func TestAggregatedRangeProveVerify(t *testing.T) {
    99  	for i := 0; i < 10; i++ {
   100  		//prepare witness for Aggregated range protocol
   101  		wit := new(AggregatedRangeWitness)
   102  		numValue := rand.Intn(maxOutputNumber)
   103  		values := make([]uint64, numValue)
   104  		rands := make([]*privacy.Scalar, numValue)
   105  
   106  		for i := range values {
   107  			values[i] = uint64(rand.Uint64())
   108  			rands[i] = privacy.RandomScalar()
   109  		}
   110  		wit.Set(values, rands)
   111  
   112  		// proving
   113  		proof, err := wit.Prove()
   114  		assert.Equal(t, nil, err)
   115  
   116  		// verify the proof
   117  		res, err := proof.Verify()
   118  		assert.Equal(t, true, res)
   119  		assert.Equal(t, nil, err)
   120  
   121  		// validate sanity for proof
   122  		isValidSanity := proof.ValidateSanity()
   123  		assert.Equal(t, true, isValidSanity)
   124  
   125  		// convert proof to bytes array
   126  		bytes := proof.Bytes()
   127  		expectProofSize := EstimateMultiRangeProofSize(numValue)
   128  		assert.Equal(t, int(expectProofSize), len(bytes))
   129  
   130  		// new aggregatedRangeProof from bytes array
   131  		proof2 := new(AggregatedRangeProof)
   132  		proof2.SetBytes(bytes)
   133  
   134  		// verify the proof
   135  		res, err = proof2.Verify()
   136  		assert.Equal(t, true, res)
   137  		assert.Equal(t, nil, err)
   138  	}
   139  }
   140  
   141  func TestAggregatedRangeProveVerifyUltraFast(t *testing.T) {
   142  	count := 10
   143  	proofs := make([]*AggregatedRangeProof, 0)
   144  
   145  	for i := 0; i < count; i++ {
   146  		//prepare witness for Aggregated range protocol
   147  		wit := new(AggregatedRangeWitness)
   148  		numValue := rand.Intn(maxOutputNumber)
   149  		values := make([]uint64, numValue)
   150  		rands := make([]*privacy.Scalar, numValue)
   151  
   152  		for i := range values {
   153  			values[i] = uint64(rand.Uint64())
   154  			rands[i] = privacy.RandomScalar()
   155  		}
   156  		wit.Set(values, rands)
   157  
   158  		// proving
   159  		proof, err := wit.Prove()
   160  		assert.Equal(t, nil, err)
   161  
   162  		proofs = append(proofs, proof)
   163  	}
   164  	// verify the proof faster
   165  	res, err, _ := VerifyBatchingAggregatedRangeProofs(proofs)
   166  	assert.Equal(t, true, res)
   167  	assert.Equal(t, nil, err)
   168  }
   169  
   170  func TestBenchmarkAggregatedRangeProveVerifyUltraFast(t *testing.T) {
   171  	for k := 1; k < 100; k += 5 {
   172  		count := k
   173  		proofs := make([]*AggregatedRangeProof, 0)
   174  		start := time.Now()
   175  		t1 := time.Now().Sub(start)
   176  		for i := 0; i < count; i++ {
   177  			//prepare witness for Aggregated range protocol
   178  			wit := new(AggregatedRangeWitness)
   179  			//numValue := rand.Intn(maxOutputNumber)
   180  			numValue := 2
   181  			values := make([]uint64, numValue)
   182  			rands := make([]*privacy.Scalar, numValue)
   183  
   184  			for i := range values {
   185  				values[i] = uint64(rand.Uint64())
   186  				rands[i] = privacy.RandomScalar()
   187  			}
   188  			wit.Set(values, rands)
   189  
   190  			// proving
   191  			proof, err := wit.Prove()
   192  			assert.Equal(t, nil, err)
   193  			start := time.Now()
   194  			proof.Verify()
   195  			t1 += time.Now().Sub(start)
   196  
   197  			proofs = append(proofs, proof)
   198  		}
   199  		// verify the proof faster
   200  		start = time.Now()
   201  		res, err, _ := VerifyBatchingAggregatedRangeProofs(proofs)
   202  		fmt.Println(t1, time.Now().Sub(start), k)
   203  
   204  		assert.Equal(t, true, res)
   205  		assert.Equal(t, nil, err)
   206  	}
   207  }
   208  
   209  func TestInnerProductProveVerify(t *testing.T) {
   210  	for k := 0; k < 1; k++ {
   211  		numValue := rand.Intn(maxOutputNumber)
   212  		numValuePad := pad(numValue)
   213  		aggParam := new(bulletproofParams)
   214  		aggParam.g = AggParam.g[0 : numValuePad*maxExp]
   215  		aggParam.h = AggParam.h[0 : numValuePad*maxExp]
   216  		aggParam.u = AggParam.u
   217  		aggParam.cs = AggParam.cs
   218  
   219  		wit := new(InnerProductWitness)
   220  		n := maxExp * numValuePad
   221  		wit.a = make([]*privacy.Scalar, n)
   222  		wit.b = make([]*privacy.Scalar, n)
   223  
   224  		for i := range wit.a {
   225  			wit.a[i] = new(privacy.Scalar).FromUint64(uint64(rand.Intn(1000000)))
   226  			wit.b[i] = new(privacy.Scalar).FromUint64(uint64(rand.Intn(1000000)))
   227  		}
   228  
   229  		c, err := innerProduct(wit.a, wit.b)
   230  
   231  		if err != nil {
   232  			fmt.Printf("Err: %v\n", err)
   233  		}
   234  		wit.p = new(privacy.Point).ScalarMult(aggParam.u, c)
   235  
   236  		for i := range wit.a {
   237  			wit.p.Add(wit.p, new(privacy.Point).ScalarMult(aggParam.g[i], wit.a[i]))
   238  			wit.p.Add(wit.p, new(privacy.Point).ScalarMult(aggParam.h[i], wit.b[i]))
   239  		}
   240  
   241  		proof, err := wit.Prove(aggParam)
   242  		if err != nil {
   243  			fmt.Printf("Err: %v\n", err)
   244  			return
   245  		}
   246  		res2 := proof.Verify(aggParam)
   247  		assert.Equal(t, true, res2)
   248  
   249  		bytes := proof.Bytes()
   250  		proof2 := new(InnerProductProof)
   251  		proof2.SetBytes(bytes)
   252  		res3 := proof2.Verify(aggParam)
   253  		assert.Equal(t, true, res3)
   254  		res3prime := proof2.Verify(aggParam)
   255  		assert.Equal(t, true, res3prime)
   256  
   257  	}
   258  }
   259  
   260  func TestInnerProductProveVerifyUltraFast(t *testing.T) {
   261  	proofs := make([]*InnerProductProof, 0)
   262  	csList := make([][]byte, 0)
   263  	count := 15
   264  	for k := 0; k < count; k++ {
   265  		numValue := rand.Intn(maxOutputNumber)
   266  		numValuePad := pad(numValue)
   267  		aggParam := new(bulletproofParams)
   268  		aggParam.g = AggParam.g[0 : numValuePad*maxExp]
   269  		aggParam.h = AggParam.h[0 : numValuePad*maxExp]
   270  		aggParam.u = AggParam.u
   271  		aggParam.cs = AggParam.cs
   272  
   273  		wit := new(InnerProductWitness)
   274  		n := maxExp * numValuePad
   275  		wit.a = make([]*privacy.Scalar, n)
   276  		wit.b = make([]*privacy.Scalar, n)
   277  
   278  		for i := range wit.a {
   279  			wit.a[i] = new(privacy.Scalar).FromUint64(uint64(rand.Intn(1000000)))
   280  			wit.b[i] = new(privacy.Scalar).FromUint64(uint64(rand.Intn(1000000)))
   281  		}
   282  
   283  		c, err := innerProduct(wit.a, wit.b)
   284  		if err != nil {
   285  			fmt.Printf("Err: %v\n", err)
   286  		}
   287  		if k == 0 {
   288  			wit.p = new(privacy.Point).ScalarMult(aggParam.u, c.Add(c, new(privacy.Scalar).FromUint64(1)))
   289  		} else {
   290  			wit.p = new(privacy.Point).ScalarMult(aggParam.u, c)
   291  		}
   292  
   293  		for i := range wit.a {
   294  			wit.p.Add(wit.p, new(privacy.Point).ScalarMult(aggParam.g[i], wit.a[i]))
   295  			if k == count-1 {
   296  				wit.p.Add(wit.p, new(privacy.Point).ScalarMult(aggParam.h[i], wit.a[i]))
   297  			} else {
   298  				wit.p.Add(wit.p, new(privacy.Point).ScalarMult(aggParam.h[i], wit.b[i]))
   299  			}
   300  		}
   301  
   302  		proof, err := wit.Prove(aggParam)
   303  		if err != nil {
   304  			fmt.Printf("Err: %v\n", err)
   305  			return
   306  		}
   307  		proofs = append(proofs, proof)
   308  		csList = append(csList, aggParam.cs)
   309  	}
   310  	res := VerifyBatchingInnerProductProofs(proofs, csList)
   311  	assert.Equal(t, false, res)
   312  	res = VerifyBatchingInnerProductProofs(proofs[1:], csList[1:])
   313  	assert.Equal(t, false, res)
   314  	res = VerifyBatchingInnerProductProofs(proofs[:len(proofs)-1], csList[:len(proofs)-1])
   315  	assert.Equal(t, false, res)
   316  	res = VerifyBatchingInnerProductProofs(proofs[1:len(proofs)-1], csList[1:len(proofs)-1])
   317  	assert.Equal(t, true, res)
   318  }
   319  func benchmarkAggRangeProof_Proof(numberofOutput int, b *testing.B) {
   320  	wit := new(AggregatedRangeWitness)
   321  	values := make([]uint64, numberofOutput)
   322  	rands := make([]*privacy.Scalar, numberofOutput)
   323  
   324  	for i := range values {
   325  		values[i] = uint64(rand.Uint64())
   326  		rands[i] = privacy.RandomScalar()
   327  	}
   328  	wit.Set(values, rands)
   329  
   330  	b.ResetTimer()
   331  
   332  	for i := 0; i < b.N; i++ {
   333  		wit.Prove()
   334  	}
   335  }
   336  
   337  func TestAnStrictInnerProductProveVerifyUltraFast(t *testing.T) {
   338  	proofs := make([]*InnerProductProof, 0)
   339  	csList := make([][]byte, 0)
   340  	count := 5
   341  	for k := 0; k < count; k++ {
   342  		numValue := rand.Intn(maxOutputNumber)
   343  		numValuePad := pad(numValue)
   344  		aggParam := new(bulletproofParams)
   345  		aggParam.g = AggParam.g[0 : numValuePad*maxExp]
   346  		aggParam.h = AggParam.h[0 : numValuePad*maxExp]
   347  		aggParam.u = AggParam.u
   348  		aggParam.cs = AggParam.cs
   349  		wit := new(InnerProductWitness)
   350  		n := maxExp * numValuePad
   351  		wit.a = make([]*privacy.Scalar, n)
   352  		wit.b = make([]*privacy.Scalar, n)
   353  		for i := range wit.a {
   354  			wit.a[i] = new(privacy.Scalar).FromUint64(uint64(rand.Intn(1000000)))
   355  			wit.b[i] = new(privacy.Scalar).FromUint64(uint64(rand.Intn(1000000)))
   356  		}
   357  		c, err := innerProduct(wit.a, wit.b)
   358  		if err != nil {
   359  			fmt.Printf("Err: %v\n", err)
   360  		}
   361  		wit.p = new(privacy.Point).ScalarMult(aggParam.u, c)
   362  		for i := range wit.a {
   363  			wit.p.Add(wit.p, new(privacy.Point).ScalarMult(aggParam.g[i], wit.a[i]))
   364  			wit.p.Add(wit.p, new(privacy.Point).ScalarMult(aggParam.h[i], wit.b[i]))
   365  		}
   366  		proof, err := wit.Prove(aggParam)
   367  		if err != nil {
   368  			fmt.Printf("Err: %v\n", err)
   369  			return
   370  		}
   371  		proofs = append(proofs, proof)
   372  		csList = append(csList, aggParam.cs)
   373  	}
   374  	res := VerifyBatchingInnerProductProofs(proofs, csList)
   375  	assert.Equal(t, true, res)
   376  	for j := 0; j < 50; j += 1 {
   377  		i := common.RandInt() % len(proofs)
   378  		r := common.RandInt() % 5
   379  		if r == 0 {
   380  			ran := common.RandInt() % len(proofs[i].l)
   381  			remember := proofs[i].l[ran]
   382  			proofs[i].l[ran] = obfuscatePoint(proofs[i].l[ran])
   383  			assert.NotEqual(t, remember, proofs[i].l[ran])
   384  			res := VerifyBatchingInnerProductProofs(proofs, csList)
   385  			assert.Equal(t, false, res)
   386  			proofs[i].l[ran] = remember
   387  		} else if r == 1 {
   388  			ran := common.RandInt() % len(proofs[i].r)
   389  			remember := proofs[i].r[ran]
   390  			proofs[i].r[ran] = obfuscatePoint(proofs[i].r[ran])
   391  			assert.NotEqual(t, remember, proofs[i].r[ran])
   392  			res := VerifyBatchingInnerProductProofs(proofs, csList)
   393  			assert.Equal(t, false, res)
   394  			proofs[i].r[ran] = remember
   395  		} else if r == 2 {
   396  			remember := proofs[i].a
   397  			proofs[i].a = obfuscateScalar(proofs[i].a)
   398  			assert.NotEqual(t, remember, proofs[i].a)
   399  			res := VerifyBatchingInnerProductProofs(proofs, csList)
   400  			assert.Equal(t, false, res)
   401  			proofs[i].a = remember
   402  		} else if r == 3 {
   403  			remember := proofs[i].b
   404  			proofs[i].b = obfuscateScalar(proofs[i].b)
   405  			assert.NotEqual(t, remember, proofs[i].b)
   406  			res := VerifyBatchingInnerProductProofs(proofs, csList)
   407  			assert.Equal(t, false, res)
   408  			proofs[i].b = remember
   409  		} else if r == 4 {
   410  			remember := proofs[i].p
   411  			proofs[i].p = obfuscatePoint(proofs[i].p)
   412  			assert.NotEqual(t, remember, proofs[i].p)
   413  			res := VerifyBatchingInnerProductProofs(proofs, csList)
   414  			assert.Equal(t, false, res)
   415  			proofs[i].p = remember
   416  		}
   417  	}
   418  	res = VerifyBatchingInnerProductProofs(proofs, csList)
   419  	assert.Equal(t, true, res)
   420  }
   421  func obfuscatePoint(value *privacy.Point) *privacy.Point {
   422  	for {
   423  		k := value.GetKey()
   424  		r := common.RandInt() % len(k)
   425  		i := common.RandInt() % 8
   426  		k[r] ^= (1 << uint8(i))
   427  		after, err := new(privacy.Point).SetKey(&k)
   428  		if err == nil {
   429  			return after
   430  		}
   431  	}
   432  }
   433  func obfuscateScalar(value *privacy.Scalar) *privacy.Scalar {
   434  	for {
   435  		k := value.GetKey()
   436  		r := common.RandInt() % len(k)
   437  		i := common.RandInt() % 8
   438  		k[r] ^= (1 << uint8(i))
   439  		after, err := new(privacy.Scalar).SetKey(&k)
   440  		if err == nil {
   441  			return after
   442  		}
   443  	}
   444  }
   445  
   446  func benchmarkAggRangeProof_Verify(numberofOutput int, b *testing.B) {
   447  	wit := new(AggregatedRangeWitness)
   448  	values := make([]uint64, numberofOutput)
   449  	rands := make([]*privacy.Scalar, numberofOutput)
   450  
   451  	for i := range values {
   452  		values[i] = uint64(common.RandInt64())
   453  		rands[i] = privacy.RandomScalar()
   454  	}
   455  	wit.Set(values, rands)
   456  	proof, _ := wit.Prove()
   457  
   458  	b.ResetTimer()
   459  
   460  	for i := 0; i < b.N; i++ {
   461  		proof.Verify()
   462  	}
   463  }
   464  
   465  func benchmarkAggRangeProof_VerifyFaster(numberofOutput int, b *testing.B) {
   466  	wit := new(AggregatedRangeWitness)
   467  	values := make([]uint64, numberofOutput)
   468  	rands := make([]*privacy.Scalar, numberofOutput)
   469  
   470  	for i := range values {
   471  		values[i] = uint64(common.RandInt64())
   472  		rands[i] = privacy.RandomScalar()
   473  	}
   474  	wit.Set(values, rands)
   475  	proof, _ := wit.Prove()
   476  
   477  	b.ResetTimer()
   478  
   479  	for i := 0; i < b.N; i++ {
   480  		proof.Verify()
   481  	}
   482  }
   483  
   484  func BenchmarkAggregatedRangeWitness_Prove1(b *testing.B) { benchmarkAggRangeProof_Proof(1, b) }
   485  func BenchmarkAggregatedRangeProof_Verify1(b *testing.B)  { benchmarkAggRangeProof_Verify(1, b) }
   486  func BenchmarkAggregatedRangeProof_VerifyFaster1(b *testing.B) {
   487  	benchmarkAggRangeProof_VerifyFaster(1, b)
   488  }
   489  
   490  func BenchmarkAggregatedRangeWitness_Prove2(b *testing.B) { benchmarkAggRangeProof_Proof(2, b) }
   491  func BenchmarkAggregatedRangeProof_Verify2(b *testing.B)  { benchmarkAggRangeProof_Verify(2, b) }
   492  func BenchmarkAggregatedRangeProof_VerifyFaster2(b *testing.B) {
   493  	benchmarkAggRangeProof_VerifyFaster(2, b)
   494  }
   495  
   496  func BenchmarkAggregatedRangeWitness_Prove4(b *testing.B) { benchmarkAggRangeProof_Proof(4, b) }
   497  func BenchmarkAggregatedRangeProof_Verify4(b *testing.B)  { benchmarkAggRangeProof_Verify(4, b) }
   498  func BenchmarkAggregatedRangeProof_VerifyFaster4(b *testing.B) {
   499  	benchmarkAggRangeProof_VerifyFaster(4, b)
   500  }
   501  
   502  func BenchmarkAggregatedRangeWitness_Prove8(b *testing.B) { benchmarkAggRangeProof_Proof(8, b) }
   503  func BenchmarkAggregatedRangeProof_Verify8(b *testing.B)  { benchmarkAggRangeProof_Verify(8, b) }
   504  func BenchmarkAggregatedRangeProof_VerifyFaster8(b *testing.B) {
   505  	benchmarkAggRangeProof_VerifyFaster(8, b)
   506  }
   507  
   508  func BenchmarkAggregatedRangeWitness_Prove16(b *testing.B) { benchmarkAggRangeProof_Proof(16, b) }
   509  func BenchmarkAggregatedRangeProof_Verify16(b *testing.B)  { benchmarkAggRangeProof_Verify(16, b) }
   510  func BenchmarkAggregatedRangeProof_VerifyFaster16(b *testing.B) {
   511  	benchmarkAggRangeProof_VerifyFaster(16, b)
   512  }