github.com/dusk-network/dusk-crypto@v0.1.3/rangeproof/vector/vector.go (about)

     1  package vector
     2  
     3  import (
     4  	"errors"
     5  
     6  	ristretto "github.com/bwesterb/go-ristretto"
     7  )
     8  
     9  // Add adds two scalar slices a and b,
    10  // returning the resulting slice and an error
    11  // if a and b were different sizes
    12  func Add(a, b []ristretto.Scalar) ([]ristretto.Scalar, error) {
    13  	if len(a) != len(b) {
    14  		return nil, errors.New("Length of a does not equal b")
    15  	}
    16  
    17  	res := make([]ristretto.Scalar, len(a))
    18  
    19  	for i := 0; i < len(a); i++ {
    20  		res[i].Add(&a[i], &b[i])
    21  	}
    22  
    23  	return res, nil
    24  }
    25  
    26  // AddScalar takes a scalar slice a and a scalar, b
    27  // then adds b to every element in a
    28  func AddScalar(a []ristretto.Scalar, b ristretto.Scalar) []ristretto.Scalar {
    29  
    30  	res := make([]ristretto.Scalar, len(a))
    31  
    32  	for i := 0; i < len(a); i++ {
    33  		res[i].Add(&a[i], &b)
    34  	}
    35  
    36  	return res
    37  }
    38  
    39  // Sub subtracts a vector a from a vector b
    40  func Sub(a, b []ristretto.Scalar) ([]ristretto.Scalar, error) {
    41  	if len(a) != len(b) {
    42  		return nil, errors.New("Length of a does not equal b")
    43  	}
    44  
    45  	res := make([]ristretto.Scalar, len(a))
    46  
    47  	for i := 0; i < len(a); i++ {
    48  		res[i].Sub(&a[i], &b[i])
    49  	}
    50  
    51  	return res, nil
    52  }
    53  
    54  // Neg Negates a vector a
    55  func Neg(a []ristretto.Scalar) []ristretto.Scalar {
    56  	if len(a) == 0 {
    57  		return a
    58  	}
    59  
    60  	res := make([]ristretto.Scalar, len(a))
    61  
    62  	for i := range a {
    63  		res[i].Neg(&a[i])
    64  	}
    65  
    66  	return res
    67  }
    68  
    69  // SubScalar Subtracts a scalars value b, from every element in the slice a
    70  func SubScalar(a []ristretto.Scalar, b ristretto.Scalar) []ristretto.Scalar {
    71  
    72  	if b.IsNonZeroI() == 0 {
    73  		return a
    74  	}
    75  
    76  	res := make([]ristretto.Scalar, len(a))
    77  
    78  	for i := 0; i < len(a); i++ {
    79  		res[i].Sub(&a[i], &b)
    80  	}
    81  
    82  	return res
    83  }
    84  
    85  // MulScalar take a scalar b, and a vector a
    86  // then multiplies every element in the scalar vector by b
    87  func MulScalar(a []ristretto.Scalar, b ristretto.Scalar) []ristretto.Scalar {
    88  
    89  	res := make([]ristretto.Scalar, len(a))
    90  
    91  	for i := 0; i < len(a); i++ {
    92  		res[i].Mul(&a[i], &b)
    93  	}
    94  
    95  	return res
    96  }
    97  
    98  // InnerProduct takes two scalar arrays and constructs the inner product
    99  func InnerProduct(a, b []ristretto.Scalar) (ristretto.Scalar, error) {
   100  
   101  	res := ristretto.Scalar{}
   102  	res.SetZero()
   103  
   104  	if len(a) != len(b) {
   105  		return res, errors.New("[Inner Product]:Length of a does not equal length of b")
   106  	}
   107  
   108  	for i := 0; i < len(a); i++ {
   109  		res.MulAdd(&a[i], &b[i], &res)
   110  	}
   111  
   112  	return res, nil
   113  }
   114  
   115  // Exp exponentiates and sums a vector a to b, creating a commitment
   116  func Exp(a []ristretto.Scalar, b []ristretto.Point, N, M int) (ristretto.Point, error) {
   117  	result := ristretto.Point{} // defaults to zero
   118  	result.SetZero()
   119  
   120  	if len(a) != len(b) {
   121  		return result, errors.New("length of slice of scalars a does not equal length of slices of points b")
   122  	}
   123  
   124  	if len(a) < N*M {
   125  		return result, errors.New("length of scalar a is not less than N*M")
   126  	}
   127  
   128  	for i := range b {
   129  
   130  		scalar := a[i]
   131  		point := b[i]
   132  
   133  		var sum ristretto.Point
   134  		sum.ScalarMult(&point, &scalar)
   135  
   136  		result.Add(&result, &sum)
   137  
   138  	}
   139  
   140  	return result, nil
   141  }
   142  
   143  // ScalarPowers constructs a vector of powers
   144  // vecPowers(5, 3) = <5^0, 5^1, 5^2>
   145  func ScalarPowers(a ristretto.Scalar, n uint32) []ristretto.Scalar {
   146  
   147  	res := make([]ristretto.Scalar, n)
   148  
   149  	if n == 0 {
   150  		return res
   151  	}
   152  
   153  	if a.IsNonZeroI() == 0 {
   154  		return res
   155  	}
   156  
   157  	var k ristretto.Scalar
   158  	k.SetOne()
   159  	res[0] = k
   160  
   161  	if n == 1 {
   162  		return res
   163  	}
   164  	res[1] = a
   165  
   166  	for i := uint32(2); i < n; i++ {
   167  		res[i].Mul(&res[i-1], &a)
   168  	}
   169  
   170  	return res
   171  }
   172  
   173  // ScalarPowersSum constructs the Scalar power and then sums up each value
   174  func ScalarPowersSum(a ristretto.Scalar, n uint64) ristretto.Scalar {
   175  
   176  	res := ristretto.Scalar{}
   177  	res.SetZero()
   178  
   179  	if n == 0 {
   180  		return res
   181  	}
   182  
   183  	res.SetOne()
   184  
   185  	if n == 1 {
   186  		return res
   187  	}
   188  
   189  	prev := a
   190  
   191  	for i := uint64(1); i < n; i++ {
   192  		if i > 1 {
   193  			prev.Mul(&prev, &a)
   194  		}
   195  		res.Add(&res, &prev)
   196  	}
   197  
   198  	return res
   199  }
   200  
   201  // Hadamard takes two scalar arrays and construct the Hadamard product
   202  func Hadamard(a, b []ristretto.Scalar) ([]ristretto.Scalar, error) {
   203  
   204  	if len(a) != len(b) {
   205  		return nil, errors.New("Length of a does not equal length of b")
   206  	}
   207  
   208  	res := make([]ristretto.Scalar, len(a))
   209  
   210  	for i := 0; i < len(a); i++ {
   211  		res[i].Mul(&a[i], &b[i])
   212  	}
   213  	return res, nil
   214  }
   215  
   216  // FromScalar takes a scalar,a, scaToVec will return a slice of size n, with all elements equal to a
   217  func FromScalar(a ristretto.Scalar, n uint32) []ristretto.Scalar {
   218  	res := make([]ristretto.Scalar, n)
   219  
   220  	for i := uint32(0); i < n; i++ {
   221  		res[i] = a
   222  	}
   223  
   224  	return res
   225  }
   226  
   227  // SplitPoints will split a slice x using n
   228  // Result will be two slices a and b where a = [0,n) and b = [n, len(x))
   229  func SplitPoints(x []ristretto.Point, n uint32) ([]ristretto.Point, []ristretto.Point, error) {
   230  	if len(x) <= 0 {
   231  		return nil, nil, errors.New("Original vector has length of zero")
   232  	}
   233  	if n >= uint32(len(x)) {
   234  		return nil, nil, errors.New("n is larger than the size of the slice x")
   235  	}
   236  	return x[:n], x[n:], nil
   237  }
   238  
   239  // SplitScalars will split a slice x using n
   240  // Result will be two slices a and b where a = [0,n) and b = [n, len(x))
   241  // Method same as above
   242  // XXX: use unit test to make sure they output same sizes
   243  func SplitScalars(x []ristretto.Scalar, n uint32) ([]ristretto.Scalar, []ristretto.Scalar, error) {
   244  	if len(x) <= 0 {
   245  		return nil, nil, errors.New("Original vector has length of zero")
   246  	}
   247  	if n >= uint32(len(x)) {
   248  		return nil, nil, errors.New("n is larger than the size of the slice x")
   249  	}
   250  	return x[:n], x[n:], nil
   251  }