Skip to content

Commit

Permalink
expUnsigned impl (test still failing)
Browse files Browse the repository at this point in the history
  • Loading branch information
kushti committed Jun 8, 2024
1 parent 15f4f67 commit 303f969
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 7 deletions.
2 changes: 2 additions & 0 deletions core/shared/src/main/scala/sigma/SigmaDsl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ trait GroupElement {
*/
def exp(k: BigInt): GroupElement

def expUnsigned(k: UnsignedBigInt): GroupElement

/** Group operation. */
def multiply(that: GroupElement): GroupElement

Expand Down
5 changes: 4 additions & 1 deletion core/shared/src/main/scala/sigma/data/CGroupElement.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package sigma.data
import sigma.crypto.{CryptoFacade, Ecp}
import sigma.serialization.GroupElementSerializer
import sigma.util.Extensions.EcpOps
import sigma.{BigInt, Coll, Colls, GroupElement}
import sigma.{BigInt, Coll, Colls, GroupElement, UnsignedBigInt}

/** A default implementation of [[GroupElement]] interface.
*
Expand All @@ -21,6 +21,9 @@ case class CGroupElement(override val wrappedValue: Ecp) extends GroupElement wi
override def exp(k: BigInt): GroupElement =
CGroupElement(CryptoFacade.exponentiatePoint(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue))

override def expUnsigned(k: UnsignedBigInt): GroupElement =
CGroupElement(CryptoFacade.exponentiatePoint(wrappedValue, k.asInstanceOf[CUnsignedBigInt].wrappedValue))

override def multiply(that: GroupElement): GroupElement =
CGroupElement(CryptoFacade.multiplyPoints(wrappedValue, that.asInstanceOf[CGroupElement].wrappedValue))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ object ReflectionData {
mkMethod(clazz, "exp", Array[Class[_]](classOf[BigInt])) { (obj, args) =>
obj.asInstanceOf[GroupElement].exp(args(0).asInstanceOf[BigInt])
},
mkMethod(clazz, "expUnsigned", Array[Class[_]](classOf[UnsignedBigInt])) { (obj, args) =>
obj.asInstanceOf[GroupElement].expUnsigned(args(0).asInstanceOf[UnsignedBigInt])
},
mkMethod(clazz, "multiply", Array[Class[_]](classOf[GroupElement])) { (obj, args) =>
obj.asInstanceOf[GroupElement].multiply(args(0).asInstanceOf[GroupElement])
},
Expand Down
28 changes: 22 additions & 6 deletions data/shared/src/main/scala/sigma/ast/methods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,11 @@ case object SGroupElementMethods extends MonoTypeMethods {
"Exponentiate this \\lst{GroupElement} to the given number. Returns this to the power of k",
ArgInfo("k", "The power"))

lazy val ExponentiateUnsignedMethod: SMethod = SMethod(
this, "expUnsigned", SFunc(Array(this.ownerType, SUnsignedBigInt), this.ownerType), 6, Exponentiate.costKind) // todo: recheck costing
.withInfo("Exponentiate this \\lst{GroupElement} to the given number. Returns this to the power of k",
ArgInfo("k", "The power"))

lazy val MultiplyMethod: SMethod = SMethod(
this, "multiply", SFunc(Array(this.ownerType, SGroupElement), this.ownerType), 4, MultiplyGroup.costKind)
.withIRInfo({ case (builder, obj, _, Seq(arg), _) =>
Expand All @@ -379,16 +384,27 @@ case object SGroupElementMethods extends MonoTypeMethods {
.withIRInfo(MethodCallIrBuilder)
.withInfo(PropertyCall, "Inverse element of the group.")

protected override def getMethods(): Seq[SMethod] = super.getMethods() ++ Seq(
protected override def getMethods(): Seq[SMethod] = {
/* TODO soft-fork: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479
SMethod(this, "isIdentity", SFunc(this, SBoolean), 1)
.withInfo(PropertyCall, "Checks if this value is identity element of the eliptic curve group."),
*/
GetEncodedMethod,
ExponentiateMethod,
MultiplyMethod,
NegateMethod
)
val v5Methods = Seq(
GetEncodedMethod,
ExponentiateMethod,
MultiplyMethod,
NegateMethod)

super.getMethods() ++ (if (VersionContext.current.isV6SoftForkActivated) {
v5Methods
} else {
v5Methods ++ Seq(ExponentiateUnsignedMethod)
})
}

def expUnsigned_eval(mc: MethodCall, power: UnsignedBigInt)(implicit E: ErgoTreeEvaluator): GroupElement = {
???
}
}

/** Methods of type `SigmaProp` which represent sigma-protocol propositions. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,9 @@ trait GraphBuilding extends Base with DefRewriting { IR: IRContext =>
case SGroupElementMethods.ExponentiateMethod.name =>
val k = asRep[BigInt](argsV(0))
ge.exp(k)
case SGroupElementMethods.ExponentiateUnsignedMethod.name =>
val k = asRep[UnsignedBigInt](argsV(0))
ge.expUnsigned(k)
case _ => throwError
}
case (box: Ref[Box]@unchecked, SBoxMethods) => method.name match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import scalan._
};
trait GroupElement extends Def[GroupElement] {
def exp(k: Ref[BigInt]): Ref[GroupElement];
def expUnsigned(k: Ref[UnsignedBigInt]): Ref[GroupElement];
def multiply(that: Ref[GroupElement]): Ref[GroupElement];
def negate: Ref[GroupElement];
def getEncoded: Ref[Coll[Byte]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,13 @@ object GroupElement extends EntityObject("GroupElement") {
true, false, element[GroupElement]))
}

override def expUnsigned(k: Ref[UnsignedBigInt]): Ref[GroupElement] = {
asRep[GroupElement](mkMethodCall(self,
GroupElementClass.getMethod("expUnsigned", classOf[Sym]),
Array[AnyRef](k),
true, false, element[GroupElement]))
}

override def multiply(that: Ref[GroupElement]): Ref[GroupElement] = {
asRep[GroupElement](mkMethodCall(self,
GroupElementClass.getMethod("multiply", classOf[Sym]),
Expand Down Expand Up @@ -491,6 +498,13 @@ object GroupElement extends EntityObject("GroupElement") {
true, true, element[GroupElement]))
}

def expUnsigned(k: Ref[UnsignedBigInt]): Ref[GroupElement] = {
asRep[GroupElement](mkMethodCall(source,
GroupElementClass.getMethod("expUnsigned", classOf[Sym]),
Array[AnyRef](k),
true, true, element[GroupElement]))
}

def multiply(that: Ref[GroupElement]): Ref[GroupElement] = {
asRep[GroupElement](mkMethodCall(source,
GroupElementClass.getMethod("multiply", classOf[Sym]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class SigmaBinder(env: ScriptEnv, builder: SigmaBuilder,
case _ @ Apply(ApplyTypes(Ident("Coll", _), Seq(tpe)), args) =>
Some(mkConcreteCollection(args, tpe))

// hack to make possible to write g.exp(ubi) for both unsigned and signed big integers
case Apply(Select(obj, n, resType), args) if n == "exp" && args(0).isInstanceOf[Value[SUnsignedBigInt.type]] =>
Some(Apply(Select(obj, "expUnsigned", resType), args))

// Rule: Coll(...) -->
case Apply(Ident("Coll", _), args) =>
val tpe = if (args.isEmpty) NoType else args(0).tpe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ class SigmaTyper(val builder: SigmaBuilder,
case app @ Apply(sel @ Select(obj, n, _), args) =>
val newSel = assignType(env, sel)
val newArgs = args.map(assignType(env, _))
if(n=="expUnsigned") {
println(app)
println("newSel: " + newSel)
println("newArgs: " + newArgs)
}
newSel.tpe match {
case genFunTpe @ SFunc(argTypes, _, _) =>
// If it's a function then the application has type of that function's return type.
Expand Down

0 comments on commit 303f969

Please sign in to comment.