-
Notifications
You must be signed in to change notification settings - Fork 150
/
pedersen.go
113 lines (93 loc) · 3.12 KB
/
pedersen.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright 2020 ConsenSys Software Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by consensys/gnark-crypto DO NOT EDIT
package pedersen
import (
"crypto/rand"
"fmt"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark-crypto/ecc/bls12-378"
"github.com/consensys/gnark-crypto/ecc/bls12-378/fr"
"math/big"
)
// Key for proof and verification
type Key struct {
g bls12378.G2Affine // TODO @tabaie: does this really have to be randomized?
gRootSigmaNeg bls12378.G2Affine //gRootSigmaNeg = g^{-1/σ}
basis []bls12378.G1Affine
basisExpSigma []bls12378.G1Affine
}
func randomOnG2() (bls12378.G2Affine, error) { // TODO: Add to G2.go?
gBytes := make([]byte, fr.Bytes)
if _, err := rand.Read(gBytes); err != nil {
return bls12378.G2Affine{}, err
}
return bls12378.HashToG2(gBytes, []byte("random on g2"))
}
func Setup(basis []bls12378.G1Affine) (Key, error) {
var (
k Key
err error
)
if k.g, err = randomOnG2(); err != nil {
return k, err
}
var modMinusOne big.Int
modMinusOne.Sub(fr.Modulus(), big.NewInt(1))
var sigma *big.Int
if sigma, err = rand.Int(rand.Reader, &modMinusOne); err != nil {
return k, err
}
sigma.Add(sigma, big.NewInt(1))
var sigmaInvNeg big.Int
sigmaInvNeg.ModInverse(sigma, fr.Modulus())
sigmaInvNeg.Sub(fr.Modulus(), &sigmaInvNeg)
k.gRootSigmaNeg.ScalarMultiplication(&k.g, &sigmaInvNeg)
k.basisExpSigma = make([]bls12378.G1Affine, len(basis))
for i := range basis {
k.basisExpSigma[i].ScalarMultiplication(&basis[i], sigma)
}
k.basis = basis
return k, err
}
func (k *Key) Commit(values []fr.Element) (commitment bls12378.G1Affine, knowledgeProof bls12378.G1Affine, err error) {
if len(values) != len(k.basis) {
err = fmt.Errorf("unexpected number of values")
return
}
// TODO @gbotrel this will spawn more than one task, see
// https://github.com/ConsenSys/gnark-crypto/issues/269
config := ecc.MultiExpConfig{
NbTasks: 1, // TODO Experiment
}
if _, err = commitment.MultiExp(k.basis, values, config); err != nil {
return
}
_, err = knowledgeProof.MultiExp(k.basisExpSigma, values, config)
return
}
// VerifyKnowledgeProof checks if the proof of knowledge is valid
func (k *Key) VerifyKnowledgeProof(commitment bls12378.G1Affine, knowledgeProof bls12378.G1Affine) error {
if !commitment.IsInSubGroup() || !knowledgeProof.IsInSubGroup() {
return fmt.Errorf("subgroup check failed")
}
product, err := bls12378.Pair([]bls12378.G1Affine{commitment, knowledgeProof}, []bls12378.G2Affine{k.g, k.gRootSigmaNeg})
if err != nil {
return err
}
if product.IsOne() {
return nil
}
return fmt.Errorf("proof rejected")
}