package privacypass import ( "crypto/rand" "git.openprivacy.ca/cwtch.im/tapir/primitives/core" ristretto "github.com/gtank/ristretto255" ) // DLEQProof encapsulates a Chaum-Pedersen DLEQ Proof // gut In Ernest F. Brickell, editor,CRYPTO’92,volume 740 ofLNCS, pages 89–105. Springer, Heidelberg,August 1993 type DLEQProof struct { C *ristretto.Scalar S *ristretto.Scalar } // DiscreteLogEquivalenceProof constructs a valid DLEQProof for the given parameters and transcript // Given Y = kX & Q = kP // Peggy: t := choose randomly from Zq // // A := tX // B := tP // c := H(transcript(X,Y,P,Q,A,B)) // s := (t + ck) mod q // // Sends c,s to Vicky func DiscreteLogEquivalenceProof(k *ristretto.Scalar, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) DLEQProof { private := make([]byte, 64) rand.Read(private) t, err := new(ristretto.Scalar).SetUniformBytes(private) if err != nil { return DLEQProof{ristretto.NewScalar(), ristretto.NewScalar()} } A := new(ristretto.Element).ScalarMult(t, X) B := new(ristretto.Element).ScalarMult(t, P) transcript.AddToTranscript(DLEQX, X.Bytes()) transcript.AddToTranscript(DLEQY, Y.Bytes()) transcript.AddToTranscript(DLEQP, P.Bytes()) transcript.AddToTranscript(DLEQQ, Q.Bytes()) transcript.AddToTranscript(DLEQA, A.Bytes()) transcript.AddToTranscript(DLEQB, B.Bytes()) c := transcript.CommitToTranscriptScalar("c") s := new(ristretto.Scalar).Subtract(t, new(ristretto.Scalar).Multiply(c, k)) return DLEQProof{c, s} } // VerifyDiscreteLogEquivalenceProof verifies the DLEQ for the given parameters and transcript // Given Y = kX & Q = kP and Proof = (c,s) // Vicky: X' := sX // // Y' := cY // P' := sP // Q' := cQ // A' = X'+Y' == sX + cY ?= sG + ckG == (s+ck)X == tX == A // B' = P'+Q' == sP + cQ ?= sP + ckP == (s+ck)P == tP == B // c' := H(transcript(X,Y,P,Q,A',B')) // // Tests c ?= c func VerifyDiscreteLogEquivalenceProof(dleq DLEQProof, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) bool { Xs := new(ristretto.Element).ScalarMult(dleq.S, X) Yc := new(ristretto.Element).ScalarMult(dleq.C, Y) Ps := new(ristretto.Element).ScalarMult(dleq.S, P) Qc := new(ristretto.Element).ScalarMult(dleq.C, Q) A := new(ristretto.Element).Add(Xs, Yc) B := new(ristretto.Element).Add(Ps, Qc) transcript.AddToTranscript(DLEQX, X.Bytes()) transcript.AddToTranscript(DLEQY, Y.Bytes()) transcript.AddToTranscript(DLEQP, P.Bytes()) transcript.AddToTranscript(DLEQQ, Q.Bytes()) transcript.AddToTranscript(DLEQA, A.Bytes()) transcript.AddToTranscript(DLEQB, B.Bytes()) return transcript.CommitToTranscriptScalar("c").Equal(dleq.C) == 1 }