github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/zkp/aggregaterange/aggregaterange.go (about) 1 package aggregaterange 2 3 import ( 4 "fmt" 5 "github.com/incognitochain/go-incognito-sdk/privacy" 6 "github.com/incognitochain/go-incognito-sdk/privacy/zkp/aggregaterange/bulletproofs" 7 "github.com/pkg/errors" 8 ) 9 10 // This protocol proves in zero-knowledge that a list of committed values falls in [0, 2^64) 11 12 type AggregatedRangeWitness struct { 13 values []uint64 14 rands []*privacy.Scalar 15 } 16 17 type AggregatedRangeProof struct { 18 cmsValue []*privacy.Point 19 a *privacy.Point 20 s *privacy.Point 21 t1 *privacy.Point 22 t2 *privacy.Point 23 tauX *privacy.Scalar 24 tHat *privacy.Scalar 25 mu *privacy.Scalar 26 innerProductProof *InnerProductProof 27 } 28 29 func (proof AggregatedRangeProof) GetCmValues() []*privacy.Point { 30 return proof.cmsValue 31 } 32 33 func (proof AggregatedRangeProof) ValidateSanity() bool { 34 for i := 0; i < len(proof.cmsValue); i++ { 35 if !proof.cmsValue[i].PointValid() { 36 return false 37 } 38 } 39 if !proof.a.PointValid() { 40 return false 41 } 42 if !proof.s.PointValid() { 43 return false 44 } 45 if !proof.t1.PointValid() { 46 return false 47 } 48 if !proof.t2.PointValid() { 49 return false 50 } 51 if !proof.tauX.ScalarValid() { 52 return false 53 } 54 if !proof.tHat.ScalarValid() { 55 return false 56 } 57 if !proof.mu.ScalarValid() { 58 return false 59 } 60 61 return proof.innerProductProof.ValidateSanity() 62 } 63 64 func (proof *AggregatedRangeProof) Init() { 65 proof.a = new(privacy.Point).Identity() 66 proof.s = new(privacy.Point).Identity() 67 proof.t1 = new(privacy.Point).Identity() 68 proof.t2 = new(privacy.Point).Identity() 69 proof.tauX = new(privacy.Scalar) 70 proof.tHat = new(privacy.Scalar) 71 proof.mu = new(privacy.Scalar) 72 proof.innerProductProof = new(InnerProductProof) 73 } 74 75 func (proof AggregatedRangeProof) IsNil() bool { 76 if proof.a == nil { 77 return true 78 } 79 if proof.s == nil { 80 return true 81 } 82 if proof.t1 == nil { 83 return true 84 } 85 if proof.t2 == nil { 86 return true 87 } 88 if proof.tauX == nil { 89 return true 90 } 91 if proof.tHat == nil { 92 return true 93 } 94 if proof.mu == nil { 95 return true 96 } 97 return proof.innerProductProof == nil 98 } 99 100 func (proof AggregatedRangeProof) Bytes() []byte { 101 var res []byte 102 103 if proof.IsNil() { 104 return []byte{} 105 } 106 107 res = append(res, byte(len(proof.cmsValue))) 108 for i := 0; i < len(proof.cmsValue); i++ { 109 res = append(res, proof.cmsValue[i].ToBytesS()...) 110 } 111 112 res = append(res, proof.a.ToBytesS()...) 113 res = append(res, proof.s.ToBytesS()...) 114 res = append(res, proof.t1.ToBytesS()...) 115 res = append(res, proof.t2.ToBytesS()...) 116 117 res = append(res, proof.tauX.ToBytesS()...) 118 res = append(res, proof.tHat.ToBytesS()...) 119 res = append(res, proof.mu.ToBytesS()...) 120 res = append(res, proof.innerProductProof.Bytes()...) 121 122 return res 123 124 } 125 126 func (proof *AggregatedRangeProof) SetBytes(bytes []byte) error { 127 if len(bytes) == 0 { 128 return nil 129 } 130 131 lenValues := int(bytes[0]) 132 offset := 1 133 var err error 134 135 proof.cmsValue = make([]*privacy.Point, lenValues) 136 for i := 0; i < lenValues; i++ { 137 proof.cmsValue[i], err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 138 if err != nil { 139 return err 140 } 141 offset += privacy.Ed25519KeySize 142 } 143 144 proof.a, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 145 if err != nil { 146 return err 147 } 148 offset += privacy.Ed25519KeySize 149 150 proof.s, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 151 if err != nil { 152 return err 153 } 154 offset += privacy.Ed25519KeySize 155 156 proof.t1, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 157 if err != nil { 158 return err 159 } 160 offset += privacy.Ed25519KeySize 161 162 proof.t2, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 163 if err != nil { 164 return err 165 } 166 offset += privacy.Ed25519KeySize 167 168 proof.tauX = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 169 offset += privacy.Ed25519KeySize 170 171 proof.tHat = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 172 offset += privacy.Ed25519KeySize 173 174 proof.mu = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 175 offset += privacy.Ed25519KeySize 176 177 proof.innerProductProof = new(InnerProductProof) 178 proof.innerProductProof.SetBytes(bytes[offset:]) 179 180 return nil 181 } 182 183 func (wit *AggregatedRangeWitness) Set(values []uint64, rands []*privacy.Scalar) { 184 numValue := len(values) 185 wit.values = make([]uint64, numValue) 186 wit.rands = make([]*privacy.Scalar, numValue) 187 188 for i := range values { 189 wit.values[i] = values[i] 190 wit.rands[i] = new(privacy.Scalar).Set(rands[i]) 191 } 192 } 193 194 func (wit AggregatedRangeWitness) Prove() (*AggregatedRangeProof, error) { 195 wit2 := new(bulletproofs.AggregatedRangeWitness) 196 wit2.Set(wit.values, wit.rands) 197 198 proof2, err := wit2.Prove() 199 if err != nil { 200 return nil, errors.New(fmt.Sprintf("cannot prove bulletproof v2. Error %v", err)) 201 } 202 proof2Bytes := proof2.Bytes() 203 proof := new(AggregatedRangeProof) 204 err = proof.SetBytes(proof2Bytes) 205 if err != nil { 206 fmt.Println("Error:", err) 207 return nil, errors.New(fmt.Sprintf("cannot convert proof ver 2 to ver 1. Error %v", err)) 208 } 209 return proof, nil 210 } 211 212 func (proof AggregatedRangeProof) Verify() (bool, error) { 213 numValue := len(proof.cmsValue) 214 if numValue > maxOutputNumber { 215 return false, errors.New("Must less than maxOutputNumber") 216 } 217 numValuePad := pad(numValue) 218 aggParam := new(bulletproofParams) 219 aggParam.g = AggParam.g[0 : numValuePad*maxExp] 220 aggParam.h = AggParam.h[0 : numValuePad*maxExp] 221 aggParam.u = AggParam.u 222 csByteH := []byte{} 223 csByteG := []byte{} 224 for i := 0; i < len(aggParam.g); i++ { 225 csByteG = append(csByteG, aggParam.g[i].ToBytesS()...) 226 csByteH = append(csByteH, aggParam.h[i].ToBytesS()...) 227 } 228 aggParam.cs = append(aggParam.cs, csByteG...) 229 aggParam.cs = append(aggParam.cs, csByteH...) 230 aggParam.cs = append(aggParam.cs, aggParam.u.ToBytesS()...) 231 232 tmpcmsValue := proof.cmsValue 233 234 for i := numValue; i < numValuePad; i++ { 235 identity := new(privacy.Point).Identity() 236 tmpcmsValue = append(tmpcmsValue, identity) 237 } 238 239 n := maxExp 240 oneNumber := new(privacy.Scalar).FromUint64(1) 241 twoNumber := new(privacy.Scalar).FromUint64(2) 242 oneVector := powerVector(oneNumber, n*numValuePad) 243 oneVectorN := powerVector(oneNumber, n) 244 twoVectorN := powerVector(twoNumber, n) 245 246 // recalculate challenge y, z 247 y := generateChallenge([][]byte{aggParam.cs, proof.a.ToBytesS(), proof.s.ToBytesS()}) 248 z := generateChallenge([][]byte{aggParam.cs, proof.a.ToBytesS(), proof.s.ToBytesS(), y.ToBytesS()}) 249 zSquare := new(privacy.Scalar).Mul(z, z) 250 251 // challenge x = hash(G || H || A || S || T1 || T2) 252 //fmt.Printf("T2: %v\n", proof.t2) 253 x := generateChallenge([][]byte{aggParam.cs, proof.a.ToBytesS(), proof.s.ToBytesS(), proof.t1.ToBytesS(), proof.t2.ToBytesS()}) 254 xSquare := new(privacy.Scalar).Mul(x, x) 255 256 yVector := powerVector(y, n*numValuePad) 257 // HPrime = H^(y^(1-i) 258 HPrime := make([]*privacy.Point, n*numValuePad) 259 yInverse := new(privacy.Scalar).Invert(y) 260 expyInverse := new(privacy.Scalar).FromUint64(1) 261 for i := 0; i < n*numValuePad; i++ { 262 HPrime[i] = new(privacy.Point).ScalarMult(aggParam.h[i], expyInverse) 263 expyInverse.Mul(expyInverse, yInverse) 264 } 265 266 // g^tHat * h^tauX = V^(z^2) * g^delta(y,z) * T1^x * T2^(x^2) 267 deltaYZ := new(privacy.Scalar).Sub(z, zSquare) 268 269 // innerProduct1 = <1^(n*m), y^(n*m)> 270 innerProduct1, err := innerProduct(oneVector, yVector) 271 if err != nil { 272 return false, privacy.NewPrivacyErr(privacy.CalInnerProductErr, err) 273 } 274 275 deltaYZ.Mul(deltaYZ, innerProduct1) 276 277 // innerProduct2 = <1^n, 2^n> 278 innerProduct2, err := innerProduct(oneVectorN, twoVectorN) 279 if err != nil { 280 return false, privacy.NewPrivacyErr(privacy.CalInnerProductErr, err) 281 } 282 283 sum := new(privacy.Scalar).FromUint64(0) 284 zTmp := new(privacy.Scalar).Set(zSquare) 285 for j := 0; j < numValuePad; j++ { 286 zTmp.Mul(zTmp, z) 287 sum.Add(sum, zTmp) 288 } 289 sum.Mul(sum, innerProduct2) 290 deltaYZ.Sub(deltaYZ, sum) 291 292 left1 := privacy.PedCom.CommitAtIndex(proof.tHat, proof.tauX, privacy.PedersenValueIndex) 293 294 right1 := new(privacy.Point).ScalarMult(proof.t2, xSquare) 295 right1.Add(right1, new(privacy.Point).AddPedersen(deltaYZ, privacy.PedCom.G[privacy.PedersenValueIndex], x, proof.t1)) 296 297 expVector := vectorMulScalar(powerVector(z, numValuePad), zSquare) 298 right1.Add(right1, new(privacy.Point).MultiScalarMult(expVector, tmpcmsValue)) 299 300 if !privacy.IsPointEqual(left1, right1) { 301 return false, errors.New("verify aggregated range proof statement 1 failed") 302 } 303 304 innerProductArgValid := proof.innerProductProof.Verify(aggParam) 305 if !innerProductArgValid { 306 return false, errors.New("verify aggregated range proof statement 2 failed") 307 } 308 309 return true, nil 310 } 311 312 func VerifyBatchingAggregatedRangeProofs(proofs []*AggregatedRangeProof) (bool, error, int) { 313 innerProductProofs := make([]*InnerProductProof, 0) 314 csList := make([][]byte, 0) 315 for k, proof := range proofs { 316 numValue := len(proof.cmsValue) 317 if numValue > maxOutputNumber { 318 return false, errors.New("Must less than maxOutputNumber"), k 319 } 320 numValuePad := pad(numValue) 321 aggParam := new(bulletproofParams) 322 aggParam.g = AggParam.g[0 : numValuePad*maxExp] 323 aggParam.h = AggParam.h[0 : numValuePad*maxExp] 324 aggParam.u = AggParam.u 325 csByteH := []byte{} 326 csByteG := []byte{} 327 for i := 0; i < len(aggParam.g); i++ { 328 csByteG = append(csByteG, aggParam.g[i].ToBytesS()...) 329 csByteH = append(csByteH, aggParam.h[i].ToBytesS()...) 330 } 331 aggParam.cs = append(aggParam.cs, csByteG...) 332 aggParam.cs = append(aggParam.cs, csByteH...) 333 aggParam.cs = append(aggParam.cs, aggParam.u.ToBytesS()...) 334 335 tmpcmsValue := proof.cmsValue 336 337 for i := numValue; i < numValuePad; i++ { 338 identity := new(privacy.Point).Identity() 339 tmpcmsValue = append(tmpcmsValue, identity) 340 } 341 342 n := maxExp 343 oneNumber := new(privacy.Scalar).FromUint64(1) 344 twoNumber := new(privacy.Scalar).FromUint64(2) 345 oneVector := powerVector(oneNumber, n*numValuePad) 346 oneVectorN := powerVector(oneNumber, n) 347 twoVectorN := powerVector(twoNumber, n) 348 349 // recalculate challenge y, z 350 y := generateChallenge([][]byte{aggParam.cs, proof.a.ToBytesS(), proof.s.ToBytesS()}) 351 z := generateChallenge([][]byte{aggParam.cs, proof.a.ToBytesS(), proof.s.ToBytesS(), y.ToBytesS()}) 352 zSquare := new(privacy.Scalar).Mul(z, z) 353 354 // challenge x = hash(G || H || A || S || T1 || T2) 355 //fmt.Printf("T2: %v\n", proof.t2) 356 x := generateChallenge([][]byte{aggParam.cs, proof.a.ToBytesS(), proof.s.ToBytesS(), proof.t1.ToBytesS(), proof.t2.ToBytesS()}) 357 xSquare := new(privacy.Scalar).Mul(x, x) 358 359 yVector := powerVector(y, n*numValuePad) 360 // HPrime = H^(y^(1-i) 361 HPrime := make([]*privacy.Point, n*numValuePad) 362 yInverse := new(privacy.Scalar).Invert(y) 363 expyInverse := new(privacy.Scalar).FromUint64(1) 364 for i := 0; i < n*numValuePad; i++ { 365 HPrime[i] = new(privacy.Point).ScalarMult(aggParam.h[i], expyInverse) 366 expyInverse.Mul(expyInverse, yInverse) 367 } 368 369 // g^tHat * h^tauX = V^(z^2) * g^delta(y,z) * T1^x * T2^(x^2) 370 deltaYZ := new(privacy.Scalar).Sub(z, zSquare) 371 372 // innerProduct1 = <1^(n*m), y^(n*m)> 373 innerProduct1, err := innerProduct(oneVector, yVector) 374 if err != nil { 375 return false, privacy.NewPrivacyErr(privacy.CalInnerProductErr, err), k 376 } 377 378 deltaYZ.Mul(deltaYZ, innerProduct1) 379 380 // innerProduct2 = <1^n, 2^n> 381 innerProduct2, err := innerProduct(oneVectorN, twoVectorN) 382 if err != nil { 383 return false, privacy.NewPrivacyErr(privacy.CalInnerProductErr, err), k 384 } 385 386 sum := new(privacy.Scalar).FromUint64(0) 387 zTmp := new(privacy.Scalar).Set(zSquare) 388 for j := 0; j < numValuePad; j++ { 389 zTmp.Mul(zTmp, z) 390 sum.Add(sum, zTmp) 391 } 392 sum.Mul(sum, innerProduct2) 393 deltaYZ.Sub(deltaYZ, sum) 394 395 left1 := privacy.PedCom.CommitAtIndex(proof.tHat, proof.tauX, privacy.PedersenValueIndex) 396 397 right1 := new(privacy.Point).ScalarMult(proof.t2, xSquare) 398 right1.Add(right1, new(privacy.Point).AddPedersen(deltaYZ, privacy.PedCom.G[privacy.PedersenValueIndex], x, proof.t1)) 399 400 expVector := vectorMulScalar(powerVector(z, numValuePad), zSquare) 401 right1.Add(right1, new(privacy.Point).MultiScalarMult(expVector, tmpcmsValue)) 402 403 if !privacy.IsPointEqual(left1, right1) { 404 return false, fmt.Errorf("verify aggregated range proof statement 1 failed index %d", k), k 405 } 406 407 innerProductProofs = append(innerProductProofs, proof.innerProductProof) 408 csList = append(csList, aggParam.cs) 409 } 410 411 innerProductArgsValid := VerifyBatchingInnerProductProofs(innerProductProofs, csList) 412 if !innerProductArgsValid { 413 return false, errors.New("verify batch aggregated range proofs statement 2 failed"), -1 414 } 415 416 return true, nil, -1 417 }