sigmastate.crypto.DiffieHellmanTupleProtocol.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sigma-state_2.12 Show documentation
Show all versions of sigma-state_2.12 Show documentation
Interpreter of a Sigma-State language
The newest version!
package sigmastate.crypto
import sigma.crypto.{BigIntegers, CryptoConstants, EcPointType}
import sigma.data.ProveDHTuple
import sigma.serialization.GroupElementSerializer
import sigmastate.crypto.VerifierMessage.Challenge
import java.math.BigInteger
case class DiffieHellmanTupleProverInput(w: BigInteger, commonInput: ProveDHTuple)
extends SigmaProtocolPrivateInput[ProveDHTuple] {
override lazy val publicImage: ProveDHTuple = commonInput
}
object DiffieHellmanTupleProverInput {
import CryptoConstants.dlogGroup
def random(): DiffieHellmanTupleProverInput = {
val g = dlogGroup.generator
val h = dlogGroup.createRandomGenerator()
val qMinusOne = dlogGroup.order.subtract(BigInteger.ONE)
val w = BigIntegers.createRandomInRange(BigInteger.ZERO, qMinusOne, dlogGroup.secureRandom)
val u = dlogGroup.exponentiate(g, w)
val v = dlogGroup.exponentiate(h, w)
val ci = ProveDHTuple(g, h, u, v)
DiffieHellmanTupleProverInput(w, ci)
}
}
/** First message of Diffie Hellman tuple sigma protocol.
* @param a commitment to secret randomness `a = g^r`, where `g` is default generator of the group
* @param b commitment to secret randomness `b = h^r`, where `h` is another random generator of the group
* @see createRandomGenerator in [[CryptoConstants.dlogGroup]]
*/
case class FirstDHTupleProverMessage(a: EcPointType, b: EcPointType)
extends FirstProverMessage {
override def bytes: Array[Byte] = {
GroupElementSerializer.toBytes(a) ++ GroupElementSerializer.toBytes(b)
}
}
/** Represents a response for challenge in Diffie Hellman tuple sigma protocol.
* @param z responce to the challenge computed as `(r + ew) mod q`, where
* `r` is the prover's randomness,
* `e` challenge from the verifier (also computed by the prover in non-interactive case),
* `w` is the prover's secret.
* `q` is the group order
*/
case class SecondDHTupleProverMessage(z: BigInteger) extends SecondProverMessage
object DiffieHellmanTupleProver extends SigmaProtocolProver {
import CryptoConstants.dlogGroup
/** Create a commitment to randomness r and a first message of sigma protocol. */
def firstMessage(publicInput: ProveDHTuple): (BigInteger, FirstDHTupleProverMessage) = {
val qMinusOne = dlogGroup.order.subtract(BigInteger.ONE)
val r = BigIntegers.createRandomInRange(BigInteger.ZERO, qMinusOne, dlogGroup.secureRandom)
val a = dlogGroup.exponentiate(publicInput.g, r)
val b = dlogGroup.exponentiate(publicInput.h, r)
r -> FirstDHTupleProverMessage(a, b)
}
/** Creates second message of sigma protocol, which is a response for the challenge from the verifier.
*
* @param privateInput private input of the prover (secret)
* @param rnd random number generated by the prover (secret random number used to
* compute commitment)
* @param challenge challenge from the verifier (also computed by the prover in non-interactive case)
* @return second message from the prover
*/
def secondMessage(privateInput: DiffieHellmanTupleProverInput,
rnd: BigInteger,
challenge: Challenge): SecondDHTupleProverMessage = {
val z = responseToChallenge(privateInput, rnd, challenge)
SecondDHTupleProverMessage(z)
}
/** Simulates messages of the sigma protocol which are indistinquishable from generated
* by the real prover. */
def simulate(publicInput: ProveDHTuple, challenge: Challenge): (FirstDHTupleProverMessage, SecondDHTupleProverMessage) = {
val qMinusOne = dlogGroup.order.subtract(BigInteger.ONE)
//SAMPLE a random z <- Zq, this will be the simulated response to the challenge
val z = BigIntegers.createRandomInRange(BigInteger.ZERO, qMinusOne, dlogGroup.secureRandom)
// COMPUTE a = g^z*u^(-e) and b = h^z*v^{-e} (where -e here means -e mod q)
// in real prover we compute commitments from random number and them compute response to the challenge,
// but here we do in opposite direction, use random response and compute commitments from it
val e: BigInteger = new BigInteger(1, challenge.toArray)
val minusE = dlogGroup.order.subtract(e)
val hToZ = dlogGroup.exponentiate(publicInput.h, z)
val gToZ = dlogGroup.exponentiate(publicInput.g, z)
val uToMinusE = dlogGroup.exponentiate(publicInput.u, minusE)
val vToMinusE = dlogGroup.exponentiate(publicInput.v, minusE)
val a = dlogGroup.multiplyGroupElements(gToZ, uToMinusE)
val b = dlogGroup.multiplyGroupElements(hToZ, vToMinusE)
FirstDHTupleProverMessage(a, b) -> SecondDHTupleProverMessage(z)
}
/**
* The function computes initial prover's commitment to randomness
* ("a" message of the sigma-protocol, which in this case has two parts "a" and "b")
* based on the verifier's challenge ("e")
* and prover's response ("z")
*
* g^z = a*u^e, h^z = b*v^e => a = g^z/u^e, b = h^z/v^e
*
* @param proposition proposition "I know DH tuple"
* @param challenge challenge from verifier
* @param secondMessage prover's response to the challenge
* @return
*/
def computeCommitment(proposition: ProveDHTuple,
challenge: Challenge,
secondMessage: SecondDHTupleProverMessage): (EcPointType, EcPointType) = {
val g = proposition.g
val h = proposition.h
val u = proposition.u
val v = proposition.v
val z = secondMessage.z
val e = new BigInteger(1, challenge.toArray)
val gToZ = dlogGroup.exponentiate(g, z)
val hToZ = dlogGroup.exponentiate(h, z)
val uToE = dlogGroup.exponentiate(u, e)
val vToE = dlogGroup.exponentiate(v, e)
val a = dlogGroup.multiplyGroupElements(gToZ, dlogGroup.inverseOf(uToE))
val b = dlogGroup.multiplyGroupElements(hToZ, dlogGroup.inverseOf(vToE))
a -> b
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy