github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/zkp/aggregaterange/bulletproofs/bulletproofs.go (about) 1 package bulletproofs 2 3 import ( 4 "github.com/incognitochain/go-incognito-sdk/privacy" 5 "github.com/incognitochain/go-incognito-sdk/privacy/privacy_util" 6 "github.com/pkg/errors" 7 "math" 8 ) 9 10 type bulletproofParams struct { 11 g []*privacy.Point 12 h []*privacy.Point 13 u *privacy.Point 14 cs *privacy.Point 15 } 16 17 type AggregatedRangeWitness struct { 18 values []uint64 19 rands []*privacy.Scalar 20 } 21 22 type AggregatedRangeProof struct { 23 cmsValue []*privacy.Point 24 a *privacy.Point 25 s *privacy.Point 26 t1 *privacy.Point 27 t2 *privacy.Point 28 tauX *privacy.Scalar 29 tHat *privacy.Scalar 30 mu *privacy.Scalar 31 innerProductProof *InnerProductProof 32 } 33 34 var AggParam = newBulletproofParams(privacy_util.MaxOutputCoin) 35 36 func (proof AggregatedRangeProof) ValidateSanity() bool { 37 for i := 0; i < len(proof.cmsValue); i++ { 38 if !proof.cmsValue[i].PointValid() { 39 return false 40 } 41 } 42 if !proof.a.PointValid() || !proof.s.PointValid() || !proof.t1.PointValid() || !proof.t2.PointValid() { 43 return false 44 } 45 if !proof.tauX.ScalarValid() || !proof.tHat.ScalarValid() || !proof.mu.ScalarValid() { 46 return false 47 } 48 49 return proof.innerProductProof.ValidateSanity() 50 } 51 52 func (proof *AggregatedRangeProof) Init() { 53 proof.a = new(privacy.Point).Identity() 54 proof.s = new(privacy.Point).Identity() 55 proof.t1 = new(privacy.Point).Identity() 56 proof.t2 = new(privacy.Point).Identity() 57 proof.tauX = new(privacy.Scalar) 58 proof.tHat = new(privacy.Scalar) 59 proof.mu = new(privacy.Scalar) 60 proof.innerProductProof = new(InnerProductProof).Init() 61 } 62 63 func (proof AggregatedRangeProof) IsNil() bool { 64 if proof.a == nil { 65 return true 66 } 67 if proof.s == nil { 68 return true 69 } 70 if proof.t1 == nil { 71 return true 72 } 73 if proof.t2 == nil { 74 return true 75 } 76 if proof.tauX == nil { 77 return true 78 } 79 if proof.tHat == nil { 80 return true 81 } 82 if proof.mu == nil { 83 return true 84 } 85 return proof.innerProductProof == nil 86 } 87 88 func (proof AggregatedRangeProof) Bytes() []byte { 89 var res []byte 90 91 if proof.IsNil() { 92 return []byte{} 93 } 94 95 res = append(res, byte(len(proof.cmsValue))) 96 for i := 0; i < len(proof.cmsValue); i++ { 97 res = append(res, proof.cmsValue[i].ToBytesS()...) 98 } 99 100 res = append(res, proof.a.ToBytesS()...) 101 res = append(res, proof.s.ToBytesS()...) 102 res = append(res, proof.t1.ToBytesS()...) 103 res = append(res, proof.t2.ToBytesS()...) 104 105 res = append(res, proof.tauX.ToBytesS()...) 106 res = append(res, proof.tHat.ToBytesS()...) 107 res = append(res, proof.mu.ToBytesS()...) 108 res = append(res, proof.innerProductProof.Bytes()...) 109 110 return res 111 } 112 113 func (proof AggregatedRangeProof) GetCommitments() []*privacy.Point {return proof.cmsValue} 114 115 func (proof *AggregatedRangeProof) SetCommitments(cmsValue []*privacy.Point) { 116 proof.cmsValue = cmsValue 117 } 118 119 func (proof *AggregatedRangeProof) SetBytes(bytes []byte) error { 120 if len(bytes) == 0 { 121 return nil 122 } 123 124 lenValues := int(bytes[0]) 125 offset := 1 126 var err error 127 128 proof.cmsValue = make([]*privacy.Point, lenValues) 129 for i := 0; i < lenValues; i++ { 130 if offset+privacy.Ed25519KeySize > len(bytes){ 131 return errors.New("Range Proof unmarshaling from bytes failed") 132 } 133 proof.cmsValue[i], err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 134 if err != nil { 135 return err 136 } 137 offset += privacy.Ed25519KeySize 138 } 139 140 if offset+privacy.Ed25519KeySize > len(bytes){ 141 return errors.New("Range Proof unmarshaling from bytes failed") 142 } 143 proof.a, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 144 if err != nil { 145 return err 146 } 147 offset += privacy.Ed25519KeySize 148 149 if offset+privacy.Ed25519KeySize > len(bytes){ 150 return errors.New("Range Proof unmarshaling from bytes failed") 151 } 152 proof.s, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 153 if err != nil { 154 return err 155 } 156 offset += privacy.Ed25519KeySize 157 158 if offset+privacy.Ed25519KeySize > len(bytes){ 159 return errors.New("Range Proof unmarshaling from bytes failed") 160 } 161 proof.t1, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 162 if err != nil { 163 return err 164 } 165 offset += privacy.Ed25519KeySize 166 167 if offset+privacy.Ed25519KeySize > len(bytes){ 168 return errors.New("Range Proof unmarshaling from bytes failed") 169 } 170 proof.t2, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 171 if err != nil { 172 return err 173 } 174 offset += privacy.Ed25519KeySize 175 176 if offset+privacy.Ed25519KeySize > len(bytes){ 177 return errors.New("Range Proof unmarshaling from bytes failed") 178 } 179 proof.tauX = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 180 offset += privacy.Ed25519KeySize 181 182 if offset+privacy.Ed25519KeySize > len(bytes){ 183 return errors.New("Range Proof unmarshaling from bytes failed") 184 } 185 proof.tHat = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 186 offset += privacy.Ed25519KeySize 187 188 if offset+privacy.Ed25519KeySize > len(bytes){ 189 return errors.New("Range Proof unmarshaling from bytes failed") 190 } 191 proof.mu = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 192 offset += privacy.Ed25519KeySize 193 194 if offset >= len(bytes){ 195 return errors.New("Range Proof unmarshaling from bytes failed") 196 } 197 198 proof.innerProductProof = new(InnerProductProof) 199 err = proof.innerProductProof.SetBytes(bytes[offset:]) 200 // it's the last check, so we just return it 201 //privacy.Logger.Log.Debugf("AFTER SETBYTES ------------ %v\n", proof.Bytes()) 202 return err 203 } 204 205 func (wit *AggregatedRangeWitness) Set(values []uint64, rands []*privacy.Scalar) { 206 numValue := len(values) 207 wit.values = make([]uint64, numValue) 208 wit.rands = make([]*privacy.Scalar, numValue) 209 210 for i := range values { 211 wit.values[i] = values[i] 212 wit.rands[i] = new(privacy.Scalar).Set(rands[i]) 213 } 214 } 215 216 func (wit AggregatedRangeWitness) Prove() (*AggregatedRangeProof, error) { 217 proof := new(AggregatedRangeProof) 218 numValue := len(wit.values) 219 if numValue > privacy_util.MaxOutputCoin { 220 return nil, errors.New("Must less than MaxOutputCoin") 221 } 222 numValuePad := roundUpPowTwo(numValue) 223 maxExp := privacy_util.MaxExp 224 N := maxExp * numValuePad 225 226 aggParam := setAggregateParams(N) 227 228 values := make([]uint64, numValuePad) 229 rands := make([]*privacy.Scalar, numValuePad) 230 for i := range wit.values { 231 values[i] = wit.values[i] 232 rands[i] = new(privacy.Scalar).Set(wit.rands[i]) 233 } 234 for i := numValue; i < numValuePad; i++ { 235 values[i] = uint64(0) 236 rands[i] = new(privacy.Scalar).FromUint64(0) 237 } 238 239 proof.cmsValue = make([]*privacy.Point, numValue) 240 for i := 0; i < numValue; i++ { 241 proof.cmsValue[i] = privacy.PedCom.CommitAtIndex(new(privacy.Scalar).FromUint64(values[i]), rands[i], privacy.PedersenValueIndex) 242 } 243 // Convert values to binary array 244 aL := make([]*privacy.Scalar, N) 245 aR := make([]*privacy.Scalar, N) 246 sL := make([]*privacy.Scalar, N) 247 sR := make([]*privacy.Scalar, N) 248 249 for i, value := range values { 250 tmp := ConvertUint64ToBinary(value, maxExp) 251 for j := 0; j < maxExp; j++ { 252 aL[i*maxExp+j] = tmp[j] 253 aR[i*maxExp+j] = new(privacy.Scalar).Sub(tmp[j], new(privacy.Scalar).FromUint64(1)) 254 sL[i*maxExp+j] = privacy.RandomScalar() 255 sR[i*maxExp+j] = privacy.RandomScalar() 256 } 257 } 258 // LINE 40-50 259 // Commitment to aL, aR: A = h^alpha * G^aL * H^aR 260 // Commitment to sL, sR : S = h^rho * G^sL * H^sR 261 var alpha, rho *privacy.Scalar 262 if A, err := encodeVectors(aL, aR, aggParam.g, aggParam.h); err != nil { 263 return nil, err 264 } else if S, err := encodeVectors(sL, sR, aggParam.g, aggParam.h); err != nil { 265 return nil, err 266 } else { 267 alpha = privacy.RandomScalar() 268 rho = privacy.RandomScalar() 269 A.Add(A, new(privacy.Point).ScalarMult(privacy.HBase, alpha)) 270 S.Add(S, new(privacy.Point).ScalarMult(privacy.HBase, rho)) 271 proof.a = A 272 proof.s = S 273 } 274 // challenge y, z 275 y := generateChallenge(aggParam.cs.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 276 z := generateChallenge(y.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 277 278 // LINE 51-54 279 twoNumber := new(privacy.Scalar).FromUint64(2) 280 twoVectorN := powerVector(twoNumber, maxExp) 281 282 // HPrime = H^(y^(1-i) 283 HPrime := computeHPrime(y, N, aggParam.h) 284 285 // l(X) = (aL -z*1^n) + sL*X; r(X) = y^n hada (aR +z*1^n + sR*X) + z^2 * 2^n 286 yVector := powerVector(y, N) 287 hadaProduct, err := hadamardProduct(yVector, vectorAddScalar(aR, z)) 288 if err != nil { 289 return nil, err 290 } 291 vectorSum := make([]*privacy.Scalar, N) 292 zTmp := new(privacy.Scalar).Set(z) 293 for j := 0; j < numValuePad; j++ { 294 zTmp.Mul(zTmp, z) 295 for i := 0; i < maxExp; i++ { 296 vectorSum[j*maxExp+i] = new(privacy.Scalar).Mul(twoVectorN[i], zTmp) 297 } 298 } 299 zNeg := new(privacy.Scalar).Sub(new(privacy.Scalar).FromUint64(0), z) 300 l0 := vectorAddScalar(aL, zNeg) 301 l1 := sL 302 var r0, r1 []*privacy.Scalar 303 if r0, err = vectorAdd(hadaProduct, vectorSum); err != nil { 304 return nil, err 305 } else { 306 if r1, err = hadamardProduct(yVector, sR); err != nil { 307 return nil, err 308 } 309 } 310 311 // t(X) = <l(X), r(X)> = t0 + t1*X + t2*X^2 312 // t1 = <l1, ro> + <l0, r1>, t2 = <l1, r1> 313 var t1, t2 *privacy.Scalar 314 if ip3, err := innerProduct(l1, r0); err != nil { 315 return nil, err 316 } else if ip4, err := innerProduct(l0, r1); err != nil { 317 return nil, err 318 } else { 319 t1 = new(privacy.Scalar).Add(ip3, ip4) 320 if t2, err = innerProduct(l1, r1); err != nil { 321 return nil, err 322 } 323 } 324 325 // commitment to t1, t2 326 tau1 := privacy.RandomScalar() 327 tau2 := privacy.RandomScalar() 328 proof.t1 = privacy.PedCom.CommitAtIndex(t1, tau1, privacy.PedersenValueIndex) 329 proof.t2 = privacy.PedCom.CommitAtIndex(t2, tau2, privacy.PedersenValueIndex) 330 331 x := generateChallenge(z.ToBytesS(), []*privacy.Point{proof.t1, proof.t2}) 332 xSquare := new(privacy.Scalar).Mul(x, x) 333 334 // lVector = aL - z*1^n + sL*x 335 // rVector = y^n hada (aR +z*1^n + sR*x) + z^2*2^n 336 // tHat = <lVector, rVector> 337 lVector, err := vectorAdd(vectorAddScalar(aL, zNeg), vectorMulScalar(sL, x)) 338 if err != nil { 339 return nil, err 340 } 341 tmpVector, err := vectorAdd(vectorAddScalar(aR, z), vectorMulScalar(sR, x)) 342 if err != nil { 343 return nil, err 344 } 345 rVector, err := hadamardProduct(yVector, tmpVector) 346 if err != nil { 347 return nil, err 348 } 349 rVector, err = vectorAdd(rVector, vectorSum) 350 if err != nil { 351 return nil, err 352 } 353 proof.tHat, err = innerProduct(lVector, rVector) 354 if err != nil { 355 return nil, err 356 } 357 358 // blinding value for tHat: tauX = tau2*x^2 + tau1*x + z^2*rand 359 proof.tauX = new(privacy.Scalar).Mul(tau2, xSquare) 360 proof.tauX.Add(proof.tauX, new(privacy.Scalar).Mul(tau1, x)) 361 zTmp = new(privacy.Scalar).Set(z) 362 tmpBN := new(privacy.Scalar) 363 for j := 0; j < numValuePad; j++ { 364 zTmp.Mul(zTmp, z) 365 proof.tauX.Add(proof.tauX, tmpBN.Mul(zTmp, rands[j])) 366 } 367 368 // alpha, rho blind A, S 369 // mu = alpha + rho*x 370 proof.mu = new(privacy.Scalar).Add(alpha, new(privacy.Scalar).Mul(rho, x)) 371 372 // instead of sending left vector and right vector, we use inner sum argument to reduce proof size from 2*n to 2(log2(n)) + 2 373 innerProductWit := new(InnerProductWitness) 374 innerProductWit.a = lVector 375 innerProductWit.b = rVector 376 innerProductWit.p, err = encodeVectors(lVector, rVector, aggParam.g, HPrime) 377 if err != nil { 378 return nil, err 379 } 380 uPrime := new(privacy.Point).ScalarMult(aggParam.u, privacy.HashToScalar(x.ToBytesS())) 381 innerProductWit.p = innerProductWit.p.Add(innerProductWit.p, new(privacy.Point).ScalarMult(uPrime, proof.tHat)) 382 383 proof.innerProductProof, err = innerProductWit.Prove(aggParam.g, HPrime, uPrime, x.ToBytesS()) 384 if err != nil { 385 return nil, err 386 } 387 388 return proof, nil 389 } 390 391 func (proof AggregatedRangeProof) Verify() (bool, error) { 392 numValue := len(proof.cmsValue) 393 if numValue > privacy_util.MaxOutputCoin { 394 return false, errors.New("Must less than MaxOutputNumber") 395 } 396 numValuePad := roundUpPowTwo(numValue) 397 maxExp := privacy_util.MaxExp 398 N := numValuePad * maxExp 399 twoVectorN := powerVector(new(privacy.Scalar).FromUint64(2), maxExp) 400 aggParam := setAggregateParams(N) 401 402 cmsValue := proof.cmsValue 403 for i := numValue; i < numValuePad; i++ { 404 cmsValue = append(cmsValue, new(privacy.Point).Identity()) 405 } 406 407 // recalculate challenge y, z 408 y := generateChallenge(aggParam.cs.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 409 z := generateChallenge(y.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 410 zSquare := new(privacy.Scalar).Mul(z, z) 411 zNeg := new(privacy.Scalar).Sub(new(privacy.Scalar).FromUint64(0), z) 412 413 x := generateChallenge(z.ToBytesS(), []*privacy.Point{proof.t1, proof.t2}) 414 xSquare := new(privacy.Scalar).Mul(x, x) 415 416 // HPrime = H^(y^(1-i) 417 HPrime := computeHPrime(y, N, aggParam.h) 418 419 // g^tHat * h^tauX = V^(z^2) * g^delta(y,z) * T1^x * T2^(x^2) 420 yVector := powerVector(y, N) 421 deltaYZ, err := computeDeltaYZ(z, zSquare, yVector, N) 422 if err != nil { 423 return false, err 424 } 425 426 LHS := privacy.PedCom.CommitAtIndex(proof.tHat, proof.tauX, privacy.PedersenValueIndex) 427 RHS := new(privacy.Point).ScalarMult(proof.t2, xSquare) 428 RHS.Add(RHS, new(privacy.Point).AddPedersen(deltaYZ, privacy.PedCom.G[privacy.PedersenValueIndex], x, proof.t1)) 429 430 expVector := vectorMulScalar(powerVector(z, numValuePad), zSquare) 431 RHS.Add(RHS, new(privacy.Point).MultiScalarMult(expVector, cmsValue)) 432 433 if !privacy.IsPointEqual(LHS, RHS) { 434 //privacy.Logger.Log.Errorf("verify aggregated range proof statement 1 failed") 435 return false, errors.New("verify aggregated range proof statement 1 failed") 436 } 437 438 // verify eq (66) 439 uPrime := new(privacy.Point).ScalarMult(aggParam.u, privacy.HashToScalar(x.ToBytesS())) 440 441 vectorSum := make([]*privacy.Scalar, N) 442 zTmp := new(privacy.Scalar).Set(z) 443 for j := 0; j < numValuePad; j++ { 444 zTmp.Mul(zTmp, z) 445 for i := 0; i < maxExp; i++ { 446 vectorSum[j*maxExp+i] = new(privacy.Scalar).Mul(twoVectorN[i], zTmp) 447 vectorSum[j*maxExp+i].Add(vectorSum[j*maxExp+i], new(privacy.Scalar).Mul(z, yVector[j*maxExp+i])) 448 } 449 } 450 tmpHPrime := new(privacy.Point).MultiScalarMult(vectorSum, HPrime) 451 tmpG := new(privacy.Point).Set(aggParam.g[0]) 452 for i:= 1; i < N; i++ { 453 tmpG.Add(tmpG, aggParam.g[i]) 454 } 455 ASx := new(privacy.Point).Add(proof.a, new(privacy.Point).ScalarMult(proof.s, x)) 456 P := new(privacy.Point).Add(new(privacy.Point).ScalarMult(tmpG, zNeg), tmpHPrime) 457 P.Add(P, ASx) 458 P.Add(P, new(privacy.Point).ScalarMult(uPrime, proof.tHat)) 459 PPrime := new(privacy.Point).Add(proof.innerProductProof.p, new(privacy.Point).ScalarMult(privacy.HBase, proof.mu) ) 460 461 if !privacy.IsPointEqual(P, PPrime) { 462 //privacy.Logger.Log.Errorf("verify aggregated range proof statement 2-1 failed") 463 return false, errors.New("verify aggregated range proof statement 2-1 failed") 464 } 465 466 // verify eq (68) 467 innerProductArgValid := proof.innerProductProof.Verify(aggParam.g, HPrime, uPrime, x.ToBytesS()) 468 if !innerProductArgValid { 469 //privacy.Logger.Log.Errorf("verify aggregated range proof statement 2 failed") 470 return false, errors.New("verify aggregated range proof statement 2 failed") 471 } 472 473 return true, nil 474 } 475 476 func (proof AggregatedRangeProof) VerifyFaster() (bool, error) { 477 numValue := len(proof.cmsValue) 478 if numValue > privacy_util.MaxOutputCoin { 479 return false, errors.New("Must less than MaxOutputNumber") 480 } 481 numValuePad := roundUpPowTwo(numValue) 482 maxExp := privacy_util.MaxExp 483 N := maxExp * numValuePad 484 aggParam := setAggregateParams(N) 485 twoVectorN := powerVector(new(privacy.Scalar).FromUint64(2), maxExp) 486 487 cmsValue := proof.cmsValue 488 for i := numValue; i < numValuePad; i++ { 489 cmsValue = append(cmsValue, new(privacy.Point).Identity()) 490 } 491 492 // recalculate challenge y, z 493 y := generateChallenge(aggParam.cs.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 494 z := generateChallenge(y.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 495 zSquare := new(privacy.Scalar).Mul(z, z) 496 zNeg := new(privacy.Scalar).Sub(new(privacy.Scalar).FromUint64(0), z) 497 498 x := generateChallenge(z.ToBytesS(), []*privacy.Point{proof.t1, proof.t2}) 499 xSquare := new(privacy.Scalar).Mul(x, x) 500 501 // g^tHat * h^tauX = V^(z^2) * g^delta(y,z) * T1^x * T2^(x^2) 502 yVector := powerVector(y, N) 503 deltaYZ, err := computeDeltaYZ(z, zSquare, yVector, N) 504 if err != nil { 505 return false, err 506 } 507 // HPrime = H^(y^(1-i) 508 HPrime := computeHPrime(y, N, aggParam.h) 509 uPrime := new(privacy.Point).ScalarMult(aggParam.u, privacy.HashToScalar(x.ToBytesS())) 510 511 512 // Verify eq (65) 513 LHS := privacy.PedCom.CommitAtIndex(proof.tHat, proof.tauX, privacy.PedersenValueIndex) 514 RHS := new(privacy.Point).ScalarMult(proof.t2, xSquare) 515 RHS.Add(RHS, new(privacy.Point).AddPedersen(deltaYZ, privacy.PedCom.G[privacy.PedersenValueIndex], x, proof.t1)) 516 expVector := vectorMulScalar(powerVector(z, numValuePad), zSquare) 517 RHS.Add(RHS, new(privacy.Point).MultiScalarMult(expVector, cmsValue)) 518 if !privacy.IsPointEqual(LHS, RHS) { 519 //privacy.Logger.Log.Errorf("verify aggregated range proof statement 1 failed") 520 return false, errors.New("verify aggregated range proof statement 1 failed") 521 } 522 523 // Verify eq (66) 524 vectorSum := make([]*privacy.Scalar, N) 525 zTmp := new(privacy.Scalar).Set(z) 526 for j := 0; j < numValuePad; j++ { 527 zTmp.Mul(zTmp, z) 528 for i := 0; i < maxExp; i++ { 529 vectorSum[j*maxExp+i] = new(privacy.Scalar).Mul(twoVectorN[i], zTmp) 530 vectorSum[j*maxExp+i].Add(vectorSum[j*maxExp+i], new(privacy.Scalar).Mul(z, yVector[j*maxExp+i])) 531 } 532 } 533 tmpHPrime := new(privacy.Point).MultiScalarMult(vectorSum, HPrime) 534 tmpG := new(privacy.Point).Set(aggParam.g[0]) 535 for i:= 1; i < N; i++ { 536 tmpG.Add(tmpG, aggParam.g[i]) 537 } 538 ASx := new(privacy.Point).Add(proof.a, new(privacy.Point).ScalarMult(proof.s, x)) 539 P := new(privacy.Point).Add(new(privacy.Point).ScalarMult(tmpG, zNeg), tmpHPrime) 540 P.Add(P, ASx) 541 P.Add(P, new(privacy.Point).ScalarMult(uPrime, proof.tHat)) 542 PPrime := new(privacy.Point).Add(proof.innerProductProof.p, new(privacy.Point).ScalarMult(privacy.HBase, proof.mu) ) 543 544 if !privacy.IsPointEqual(P, PPrime) { 545 //privacy.Logger.Log.Errorf("verify aggregated range proof statement 2-1 failed") 546 return false, errors.New("verify aggregated range proof statement 2-1 failed") 547 } 548 549 // Verify eq (68) 550 hashCache := x.ToBytesS() 551 L := proof.innerProductProof.l 552 R := proof.innerProductProof.r 553 s := make([]*privacy.Scalar, N) 554 sInverse := make([]*privacy.Scalar, N) 555 logN := int(math.Log2(float64(N))) 556 vSquareList := make([]*privacy.Scalar, logN) 557 vInverseSquareList := make([]*privacy.Scalar, logN) 558 559 for i := 0; i < N; i++ { 560 s[i] = new(privacy.Scalar).Set(proof.innerProductProof.a) 561 sInverse[i] = new(privacy.Scalar).Set(proof.innerProductProof.b) 562 } 563 564 for i := range L { 565 v := generateChallenge(hashCache, []*privacy.Point{L[i], R[i]}) 566 hashCache = v.ToBytesS() 567 vInverse := new(privacy.Scalar).Invert(v) 568 vSquareList[i] = new(privacy.Scalar).Mul(v, v) 569 vInverseSquareList[i] = new(privacy.Scalar).Mul(vInverse, vInverse) 570 571 for j := 0; j < N; j++ { 572 if j&int(math.Pow(2, float64(logN-i-1))) != 0 { 573 s[j] = new(privacy.Scalar).Mul(s[j], v) 574 sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], vInverse) 575 } else { 576 s[j] = new(privacy.Scalar).Mul(s[j], vInverse) 577 sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], v) 578 } 579 } 580 } 581 582 c := new(privacy.Scalar).Mul(proof.innerProductProof.a, proof.innerProductProof.b) 583 tmp1 := new(privacy.Point).MultiScalarMult(s, aggParam.g) 584 tmp2 := new(privacy.Point).MultiScalarMult(sInverse, HPrime) 585 rightHS := new(privacy.Point).Add(tmp1, tmp2) 586 rightHS.Add(rightHS, new(privacy.Point).ScalarMult(uPrime, c)) 587 588 tmp3 := new(privacy.Point).MultiScalarMult(vSquareList, L) 589 tmp4 := new(privacy.Point).MultiScalarMult(vInverseSquareList, R) 590 leftHS := new(privacy.Point).Add(tmp3, tmp4) 591 leftHS.Add(leftHS, proof.innerProductProof.p) 592 593 res := privacy.IsPointEqual(rightHS, leftHS) 594 if !res { 595 //privacy.Logger.Log.Errorf("verify aggregated range proof statement 2 failed") 596 return false, errors.New("verify aggregated range proof statement 2 failed") 597 } 598 599 return true, nil 600 } 601 602 func VerifyBatch(proofs []*AggregatedRangeProof) (bool, error, int) { 603 maxExp := privacy_util.MaxExp 604 baseG := privacy.PedCom.G[privacy.PedersenValueIndex] 605 baseH := privacy.PedCom.G[privacy.PedersenRandomnessIndex] 606 607 sum_tHat := new(privacy.Scalar).FromUint64(0) 608 sum_tauX := new(privacy.Scalar).FromUint64(0) 609 list_x_alpha := make([]*privacy.Scalar, 0) 610 list_x_beta := make([]*privacy.Scalar, 0) 611 list_xSquare := make([]*privacy.Scalar, 0) 612 list_zSquare := make([]*privacy.Scalar, 0) 613 614 list_t1 := make([]*privacy.Point, 0) 615 list_t2 := make([]*privacy.Point, 0) 616 list_V := make([]*privacy.Point, 0) 617 618 sum_mu := new(privacy.Scalar).FromUint64(0) 619 sum_absubthat := new(privacy.Scalar).FromUint64(0) 620 621 list_S := make([]*privacy.Point, 0) 622 list_A := make([]*privacy.Point, 0) 623 list_beta := make([]*privacy.Scalar, 0) 624 list_LR := make([]*privacy.Point, 0) 625 list_lVector := make([]*privacy.Scalar, 0) 626 list_rVector := make([]*privacy.Scalar, 0) 627 list_gVector := make([]*privacy.Point, 0) 628 list_hVector := make([]*privacy.Point, 0) 629 630 twoNumber := new(privacy.Scalar).FromUint64(2) 631 twoVectorN := powerVector(twoNumber, maxExp) 632 633 for k, proof := range proofs { 634 numValue := len(proof.cmsValue) 635 if numValue > privacy_util.MaxOutputCoin { 636 return false, errors.New("Must less than MaxOutputNumber"), k 637 } 638 numValuePad := roundUpPowTwo(numValue) 639 N := maxExp * numValuePad 640 aggParam := setAggregateParams(N) 641 642 cmsValue := proof.cmsValue 643 for i := numValue; i < numValuePad; i++ { 644 identity := new(privacy.Point).Identity() 645 cmsValue = append(cmsValue, identity) 646 } 647 648 // recalculate challenge y, z, x 649 y := generateChallenge(aggParam.cs.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 650 z := generateChallenge(y.ToBytesS(), []*privacy.Point{proof.a, proof.s}) 651 x := generateChallenge(z.ToBytesS(), []*privacy.Point{proof.t1, proof.t2}) 652 zSquare := new(privacy.Scalar).Mul(z, z) 653 xSquare := new(privacy.Scalar).Mul(x, x) 654 655 // Random alpha and beta for batch equations check 656 alpha := privacy.RandomScalar() 657 beta := privacy.RandomScalar() 658 list_beta = append(list_beta, beta) 659 660 // Compute first equation check 661 yVector := powerVector(y, N) 662 deltaYZ, err := computeDeltaYZ(z, zSquare, yVector, N) 663 if err != nil { 664 return false, err, k 665 } 666 sum_tHat.Add(sum_tHat, new(privacy.Scalar).Mul(alpha, new(privacy.Scalar).Sub(proof.tHat, deltaYZ))) 667 sum_tauX.Add(sum_tauX, new(privacy.Scalar).Mul(alpha, proof.tauX)) 668 669 list_x_alpha = append(list_x_alpha, new(privacy.Scalar).Mul(x, alpha)) 670 list_x_beta = append(list_x_beta, new(privacy.Scalar).Mul(x, beta)) 671 list_xSquare = append(list_xSquare, new(privacy.Scalar).Mul(xSquare, alpha)) 672 tmp := vectorMulScalar(powerVector(z, numValuePad), new(privacy.Scalar).Mul(zSquare, alpha)) 673 list_zSquare = append(list_zSquare, tmp...) 674 675 list_V = append(list_V, cmsValue...) 676 list_t1 = append(list_t1, proof.t1) 677 list_t2 = append(list_t2, proof.t2) 678 679 // Verify the second argument 680 hashCache := x.ToBytesS() 681 L := proof.innerProductProof.l 682 R := proof.innerProductProof.r 683 s := make([]*privacy.Scalar, N) 684 sInverse := make([]*privacy.Scalar, N) 685 logN := int(math.Log2(float64(N))) 686 vSquareList := make([]*privacy.Scalar, logN) 687 vInverseSquareList := make([]*privacy.Scalar, logN) 688 689 for i := 0; i < N; i++ { 690 s[i] = new(privacy.Scalar).Set(proof.innerProductProof.a) 691 sInverse[i] = new(privacy.Scalar).Set(proof.innerProductProof.b) 692 } 693 694 for i := range L { 695 v := generateChallenge(hashCache, []*privacy.Point{L[i], R[i]}) 696 hashCache = v.ToBytesS() 697 vInverse := new(privacy.Scalar).Invert(v) 698 vSquareList[i] = new(privacy.Scalar).Mul(v, v) 699 vInverseSquareList[i] = new(privacy.Scalar).Mul(vInverse, vInverse) 700 701 for j := 0; j < N; j++ { 702 if j&int(math.Pow(2, float64(logN-i-1))) != 0 { 703 s[j] = new(privacy.Scalar).Mul(s[j], v) 704 sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], vInverse) 705 } else { 706 s[j] = new(privacy.Scalar).Mul(s[j], vInverse) 707 sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], v) 708 } 709 } 710 } 711 712 lVector := make([]*privacy.Scalar, N) 713 rVector := make([]*privacy.Scalar, N) 714 715 vectorSum := make([]*privacy.Scalar, N) 716 zTmp := new(privacy.Scalar).Set(z) 717 for j := 0; j < numValuePad; j++ { 718 zTmp.Mul(zTmp, z) 719 for i := 0; i < maxExp; i++ { 720 vectorSum[j*maxExp+i] = new(privacy.Scalar).Mul(twoVectorN[i], zTmp) 721 } 722 } 723 yInverse := new(privacy.Scalar).Invert(y) 724 yTmp := new(privacy.Scalar).Set(y) 725 for j := 0; j < N; j++ { 726 yTmp.Mul(yTmp, yInverse) 727 lVector[j] = new(privacy.Scalar).Add(s[j], z) 728 rVector[j] = new(privacy.Scalar).Sub(sInverse[j], vectorSum[j]) 729 rVector[j].Mul(rVector[j], yTmp) 730 rVector[j].Sub(rVector[j], z) 731 732 lVector[j].Mul(lVector[j], beta) 733 rVector[j].Mul(rVector[j], beta) 734 } 735 736 list_lVector = append(list_lVector, lVector...) 737 list_rVector = append(list_rVector, rVector...) 738 739 tmp1 := new(privacy.Point).MultiScalarMult(vSquareList, L) 740 tmp2 := new(privacy.Point).MultiScalarMult(vInverseSquareList, R) 741 list_LR = append(list_LR, new(privacy.Point).Add(tmp1, tmp2)) 742 743 list_gVector = append(list_gVector, aggParam.g...) 744 list_hVector = append(list_hVector, aggParam.h...) 745 746 sum_mu.Add(sum_mu, new(privacy.Scalar).Mul(proof.mu, beta)) 747 ab := new(privacy.Scalar).Mul(proof.innerProductProof.a, proof.innerProductProof.b) 748 absubthat := new(privacy.Scalar).Sub(ab, proof.tHat) 749 absubthat.Mul(absubthat, privacy.HashToScalar(x.ToBytesS())) 750 sum_absubthat.Add(sum_absubthat, new(privacy.Scalar).Mul(absubthat, beta)) 751 list_A = append(list_A, proof.a) 752 list_S = append(list_S, proof.s) 753 } 754 755 tmp1 := new(privacy.Point).MultiScalarMult(list_lVector, list_gVector) 756 tmp2 := new(privacy.Point).MultiScalarMult(list_rVector, list_hVector) 757 tmp3 := new(privacy.Point).ScalarMult(AggParam.u, sum_absubthat) 758 tmp4 := new(privacy.Point).ScalarMult(baseH, sum_mu) 759 LHSPrime := new(privacy.Point).Add(tmp1, tmp2) 760 LHSPrime.Add(LHSPrime, tmp3) 761 LHSPrime.Add(LHSPrime, tmp4) 762 763 LHS := new(privacy.Point).AddPedersen(sum_tHat, baseG, sum_tauX, baseH) 764 LHSPrime.Add(LHSPrime, LHS) 765 766 tmp5 := new(privacy.Point).MultiScalarMult(list_beta, list_A) 767 tmp6 := new(privacy.Point).MultiScalarMult(list_x_beta, list_S) 768 RHSPrime := new(privacy.Point).Add(tmp5, tmp6) 769 RHSPrime.Add(RHSPrime, new(privacy.Point).MultiScalarMult(list_beta, list_LR)) 770 771 part1 := new(privacy.Point).MultiScalarMult(list_x_alpha, list_t1) 772 part2 := new(privacy.Point).MultiScalarMult(list_xSquare, list_t2) 773 RHS := new(privacy.Point).Add(part1, part2) 774 RHS.Add(RHS, new(privacy.Point).MultiScalarMult(list_zSquare, list_V)) 775 RHSPrime.Add(RHSPrime, RHS) 776 //fmt.Println("Batch Verification ", LHSPrime) 777 //fmt.Println("Batch Verification ", RHSPrime) 778 779 if !privacy.IsPointEqual(LHSPrime, RHSPrime) { 780 //privacy.Logger.Log.Errorf("batch verify aggregated range proof failed") 781 return false, errors.New("batch verify aggregated range proof failed"), -1 782 } 783 return true, nil, -1 784 } 785 786 // estimateMultiRangeProofSize estimate multi range proof size 787 func EstimateMultiRangeProofSize(nOutput int) uint64 { 788 return uint64((nOutput+2*int(math.Log2(float64(privacy_util.MaxExp*roundUpPowTwo(nOutput))))+5)*privacy.Ed25519KeySize + 5*privacy.Ed25519KeySize + 2) 789 }