tapir/primitives/privacypass/dlogeq.go

79 lines
2.7 KiB
Go
Raw Normal View History

2019-09-14 23:44:19 +00:00
package privacypass
import (
2019-09-15 21:20:05 +00:00
"crypto/rand"
"git.openprivacy.ca/cwtch.im/tapir/primitives/core"
2019-09-15 21:20:05 +00:00
ristretto "github.com/gtank/ristretto255"
2019-09-14 23:44:19 +00:00
)
// DLEQProof encapsulates a Chaum-Pedersen DLEQ Proof
// gut In Ernest F. Brickell, editor,CRYPTO92,volume 740 ofLNCS, pages 89105. Springer, Heidelberg,August 1993
2019-09-14 23:44:19 +00:00
type DLEQProof struct {
C *ristretto.Scalar
S *ristretto.Scalar
}
// DiscreteLogEquivalenceProof constructs a valid DLEQProof for the given parameters and transcript
2019-11-26 21:10:09 +00:00
// Given Y = kX & Q = kP
2019-09-14 23:44:19 +00:00
// Peggy: t := choose randomly from Zq
//
// A := tX
// B := tP
// c := H(transcript(X,Y,P,Q,A,B))
// s := (t + ck) mod q
2019-09-14 23:44:19 +00:00
//
// Sends c,s to Vicky
2019-09-15 21:20:05 +00:00
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)
2022-08-29 03:12:14 +00:00
t, err := new(ristretto.Scalar).SetUniformBytes(private)
if err != nil {
return DLEQProof{ristretto.NewScalar(), ristretto.NewScalar()}
}
2019-09-15 21:20:05 +00:00
A := new(ristretto.Element).ScalarMult(t, X)
B := new(ristretto.Element).ScalarMult(t, P)
2019-09-14 23:44:19 +00:00
2022-08-29 03:12:14 +00:00
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())
2019-09-14 23:44:19 +00:00
c := transcript.CommitToTranscriptScalar("c")
2019-09-15 21:20:05 +00:00
s := new(ristretto.Scalar).Subtract(t, new(ristretto.Scalar).Multiply(c, k))
2019-09-14 23:44:19 +00:00
return DLEQProof{c, s}
}
// VerifyDiscreteLogEquivalenceProof verifies the DLEQ for the given parameters and transcript
2019-11-26 21:10:09 +00:00
// Given Y = kX & Q = kP and Proof = (c,s)
2019-09-14 23:44:19 +00:00
// 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'))
//
2019-09-14 23:44:19 +00:00
// Tests c ?= c
2019-09-15 21:20:05 +00:00
func VerifyDiscreteLogEquivalenceProof(dleq DLEQProof, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) bool {
2019-09-14 23:44:19 +00:00
2019-09-15 21:20:05 +00:00
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)
2019-09-14 23:44:19 +00:00
2019-09-15 21:20:05 +00:00
A := new(ristretto.Element).Add(Xs, Yc)
B := new(ristretto.Element).Add(Ps, Qc)
2019-09-14 23:44:19 +00:00
2022-08-29 03:12:14 +00:00
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())
2019-09-14 23:44:19 +00:00
2019-09-15 21:20:05 +00:00
return transcript.CommitToTranscriptScalar("c").Equal(dleq.C) == 1
2019-09-14 23:44:19 +00:00
}