2021-11-08 16:39:17 +00:00

555 lines
22 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"
import "math/big"
import "strconv"
//import "crypto/rand"
import "encoding/hex"
import "github.com/deroproject/derohe/cryptography/bn256"
//import "golang.org/x/crypto/sha3"
// below 2 structures form bulletproofs and many to many proofs
type AnonSupport struct {
v *big.Int
w *big.Int
vPow *big.Int
wPow *big.Int
f [][2]*big.Int
r [][2]*big.Int
temp *bn256.G1
CLnR *bn256.G1
CRnR *bn256.G1
CR [][2]*bn256.G1
yR [][2]*bn256.G1
C_XR *bn256.G1
y_XR *bn256.G1
gR *bn256.G1
DR *bn256.G1
}
type ProtocolSupport struct {
y *big.Int
ys []*big.Int
z *big.Int
zs []*big.Int // [z^2, z^3] // only max 2
twoTimesZSquared [128]*big.Int
zSum *big.Int
x *big.Int
t *big.Int
k *big.Int
tEval *bn256.G1
}
// sigma protocol
type SigmaSupport struct {
c *big.Int
A_y, A_D, A_b, A_X, A_t, A_u *bn256.G1
}
// support structures are those which
type InnerProductSupport struct {
P bn256.G1
u_x bn256.G1
hPrimes []*bn256.G1
hPrimeSum bn256.G1
o *big.Int
}
func unmarshalpoint(input string) *bn256.G1 {
d, err := hex.DecodeString(input)
if err != nil {
panic(err)
}
if len(d) != 64 {
panic("wrong length")
}
x := new(bn256.G1)
x.Unmarshal(d)
return x
}
var gparams = NewGeneratorParams(128) // these can be pregenerated similarly as in DERO project
// verify proof
// first generate supporting structures
func (proof *Proof) Verify(scid Hash, scid_index int, s *Statement, txid Hash, extra_value uint64) bool {
var anonsupport AnonSupport
var protsupport ProtocolSupport
var sigmasupport SigmaSupport
if len(s.C) != len(s.Publickeylist) {
return false
}
total_open_value := s.Fees + extra_value
if total_open_value < s.Fees || total_open_value < extra_value { // stop over flowing attacks
return false
}
statementhash := reducedhash(txid[:])
var input []byte
input = append(input, ConvertBigIntToByte(statementhash)...)
input = append(input, proof.BA.Marshal()...)
input = append(input, proof.BS.Marshal()...)
input = append(input, proof.A.Marshal()...)
input = append(input, proof.B.Marshal()...)
anonsupport.v = reducedhash(input)
anonsupport.w = proof.hashmash1(anonsupport.v)
m := proof.f.Length() / 2
N := int(math.Pow(2, float64(m)))
anonsupport.f = make([][2]*big.Int, 2*m, 2*m)
// the secret parity is checked cryptographically
for k := 0; k < 2*m; k++ {
anonsupport.f[k][1] = new(big.Int).Set(proof.f.vector[k])
anonsupport.f[k][0] = new(big.Int).Mod(new(big.Int).Sub(anonsupport.w, proof.f.vector[k]), bn256.Order)
}
// check parity condition
if anonsupport.w.Cmp(proof.f.vector[0]) == 0 || anonsupport.w.Cmp(proof.f.vector[m]) == 0 {
// fmt.Printf("parity is well formed\n")
} else { // test failed, reject the tx
Logger.V(1).Info("Parity check failed")
return false
}
anonsupport.temp = new(bn256.G1)
var zeroes [64]byte
anonsupport.temp.Unmarshal(zeroes[:])
for k := 0; k < 2*m; k++ {
anonsupport.temp = new(bn256.G1).Add(anonsupport.temp, new(bn256.G1).ScalarMult(gparams.Gs.vector[k], anonsupport.f[k][1]))
t := new(big.Int).Mod(new(big.Int).Mul(anonsupport.f[k][1], anonsupport.f[k][0]), bn256.Order)
anonsupport.temp = new(bn256.G1).Add(anonsupport.temp, new(bn256.G1).ScalarMult(gparams.Hs.vector[k], t))
}
t0 := new(bn256.G1).ScalarMult(gparams.Hs.vector[0+2*m], new(big.Int).Mod(new(big.Int).Mul(anonsupport.f[0][1], anonsupport.f[m][1]), bn256.Order))
t1 := new(bn256.G1).ScalarMult(gparams.Hs.vector[1+2*m], new(big.Int).Mod(new(big.Int).Mul(anonsupport.f[0][0], anonsupport.f[m][0]), bn256.Order))
anonsupport.temp = new(bn256.G1).Add(anonsupport.temp, t0)
anonsupport.temp = new(bn256.G1).Add(anonsupport.temp, t1)
// check whether we successfuly recover B^w * A
stored := new(bn256.G1).Add(new(bn256.G1).ScalarMult(proof.B, anonsupport.w), proof.A)
computed := new(bn256.G1).Add(anonsupport.temp, new(bn256.G1).ScalarMult(gparams.H, proof.z_A))
// for i := range proof.f.vector {
// klog.V(2).Infof("proof.f %d %s\n", i, proof.f.vector[i].Text(16))
// }
// klog.V(2).Infof("anonsupport.w %s\n", anonsupport.w.Text(16))
// klog.V(2).Infof("proof.z_A %s\n", proof.z_A.Text(16))
// klog.V(2).Infof("proof.B %s\n", proof.B.String())
// klog.V(2).Infof("proof.A %s\n", proof.A.String())
// klog.V(2).Infof("gparams.H %s\n", gparams.H.String())
// klog.V(2).Infof("stored %s\n", stored.String())
// klog.V(2).Infof("computed %s\n", computed.String())
if stored.String() != computed.String() { // if failed bail out
Logger.V(1).Info("Recover key failed B^w * A")
return false
}
anonsupport.r = assemblepolynomials(anonsupport.f)
// for i := 0; i < len(anonsupport.r); i++ {
// klog.V(2).Infof("proof.r %d %s\n", i, anonsupport.r[i][0].Text(16))
// }
// for i := 0; i < len(anonsupport.r); i++ {
// klog.V(2).Infof("proof.q %d %s\n", i, anonsupport.r[i][1].Text(16))
// }
anonsupport.CLnR = new(bn256.G1)
anonsupport.CRnR = new(bn256.G1)
anonsupport.CLnR.Unmarshal(zeroes[:])
anonsupport.CRnR.Unmarshal(zeroes[:])
for i := 0; i < N; i++ {
anonsupport.CLnR = new(bn256.G1).Add(anonsupport.CLnR, new(bn256.G1).ScalarMult(s.CLn[i], anonsupport.r[i][0]))
anonsupport.CRnR = new(bn256.G1).Add(anonsupport.CRnR, new(bn256.G1).ScalarMult(s.CRn[i], anonsupport.r[i][0]))
}
// klog.V(2).Infof("qCrnR %s\n", anonsupport.CRnR.String())
var p, q []*big.Int
for i := 0; i < len(anonsupport.r); i++ {
p = append(p, anonsupport.r[i][0])
q = append(q, anonsupport.r[i][1])
}
// for i := range s.C {
// klog.V(2).Infof("S.c %d %s \n", i, s.C[i].String())
// }
// share code with proof generator for better testing
C_p := Convolution(NewFieldVector(p), NewPointVector(s.C))
C_q := Convolution(NewFieldVector(q), NewPointVector(s.C))
y_p := Convolution(NewFieldVector(p), NewPointVector(s.Publickeylist))
y_q := Convolution(NewFieldVector(q), NewPointVector(s.Publickeylist))
// for i := range s.C {
// klog.V(2).Infof("S.c %d %s \n", i, s.C[i].String())
// }
// for i := range y_p.vector {
// klog.V(2).Infof("y_p %d %s \n", i, y_p.vector[i].String())
// }
// for i := range y_q.vector {
// klog.V(2).Infof("y_q %d %s \n", i, y_q.vector[i].String())
// }
for i := range C_p.vector { // assemble back
anonsupport.CR = append(anonsupport.CR, [2]*bn256.G1{C_p.vector[i], C_q.vector[i]})
anonsupport.yR = append(anonsupport.yR, [2]*bn256.G1{y_p.vector[i], y_q.vector[i]})
}
anonsupport.vPow = new(big.Int).SetUint64(1)
anonsupport.C_XR = new(bn256.G1)
anonsupport.y_XR = new(bn256.G1)
anonsupport.C_XR.Unmarshal(zeroes[:])
anonsupport.y_XR.Unmarshal(zeroes[:])
for i := 0; i < N; i++ {
anonsupport.C_XR.Add(new(bn256.G1).Set(anonsupport.C_XR), new(bn256.G1).ScalarMult(anonsupport.CR[i/2][i%2], anonsupport.vPow))
anonsupport.y_XR.Add(new(bn256.G1).Set(anonsupport.y_XR), new(bn256.G1).ScalarMult(anonsupport.yR[i/2][i%2], anonsupport.vPow))
if i > 0 {
anonsupport.vPow = new(big.Int).Mod(new(big.Int).Mul(anonsupport.vPow, anonsupport.v), bn256.Order)
// klog.V(2).Infof("vPow %s\n", anonsupport.vPow.Text(16))
}
}
// klog.V(2).Infof("vPow %s\n", anonsupport.vPow.Text(16))
// klog.V(2).Infof("v %s\n", anonsupport.v.Text(16))
anonsupport.wPow = new(big.Int).SetUint64(1)
anonsupport.gR = new(bn256.G1)
anonsupport.gR.Unmarshal(zeroes[:])
anonsupport.DR = new(bn256.G1)
anonsupport.DR.Unmarshal(zeroes[:])
for i := 0; i < m; i++ {
wPow_neg := new(big.Int).Mod(new(big.Int).Neg(anonsupport.wPow), bn256.Order)
anonsupport.CLnR.Add(new(bn256.G1).Set(anonsupport.CLnR), new(bn256.G1).ScalarMult(proof.CLnG[i], wPow_neg))
anonsupport.CRnR.Add(new(bn256.G1).Set(anonsupport.CRnR), new(bn256.G1).ScalarMult(proof.CRnG[i], wPow_neg))
anonsupport.CR[0][0].Add(new(bn256.G1).Set(anonsupport.CR[0][0]), new(bn256.G1).ScalarMult(proof.C_0G[i], wPow_neg))
anonsupport.DR.Add(new(bn256.G1).Set(anonsupport.DR), new(bn256.G1).ScalarMult(proof.DG[i], wPow_neg))
anonsupport.yR[0][0].Add(new(bn256.G1).Set(anonsupport.yR[0][0]), new(bn256.G1).ScalarMult(proof.y_0G[i], wPow_neg))
anonsupport.gR.Add(new(bn256.G1).Set(anonsupport.gR), new(bn256.G1).ScalarMult(proof.gG[i], wPow_neg))
anonsupport.C_XR.Add(new(bn256.G1).Set(anonsupport.C_XR), new(bn256.G1).ScalarMult(proof.C_XG[i], wPow_neg))
anonsupport.y_XR.Add(new(bn256.G1).Set(anonsupport.y_XR), new(bn256.G1).ScalarMult(proof.y_XG[i], wPow_neg))
anonsupport.wPow = new(big.Int).Mod(new(big.Int).Mul(anonsupport.wPow, anonsupport.w), bn256.Order)
}
// klog.V(2).Infof("qCrnR %s\n", anonsupport.CRnR.String())
anonsupport.DR.Add(new(bn256.G1).Set(anonsupport.DR), new(bn256.G1).ScalarMult(s.D, anonsupport.wPow))
anonsupport.gR.Add(new(bn256.G1).Set(anonsupport.gR), new(bn256.G1).ScalarMult(gparams.G, anonsupport.wPow))
anonsupport.C_XR.Add(new(bn256.G1).Set(anonsupport.C_XR), new(bn256.G1).ScalarMult(gparams.G, new(big.Int).Mod(new(big.Int).Mul(new(big.Int).SetUint64(total_open_value), anonsupport.wPow), bn256.Order)))
//anonAuxiliaries.C_XR = anonAuxiliaries.C_XR.add(Utils.g().mul(Utils.fee().mul(anonAuxiliaries.wPow))); // this line is new
// at this point, these parameters are comparable with proof generator
// klog.V(2).Infof("CLnR %s\n", anonsupport.CLnR.String())
// klog.V(2).Infof("qCrnR %s\n", anonsupport.CRnR.String())
// klog.V(2).Infof("DR %s\n", anonsupport.DR.String())
// klog.V(2).Infof("gR %s\n", anonsupport.gR.String())
// klog.V(2).Infof("C_XR %s\n", anonsupport.C_XR.String())
// klog.V(2).Infof("y_XR %s\n", anonsupport.y_XR.String())
protsupport.y = reducedhash(ConvertBigIntToByte(anonsupport.w))
protsupport.ys = append(protsupport.ys, new(big.Int).SetUint64(1))
protsupport.k = new(big.Int).SetUint64(1)
for i := 1; i < 128; i++ {
protsupport.ys = append(protsupport.ys, new(big.Int).Mod(new(big.Int).Mul(protsupport.ys[i-1], protsupport.y), bn256.Order))
protsupport.k = new(big.Int).Mod(new(big.Int).Add(protsupport.k, protsupport.ys[i]), bn256.Order)
}
protsupport.z = reducedhash(ConvertBigIntToByte(protsupport.y))
protsupport.zs = []*big.Int{new(big.Int).Exp(protsupport.z, new(big.Int).SetUint64(2), bn256.Order), new(big.Int).Exp(protsupport.z, new(big.Int).SetUint64(3), bn256.Order)}
protsupport.zSum = new(big.Int).Mod(new(big.Int).Add(protsupport.zs[0], protsupport.zs[1]), bn256.Order)
protsupport.zSum = new(big.Int).Mod(new(big.Int).Mul(new(big.Int).Set(protsupport.zSum), protsupport.z), bn256.Order)
// klog.V(2).Infof("zsum %s\n ", protsupport.zSum.Text(16))
z_z0 := new(big.Int).Mod(new(big.Int).Sub(protsupport.z, protsupport.zs[0]), bn256.Order)
protsupport.k = new(big.Int).Mod(new(big.Int).Mul(protsupport.k, z_z0), bn256.Order)
proof_2_64, _ := new(big.Int).SetString("18446744073709551616", 10)
zsum_pow := new(big.Int).Mod(new(big.Int).Mul(protsupport.zSum, proof_2_64), bn256.Order)
zsum_pow = new(big.Int).Mod(new(big.Int).Sub(zsum_pow, protsupport.zSum), bn256.Order)
protsupport.k = new(big.Int).Mod(new(big.Int).Sub(protsupport.k, zsum_pow), bn256.Order)
protsupport.t = new(big.Int).Mod(new(big.Int).Sub(proof.that, protsupport.k), bn256.Order) // t = tHat - delta(y, z)
// klog.V(2).Infof("that %s\n ", proof.that.Text(16))
// klog.V(2).Infof("zk %s\n ", protsupport.k.Text(16))
for i := 0; i < 64; i++ {
protsupport.twoTimesZSquared[i] = new(big.Int).Mod(new(big.Int).Mul(protsupport.zs[0], new(big.Int).SetUint64(uint64(math.Pow(2, float64(i))))), bn256.Order)
protsupport.twoTimesZSquared[64+i] = new(big.Int).Mod(new(big.Int).Mul(protsupport.zs[1], new(big.Int).SetUint64(uint64(math.Pow(2, float64(i))))), bn256.Order)
}
// for i := 0; i < 128; i++ {
// klog.V(2).Infof("zsq %d %s", i, protsupport.twoTimesZSquared[i].Text(16))
// }
x := new(big.Int)
{
var input []byte
input = append(input, ConvertBigIntToByte(protsupport.z)...) // tie intermediates/commit
input = append(input, proof.T_1.Marshal()...)
input = append(input, proof.T_2.Marshal()...)
x = reducedhash(input)
}
xsq := new(big.Int).Mod(new(big.Int).Mul(x, x), bn256.Order)
protsupport.tEval = new(bn256.G1).ScalarMult(proof.T_1, x)
protsupport.tEval.Add(new(bn256.G1).Set(protsupport.tEval), new(bn256.G1).ScalarMult(proof.T_2, xsq))
//fmt.Printf("protsupport.tEval %s\n", protsupport.tEval.String())
proof_c_neg := new(big.Int).Mod(new(big.Int).Neg(proof.c), bn256.Order)
sigmasupport.A_y = new(bn256.G1).Add(new(bn256.G1).ScalarMult(anonsupport.gR, proof.s_sk), new(bn256.G1).ScalarMult(anonsupport.yR[0][0], proof_c_neg))
sigmasupport.A_D = new(bn256.G1).Add(new(bn256.G1).ScalarMult(gparams.G, proof.s_r), new(bn256.G1).ScalarMult(s.D, proof_c_neg))
zs0_neg := new(big.Int).Mod(new(big.Int).Neg(protsupport.zs[0]), bn256.Order)
left := new(bn256.G1).ScalarMult(anonsupport.DR, zs0_neg)
left.Add(new(bn256.G1).Set(left), new(bn256.G1).ScalarMult(anonsupport.CRnR, protsupport.zs[1]))
left = new(bn256.G1).ScalarMult(new(bn256.G1).Set(left), proof.s_sk)
// TODO mid seems wrong
amount_fees := new(big.Int).SetUint64(total_open_value)
mid := new(bn256.G1).ScalarMult(G, new(big.Int).Mod(new(big.Int).Mul(amount_fees, anonsupport.wPow), bn256.Order))
mid.Add(new(bn256.G1).Set(mid), new(bn256.G1).Set(anonsupport.CR[0][0]))
right := new(bn256.G1).ScalarMult(mid, zs0_neg)
right.Add(new(bn256.G1).Set(right), new(bn256.G1).ScalarMult(anonsupport.CLnR, protsupport.zs[1]))
right = new(bn256.G1).ScalarMult(new(bn256.G1).Set(right), proof_c_neg)
sigmasupport.A_b = new(bn256.G1).ScalarMult(gparams.G, proof.s_b)
temp := new(bn256.G1).Add(left, right)
sigmasupport.A_b.Add(new(bn256.G1).Set(sigmasupport.A_b), temp)
//- sigmaAuxiliaries.A_b = Utils.g().mul(proof.s_b).add(anonAuxiliaries.DR.mul(zetherAuxiliaries.zs[0].neg()).add(anonAuxiliaries.CRnR.mul(zetherAuxiliaries.zs[1])).mul(proof.s_sk).add(anonAuxiliaries.CR[0][0] .mul(zetherAuxiliaries.zs[0].neg()).add(anonAuxiliaries.CLnR.mul(zetherAuxiliaries.zs[1])).mul(proof.c.neg())));
//+ sigmaAuxiliaries.A_b = Utils.g().mul(proof.s_b).add(anonAuxiliaries.DR.mul(zetherAuxiliaries.zs[0].neg()).add(anonAuxiliaries.CRnR.mul(zetherAuxiliaries.zs[1])).mul(proof.s_sk).add(anonAuxiliaries.CR[0][0].add(Utils.g().mul(Utils.fee().mul(anonAuxiliaries.wPow))).mul(zetherAuxiliaries.zs[0].neg()).add(anonAuxiliaries.CLnR.mul(zetherAuxiliaries.zs[1])).mul(proof.c.neg())));
//var fees bn256.G1
//fees.ScalarMult(G, new(big.Int).SetInt64(int64( -1 )))
//anonsupport.C_XR.Add( new(bn256.G1).Set(anonsupport.C_XR), &fees)
sigmasupport.A_X = new(bn256.G1).Add(new(bn256.G1).ScalarMult(anonsupport.y_XR, proof.s_r), new(bn256.G1).ScalarMult(anonsupport.C_XR, proof_c_neg))
proof_s_b_neg := new(big.Int).Mod(new(big.Int).Neg(proof.s_b), bn256.Order)
sigmasupport.A_t = new(bn256.G1).ScalarMult(gparams.G, protsupport.t)
sigmasupport.A_t.Add(new(bn256.G1).Set(sigmasupport.A_t), new(bn256.G1).Neg(protsupport.tEval))
sigmasupport.A_t = new(bn256.G1).ScalarMult(sigmasupport.A_t, new(big.Int).Mod(new(big.Int).Mul(proof.c, anonsupport.wPow), bn256.Order))
sigmasupport.A_t.Add(new(bn256.G1).Set(sigmasupport.A_t), new(bn256.G1).ScalarMult(gparams.H, proof.s_tau))
sigmasupport.A_t.Add(new(bn256.G1).Set(sigmasupport.A_t), new(bn256.G1).ScalarMult(gparams.G, proof_s_b_neg))
// klog.V(2).Infof("t %s\n ", protsupport.t.Text(16))
// klog.V(2).Infof("protsupport.tEval %s\n", protsupport.tEval.String())
{
var input []byte
input = append(input, []byte(PROTOCOL_CONSTANT)...)
input = append(input, s.Roothash[:]...)
scid_index_str := strconv.Itoa(scid_index)
input = append(input, scid[:]...)
input = append(input, scid_index_str...)
point := HashToPoint(HashtoNumber(input))
sigmasupport.A_u = new(bn256.G1).ScalarMult(point, proof.s_sk)
sigmasupport.A_u.Add(new(bn256.G1).Set(sigmasupport.A_u), new(bn256.G1).ScalarMult(proof.u, proof_c_neg))
}
//fmt.Printf("A_y %s\n", sigmasupport.A_y.String())
//fmt.Printf("A_D %s\n", sigmasupport.A_D.String())
//fmt.Printf("A_b %s\n", sigmasupport.A_b.String())
//fmt.Printf("A_X %s\n", sigmasupport.A_X.String())
//fmt.Printf("A_t %s\n", sigmasupport.A_t.String())
//fmt.Printf("A_u %s\n", sigmasupport.A_u.String())
{
var input []byte
input = append(input, ConvertBigIntToByte(x)...)
input = append(input, sigmasupport.A_y.Marshal()...)
input = append(input, sigmasupport.A_D.Marshal()...)
input = append(input, sigmasupport.A_b.Marshal()...)
input = append(input, sigmasupport.A_X.Marshal()...)
input = append(input, sigmasupport.A_t.Marshal()...)
input = append(input, sigmasupport.A_u.Marshal()...)
//fmt.Printf("C calculation expected %s actual %s\n",proof.c.Text(16), reducedhash(input).Text(16) )
if reducedhash(input).Text(16) != proof.c.Text(16) { // we must fail here
Logger.V(1).Info("C calculation failed")
return false
}
}
o := reducedhash(ConvertBigIntToByte(proof.c))
u_x := new(bn256.G1).ScalarMult(gparams.H, o)
var hPrimes []*bn256.G1
hPrimeSum := new(bn256.G1)
hPrimeSum.Unmarshal(zeroes[:])
for i := 0; i < 128; i++ {
hPrimes = append(hPrimes, new(bn256.G1).ScalarMult(gparams.Hs.vector[i], new(big.Int).ModInverse(protsupport.ys[i], bn256.Order)))
// klog.V(2).Infof("hPrimes %d %s\n", i, hPrimes[i].String())
tmp := new(big.Int).Mod(new(big.Int).Mul(protsupport.ys[i], protsupport.z), bn256.Order)
tmp = new(big.Int).Mod(new(big.Int).Add(tmp, protsupport.twoTimesZSquared[i]), bn256.Order)
hPrimeSum = new(bn256.G1).Add(hPrimeSum, new(bn256.G1).ScalarMult(hPrimes[i], tmp))
}
P := new(bn256.G1).Add(proof.BA, new(bn256.G1).ScalarMult(proof.BS, x))
P = new(bn256.G1).Add(P, new(bn256.G1).ScalarMult(gparams.GSUM, new(big.Int).Mod(new(big.Int).Neg(protsupport.z), bn256.Order)))
P = new(bn256.G1).Add(P, hPrimeSum)
P = new(bn256.G1).Add(P, new(bn256.G1).ScalarMult(gparams.H, new(big.Int).Mod(new(big.Int).Neg(proof.mu), bn256.Order)))
P = new(bn256.G1).Add(P, new(bn256.G1).ScalarMult(u_x, new(big.Int).Mod(new(big.Int).Set(proof.that), bn256.Order)))
// klog.V(2).Infof("P %s\n", P.String())
if !proof.ip.Verify(hPrimes, u_x, P, o, gparams) {
Logger.V(1).Info("inner proof failed")
return false
}
// klog.V(2).Infof("proof %s\n", proof.String())
// panic("proof successful")
// klog.V(2).Infof("Proof successful verified\n")
return true
}
/*
func (proof *Proof) String() string {
klog.V(1).Infof("proof BA %s\n", proof.BA.String())
klog.V(1).Infof("proof BS %s\n", proof.BS.String())
klog.V(1).Infof("proof A %s\n", proof.A.String())
klog.V(1).Infof("proof B %s\n", proof.B.String())
for i := range proof.CLnG {
klog.V(1).Infof("CLnG %d %s \n", i, proof.CLnG[i].String())
}
for i := range proof.CRnG {
klog.V(1).Infof("CRnG %d %s \n", i, proof.CRnG[i].String())
}
for i := range proof.C_0G {
klog.V(1).Infof("C_0G %d %s \n", i, proof.C_0G[i].String())
}
for i := range proof.DG {
klog.V(1).Infof("DG %d %s \n", i, proof.DG[i].String())
}
for i := range proof.y_0G {
klog.V(1).Infof("y_0G %d %s \n", i, proof.y_0G[i].String())
}
for i := range proof.gG {
klog.V(1).Infof("gG %d %s \n", i, proof.gG[i].String())
}
for i := range proof.C_XG {
klog.V(1).Infof("C_XG %d %s \n", i, proof.C_XG[i].String())
}
for i := range proof.y_XG {
klog.V(1).Infof("y_XG %d %s \n", i, proof.y_XG[i].String())
}
//for i := range proof.tCommits.vector {
// klog.V(1).Infof("tCommits %d %s \n", i, proof.tCommits.vector[i].String())
//}
klog.V(1).Infof("proof z_A %s\n", proof.z_A.Text(16))
klog.V(1).Infof("proof that %s\n", proof.that.Text(16))
klog.V(1).Infof("proof mu %s\n", proof.mu.Text(16))
klog.V(1).Infof("proof C %s\n", proof.c.Text(16))
klog.V(1).Infof("proof s_sk %s\n", proof.s_sk.Text(16))
klog.V(1).Infof("proof s_r %s\n", proof.s_r.Text(16))
klog.V(1).Infof("proof s_b %s\n", proof.s_b.Text(16))
klog.V(1).Infof("proof s_tau %s\n", proof.s_tau.Text(16))
return ""
}
*/
func assemblepolynomials(f [][2]*big.Int) [][2]*big.Int {
m := len(f) / 2
N := int(math.Pow(2, float64(m)))
result := make([][2]*big.Int, N, N)
for i := 0; i < 2; i++ {
half := recursivepolynomials(i*m, (i+1)*m, new(big.Int).SetInt64(1), f)
for j := 0; j < N; j++ {
result[j][i] = half[j]
}
}
return result
}
func recursivepolynomials(baseline, current int, accum *big.Int, f [][2]*big.Int) []*big.Int {
size := int(math.Pow(2, float64(current-baseline)))
result := make([]*big.Int, size, size)
if current == baseline {
result[0] = accum
return result
}
current--
left := recursivepolynomials(baseline, current, new(big.Int).Mod(new(big.Int).Mul(accum, f[current][0]), bn256.Order), f)
right := recursivepolynomials(baseline, current, new(big.Int).Mod(new(big.Int).Mul(accum, f[current][1]), bn256.Order), f)
for i := 0; i < size/2; i++ {
result[i] = left[i]
result[i+size/2] = right[i]
}
return result
}