github.com/consensys/gnark-crypto@v0.14.0/internal/generator/pedersen/template/pedersen.test.go.tmpl (about) 1 import ( 2 "fmt" 3 "testing" 4 5 "github.com/consensys/gnark-crypto/ecc" 6 curve "github.com/consensys/gnark-crypto/ecc/{{.Name}}" 7 "github.com/consensys/gnark-crypto/ecc/{{.Name}}/fr" 8 "github.com/consensys/gnark-crypto/utils/testutils" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func interfaceSliceToFrSlice(t *testing.T, values ...interface{}) []fr.Element { 13 res := make([]fr.Element, len(values)) 14 for i, v := range values { 15 _, err := res[i].SetInterface(v) 16 assert.NoError(t, err) 17 } 18 return res 19 } 20 21 func randomFrSlice(t *testing.T, size int) []interface{} { 22 res := make([]interface{}, size) 23 var err error 24 for i := range res { 25 var v fr.Element 26 res[i], err = v.SetRandom() 27 assert.NoError(t, err) 28 } 29 return res 30 } 31 32 func randomOnG1() (curve.G1Affine, error) { // TODO: Add to G1.go? 33 if gBytes, err := randomFrSizedBytes(); err != nil { 34 return curve.G1Affine{}, err 35 } else { 36 return curve.HashToG1(gBytes, []byte("random on g1")) 37 } 38 } 39 40 func randomG1Slice(t *testing.T, size int) []curve.G1Affine { 41 res := make([]curve.G1Affine, size) 42 for i := range res { 43 var err error 44 res[i], err = randomOnG1() 45 assert.NoError(t, err) 46 } 47 return res 48 } 49 50 func testCommit(t *testing.T, values ...interface{}) { 51 52 basis := randomG1Slice(t, len(values)) 53 54 var ( 55 pk []ProvingKey 56 vk VerifyingKey 57 err error 58 commitment, pok curve.G1Affine 59 ) 60 valuesFr := interfaceSliceToFrSlice(t, values...) 61 62 pk, vk, err = Setup([][]curve.G1Affine{basis}) 63 assert.NoError(t, err) 64 commitment, err = pk[0].Commit(valuesFr) 65 assert.NoError(t, err) 66 pok, err = pk[0].ProveKnowledge(valuesFr) 67 assert.NoError(t, err) 68 assert.NoError(t, vk.Verify(commitment, pok)) 69 70 pok.Neg(&pok) 71 assert.NotNil(t, vk.Verify(commitment, pok)) 72 } 73 74 func TestFoldProofs(t *testing.T) { 75 76 values := [][]fr.Element{ 77 interfaceSliceToFrSlice(t, randomFrSlice(t, 5)...), 78 interfaceSliceToFrSlice(t, randomFrSlice(t, 5)...), 79 interfaceSliceToFrSlice(t, randomFrSlice(t, 5)...), 80 } 81 82 bases := make([][]curve.G1Affine, len(values)) 83 for i := range bases { 84 bases[i] = randomG1Slice(t, len(values[i])) 85 } 86 87 pk, vk, err := Setup(bases) 88 assert.NoError(t, err) 89 90 commitments := make([]curve.G1Affine, len(values)) 91 for i := range values { 92 commitments[i], err = pk[i].Commit(values[i]) 93 assert.NoError(t, err) 94 } 95 96 hashes, err := fr.Hash([]byte("test"), []byte("pedersen"), 1) 97 assert.NoError(t, err) 98 99 t.Run("folding with zeros", func(t *testing.T) { 100 pokFolded, err := BatchProve(pk[:2], [][]fr.Element{ 101 values[0], 102 make([]fr.Element, len(values[1])), 103 }, hashes[0]) 104 assert.NoError(t, err) 105 var pok curve.G1Affine 106 pok, err = pk[0].ProveKnowledge(values[0]) 107 assert.NoError(t, err) 108 assert.Equal(t, pok, pokFolded) 109 }) 110 111 t.Run("run empty", func(t *testing.T) { 112 var foldedCommitment curve.G1Affine 113 pok, err := BatchProve([]ProvingKey{}, [][]fr.Element{}, hashes[0]) 114 assert.NoError(t, err) 115 116 _, err = foldedCommitment.Fold([]curve.G1Affine{}, hashes[0], ecc.MultiExpConfig{NbTasks: 1}) 117 assert.NoError(t, err) 118 assert.NoError(t, vk.Verify(foldedCommitment, pok)) 119 }) 120 121 run := func(values [][]fr.Element) func(t *testing.T) { 122 return func(t *testing.T) { 123 124 var foldedCommitment curve.G1Affine 125 pok, err := BatchProve(pk[:len(values)], values, hashes[0]) 126 assert.NoError(t, err) 127 128 _, err = foldedCommitment.Fold(commitments[:len(values)], hashes[0], ecc.MultiExpConfig{NbTasks: 1}) 129 assert.NoError(t, err) 130 assert.NoError(t, vk.Verify(foldedCommitment, pok)) 131 132 pok.Neg(&pok) 133 assert.NotNil(t, vk.Verify(foldedCommitment, pok)) 134 } 135 } 136 137 for i := range values { 138 t.Run(fmt.Sprintf("folding %d", i+1), run(values[:i+1])) 139 } 140 } 141 142 func TestCommitToOne(t *testing.T) { 143 testCommit(t, 1) 144 } 145 146 func TestCommitSingle(t *testing.T) { 147 testCommit(t, randomFrSlice(t, 1)...) 148 } 149 150 func TestCommitFiveElements(t *testing.T) { 151 testCommit(t, randomFrSlice(t, 5)...) 152 } 153 154 func TestMarshal(t *testing.T) { 155 var pk ProvingKey 156 pk.BasisExpSigma = randomG1Slice(t, 5) 157 pk.Basis = randomG1Slice(t, 5) 158 159 var ( 160 vk VerifyingKey 161 err error 162 ) 163 vk.G, err = curve.RandomOnG2() 164 assert.NoError(t, err) 165 vk.GSigma, err = curve.RandomOnG2() 166 assert.NoError(t, err) 167 168 t.Run("ProvingKey -> Bytes -> ProvingKey must remain identical.", testutils.SerializationRoundTrip(&pk)) 169 t.Run("ProvingKey -> Bytes (raw) -> ProvingKey must remain identical.", testutils.SerializationRoundTripRaw(&pk)) 170 t.Run("VerifyingKey -> Bytes -> VerifyingKey must remain identical.", testutils.SerializationRoundTrip(&vk)) 171 t.Run("VerifyingKey -> Bytes (raw) -> ProvingKey must remain identical.", testutils.SerializationRoundTripRaw(&vk)) 172 } 173 174 175 func TestSemiFoldProofs(t *testing.T) { 176 const ( 177 commitmentLength = 5 178 nbCommitments = 5 179 ) 180 g, err := curve.RandomOnG2() 181 assert.NoError(t, err) 182 183 basis := randomG1Slice(t, commitmentLength*nbCommitments) 184 185 vk, pk := make([]VerifyingKey, nbCommitments), make([]ProvingKey, nbCommitments) 186 for i := range pk { 187 var pk0 []ProvingKey 188 pk0, vk[i], err = Setup([][]curve.G1Affine{basis[i*commitmentLength : (i+1)*commitmentLength]}, WithG2Point(g)) 189 assert.NoError(t, err) 190 pk[i] = pk0[0] 191 } 192 193 values := make([][]fr.Element, nbCommitments) 194 for i := range values { 195 values[i] = make([]fr.Element, commitmentLength) 196 for j := range values[i] { 197 _, err = values[i][j].SetRandom() 198 assert.NoError(t, err) 199 } 200 } 201 202 commitments := make([]curve.G1Affine, nbCommitments) 203 proofs := make([]curve.G1Affine, nbCommitments) 204 for i := range commitments { 205 commitments[i], err = pk[i].Commit(values[i]) 206 assert.NoError(t, err) 207 proofs[i], err = pk[i].ProveKnowledge(values[i]) 208 assert.NoError(t, err) 209 } 210 211 var challenge fr.Element 212 _, err = challenge.SetRandom() 213 assert.NoError(t, err) 214 215 assert.NoError(t, BatchVerifyMultiVk(vk, commitments, proofs, challenge)) 216 217 // send folded proof 218 proof, err := new(curve.G1Affine).Fold(proofs, challenge, ecc.MultiExpConfig{NbTasks: 1}) 219 assert.NoError(t, err) 220 assert.NoError(t, BatchVerifyMultiVk(vk, commitments, []curve.G1Affine{*proof}, challenge)) 221 }