// 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]) }