Alignment with dalek
the build failed
Details
the build failed
Details
This commit is contained in:
parent
5afd4a930a
commit
daa05d97c8
|
@ -20,11 +20,11 @@ func TestConstraintSystem(t *testing.T) {
|
||||||
b := new(ristretto.Scalar)
|
b := new(ristretto.Scalar)
|
||||||
b.FromUniformBytes(bbytes[:])
|
b.FromUniformBytes(bbytes[:])
|
||||||
|
|
||||||
xbytes := sha512.Sum512([]byte("a"))
|
xbytes := sha512.Sum512([]byte("b"))
|
||||||
x := new(ristretto.Scalar)
|
x := new(ristretto.Scalar)
|
||||||
x.FromUniformBytes(xbytes[:])
|
x.FromUniformBytes(xbytes[:])
|
||||||
|
|
||||||
ybytes := sha512.Sum512([]byte("b"))
|
ybytes := sha512.Sum512([]byte("a"))
|
||||||
y := new(ristretto.Scalar)
|
y := new(ristretto.Scalar)
|
||||||
y.FromUniformBytes(ybytes[:])
|
y.FromUniformBytes(ybytes[:])
|
||||||
|
|
||||||
|
@ -83,8 +83,8 @@ func TestConstraintSystemMix(t *testing.T) {
|
||||||
|
|
||||||
V1, a_lc := cs.Commit(three, prng.Next())
|
V1, a_lc := cs.Commit(three, prng.Next())
|
||||||
V2, b_lc := cs.Commit(three, prng.Next())
|
V2, b_lc := cs.Commit(three, prng.Next())
|
||||||
V3, x_lc := cs.Commit(four, prng.Next())
|
V3, x_lc := cs.Commit(two, prng.Next())
|
||||||
V4, y_lc := cs.Commit(two, prng.Next())
|
V4, y_lc := cs.Commit(four, prng.Next())
|
||||||
|
|
||||||
// todo make this an actual verifier!
|
// todo make this an actual verifier!
|
||||||
cs.VerifierCommit(V1)
|
cs.VerifierCommit(V1)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
package bulletproofs
|
||||||
|
|
||||||
|
type Generator struct {
|
||||||
|
}
|
|
@ -2,10 +2,9 @@ package bulletproofs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cwtch.im/tapir/primitives/core"
|
"cwtch.im/tapir/primitives/core"
|
||||||
"encoding/json"
|
"encoding/binary"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
ristretto "github.com/gtank/ristretto255"
|
ristretto "github.com/gtank/ristretto255"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// InnerProductProof encapsulates an inner product proof
|
// InnerProductProof encapsulates an inner product proof
|
||||||
|
@ -19,14 +18,14 @@ type InnerProductProof struct {
|
||||||
// ProveInnerProduct generates a proof for <a,b>, the inner product of a and b
|
// ProveInnerProduct generates a proof for <a,b>, the inner product of a and b
|
||||||
func ProveInnerProduct(a, b core.ScalarVector, u *ristretto.Element, P *ristretto.Element, G, H core.GeneratorVector, transcript *core.Transcript) InnerProductProof {
|
func ProveInnerProduct(a, b core.ScalarVector, u *ristretto.Element, P *ristretto.Element, G, H core.GeneratorVector, transcript *core.Transcript) InnerProductProof {
|
||||||
n := len(a)
|
n := len(a)
|
||||||
transcript.AddToTranscript("n", []byte(strconv.Itoa(n)))
|
|
||||||
|
transcript.AddToTranscript("dom-sep", []byte("ipp v1"))
|
||||||
|
nb := make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(nb, uint64(n))
|
||||||
|
transcript.AddToTranscript("n", nb)
|
||||||
|
|
||||||
Lvec := core.PointVector{}
|
Lvec := core.PointVector{}
|
||||||
Rvec := core.PointVector{}
|
Rvec := core.PointVector{}
|
||||||
Gbytes, _ := json.Marshal(G)
|
|
||||||
transcript.AddToTranscript("G", Gbytes)
|
|
||||||
Hbytes, _ := json.Marshal(H)
|
|
||||||
transcript.AddToTranscript("H", Hbytes)
|
|
||||||
transcript.AddToTranscript("P'", []byte(P.String()))
|
|
||||||
for n != 1 {
|
for n != 1 {
|
||||||
np := n / 2
|
np := n / 2
|
||||||
aL, aR := a[:np], a[np:]
|
aL, aR := a[:np], a[np:]
|
||||||
|
@ -40,9 +39,9 @@ func ProveInnerProduct(a, b core.ScalarVector, u *ristretto.Element, P *ristrett
|
||||||
L := core.MultiExp(append(aL.Join(bR), cL), append(GR.Join(HL), u))
|
L := core.MultiExp(append(aL.Join(bR), cL), append(GR.Join(HL), u))
|
||||||
R := core.MultiExp(append(aR.Join(bL), cR), append(GL.Join(HR), u))
|
R := core.MultiExp(append(aR.Join(bL), cR), append(GL.Join(HR), u))
|
||||||
|
|
||||||
transcript.AddToTranscript("L", []byte(L.String()))
|
transcript.AddElementToTranscript("L", L)
|
||||||
Lvec = append(Lvec, L)
|
Lvec = append(Lvec, L)
|
||||||
transcript.AddToTranscript("R", []byte(R.String()))
|
transcript.AddElementToTranscript("R", R)
|
||||||
Rvec = append(Rvec, R)
|
Rvec = append(Rvec, R)
|
||||||
|
|
||||||
u := transcript.CommitToTranscriptScalar("u")
|
u := transcript.CommitToTranscriptScalar("u")
|
||||||
|
@ -64,16 +63,12 @@ func ProveInnerProduct(a, b core.ScalarVector, u *ristretto.Element, P *ristrett
|
||||||
P_.Add(P_, P)
|
P_.Add(P_, P)
|
||||||
P_.Add(P_, new(ristretto.Element).ScalarMult(new(ristretto.Scalar).Invert(x2), R))
|
P_.Add(P_, new(ristretto.Element).ScalarMult(new(ristretto.Scalar).Invert(x2), R))
|
||||||
P = P_
|
P = P_
|
||||||
transcript.AddToTranscript("P'", []byte(P.String()))
|
//ranscript.AddToTranscript("P'", []byte(P.String()))
|
||||||
|
|
||||||
a = aL
|
a = aL
|
||||||
b = bL
|
b = bL
|
||||||
G = GL
|
G = GL
|
||||||
H = HL
|
H = HL
|
||||||
Gbytes, _ := json.Marshal(G)
|
|
||||||
transcript.AddToTranscript("G", Gbytes)
|
|
||||||
Hbytes, _ := json.Marshal(H)
|
|
||||||
transcript.AddToTranscript("H", Hbytes)
|
|
||||||
n = np
|
n = np
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,21 +77,23 @@ func ProveInnerProduct(a, b core.ScalarVector, u *ristretto.Element, P *ristrett
|
||||||
|
|
||||||
// Verify checks the given inner product proof
|
// Verify checks the given inner product proof
|
||||||
func Verify(proof InnerProductProof, n int, u, P *ristretto.Element, G, H core.GeneratorVector, transcript *core.Transcript) bool {
|
func Verify(proof InnerProductProof, n int, u, P *ristretto.Element, G, H core.GeneratorVector, transcript *core.Transcript) bool {
|
||||||
transcript.AddToTranscript("n", []byte(strconv.Itoa(n)))
|
|
||||||
np := n / 2
|
np := n / 2
|
||||||
|
|
||||||
Gbytes, _ := json.Marshal(G)
|
transcript.AddToTranscript("dom-sep", []byte("ipp v1"))
|
||||||
transcript.AddToTranscript("G", Gbytes)
|
b := make([]byte, 8)
|
||||||
Hbytes, _ := json.Marshal(H)
|
binary.LittleEndian.PutUint64(b, uint64(n))
|
||||||
transcript.AddToTranscript("H", Hbytes)
|
transcript.AddToTranscript("n", b)
|
||||||
transcript.AddToTranscript("P'", []byte(P.String()))
|
|
||||||
for i := range proof.L {
|
for i := range proof.L {
|
||||||
GL, GR := G[:np], G[np:]
|
GL, GR := G[:np], G[np:]
|
||||||
HL, HR := H[:np], H[np:]
|
HL, HR := H[:np], H[np:]
|
||||||
|
|
||||||
transcript.AddToTranscript("L", []byte(proof.L[i].String()))
|
transcript.AddElementToTranscript("L", proof.L[i])
|
||||||
transcript.AddToTranscript("R", []byte(proof.R[i].String()))
|
transcript.AddElementToTranscript("R", proof.R[i])
|
||||||
x := transcript.CommitToTranscriptScalar("u")
|
x := transcript.CommitToTranscriptScalar("u")
|
||||||
|
|
||||||
|
log.Debugf("L: %x\n", proof.L[i].Encode([]byte{}))
|
||||||
|
log.Debugf("R %x\n", proof.R[i].Encode([]byte{}))
|
||||||
|
log.Debugf("u: %x\n", x.Encode([]byte{}))
|
||||||
xinv := new(ristretto.Scalar)
|
xinv := new(ristretto.Scalar)
|
||||||
xinv.Invert(x)
|
xinv.Invert(x)
|
||||||
|
|
||||||
|
@ -110,14 +107,8 @@ func Verify(proof InnerProductProof, n int, u, P *ristretto.Element, G, H core.G
|
||||||
P_.Add(P_, P)
|
P_.Add(P_, P)
|
||||||
P_.Add(P_, new(ristretto.Element).ScalarMult(new(ristretto.Scalar).Invert(x2), proof.R[i]))
|
P_.Add(P_, new(ristretto.Element).ScalarMult(new(ristretto.Scalar).Invert(x2), proof.R[i]))
|
||||||
P = P_
|
P = P_
|
||||||
transcript.AddToTranscript("P'", []byte(P.String()))
|
|
||||||
|
|
||||||
G = GL
|
G = GL
|
||||||
H = HL
|
H = HL
|
||||||
Gbytes, _ := json.Marshal(G)
|
|
||||||
transcript.AddToTranscript("G", Gbytes)
|
|
||||||
Hbytes, _ := json.Marshal(H)
|
|
||||||
transcript.AddToTranscript("H", Hbytes)
|
|
||||||
np = np / 2
|
np = np / 2
|
||||||
}
|
}
|
||||||
c := new(ristretto.Scalar)
|
c := new(ristretto.Scalar)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package bulletproofs
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"cwtch.im/tapir/primitives/core"
|
"cwtch.im/tapir/primitives/core"
|
||||||
|
"encoding/binary"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
ristretto "github.com/gtank/ristretto255"
|
ristretto "github.com/gtank/ristretto255"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -18,7 +19,7 @@ type RangeProof struct {
|
||||||
InnerProduct *ristretto.Scalar
|
InnerProduct *ristretto.Scalar
|
||||||
Mu *ristretto.Scalar
|
Mu *ristretto.Scalar
|
||||||
IPP InnerProductProof
|
IPP InnerProductProof
|
||||||
V *ristretto.Element
|
V []*ristretto.Element
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitmentsParams encapsulates the commitment parameters for a given range proof
|
// CommitmentsParams encapsulates the commitment parameters for a given range proof
|
||||||
|
@ -57,6 +58,14 @@ func GenerateRangeProof(value int32, c CommitmentsParams, transcript *core.Trans
|
||||||
two.Add(one, one)
|
two.Add(one, one)
|
||||||
two_n := core.PowerVector(two, c.max)
|
two_n := core.PowerVector(two, c.max)
|
||||||
|
|
||||||
|
transcript.AddToTranscript("dom-sep", []byte("rangeproof v1"))
|
||||||
|
b := make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(b, uint64(c.max))
|
||||||
|
transcript.AddToTranscript("n", b)
|
||||||
|
b = make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(b, 1)
|
||||||
|
transcript.AddToTranscript("m", b)
|
||||||
|
|
||||||
// Generate a prng to from this transcript and some external randomness
|
// Generate a prng to from this transcript and some external randomness
|
||||||
// We use this to generate the rest of our private scalars
|
// We use this to generate the rest of our private scalars
|
||||||
// TODO: move to transcript
|
// TODO: move to transcript
|
||||||
|
@ -73,11 +82,14 @@ func GenerateRangeProof(value int32, c CommitmentsParams, transcript *core.Trans
|
||||||
alpha := prng.Next()
|
alpha := prng.Next()
|
||||||
|
|
||||||
vs := new(ristretto.Scalar)
|
vs := new(ristretto.Scalar)
|
||||||
b := make([]byte, 32)
|
b = make([]byte, 32)
|
||||||
copy(b, big.NewInt(int64(value)).Bytes())
|
copy(b, big.NewInt(int64(value)).Bytes())
|
||||||
vs.Decode(b)
|
vs.Decode(b)
|
||||||
|
|
||||||
V := core.MultiExp(core.ScalarVector{gamma, vs}, core.GeneratorVector{c.h, c.g})
|
V := core.MultiExp(core.ScalarVector{gamma, vs}, core.GeneratorVector{c.h, c.g})
|
||||||
|
|
||||||
|
transcript.AddElementToTranscript("V", V)
|
||||||
|
|
||||||
A := core.MultiExp(append(aL.Join(aR), alpha), append(c.G.Join(c.H), c.h))
|
A := core.MultiExp(append(aL.Join(aR), alpha), append(c.G.Join(c.H), c.h))
|
||||||
log.Debugf("vs: %v", vs)
|
log.Debugf("vs: %v", vs)
|
||||||
|
|
||||||
|
@ -91,8 +103,8 @@ func GenerateRangeProof(value int32, c CommitmentsParams, transcript *core.Trans
|
||||||
|
|
||||||
S := core.MultiExp(append(Sl.Join(Sr), p), append(c.G.Join(c.H), c.h))
|
S := core.MultiExp(append(Sl.Join(Sr), p), append(c.G.Join(c.H), c.h))
|
||||||
|
|
||||||
transcript.AddToTranscript("A", []byte(A.String()))
|
transcript.AddElementToTranscript("A", A)
|
||||||
transcript.AddToTranscript("S", []byte(S.String()))
|
transcript.AddElementToTranscript("S", S)
|
||||||
|
|
||||||
y := transcript.CommitToTranscriptScalar("y")
|
y := transcript.CommitToTranscriptScalar("y")
|
||||||
z := transcript.CommitToTranscriptScalar("z")
|
z := transcript.CommitToTranscriptScalar("z")
|
||||||
|
@ -116,8 +128,8 @@ func GenerateRangeProof(value int32, c CommitmentsParams, transcript *core.Trans
|
||||||
T1 := core.MultiExp(core.ScalarVector{t1, tau1}, core.GeneratorVector{c.g, c.h})
|
T1 := core.MultiExp(core.ScalarVector{t1, tau1}, core.GeneratorVector{c.g, c.h})
|
||||||
T2 := core.MultiExp(core.ScalarVector{t2, tau2}, core.GeneratorVector{c.g, c.h})
|
T2 := core.MultiExp(core.ScalarVector{t2, tau2}, core.GeneratorVector{c.g, c.h})
|
||||||
|
|
||||||
transcript.AddToTranscript("T1", []byte(T1.String()))
|
transcript.AddElementToTranscript("T_1", T1)
|
||||||
transcript.AddToTranscript("T2", []byte(T2.String()))
|
transcript.AddElementToTranscript("T_2", T2)
|
||||||
|
|
||||||
x := transcript.CommitToTranscriptScalar("x")
|
x := transcript.CommitToTranscriptScalar("x")
|
||||||
|
|
||||||
|
@ -147,18 +159,26 @@ func GenerateRangeProof(value int32, c CommitmentsParams, transcript *core.Trans
|
||||||
P := core.MultiExp(l.Join(r), c.G.Join(H_))
|
P := core.MultiExp(l.Join(r), c.G.Join(H_))
|
||||||
log.Debugf("P: %v", P)
|
log.Debugf("P: %v", P)
|
||||||
|
|
||||||
uP := new(ristretto.Element).Add(P, new(ristretto.Element).ScalarMult(iplr, c.u))
|
mu := new(ristretto.Scalar)
|
||||||
log.Debugf("uP: %v", uP)
|
mu.Add(alpha, new(ristretto.Scalar).Multiply(p, x))
|
||||||
ipp := ProveInnerProduct(l, r, c.u, new(ristretto.Element).Add(new(ristretto.Element).Zero(), uP), core.CopyVector(c.G), core.CopyVector(H_), transcript)
|
|
||||||
|
|
||||||
taux := new(ristretto.Scalar)
|
taux := new(ristretto.Scalar)
|
||||||
taux.Multiply(tau2, new(ristretto.Scalar).Multiply(x, x))
|
taux.Multiply(tau2, new(ristretto.Scalar).Multiply(x, x))
|
||||||
taux.Add(taux, new(ristretto.Scalar).Multiply(tau1, x))
|
taux.Add(taux, new(ristretto.Scalar).Multiply(tau1, x))
|
||||||
taux.Add(taux, new(ristretto.Scalar).Multiply(z2, gamma))
|
taux.Add(taux, new(ristretto.Scalar).Multiply(z2, gamma))
|
||||||
|
|
||||||
mu := new(ristretto.Scalar)
|
transcript.AddToTranscript("t_x", iplr.Encode([]byte{}))
|
||||||
mu.Add(alpha, new(ristretto.Scalar).Multiply(p, x))
|
transcript.AddToTranscript("t_x_blinding", taux.Encode([]byte{}))
|
||||||
return RangeProof{A, S, T1, T2, taux, iplr, mu, ipp, V}, gamma
|
transcript.AddToTranscript("e_blinding", mu.Encode([]byte{}))
|
||||||
|
w := transcript.CommitToTranscriptScalar("w")
|
||||||
|
|
||||||
|
U := new(ristretto.Element).ScalarMult(w, c.g)
|
||||||
|
|
||||||
|
uP := new(ristretto.Element).Add(P, new(ristretto.Element).ScalarMult(iplr, U))
|
||||||
|
log.Debugf("uP: %v", uP)
|
||||||
|
ipp := ProveInnerProduct(l, r, U, new(ristretto.Element).Add(new(ristretto.Element).Zero(), uP), core.CopyVector(c.G), core.CopyVector(H_), transcript)
|
||||||
|
|
||||||
|
return RangeProof{A, S, T1, T2, taux, iplr, mu, ipp, []*ristretto.Element{V}}, gamma
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyRangeProof returns true if the given proof passes all the checks for a given set of commitment parameters
|
// VerifyRangeProof returns true if the given proof passes all the checks for a given set of commitment parameters
|
||||||
|
@ -169,13 +189,32 @@ func VerifyRangeProof(proof RangeProof, c CommitmentsParams, transcript *core.Tr
|
||||||
two.Add(one, one)
|
two.Add(one, one)
|
||||||
two_n := core.PowerVector(two, c.max)
|
two_n := core.PowerVector(two, c.max)
|
||||||
|
|
||||||
transcript.AddToTranscript("A", []byte(proof.A.String()))
|
transcript.AddToTranscript("dom-sep", []byte("rangeproof v1"))
|
||||||
transcript.AddToTranscript("S", []byte(proof.S.String()))
|
b := make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(b, uint64(c.max))
|
||||||
|
transcript.AddToTranscript("n", b)
|
||||||
|
b = make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(b, 1)
|
||||||
|
transcript.AddToTranscript("m", b)
|
||||||
|
|
||||||
|
for _, v := range proof.V {
|
||||||
|
transcript.AddElementToTranscript("V", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
transcript.AddElementToTranscript("A", proof.A)
|
||||||
|
transcript.AddElementToTranscript("S", proof.S)
|
||||||
y := transcript.CommitToTranscriptScalar("y")
|
y := transcript.CommitToTranscriptScalar("y")
|
||||||
z := transcript.CommitToTranscriptScalar("z")
|
z := transcript.CommitToTranscriptScalar("z")
|
||||||
transcript.AddToTranscript("T1", []byte(proof.T1.String()))
|
transcript.AddElementToTranscript("T_1", proof.T1)
|
||||||
transcript.AddToTranscript("T2", []byte(proof.T2.String()))
|
transcript.AddElementToTranscript("T_2", proof.T2)
|
||||||
x := transcript.CommitToTranscriptScalar("x")
|
x := transcript.CommitToTranscriptScalar("x")
|
||||||
|
|
||||||
|
transcript.AddToTranscript("t_x", proof.InnerProduct.Encode([]byte{}))
|
||||||
|
transcript.AddToTranscript("t_x_blinding", proof.TauX.Encode([]byte{}))
|
||||||
|
transcript.AddToTranscript("e_blinding", proof.Mu.Encode([]byte{}))
|
||||||
|
log.Debugf("mu: %x", proof.Mu.Encode([]byte{}))
|
||||||
|
|
||||||
|
log.Debugf("x: %x", x.Encode([]byte{}))
|
||||||
y_n := core.PowerVector(y, c.max)
|
y_n := core.PowerVector(y, c.max)
|
||||||
// generate h'
|
// generate h'
|
||||||
H_ := make(core.GeneratorVector, c.max)
|
H_ := make(core.GeneratorVector, c.max)
|
||||||
|
@ -193,7 +232,7 @@ func VerifyRangeProof(proof RangeProof, c CommitmentsParams, transcript *core.Tr
|
||||||
x2 := new(ristretto.Scalar)
|
x2 := new(ristretto.Scalar)
|
||||||
x2.Multiply(x, x)
|
x2.Multiply(x, x)
|
||||||
|
|
||||||
rhs := core.MultiExp(core.ScalarVector{z2, delta(y_n, z, c.max), x, x2}, core.GeneratorVector{proof.V, c.g, proof.T1, proof.T2})
|
rhs := core.MultiExp(core.ScalarVector{z2, delta(y_n, z, c.max), x, x2}, core.GeneratorVector(proof.V).Join(core.GeneratorVector{c.g, proof.T1, proof.T2}))
|
||||||
log.Debugf("lhs: %v", lhs)
|
log.Debugf("lhs: %v", lhs)
|
||||||
log.Debugf("rhs: %v", rhs)
|
log.Debugf("rhs: %v", rhs)
|
||||||
log.Debugf("equal: %v", lhs.Equal(rhs))
|
log.Debugf("equal: %v", lhs.Equal(rhs))
|
||||||
|
@ -218,12 +257,15 @@ func VerifyRangeProof(proof RangeProof, c CommitmentsParams, transcript *core.Tr
|
||||||
Pl := new(ristretto.Element).Subtract(Pr, new(ristretto.Element).ScalarMult(proof.Mu, c.h))
|
Pl := new(ristretto.Element).Subtract(Pr, new(ristretto.Element).ScalarMult(proof.Mu, c.h))
|
||||||
// check inner product
|
// check inner product
|
||||||
|
|
||||||
uP := new(ristretto.Element).Add(Pl, new(ristretto.Element).ScalarMult(proof.InnerProduct, c.u))
|
w := transcript.CommitToTranscriptScalar("w")
|
||||||
|
U := new(ristretto.Element).ScalarMult(w, c.g)
|
||||||
|
|
||||||
|
uP := new(ristretto.Element).Add(Pl, new(ristretto.Element).ScalarMult(proof.InnerProduct, U))
|
||||||
|
|
||||||
log.Debugf("P: %v", Pl)
|
log.Debugf("P: %v", Pl)
|
||||||
log.Debugf("uP: %v", uP)
|
log.Debugf("uP: %v", uP)
|
||||||
|
|
||||||
return Verify(proof.IPP, c.max, c.u, new(ristretto.Element).Add(new(ristretto.Element).Zero(), uP), core.CopyVector(c.G), core.CopyVector(H_), transcript)
|
return Verify(proof.IPP, c.max, U, new(ristretto.Element).Add(new(ristretto.Element).Zero(), uP), core.CopyVector(c.G), core.CopyVector(H_), transcript)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@ package bulletproofs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cwtch.im/tapir/primitives/core"
|
"cwtch.im/tapir/primitives/core"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
|
"github.com/gtank/ristretto255"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,3 +27,124 @@ func TestProove(t *testing.T) {
|
||||||
t.Fatalf("Failed to Verify Range Proof")
|
t.Fatalf("Failed to Verify Range Proof")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func byteToPoint(in []byte) *ristretto255.Element {
|
||||||
|
element := ristretto255.NewElement()
|
||||||
|
element.Decode(in)
|
||||||
|
return element
|
||||||
|
}
|
||||||
|
|
||||||
|
func byteToScalar(in []byte) *ristretto255.Scalar {
|
||||||
|
scalar := ristretto255.NewScalar()
|
||||||
|
scalar.Decode(in[0:32])
|
||||||
|
return scalar
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeInnerProduct(in []byte) *InnerProductProof {
|
||||||
|
num_elements := len(in) / 32
|
||||||
|
lg_n := (num_elements - 2) / 2
|
||||||
|
lvec := make(core.PointVector, lg_n)
|
||||||
|
rvec := make(core.PointVector, lg_n)
|
||||||
|
for i := 0; i < lg_n; i++ {
|
||||||
|
pos := 2 * i * 32
|
||||||
|
lvec[i] = byteToPoint(in[pos : pos+32])
|
||||||
|
rvec[i] = byteToPoint(in[pos+32 : pos+64])
|
||||||
|
}
|
||||||
|
pos := 2 * lg_n * 32
|
||||||
|
a := byteToScalar(in[pos : pos+32])
|
||||||
|
b := byteToScalar(in[pos+32 : pos+64])
|
||||||
|
return &InnerProductProof{lvec, rvec, a, b}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDalek(t *testing.T) {
|
||||||
|
log.SetLevel(log.LevelDebug)
|
||||||
|
|
||||||
|
t.Logf("Testing dalek-cryptography bulletproofs test vector...")
|
||||||
|
rp, _ := hex.DecodeString("46b6ea8b6a9710c41c2622d4b353dbcf5f89afe8ed66c469f192bec19dc71d23c0442827f97fc9085a89caa87d294b0a21e7b8957732ec4951f6bf7d3aa2c66e7af3b7b956c7dcb3bed1223575a217a30642b603b6bf1d4138ed95e3458c524510b42c8d82958f40b447a84242b1ba1eeea54013f80bad643048eeb0b17c292a057cb6ae1c42338837c05eaa6336a17d60fa141204e015a1df15b28c1318c709d7eb35569cde89c0bf37eace54880a151498b38da54c6d739564f46f01b73601e518355ea06c9ef58a45fcb3baadbd1ac54e0838c471a6b91845f123d569fa0c46ef94471b7b826230e8576146beec08ac3e6683998815c576581f4c0e493433480f95f6495210636eaa2e32b577e1c363e35e522db85b18a56d57eb626f9e2b50578e0d7ee7b74b328e158b366bb9d117db725820a2fec3b1508212d75823345a801c0b602bfa05919d7e3bb8e71944587072badc363f334b08ba90d13e077ad24b82bacd51fc668d2b880daabd3b87e6bdc9584af66523026a30aadfc359283891bb65cca502f47421ffeee1fb5a5237bfa965b66a8b8ca5d6954f4f8222244c6a5340dc81e8d781d092cae2a763f185dd0b89965b1dd2506807b5d3e5a305fd9a68e60b91389dcffae6f85538713aa7ed272b8174e2f0b9730ebb6c464d06")
|
||||||
|
|
||||||
|
t.Logf("Deserializing dalek-cryptography bulletproofs test vector...%x", rp)
|
||||||
|
|
||||||
|
A := byteToPoint(rp[0:32])
|
||||||
|
S := byteToPoint(rp[32:64])
|
||||||
|
T1 := byteToPoint(rp[64:96])
|
||||||
|
T2 := byteToPoint(rp[96:128])
|
||||||
|
|
||||||
|
TX := byteToScalar(rp[128:160])
|
||||||
|
TX_blinding := byteToScalar(rp[160:192])
|
||||||
|
micro := byteToScalar(rp[192 : 192+32])
|
||||||
|
|
||||||
|
ipp := decodeInnerProduct(rp[192+32:])
|
||||||
|
|
||||||
|
vbytes := []string{
|
||||||
|
"90b0c2fe57934dff9f5396e135e7d72b82b3c5393e1843178918eb2cf28a5f3c",
|
||||||
|
"74256a3e2a7fe948210c4095195ae4db3e3498c6c5fddc2afb226c0f1e97e468",
|
||||||
|
"7e348def6d03dc7bcbe7e03736ca2898e2efa9f6ff8ae4ed1cb5252ec1744075",
|
||||||
|
"861859f5d4c14f5d6d7ad88dcf43c9a98064a7d8702ffc9bad9eba2ed766702a",
|
||||||
|
"4c09b1260c833fefe25b1c3d3becc80979beca5e864d57fcb410bb15c7ba5c14",
|
||||||
|
"08cf26bfdf2e6b731536f5e48b4c0ac7b5fc846d36aaa3fe0d28f07c207f0814",
|
||||||
|
"a6e2d1c2770333c9a8a5ac10d9eb28e8609d5954428261335b2fd6ff0e0e8d69",
|
||||||
|
"30beef3b58fd2c18dde771d5c77e32f8dc01361e284aef517bce54a5c74c4665",
|
||||||
|
}
|
||||||
|
|
||||||
|
V := make([]*ristretto255.Element, len(vbytes))
|
||||||
|
for i, v := range vbytes {
|
||||||
|
V[i] = ristretto255.NewElement()
|
||||||
|
vdec, _ := hex.DecodeString(v)
|
||||||
|
V[i].Decode(vdec)
|
||||||
|
}
|
||||||
|
|
||||||
|
rangeProof := RangeProof{A, S, T1, T2, TX_blinding, TX, micro, *ipp, V[0:1]}
|
||||||
|
|
||||||
|
json, _ := json.Marshal(rangeProof)
|
||||||
|
t.Logf("RangeProof: %s", json)
|
||||||
|
|
||||||
|
t.Logf("Deserialized Range Proof: %s", json)
|
||||||
|
|
||||||
|
t.Logf("Generating dalek-cryptography pedersen generators....")
|
||||||
|
params := CommitmentsParams{}
|
||||||
|
params.g = ristretto255.NewElement().Base()
|
||||||
|
params.h = ristretto255.NewElement()
|
||||||
|
h := sha3.Sum512(params.g.Encode([]byte{}))
|
||||||
|
|
||||||
|
params.h = ristretto255.NewElement().FromUniformBytes(h[:])
|
||||||
|
|
||||||
|
params.max = 8
|
||||||
|
params.G = make(core.GeneratorVector, params.max)
|
||||||
|
params.H = make(core.GeneratorVector, params.max)
|
||||||
|
|
||||||
|
labelG := []byte{'G', 0, 0, 0, 0}
|
||||||
|
shake := sha3.NewShake256()
|
||||||
|
shake.Write([]byte("GeneratorsChain"))
|
||||||
|
shake.Write(labelG[:])
|
||||||
|
|
||||||
|
labelH := []byte{'H', 0, 0, 0, 0}
|
||||||
|
shakeH := sha3.NewShake256()
|
||||||
|
shakeH.Write([]byte("GeneratorsChain"))
|
||||||
|
shakeH.Write(labelH[:])
|
||||||
|
|
||||||
|
t.Logf("Generating dalek-cryptography BP generators....")
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
b := make([]byte, 64)
|
||||||
|
shake.Read(b)
|
||||||
|
params.G[i] = ristretto255.NewElement()
|
||||||
|
params.G[i].FromUniformBytes(b)
|
||||||
|
|
||||||
|
//t.Logf("G: %x", params.G[i].Encode([]byte{}))
|
||||||
|
|
||||||
|
bH := make([]byte, 64)
|
||||||
|
shakeH.Read(bH)
|
||||||
|
params.H[i] = ristretto255.NewElement()
|
||||||
|
params.H[i].FromUniformBytes(bH)
|
||||||
|
|
||||||
|
// t.Logf("H: %x", params.H[i].Encode([]byte{}))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//t.Logf("parmas: %v", params)
|
||||||
|
|
||||||
|
verifierTranscript := core.NewTranscript("Deserialize-And-Verify Test")
|
||||||
|
t.Logf("Verification Result: %v", VerifyRangeProof(rangeProof, params, verifierTranscript))
|
||||||
|
|
||||||
|
t.Logf("Transcript: %s\n", verifierTranscript.OutputTranscriptToAudit())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/gtank/merlin"
|
||||||
ristretto "github.com/gtank/ristretto255"
|
ristretto "github.com/gtank/ristretto255"
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
"hash"
|
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,15 +18,14 @@ import (
|
||||||
//
|
//
|
||||||
// At some point we might want to extend this to be compatible with Merlin transcripts, built on STROBE
|
// At some point we might want to extend this to be compatible with Merlin transcripts, built on STROBE
|
||||||
type Transcript struct {
|
type Transcript struct {
|
||||||
hash hash.Hash
|
merlinTranscript *merlin.Transcript
|
||||||
transcript string
|
transcript string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTranscript creates a new Transcript with the given Label, the label should be unique to the application
|
// NewTranscript creates a new Transcript with the given Label, the label should be unique to the application
|
||||||
func NewTranscript(label string) *Transcript {
|
func NewTranscript(label string) *Transcript {
|
||||||
transcript := new(Transcript)
|
transcript := new(Transcript)
|
||||||
transcript.hash = sha3.New512()
|
transcript.merlinTranscript = merlin.NewTranscript(label)
|
||||||
transcript.AddToTranscript("protocol", []byte(label))
|
|
||||||
return transcript
|
return transcript
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +34,13 @@ func NewTranscript(label string) *Transcript {
|
||||||
func (t *Transcript) AddToTranscript(label string, b []byte) {
|
func (t *Transcript) AddToTranscript(label string, b []byte) {
|
||||||
op := fmt.Sprintf("%s (%d) %x;", label, len(b), b)
|
op := fmt.Sprintf("%s (%d) %x;", label, len(b), b)
|
||||||
t.transcript = fmt.Sprintf("%v\n%v", t.transcript, op)
|
t.transcript = fmt.Sprintf("%v\n%v", t.transcript, op)
|
||||||
t.hash.Write([]byte(op))
|
t.merlinTranscript.AppendMessage([]byte(label), b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddElementToTranscript appends a value to the transcript with the given label
|
||||||
|
// This binds the given data to the label.
|
||||||
|
func (t *Transcript) AddElementToTranscript(label string, element *ristretto.Element) {
|
||||||
|
t.AddToTranscript(label, element.Encode([]byte{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// OutputTranscriptToAudit outputs a human-readable copy of the transcript so far.
|
// OutputTranscriptToAudit outputs a human-readable copy of the transcript so far.
|
||||||
|
@ -48,14 +53,13 @@ func (t Transcript) OutputTranscriptToAudit() string {
|
||||||
func (t *Transcript) NewProtocol(label string) {
|
func (t *Transcript) NewProtocol(label string) {
|
||||||
op := fmt.Sprintf("---- new-protcol: %s ----", label)
|
op := fmt.Sprintf("---- new-protcol: %s ----", label)
|
||||||
t.transcript = fmt.Sprintf("%v\n%v", t.transcript, op)
|
t.transcript = fmt.Sprintf("%v\n%v", t.transcript, op)
|
||||||
t.hash.Write([]byte(op))
|
t.merlinTranscript.AppendMessage([]byte("protocol"), []byte(label))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitToTranscript generates a challenge based on the current transcript, it also commits the challenge to the transcript.
|
// CommitToTranscript generates a challenge based on the current transcript, it also commits the challenge to the transcript.
|
||||||
func (t *Transcript) CommitToTranscript(label string) []byte {
|
func (t *Transcript) CommitToTranscript(label string) []byte {
|
||||||
t.AddToTranscript("commit", []byte(label))
|
//t.AddToTranscript("commit", []byte(label))
|
||||||
b := t.hash.Sum([]byte{})
|
b := t.merlinTranscript.ExtractBytes([]byte(label), 64)
|
||||||
t.AddToTranscript(label, b)
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +79,7 @@ func (prng *PRNG) Next() *ristretto.Scalar {
|
||||||
|
|
||||||
// CommitToPRNG commits the label to the transcript and derives a PRNG from the transcript.
|
// CommitToPRNG commits the label to the transcript and derives a PRNG from the transcript.
|
||||||
func (t *Transcript) CommitToPRNG(label string) PRNG {
|
func (t *Transcript) CommitToPRNG(label string) PRNG {
|
||||||
t.AddToTranscript("commit-prng", []byte(label))
|
b := t.merlinTranscript.ExtractBytes([]byte(label), 64)
|
||||||
b := t.hash.Sum([]byte{})
|
|
||||||
t.AddToTranscript(label, b)
|
|
||||||
prng := sha3.NewShake256()
|
prng := sha3.NewShake256()
|
||||||
prng.Write(b)
|
prng.Write(b)
|
||||||
return PRNG{prng: prng}
|
return PRNG{prng: prng}
|
||||||
|
|
Loading…
Reference in New Issue