-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathverify.go
111 lines (93 loc) · 2.68 KB
/
verify.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
package dleq
import (
"errors"
"fmt"
)
// Verify verifies the proof is valid against the given curves.
// TODO: encode curves into proof somehow?
func (p *Proof) Verify(curveA, curveB Curve) error {
commitmentsA := make([]commitment, len(p.proofs))
for i := range commitmentsA {
commitmentsA[i] = p.proofs[i].commitmentA
}
err := verifyCommitmentsSum(curveA, commitmentsA, p.CommitmentA)
if err != nil {
return fmt.Errorf("failed to verify commitment on curve A: %w", err)
}
commitmentsB := make([]commitment, len(p.proofs))
for i := range commitmentsB {
commitmentsB[i] = p.proofs[i].commitmentB
}
err = verifyCommitmentsSum(curveB, commitmentsB, p.CommitmentB)
if err != nil {
return fmt.Errorf("failed to verify commitment on curve B: %w", err)
}
// verify signatures
ok := curveA.Verify(p.CommitmentA, p.CommitmentA, p.signatureA.inner)
if !ok {
return fmt.Errorf("failed to verify signature on commitment A")
}
ok = curveB.Verify(p.CommitmentB, p.CommitmentB, p.signatureB.inner)
if !ok {
return fmt.Errorf("failed to verify signature on commitment B")
}
// now calculate challenges and verify
bits := min(curveA.BitSize(), curveB.BitSize())
for i := uint64(0); i < bits; i++ {
proof := p.proofs[i]
aG := curveA.ScalarMul(proof.ringSig.a1, curveA.AltBasePoint())
eCA := proof.commitmentA.commitment.ScalarMul(proof.ringSig.eCurveA)
bH := curveB.ScalarMul(proof.ringSig.b1, curveB.AltBasePoint())
eCB := proof.commitmentB.commitment.ScalarMul(proof.ringSig.eCurveB)
eA1, err := hashToScalar(
curveA,
proof.commitmentA.commitment,
proof.commitmentB.commitment,
aG.Sub(eCA),
bH.Sub(eCB),
)
if err != nil {
return err
}
eB1, err := hashToScalar(
curveB,
proof.commitmentA.commitment,
proof.commitmentB.commitment,
aG.Sub(eCA),
bH.Sub(eCB),
)
if err != nil {
return err
}
commitmentAMinusOne := proof.commitmentA.commitment.Sub(curveA.BasePoint())
commitmentBMinusOne := proof.commitmentB.commitment.Sub(curveB.BasePoint())
aG = curveA.ScalarMul(proof.ringSig.a0, curveA.AltBasePoint())
bH = curveB.ScalarMul(proof.ringSig.b0, curveB.AltBasePoint())
ecA := commitmentAMinusOne.ScalarMul(eA1)
ecB := commitmentBMinusOne.ScalarMul(eB1)
eA0, err := hashToScalar(
curveA,
proof.commitmentA.commitment,
proof.commitmentB.commitment,
aG.Sub(ecA),
bH.Sub(ecB),
)
if err != nil {
return err
}
eB0, err := hashToScalar(
curveB,
proof.commitmentA.commitment,
proof.commitmentB.commitment,
aG.Sub(ecA),
bH.Sub(ecB),
)
if err != nil {
return err
}
if !eA0.Eq(proof.ringSig.eCurveA) || !eB0.Eq(proof.ringSig.eCurveB) {
return errors.New("invalid proof")
}
}
return nil
}