202 lines
5.2 KiB
Go
202 lines
5.2 KiB
Go
// Copyright 2017-2021 DERO Project. All rights reserved.
|
|
// Use of this source code in any form is governed by RESEARCH license.
|
|
// license can be found in the LICENSE file.
|
|
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
|
|
//
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
package crypto
|
|
|
|
//import "fmt"
|
|
import "math/big"
|
|
|
|
//import "crypto/rand"
|
|
//import "encoding/hex"
|
|
|
|
import "github.com/deroproject/derohe/cryptography/bn256"
|
|
|
|
//import "golang.org/x/crypto/sha3"
|
|
|
|
type FieldVector struct {
|
|
vector []*big.Int
|
|
}
|
|
|
|
func NewFieldVector(input []*big.Int) *FieldVector {
|
|
return &FieldVector{vector: input}
|
|
}
|
|
|
|
func NewFieldVectorRandomFilled(capacity int) *FieldVector {
|
|
fv := &FieldVector{vector: make([]*big.Int, capacity, capacity)}
|
|
for i := range fv.vector {
|
|
fv.vector[i] = RandomScalarFixed()
|
|
}
|
|
return fv
|
|
}
|
|
|
|
func (fv *FieldVector) Length() int {
|
|
return len(fv.vector)
|
|
}
|
|
|
|
// slice and return
|
|
func (fv *FieldVector) Slice(start, end int) *FieldVector {
|
|
var result FieldVector
|
|
for i := start; i < end; i++ {
|
|
result.vector = append(result.vector, new(big.Int).Set(fv.vector[i]))
|
|
}
|
|
return &result
|
|
}
|
|
|
|
//copy and return
|
|
func (fv *FieldVector) Clone() *FieldVector {
|
|
return fv.Slice(0, len(fv.vector))
|
|
}
|
|
|
|
func (fv *FieldVector) SliceRaw(start, end int) []*big.Int {
|
|
var result FieldVector
|
|
for i := start; i < end; i++ {
|
|
result.vector = append(result.vector, new(big.Int).Set(fv.vector[i]))
|
|
}
|
|
return result.vector
|
|
}
|
|
|
|
func (fv *FieldVector) Flip() *FieldVector {
|
|
var result FieldVector
|
|
for i := range fv.vector {
|
|
result.vector = append(result.vector, new(big.Int).Set(fv.vector[(len(fv.vector)-i)%len(fv.vector)]))
|
|
}
|
|
return &result
|
|
}
|
|
|
|
func (fv *FieldVector) Sum() *big.Int {
|
|
var accumulator big.Int
|
|
|
|
for i := range fv.vector {
|
|
var accopy big.Int
|
|
|
|
accopy.Add(&accumulator, fv.vector[i])
|
|
accumulator.Mod(&accopy, bn256.Order)
|
|
}
|
|
|
|
return &accumulator
|
|
}
|
|
|
|
func (fv *FieldVector) Add(addendum *FieldVector) *FieldVector {
|
|
var result FieldVector
|
|
|
|
if len(fv.vector) != len(addendum.vector) {
|
|
panic("mismatched number of elements")
|
|
}
|
|
|
|
for i := range fv.vector {
|
|
var ri big.Int
|
|
ri.Mod(new(big.Int).Add(fv.vector[i], addendum.vector[i]), bn256.Order)
|
|
result.vector = append(result.vector, &ri)
|
|
}
|
|
|
|
return &result
|
|
}
|
|
|
|
func (gv *FieldVector) AddConstant(c *big.Int) *FieldVector {
|
|
var result FieldVector
|
|
|
|
for i := range gv.vector {
|
|
var ri big.Int
|
|
ri.Mod(new(big.Int).Add(gv.vector[i], c), bn256.Order)
|
|
result.vector = append(result.vector, &ri)
|
|
}
|
|
|
|
return &result
|
|
}
|
|
|
|
func (fv *FieldVector) Hadamard(exponent *FieldVector) *FieldVector {
|
|
var result FieldVector
|
|
|
|
if len(fv.vector) != len(exponent.vector) {
|
|
panic("mismatched number of elements")
|
|
}
|
|
for i := range fv.vector {
|
|
result.vector = append(result.vector, new(big.Int).Mod(new(big.Int).Mul(fv.vector[i], exponent.vector[i]), bn256.Order))
|
|
}
|
|
|
|
return &result
|
|
}
|
|
|
|
func (fv *FieldVector) InnerProduct(exponent *FieldVector) *big.Int {
|
|
if len(fv.vector) != len(exponent.vector) {
|
|
panic("mismatched number of elements")
|
|
}
|
|
|
|
accumulator := new(big.Int)
|
|
for i := range fv.vector {
|
|
tmp := new(big.Int).Mod(new(big.Int).Mul(fv.vector[i], exponent.vector[i]), bn256.Order)
|
|
accumulator.Add(accumulator, tmp)
|
|
accumulator.Mod(accumulator, bn256.Order)
|
|
}
|
|
|
|
return accumulator
|
|
}
|
|
|
|
func (fv *FieldVector) Negate() *FieldVector {
|
|
var result FieldVector
|
|
for i := range fv.vector {
|
|
result.vector = append(result.vector, new(big.Int).Mod(new(big.Int).Neg(fv.vector[i]), bn256.Order))
|
|
}
|
|
return &result
|
|
}
|
|
|
|
func (fv *FieldVector) Times(multiplier *big.Int) *FieldVector {
|
|
var result FieldVector
|
|
for i := range fv.vector {
|
|
res := new(big.Int).Mul(fv.vector[i], multiplier)
|
|
res.Mod(res, bn256.Order)
|
|
result.vector = append(result.vector, res)
|
|
}
|
|
return &result
|
|
}
|
|
|
|
func (fv *FieldVector) Invert() *FieldVector {
|
|
var result FieldVector
|
|
for i := range fv.vector {
|
|
result.vector = append(result.vector, new(big.Int).ModInverse(fv.vector[i], bn256.Order))
|
|
}
|
|
return &result
|
|
}
|
|
|
|
func (fv *FieldVector) Concat(addendum *FieldVector) *FieldVector {
|
|
var result FieldVector
|
|
for i := range fv.vector {
|
|
result.vector = append(result.vector, new(big.Int).Set(fv.vector[i]))
|
|
}
|
|
|
|
for i := range addendum.vector {
|
|
result.vector = append(result.vector, new(big.Int).Set(addendum.vector[i]))
|
|
}
|
|
|
|
return &result
|
|
}
|
|
|
|
func (fv *FieldVector) Extract(parity bool) *FieldVector {
|
|
var result FieldVector
|
|
|
|
remainder := 0
|
|
if parity {
|
|
remainder = 1
|
|
}
|
|
for i := range fv.vector {
|
|
if i%2 == remainder {
|
|
|
|
result.vector = append(result.vector, new(big.Int).Set(fv.vector[i]))
|
|
}
|
|
}
|
|
return &result
|
|
}
|