github.com/consensys/gnark-crypto@v0.14.0/ecc/bw6-633/fr/pedersen/pedersen_test.go (about)

     1  // Copyright 2020 Consensys Software Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Code generated by consensys/gnark-crypto DO NOT EDIT
    16  
    17  package pedersen
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/consensys/gnark-crypto/ecc"
    24  	curve "github.com/consensys/gnark-crypto/ecc/bw6-633"
    25  	"github.com/consensys/gnark-crypto/ecc/bw6-633/fr"
    26  	"github.com/consensys/gnark-crypto/utils/testutils"
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  func interfaceSliceToFrSlice(t *testing.T, values ...interface{}) []fr.Element {
    31  	res := make([]fr.Element, len(values))
    32  	for i, v := range values {
    33  		_, err := res[i].SetInterface(v)
    34  		assert.NoError(t, err)
    35  	}
    36  	return res
    37  }
    38  
    39  func randomFrSlice(t *testing.T, size int) []interface{} {
    40  	res := make([]interface{}, size)
    41  	var err error
    42  	for i := range res {
    43  		var v fr.Element
    44  		res[i], err = v.SetRandom()
    45  		assert.NoError(t, err)
    46  	}
    47  	return res
    48  }
    49  
    50  func randomOnG1() (curve.G1Affine, error) { // TODO: Add to G1.go?
    51  	if gBytes, err := randomFrSizedBytes(); err != nil {
    52  		return curve.G1Affine{}, err
    53  	} else {
    54  		return curve.HashToG1(gBytes, []byte("random on g1"))
    55  	}
    56  }
    57  
    58  func randomG1Slice(t *testing.T, size int) []curve.G1Affine {
    59  	res := make([]curve.G1Affine, size)
    60  	for i := range res {
    61  		var err error
    62  		res[i], err = randomOnG1()
    63  		assert.NoError(t, err)
    64  	}
    65  	return res
    66  }
    67  
    68  func testCommit(t *testing.T, values ...interface{}) {
    69  
    70  	basis := randomG1Slice(t, len(values))
    71  
    72  	var (
    73  		pk              []ProvingKey
    74  		vk              VerifyingKey
    75  		err             error
    76  		commitment, pok curve.G1Affine
    77  	)
    78  	valuesFr := interfaceSliceToFrSlice(t, values...)
    79  
    80  	pk, vk, err = Setup([][]curve.G1Affine{basis})
    81  	assert.NoError(t, err)
    82  	commitment, err = pk[0].Commit(valuesFr)
    83  	assert.NoError(t, err)
    84  	pok, err = pk[0].ProveKnowledge(valuesFr)
    85  	assert.NoError(t, err)
    86  	assert.NoError(t, vk.Verify(commitment, pok))
    87  
    88  	pok.Neg(&pok)
    89  	assert.NotNil(t, vk.Verify(commitment, pok))
    90  }
    91  
    92  func TestFoldProofs(t *testing.T) {
    93  
    94  	values := [][]fr.Element{
    95  		interfaceSliceToFrSlice(t, randomFrSlice(t, 5)...),
    96  		interfaceSliceToFrSlice(t, randomFrSlice(t, 5)...),
    97  		interfaceSliceToFrSlice(t, randomFrSlice(t, 5)...),
    98  	}
    99  
   100  	bases := make([][]curve.G1Affine, len(values))
   101  	for i := range bases {
   102  		bases[i] = randomG1Slice(t, len(values[i]))
   103  	}
   104  
   105  	pk, vk, err := Setup(bases)
   106  	assert.NoError(t, err)
   107  
   108  	commitments := make([]curve.G1Affine, len(values))
   109  	for i := range values {
   110  		commitments[i], err = pk[i].Commit(values[i])
   111  		assert.NoError(t, err)
   112  	}
   113  
   114  	hashes, err := fr.Hash([]byte("test"), []byte("pedersen"), 1)
   115  	assert.NoError(t, err)
   116  
   117  	t.Run("folding with zeros", func(t *testing.T) {
   118  		pokFolded, err := BatchProve(pk[:2], [][]fr.Element{
   119  			values[0],
   120  			make([]fr.Element, len(values[1])),
   121  		}, hashes[0])
   122  		assert.NoError(t, err)
   123  		var pok curve.G1Affine
   124  		pok, err = pk[0].ProveKnowledge(values[0])
   125  		assert.NoError(t, err)
   126  		assert.Equal(t, pok, pokFolded)
   127  	})
   128  
   129  	t.Run("run empty", func(t *testing.T) {
   130  		var foldedCommitment curve.G1Affine
   131  		pok, err := BatchProve([]ProvingKey{}, [][]fr.Element{}, hashes[0])
   132  		assert.NoError(t, err)
   133  
   134  		_, err = foldedCommitment.Fold([]curve.G1Affine{}, hashes[0], ecc.MultiExpConfig{NbTasks: 1})
   135  		assert.NoError(t, err)
   136  		assert.NoError(t, vk.Verify(foldedCommitment, pok))
   137  	})
   138  
   139  	run := func(values [][]fr.Element) func(t *testing.T) {
   140  		return func(t *testing.T) {
   141  
   142  			var foldedCommitment curve.G1Affine
   143  			pok, err := BatchProve(pk[:len(values)], values, hashes[0])
   144  			assert.NoError(t, err)
   145  
   146  			_, err = foldedCommitment.Fold(commitments[:len(values)], hashes[0], ecc.MultiExpConfig{NbTasks: 1})
   147  			assert.NoError(t, err)
   148  			assert.NoError(t, vk.Verify(foldedCommitment, pok))
   149  
   150  			pok.Neg(&pok)
   151  			assert.NotNil(t, vk.Verify(foldedCommitment, pok))
   152  		}
   153  	}
   154  
   155  	for i := range values {
   156  		t.Run(fmt.Sprintf("folding %d", i+1), run(values[:i+1]))
   157  	}
   158  }
   159  
   160  func TestCommitToOne(t *testing.T) {
   161  	testCommit(t, 1)
   162  }
   163  
   164  func TestCommitSingle(t *testing.T) {
   165  	testCommit(t, randomFrSlice(t, 1)...)
   166  }
   167  
   168  func TestCommitFiveElements(t *testing.T) {
   169  	testCommit(t, randomFrSlice(t, 5)...)
   170  }
   171  
   172  func TestMarshal(t *testing.T) {
   173  	var pk ProvingKey
   174  	pk.BasisExpSigma = randomG1Slice(t, 5)
   175  	pk.Basis = randomG1Slice(t, 5)
   176  
   177  	var (
   178  		vk  VerifyingKey
   179  		err error
   180  	)
   181  	vk.G, err = curve.RandomOnG2()
   182  	assert.NoError(t, err)
   183  	vk.GSigma, err = curve.RandomOnG2()
   184  	assert.NoError(t, err)
   185  
   186  	t.Run("ProvingKey -> Bytes -> ProvingKey must remain identical.", testutils.SerializationRoundTrip(&pk))
   187  	t.Run("ProvingKey -> Bytes (raw) -> ProvingKey must remain identical.", testutils.SerializationRoundTripRaw(&pk))
   188  	t.Run("VerifyingKey -> Bytes -> VerifyingKey must remain identical.", testutils.SerializationRoundTrip(&vk))
   189  	t.Run("VerifyingKey -> Bytes (raw) -> ProvingKey must remain identical.", testutils.SerializationRoundTripRaw(&vk))
   190  }
   191  
   192  func TestSemiFoldProofs(t *testing.T) {
   193  	const (
   194  		commitmentLength = 5
   195  		nbCommitments    = 5
   196  	)
   197  	g, err := curve.RandomOnG2()
   198  	assert.NoError(t, err)
   199  
   200  	basis := randomG1Slice(t, commitmentLength*nbCommitments)
   201  
   202  	vk, pk := make([]VerifyingKey, nbCommitments), make([]ProvingKey, nbCommitments)
   203  	for i := range pk {
   204  		var pk0 []ProvingKey
   205  		pk0, vk[i], err = Setup([][]curve.G1Affine{basis[i*commitmentLength : (i+1)*commitmentLength]}, WithG2Point(g))
   206  		assert.NoError(t, err)
   207  		pk[i] = pk0[0]
   208  	}
   209  
   210  	values := make([][]fr.Element, nbCommitments)
   211  	for i := range values {
   212  		values[i] = make([]fr.Element, commitmentLength)
   213  		for j := range values[i] {
   214  			_, err = values[i][j].SetRandom()
   215  			assert.NoError(t, err)
   216  		}
   217  	}
   218  
   219  	commitments := make([]curve.G1Affine, nbCommitments)
   220  	proofs := make([]curve.G1Affine, nbCommitments)
   221  	for i := range commitments {
   222  		commitments[i], err = pk[i].Commit(values[i])
   223  		assert.NoError(t, err)
   224  		proofs[i], err = pk[i].ProveKnowledge(values[i])
   225  		assert.NoError(t, err)
   226  	}
   227  
   228  	var challenge fr.Element
   229  	_, err = challenge.SetRandom()
   230  	assert.NoError(t, err)
   231  
   232  	assert.NoError(t, BatchVerifyMultiVk(vk, commitments, proofs, challenge))
   233  
   234  	// send folded proof
   235  	proof, err := new(curve.G1Affine).Fold(proofs, challenge, ecc.MultiExpConfig{NbTasks: 1})
   236  	assert.NoError(t, err)
   237  	assert.NoError(t, BatchVerifyMultiVk(vk, commitments, []curve.G1Affine{*proof}, challenge))
   238  }