1207 lines
35 KiB
Go
1207 lines
35 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 "bytes"
|
|
|
|
//import "crypto/rand"
|
|
//import "encoding/hex"
|
|
|
|
import "github.com/deroproject/derohe/cryptography/bn256"
|
|
|
|
//import "golang.org/x/crypto/sha3"
|
|
|
|
//import "github.com/kubernetes/klog"
|
|
|
|
type Proof struct {
|
|
BA *bn256.G1
|
|
BS *bn256.G1
|
|
A *bn256.G1
|
|
B *bn256.G1
|
|
|
|
CLnG, CRnG, C_0G, DG, y_0G, gG, C_XG, y_XG []*bn256.G1
|
|
|
|
u *bn256.G1
|
|
|
|
f *FieldVector
|
|
|
|
z_A *big.Int
|
|
|
|
T_1 *bn256.G1
|
|
T_2 *bn256.G1
|
|
|
|
that *big.Int
|
|
mu *big.Int
|
|
|
|
c *big.Int
|
|
s_sk, s_r, s_b, s_tau *big.Int
|
|
|
|
ip *InnerProduct
|
|
}
|
|
|
|
type IPStatement struct {
|
|
PrimeBase *GeneratorParams
|
|
P *bn256.G1
|
|
}
|
|
|
|
type IPWitness struct {
|
|
L *FieldVector
|
|
R *FieldVector
|
|
}
|
|
|
|
// this is based on roothash and user's secret key and thus is the basis of protection from a number of double spending attacks
|
|
func (p *Proof) Nonce() Hash {
|
|
return Keccak256(p.u.EncodeCompressed())
|
|
}
|
|
|
|
func (p *Proof) Serialize(w *bytes.Buffer) {
|
|
if p == nil {
|
|
return
|
|
}
|
|
w.Write(p.BA.EncodeCompressed())
|
|
w.Write(p.BS.EncodeCompressed())
|
|
w.Write(p.A.EncodeCompressed())
|
|
w.Write(p.B.EncodeCompressed())
|
|
|
|
//w.WriteByte(byte(len(p.CLnG))) // we can skip this byte also, why not skip it
|
|
|
|
// fmt.Printf("CLnG byte %d\n",len(p.CLnG))
|
|
for i := 0; i < len(p.CLnG); i++ {
|
|
w.Write(p.CLnG[i].EncodeCompressed())
|
|
w.Write(p.CRnG[i].EncodeCompressed())
|
|
w.Write(p.C_0G[i].EncodeCompressed())
|
|
w.Write(p.DG[i].EncodeCompressed())
|
|
w.Write(p.y_0G[i].EncodeCompressed())
|
|
w.Write(p.gG[i].EncodeCompressed())
|
|
w.Write(p.C_XG[i].EncodeCompressed())
|
|
w.Write(p.y_XG[i].EncodeCompressed())
|
|
}
|
|
|
|
w.Write(p.u.EncodeCompressed())
|
|
|
|
if len(p.CLnG) != len(p.f.vector) {
|
|
/// panic(fmt.Sprintf("different size %d %d", len(p.CLnG), len(p.f.vector)))
|
|
}
|
|
|
|
/*if len(p.f.vector) != 2 {
|
|
panic(fmt.Sprintf("f could not be serialized length %d", len(p.CLnG), len(p.f.vector)))
|
|
}
|
|
*/
|
|
|
|
// fmt.Printf("writing %d fvector points\n", len(p.f.vector));
|
|
for i := 0; i < len(p.f.vector); i++ {
|
|
w.Write(ConvertBigIntToByte(p.f.vector[i]))
|
|
}
|
|
|
|
w.Write(ConvertBigIntToByte(p.z_A))
|
|
|
|
w.Write(p.T_1.EncodeCompressed())
|
|
w.Write(p.T_2.EncodeCompressed())
|
|
|
|
w.Write(ConvertBigIntToByte(p.that))
|
|
w.Write(ConvertBigIntToByte(p.mu))
|
|
|
|
w.Write(ConvertBigIntToByte(p.c))
|
|
w.Write(ConvertBigIntToByte(p.s_sk))
|
|
w.Write(ConvertBigIntToByte(p.s_r))
|
|
w.Write(ConvertBigIntToByte(p.s_b))
|
|
w.Write(ConvertBigIntToByte(p.s_tau))
|
|
|
|
p.ip.Serialize(w)
|
|
|
|
}
|
|
|
|
func (proof *Proof) Deserialize(r *bytes.Reader, length int) error {
|
|
|
|
var buf [32]byte
|
|
var bufp [33]byte
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.BA = &p
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.BS = &p
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.A = &p
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.B = &p
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
proof.CLnG = proof.CLnG[:0]
|
|
proof.CRnG = proof.CRnG[:0]
|
|
proof.C_0G = proof.C_0G[:0]
|
|
proof.DG = proof.DG[:0]
|
|
proof.y_0G = proof.y_0G[:0]
|
|
proof.gG = proof.gG[:0]
|
|
proof.C_XG = proof.C_XG[:0]
|
|
proof.y_XG = proof.y_XG[:0]
|
|
|
|
for i := 0; i < length; i++ {
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.CLnG = append(proof.CLnG, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
//fmt.Printf("CRnG point bytes2 %x\n", bufp[:])
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
//fmt.Printf("CRng point bytes1 %x\n", bufp[:])
|
|
return err
|
|
}
|
|
proof.CRnG = append(proof.CRnG, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.C_0G = append(proof.C_0G, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.DG = append(proof.DG, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.y_0G = append(proof.y_0G, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.gG = append(proof.gG, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.C_XG = append(proof.C_XG, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.y_XG = append(proof.y_XG, &p)
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.u = &p
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
proof.f = &FieldVector{}
|
|
|
|
//fmt.Printf("flen %d\n", flen )
|
|
for j := 0; j < length*2; j++ {
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.f.vector = append(proof.f.vector, new(big.Int).SetBytes(buf[:]))
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
}
|
|
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.z_A = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.T_1 = &p
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(bufp[:]); n == 33 && err == nil {
|
|
var p bn256.G1
|
|
if err = p.DecodeCompressed(bufp[:]); err != nil {
|
|
return err
|
|
}
|
|
proof.T_2 = &p
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.that = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.mu = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.c = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.s_sk = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.s_r = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.s_b = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
if n, err := r.Read(buf[:]); n == 32 && err == nil {
|
|
proof.s_tau = new(big.Int).SetBytes(buf[:])
|
|
} else {
|
|
return err
|
|
}
|
|
proof.ip = &InnerProduct{}
|
|
|
|
return proof.ip.Deserialize(r)
|
|
|
|
}
|
|
|
|
/*
|
|
// statement hash
|
|
func (s *Statement) Hash() *big.Int {
|
|
var input []byte
|
|
for i := range s.CLn {
|
|
input = append(input, s.CLn[i].Marshal()...)
|
|
}
|
|
for i := range s.CRn {
|
|
input = append(input, s.CRn[i].Marshal()...)
|
|
}
|
|
for i := range s.C {
|
|
input = append(input, s.C[i].Marshal()...)
|
|
}
|
|
input = append(input, s.D.Marshal()...)
|
|
for i := range s.Publickeylist {
|
|
input = append(input, s.Publickeylist[i].Marshal()...)
|
|
}
|
|
input = append(input, s.Roothash[:]...)
|
|
|
|
return reducedhash(input)
|
|
}
|
|
*/
|
|
|
|
func (p *Proof) Size() int {
|
|
size := 4*POINT_SIZE + (len(p.CLnG)+len(p.CRnG)+len(p.C_0G)+len(p.DG)+len(p.y_0G)+len(p.gG)+len(p.C_XG)+len(p.y_XG))*POINT_SIZE
|
|
size += POINT_SIZE
|
|
size += len(p.f.vector) * FIELDELEMENT_SIZE
|
|
size += FIELDELEMENT_SIZE
|
|
size += 2 * POINT_SIZE // T_1 ,T_2
|
|
size += 7 * FIELDELEMENT_SIZE
|
|
size += p.ip.Size()
|
|
return size
|
|
}
|
|
|
|
func (proof *Proof) hashmash1(v *big.Int) *big.Int {
|
|
var input []byte
|
|
input = append(input, ConvertBigIntToByte(v)...)
|
|
for i := range proof.CLnG {
|
|
input = append(input, proof.CLnG[i].Marshal()...)
|
|
}
|
|
for i := range proof.CRnG {
|
|
input = append(input, proof.CRnG[i].Marshal()...)
|
|
}
|
|
for i := range proof.C_0G {
|
|
input = append(input, proof.C_0G[i].Marshal()...)
|
|
}
|
|
for i := range proof.DG {
|
|
input = append(input, proof.DG[i].Marshal()...)
|
|
}
|
|
for i := range proof.y_0G {
|
|
input = append(input, proof.y_0G[i].Marshal()...)
|
|
}
|
|
for i := range proof.gG {
|
|
input = append(input, proof.gG[i].Marshal()...)
|
|
}
|
|
for i := range proof.C_XG {
|
|
input = append(input, proof.C_XG[i].Marshal()...)
|
|
}
|
|
for i := range proof.y_XG {
|
|
input = append(input, proof.y_XG[i].Marshal()...)
|
|
}
|
|
return reducedhash(input)
|
|
}
|
|
|
|
// function, which takes a string as
|
|
// argument and return the reverse of string.
|
|
func reverse(s string) string {
|
|
rns := []rune(s) // convert to rune
|
|
for i, j := 0, len(rns)-1; i < j; i, j = i+1, j-1 {
|
|
|
|
// swap the letters of the string,
|
|
// like first with last and so on.
|
|
rns[i], rns[j] = rns[j], rns[i]
|
|
}
|
|
|
|
// return the reversed string.
|
|
return string(rns)
|
|
}
|
|
|
|
var params = NewGeneratorParams(128) // these can be pregenerated similarly as in DERO project
|
|
|
|
func GenerateProof(s *Statement, witness *Witness, u *bn256.G1, txid Hash, burn_value uint64) *Proof {
|
|
|
|
var proof Proof
|
|
proof.u = u
|
|
|
|
statementhash := reducedhash(txid[:])
|
|
|
|
// statement should be constructed from these, however these are being simplified
|
|
var C []*ElGamal
|
|
var Cn ElGamalVector
|
|
for i := range s.C {
|
|
C = append(C, ConstructElGamal(s.C[i], s.D))
|
|
Cn.vector = append(Cn.vector, ConstructElGamal(s.CLn[i], s.CRn[i]))
|
|
}
|
|
|
|
btransfer := new(big.Int).SetInt64(int64(witness.TransferAmount)) // this should be reduced
|
|
bdiff := new(big.Int).SetInt64(int64(witness.Balance)) // this should be reduced
|
|
|
|
number := btransfer.Add(btransfer, bdiff.Lsh(bdiff, 64)) // we are placing balance and left over balance, and doing a range proof of 128 bits
|
|
|
|
number_string := reverse("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + number.Text(2))
|
|
number_string_left_128bits := string(number_string[0:128])
|
|
|
|
var aL, aR FieldVector // convert the amount to make sure it cannot be negative
|
|
|
|
//klog.V(2).Infof("reverse %s\n", number_string_left_128bits)
|
|
for _, b := range []byte(number_string_left_128bits) {
|
|
if b == '1' {
|
|
aL.vector = append(aL.vector, new(big.Int).SetInt64(1))
|
|
aR.vector = append(aR.vector, new(big.Int).SetInt64(0))
|
|
} else {
|
|
aL.vector = append(aL.vector, new(big.Int).SetInt64(0))
|
|
aR.vector = append(aR.vector, new(big.Int).Mod(new(big.Int).SetInt64(-1), bn256.Order))
|
|
}
|
|
}
|
|
|
|
//klog.V(2).Infof("aRa %+v\n", aRa)
|
|
|
|
proof_BA_internal := NewPedersenVectorCommitment().Commit(&aL, &aR)
|
|
proof.BA = proof_BA_internal.Result
|
|
|
|
sL := NewFieldVectorRandomFilled(len(aL.vector))
|
|
sR := NewFieldVectorRandomFilled(len(aL.vector))
|
|
proof_BS_internal := NewPedersenVectorCommitment().Commit(sL, sR)
|
|
proof.BS = proof_BS_internal.Result
|
|
|
|
//klog.V(2).Infof("Proof BA %s\n", proof.BA.String())
|
|
//klog.V(2).Infof("Proof BS %s\n", proof.BS.String())
|
|
|
|
if len(s.Publickeylist) >= 1 && len(s.Publickeylist)&(len(s.Publickeylist)-1) != 0 {
|
|
fmt.Printf("len of Publickeylist %d\n", len(s.Publickeylist))
|
|
panic("we need power of 2")
|
|
}
|
|
|
|
N := len(s.Publickeylist)
|
|
m := int(math.Log2(float64(N)))
|
|
|
|
if math.Pow(2, float64(m)) != float64(N) {
|
|
panic("log failed")
|
|
}
|
|
|
|
var aa, ba, bspecial []*big.Int
|
|
for i := 0; i < 2*m; i++ {
|
|
aa = append(aa, RandomScalarFixed())
|
|
}
|
|
|
|
witness_index := reverse(fmt.Sprintf("%0"+fmt.Sprintf("%db", m)+"%0"+fmt.Sprintf("%db", m), witness.Index[1], witness.Index[0]))
|
|
|
|
for _, b := range []byte(witness_index) {
|
|
if b == '1' {
|
|
ba = append(ba, new(big.Int).SetUint64(1))
|
|
bspecial = append(bspecial, new(big.Int).Mod(new(big.Int).SetInt64(-1), bn256.Order))
|
|
} else {
|
|
ba = append(ba, new(big.Int).SetUint64(0))
|
|
bspecial = append(bspecial, new(big.Int).Mod(new(big.Int).SetInt64(1), bn256.Order))
|
|
}
|
|
}
|
|
|
|
a := NewFieldVector(aa)
|
|
b := NewFieldVector(ba)
|
|
|
|
// klog.V(1).Infof("witness_index of sender/receiver %s\n", witness_index)
|
|
|
|
c := a.Hadamard(NewFieldVector(bspecial))
|
|
d := a.Hadamard(a).Negate()
|
|
|
|
// klog.V(2).Infof("d %s\n", d.vector[0].Text(16))
|
|
|
|
e := NewFieldVector([]*big.Int{new(big.Int).Mod(new(big.Int).Mul(a.vector[0], a.vector[m]), bn256.Order),
|
|
new(big.Int).Mod(new(big.Int).Mul(a.vector[0], a.vector[m]), bn256.Order)})
|
|
|
|
second := new(big.Int).Set(a.vector[b.vector[m].Uint64()*uint64(m)])
|
|
second.Neg(second)
|
|
|
|
f := NewFieldVector([]*big.Int{a.vector[b.vector[0].Uint64()*uint64(m)], new(big.Int).Mod(second, bn256.Order)})
|
|
|
|
// for i := range f.vector {
|
|
// klog.V(2).Infof("f %d %s\n", i, f.vector[i].Text(16))
|
|
// }
|
|
|
|
proof_A_internal := NewPedersenVectorCommitment().Commit(a, d.Concat(e))
|
|
proof.A = proof_A_internal.Result
|
|
proof_B_internal := NewPedersenVectorCommitment().Commit(b, c.Concat(f))
|
|
proof.B = proof_B_internal.Result
|
|
|
|
// klog.V(2).Infof("Proof A %s\n", proof.A.String())
|
|
// klog.V(2).Infof("Proof B %s\n", proof.B.String())
|
|
|
|
var v *big.Int
|
|
|
|
{ // hash mash
|
|
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()...)
|
|
v = reducedhash(input)
|
|
}
|
|
|
|
var P, Q, Pi, Qi [][]*big.Int
|
|
Pi = RecursivePolynomials(Pi, NewPolynomial(nil), a.SliceRaw(0, m), b.SliceRaw(0, m))
|
|
Qi = RecursivePolynomials(Qi, NewPolynomial(nil), a.SliceRaw(m, 2*m), b.SliceRaw(m, 2*m))
|
|
|
|
// transpose the matrices
|
|
for i := 0; i < m; i++ {
|
|
P = append(P, []*big.Int{})
|
|
Q = append(Q, []*big.Int{})
|
|
for j := range Pi {
|
|
P[i] = append(P[i], Pi[j][i])
|
|
Q[i] = append(Q[i], Qi[j][i])
|
|
}
|
|
}
|
|
|
|
// for i := range P {
|
|
// for j := range P[i] {
|
|
// klog.V(2).Infof("P%d,%d %s\n", i, j, P[i][j].Text(16))
|
|
// }
|
|
// }
|
|
|
|
//phi := NewFieldVectorRandomFilled(m)
|
|
//chi := NewFieldVectorRandomFilled(m)
|
|
//psi := NewFieldVectorRandomFilled(m)
|
|
|
|
var phi, chi, psi ElGamalVector
|
|
for i := 0; i < m; i++ {
|
|
phi.vector = append(phi.vector, CommitElGamal(s.Publickeylist[witness.Index[0]], new(big.Int).SetUint64(0)))
|
|
chi.vector = append(chi.vector, CommitElGamal(s.Publickeylist[witness.Index[0]], new(big.Int).SetUint64(0)))
|
|
psi.vector = append(psi.vector, CommitElGamal(s.Publickeylist[witness.Index[0]], new(big.Int).SetUint64(0)))
|
|
}
|
|
|
|
var CnG, C_0G, y_0G ElGamalVector
|
|
for i := 0; i < m; i++ {
|
|
|
|
CnG.vector = append(CnG.vector, Cn.MultiExponentiate(NewFieldVector(P[i])).Add(phi.vector[i]))
|
|
|
|
{
|
|
var pvector PointVector
|
|
for j := range C {
|
|
pvector.vector = append(pvector.vector, C[j].Left)
|
|
}
|
|
left := pvector.MultiExponentiate(NewFieldVector(P[i])) //.Add(chi.vector[i].Left)
|
|
left = new(bn256.G1).Add(new(bn256.G1).Set(left), chi.vector[i].Left)
|
|
C_0G.vector = append(C_0G.vector, ConstructElGamal(left, chi.vector[i].Right))
|
|
}
|
|
|
|
{
|
|
|
|
left := NewPointVector(s.Publickeylist).MultiExponentiate(NewFieldVector(P[i]))
|
|
left = new(bn256.G1).Add(new(bn256.G1).Set(left), psi.vector[i].Left)
|
|
y_0G.vector = append(y_0G.vector, ConstructElGamal(left, psi.vector[i].Right))
|
|
}
|
|
|
|
/*
|
|
{ // y_0G
|
|
var rightp, result bn256.G1
|
|
leftp := NewPointVector(s.Publickeylist).Commit(P[i])
|
|
rightp.ScalarMult(s.Publickeylist[witness.Index[0]], psi.vector[i])
|
|
result.Add(leftp, &rightp)
|
|
proof.y_0G = append(proof.y_0G, &result)
|
|
//klog.V(2).Infof("y_0G %d %s\n",i, result.String())
|
|
}
|
|
|
|
{ // gG
|
|
var result bn256.G1
|
|
result.ScalarMult(params.G, psi.vector[i])
|
|
proof.gG = append(proof.gG, &result)
|
|
//klog.V(2).Infof("gG %d %s\n",i, result.String())
|
|
}
|
|
*/
|
|
|
|
/*
|
|
{ // C_XG
|
|
var result bn256.G1
|
|
result.ScalarMult(s.D, omega.vector[i])
|
|
proof.C_XG = append(proof.C_XG, &result)
|
|
//klog.V(2).Infof("C_XG %d %s\n",i, result.String())
|
|
}
|
|
|
|
{ // y_XG
|
|
var result bn256.G1
|
|
result.ScalarMult(params.G, omega.vector[i])
|
|
proof.y_XG = append(proof.y_XG, &result)
|
|
klog.V(2).Infof("y_XG %d %s\n", i, result.String())
|
|
}
|
|
*/
|
|
|
|
}
|
|
|
|
/*
|
|
for i := range proof.CLnG {
|
|
klog.V(2).Infof("CLnG %d %s\n", i, proof.CLnG[i].String())
|
|
}
|
|
for i := range proof.CRnG {
|
|
klog.V(2).Infof("CRnG %d %s\n", i, proof.CRnG[i].String())
|
|
}
|
|
for i := range proof.C_0G {
|
|
klog.V(2).Infof("C_0G %d %s\n", i, proof.C_0G[i].String())
|
|
}
|
|
for i := range proof.DG {
|
|
klog.V(2).Infof("DG %d %s\n", i, proof.DG[i].String())
|
|
}
|
|
for i := range proof.y_0G {
|
|
klog.V(2).Infof("y_0G %d %s\n", i, proof.y_0G[i].String())
|
|
}
|
|
for i := range proof.gG {
|
|
klog.V(2).Infof("gG %d %s\n", i, proof.gG[i].String())
|
|
}
|
|
for i := range proof.C_XG {
|
|
klog.V(2).Infof("C_XG %d %s\n", i, proof.C_XG[i].String())
|
|
}
|
|
for i := range proof.y_XG {
|
|
klog.V(2).Infof("y_XG %d %s\n", i, proof.y_XG[i].String())
|
|
}
|
|
*/
|
|
var C_XG []*ElGamal
|
|
for i := 0; i < m; i++ {
|
|
C_XG = append(C_XG, CommitElGamal(C[0].Right, new(big.Int).SetUint64(0)))
|
|
}
|
|
|
|
vPow := new(big.Int).SetInt64(1) // doesn't need reduction, since it' alredy reduced
|
|
|
|
for i := 0; i < N; i++ {
|
|
|
|
var poly [][]*big.Int
|
|
if i%2 == 0 {
|
|
poly = P
|
|
} else {
|
|
poly = Q
|
|
}
|
|
|
|
// klog.V(2).Infof("\n\n")
|
|
// for i := range proof.C_XG {
|
|
// klog.V(2).Infof("C_XG before %d %s\n", i, proof.C_XG[i].String())
|
|
// }
|
|
|
|
// klog.V(2).Infof("loop %d pos in poly sender %d receiver %d\n", i, (witness.Index[0]+N-(i-i%2))%N, (witness.Index[1]+N-(i-i%2))%N)
|
|
|
|
for j := range C_XG {
|
|
|
|
amount := new(big.Int).SetUint64(uint64(witness.TransferAmount))
|
|
amount_neg := new(big.Int).Neg(amount)
|
|
amount_fees := new(big.Int).SetUint64(s.Fees + burn_value)
|
|
left := new(big.Int).Sub(amount_neg, amount_fees)
|
|
left = new(big.Int).Mod(new(big.Int).Mul(new(big.Int).Set(left), poly[j][(witness.Index[0]+N-(i-i%2))%N]), bn256.Order)
|
|
|
|
right := new(big.Int).Mod(new(big.Int).Mul(new(big.Int).Set(amount), poly[j][(witness.Index[1]+N-(i-i%2))%N]), bn256.Order)
|
|
|
|
joined := new(big.Int).Mod(new(big.Int).Add(left, right), bn256.Order)
|
|
|
|
mul := new(big.Int).Mod(new(big.Int).Mul(vPow, joined), bn256.Order)
|
|
|
|
C_XG[j] = C_XG[j].Plus(mul)
|
|
}
|
|
|
|
if i != 0 {
|
|
vPow.Mul(vPow, v)
|
|
vPow.Mod(vPow, bn256.Order)
|
|
}
|
|
|
|
//klog.V(2).Infof("vPow %d %s\n", i, vPow.Text(16)))
|
|
|
|
}
|
|
|
|
for i := range C_XG {
|
|
proof.C_XG = append(proof.C_XG, C_XG[i].Left)
|
|
proof.y_XG = append(proof.y_XG, C_XG[i].Right)
|
|
|
|
proof.CLnG = append(proof.CLnG, CnG.vector[i].Left)
|
|
proof.CRnG = append(proof.CRnG, CnG.vector[i].Right)
|
|
|
|
proof.C_0G = append(proof.C_0G, C_0G.vector[i].Left)
|
|
proof.DG = append(proof.DG, C_0G.vector[i].Right)
|
|
|
|
proof.y_0G = append(proof.y_0G, y_0G.vector[i].Left)
|
|
proof.gG = append(proof.gG, y_0G.vector[i].Right)
|
|
}
|
|
|
|
//klog.V(2).Infof("\n\n")
|
|
// for i := range proof.C_XG {
|
|
// klog.V(2).Infof("C_XG after %d %s\n", i, proof.C_XG[i].String())
|
|
// }
|
|
|
|
// calculate w hashmash
|
|
|
|
w := proof.hashmash1(v)
|
|
|
|
{
|
|
var input []byte
|
|
|
|
input = append(input, ConvertBigIntToByte(v)...)
|
|
for i := range proof.CLnG {
|
|
input = append(input, proof.CLnG[i].Marshal()...)
|
|
}
|
|
for i := range proof.CRnG {
|
|
input = append(input, proof.CRnG[i].Marshal()...)
|
|
}
|
|
|
|
for i := range proof.C_0G {
|
|
input = append(input, proof.C_0G[i].Marshal()...)
|
|
}
|
|
for i := range proof.DG {
|
|
input = append(input, proof.DG[i].Marshal()...)
|
|
}
|
|
for i := range proof.y_0G {
|
|
input = append(input, proof.y_0G[i].Marshal()...)
|
|
}
|
|
for i := range proof.gG {
|
|
input = append(input, proof.gG[i].Marshal()...)
|
|
}
|
|
for i := range C_XG {
|
|
input = append(input, C_XG[i].Left.Marshal()...)
|
|
}
|
|
for i := range proof.y_XG {
|
|
input = append(input, C_XG[i].Right.Marshal()...)
|
|
}
|
|
//fmt.Printf("whash %s %s\n", reducedhash(input).Text(16), w.Text(16))
|
|
|
|
}
|
|
|
|
proof.f = b.Times(w).Add(a)
|
|
|
|
// for i := range proof.f.vector {
|
|
// klog.V(2).Infof("proof.f %d %s\n", i, proof.f.vector[i].Text(16))
|
|
// }
|
|
|
|
ttttt := new(big.Int).Mod(new(big.Int).Mul(proof_B_internal.Randomness, w), bn256.Order)
|
|
proof.z_A = new(big.Int).Mod(new(big.Int).Add(ttttt, proof_A_internal.Randomness), bn256.Order)
|
|
|
|
// klog.V(2).Infof("proofz_A %s\n", proof.z_A.Text(16))
|
|
|
|
y := reducedhash(ConvertBigIntToByte(w))
|
|
|
|
// klog.V(2).Infof("yyyyyyyyyy %s\n", y.Text(16))
|
|
|
|
ys_raw := []*big.Int{new(big.Int).SetUint64(1)}
|
|
for i := 1; i < 128; i++ {
|
|
var tt big.Int
|
|
tt.Mul(ys_raw[len(ys_raw)-1], y)
|
|
tt.Mod(&tt, bn256.Order)
|
|
ys_raw = append(ys_raw, &tt)
|
|
}
|
|
ys := NewFieldVector(ys_raw)
|
|
|
|
z := reducedhash(ConvertBigIntToByte(y))
|
|
// klog.V(2).Infof("zzzzzzzzzz %s \n", z.Text(16))
|
|
|
|
zs := []*big.Int{new(big.Int).Exp(z, new(big.Int).SetUint64(2), bn256.Order), new(big.Int).Exp(z, new(big.Int).SetUint64(3), bn256.Order)}
|
|
// for i := range zs {
|
|
// klog.V(2).Infof("zs %d %s\n", i, zs[i].Text(16))
|
|
// }
|
|
|
|
twos := []*big.Int{new(big.Int).SetUint64(1)}
|
|
for i := 1; i < 64; i++ {
|
|
var tt big.Int
|
|
tt.Mul(twos[len(twos)-1], new(big.Int).SetUint64(2))
|
|
tt.Mod(&tt, bn256.Order)
|
|
twos = append(twos, &tt)
|
|
}
|
|
|
|
twoTimesZs := []*big.Int{}
|
|
for i := 0; i < 2; i++ {
|
|
for j := 0; j < 64; j++ {
|
|
var tt big.Int
|
|
tt.Mul(zs[i], twos[j])
|
|
tt.Mod(&tt, bn256.Order)
|
|
twoTimesZs = append(twoTimesZs, &tt)
|
|
|
|
// klog.V(2).Infof("twoTimesZssss ============= %d %s\n", i*32+j, twoTimesZs[i*32+j].Text(16))
|
|
|
|
}
|
|
}
|
|
|
|
tmp := aL.AddConstant(new(big.Int).Mod(new(big.Int).Neg(z), bn256.Order))
|
|
lPoly := NewFieldVectorPolynomial(tmp, sL)
|
|
//for i := range lPoly.coefficients {
|
|
// for j := range lPoly.coefficients[i].vector {
|
|
// klog.V(2).Infof("lPoly %d,%d %s\n", i, j, lPoly.coefficients[i].vector[j].Text(16))
|
|
// }
|
|
//}
|
|
|
|
rPoly := NewFieldVectorPolynomial(ys.Hadamard(aR.AddConstant(z)).Add(NewFieldVector(twoTimesZs)), sR.Hadamard(ys))
|
|
//for i := range rPoly.coefficients {
|
|
// for j := range rPoly.coefficients[i].vector {
|
|
// klog.V(2).Infof("rPoly %d,%d %s\n", i, j, rPoly.coefficients[i].vector[j].Text(16))
|
|
// }
|
|
//}
|
|
|
|
tPolyCoefficients := lPoly.InnerProduct(rPoly) // just an array of BN Reds... should be length 3
|
|
//for j := range tPolyCoefficients {
|
|
// klog.V(2).Infof("tPolyCoefficients %d,%d %s\n", 0, j, tPolyCoefficients[j].Text(16))
|
|
//}
|
|
|
|
proof_T1 := NewPedersenCommitmentNew().Commit(tPolyCoefficients[1])
|
|
proof_T2 := NewPedersenCommitmentNew().Commit(tPolyCoefficients[2])
|
|
proof.T_1 = proof_T1.Result
|
|
proof.T_2 = proof_T2.Result
|
|
|
|
//polyCommitment := NewPolyCommitment(params, tPolyCoefficients)
|
|
/*proof.tCommits = NewPointVector(polyCommitment.GetCommitments())
|
|
|
|
for j := range proof.tCommits.vector {
|
|
klog.V(2).Infof("tCommits %d %s\n", j, proof.tCommits.vector[j].String())
|
|
}
|
|
*/
|
|
|
|
x := new(big.Int)
|
|
|
|
{
|
|
var input []byte
|
|
input = append(input, ConvertBigIntToByte(z)...) // tie intermediates/commit
|
|
//for j := range proof.tCommits.vector {
|
|
// input = append(input, proof.tCommits.vector[j].Marshal()...)
|
|
//}
|
|
input = append(input, proof_T1.Result.Marshal()...)
|
|
input = append(input, proof_T2.Result.Marshal()...)
|
|
x = reducedhash(input)
|
|
}
|
|
|
|
//klog.V(2).Infof("x %s\n", x.Text(16))
|
|
|
|
//evalCommit := polyCommitment.Evaluate(x)
|
|
|
|
//klog.V(2).Infof("evalCommit.X %s\n", j, evalCommit.X.Text(16))
|
|
//klog.V(2).Infof("evalCommit.R %s\n", j, evalCommit.R.Text(16))
|
|
|
|
//proof.that = evalCommit.X
|
|
|
|
xsquare := new(big.Int).Mod(new(big.Int).Mul(x, x), bn256.Order)
|
|
|
|
proof.that = tPolyCoefficients[0]
|
|
proof.that = new(big.Int).Mod(new(big.Int).Add(proof.that, new(big.Int).Mod(new(big.Int).Mul(tPolyCoefficients[1], x), bn256.Order)), bn256.Order)
|
|
proof.that = new(big.Int).Mod(new(big.Int).Add(proof.that, new(big.Int).Mod(new(big.Int).Mul(tPolyCoefficients[2], xsquare), bn256.Order)), bn256.Order)
|
|
|
|
/*
|
|
accumulator := new(big.Int).Set(x)
|
|
for i := 1; i < 3; i++ {
|
|
tmp := new(big.Int).Set(accumulator)
|
|
proof.that = proof.that.Add(new(bn256.G1).Set(proof.that), tPolyCoefficients[i].Times(accumulator))
|
|
accumulator.Mod(new(big.Int).Mul(tmp, x), bn256.Order)
|
|
}
|
|
*/
|
|
|
|
//klog.V(2).Infof("evalCommit.that %s\n", proof.that.Text(16))
|
|
|
|
//tauX := evalCommit.R
|
|
tauX_left := new(big.Int).Mod(new(big.Int).Mul(proof_T1.Randomness, x), bn256.Order)
|
|
tauX_right := new(big.Int).Mod(new(big.Int).Mul(proof_T2.Randomness, xsquare), bn256.Order)
|
|
tauX := new(big.Int).Mod(new(big.Int).Add(tauX_left, tauX_right), bn256.Order)
|
|
|
|
proof.mu = new(big.Int).Mod(new(big.Int).Mul(proof_BS_internal.Randomness, x), bn256.Order)
|
|
proof.mu.Add(proof.mu, proof_BA_internal.Randomness)
|
|
proof.mu.Mod(proof.mu, bn256.Order)
|
|
|
|
//klog.V(2).Infof("proof.mu %s\n", proof.mu.Text(16))
|
|
|
|
var CrnR, y_0R, y_XR bn256.G1
|
|
// var gR bn256.G1
|
|
CrnR.ScalarMult(params.G, new(big.Int))
|
|
y_0R.ScalarMult(params.G, new(big.Int))
|
|
y_XR.ScalarMult(params.G, new(big.Int))
|
|
//DR.ScalarMult(params.G, new(big.Int))
|
|
//gR.ScalarMult(params.G, new(big.Int))
|
|
|
|
CnR := ConstructElGamal(nil, ElGamal_ZERO) // only right side is needer
|
|
chi_bigint := new(big.Int).SetUint64(0)
|
|
psi_bigint := new(big.Int).SetUint64(0)
|
|
C_XR := ConstructElGamal(nil, ElGamal_ZERO) // only right side is needer
|
|
|
|
var p_, q_ []*big.Int
|
|
for i := 0; i < N; i++ {
|
|
p_ = append(p_, new(big.Int))
|
|
q_ = append(q_, new(big.Int))
|
|
}
|
|
p := NewFieldVector(p_)
|
|
q := NewFieldVector(q_)
|
|
|
|
wPow := new(big.Int).SetUint64(1) // already reduced
|
|
|
|
for i := 0; i < m; i++ {
|
|
|
|
{
|
|
CnR = CnR.Add(phi.vector[i].Neg().Mul(wPow))
|
|
}
|
|
|
|
{
|
|
mm := new(big.Int).Mod(new(big.Int).Mul(chi.vector[i].Randomness, wPow), bn256.Order)
|
|
chi_bigint = new(big.Int).Mod(new(big.Int).Add(chi_bigint, mm), bn256.Order)
|
|
}
|
|
|
|
{
|
|
mm := new(big.Int).Mod(new(big.Int).Mul(psi.vector[i].Randomness, wPow), bn256.Order)
|
|
psi_bigint = new(big.Int).Mod(new(big.Int).Add(psi_bigint, mm), bn256.Order)
|
|
}
|
|
|
|
/* {
|
|
tmp := new(bn256.G1)
|
|
mm := new(big.Int).Mod(new(big.Int).Neg(chi.vector[i]), bn256.Order)
|
|
mm = mm.Mod(new(big.Int).Mul(mm, wPow), bn256.Order)
|
|
tmp.ScalarMult(params.G, mm)
|
|
DR.Add(new(bn256.G1).Set(&DR), tmp)
|
|
}
|
|
|
|
{
|
|
tmp := new(bn256.G1)
|
|
mm := new(big.Int).Mod(new(big.Int).Neg(psi.vector[i]), bn256.Order)
|
|
mm = mm.Mod(new(big.Int).Mul(mm, wPow), bn256.Order)
|
|
tmp.ScalarMult(s.Publickeylist[witness.Index[0]], mm)
|
|
y_0R.Add(new(bn256.G1).Set(&y_0R), tmp)
|
|
}
|
|
*/
|
|
/*
|
|
{
|
|
tmp := new(bn256.G1)
|
|
mm := new(big.Int).Mod(new(big.Int).Neg(psi.vector[i]), bn256.Order)
|
|
mm = mm.Mod(new(big.Int).Mul(mm, wPow), bn256.Order)
|
|
tmp.ScalarMult(params.G, mm)
|
|
gR.Add(new(bn256.G1).Set(&gR), tmp)
|
|
}
|
|
|
|
{
|
|
tmp := new(bn256.G1)
|
|
tmp.ScalarMult(proof.y_XG[i], new(big.Int).Neg(wPow))
|
|
y_XR.Add(new(bn256.G1).Set(&y_XR), tmp)
|
|
}
|
|
*/
|
|
|
|
{
|
|
C_XR = C_XR.Add(C_XG[i].Neg().Mul(wPow))
|
|
}
|
|
|
|
//fmt.Printf("y_XG[%d] %s\n",i, proof.y_XG[i].String())
|
|
//fmt.Printf("C_XG[%d] %s\n",i, C_XG[i].Right.String())
|
|
|
|
//fmt.Printf("G %s\n",G.String())
|
|
//fmt.Printf("elgamalG %s\n",C_XG[0].G.String())
|
|
|
|
p = p.Add(NewFieldVector(P[i]).Times(wPow))
|
|
q = q.Add(NewFieldVector(Q[i]).Times(wPow))
|
|
wPow = new(big.Int).Mod(new(big.Int).Mul(wPow, w), bn256.Order)
|
|
|
|
// klog.V(2).Infof("wPow %s\n", wPow.Text(16))
|
|
|
|
}
|
|
|
|
CnR = CnR.Add(Cn.vector[witness.Index[0]].Mul(wPow))
|
|
|
|
//for i := range CnR{
|
|
// proof.CLnG = append(proof.CLnG, CnR[i].Left)
|
|
// proof.CRnG = append(proof.CRnG, CnR[i].Right)
|
|
//}
|
|
|
|
//CrnR.Add(new(bn256.G1).Set(&CrnR), new(bn256.G1).ScalarMult(s.CRn[witness.Index[0]], wPow))
|
|
//y_0R.Add(new(bn256.G1).Set(&y_0R), new(bn256.G1).ScalarMult(s.Publickeylist[witness.Index[0]], wPow))
|
|
//DR.Add(new(bn256.G1).Set(&DR), new(bn256.G1).ScalarMult(s.D, wPow))
|
|
|
|
DR := new(bn256.G1).ScalarMult(C[0].Right, wPow)
|
|
DR = new(bn256.G1).Add(new(bn256.G1).Set(DR), new(bn256.G1).ScalarMult(global_pedersen_values.G, new(big.Int).Mod(new(big.Int).Neg(chi_bigint), bn256.Order)))
|
|
|
|
gR := new(bn256.G1).ScalarMult(global_pedersen_values.G, new(big.Int).Mod(new(big.Int).Sub(wPow, psi_bigint), bn256.Order))
|
|
|
|
//gR.Add(new(bn256.G1).Set(&gR), new(bn256.G1).ScalarMult(params.G, wPow))
|
|
|
|
var p__, q__ []*big.Int
|
|
for i := 0; i < N; i++ {
|
|
|
|
if i == witness.Index[0] {
|
|
p__ = append(p__, new(big.Int).Set(wPow))
|
|
} else {
|
|
p__ = append(p__, new(big.Int))
|
|
}
|
|
|
|
if i == witness.Index[1] {
|
|
q__ = append(q__, new(big.Int).Set(wPow))
|
|
} else {
|
|
q__ = append(q__, new(big.Int))
|
|
}
|
|
}
|
|
p = p.Add(NewFieldVector(p__))
|
|
q = q.Add(NewFieldVector(q__))
|
|
|
|
// klog.V(2).Infof("CrnR %s\n", CrnR.String())
|
|
// klog.V(2).Infof("DR %s\n", DR.String())
|
|
// klog.V(2).Infof("y_0R %s\n", y_0R.String())
|
|
// klog.V(2).Infof("gR %s\n", gR.String())
|
|
// klog.V(2).Infof("y_XR %s\n", y_XR.String())
|
|
|
|
// for i := range p.vector {
|
|
// klog.V(2).Infof("p %d %s \n", i, p.vector[i].Text(16))
|
|
// }
|
|
|
|
// for i := range q.vector {
|
|
// klog.V(2).Infof("q %d %s \n", i, q.vector[i].Text(16))
|
|
// }
|
|
|
|
y_p := Convolution(p, NewPointVector(s.Publickeylist))
|
|
y_q := Convolution(q, NewPointVector(s.Publickeylist))
|
|
|
|
// 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())
|
|
// }
|
|
|
|
vPow = new(big.Int).SetUint64(1) // already reduced
|
|
for i := 0; i < N; i++ {
|
|
|
|
ypoly := y_p
|
|
if i%2 == 1 {
|
|
ypoly = y_q
|
|
}
|
|
y_XR.Add(new(bn256.G1).Set(&y_XR), new(bn256.G1).ScalarMult(ypoly.vector[i/2], vPow))
|
|
|
|
C_XR = C_XR.Add(ConstructElGamal(nil, new(bn256.G1).ScalarMult(ypoly.vector[i/2], vPow)))
|
|
|
|
//fmt.Printf("y_XR[%d] %s\n",i, y_XR.String())
|
|
//fmt.Printf("C_XR[%d] %s\n",i, C_XR.Right.String())
|
|
if i > 0 {
|
|
vPow = new(big.Int).Mod(new(big.Int).Mul(vPow, v), bn256.Order)
|
|
}
|
|
}
|
|
|
|
// klog.V(2).Infof("y_XR %s\n", y_XR.String())
|
|
// klog.V(2).Infof("vPow %s\n", vPow.Text(16))
|
|
// klog.V(2).Infof("v %s\n", v.Text(16))
|
|
|
|
k_sk := RandomScalarFixed()
|
|
k_r := RandomScalarFixed()
|
|
k_b := RandomScalarFixed()
|
|
k_tau := RandomScalarFixed()
|
|
|
|
A_y := new(bn256.G1).ScalarMult(gR, k_sk)
|
|
A_D := new(bn256.G1).ScalarMult(params.G, k_r)
|
|
A_b := new(bn256.G1).ScalarMult(params.G, k_b)
|
|
t1 := new(bn256.G1).ScalarMult(CnR.Right, zs[1])
|
|
d1 := new(bn256.G1).ScalarMult(DR, new(big.Int).Mod(new(big.Int).Neg(zs[0]), bn256.Order))
|
|
d1 = new(bn256.G1).Add(d1, t1)
|
|
d1 = new(bn256.G1).ScalarMult(d1, k_sk)
|
|
A_b = new(bn256.G1).Add(A_b, d1)
|
|
|
|
A_X := new(bn256.G1).ScalarMult(C_XR.Right, k_r)
|
|
|
|
A_t := new(bn256.G1).ScalarMult(params.G, new(big.Int).Mod(new(big.Int).Neg(k_b), bn256.Order))
|
|
A_t = new(bn256.G1).Add(A_t, new(bn256.G1).ScalarMult(params.H, k_tau))
|
|
|
|
A_u := new(bn256.G1)
|
|
|
|
{
|
|
var input []byte
|
|
input = append(input, []byte(PROTOCOL_CONSTANT)...)
|
|
input = append(input, s.Roothash[:]...)
|
|
|
|
point := HashToPoint(HashtoNumber(input))
|
|
|
|
A_u = new(bn256.G1).ScalarMult(point, k_sk)
|
|
}
|
|
|
|
// klog.V(2).Infof("A_y %s\n", A_y.String())
|
|
// klog.V(2).Infof("A_D %s\n", A_D.String())
|
|
// klog.V(2).Infof("A_b %s\n", A_b.String())
|
|
// klog.V(2).Infof("A_X %s\n", A_X.String())
|
|
// klog.V(2).Infof("A_t %s\n", A_t.String())
|
|
// klog.V(2).Infof("A_u %s\n", A_u.String())
|
|
|
|
{
|
|
var input []byte
|
|
input = append(input, ConvertBigIntToByte(x)...)
|
|
input = append(input, A_y.Marshal()...)
|
|
input = append(input, A_D.Marshal()...)
|
|
input = append(input, A_b.Marshal()...)
|
|
input = append(input, A_X.Marshal()...)
|
|
input = append(input, A_t.Marshal()...)
|
|
input = append(input, A_u.Marshal()...)
|
|
proof.c = reducedhash(input)
|
|
}
|
|
|
|
proof.s_sk = new(big.Int).Mod(new(big.Int).Mul(proof.c, witness.SecretKey), bn256.Order)
|
|
proof.s_sk = new(big.Int).Mod(new(big.Int).Add(proof.s_sk, k_sk), bn256.Order)
|
|
|
|
proof.s_r = new(big.Int).Mod(new(big.Int).Mul(proof.c, witness.R), bn256.Order)
|
|
proof.s_r = new(big.Int).Mod(new(big.Int).Add(proof.s_r, k_r), bn256.Order)
|
|
|
|
// proof_c_neg := new(big.Int).Mod(new(big.Int).Neg(proof.c), bn256.Order)
|
|
// dummyA_X := new(bn256.G1).ScalarMult(&y_XR, proof.s_r) //, new(bn256.G1).ScalarMult(anonsupport.C_XR, proof_c_neg) )
|
|
|
|
// klog.V(2).Infof("dummyA_X %s\n", dummyA_X.String())
|
|
// klog.V(2).Infof("s_r %s\n", proof.s_r.Text(16))
|
|
// klog.V(2).Infof("C %s\n", proof.c.Text(16))
|
|
// klog.V(2).Infof("C_neg %s\n", proof_c_neg.Text(16))
|
|
|
|
w_transfer := new(big.Int).Mod(new(big.Int).Mul(new(big.Int).SetUint64(uint64(witness.TransferAmount)), zs[0]), bn256.Order)
|
|
w_balance := new(big.Int).Mod(new(big.Int).Mul(new(big.Int).SetUint64(uint64(witness.Balance)), zs[1]), bn256.Order)
|
|
w_tmp := new(big.Int).Mod(new(big.Int).Add(w_transfer, w_balance), bn256.Order)
|
|
w_tmp = new(big.Int).Mod(new(big.Int).Mul(w_tmp, wPow), bn256.Order)
|
|
w_tmp = new(big.Int).Mod(new(big.Int).Mul(w_tmp, proof.c), bn256.Order)
|
|
proof.s_b = new(big.Int).Mod(new(big.Int).Add(w_tmp, k_b), bn256.Order)
|
|
|
|
proof.s_tau = new(big.Int).Mod(new(big.Int).Mul(tauX, wPow), bn256.Order)
|
|
proof.s_tau = new(big.Int).Mod(new(big.Int).Mul(proof.s_tau, proof.c), bn256.Order)
|
|
proof.s_tau = new(big.Int).Mod(new(big.Int).Add(proof.s_tau, k_tau), bn256.Order)
|
|
|
|
// klog.V(2).Infof("proof.c %s\n", proof.c.Text(16))
|
|
// klog.V(2).Infof("proof.s_sk %s\n", proof.s_sk.Text(16))
|
|
// klog.V(2).Infof("proof.s_r %s\n", proof.s_r.Text(16))
|
|
// klog.V(2).Infof("proof.s_b %s\n", proof.s_b.Text(16))
|
|
// klog.V(2).Infof("proof.s_tau %s\n", proof.s_tau.Text(16))
|
|
|
|
o := reducedhash(ConvertBigIntToByte(proof.c))
|
|
|
|
pvector := NewPedersenVectorCommitment()
|
|
pvector.H = new(bn256.G1).ScalarMult(pvector.H, o)
|
|
pvector.Hs = pvector.Hs.Hadamard(ys.Invert().vector)
|
|
pvector.gvalues = lPoly.Evaluate(x)
|
|
pvector.hvalues = rPoly.Evaluate(x)
|
|
proof.ip = NewInnerProductProofNew(pvector, o)
|
|
/*
|
|
|
|
u_x := new(bn256.G1).ScalarMult(params.G, o)
|
|
P1 = new(bn256.G1).Add(P1, new(bn256.G1).ScalarMult(u_x, proof.that))
|
|
klog.V(2).Infof("o %s\n", o.Text(16))
|
|
klog.V(2).Infof("x %s\n", x.Text(16))
|
|
klog.V(2).Infof("u_x %s\n", u_x.String())
|
|
klog.V(2).Infof("p %s\n", P1.String())
|
|
klog.V(2).Infof("hPrimes length %d\n", len(hPrimes.vector))
|
|
|
|
primebase := NewGeneratorParams3(u_x, params.Gs, hPrimes) // trigger sigma protocol
|
|
ipstatement := &IPStatement{PrimeBase: primebase, P: P1}
|
|
ipwitness := &IPWitness{L: lPoly.Evaluate(x), R: rPoly.Evaluate(x)}
|
|
|
|
for i := range ipwitness.L.vector {
|
|
klog.V(2).Infof("L %d %s \n", i, ipwitness.L.vector[i].Text(16))
|
|
}
|
|
|
|
for i := range ipwitness.R.vector {
|
|
klog.V(2).Infof("R %d %s \n", i, ipwitness.R.vector[i].Text(16))
|
|
}
|
|
|
|
proof.ip = NewInnerProductProof(ipstatement, ipwitness, o)
|
|
*/
|
|
|
|
return &proof
|
|
|
|
}
|