github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/zkp/aggregaterange/innerproductargument.go (about)

     1  package aggregaterange
     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 (proof InnerProductProof) ValidateSanity() bool {
    24  	if len(proof.l) != len(proof.r) {
    25  		return false
    26  	}
    27  
    28  	for i := 0; i < len(proof.l); i++ {
    29  		if !proof.l[i].PointValid() || !proof.r[i].PointValid() {
    30  			return false
    31  		}
    32  	}
    33  
    34  	if !proof.a.ScalarValid() || !proof.b.ScalarValid() {
    35  		return false
    36  	}
    37  
    38  	return proof.p.PointValid()
    39  }
    40  
    41  func (proof InnerProductProof) Bytes() []byte {
    42  	var res []byte
    43  
    44  	res = append(res, byte(len(proof.l)))
    45  	for _, l := range proof.l {
    46  		res = append(res, l.ToBytesS()...)
    47  	}
    48  
    49  	for _, r := range proof.r {
    50  		res = append(res, r.ToBytesS()...)
    51  	}
    52  
    53  	res = append(res, proof.a.ToBytesS()...)
    54  	res = append(res, proof.b.ToBytesS()...)
    55  	res = append(res, proof.p.ToBytesS()...)
    56  
    57  	return res
    58  }
    59  
    60  func (proof *InnerProductProof) SetBytes(bytes []byte) error {
    61  	if len(bytes) == 0 {
    62  		return nil
    63  	}
    64  
    65  	lenLArray := int(bytes[0])
    66  	offset := 1
    67  	var err error
    68  
    69  	proof.l = make([]*privacy.Point, lenLArray)
    70  	for i := 0; i < lenLArray; i++ {
    71  		proof.l[i], err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
    72  		if err != nil {
    73  			return err
    74  		}
    75  		offset += privacy.Ed25519KeySize
    76  	}
    77  
    78  	proof.r = make([]*privacy.Point, lenLArray)
    79  	for i := 0; i < lenLArray; i++ {
    80  		proof.r[i], err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
    81  		if err != nil {
    82  			return err
    83  		}
    84  		offset += privacy.Ed25519KeySize
    85  	}
    86  
    87  	proof.a = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
    88  	offset += privacy.Ed25519KeySize
    89  
    90  	proof.b = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
    91  	offset += privacy.Ed25519KeySize
    92  
    93  	proof.p, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	return nil
    99  }
   100  
   101  func (wit InnerProductWitness) Prove(aggParam *bulletproofParams) (*InnerProductProof, error) {
   102  	if len(wit.a) != len(wit.b) {
   103  		return nil, errors.New("invalid inputs")
   104  	}
   105  
   106  	n := len(wit.a)
   107  
   108  	a := make([]*privacy.Scalar, n)
   109  	b := make([]*privacy.Scalar, n)
   110  
   111  	for i := range wit.a {
   112  		a[i] = new(privacy.Scalar).Set(wit.a[i])
   113  		b[i] = new(privacy.Scalar).Set(wit.b[i])
   114  	}
   115  
   116  	p := new(privacy.Point).Set(wit.p)
   117  	G := make([]*privacy.Point, n)
   118  	H := make([]*privacy.Point, n)
   119  	for i := range G {
   120  		G[i] = new(privacy.Point).Set(aggParam.g[i])
   121  		H[i] = new(privacy.Point).Set(aggParam.h[i])
   122  	}
   123  
   124  	proof := new(InnerProductProof)
   125  	proof.l = make([]*privacy.Point, 0)
   126  	proof.r = make([]*privacy.Point, 0)
   127  	proof.p = new(privacy.Point).Set(wit.p)
   128  
   129  	for n > 1 {
   130  		nPrime := n / 2
   131  
   132  		cL, err := innerProduct(a[:nPrime], b[nPrime:])
   133  		if err != nil {
   134  			return nil, err
   135  		}
   136  
   137  		cR, err := innerProduct(a[nPrime:], b[:nPrime])
   138  		if err != nil {
   139  			return nil, err
   140  		}
   141  
   142  		L, err := encodeVectors(a[:nPrime], b[nPrime:], G[nPrime:], H[:nPrime])
   143  		if err != nil {
   144  			return nil, err
   145  		}
   146  		L.Add(L, new(privacy.Point).ScalarMult(aggParam.u, cL))
   147  		proof.l = append(proof.l, L)
   148  
   149  		R, err := encodeVectors(a[nPrime:], b[:nPrime], G[:nPrime], H[nPrime:])
   150  		if err != nil {
   151  			return nil, err
   152  		}
   153  		R.Add(R, new(privacy.Point).ScalarMult(aggParam.u, cR))
   154  		proof.r = append(proof.r, R)
   155  
   156  		// calculate challenge x = hash(G || H || u || x || l || r)
   157  		x := generateChallenge([][]byte{aggParam.cs, p.ToBytesS(), L.ToBytesS(), R.ToBytesS()})
   158  		//x := generateChallengeOld(aggParam, [][]byte{p.ToBytesS(), L.ToBytesS(), R.ToBytesS()})
   159  		xInverse := new(privacy.Scalar).Invert(x)
   160  		xSquare := new(privacy.Scalar).Mul(x, x)
   161  		xSquareInverse := new(privacy.Scalar).Mul(xInverse, xInverse)
   162  
   163  		// calculate GPrime, HPrime, PPrime for the next loop
   164  		GPrime := make([]*privacy.Point, nPrime)
   165  		HPrime := make([]*privacy.Point, nPrime)
   166  
   167  		for i := range GPrime {
   168  			GPrime[i] = new(privacy.Point).AddPedersen(xInverse, G[i], x, G[i+nPrime])
   169  			HPrime[i] = new(privacy.Point).AddPedersen(x, H[i], xInverse, H[i+nPrime])
   170  		}
   171  
   172  		// x^2 * l + P + xInverse^2 * r
   173  		PPrime := new(privacy.Point).AddPedersen(xSquare, L, xSquareInverse, R)
   174  		PPrime.Add(PPrime, p)
   175  
   176  		// calculate aPrime, bPrime
   177  		aPrime := make([]*privacy.Scalar, nPrime)
   178  		bPrime := make([]*privacy.Scalar, nPrime)
   179  
   180  		for i := range aPrime {
   181  			aPrime[i] = new(privacy.Scalar).Mul(a[i], x)
   182  			aPrime[i] = new(privacy.Scalar).MulAdd(a[i+nPrime], xInverse, aPrime[i])
   183  
   184  			bPrime[i] = new(privacy.Scalar).Mul(b[i], xInverse)
   185  			bPrime[i] = new(privacy.Scalar).MulAdd(b[i+nPrime], x, bPrime[i])
   186  		}
   187  
   188  		a = aPrime
   189  		b = bPrime
   190  		p.Set(PPrime)
   191  		G = GPrime
   192  		H = HPrime
   193  		n = nPrime
   194  	}
   195  
   196  	proof.a = new(privacy.Scalar).Set(a[0])
   197  	proof.b = new(privacy.Scalar).Set(b[0])
   198  
   199  	return proof, nil
   200  }
   201  
   202  func (proof InnerProductProof) Verify(aggParam *bulletproofParams) bool {
   203  	//var aggParam = newBulletproofParams(1)
   204  	p := new(privacy.Point)
   205  	p.Set(proof.p)
   206  	n := len(aggParam.g)
   207  	G := make([]*privacy.Point, n)
   208  	H := make([]*privacy.Point, n)
   209  	s := make([]*privacy.Scalar, n)
   210  	sInverse := make([]*privacy.Scalar, n)
   211  
   212  	for i := range G {
   213  		G[i] = new(privacy.Point).Set(aggParam.g[i])
   214  		H[i] = new(privacy.Point).Set(aggParam.h[i])
   215  		s[i] = new(privacy.Scalar).FromUint64(1)
   216  		sInverse[i] = new(privacy.Scalar).FromUint64(1)
   217  	}
   218  	logN := int(math.Log2(float64(n)))
   219  	xList := make([]*privacy.Scalar, logN)
   220  	xInverseList := make([]*privacy.Scalar, logN)
   221  	xSquareList := make([]*privacy.Scalar, logN)
   222  	xInverseSquare_List := make([]*privacy.Scalar, logN)
   223  
   224  	//a*s ; b*s^-1
   225  	for i := range proof.l {
   226  		// calculate challenge x = hash(hash(G || H || u || p) || x || l || r)
   227  		xList[i] = generateChallenge([][]byte{aggParam.cs, p.ToBytesS(), proof.l[i].ToBytesS(), proof.r[i].ToBytesS()})
   228  		xInverseList[i] = new(privacy.Scalar).Invert(xList[i])
   229  		xSquareList[i] = new(privacy.Scalar).Mul(xList[i], xList[i])
   230  		xInverseSquare_List[i] = new(privacy.Scalar).Mul(xInverseList[i], xInverseList[i])
   231  
   232  		//Update s, s^-1
   233  		for j := 0; j < n; j++ {
   234  			if j&int(math.Pow(2, float64(logN-i-1))) != 0 {
   235  				s[j] = new(privacy.Scalar).Mul(s[j], xList[i])
   236  				sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], xInverseList[i])
   237  			} else {
   238  				s[j] = new(privacy.Scalar).Mul(s[j], xInverseList[i])
   239  				sInverse[j] = new(privacy.Scalar).Mul(sInverse[j], xList[i])
   240  			}
   241  		}
   242  		PPrime := new(privacy.Point).AddPedersen(xSquareList[i], proof.l[i], xInverseSquare_List[i], proof.r[i])
   243  		PPrime.Add(PPrime, p)
   244  		p = PPrime
   245  	}
   246  
   247  	// Compute (g^s)^a (h^-s)^b u^(ab) = p l^(x^2) r^(-x^2)
   248  	c := new(privacy.Scalar).Mul(proof.a, proof.b)
   249  	rightHSPart1 := new(privacy.Point).MultiScalarMult(s, G)
   250  	rightHSPart1.ScalarMult(rightHSPart1, proof.a)
   251  	rightHSPart2 := new(privacy.Point).MultiScalarMult(sInverse, H)
   252  	rightHSPart2.ScalarMult(rightHSPart2, proof.b)
   253  	rightHS := new(privacy.Point).Add(rightHSPart1, rightHSPart2)
   254  	rightHS.Add(rightHS, new(privacy.Point).ScalarMult(aggParam.u, c))
   255  
   256  	leftHSPart1 := new(privacy.Point).MultiScalarMult(xSquareList, proof.l)
   257  	leftHSPart2 := new(privacy.Point).MultiScalarMult(xInverseSquare_List, proof.r)
   258  	leftHS := new(privacy.Point).Add(leftHSPart1, leftHSPart2)
   259  	leftHS.Add(leftHS, proof.p)
   260  
   261  	res := privacy.IsPointEqual(rightHS, leftHS)
   262  	if !res {
   263  
   264  	}
   265  
   266  	return res
   267  }
   268  
   269  func VerifyBatchingInnerProductProofs(proofs []*InnerProductProof, csList [][]byte) bool {
   270  	batchSize := len(proofs)
   271  	// Generate list of random value
   272  	sum_abAlpha := new(privacy.Scalar).FromUint64(0)
   273  	pList := make([]*privacy.Point, 0)
   274  	alphaList := make([]*privacy.Scalar, 0)
   275  	LList := make([]*privacy.Point, 0)
   276  	nXSquareList := make([]*privacy.Scalar, 0)
   277  	RList := make([]*privacy.Point, 0)
   278  	nXInverseSquareList := make([]*privacy.Scalar, 0)
   279  
   280  	maxN := 0
   281  	asAlphaList := make([]*privacy.Scalar, len(AggParam.g))
   282  	bsInverseAlphaList := make([]*privacy.Scalar, len(AggParam.g))
   283  	for k := 0; k < len(AggParam.g); k++ {
   284  		asAlphaList[k] = new(privacy.Scalar).FromUint64(0)
   285  		bsInverseAlphaList[k] = new(privacy.Scalar).FromUint64(0)
   286  	}
   287  	for i := 0; i < batchSize; i++ {
   288  		alpha := privacy.RandomScalar()
   289  		abAlpha := new(privacy.Scalar).Mul(proofs[i].a, proofs[i].b)
   290  		abAlpha.Mul(abAlpha, alpha)
   291  		sum_abAlpha.Add(sum_abAlpha, abAlpha)
   292  
   293  		//prod_PAlpha.Add(prod_PAlpha, new(privacy.Point).ScalarMult(proofs[i].p,alpha))
   294  		pList = append(pList, proofs[i].p)
   295  		alphaList = append(alphaList, alpha)
   296  
   297  		n := int(math.Pow(2, float64(len(proofs[i].l))))
   298  		if maxN < n {
   299  			maxN = n
   300  		}
   301  		logN := int(math.Log2(float64(n)))
   302  		s := make([]*privacy.Scalar, n)
   303  		sInverse := make([]*privacy.Scalar, n)
   304  		xList := make([]*privacy.Scalar, logN)
   305  		xInverseList := make([]*privacy.Scalar, logN)
   306  		xSquareList := make([]*privacy.Scalar, logN)
   307  		xSquareAlphaList := make([]*privacy.Scalar, logN)
   308  		xInverseSquareList := make([]*privacy.Scalar, logN)
   309  		xInverseSquareAlphaList := make([]*privacy.Scalar, logN)
   310  
   311  		for k := 0; k < n; k++ {
   312  			s[k] = new(privacy.Scalar).Mul(alpha, proofs[i].a)
   313  			sInverse[k] = new(privacy.Scalar).Mul(alpha, proofs[i].b)
   314  		}
   315  
   316  		p := new(privacy.Point).Set(proofs[i].p)
   317  		for j := 0; j < len(proofs[i].l); j++ {
   318  			// calculate challenge x = hash(hash(G || H || u || p) || x || l || r)
   319  			xList[j] = generateChallenge([][]byte{csList[i], p.ToBytesS(), proofs[i].l[j].ToBytesS(), proofs[i].r[j].ToBytesS()})
   320  			xInverseList[j] = new(privacy.Scalar).Invert(xList[j])
   321  			xSquareList[j] = new(privacy.Scalar).Mul(xList[j], xList[j])
   322  			xSquareAlphaList[j] = new(privacy.Scalar).Mul(xSquareList[j], alpha)
   323  			xInverseSquareList[j] = new(privacy.Scalar).Mul(xInverseList[j], xInverseList[j])
   324  			xInverseSquareAlphaList[j] = new(privacy.Scalar).Mul(xInverseSquareList[j], alpha)
   325  
   326  			pPrime := new(privacy.Point).AddPedersen(xSquareList[j], proofs[i].l[j], xInverseSquareList[j], proofs[i].r[j])
   327  			pPrime.Add(pPrime, p)
   328  			p = pPrime
   329  
   330  			//Update s, s^-1
   331  			for k := 0; k < n; k++ {
   332  				if k&int(math.Pow(2, float64(logN-j-1))) != 0 {
   333  					s[k] = new(privacy.Scalar).Mul(s[k], xList[j])
   334  					sInverse[k] = new(privacy.Scalar).Mul(sInverse[k], xInverseList[j])
   335  				} else {
   336  					s[k] = new(privacy.Scalar).Mul(s[k], xInverseList[j])
   337  					sInverse[k] = new(privacy.Scalar).Mul(sInverse[k], xList[j])
   338  				}
   339  			}
   340  		}
   341  		for k := 0; k < n; k++ {
   342  			asAlphaList[k].Add(asAlphaList[k], s[k])
   343  			bsInverseAlphaList[k].Add(bsInverseAlphaList[k], sInverse[k])
   344  		}
   345  
   346  		LList = append(LList, proofs[i].l...)
   347  		nXSquareList = append(nXSquareList, xSquareAlphaList...)
   348  		RList = append(RList, proofs[i].r...)
   349  		nXInverseSquareList = append(nXInverseSquareList, xInverseSquareAlphaList...)
   350  	}
   351  
   352  	gAlphaAS := new(privacy.Point).MultiScalarMult(asAlphaList[0:maxN], AggParam.g[0:maxN])
   353  	hAlphaBSInverse := new(privacy.Point).MultiScalarMult(bsInverseAlphaList[0:maxN], AggParam.h[0:maxN])
   354  	LHS := new(privacy.Point).Add(gAlphaAS, hAlphaBSInverse)
   355  	LHS.Add(LHS, new(privacy.Point).ScalarMult(AggParam.u, sum_abAlpha))
   356  	//fmt.Println("LHS:", LHS )
   357  
   358  	prod_PAlpha := new(privacy.Point).MultiScalarMult(alphaList, pList)
   359  	prod_LX := new(privacy.Point).MultiScalarMult(nXSquareList, LList)
   360  	prod_RX := new(privacy.Point).MultiScalarMult(nXInverseSquareList, RList)
   361  
   362  	RHS := new(privacy.Point).Add(prod_LX, prod_RX)
   363  	RHS.Add(RHS, prod_PAlpha)
   364  	//fmt.Println("RHS:", RHS)
   365  
   366  	res := privacy.IsPointEqual(RHS, LHS)
   367  	if !res {
   368  	}
   369  
   370  	return res
   371  }