// // Copyright Coinbase, Inc. All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // package accumulator import ( "fmt" "math" "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves" ) // dad constructs two polynomials - dA(x) and dD(x) // dA(y) = prod(y_A,t - y), t = 1...n // dD(y) = prod(y_D,t - y), t = 1...n func dad(values []Element, y Element) (Element, error) { if values == nil || y == nil { return nil, fmt.Errorf("curve, values or y should not be nil") } for _, value := range values { if value == nil { return nil, fmt.Errorf("some element is nil") } } result := y.One() if len(values) == 1 { a := values[0] result = a.Sub(y) } else { for i := 0; i < len(values); i++ { temp := values[i].Sub(y) result = result.Mul(temp) } } return result, nil } type polynomialPoint []curves.Point // evaluate evaluates a PolynomialG1 on input x. func (p polynomialPoint) evaluate(x curves.Scalar) (curves.Point, error) { if p == nil { return nil, fmt.Errorf("p cannot be empty") } for i := 0; i < len(p); i++ { if p[i] == nil { return nil, fmt.Errorf("some coefficient in p is nil") } } pp := x res := p[0] for i := 1; i < len(p); i++ { r := p[i].Mul(pp) res = res.Add(r) pp = pp.Mul(x) } return res, nil } // Add adds two PolynomialG1 func (p polynomialPoint) Add(rhs polynomialPoint) (polynomialPoint, error) { maxLen := int(math.Max(float64(len(p)), float64(len(rhs)))) result := make(polynomialPoint, maxLen) for i, c := range p { if c == nil { return nil, fmt.Errorf("invalid coefficient at %d", i) } result[i] = c.Add(c.Identity()) } for i, c := range rhs { if c == nil { return nil, fmt.Errorf("invalid coefficient at %d", i) } if result[i] == nil { result[i] = c.Add(c.Identity()) } else { result[i] = result[i].Add(c) } } return result, nil } // Mul for PolynomialG1 computes rhs * p, p is a polynomial, rhs is a value func (p polynomialPoint) Mul(rhs curves.Scalar) (polynomialPoint, error) { result := make(polynomialPoint, len(p)) for i, c := range p { if c == nil { return nil, fmt.Errorf("invalid coefficient at %d", i) } result[i] = c.Mul(rhs) } return result, nil } type polynomial []curves.Scalar // Add adds two polynomials func (p polynomial) Add(rhs polynomial) (polynomial, error) { maxLen := int(math.Max(float64(len(p)), float64(len(rhs)))) result := make([]curves.Scalar, maxLen) for i, c := range p { if c == nil { return nil, fmt.Errorf("invalid coefficient at %d", i) } result[i] = c.Clone() } for i, c := range rhs { if c == nil { return nil, fmt.Errorf("invalid coefficient at %d", i) } if result[i] == nil { result[i] = c.Clone() } else { result[i] = result[i].Add(c) } } return result, nil } // Sub computes p-rhs and returns func (p polynomial) Sub(rhs polynomial) (polynomial, error) { maxLen := int(math.Max(float64(len(p)), float64(len(rhs)))) result := make([]curves.Scalar, maxLen) for i, c := range p { if c == nil { return nil, fmt.Errorf("invalid coefficient at %d", i) } result[i] = c.Clone() } for i, c := range rhs { if c == nil { return nil, fmt.Errorf("invalid coefficient at %d", i) } if result[i] == nil { result[i] = c.Neg() } else { result[i] = result[i].Sub(c) } } return result, nil } // Mul multiplies two polynomials - p * rhs func (p polynomial) Mul(rhs polynomial) (polynomial, error) { // Check for each coefficient that should not be nil for i, c := range p { if c == nil { return nil, fmt.Errorf("coefficient in p at %d is nil", i) } } for i, c := range rhs { if c == nil { return nil, fmt.Errorf("coefficient in rhs at %d is nil", i) } } m := len(p) n := len(rhs) // Initialize the product polynomial prod := make(polynomial, m+n-1) for i := 0; i < len(prod); i++ { prod[i] = p[0].Zero() } // Multiply two polynomials term by term for i, cp := range p { for j, cr := range rhs { temp := cp.Mul(cr) prod[i+j] = prod[i+j].Add(temp) } } return prod, nil } // MulScalar computes p * rhs, where rhs is a scalar value func (p polynomial) MulScalar(rhs curves.Scalar) (polynomial, error) { result := make(polynomial, len(p)) for i, c := range p { if c == nil { return nil, fmt.Errorf("coefficient at %d is nil", i) } result[i] = c.Mul(rhs) } return result, nil }