Skip to content

Commit

Permalink
refactoring: avoided duplicated code in computing response to challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
aslesarenko committed Jul 30, 2023
1 parent fbac23a commit 49d1255
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import scorex.util.encode.Base16
import sigmastate.Values.SigmaBoolean
import sigmastate.basics.DLogProtocol.{ProveDlog, SecondDLogProverMessage}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.basics.{CryptoConstants, ProveDHTuple, SecondDiffieHellmanTupleProverMessage}
import sigmastate.basics.{CryptoConstants, ProveDHTuple, SecondDHTupleProverMessage}
import sigmastate.interpreter.ErgoTreeEvaluator.{fixedCostOp, perItemCostOp}
import sigmastate.interpreter.{ErgoTreeEvaluator, NamedDesc, OperationCostInfo}
import sigmastate.serialization.SigmaSerializer
Expand Down Expand Up @@ -204,7 +204,7 @@ class SigSerializer {
fixedCostOp(ParseChallenge_ProveDHT) {
val z_bytes = readBytesChecked(r, order, hex => warn(s"Invalid z bytes for $dh: $hex"))
val z = BigIntegers.fromUnsignedByteArray(z_bytes)
UncheckedDiffieHellmanTuple(dh, None, challenge, SecondDiffieHellmanTupleProverMessage(z))
UncheckedDiffieHellmanTuple(dh, None, challenge, SecondDHTupleProverMessage(z))
}

case and: CAND =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package sigmastate
import sigmastate.basics.DLogProtocol.{FirstDLogProverMessage, ProveDlog, SecondDLogProverMessage}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.Values.SigmaBoolean
import sigmastate.basics.{FirstDiffieHellmanTupleProverMessage, ProveDHTuple, SecondDiffieHellmanTupleProverMessage}
import sigmastate.basics.{FirstDHTupleProverMessage, ProveDHTuple, SecondDHTupleProverMessage}
import sigmastate.crypto.GF2_192_Poly

sealed trait UncheckedTree extends ProofTree
Expand All @@ -29,9 +29,9 @@ case class UncheckedSchnorr(

case class UncheckedDiffieHellmanTuple(
override val proposition: ProveDHTuple,
override val commitmentOpt: Option[FirstDiffieHellmanTupleProverMessage],
override val commitmentOpt: Option[FirstDHTupleProverMessage],
override val challenge: Challenge,
secondMessage: SecondDiffieHellmanTupleProverMessage
secondMessage: SecondDHTupleProverMessage
) extends UncheckedLeaf[ProveDHTuple]

case class CAndUncheckedNode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import java.math.BigInteger
import sigmastate.Values.{ErgoTree, SigmaBoolean, SigmaPropConstant}
import sigmastate.basics.DLogProtocol.{FirstDLogProverMessage, ProveDlog}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.basics.{FirstDiffieHellmanTupleProverMessage, FirstProverMessage, ProveDHTuple}
import sigmastate.basics.{FirstDHTupleProverMessage, FirstProverMessage, ProveDHTuple}
import sigmastate.interpreter.{ErgoTreeEvaluator, NamedDesc, OperationCostInfo}
import sigmastate.interpreter.ErgoTreeEvaluator.fixedCostOp
import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer
Expand Down Expand Up @@ -187,7 +187,7 @@ case class UnprovenSchnorr(override val proposition: ProveDlog,
}

case class UnprovenDiffieHellmanTuple(override val proposition: ProveDHTuple,
override val commitmentOpt: Option[FirstDiffieHellmanTupleProverMessage],
override val commitmentOpt: Option[FirstDHTupleProverMessage],
randomnessOpt: Option[BigInteger],
override val challengeOpt: Option[Challenge] = None,
override val simulated: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,7 @@ object DLogProtocol {
}

def secondMessage(privateInput: DLogProverInput, rnd: BigInteger, challenge: Challenge): SecondDLogProverMessage = {
import CryptoConstants.dlogGroup

// TODO: get rid of duplicate code
val q: BigInteger = dlogGroup.order
val e: BigInteger = new BigInteger(1, challenge.toArray)
val ew: BigInteger = e.multiply(privateInput.w).mod(q)
val z: BigInteger = rnd.add(ew).mod(q)
val z = responseToChallenge(privateInput, rnd, challenge)
SecondDLogProverMessage(z)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import special.sigma.SigmaProp


trait DiffieHellmanTupleProtocol extends SigmaProtocol[DiffieHellmanTupleProtocol] {
override type A = FirstDiffieHellmanTupleProverMessage
override type Z = SecondDiffieHellmanTupleProverMessage
override type A = FirstDHTupleProverMessage
override type Z = SecondDHTupleProverMessage
}

case class DiffieHellmanTupleProverInput(w: BigInteger, commonInput: ProveDHTuple)
Expand All @@ -41,8 +41,12 @@ object DiffieHellmanTupleProverInput {
}
}

//a = g^r, b = h^r
case class FirstDiffieHellmanTupleProverMessage(a: CryptoConstants.EcPointType, b: CryptoConstants.EcPointType)
/** 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 [[sigmastate.basics.CryptoConstants.dlogGroup]]
*/
case class FirstDHTupleProverMessage(a: EcPointType, b: EcPointType)
extends FirstProverMessage {

override type SP = DiffieHellmanTupleProtocol
Expand All @@ -52,11 +56,15 @@ case class FirstDiffieHellmanTupleProverMessage(a: CryptoConstants.EcPointType,
}
}

//z = r + ew mod q
case class SecondDiffieHellmanTupleProverMessage(z: BigInteger) extends SecondProverMessage {

/** 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 {
override type SP = DiffieHellmanTupleProtocol

}

/** Construct a new SigmaProp value representing public key of Diffie Hellman signature protocol.
Expand Down Expand Up @@ -87,33 +95,42 @@ object DiffieHellmanTupleInteractiveProver extends SigmaProtocolProver {

import CryptoConstants.dlogGroup

def firstMessage(publicInput: ProveDHTuple): (BigInteger, FirstDiffieHellmanTupleProverMessage) = {
/** 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 -> FirstDiffieHellmanTupleProverMessage(a, b)
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): SecondDiffieHellmanTupleProverMessage = {
val q: BigInteger = dlogGroup.order
val e: BigInteger = new BigInteger(1, challenge.toArray)
val ew: BigInteger = e.multiply(privateInput.w).mod(q)
val z: BigInteger = rnd.add(ew).mod(q)
SecondDiffieHellmanTupleProverMessage(z)
challenge: Challenge): SecondDHTupleProverMessage = {
val z = responseToChallenge(privateInput, rnd, challenge)
SecondDHTupleProverMessage(z)
}

def simulate(publicInput: ProveDHTuple, challenge: Challenge):
(FirstDiffieHellmanTupleProverMessage, SecondDiffieHellmanTupleProverMessage) = {
/** 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
//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)
Expand All @@ -122,7 +139,7 @@ object DiffieHellmanTupleInteractiveProver extends SigmaProtocolProver {
val vToMinusE = dlogGroup.exponentiate(publicInput.v, minusE)
val a = dlogGroup.multiplyGroupElements(gToZ, uToMinusE)
val b = dlogGroup.multiplyGroupElements(hToZ, vToMinusE)
FirstDiffieHellmanTupleProverMessage(a, b) -> SecondDiffieHellmanTupleProverMessage(z)
FirstDHTupleProverMessage(a, b) -> SecondDHTupleProverMessage(z)
}

/**
Expand All @@ -133,14 +150,14 @@ object DiffieHellmanTupleInteractiveProver extends SigmaProtocolProver {
*
* g^z = a*u^e, h^z = b*v^e => a = g^z/u^e, b = h^z/v^e
*
* @param proposition
* @param challenge
* @param secondMessage
* @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: SecondDiffieHellmanTupleProverMessage): (EcPointType, EcPointType) = {
secondMessage: SecondDHTupleProverMessage): (EcPointType, EcPointType) = {

val g = proposition.g
val h = proposition.h
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package sigmastate.basics

import sigmastate.SigmaLeaf
import sigmastate.basics.CryptoConstants.dlogGroup
import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog}
import sigmastate.basics.VerifierMessage.Challenge
import special.collection.Coll
import supertagged.TaggedType

import java.math.BigInteger

/*
Abstracting Sigma protocols
Functionality to get:
Expand Down Expand Up @@ -53,11 +58,34 @@ trait SigmaProtocol[SP <: SigmaProtocol[SP]] {


trait SigmaProtocolPrivateInput[CI <: SigmaLeaf] {
/** Public image generated from the secret.
* Represents proof of knowledge proposition.
*/
def publicImage: CI

/** Secret random number known to the prover. */
def w: BigInteger
}

trait SigmaProtocolProver {

/** Computes response for the challenge in non-interactive sigma protocol.
*
* @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 response computed by the prover
*/
protected def responseToChallenge(
privateInput: SigmaProtocolPrivateInput[_ <: SigmaLeaf],
rnd: BigInteger,
challenge: Challenge): BigInteger = {
val q: BigInteger = dlogGroup.order
val e: BigInteger = new BigInteger(1, challenge.toArray)
val ew: BigInteger = e.multiply(privateInput.w).mod(q)
val z: BigInteger = rnd.add(ew).mod(q)
z
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ trait Interpreter {
implicit val E = ErgoTreeEvaluator.getCurrentEvaluator
fixedCostOp(ComputeCommitments_DHT) {
val (a, b) = DiffieHellmanTupleInteractiveProver.computeCommitment(dh.proposition, dh.challenge, dh.secondMessage)
dh.copy(commitmentOpt = Some(FirstDiffieHellmanTupleProverMessage(a, b)))
dh.copy(commitmentOpt = Some(FirstDHTupleProverMessage(a, b)))
}

case _: UncheckedSigmaTree => ???
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ trait ProverInterpreter extends Interpreter with ProverUtils {

// Step 6 (real leaf -- compute the commitment a or take it from the hints bag)
hintsBag.commitments.find(_.position == dhu.position).map { cmtHint =>
dhu.copy(commitmentOpt = Some(cmtHint.commitment.asInstanceOf[FirstDiffieHellmanTupleProverMessage]))
dhu.copy(commitmentOpt = Some(cmtHint.commitment.asInstanceOf[FirstDHTupleProverMessage]))
}.getOrElse {
if (dhu.simulated) {
// Step 5 (simulated leaf -- complete the simulation)
Expand Down Expand Up @@ -542,7 +542,7 @@ trait ProverInterpreter extends Interpreter with ProverUtils {
provenSchnorr.secondMessage
}.getOrElse {
val bs = secureRandomBytes(32)
SecondDiffieHellmanTupleProverMessage(new BigInteger(1, bs).mod(CryptoConstants.groupOrder))
SecondDHTupleProverMessage(new BigInteger(1, bs).mod(CryptoConstants.groupOrder))
}
}
UncheckedDiffieHellmanTuple(dhu.proposition, None, dhu.challengeOpt.get, z)
Expand Down
2 changes: 1 addition & 1 deletion interpreter/shared/src/main/scala/sigmastate/trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ trait SigmaConjecture extends SigmaBoolean {
}

/**
* Basic trait for leafs of crypto-trees, such as ProveDlog and ProveDiffieHellman instances
* Basic trait for leafs of crypto-trees, such as [[sigmastate.basics.DLogProtocol.ProveDlog]] and [[sigmastate.basics.ProveDHTuple]] instances
*/
trait SigmaLeaf extends SigmaBoolean

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import sigmastate.Values.SigmaBoolean
import sigmastate._
import sigmastate.basics.DLogProtocol.{ProveDlog, SecondDLogProverMessage}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.basics.{ProveDHTuple, SecondDiffieHellmanTupleProverMessage}
import sigmastate.basics.{ProveDHTuple, SecondDHTupleProverMessage}
import sigmastate.crypto.GF2_192_Poly
import sigmastate.eval.Extensions.ArrayOps
import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTransactionTesting, TestingCommons}
Expand Down Expand Up @@ -173,7 +173,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("9ec740b57353cb2f6035bb1a481b0066b2fdc0406a6fa67e").toColl,
SecondDiffieHellmanTupleProverMessage(
SecondDHTupleProverMessage(
new BigInteger("bb2e6f44a38052b3f564fafcd477c4eb8cda1a8a553a4a5f38f1e1084d6a69f0", 16)
)
),
Expand Down Expand Up @@ -306,7 +306,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("ffd3149193b042fda134c0e208fefcb791379959ac6fc731").toColl,
SecondDiffieHellmanTupleProverMessage(new BigInteger("adf47e32000fc75e2923dba482c843c7f6b684cbf2ceec5bfdf5fe6d13cabe5d", 16))
SecondDHTupleProverMessage(new BigInteger("adf47e32000fc75e2923dba482c843c7f6b684cbf2ceec5bfdf5fe6d13cabe5d", 16))
),
COrUncheckedNode(
Challenge @@ ErgoAlgos.decodeUnsafe("697ecb4c5fa939260dc100f6274f908ea97cafc056281d4c").toColl,
Expand All @@ -326,7 +326,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("7c86e210fb413069b7fd47e09890534acb3dd5b9f037d104").toColl,
SecondDiffieHellmanTupleProverMessage(new BigInteger("dd97c3bd2fe40ecdbbda6f43bf71240da8dac878c044c16d42a4b34c536bbb1b", 16))
SecondDHTupleProverMessage(new BigInteger("dd97c3bd2fe40ecdbbda6f43bf71240da8dac878c044c16d42a4b34c536bbb1b", 16))
)
)
)
Expand Down Expand Up @@ -390,7 +390,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("ff8b9c2a4eed345a11c697f6850cf3a38763d738539ad2d2").toColl,
SecondDiffieHellmanTupleProverMessage(new BigInteger("140fc95e28775cde52e71bb4d7b5ee2564553fac5b52202530fcbcdf205b7cca", 16))
SecondDHTupleProverMessage(new BigInteger("140fc95e28775cde52e71bb4d7b5ee2564553fac5b52202530fcbcdf205b7cca", 16))
)
)
),
Expand All @@ -406,7 +406,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("145202fb2a5bb181a890eb15536b08b747ea163f6b5d32a1").toColl,
SecondDiffieHellmanTupleProverMessage(new BigInteger("16fa9e1eb6b348fd82d3ebc11c125e5bc3f09c499aa0a8db14dc1780b4181f9b", 16))
SecondDHTupleProverMessage(new BigInteger("16fa9e1eb6b348fd82d3ebc11c125e5bc3f09c499aa0a8db14dc1780b4181f9b", 16))
),
UncheckedDiffieHellmanTuple(
ProveDHTuple(
Expand All @@ -417,7 +417,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("a405e8a07b6ec105b167a40ad8dd02d2e298bb0113e86b10").toColl,
SecondDiffieHellmanTupleProverMessage(new BigInteger("ae5ed0f743f71b82b18784380814507d810cbef61ebc0b30e7f324083e2d3d08", 16))
SecondDHTupleProverMessage(new BigInteger("ae5ed0f743f71b82b18784380814507d810cbef61ebc0b30e7f324083e2d3d08", 16))
)
)
)
Expand Down Expand Up @@ -465,7 +465,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("5735f4df1b280e1d423a8f28977057af8c52123c9a3fe96d").toColl,
SecondDiffieHellmanTupleProverMessage(new BigInteger("da857dd649d3228a8c359ac499d430ecada3f92d5206cddeffb16248068c1003", 16))
SecondDHTupleProverMessage(new BigInteger("da857dd649d3228a8c359ac499d430ecada3f92d5206cddeffb16248068c1003", 16))
),
UncheckedDiffieHellmanTuple(
ProveDHTuple(
Expand All @@ -476,7 +476,7 @@ class SigSerializerSpecification extends TestingCommons
),
None,
Challenge @@ ErgoAlgos.decodeUnsafe("980cc5d167b847dc8baceeb02fa66d8095bb9a7f22249d54").toColl,
SecondDiffieHellmanTupleProverMessage(new BigInteger("477d717e04afbf206c87a59ce5263ee7cc4020b5772d91b1df00bd72b15347fd", 16))
SecondDHTupleProverMessage(new BigInteger("477d717e04afbf206c87a59ce5263ee7cc4020b5772d91b1df00bd72b15347fd", 16))
)
),
2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import scorex.crypto.hash.Blake2b256
import sigmastate.Values.SigmaBoolean
import sigmastate._
import sigmastate.basics.DLogProtocol.FirstDLogProverMessage
import sigmastate.basics.{FirstDiffieHellmanTupleProverMessage, SecP256K1Group}
import sigmastate.basics.{FirstDHTupleProverMessage, SecP256K1Group}
import sigmastate.exceptions.InterpreterException
import sigmastate.helpers.{ErgoLikeTestProvingInterpreter, TestingCommons}
import sigmastate.interpreter.{HintsBag, ProverInterpreter}
Expand Down Expand Up @@ -52,7 +52,7 @@ class ProverSpecification extends TestingCommons {

h3.realCommitments.head.commitment shouldBe h3.ownCommitments.head.commitment

h3.realCommitments.head.commitment.isInstanceOf[FirstDiffieHellmanTupleProverMessage] shouldBe true
h3.realCommitments.head.commitment.isInstanceOf[FirstDHTupleProverMessage] shouldBe true
}

property("setPositions - and") {
Expand Down

0 comments on commit 49d1255

Please sign in to comment.