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

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