github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/zkp/aggregaterange/bulletproofs/innerproduct.go (about) 1 package bulletproofs 2 3 import ( 4 "errors" 5 "github.com/incognitochain/go-incognito-sdk/privacy" 6 "math" 7 ) 8 9 type InnerProductWitness struct { 10 a []*privacy.Scalar 11 b []*privacy.Scalar 12 p *privacy.Point 13 } 14 15 type InnerProductProof struct { 16 l []*privacy.Point 17 r []*privacy.Point 18 a *privacy.Scalar 19 b *privacy.Scalar 20 p *privacy.Point 21 } 22 23 func (inner *InnerProductProof) Init() *InnerProductProof { 24 if inner == nil { 25 inner = new(InnerProductProof) 26 } 27 inner.l = []*privacy.Point{} 28 inner.r = []*privacy.Point{} 29 inner.a = new(privacy.Scalar) 30 inner.b = new(privacy.Scalar) 31 inner.p = new(privacy.Point).Identity() 32 33 return inner 34 } 35 36 func (proof InnerProductProof) ValidateSanity() bool { 37 if len(proof.l) != len(proof.r) { 38 return false 39 } 40 for i := 0; i < len(proof.l); i++ { 41 if !proof.l[i].PointValid() || !proof.r[i].PointValid() { 42 return false 43 } 44 } 45 if !proof.a.ScalarValid() || !proof.b.ScalarValid() { 46 return false 47 } 48 return proof.p.PointValid() 49 } 50 51 func (proof InnerProductProof) Bytes() []byte { 52 var res []byte 53 54 res = append(res, byte(len(proof.l))) 55 for _, l := range proof.l { 56 res = append(res, l.ToBytesS()...) 57 } 58 59 for _, r := range proof.r { 60 res = append(res, r.ToBytesS()...) 61 } 62 63 res = append(res, proof.a.ToBytesS()...) 64 res = append(res, proof.b.ToBytesS()...) 65 res = append(res, proof.p.ToBytesS()...) 66 67 return res 68 } 69 70 func (proof *InnerProductProof) SetBytes(bytes []byte) error { 71 if len(bytes) == 0 { 72 return nil 73 } 74 75 lenLArray := int(bytes[0]) 76 offset := 1 77 var err error 78 79 proof.l = make([]*privacy.Point, lenLArray) 80 for i := 0; i < lenLArray; i++ { 81 if offset+privacy.Ed25519KeySize > len(bytes){ 82 return errors.New("Inner Product Proof byte unmarshaling failed") 83 } 84 proof.l[i], err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 85 if err != nil { 86 return err 87 } 88 offset += privacy.Ed25519KeySize 89 } 90 91 proof.r = make([]*privacy.Point, lenLArray) 92 for i := 0; i < lenLArray; i++ { 93 if offset+privacy.Ed25519KeySize > len(bytes){ 94 return errors.New("Inner Product Proof byte unmarshaling failed") 95 } 96 proof.r[i], err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 97 if err != nil { 98 return err 99 } 100 offset += privacy.Ed25519KeySize 101 } 102 103 if offset+privacy.Ed25519KeySize > len(bytes){ 104 return errors.New("Inner Product Proof byte unmarshaling failed") 105 } 106 proof.a = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 107 offset += privacy.Ed25519KeySize 108 109 if offset+privacy.Ed25519KeySize > len(bytes){ 110 return errors.New("Inner Product Proof byte unmarshaling failed") 111 } 112 proof.b = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 113 offset += privacy.Ed25519KeySize 114 115 if offset+privacy.Ed25519KeySize > len(bytes){ 116 return errors.New("Inner Product Proof byte unmarshaling failed") 117 } 118 proof.p, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 119 if err != nil { 120 return err 121 } 122 123 return nil 124 } 125 126 func (wit InnerProductWitness) Prove(GParam []*privacy.Point, HParam []*privacy.Point, uParam *privacy.Point, hashCache []byte) (*InnerProductProof, error) { 127 if len(wit.a) != len(wit.b) { 128 return nil, errors.New("invalid inputs") 129 } 130 131 N := len(wit.a) 132 133 a := make([]*privacy.Scalar, N) 134 b := make([]*privacy.Scalar, N) 135 136 for i := range wit.a { 137 a[i] = new(privacy.Scalar).Set(wit.a[i]) 138 b[i] = new(privacy.Scalar).Set(wit.b[i]) 139 } 140 141 p := new(privacy.Point).Set(wit.p) 142 G := make([]*privacy.Point, N) 143 H := make([]*privacy.Point, N) 144 for i := range G { 145 G[i] = new(privacy.Point).Set(GParam[i]) 146 H[i] = new(privacy.Point).Set(HParam[i]) 147 } 148 149 proof := new(InnerProductProof) 150 proof.l = make([]*privacy.Point, 0) 151 proof.r = make([]*privacy.Point, 0) 152 proof.p = new(privacy.Point).Set(wit.p) 153 154 for N > 1 { 155 nPrime := N / 2 156 157 cL, err := innerProduct(a[:nPrime], b[nPrime:]) 158 if err != nil { 159 return nil, err 160 } 161 cR, err := innerProduct(a[nPrime:], b[:nPrime]) 162 if err != nil { 163 return nil, err 164 } 165 166 L, err := encodeVectors(a[:nPrime], b[nPrime:], G[nPrime:], H[:nPrime]) 167 if err != nil { 168 return nil, err 169 } 170 L.Add(L, new(privacy.Point).ScalarMult(uParam, cL)) 171 proof.l = append(proof.l, L) 172 173 R, err := encodeVectors(a[nPrime:], b[:nPrime], G[:nPrime], H[nPrime:]) 174 if err != nil { 175 return nil, err 176 } 177 R.Add(R, new(privacy.Point).ScalarMult(uParam, cR)) 178 proof.r = append(proof.r, R) 179 180 x := generateChallenge(hashCache, []*privacy.Point{L, R}) 181 hashCache = new(privacy.Scalar).Set(x).ToBytesS() 182 183 xInverse := new(privacy.Scalar).Invert(x) 184 xSquare := new(privacy.Scalar).Mul(x, x) 185 xSquareInverse := new(privacy.Scalar).Mul(xInverse, xInverse) 186 187 // calculate GPrime, HPrime, PPrime for the next loop 188 GPrime := make([]*privacy.Point, nPrime) 189 HPrime := make([]*privacy.Point, nPrime) 190 191 for i := range GPrime { 192 GPrime[i] = new(privacy.Point).AddPedersen(xInverse, G[i], x, G[i+nPrime]) 193 HPrime[i] = new(privacy.Point).AddPedersen(x, H[i], xInverse, H[i+nPrime]) 194 } 195 196 // x^2 * l + P + xInverse^2 * r 197 PPrime := new(privacy.Point).AddPedersen(xSquare, L, xSquareInverse, R) 198 PPrime.Add(PPrime, p) 199 200 // calculate aPrime, bPrime 201 aPrime := make([]*privacy.Scalar, nPrime) 202 bPrime := make([]*privacy.Scalar, nPrime) 203 204 for i := range aPrime { 205 aPrime[i] = new(privacy.Scalar).Mul(a[i], x) 206 aPrime[i] = new(privacy.Scalar).MulAdd(a[i+nPrime], xInverse, aPrime[i]) 207 208 bPrime[i] = new(privacy.Scalar).Mul(b[i], xInverse) 209 bPrime[i] = new(privacy.Scalar).MulAdd(b[i+nPrime], x, bPrime[i]) 210 } 211 212 a = aPrime 213 b = bPrime 214 p.Set(PPrime) 215 G = GPrime 216 H = HPrime 217 N = nPrime 218 } 219 220 proof.a = new(privacy.Scalar).Set(a[0]) 221 proof.b = new(privacy.Scalar).Set(b[0]) 222 223 return proof, nil 224 } 225 226 func (proof InnerProductProof) Verify(GParam []*privacy.Point, HParam []*privacy.Point, uParam *privacy.Point, hashCache []byte) bool { 227 //var aggParam = newBulletproofParams(1) 228 p := new(privacy.Point) 229 p.Set(proof.p) 230 231 n := len(GParam) 232 G := make([]*privacy.Point, n) 233 H := make([]*privacy.Point, n) 234 for i := range G { 235 G[i] = new(privacy.Point).Set(GParam[i]) 236 H[i] = new(privacy.Point).Set(HParam[i]) 237 } 238 239 for i := range proof.l { 240 nPrime := n / 2 241 x := generateChallenge(hashCache, []*privacy.Point{proof.l[i], proof.r[i]}) 242 hashCache = new(privacy.Scalar).Set(x).ToBytesS() 243 xInverse := new(privacy.Scalar).Invert(x) 244 xSquare := new(privacy.Scalar).Mul(x, x) 245 xSquareInverse := new(privacy.Scalar).Mul(xInverse, xInverse) 246 247 // calculate GPrime, HPrime, PPrime for the next loop 248 GPrime := make([]*privacy.Point, nPrime) 249 HPrime := make([]*privacy.Point, nPrime) 250 251 for j := 0; j < len(GPrime); j++ { 252 GPrime[j] = new(privacy.Point).AddPedersen(xInverse, G[j], x, G[j+nPrime]) 253 HPrime[j] = new(privacy.Point).AddPedersen(x, H[j], xInverse, H[j+nPrime]) 254 } 255 // calculate x^2 * l + P + xInverse^2 * r 256 PPrime := new(privacy.Point).AddPedersen(xSquare, proof.l[i], xSquareInverse, proof.r[i]) 257 PPrime.Add(PPrime, p) 258 259 p = PPrime 260 G = GPrime 261 H = HPrime 262 n = nPrime 263 } 264 265 c := new(privacy.Scalar).Mul(proof.a, proof.b) 266 rightPoint := new(privacy.Point).AddPedersen(proof.a, G[0], proof.b, H[0]) 267 rightPoint.Add(rightPoint, new(privacy.Point).ScalarMult(uParam, c)) 268 res := privacy.IsPointEqual(rightPoint, p) 269 if !res { 270 //Logger.Log.Error("Inner product argument failed:") 271 //Logger.Log.Error("p: %v\n", p) 272 //Logger.Log.Error("RightPoint: %v\n", rightPoint) 273 } 274 275 return res 276 } 277 278 func (proof InnerProductProof) VerifyFaster(GParam []*privacy.Point, HParam []*privacy.Point, uParam *privacy.Point, hashCache []byte) bool { 279 //var aggParam = newBulletproofParams(1) 280 p := new(privacy.Point) 281 p.Set(proof.p) 282 n := len(GParam) 283 G := make([]*privacy.Point, n) 284 H := make([]*privacy.Point, n) 285 s := make([]*privacy.Scalar, n) 286 sInverse := make([]*privacy.Scalar, n) 287 288 for i := range G { 289 G[i] = new(privacy.Point).Set(GParam[i]) 290 H[i] = new(privacy.Point).Set(HParam[i]) 291 s[i] = new(privacy.Scalar).FromUint64(1) 292 sInverse[i] = new(privacy.Scalar).FromUint64(1) 293 } 294 logN := int(math.Log2(float64(n))) 295 xList := make([]*privacy.Scalar, logN) 296 xInverseList := make([]*privacy.Scalar, logN) 297 xSquareList := make([]*privacy.Scalar, logN) 298 xInverseSquare_List := make([]*privacy.Scalar, logN) 299 300 //a*s ; b*s^-1 301 302 for i := range proof.l { 303 // calculate challenge x = hash(hash(G || H || u || p) || x || l || r) 304 xList[i] = generateChallenge(hashCache, []*privacy.Point{proof.l[i], proof.r[i]}) 305 hashCache = new(privacy.Scalar).Set(xList[i]).ToBytesS() 306 307 xInverseList[i] = new(privacy.Scalar).Invert(xList[i]) 308 xSquareList[i] = new(privacy.Scalar).Mul(xList[i], xList[i]) 309 xInverseSquare_List[i] = new(privacy.Scalar).Mul(xInverseList[i], xInverseList[i]) 310 311 //Update s, s^-1 312 for j := 0; j < n; j++ { 313 if j&int(math.Pow(2, float64(logN-i-1))) != 0 { 314 s[j] = new(privacy.Scalar).Mul(s[j], xList[i]) 315 sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], xInverseList[i]) 316 } else { 317 s[j] = new(privacy.Scalar).Mul(s[j], xInverseList[i]) 318 sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], xList[i]) 319 } 320 } 321 } 322 323 // Compute (g^s)^a (h^-s)^b u^(ab) = p l^(x^2) r^(-x^2) 324 c := new(privacy.Scalar).Mul(proof.a, proof.b) 325 rightHSPart1 := new(privacy.Point).MultiScalarMult(s, G) 326 rightHSPart1.ScalarMult(rightHSPart1, proof.a) 327 rightHSPart2 := new(privacy.Point).MultiScalarMult(sInverse, H) 328 rightHSPart2.ScalarMult(rightHSPart2, proof.b) 329 330 rightHS := new(privacy.Point).Add(rightHSPart1, rightHSPart2) 331 rightHS.Add(rightHS, new(privacy.Point).ScalarMult(uParam, c)) 332 333 leftHSPart1 := new(privacy.Point).MultiScalarMult(xSquareList, proof.l) 334 leftHSPart2 := new(privacy.Point).MultiScalarMult(xInverseSquare_List, proof.r) 335 336 leftHS := new(privacy.Point).Add(leftHSPart1, leftHSPart2) 337 leftHS.Add(leftHS, proof.p) 338 339 res := privacy.IsPointEqual(rightHS, leftHS) 340 if !res { 341 //Logger.Log.Error("Inner product argument failed:") 342 //Logger.Log.Error("LHS: %v\n", leftHS) 343 //Logger.Log.Error("RHS: %v\n", rightHS) 344 } 345 346 return res 347 }