diff --git a/primitives/bulletproofs/constaint_system_test.go b/primitives/bulletproofs/constaint_system_test.go index 69d15f5..ae1b7ff 100644 --- a/primitives/bulletproofs/constaint_system_test.go +++ b/primitives/bulletproofs/constaint_system_test.go @@ -20,11 +20,11 @@ func TestConstraintSystem(t *testing.T) { b := new(ristretto.Scalar) b.FromUniformBytes(bbytes[:]) - xbytes := sha512.Sum512([]byte("a")) + xbytes := sha512.Sum512([]byte("b")) x := new(ristretto.Scalar) x.FromUniformBytes(xbytes[:]) - ybytes := sha512.Sum512([]byte("b")) + ybytes := sha512.Sum512([]byte("a")) y := new(ristretto.Scalar) y.FromUniformBytes(ybytes[:]) @@ -83,8 +83,8 @@ func TestConstraintSystemMix(t *testing.T) { V1, a_lc := cs.Commit(three, prng.Next()) V2, b_lc := cs.Commit(three, prng.Next()) - V3, x_lc := cs.Commit(four, prng.Next()) - V4, y_lc := cs.Commit(two, prng.Next()) + V3, x_lc := cs.Commit(two, prng.Next()) + V4, y_lc := cs.Commit(four, prng.Next()) // todo make this an actual verifier! cs.VerifierCommit(V1) diff --git a/primitives/bulletproofs/generators.go b/primitives/bulletproofs/generators.go new file mode 100644 index 0000000..cd1a65e --- /dev/null +++ b/primitives/bulletproofs/generators.go @@ -0,0 +1,4 @@ +package bulletproofs + +type Generator struct { +} diff --git a/primitives/bulletproofs/inner_product.go b/primitives/bulletproofs/inner_product.go index d23fca1..761a681 100644 --- a/primitives/bulletproofs/inner_product.go +++ b/primitives/bulletproofs/inner_product.go @@ -2,10 +2,9 @@ package bulletproofs import ( "cwtch.im/tapir/primitives/core" - "encoding/json" + "encoding/binary" "git.openprivacy.ca/openprivacy/libricochet-go/log" ristretto "github.com/gtank/ristretto255" - "strconv" ) // InnerProductProof encapsulates an inner product proof @@ -19,14 +18,14 @@ type InnerProductProof struct { // ProveInnerProduct generates a proof for , 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 { 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{} 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 { np := n / 2 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)) 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) - transcript.AddToTranscript("R", []byte(R.String())) + transcript.AddElementToTranscript("R", R) Rvec = append(Rvec, R) 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_, new(ristretto.Element).ScalarMult(new(ristretto.Scalar).Invert(x2), R)) P = P_ - transcript.AddToTranscript("P'", []byte(P.String())) + //ranscript.AddToTranscript("P'", []byte(P.String())) a = aL b = bL G = GL H = HL - Gbytes, _ := json.Marshal(G) - transcript.AddToTranscript("G", Gbytes) - Hbytes, _ := json.Marshal(H) - transcript.AddToTranscript("H", Hbytes) n = np } @@ -82,21 +77,23 @@ func ProveInnerProduct(a, b core.ScalarVector, u *ristretto.Element, P *ristrett // 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 { - transcript.AddToTranscript("n", []byte(strconv.Itoa(n))) np := n / 2 - Gbytes, _ := json.Marshal(G) - transcript.AddToTranscript("G", Gbytes) - Hbytes, _ := json.Marshal(H) - transcript.AddToTranscript("H", Hbytes) - transcript.AddToTranscript("P'", []byte(P.String())) + transcript.AddToTranscript("dom-sep", []byte("ipp v1")) + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, uint64(n)) + transcript.AddToTranscript("n", b) for i := range proof.L { GL, GR := G[:np], G[np:] HL, HR := H[:np], H[np:] - transcript.AddToTranscript("L", []byte(proof.L[i].String())) - transcript.AddToTranscript("R", []byte(proof.R[i].String())) + transcript.AddElementToTranscript("L", proof.L[i]) + transcript.AddElementToTranscript("R", proof.R[i]) 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.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_, new(ristretto.Element).ScalarMult(new(ristretto.Scalar).Invert(x2), proof.R[i])) P = P_ - transcript.AddToTranscript("P'", []byte(P.String())) - G = GL H = HL - Gbytes, _ := json.Marshal(G) - transcript.AddToTranscript("G", Gbytes) - Hbytes, _ := json.Marshal(H) - transcript.AddToTranscript("H", Hbytes) np = np / 2 } c := new(ristretto.Scalar) diff --git a/primitives/bulletproofs/range_proof.go b/primitives/bulletproofs/range_proof.go index 85ac52b..7b9a8e0 100644 --- a/primitives/bulletproofs/range_proof.go +++ b/primitives/bulletproofs/range_proof.go @@ -3,6 +3,7 @@ package bulletproofs import ( "crypto/rand" "cwtch.im/tapir/primitives/core" + "encoding/binary" "git.openprivacy.ca/openprivacy/libricochet-go/log" ristretto "github.com/gtank/ristretto255" "math/big" @@ -18,7 +19,7 @@ type RangeProof struct { InnerProduct *ristretto.Scalar Mu *ristretto.Scalar IPP InnerProductProof - V *ristretto.Element + V []*ristretto.Element } // 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_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 // We use this to generate the rest of our private scalars // TODO: move to transcript @@ -73,11 +82,14 @@ func GenerateRangeProof(value int32, c CommitmentsParams, transcript *core.Trans alpha := prng.Next() vs := new(ristretto.Scalar) - b := make([]byte, 32) + b = make([]byte, 32) copy(b, big.NewInt(int64(value)).Bytes()) vs.Decode(b) 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)) 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)) - transcript.AddToTranscript("A", []byte(A.String())) - transcript.AddToTranscript("S", []byte(S.String())) + transcript.AddElementToTranscript("A", A) + transcript.AddElementToTranscript("S", S) y := transcript.CommitToTranscriptScalar("y") 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}) T2 := core.MultiExp(core.ScalarVector{t2, tau2}, core.GeneratorVector{c.g, c.h}) - transcript.AddToTranscript("T1", []byte(T1.String())) - transcript.AddToTranscript("T2", []byte(T2.String())) + transcript.AddElementToTranscript("T_1", T1) + transcript.AddElementToTranscript("T_2", T2) 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_)) log.Debugf("P: %v", P) - uP := new(ristretto.Element).Add(P, new(ristretto.Element).ScalarMult(iplr, c.u)) - log.Debugf("uP: %v", uP) - ipp := ProveInnerProduct(l, r, c.u, new(ristretto.Element).Add(new(ristretto.Element).Zero(), uP), core.CopyVector(c.G), core.CopyVector(H_), transcript) + mu := new(ristretto.Scalar) + mu.Add(alpha, new(ristretto.Scalar).Multiply(p, x)) taux := new(ristretto.Scalar) 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(z2, gamma)) - mu := new(ristretto.Scalar) - mu.Add(alpha, new(ristretto.Scalar).Multiply(p, x)) - return RangeProof{A, S, T1, T2, taux, iplr, mu, ipp, V}, gamma + transcript.AddToTranscript("t_x", iplr.Encode([]byte{})) + transcript.AddToTranscript("t_x_blinding", taux.Encode([]byte{})) + 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 @@ -169,13 +189,32 @@ func VerifyRangeProof(proof RangeProof, c CommitmentsParams, transcript *core.Tr two.Add(one, one) two_n := core.PowerVector(two, c.max) - transcript.AddToTranscript("A", []byte(proof.A.String())) - transcript.AddToTranscript("S", []byte(proof.S.String())) + 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) + + for _, v := range proof.V { + transcript.AddElementToTranscript("V", v) + } + + transcript.AddElementToTranscript("A", proof.A) + transcript.AddElementToTranscript("S", proof.S) y := transcript.CommitToTranscriptScalar("y") z := transcript.CommitToTranscriptScalar("z") - transcript.AddToTranscript("T1", []byte(proof.T1.String())) - transcript.AddToTranscript("T2", []byte(proof.T2.String())) + transcript.AddElementToTranscript("T_1", proof.T1) + transcript.AddElementToTranscript("T_2", proof.T2) 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) // generate h' H_ := make(core.GeneratorVector, c.max) @@ -193,7 +232,7 @@ func VerifyRangeProof(proof RangeProof, c CommitmentsParams, transcript *core.Tr x2 := new(ristretto.Scalar) 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("rhs: %v", 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)) // 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("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 } diff --git a/primitives/bulletproofs/range_proof_test.go b/primitives/bulletproofs/range_proof_test.go index cef9f9d..1144313 100644 --- a/primitives/bulletproofs/range_proof_test.go +++ b/primitives/bulletproofs/range_proof_test.go @@ -2,8 +2,11 @@ package bulletproofs import ( "cwtch.im/tapir/primitives/core" + "encoding/hex" "encoding/json" "git.openprivacy.ca/openprivacy/libricochet-go/log" + "github.com/gtank/ristretto255" + "golang.org/x/crypto/sha3" "testing" ) @@ -24,3 +27,124 @@ func TestProove(t *testing.T) { 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()) + +} diff --git a/primitives/core/transcript.go b/primitives/core/transcript.go index b84e762..d02f1c8 100644 --- a/primitives/core/transcript.go +++ b/primitives/core/transcript.go @@ -2,9 +2,9 @@ package core import ( "fmt" + "github.com/gtank/merlin" ristretto "github.com/gtank/ristretto255" "golang.org/x/crypto/sha3" - "hash" "io" ) @@ -18,15 +18,14 @@ import ( // // At some point we might want to extend this to be compatible with Merlin transcripts, built on STROBE type Transcript struct { - hash hash.Hash - transcript string + merlinTranscript *merlin.Transcript + transcript string } // NewTranscript creates a new Transcript with the given Label, the label should be unique to the application func NewTranscript(label string) *Transcript { transcript := new(Transcript) - transcript.hash = sha3.New512() - transcript.AddToTranscript("protocol", []byte(label)) + transcript.merlinTranscript = merlin.NewTranscript(label) return transcript } @@ -35,7 +34,13 @@ func NewTranscript(label string) *Transcript { func (t *Transcript) AddToTranscript(label string, b []byte) { op := fmt.Sprintf("%s (%d) %x;", label, len(b), b) 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. @@ -48,14 +53,13 @@ func (t Transcript) OutputTranscriptToAudit() string { func (t *Transcript) NewProtocol(label string) { op := fmt.Sprintf("---- new-protcol: %s ----", label) 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. func (t *Transcript) CommitToTranscript(label string) []byte { - t.AddToTranscript("commit", []byte(label)) - b := t.hash.Sum([]byte{}) - t.AddToTranscript(label, b) + //t.AddToTranscript("commit", []byte(label)) + b := t.merlinTranscript.ExtractBytes([]byte(label), 64) 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. func (t *Transcript) CommitToPRNG(label string) PRNG { - t.AddToTranscript("commit-prng", []byte(label)) - b := t.hash.Sum([]byte{}) - t.AddToTranscript(label, b) + b := t.merlinTranscript.ExtractBytes([]byte(label), 64) prng := sha3.NewShake256() prng.Write(b) return PRNG{prng: prng}