2021-12-04 16:42:11 +00:00

92 lines
2.8 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 Polynomial struct {
coefficients []*big.Int
}
func NewPolynomial(input []*big.Int) *Polynomial {
if input == nil {
return &Polynomial{coefficients: []*big.Int{new(big.Int).SetInt64(1)}}
}
return &Polynomial{coefficients: input}
}
func (p *Polynomial) Length() int {
return len(p.coefficients)
}
func (p *Polynomial) Mul(m *Polynomial) *Polynomial {
var product []*big.Int
for i := range p.coefficients {
product = append(product, new(big.Int).Mod(new(big.Int).Mul(p.coefficients[i], m.coefficients[0]), bn256.Order))
}
product = append(product, new(big.Int)) // add 0 element
if m.coefficients[1].IsInt64() && m.coefficients[1].Int64() == 1 {
for i := range product {
if i > 0 {
tmp := new(big.Int).Add(product[i], p.coefficients[i-1])
product[i] = new(big.Int).Mod(tmp, bn256.Order)
} else { // do nothing
}
}
}
return NewPolynomial(product)
}
type dummy struct {
list [][]*big.Int
}
func RecursivePolynomials(list [][]*big.Int, accum *Polynomial, a, b []*big.Int) (rlist [][]*big.Int) {
var d dummy
d.recursivePolynomialsinternal(accum, a, b)
return d.list
}
func (d *dummy) recursivePolynomialsinternal(accum *Polynomial, a, b []*big.Int) {
if len(a) == 0 {
d.list = append(d.list, accum.coefficients)
return
}
atop := a[len(a)-1]
btop := b[len(b)-1]
left := NewPolynomial([]*big.Int{new(big.Int).Mod(new(big.Int).Neg(atop), bn256.Order), new(big.Int).Mod(new(big.Int).Sub(new(big.Int).SetInt64(1), btop), bn256.Order)})
right := NewPolynomial([]*big.Int{atop, btop})
d.recursivePolynomialsinternal(accum.Mul(left), a[:len(a)-1], b[:len(b)-1])
d.recursivePolynomialsinternal(accum.Mul(right), a[:len(a)-1], b[:len(b)-1])
}