74 lines
2.7 KiB
Go
74 lines
2.7 KiB
Go
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 := new(ristretto.Scalar)
|
||
t.FromUniformBytes(private)
|
||
A := new(ristretto.Element).ScalarMult(t, X)
|
||
B := new(ristretto.Element).ScalarMult(t, P)
|
||
|
||
transcript.AddToTranscript(DLEQX, X.Encode(nil))
|
||
transcript.AddToTranscript(DLEQY, Y.Encode(nil))
|
||
transcript.AddToTranscript(DLEQP, P.Encode(nil))
|
||
transcript.AddToTranscript(DLEQQ, Q.Encode(nil))
|
||
transcript.AddToTranscript(DLEQA, A.Encode(nil))
|
||
transcript.AddToTranscript(DLEQB, B.Encode(nil))
|
||
|
||
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.Encode(nil))
|
||
transcript.AddToTranscript(DLEQY, Y.Encode(nil))
|
||
transcript.AddToTranscript(DLEQP, P.Encode(nil))
|
||
transcript.AddToTranscript(DLEQQ, Q.Encode(nil))
|
||
transcript.AddToTranscript(DLEQA, A.Encode(nil))
|
||
transcript.AddToTranscript(DLEQB, B.Encode(nil))
|
||
|
||
return transcript.CommitToTranscriptScalar("c").Equal(dleq.C) == 1
|
||
}
|