1
1
package group
2
2
3
3
import (
4
+ "fmt"
5
+
4
6
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
7
+ "github.com/jsign/curdleproofs/common"
5
8
)
6
9
7
10
type Group interface {
@@ -11,9 +14,11 @@ type Group interface {
11
14
type Element interface {
12
15
ScalarMultiplication (e Element , scalar fr.Element ) Element
13
16
Set (e Element ) Element
17
+ Add (a , b Element ) Element
14
18
AddAssign (e Element ) Element
15
19
Equal (e Element ) bool
16
20
Bytes () []byte
21
+ MultiExp ([]Element , []fr.Element ) (Element , error )
17
22
}
18
23
19
24
type GroupCommitment struct {
@@ -68,3 +73,73 @@ func (gc *GroupCommitment) Mul(scalar fr.Element) GroupCommitment {
68
73
func (t GroupCommitment ) Eq (cm GroupCommitment ) bool {
69
74
return t .T_1 .Equal (cm .T_1 ) && t .T_2 .Equal (cm .T_2 )
70
75
}
76
+
77
+ type MsmAccumulator struct {
78
+ g Group
79
+ A_c Element
80
+ baseScalarMap []msmCoeff
81
+ }
82
+
83
+ type msmCoeff struct {
84
+ basis Element
85
+ scalar fr.Element
86
+ }
87
+
88
+ func NewMsmAccumulator (g Group ) * MsmAccumulator {
89
+ return & MsmAccumulator {
90
+ g : g ,
91
+ A_c : g .CreateElement (),
92
+ baseScalarMap : nil ,
93
+ }
94
+ }
95
+
96
+ func (ma * MsmAccumulator ) AccumulateCheck (
97
+ C Element ,
98
+ scalar []fr.Element ,
99
+ basis []Element ,
100
+ rand * common.Rand ) error {
101
+ if len (basis ) != len (scalar ) {
102
+ return fmt .Errorf ("x and v must have the same length" )
103
+ }
104
+
105
+ alpha , err := rand .GetFr ()
106
+ if err != nil {
107
+ return fmt .Errorf ("get random scalar: %s" , err )
108
+ }
109
+
110
+ var tmp fr.Element
111
+ outer:
112
+ for i := 0 ; i < len (basis ); i ++ {
113
+ tmp .Mul (& alpha , & scalar [i ])
114
+
115
+ for j := range ma .baseScalarMap {
116
+ if ma .baseScalarMap [j ].basis .Equal (basis [i ]) {
117
+ var scalar fr.Element
118
+ scalar .Add (& ma .baseScalarMap [j ].scalar , & tmp )
119
+ ma .baseScalarMap [j ].scalar = scalar
120
+ continue outer
121
+ }
122
+ }
123
+ ma .baseScalarMap = append (ma .baseScalarMap , msmCoeff {basis : basis [i ], scalar : tmp })
124
+ }
125
+ ma .A_c .AddAssign (C .ScalarMultiplication (C , alpha ))
126
+
127
+ return nil
128
+ }
129
+
130
+ func (ma * MsmAccumulator ) Verify () (bool , error ) {
131
+ x := make ([]fr.Element , 0 , len (ma .baseScalarMap ))
132
+ v := make ([]Element , 0 , len (ma .baseScalarMap ))
133
+
134
+ for _ , coeff := range ma .baseScalarMap {
135
+ v = append (v , coeff .basis )
136
+ x = append (x , coeff .scalar )
137
+ }
138
+
139
+ msmRes := ma .g .CreateElement ()
140
+ if _ , err := msmRes .MultiExp (v , x ); err != nil {
141
+ return false , fmt .Errorf ("computing msm: %s" , err )
142
+ }
143
+
144
+ return msmRes .Equal (ma .A_c ), nil
145
+ }
0 commit comments