Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/refactoring' into multisig
Browse files Browse the repository at this point in the history
# Conflicts:
#	sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala
  • Loading branch information
aslesarenko committed Jul 30, 2023
2 parents 3ee7f68 + 49d1255 commit 7798f6c
Show file tree
Hide file tree
Showing 24 changed files with 241 additions and 243 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class WOptionCls extends EntityObject("WOption") {
case class WOptionAdapter[A](source: Ref[WOption[A]])
extends Node with WOption[A]
with Def[WOption[A]] {
implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]
implicit lazy val eA: Elem[A] = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]

val resultType: Elem[WOption[A]] = element[WOption[A]]
override def transform(t: Transformer) = WOptionAdapter[A](t(source))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class WRTypeCls extends EntityObject("WRType") {
case class WRTypeAdapter[A](source: Ref[WRType[A]])
extends Node with WRType[A]
with Def[WRType[A]] {
implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]
implicit lazy val eA: Elem[A] = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]

val resultType: Elem[WRType[A]] = element[WRType[A]]
override def transform(t: Transformer) = WRTypeAdapter[A](t(source))
Expand Down
19 changes: 10 additions & 9 deletions interpreter/shared/src/main/scala/sigmastate/SigSerializer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import scorex.util.encode.Base16
import sigmastate.Values.SigmaBoolean
import sigmastate.basics.DLogProtocol.{ProveDlog, SecondDLogProverMessage}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.basics.{SecondDiffieHellmanTupleProverMessage, ProveDHTuple, CryptoConstants}
import sigmastate.basics.{CryptoConstants, ProveDHTuple, SecondDHTupleProverMessage}
import sigmastate.interpreter.ErgoTreeEvaluator.{fixedCostOp, perItemCostOp}
import sigmastate.interpreter.{ErgoTreeEvaluator, NamedDesc, OperationCostInfo}
import sigmastate.serialization.SigmaSerializer
import sigmastate.util.safeNewArray
import sigmastate.utils.{Helpers, SigmaByteReader, SigmaByteWriter}
import debox.cfor
import sigmastate.eval.Extensions.ArrayOps
import sigmastate.exceptions.SerializerException

/** Contains implementation of signature (aka proof) serialization.
Expand Down Expand Up @@ -61,7 +62,7 @@ class SigSerializer {
w: SigmaByteWriter,
writeChallenge: Boolean): Unit = {
if (writeChallenge) {
w.putBytes(node.challenge)
w.putBytes(node.challenge.toArray)
}
node match {
case dl: UncheckedSchnorr =>
Expand Down Expand Up @@ -184,7 +185,7 @@ class SigSerializer {
// Verifier Step 2: Let e_0 be the challenge in the node here (e_0 is called "challenge" in the code)
val challenge = if (challengeOpt == null) {
Challenge @@ readBytesChecked(r, hashSize,
hex => warn(s"Invalid challenge in: $hex"))
hex => warn(s"Invalid challenge in: $hex")).toColl
} else {
challengeOpt
}
Expand All @@ -203,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 All @@ -223,18 +224,18 @@ class SigSerializer {
// Read all the children but the last and compute the XOR of all the challenges including e_0
val nChildren = or.children.length
val children = safeNewArray[UncheckedSigmaTree](nChildren)
val xorBuf = challenge.clone()
val xorBuf = challenge.toArray.clone()
val iLastChild = nChildren - 1
cfor(0)(_ < iLastChild, _ + 1) { i =>
val parsedChild = parseAndComputeChallenges(or.children(i), r, null)
children(i) = parsedChild
Helpers.xorU(xorBuf, parsedChild.challenge) // xor it into buffer
Helpers.xorU(xorBuf, parsedChild.challenge.toArray) // xor it into buffer
}
val lastChild = or.children(iLastChild)

// use the computed XOR for last child's challenge
children(iLastChild) = parseAndComputeChallenges(
lastChild, r, challengeOpt = Challenge @@ xorBuf)
lastChild, r, challengeOpt = Challenge @@ xorBuf.toColl)

COrUncheckedNode(challenge, children)

Expand All @@ -248,13 +249,13 @@ class SigSerializer {
val polynomial = perItemCostOp(ParsePolynomial, nCoefs) { () =>
val coeffBytes = readBytesChecked(r, hashSize * nCoefs,
hex => warn(s"Invalid coeffBytes for $th: $hex"))
GF2_192_Poly.fromByteArray(challenge, coeffBytes)
GF2_192_Poly.fromByteArray(challenge.toArray, coeffBytes)
}

val children = safeNewArray[UncheckedSigmaTree](nChildren)
cfor(0)(_ < nChildren, _ + 1) { i =>
val c = perItemCostOp(EvaluatePolynomial, nCoefs) { () =>
Challenge @@ polynomial.evaluate((i + 1).toByte).toByteArray
Challenge @@ polynomial.evaluate((i + 1).toByte).toByteArray.toColl
}
children(i) = parseAndComputeChallenges(th.children(i), r, c)
}
Expand Down
119 changes: 26 additions & 93 deletions interpreter/shared/src/main/scala/sigmastate/UncheckedTree.scala
Original file line number Diff line number Diff line change
@@ -1,125 +1,58 @@
package sigmastate

import java.util.Arrays
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

case object NoProof extends UncheckedTree

sealed trait UncheckedSigmaTree extends UncheckedTree {
val challenge: Array[Byte]
val challenge: Challenge
}

trait UncheckedConjecture extends UncheckedSigmaTree with ProofTreeConjecture {

override def equals(obj: Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj match {
case x: UncheckedConjecture =>
Arrays.equals(challenge, x.challenge) && children == x.children
case _ => false
})

override def hashCode(): Int =
31 * Arrays.hashCode(challenge) + children.hashCode()
}
trait UncheckedConjecture extends UncheckedSigmaTree with ProofTreeConjecture

trait UncheckedLeaf[SP <: SigmaBoolean] extends UncheckedSigmaTree with ProofTreeLeaf {
val proposition: SigmaBoolean
}

case class UncheckedSchnorr(override val proposition: ProveDlog,
override val commitmentOpt: Option[FirstDLogProverMessage],
override val challenge: Challenge,
secondMessage: SecondDLogProverMessage)
extends UncheckedLeaf[ProveDlog] {
case class UncheckedSchnorr(
override val proposition: ProveDlog,
override val commitmentOpt: Option[FirstDLogProverMessage],
override val challenge: Challenge,
secondMessage: SecondDLogProverMessage
) extends UncheckedLeaf[ProveDlog]

override def equals(obj: Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj match {
case x: UncheckedSchnorr =>
// NOTE, proposition is not compared because it is included into challenge
// like `challenge = hash(prop ++ msg)`
commitmentOpt == x.commitmentOpt &&
Arrays.equals(challenge, x.challenge) &&
secondMessage == x.secondMessage
case _ => false
})

override def hashCode(): Int = {
var h = commitmentOpt.hashCode()
h = 31 * h + Arrays.hashCode(challenge)
h = 31 * h + secondMessage.hashCode()
h
}
}


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

override def equals(obj: Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj match {
case x: UncheckedDiffieHellmanTuple =>
// NOTE, proposition is not compared because it is included into challenge
// like `challenge = hash(prop ++ msg)`
commitmentOpt == x.commitmentOpt &&
Arrays.equals(challenge, x.challenge) &&
secondMessage == x.secondMessage
case _ => false
})

override def hashCode(): Int = {
var h = commitmentOpt.hashCode()
h = 31 * h + Arrays.hashCode(challenge)
h = 31 * h + secondMessage.hashCode()
h
}
}

case class CAndUncheckedNode(override val challenge: Challenge,
override val children: Seq[UncheckedSigmaTree])
extends UncheckedConjecture {
case class UncheckedDiffieHellmanTuple(
override val proposition: ProveDHTuple,
override val commitmentOpt: Option[FirstDHTupleProverMessage],
override val challenge: Challenge,
secondMessage: SecondDHTupleProverMessage
) extends UncheckedLeaf[ProveDHTuple]

case class CAndUncheckedNode(
override val challenge: Challenge,
override val children: Seq[UncheckedSigmaTree]) extends UncheckedConjecture {
override val conjectureType = ConjectureType.AndConjecture
}


case class COrUncheckedNode(override val challenge: Challenge,
override val children: Seq[UncheckedSigmaTree]) extends UncheckedConjecture {

case class COrUncheckedNode(
override val challenge: Challenge,
override val children: Seq[UncheckedSigmaTree]) extends UncheckedConjecture {
override val conjectureType = ConjectureType.OrConjecture

}

case class CThresholdUncheckedNode(override val challenge: Challenge,
override val children: Seq[UncheckedSigmaTree],
k: Integer,
polynomialOpt: Option[GF2_192_Poly]) extends UncheckedConjecture {
case class CThresholdUncheckedNode(
override val challenge: Challenge,
override val children: Seq[UncheckedSigmaTree],
k: Integer,
polynomialOpt: Option[GF2_192_Poly]) extends UncheckedConjecture {
require(children.length <= 255) // Our polynomial arithmetic can take only byte inputs
require(k >= 0 && k <= children.length)

override val conjectureType = ConjectureType.ThresholdConjecture

override def canEqual(other: Any) = other.isInstanceOf[CThresholdUncheckedNode]

override def equals(other: Any) = (this eq other.asInstanceOf[AnyRef]) || (other match {
case other: CThresholdUncheckedNode =>
Arrays.equals(challenge, other.challenge) &&
children == other.children &&
k == other.k &&
polynomialOpt == other.polynomialOpt
case _ => false
})

override def hashCode(): Int = {
var h = Arrays.hashCode(challenge)
h = 31 * h + children.hashCode
h = 31 * h + k.hashCode()
h = 31 * h + polynomialOpt.hashCode()
h
}
}
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 @@ -61,7 +61,7 @@ sealed trait UnprovenTree extends ProofTree {
/**
* Challenge used by the prover.
*/
val challengeOpt: Option[Array[Byte]]
val challengeOpt: Option[Challenge]

def withChallenge(challenge: Challenge): UnprovenTree

Expand Down Expand Up @@ -146,7 +146,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 @@ -78,7 +78,7 @@ object DLogProtocol {
}


object DLogInteractiveProver {
object DLogInteractiveProver extends SigmaProtocolProver {
import CryptoConstants.secureRandom

def firstMessage(): (BigInteger, FirstDLogProverMessage) = {
Expand All @@ -91,12 +91,7 @@ object DLogProtocol {
}

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

val q: BigInteger = dlogGroup.order
val e: BigInteger = new BigInteger(1, challenge)
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 All @@ -108,7 +103,7 @@ object DLogProtocol {
val z = BigIntegers.createRandomInRange(BigInteger.ZERO, qMinusOne, secureRandom)

//COMPUTE a = g^z*h^(-e) (where -e here means -e mod q)
val e: BigInteger = new BigInteger(1, challenge)
val e: BigInteger = new BigInteger(1, challenge.toArray)
val minusE = dlogGroup.order.subtract(e)
val hToE = dlogGroup.exponentiate(publicInput.value, minusE)
val gToZ = dlogGroup.exponentiate(dlogGroup.generator, z)
Expand Down Expand Up @@ -136,7 +131,7 @@ object DLogProtocol {

dlogGroup.multiplyGroupElements(
dlogGroup.exponentiate(g, secondMessage.z.underlying()),
dlogGroup.inverseOf(dlogGroup.exponentiate(h, new BigInteger(1, challenge))))
dlogGroup.inverseOf(dlogGroup.exponentiate(h, new BigInteger(1, challenge.toArray))))
}
}

Expand Down
Loading

0 comments on commit 7798f6c

Please sign in to comment.