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

     1  package aggregaterange
     2  
     3  import (
     4  	"errors"
     5  	"github.com/incognitochain/go-incognito-sdk/privacy"
     6  	"math"
     7  )
     8  
     9  const (
    10  	maxExp               = 64
    11  	numOutputParam       = 32
    12  	maxOutputNumber      = 32
    13  	numCommitValue       = 5
    14  	maxOutputNumberParam = 256
    15  )
    16  
    17  // bulletproofParams includes all generator for aggregated range proof
    18  type bulletproofParams struct {
    19  	g  []*privacy.Point
    20  	h  []*privacy.Point
    21  	u  *privacy.Point
    22  	cs []byte
    23  }
    24  
    25  var AggParam = newBulletproofParams(numOutputParam)
    26  
    27  func newBulletproofParams(m int) *bulletproofParams {
    28  	gen := new(bulletproofParams)
    29  	gen.cs = []byte{}
    30  	capacity := maxExp * m // fixed value
    31  	gen.g = make([]*privacy.Point, capacity)
    32  	gen.h = make([]*privacy.Point, capacity)
    33  	csByteH := []byte{}
    34  	csByteG := []byte{}
    35  	for i := 0; i < capacity; i++ {
    36  		gen.g[i] = privacy.HashToPointFromIndex(int64(numCommitValue+i), privacy.CStringBulletProof)
    37  		gen.h[i] = privacy.HashToPointFromIndex(int64(numCommitValue+i+maxOutputNumberParam*maxExp), privacy.CStringBulletProof)
    38  		csByteG = append(csByteG, gen.g[i].ToBytesS()...)
    39  		csByteH = append(csByteH, gen.h[i].ToBytesS()...)
    40  	}
    41  
    42  	gen.u = new(privacy.Point)
    43  	gen.u = privacy.HashToPointFromIndex(int64(numCommitValue+2*maxOutputNumberParam*maxExp), privacy.CStringBulletProof)
    44  
    45  	gen.cs = append(gen.cs, csByteG...)
    46  	gen.cs = append(gen.cs, csByteH...)
    47  	gen.cs = append(gen.cs, gen.u.ToBytesS()...)
    48  
    49  	return gen
    50  }
    51  
    52  func generateChallenge(values [][]byte) *privacy.Scalar {
    53  	bytes := []byte{}
    54  	for i := 0; i < len(values); i++ {
    55  		bytes = append(bytes, values[i]...)
    56  	}
    57  	hash := privacy.HashToScalar(bytes)
    58  	return hash
    59  }
    60  
    61  func generateChallengeOld(AggParam *bulletproofParams, values [][]byte) *privacy.Scalar {
    62  	bytes := []byte{}
    63  	for i := 0; i < len(AggParam.g); i++ {
    64  		bytes = append(bytes, AggParam.g[i].ToBytesS()...)
    65  	}
    66  
    67  	for i := 0; i < len(AggParam.h); i++ {
    68  		bytes = append(bytes, AggParam.h[i].ToBytesS()...)
    69  	}
    70  
    71  	bytes = append(bytes, AggParam.u.ToBytesS()...)
    72  
    73  	for i := 0; i < len(values); i++ {
    74  		bytes = append(bytes, values[i]...)
    75  	}
    76  
    77  	hash := privacy.HashToScalar(bytes)
    78  	return hash
    79  }
    80  
    81  // pad returns number has format 2^k that it is the nearest number to num
    82  func pad(num int) int {
    83  	if num == 1 || num == 2 {
    84  		return num
    85  	}
    86  	tmp := 2
    87  	for i := 2; ; i++ {
    88  		tmp *= 2
    89  		if tmp >= num {
    90  			num = tmp
    91  			break
    92  		}
    93  	}
    94  	return num
    95  }
    96  
    97  /*-----------------------------Vector Functions-----------------------------*/
    98  // The length here always has to be a power of two
    99  
   100  //vectorAdd adds two vector and returns result vector
   101  func vectorAdd(a []*privacy.Scalar, b []*privacy.Scalar) ([]*privacy.Scalar, error) {
   102  	if len(a) != len(b) {
   103  		return nil, errors.New("VectorAdd: Arrays not of the same length")
   104  	}
   105  
   106  	res := make([]*privacy.Scalar, len(a))
   107  	for i := range a {
   108  		res[i] = new(privacy.Scalar).Add(a[i], b[i])
   109  	}
   110  	return res, nil
   111  }
   112  
   113  // innerProduct calculates inner product between two vectors a and b
   114  func innerProduct(a []*privacy.Scalar, b []*privacy.Scalar) (*privacy.Scalar, error) {
   115  	if len(a) != len(b) {
   116  		return nil, errors.New("InnerProduct: Arrays not of the same length")
   117  	}
   118  	res := new(privacy.Scalar).FromUint64(uint64(0))
   119  	for i := range a {
   120  		//res = a[i]*b[i] + res % l
   121  		res.MulAdd(a[i], b[i], res)
   122  	}
   123  	return res, nil
   124  }
   125  
   126  // hadamardProduct calculates hadamard product between two vectors a and b
   127  func hadamardProduct(a []*privacy.Scalar, b []*privacy.Scalar) ([]*privacy.Scalar, error) {
   128  	if len(a) != len(b) {
   129  		return nil, errors.New("InnerProduct: Arrays not of the same length")
   130  	}
   131  
   132  	res := make([]*privacy.Scalar, len(a))
   133  	for i := 0; i < len(res); i++ {
   134  		res[i] = new(privacy.Scalar).Mul(a[i], b[i])
   135  	}
   136  	return res, nil
   137  }
   138  
   139  // powerVector calculates base^n
   140  func powerVector(base *privacy.Scalar, n int) []*privacy.Scalar {
   141  	res := make([]*privacy.Scalar, n)
   142  	res[0] = new(privacy.Scalar).FromUint64(1)
   143  	if n > 1 {
   144  		res[1] = new(privacy.Scalar).Set(base)
   145  		for i := 2; i < n; i++ {
   146  			res[i] = new(privacy.Scalar).Mul(res[i-1], base)
   147  		}
   148  	}
   149  	return res
   150  }
   151  
   152  // vectorAddScalar adds a vector to a big int, returns big int array
   153  func vectorAddScalar(v []*privacy.Scalar, s *privacy.Scalar) []*privacy.Scalar {
   154  	res := make([]*privacy.Scalar, len(v))
   155  
   156  	for i := range v {
   157  		res[i] = new(privacy.Scalar).Add(v[i], s)
   158  	}
   159  	return res
   160  }
   161  
   162  // vectorMulScalar mul a vector to a big int, returns a vector
   163  func vectorMulScalar(v []*privacy.Scalar, s *privacy.Scalar) []*privacy.Scalar {
   164  	res := make([]*privacy.Scalar, len(v))
   165  
   166  	for i := range v {
   167  		res[i] = new(privacy.Scalar).Mul(v[i], s)
   168  	}
   169  	return res
   170  }
   171  
   172  // CommitAll commits a list of PCM_CAPACITY value(s)
   173  func encodeVectors(l []*privacy.Scalar, r []*privacy.Scalar, g []*privacy.Point, h []*privacy.Point) (*privacy.Point, error) {
   174  	if len(l) != len(r) || len(g) != len(l) || len(h) != len(g) {
   175  		return nil, errors.New("invalid input")
   176  	}
   177  	tmp1 := new(privacy.Point).MultiScalarMult(l, g)
   178  	tmp2 := new(privacy.Point).MultiScalarMult(r, h)
   179  
   180  	res := new(privacy.Point).Add(tmp1, tmp2)
   181  	return res, nil
   182  }
   183  
   184  // estimateMultiRangeProofSize estimate multi range proof size
   185  func EstimateMultiRangeProofSize(nOutput int) uint64 {
   186  	return uint64((nOutput+2*int(math.Log2(float64(maxExp*pad(nOutput))))+5)*privacy.Ed25519KeySize + 5*privacy.Ed25519KeySize + 2)
   187  }