forked from cwtch.im/tapir
72 lines
2.0 KiB
Go
72 lines
2.0 KiB
Go
package primitives
|
|
|
|
import (
|
|
"cwtch.im/tapir/primitives/core"
|
|
"github.com/bwesterb/go-ristretto"
|
|
)
|
|
|
|
// DLProof Encapsulates a Discrete Log / Schnorr Proof
|
|
// Note that these parameters are read-only.
|
|
type DLProof struct {
|
|
V, A ristretto.Point
|
|
R ristretto.Scalar
|
|
}
|
|
|
|
// DiscreteLogProof - Proof of Knowledge of Exponent
|
|
// Given V = xG
|
|
// Peggy: z := choose randomly from Zq
|
|
// A := zG
|
|
// c := H(transcript(G,V,A)) mod q
|
|
// r := (z + cx) mod q
|
|
//
|
|
// Sends A,r,V to Vicky
|
|
func DiscreteLogProof(x ristretto.Scalar, v ristretto.Point, transcript *core.Transcript) (proof DLProof) {
|
|
|
|
transcript.AddToTranscript("G", new(ristretto.Point).SetBase().Bytes())
|
|
|
|
// We bind the proof to our public V
|
|
proof.V = v
|
|
transcript.AddToTranscript("V", proof.V.Bytes())
|
|
|
|
// Generate a random z
|
|
// A := zG
|
|
z := new(ristretto.Scalar).Rand()
|
|
proof.A = *new(ristretto.Point).ScalarMultBase(z)
|
|
transcript.AddToTranscript("A", proof.A.Bytes())
|
|
|
|
// Derive Challenge
|
|
c := transcript.CommitToTranscriptScalar("c")
|
|
|
|
// r := (z + cx) mod p
|
|
cx := new(ristretto.Scalar).Mul(c, &x)
|
|
proof.R = *new(ristretto.Scalar).Add(z, cx)
|
|
|
|
return
|
|
}
|
|
|
|
// VerifyDiscreteLogProof validates a given Schnorr Proof
|
|
// Vicky gets A,r,V from Peggy
|
|
// Vicky computes c := H(transcript(G,V,A)) mod q
|
|
// Vicky checks rG := A + cV
|
|
// rG ?= zG + cV
|
|
// (z+cx)G ?= zG + cV
|
|
// ?= zG + cxG
|
|
// Thus demonstrating that Peggy knows the discrete log to V
|
|
func VerifyDiscreteLogProof(proof DLProof, transcript *core.Transcript) bool {
|
|
|
|
transcript.AddToTranscript("G", new(ristretto.Point).SetBase().Bytes())
|
|
transcript.AddToTranscript("V", proof.V.Bytes())
|
|
transcript.AddToTranscript("A", proof.A.Bytes())
|
|
c := transcript.CommitToTranscriptScalar("c")
|
|
|
|
// Compute left hand side
|
|
lhs := new(ristretto.Point).ScalarMultBase(&proof.R)
|
|
|
|
// Compute right hand side
|
|
cV := new(ristretto.Point).ScalarMult(&proof.V, c)
|
|
rhs := new(ristretto.Point).Add(&proof.A, cV)
|
|
|
|
// Result of verification: lhs ?= rhs
|
|
return lhs.Equals(rhs)
|
|
}
|