diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 24e1d94756..51761a5ecc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -58,7 +58,7 @@ jobs:
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v1
with:
- fail_ci_if_error: true
+ fail_ci_if_error: false
- name: Publish a snapshot ${{ github.ref }}
if: env.HAS_SECRETS == 'true'
diff --git a/build.sbt b/build.sbt
index 5b7e3219ff..6c06c611fe 100644
--- a/build.sbt
+++ b/build.sbt
@@ -17,12 +17,12 @@ lazy val commonSettings = Seq(
scalaVersion := scala212,
scalacOptions ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
- case Some((2, 13)) => Seq("-Ywarn-unused:_,imports", "-Ywarn-unused:imports")
- case Some((2, 12)) => Seq("-Ywarn-unused:_,imports", "-Ywarn-unused:imports")
+ case Some((2, 13)) => Seq("-Ywarn-unused:_,imports", "-Ywarn-unused:imports", "-release", "8")
+ case Some((2, 12)) => Seq("-Ywarn-unused:_,imports", "-Ywarn-unused:imports", "-release", "8")
case Some((2, 11)) => Seq()
case _ => sys.error("Unsupported scala version")
}
- } ++ scalacReleaseOption,
+ },
javacOptions ++= javacReleaseOption,
resolvers += Resolver.sonatypeRepo("public"),
licenses := Seq("CC0" -> url("https://creativecommons.org/publicdomain/zero/1.0/legalcode")),
@@ -56,14 +56,6 @@ lazy val commonSettings = Seq(
),
)
-def scalacReleaseOption = {
- if (System.getProperty("java.version").startsWith("1."))
- // java <9 "-release" is not supported
- Seq()
- else
- Seq("-release", "8") // this is passed to javac as `javac -release 8`
-}
-
def javacReleaseOption = {
if (System.getProperty("java.version").startsWith("1."))
// java <9 "--release" is not supported
@@ -77,25 +69,22 @@ dynverSonatypeSnapshots in ThisBuild := true
// use "-" instead of default "+"
dynverSeparator in ThisBuild := "-"
-val bouncycastleBcprov = "org.bouncycastle" % "bcprov-jdk15on" % "1.64"
-val scrypto = "org.scorexfoundation" %% "scrypto" % "2.1.10"
-val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8"
-val debox = "org.scorexfoundation" %% "debox" % "0.9.0"
-val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" // The last version published for Scala 2.11-2.13
-val kiama = "org.bitbucket.inkytonik.kiama" %% "kiama" % "2.5.0"
+val bouncycastleBcprov = "org.bouncycastle" % "bcprov-jdk15on" % "1.66"
+val scrypto = "org.scorexfoundation" %% "scrypto" % "2.3.0-RC1"
+val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.2.0"
+val debox = "org.scorexfoundation" %% "debox" % "0.10.0"
+val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1"
val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3"
-val commonsIo = "commons-io" % "commons-io" % "2.5"
-val commonsMath3 = "org.apache.commons" % "commons-math3" % "3.2"
val scalaCompat = "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0"
val testingDependencies = Seq(
- "org.scalatest" %% "scalatest" % "3.0.9" % Test,
- "org.scalactic" %% "scalactic" % "3.0.9" % Test,
- "org.scalacheck" %% "scalacheck" % "1.14.3" % Test,
+ "org.scalatest" %% "scalatest" % "3.2.14" % Test,
+ "org.scalactic" %% "scalactic" % "3.2.14" % Test,
+ "org.scalacheck" %% "scalacheck" % "1.15.2" % Test, // last supporting Scala 2.11
+ "org.scalatestplus" %% "scalacheck-1-15" % "3.2.3.0" % Test, // last supporting Scala 2.11
"com.lihaoyi" %% "pprint" % "0.6.3" % Test,
"com.storm-enroute" %% "scalameter" % "0.19" % Test,
- "junit" % "junit" % "4.12" % Test,
- "com.novocode" % "junit-interface" % "0.11" % Test
+ "junit" % "junit" % "4.12" % Test
)
lazy val testSettings = Seq(
@@ -111,8 +100,12 @@ libraryDependencies ++= Seq(
scrypto,
scorexUtil,
"org.bouncycastle" % "bcprov-jdk15on" % "1.+",
- kiama, fastparse, debox, spireMacros, scalaCompat
-) ++ testingDependencies
+ fastparse, debox, spireMacros, scalaCompat
+) ++ testingDependencies ++
+ (if (scalaVersion.value == scala211)
+ Seq(circeCore211, circeGeneric211, circeParser211)
+ else
+ Seq(circeCore, circeGeneric, circeParser))
lazy val circeCore211 = "io.circe" %% "circe-core" % "0.10.0"
lazy val circeGeneric211 = "io.circe" %% "circe-generic" % "0.10.0"
@@ -122,12 +115,6 @@ lazy val circeCore = "io.circe" %% "circe-core" % "0.13.0"
lazy val circeGeneric = "io.circe" %% "circe-generic" % "0.13.0"
lazy val circeParser = "io.circe" %% "circe-parser" % "0.13.0"
-libraryDependencies ++= Seq(
- if (scalaVersion.value == scala211) circeCore211 else circeCore,
- if (scalaVersion.value == scala211) circeGeneric211 else circeGeneric,
- if (scalaVersion.value == scala211) circeParser211 else circeParser
- )
-
scalacOptions ++= Seq("-feature", "-deprecation")
parallelExecution in Test := false
@@ -158,10 +145,10 @@ usePgpKeyHex("C1FD62B4D44BDF702CDF2B726FF59DA944B150DD")
def libraryDefSettings = commonSettings ++ testSettings
lazy val common = Project("common", file("common"))
- .settings(commonSettings ++ testSettings,
+ .settings(libraryDefSettings,
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
- debox, commonsIo, scalaCompat
+ debox, scalaCompat
))
.settings(publish / skip := true)
@@ -179,14 +166,14 @@ lazy val libraryimpl = Project("library-impl", file("library-impl"))
lazy val core = Project("core", file("core"))
.dependsOn(common % allConfigDependency, libraryapi % allConfigDependency)
- .settings(commonSettings,
+ .settings(libraryDefSettings,
libraryDependencies ++= Seq( debox ))
.settings(publish / skip := true)
lazy val library = Project("library", file("library"))
.dependsOn(common % allConfigDependency, core % allConfigDependency, libraryapi, libraryimpl)
- .settings(//commonSettings,
- libraryDefSettings ++ testSettings,
+ .settings(
+ libraryDefSettings,
libraryDependencies ++= Seq( debox ))
.settings(publish / skip := true)
@@ -217,7 +204,7 @@ lazy val sigmastate = (project in file("sigmastate"))
.dependsOn(sigmalibrary % allConfigDependency)
.settings(libraryDefSettings)
.settings(libraryDependencies ++= Seq(
- scorexUtil, kiama, fastparse, commonsMath3,
+ scorexUtil, fastparse,
if (scalaVersion.value == scala211) circeCore211 else circeCore,
if (scalaVersion.value == scala211) circeGeneric211 else circeGeneric,
if (scalaVersion.value == scala211) circeParser211 else circeParser
@@ -245,94 +232,3 @@ lazy val rootSettings = Seq(
mappings in (Test, packageBin) ++= (mappings in(Test, packageBin)).all(aggregateCompile).value.flatten,
mappings in(Test, packageSrc) ++= (mappings in(Test, packageSrc)).all(aggregateCompile).value.flatten
)
-
-def runErgoTask(task: String, sigmastateVersion: String, log: Logger): Unit = {
- val ergoBranch = "test-coverage"
- val sbtEnvVars = Seq("BUILD_ENV" -> "test", "SIGMASTATE_VERSION" -> sigmastateVersion)
-
- log.info(s"Testing current build in Ergo (branch $ergoBranch):")
- val cwd = new File("").absolutePath
- val ergoPath = new File(cwd + "/ergo-tests/")
- log.info(s"Cleaning $ergoPath")
- s"rm -rf ${ergoPath.absolutePath}" !
-
- log.info(s"Cloning Ergo branch $ergoBranch into ${ergoPath.absolutePath}")
- s"git clone -b $ergoBranch --single-branch https://github.com/ergoplatform/ergo.git ${ergoPath.absolutePath}" !
-
-
- log.info(s"Updating Ergo in $ergoPath with Sigmastate version $sigmastateVersion")
- Process(Seq("sbt", "unlock", "reload", "lock"), ergoPath, sbtEnvVars: _*) !
-
- log.info("Updated Ergo lock.sbt:")
- Process(Seq("git", "diff", "-U0", "lock.sbt"), ergoPath) !
-
- log.info(s"Running Ergo tests in $ergoPath with Sigmastate version $sigmastateVersion")
- val res = Process(Seq("sbt", task), ergoPath, sbtEnvVars: _*) !
-
- if (res != 0) sys.error(s"Ergo $task failed!")
-}
-
-lazy val ergoUnitTestTask = TaskKey[Unit]("ergoUnitTestTask", "run ergo unit tests with current version")
-ergoUnitTestTask := {
- val log = streams.value.log
- val sigmastateVersion = version.value
- runErgoTask("test", sigmastateVersion, log)
-}
-
-commands += Command.command("ergoUnitTest") { state =>
- "clean" ::
- "publishLocal" ::
- "ergoUnitTestTask" ::
- state
-}
-
-lazy val ergoItTestTask = TaskKey[Unit]("ergoItTestTask", "run ergo it:test with current version")
-ergoItTestTask := {
- val log = streams.value.log
- val sigmastateVersion = version.value
- runErgoTask("it:test", sigmastateVersion, log)
-}
-
-commands += Command.command("ergoItTest") { state =>
- "clean" ::
- "publishLocal" ::
- "ergoItTestTask" ::
- state
-}
-
-def runSpamTestTask(task: String, sigmastateVersion: String, log: Logger): Unit = {
- val spamBranch = "master"
- val envVars = Seq("SIGMASTATE_VERSION" -> sigmastateVersion,
- // SSH_SPAM_REPO_KEY should be set (see Jenkins Credentials Binding Plugin)
- "GIT_SSH_COMMAND" -> "ssh -i $SSH_SPAM_REPO_KEY")
-
- log.info(s"Testing current build with spam tests (branch $spamBranch):")
- val cwd = new File("")
- val spamPath = new File(cwd.absolutePath + "/spam-tests/")
- log.info(s"Cleaning $spamPath")
- s"rm -rf ${spamPath.absolutePath}" !
-
- log.info(s"Cloning spam tests branch $spamBranch into ${spamPath.absolutePath}")
- Process(Seq("git", "clone", "-b", spamBranch, "--single-branch", "git@github.com:greenhat/sigma-spam.git", spamPath.absolutePath),
- cwd.getAbsoluteFile,
- envVars: _*) !
-
- log.info(s"Running spam tests in $spamPath with Sigmastate version $sigmastateVersion")
- val res = Process(Seq("sbt", task), spamPath, envVars: _*) !
-
- if (res != 0) sys.error(s"Spam $task failed!")
-}
-
-lazy val spamTestTask = TaskKey[Unit]("spamTestTask", "run spam tests with current version")
-spamTestTask := {
- val log = streams.value.log
- val sigmastateVersion = version.value
- runSpamTestTask("test", sigmastateVersion, log)
-}
-
-commands += Command.command("spamTest") { state =>
- "clean" ::
- "publishLocal" ::
- "spamTestTask" ::
- state
-}
diff --git a/common/src/main/java/java7/compat/Math.java b/common/src/main/java/java7/compat/Math.java
deleted file mode 100644
index 72ed8d5de0..0000000000
--- a/common/src/main/java/java7/compat/Math.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java7.compat;
-
-/**
- * Contains methods introduced since Java 1.8 which are not available in Java 1.7.
- * Using this methods supports compatibility with Java 1.7 in non-JVM contexts like
- * RoboVM.
- * The implementations are copies from JDK 1.8 sources.
- *
- * See
- * this issue
- */
-public final class Math {
- /**
- * Returns the sum of its arguments,
- * throwing an exception if the result overflows an {@code int}.
- *
- * @param x the first value
- * @param y the second value
- * @return the result
- * @throws ArithmeticException if the result overflows an int
- * @since 1.8
- */
- public static int addExact(int x, int y) {
- int r = x + y;
- // HD 2-12 Overflow iff both arguments have the opposite sign of the result
- if (((x ^ r) & (y ^ r)) < 0) {
- throw new ArithmeticException("integer overflow");
- }
- return r;
- }
-
- /**
- * Returns the sum of its arguments,
- * throwing an exception if the result overflows a {@code long}.
- *
- * @param x the first value
- * @param y the second value
- * @return the result
- * @throws ArithmeticException if the result overflows a long
- * @since 1.8
- */
- public static long addExact(long x, long y) {
- long r = x + y;
- // HD 2-12 Overflow iff both arguments have the opposite sign of the result
- if (((x ^ r) & (y ^ r)) < 0) {
- throw new ArithmeticException("long overflow");
- }
- return r;
- }
-
- /**
- * Returns the difference of the arguments,
- * throwing an exception if the result overflows an {@code int}.
- *
- * @param x the first value
- * @param y the second value to subtract from the first
- * @return the result
- * @throws ArithmeticException if the result overflows an int
- * @since 1.8
- */
- public static int subtractExact(int x, int y) {
- int r = x - y;
- // HD 2-12 Overflow iff the arguments have different signs and
- // the sign of the result is different than the sign of x
- if (((x ^ y) & (x ^ r)) < 0) {
- throw new ArithmeticException("integer overflow");
- }
- return r;
- }
-
- /**
- * Returns the difference of the arguments,
- * throwing an exception if the result overflows a {@code long}.
- *
- * @param x the first value
- * @param y the second value to subtract from the first
- * @return the result
- * @throws ArithmeticException if the result overflows a long
- * @since 1.8
- */
- public static long subtractExact(long x, long y) {
- long r = x - y;
- // HD 2-12 Overflow iff the arguments have different signs and
- // the sign of the result is different than the sign of x
- if (((x ^ y) & (x ^ r)) < 0) {
- throw new ArithmeticException("long overflow");
- }
- return r;
- }
-
- /**
- * Returns the product of the arguments,
- * throwing an exception if the result overflows an {@code int}.
- *
- * @param x the first value
- * @param y the second value
- * @return the result
- * @throws ArithmeticException if the result overflows an int
- * @since 1.8
- */
- public static int multiplyExact(int x, int y) {
- long r = (long)x * (long)y;
- if ((int)r != r) {
- throw new ArithmeticException("integer overflow");
- }
- return (int)r;
- }
-
- /**
- * Returns the product of the arguments,
- * throwing an exception if the result overflows a {@code long}.
- *
- * @param x the first value
- * @param y the second value
- * @return the result
- * @throws ArithmeticException if the result overflows a long
- * @since 1.8
- */
- public static long multiplyExact(long x, long y) {
- long r = x * y;
- long ax = java.lang.Math.abs(x);
- long ay = java.lang.Math.abs(y);
- if (((ax | ay) >>> 31 != 0)) {
- // Some bits greater than 2^31 that might cause overflow
- // Check the result using the divide operator
- // and check for the special case of Long.MIN_VALUE * -1
- if (((y != 0) && (r / y != x)) ||
- (x == Long.MIN_VALUE && y == -1)) {
- throw new ArithmeticException("long overflow");
- }
- }
- return r;
- }
-}
diff --git a/common/src/main/java/scalan/Builtin.java b/common/src/main/java/scalan/Builtin.java
deleted file mode 100644
index 83a1c37b84..0000000000
--- a/common/src/main/java/scalan/Builtin.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-
-/** Relate annotated element with internal type or method given by `value` property.
-* Applied to entities that should be replaced during virtualization by related type.
-* The given related type is said to be pre-virtualized.
-* The 'value' is a name of the class which can be resolved in a Scalan cake. E.g. IsoUR*/
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Builtin {
- String value() default ""; // default value interpreted as "virtualized name is equal to annotated element name"
-}
diff --git a/common/src/main/java/scalan/Constructor.java b/common/src/main/java/scalan/Constructor.java
deleted file mode 100644
index 0caecfe3d9..0000000000
--- a/common/src/main/java/scalan/Constructor.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Used in generated wrappers.
- * Annotates a wrapper method of the companion of a virtualized type wrapper,
- * which (the method) corresponds to the constructor of wrapped type. */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Constructor {
-}
diff --git a/common/src/main/java/scalan/ContainerType.java b/common/src/main/java/scalan/ContainerType.java
deleted file mode 100644
index c3768cda3c..0000000000
--- a/common/src/main/java/scalan/ContainerType.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Annotates Special DSL types which implement the interface of containers.
-* Each container is described using Cont[_] descriptors.
-* Special supporting code is generated for annotated entities. */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.CLASS)
-public @interface ContainerType {
-}
diff --git a/common/src/main/java/scalan/Convertible.java b/common/src/main/java/scalan/Convertible.java
deleted file mode 100644
index 662f5f6ee3..0000000000
--- a/common/src/main/java/scalan/Convertible.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Marks annotated type as having support for generic Converter generation. */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Convertible {
-}
diff --git a/common/src/main/java/scalan/External.java b/common/src/main/java/scalan/External.java
deleted file mode 100644
index e8e2864c7c..0000000000
--- a/common/src/main/java/scalan/External.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Relate annotated element with an external type or method given by `value` property.
-* For example WOption related to Option is annotated as @External("Option")
-* This annotation is used to separate wrapper Entity from user defined virtualized Entity.
-* See WrapperEntity object. */
-@Target({ElementType.TYPE, ElementType.METHOD})
-public @interface External {
- String value() default ""; // default value interpreted as "external name is equal to annotated element name"
-}
diff --git a/common/src/main/java/scalan/FunctorType.java b/common/src/main/java/scalan/FunctorType.java
deleted file mode 100644
index 9832d78271..0000000000
--- a/common/src/main/java/scalan/FunctorType.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Used to annotate container types (like Option, Coll), which have
- * functor semantics. Special code is generated for such entities. */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.CLASS)
-public @interface FunctorType {
-}
diff --git a/common/src/main/java/scalan/InlineAt.java b/common/src/main/java/scalan/InlineAt.java
deleted file mode 100644
index 0590456be7..0000000000
--- a/common/src/main/java/scalan/InlineAt.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Specifies the predicate when the annotated method should be inlined.
-* The predicate is given by the parsable formula which can be used to
-* create runtime predicate functions.
-* Default empty string is interpreted as never invoke, in which case scalanizer
-* don't perform virtualization of the method body and replace it with delayInvoke. */
-@Target({ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface InlineAt {
- String Never = "";
- String value() default Never;
-}
diff --git a/common/src/main/java/scalan/Internal.java b/common/src/main/java/scalan/Internal.java
deleted file mode 100644
index 1555984ccc..0000000000
--- a/common/src/main/java/scalan/Internal.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Used to annotate type and methods, which should not be virtualized.
- * Everything marked @Internal are invisible for virtualization process.
- */
-@Target({ElementType.TYPE, ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Internal {
-}
diff --git a/common/src/main/java/scalan/Isospec.java b/common/src/main/java/scalan/Isospec.java
deleted file mode 100644
index d5c2498537..0000000000
--- a/common/src/main/java/scalan/Isospec.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Marks annotated type as having support for isomorphic specialization. */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Isospec {
-}
diff --git a/common/src/main/java/scalan/Liftable.java b/common/src/main/java/scalan/Liftable.java
deleted file mode 100644
index 83dc56bc17..0000000000
--- a/common/src/main/java/scalan/Liftable.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Marks annotated type as having support for lifting values to IR nodes. */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Liftable {
-}
diff --git a/common/src/main/java/scalan/NeverInline.java b/common/src/main/java/scalan/NeverInline.java
deleted file mode 100644
index 39b63e9a0c..0000000000
--- a/common/src/main/java/scalan/NeverInline.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Equvalent to InlineAt(Never). */
-@Target({ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface NeverInline {
-}
diff --git a/common/src/main/java/scalan/OverloadId.java b/common/src/main/java/scalan/OverloadId.java
deleted file mode 100644
index c167013698..0000000000
--- a/common/src/main/java/scalan/OverloadId.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Assigns an alternative name to the overloaded method. */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface OverloadId {
- String value();
-}
diff --git a/common/src/main/java/scalan/Reified.java b/common/src/main/java/scalan/Reified.java
deleted file mode 100644
index 360340f678..0000000000
--- a/common/src/main/java/scalan/Reified.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Type argument T should be reified in virtualized code type descriptor Elem[T] available
-* in the scope where T is visible. This can be done either by explicitly passing additional
-* parameter eT: Elem[T] or by proving that Elem[T] can be retrieved from the other arguments
-* of the method or class. For example if x: Rep[T] then eT can be obtained by x.elem.
-* The need for reified type arguments come from ClassTag[T], RType[T] context bounds or
-* implicit parameters in the source code.
-*/
-@Target({ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Reified {
- String value() default "";
-}
diff --git a/common/src/main/java/scalan/WithMethodCallRecognizers.java b/common/src/main/java/scalan/WithMethodCallRecognizers.java
deleted file mode 100644
index 37e229ed01..0000000000
--- a/common/src/main/java/scalan/WithMethodCallRecognizers.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package scalan;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Marks annotated method or trait/class as having support for pattern matching.
- * Extractor methods will be generated by codegen for each method either annotated or
- * belonging to the annotated type.
- * Extractors can be used in rewriting rules to recognize IR nodes of MethodCall type,
- * which represents the call of the annotated method.
- */
-@Target({ElementType.METHOD,ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface WithMethodCallRecognizers {
-}
diff --git a/common/src/main/scala-2.11/sigmastate/kiama/util/Collections.scala b/common/src/main/scala-2.11/sigmastate/kiama/util/Collections.scala
new file mode 100644
index 0000000000..347a996452
--- /dev/null
+++ b/common/src/main/scala-2.11/sigmastate/kiama/util/Collections.scala
@@ -0,0 +1,42 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2013-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama
+package util
+
+object Collections {
+
+ // Java to Scala conversions
+
+ import scala.collection.JavaConverters._
+
+ def javaCollectionToVector[T](s : java.util.Collection[T]) : Vector[T] =
+ s.asScala.toVector
+
+ def mapToJavaMap[T, U](v : Map[T, U]) : java.util.Map[T, U] =
+ v.asJava
+
+ def seqToJavaList[T](v : Seq[T]) : java.util.List[T] =
+ v.asJava
+
+ // Collection building
+
+ import scala.collection.mutable.Builder
+
+ type Factory[-B, +C] = scala.collection.generic.CanBuildFrom[_, B, C]
+ type CanBuildFrom[-A, -B, +C] = scala.collection.generic.CanBuildFrom[A, B, C]
+
+ def newBuilder[B, C](cbf : Factory[B, C]) : Builder[B, C] =
+ cbf()
+
+ def newBuilder[A, B, C](cbf : CanBuildFrom[A, B, C], from : A) : Builder[B, C] =
+ cbf(from)
+
+}
diff --git a/common/src/main/scala-2.12/sigmastate/kiama/util/Collections.scala b/common/src/main/scala-2.12/sigmastate/kiama/util/Collections.scala
new file mode 100644
index 0000000000..347a996452
--- /dev/null
+++ b/common/src/main/scala-2.12/sigmastate/kiama/util/Collections.scala
@@ -0,0 +1,42 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2013-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama
+package util
+
+object Collections {
+
+ // Java to Scala conversions
+
+ import scala.collection.JavaConverters._
+
+ def javaCollectionToVector[T](s : java.util.Collection[T]) : Vector[T] =
+ s.asScala.toVector
+
+ def mapToJavaMap[T, U](v : Map[T, U]) : java.util.Map[T, U] =
+ v.asJava
+
+ def seqToJavaList[T](v : Seq[T]) : java.util.List[T] =
+ v.asJava
+
+ // Collection building
+
+ import scala.collection.mutable.Builder
+
+ type Factory[-B, +C] = scala.collection.generic.CanBuildFrom[_, B, C]
+ type CanBuildFrom[-A, -B, +C] = scala.collection.generic.CanBuildFrom[A, B, C]
+
+ def newBuilder[B, C](cbf : Factory[B, C]) : Builder[B, C] =
+ cbf()
+
+ def newBuilder[A, B, C](cbf : CanBuildFrom[A, B, C], from : A) : Builder[B, C] =
+ cbf(from)
+
+}
diff --git a/common/src/main/scala-2.13/sigmastate/kiama/util/Collections.scala b/common/src/main/scala-2.13/sigmastate/kiama/util/Collections.scala
new file mode 100644
index 0000000000..14f3936af1
--- /dev/null
+++ b/common/src/main/scala-2.13/sigmastate/kiama/util/Collections.scala
@@ -0,0 +1,42 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2013-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama
+package util
+
+object Collections {
+
+ // Java to Scala conversions
+
+ import scala.jdk.CollectionConverters._
+
+ def javaCollectionToVector[T](s : java.util.Collection[T]) : Vector[T] =
+ s.asScala.toVector
+
+ def mapToJavaMap[T, U](v : Map[T, U]) : java.util.Map[T, U] =
+ v.asJava
+
+ def seqToJavaList[T](v : Seq[T]) : java.util.List[T] =
+ v.asJava
+
+ // Collection building
+
+ import scala.collection.mutable.Builder
+
+ type Factory[-B, +C] = scala.collection.Factory[B, C]
+ type CanBuildFrom[-A, -B, +C] = scala.collection.BuildFrom[A, B, C]
+
+ def newBuilder[B, C](f : Factory[B, C]) : Builder[B, C] =
+ f.newBuilder
+
+ def newBuilder[A, B, C](cbf : CanBuildFrom[A, B, C], from : A) : Builder[B, C] =
+ cbf.newBuilder(from)
+
+}
diff --git a/common/src/main/scala/java7/compat/Math.scala b/common/src/main/scala/java7/compat/Math.scala
new file mode 100644
index 0000000000..a1a7ce1296
--- /dev/null
+++ b/common/src/main/scala/java7/compat/Math.scala
@@ -0,0 +1,126 @@
+package java7.compat
+
+/**
+ * Contains methods introduced since Java 1.8 which are not available in Java 1.7.
+ * Using this methods supports compatibility with Java 1.7 in non-JVM contexts like
+ * RoboVM.
+ * The implementations are copies from JDK 1.8 sources.
+ *
+ * See
+ * this issue
+ */
+object Math {
+ /**
+ * Returns the sum of its arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ */
+ def addExact(x: Int, y: Int): Int = {
+ val r = x + y
+ // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+ if (((x ^ r) & (y ^ r)) < 0) {
+ throw new ArithmeticException("integer overflow")
+ }
+ r
+ }
+
+ /**
+ * Returns the sum of its arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ */
+ def addExact(x: Long, y: Long): Long = {
+ val r = x + y
+ if (((x ^ r) & (y ^ r)) < 0) {
+ throw new ArithmeticException("long overflow")
+ }
+ r
+ }
+
+ /**
+ * Returns the difference of the arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value to subtract from the first
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ */
+ def subtractExact(x: Int, y: Int): Int = {
+ val r = x - y
+ // HD 2-12 Overflow iff the arguments have different signs and
+ // the sign of the result is different than the sign of x
+ if (((x ^ y) & (x ^ r)) < 0) {
+ throw new ArithmeticException("integer overflow")
+ }
+ r
+ }
+
+ /**
+ * Returns the difference of the arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value to subtract from the first
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ */
+ def subtractExact(x: Long, y: Long) = {
+ val r = x - y
+ // HD 2-12 Overflow iff the arguments have different signs and
+ // the sign of the result is different than the sign of x
+ if (((x ^ y) & (x ^ r)) < 0) {
+ throw new ArithmeticException("long overflow")
+ }
+ r
+ }
+
+ /**
+ * Returns the product of the arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ */
+ def multiplyExact(x: Int, y: Int) = {
+ val r = x.toLong * y.toLong
+ if (r.toInt != r) {
+ throw new ArithmeticException("integer overflow")
+ }
+ r.toInt
+ }
+
+ /**
+ * Returns the product of the arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ */
+ def multiplyExact(x: Long, y: Long) = {
+ val r = x * y
+ val ax = java.lang.Math.abs(x)
+ val ay = java.lang.Math.abs(y)
+ if ((ax | ay) >>> 31 != 0) {
+ // Some bits greater than 2^31 that might cause overflow
+ // Check the result using the divide operator
+ // and check for the special case of Long.MIN_VALUE * -1
+ if (((y != 0) && (r / y != x)) || (x == Long.MinValue && y == -1)) {
+ throw new ArithmeticException("long overflow")
+ }
+ }
+ r
+ }
+}
diff --git a/common/src/main/scala/scalan/util/Extensions.scala b/common/src/main/scala/scalan/util/Extensions.scala
index d144d6dc96..5b0c70987a 100644
--- a/common/src/main/scala/scalan/util/Extensions.scala
+++ b/common/src/main/scala/scalan/util/Extensions.scala
@@ -2,7 +2,6 @@ package scalan.util
import java.math.BigInteger
import java.nio.ByteBuffer
-
import scala.language.higherKinds
object Extensions {
@@ -216,4 +215,21 @@ object Extensions {
None
}
}
+
+ /** Syntactic sugar for postfix assertions and the value pass through
+ * Example:
+ * val positiveValue = x.ensuring(_ > 0, x => s"the value is not positive: $x")
+ */
+ implicit final class Ensuring[A](private val self: A) extends AnyVal {
+ /** Ensures that the given predicate holds for this value.
+ * @param cond the predicate used to test this value.
+ * @param msg the error message to be used if the predicate does not hold.
+ * @return this value, if it satisfies the given predicate `p`.
+ * @throws AssertionError if the predicate does not hold.
+ */
+ def ensuring(cond: A => Boolean, msg: A => Any): A = {
+ assert(cond(self), msg(self))
+ self
+ }
+ }
}
diff --git a/common/src/main/scala/scalan/util/FileUtil.scala b/common/src/main/scala/scalan/util/FileUtil.scala
index 56e138e85f..89a596ed28 100644
--- a/common/src/main/scala/scalan/util/FileUtil.scala
+++ b/common/src/main/scala/scalan/util/FileUtil.scala
@@ -2,19 +2,14 @@ package scalan.util
import java.io._
import java.net.{JarURLConnection, URL}
-import java.nio.charset.Charset
import java.nio.file._
import java.nio.file.attribute.BasicFileAttributes
-import java.util.jar.JarFile
-import org.apache.commons.io.{FileUtils, IOUtils}
import scala.Console
import scala.collection.JavaConverters._
import scalan.util.StringUtil.StringUtilExtensions
import scalan.util.CollectionUtil.AnyOps
object FileUtil {
- def read(file: File): String = FileUtils.readFileToString(file, Charset.defaultCharset())
-
def withFile(file: File)(f: PrintWriter => Unit): Unit = {
if (file.isDirectory && !file.delete()) {
throw new RuntimeException(s"File $file is a non-empty directory")
@@ -53,50 +48,6 @@ object FileUtil {
out.toString
}
- def copy(source: File, target: File): Unit =
- if (source.isFile)
- FileUtils.copyFile(source, target, false)
- else
- FileUtils.copyDirectory(source, target, false)
-
- def copyFromClassPath(source: String, target: File, classLoader: ClassLoader = getClass.getClassLoader): Unit = {
- target.getParentFile.mkdirs()
- val urls = classLoader.getResources(source)
- if (urls.hasMoreElements) {
- if (source.endsWith("/")) {
- urls.asScala.foreach { url =>
- url.getProtocol match {
- case "file" =>
- FileUtils.copyDirectory(urlToFile(url), target, false)
- case "jar" =>
- val jarFile = new JarFile(jarUrlToJarFile(url))
- jarFile.entries().asScala.foreach { entry =>
- val entryPath = entry.getName
- if (entryPath.startsWith(source)) {
- val entryTarget = new File(target, entryPath.stripPrefix(source))
- if (entry.isDirectory)
- entryTarget.mkdirs()
- else {
- // copyInputStreamToFile closes stream
- FileUtils.copyInputStreamToFile(jarFile.getInputStream(entry), entryTarget)
- }
- }
- }
- }
- }
- } else {
- val url = urls.nextElement()
- if (urls.hasMoreElements) {
- throw new IllegalArgumentException(s"Multiple $source resources found on classpath")
- } else {
- // copyInputStreamToFile closes stream
- FileUtils.copyInputStreamToFile(url.openStream(), target)
- }
- }
- } else
- throw new IllegalArgumentException(s"Resource $source not found on classpath")
- }
-
def classPathLastModified(source: String, classLoader: ClassLoader = getClass.getClassLoader) = {
def urlLastModified(url: URL): Long = {
url.getProtocol match {
@@ -139,23 +90,6 @@ object FileUtil {
urlToFile(jarFileUrl)
}
- /**
- * Copy file source to targetDir, keeping the original file name
- */
- def copyToDir(source: File, targetDir: File): Unit =
- copy(source, new File(targetDir, source.getName))
-
- def move(source: File, target: File): Unit =
- if (source.isFile)
- FileUtils.moveFile(source, target)
- else
- FileUtils.moveDirectory(source, target)
-
- /**
- * Add header into the file
- */
- def addHeader(file: File, header: String): Unit = write(file, header + "\n" + read(file))
-
/**
* Like fileOrDirectory.delete() but works for non-empty directories
* and throws exceptions instead of returning false on failure
@@ -228,14 +162,6 @@ object FileUtil {
for {d <- dirs; f <- listFiles(d)} yield f
}
- def readAndCloseStream(stream: InputStream) = {
- try {
- IOUtils.toString(stream, Charset.defaultCharset())
- } finally {
- IOUtils.closeQuietly(stream)
- }
- }
-
def stripExtension(fileName: String) =
fileName.lastIndexOf('.') match {
case -1 =>
diff --git a/common/src/main/scala/scalan/util/ReflectionUtil.scala b/common/src/main/scala/scalan/util/ReflectionUtil.scala
index c463e8a787..15c73b0548 100644
--- a/common/src/main/scala/scalan/util/ReflectionUtil.scala
+++ b/common/src/main/scala/scalan/util/ReflectionUtil.scala
@@ -1,33 +1,19 @@
package scalan.util
-import java.lang.reflect.{Method, AnnotatedElement}
import scala.language.existentials
-import scala.reflect.{classTag, ClassTag}
-import scalan.OverloadId
object ReflectionUtil {
- def jAnnotation[A <: java.lang.annotation.Annotation : ClassTag](element: AnnotatedElement) =
- Option(element.getAnnotation(classTag[A].runtimeClass.asInstanceOf[Class[A]]))
-
- def overloadId(method: Method) = jAnnotation[OverloadId](method).map(_.value)
-
- /** Returns the superclass for an anonymous class produced by mixing in traits; the argument otherwise. */
- def namedSuperclass(clazz: Class[_]) = {
- if (clazz.getSimpleName.contains("$anon$")) {
- val superclass = clazz.getSuperclass
- if (superclass == classOf[Object]) {
- // clazz is composed of traits only, return the first one
- clazz.getInterfaces.head
- } else
- superclass
- } else
- clazz
- }
implicit class ClassOps(val cl: Class[_]) extends AnyVal {
+ /** Special character in the name. */
private def isSpecialChar(c: Char): Boolean = {
('0' <= c && c <= '9') || c == '$'
}
+
+ /** Safe version of `getSimpleName` that works around a bug in Scala compilers 2.11, 2.12.
+ * This method is only used for debugging purposes.
+ * @see https://github.com/scala/bug/issues/5425
+ */
def safeSimpleName: String = {
if (cl.getEnclosingClass == null) return cl.getSimpleName
val simpleName = cl.getName.substring(cl.getEnclosingClass.getName.length)
diff --git a/common/src/main/scala/sigmastate/VersionContext.scala b/common/src/main/scala/sigmastate/VersionContext.scala
index 04ac2da524..ef220d1109 100644
--- a/common/src/main/scala/sigmastate/VersionContext.scala
+++ b/common/src/main/scala/sigmastate/VersionContext.scala
@@ -21,10 +21,6 @@ case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) {
/** @return true, if the activated script version of Ergo protocol on the network is
* greater than v1. */
def isJitActivated: Boolean = activatedVersion >= JitActivationVersion
-
- /** @return true, if the version of ErgoTree being executed greater than v1. */
- def isErgoTreeVersionGreaterV1: Boolean =
- ergoTreeVersion >= JitActivationVersion
}
object VersionContext {
diff --git a/common/src/main/scala/sigmastate/kiama/kiama.scala b/common/src/main/scala/sigmastate/kiama/kiama.scala
new file mode 100644
index 0000000000..df8518f88d
--- /dev/null
+++ b/common/src/main/scala/sigmastate/kiama/kiama.scala
@@ -0,0 +1,29 @@
+package sigmastate
+
+/**
+ * Kiama is a Scala library for language processing. It is a project of the
+ * Programming Languages Research Group at Macquarie University. For full
+ * project details see the web site `http://github.com/inkytonik/kiama`.
+ *
+ * Kiama's main components address tree decoration via attribute grammars
+ * (package `attribution`), tree transformation via strategic term rewriting
+ * (package `rewriting`), dynamic semantics (package `machine`) and
+ * pretty-printing (package `output`).
+ *
+ * The `util` package contains support modules for parsing, input/output,
+ * read-eval-print loops (REPLs) and pattern matching.
+ *
+ * The `examples` package (available as part of the Kiama tests) contains
+ * many examples of using Kiama to solve small to medium language processing
+ * problems.
+ */
+package object kiama {
+ /**
+ * Convenient type constructor for partial functions.
+ */
+ type ==>[T, U] = PartialFunction[T, U]
+ /**
+ * Another convenient type constructor for partial functions.
+ */
+ type ===>[T] = PartialFunction[T, T]
+}
diff --git a/common/src/main/scala/sigmastate/kiama/rewriting/CallbackRewriter.scala b/common/src/main/scala/sigmastate/kiama/rewriting/CallbackRewriter.scala
new file mode 100644
index 0000000000..157f6f172b
--- /dev/null
+++ b/common/src/main/scala/sigmastate/kiama/rewriting/CallbackRewriter.scala
@@ -0,0 +1,71 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2013-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama
+package rewriting
+
+/**
+ * Strategy-based term rewriting with callbacks. Clients can register
+ * functions that are called whenever a rewrite operation has happened.
+ * See the `Rewriter` class documentation for more detail on the methods
+ * defined here.
+ */
+trait CallbackRewriter extends Rewriter {
+
+ /**
+ * The method to call when a rewrite operation has happened. It will
+ * be called under two circumstances. First, when a `rule` (or similar, such
+ * as `rulefs`, or `strategy`) is about to return a new term to replace an old
+ * term. (Note that if the rule creates sub-terms in the new term, the
+ * results of these operations are not notified, only the root of the
+ * new term.) Second, whenever a generic traversal (such as all or one)
+ * creates a new node to duplicate an old one. In both cases this method
+ * is called with both the old and the new terms. The return value should
+ * be a term that should go forward as the new term.
+ */
+ def rewriting[T](oldTerm : T, newTerm : T) : T
+
+ /**
+ * Produce a strategy that first runs the strategy s on the
+ * current term. If `s` fails, then fail. Otherwise, pass the original
+ * and new terms to the rewriting method and succeed with the term that
+ * it returns.
+ */
+ def dispatch(s : Strategy) : Strategy =
+ new Strategy {
+ def apply(t : Any) =
+ s(t) match {
+ case None => None
+ case Some(u) => Some(rewriting(t, u))
+ }
+ }
+
+ override def rule[T](f : ===>[T]) : Strategy =
+ dispatch(super.rule[T](f))
+
+ override def rulef(f : Any => Any) : Strategy =
+ dispatch(super.rulef(f))
+
+ override def rulefs[T](f : T ==> Strategy) : Strategy =
+ dispatch(super.rulefs[T](f))
+
+ override def strategy[T](f : T ==> Option[T]) : Strategy =
+ dispatch(super.strategy(f))
+
+ override def strategyf(f : Any => Option[Any]) : Strategy =
+ dispatch(super.strategyf(f))
+
+ /**
+ * Product duplication with callback notification.
+ */
+ override def dup[T <: Product](t : T, children : Array[AnyRef]) : T =
+ rewriting(t, super.dup(t, children))
+
+}
diff --git a/common/src/main/scala/sigmastate/kiama/rewriting/PlusStrategy.scala b/common/src/main/scala/sigmastate/kiama/rewriting/PlusStrategy.scala
new file mode 100644
index 0000000000..26ac3ae2c5
--- /dev/null
+++ b/common/src/main/scala/sigmastate/kiama/rewriting/PlusStrategy.scala
@@ -0,0 +1,42 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2008-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama.rewriting
+
+/**
+ * Helper class to contain commonality of choice in non-deterministic
+ * choice operator and then-else part of a conditional choice. Only
+ * returned by the non-deterministic choice operator. `p` and `q` are
+ * evaluated at most once.
+ */
+class PlusStrategy(p : => Strategy, q : => Strategy) extends Strategy {
+
+ /**
+ * The left alternative of the choice.
+ */
+ lazy val left = p
+
+ /**
+ * The right alternative of the choice.
+ */
+ lazy val right = q
+
+ /**
+ * The strategy itself (lazily computed).
+ */
+ private lazy val s = left <+ right
+
+ /**
+ * Implementation of this strategy. Just apply `s`.
+ */
+ def apply(t : Any) =
+ s(t)
+
+}
diff --git a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala
new file mode 100644
index 0000000000..6a2b8635c9
--- /dev/null
+++ b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala
@@ -0,0 +1,987 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2008-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama
+package rewriting
+
+import scala.collection.mutable
+
+/**
+ * Strategy-based term rewriting in the style of Stratego (http://strategoxt.org/).
+ * The implementation here is partially based on the semantics given in "Program
+ * Transformation with Scoped Dynamic Rewrite Rules", by Bravenboer, van Dam, Olmos
+ * and Visser, Fundamenta Informaticae, 69, 2005. The library strategies are mostly
+ * based on the Stratego library, but also on combinators found in the Scrap Your
+ * Boilerplate and Uniplate libraries for Haskell.
+ */
+trait Rewriter {
+
+ import sigmastate.kiama.util.Comparison.same
+ import sigmastate.kiama.util.Collections.{CanBuildFrom, Factory, newBuilder}
+
+ /**
+ * Rewrite a term. Apply the strategy `s` to a term returning the result term
+ * if `s` succeeds, otherwise return the original term.
+ */
+ def rewrite[T](s : Strategy)(t : T) : T = {
+ s(t) match {
+ case Some(t1) =>
+ t1.asInstanceOf[T]
+ case None =>
+ t
+ }
+ }
+
+ // Strategy creation
+
+ /**
+ * Make a strategy with the body `f`. By default, make a basic strategy.
+ */
+ def mkStrategy(f : Any => Option[Any]) : Strategy =
+ new Strategy {
+ def apply(t : Any) =
+ f(t)
+ }
+
+ // Builder combinators.
+
+ /**
+ * Construct a strategy that always succeeds, changing the subject term to
+ * the given term `t`. The term `t` is evaluated at most once.
+ */
+ def build(t : Any) : Strategy =
+ rulef(_ => t)
+
+ /**
+ * A strategy that always fails.
+ */
+ val fail : Strategy =
+ mkStrategy(_ => None)
+
+ /**
+ * A strategy that always succeeds.
+ */
+ val id : Strategy =
+ mkStrategy(Some(_))
+
+ /**
+ * Perform a paramorphism over a value. This is a fold in which the
+ * recursive step may refer to the recursive component of the value
+ * and the results of folding over the children. When the function `f`
+ * is called, the first parameter is the value and the second is a
+ * sequence of the values that `f` has returned for the children. This
+ * will work on any value, but will only decompose values that are
+ * supported by the `Term` generic term deconstruction. This operation
+ * is similar to that used in the Uniplate library.
+ */
+ def para[T](f : (Any, Seq[T]) => T) : Any => T = {
+ case Term(t, ts) => f(t, ts.map(para(f)))
+ }
+
+ /**
+ * Define a term query by a partial function `f`. The query always succeeds
+ * with no effect on the subject term but applies the given partial function
+ * `f` to the subject term. In other words, the strategy runs `f` for its
+ * side-effects. If the subject term is not a `T` or the function is not
+ * defined at the subject term, the strategy fails.
+ *
+ * Due to the type erasure performed on Scala programs the type test
+ * will be imprecise for some types. E.g., it is not possible to tell
+ * the difference between `List[Int]` and `List[String]`.
+ */
+ def query[T](f : T ==> Unit) : Strategy = {
+ val anyf = f.asInstanceOf[===>[Any]]
+ mkStrategy(
+ (t : Any) => {
+ val of = anyf andThen (_ => Some(t))
+ try {
+ of.applyOrElse(t, (a : Any) => None)
+ } catch {
+ case _ : ClassCastException =>
+ None
+ }
+ }
+ )
+ }
+
+ /**
+ * Define a rewrite rule using a partial function `f` defined on the type
+ * `T`. If the subject term is a `T` and the function is defined at the
+ * subject term, then the strategy succeeds with the return value of the
+ * function applied to the subject term. Otherwise, the strategy fails.
+ *
+ * Due to the type erasure performed on Scala programs the type test
+ * will be imprecise for some types. E.g., it is not possible to tell
+ * the difference between `List[Int]` and `List[String]`.
+ */
+ def rule[T](f : ===>[T]) : Strategy = {
+ val anyf = f.asInstanceOf[===>[Any]]
+ val of = anyf andThen (Some(_))
+ mkStrategy(
+ (t : Any) =>
+ try {
+ of.applyOrElse(t, (a : Any) => None)
+ } catch {
+ case _ : ClassCastException =>
+ None
+ }
+ )
+ }
+
+ /**
+ * Define a rewrite rule using a function `f` that returns a term.
+ * The rule always succeeds with the return value of the function.
+ */
+ def rulef(f : Any => Any) : Strategy =
+ strategyf(t => Some(f(t)))
+
+ /**
+ * Define a rewrite rule using a function `f` defined on type `T` that returns
+ * a strategy. If the subject term is a `T` and the function is defined at the
+ * subject term, the rule applies the function to the subject term to get a
+ * strategy which is then applied again to the subject term. In other words,
+ * the function is only used for effects such as pattern matching. The whole
+ * thing also fails if `f` is not defined at the term in the first place.
+ */
+ def rulefs[T](f : T ==> Strategy) : Strategy = {
+ val anyf = f.asInstanceOf[Any ==> Strategy]
+ mkStrategy(
+ (t : Any) => {
+ val of = anyf andThen (_.apply(t))
+ try {
+ of.applyOrElse(t, (a : Any) => None)
+ } catch {
+ case _ : ClassCastException =>
+ None
+ }
+ }
+ )
+ }
+
+ /**
+ * Make a strategy from a partial function `f` defined on the type `T`.
+ * If the subject term is a `T` and the function is defined at the
+ * subject term, then the function return value when applied to the
+ * subject term determines whether the strategy succeeds or fails.
+ * If the subject term is not a `T` or the function is not defined at
+ * the subject term, the strategy fails.
+ *
+ * Due to the type erasure performed on Scala programs the type test
+ * will be imprecise for some types. E.g., it is not possible to tell
+ * the difference between `List[Int]` and `List[String]`.
+ */
+ def strategy[T](f : T ==> Option[T]) : Strategy = {
+ val of = f.asInstanceOf[Any ==> Option[T]]
+ mkStrategy(
+ (t : Any) =>
+ try {
+ of.applyOrElse(t, (a : Any) => None)
+ } catch {
+ case _ : ClassCastException =>
+ None
+ }
+ )
+ }
+
+ /**
+ * Make a strategy from a function `f`. The function return value
+ * determines whether the strategy succeeds or fails.
+ */
+ def strategyf(f : Any => Option[Any]) : Strategy =
+ mkStrategy(f)
+
+ /**
+ * Construct a strategy that succeeds only if the subject term matches
+ * the given term `t`.
+ */
+ def term[T](t : T) : Strategy =
+ rule[T]({
+ case `t` => t
+ })
+
+ // Product duplication support
+
+ /**
+ * General product duplication functionality. This object is a function
+ * that returns a product that applies the same constructor as the
+ * product `t`, but with the given children instead of `t`'s children.
+ * The function fails if a constructor cannot be found, there are the
+ * wrong number of new children, or if one of the new children is not
+ * of the appropriate type.
+ */
+ object Duplicator {
+
+ import java.lang.reflect.Constructor
+
+ type Duper = (Any, Array[AnyRef]) => Any
+
+ object MakeDuper extends (Class[_] => Duper) {
+
+ def apply(clazz : Class[_]) : Duper =
+ try {
+ // See if this class has a MODULE$ field. This field is used by Scala
+ // to hold a singleton instance and is only present in singleton classes
+ // (e.g., ones arising from object declarations or case objects). If we
+ // are trying to duplicate one of these then we want to return the same
+ // singleton so we use an identity duper.
+ clazz.getField("MODULE$")
+ (t : Any, children : Array[AnyRef]) =>
+ t
+ } catch {
+ // Otherwise, this is a normal class, so we try to make a
+ // duper that uses the first constructor.
+ case _ : NoSuchFieldException =>
+ val ctors = clazz.getConstructors
+ if (ctors.length == 0)
+ sys.error(s"dup no constructors for ${clazz.getName}")
+ else
+ (t : Any, children : Array[AnyRef]) =>
+ makeInstance(ctors(0), children)
+ }
+
+ def makeInstance(ctor : Constructor[_], children : Array[AnyRef]) : Any =
+ try {
+ ctor.newInstance(unboxPrimitives(ctor, children) : _*)
+ } catch {
+ case e : IllegalArgumentException =>
+ sys.error(s"""dup illegal arguments: $ctor got (${children.mkString(",")})
+ |Common cause: term classes are nested in another class, move them to the top level""".stripMargin)
+ }
+
+ def unboxPrimitives(ctor : Constructor[_], children : Array[AnyRef]) : Array[AnyRef] = {
+ val numChildren = ctor.getParameterTypes().length
+ val childrenTypes = ctor.getParameterTypes()
+ val newChildren = new Array[AnyRef](numChildren)
+ var i = 0
+ while (i < numChildren) {
+ if (childrenTypes(i).isPrimitive())
+ newChildren(i) = unboxAnyVal(children(i))
+ else
+ newChildren(i) = children(i)
+ i = i + 1
+ }
+ newChildren
+ }
+
+ def unboxAnyVal(s : AnyRef) : AnyRef =
+ s match {
+ case p : Product if p.productArity == 1 =>
+ p.productElement(0).asInstanceOf[AnyRef]
+ case _ =>
+ s
+ }
+
+ }
+
+ private val cache = mutable.HashMap.empty[Class[_], Duper]
+
+ /** Obtains a duper for the given class lazily. and memoize it in the `cache` map.
+ * This is the simplest solution, but not the most efficient for concurrent access.
+ */
+ def getDuper(clazz: Class[_]): Duper = synchronized { // TODO optimize: avoid global sync
+ val duper = cache.get(clazz) match {
+ case Some(d) => d
+ case None =>
+ val d = MakeDuper(clazz)
+ cache.put(clazz, d)
+ d
+ }
+ duper
+ }
+
+ def apply[T <: Product](t : T, children : Array[AnyRef]) : T = {
+ val clazz = t.getClass
+ val duper = getDuper(clazz)
+ duper(t, children).asInstanceOf[T]
+ }
+
+ }
+
+ /**
+ * The duplicator used by the generic traversals. Needs to be defined
+ * as a method so we can override it in other rewriting modules.
+ */
+ def dup[T <: Product](t : T, children : Array[AnyRef]) : T =
+ Duplicator(t, children)
+
+ /**
+ * Copy a product node by creating a new node of the same class type
+ * using the same children.
+ */
+ def copy[T <: Product](t : T) : T =
+ Duplicator(t, t.productIterator.map(makechild).toArray)
+
+ /**
+ * Make an arbitrary value `c` into a term child, checking that it worked
+ * properly. Object references will be returned unchanged; other values
+ * will be boxed.
+ */
+ protected def makechild(c : Any) : AnyRef =
+ c.asInstanceOf[AnyRef]
+
+ // Generic traversals
+
+ /**
+ * Traversal to a single child. Construct a strategy that applies `s` to
+ * the ''ith'' child of the subject term (counting from one). If `s` succeeds on
+ * the ''ith'' child producing `t`, then succeed, forming a new term that is the
+ * same as the original term except that the ''ith'' child is now `t`. If `s` fails
+ * on the ''ith'' child or the subject term does not have an ''ith'' child, then fail.
+ * `child(i, s)` is equivalent to Stratego's `i(s)` operator. If `s` succeeds on
+ * the ''ith'' child producing the same term (by `eq` for references and by `==` for
+ * other values), then the overall strategy returns the subject term.
+ * This operation works for instances of `Product` or finite `Seq` values.
+ * `s` is evaluated at most once.
+ */
+ def child(i : Int, s : => Strategy) : Strategy =
+ mkStrategy({
+ lazy val strat = s
+ t =>
+ t match {
+ case p : Product =>
+ childProduct(strat, i, p)
+ case t : Seq[_] =>
+ childSeq(strat, i, t.asInstanceOf[Seq[Any]])
+ case _ =>
+ None
+ }
+ })
+
+ /**
+ * Implementation of `child` for `Product` values.
+ */
+ def childProduct(s : Strategy, i : Int, p : Product) : Option[Any] = {
+ val numchildren = p.productArity
+ if ((i < 1) || (i > numchildren)) {
+ None
+ } else {
+ val ct = p.productElement(i - 1)
+ s(ct) match {
+ case Some(ti) if same(ct, ti) =>
+ Some(p)
+ case Some(ti) =>
+ val newchildren = p.productIterator.map(makechild).toArray
+ newchildren(i - 1) = makechild(ti)
+ Some(dup(p, newchildren))
+ case None =>
+ None
+ }
+ }
+ }
+
+ /**
+ * Implementation of `child` for `Seq` values.
+ */
+ def childSeq[CC[U] <: Seq[U]](s : Strategy, i : Int, t : CC[Any])(implicit cbf : CanBuildFrom[CC[Any], Any, CC[Any]]) : Option[CC[Any]] = {
+ val numchildren = t.size
+ if ((i < 1) || (i > numchildren)) {
+ None
+ } else {
+ val ct = t(i - 1)
+ s(ct) match {
+ case Some(ti) if same(ct, ti) =>
+ Some(t)
+ case Some(ti) =>
+ val b = newBuilder(cbf, t)
+ b.sizeHint(t.size)
+ t.foldLeft(0) {
+ case (j, ct) =>
+ b += (if (j == i - 1) ti else ct)
+ j + 1
+ }
+ Some(b.result())
+ case None =>
+ None
+ }
+ }
+ }
+
+ /**
+ * Traversal to all children. Construct a strategy that applies `s` to all
+ * term children of the subject term. If `s` succeeds on all of the children,
+ * then succeed, forming a new term from the constructor
+ * of the original term and the result of `s` for each child. If `s` fails on any
+ * child, fail. If there are no children, succeed. If `s` succeeds on all
+ * children producing the same terms (by `eq` for references and by `==` for
+ * other values), then the overall strategy returns the subject term.
+ * This operation works on finite `Rewritable`, `Product`, `Map` and `Iterable`
+ * values, checked for in that order.
+ * Children of a `Rewritable` (resp. Product, collection) value are processed
+ * in the order returned by the value's deconstruct (resp. `productElement`,
+ * `foreach`) method.
+ * `s` is evaluated at most once.
+ */
+ def all(s : => Strategy) : Strategy =
+ mkStrategy({
+ lazy val strat = s
+ t =>
+ t match {
+ case p : Product =>
+ allProduct(strat, p)
+ case m : Map[_, _] =>
+ allMap(strat, m.asInstanceOf[Map[Any, Any]])
+ case t : Iterable[_] =>
+ allIterable(strat, t.asInstanceOf[Iterable[Any]])
+ case _ =>
+ Some(t)
+ }
+ })
+
+ /**
+ * Implementation of `all` for `Product` values.
+ */
+ def allProduct(s : Strategy, p : Product) : Option[Any] = {
+ val numchildren = p.productArity
+ if (numchildren == 0)
+ Some(p)
+ else {
+ val newchildren = Array.newBuilder[AnyRef]
+ val changed =
+ p.productIterator.foldLeft(false) {
+ case (changed, ct) =>
+ s(ct) match {
+ case Some(ti) =>
+ newchildren += makechild(ti)
+ changed || !same(ct, ti)
+ case None =>
+ return None
+ }
+ }
+ if (changed)
+ Some(dup(p, newchildren.result()))
+ else
+ Some(p)
+ }
+ }
+
+ /**
+ * Implementation of `all` for `Iterable` values.
+ */
+ def allIterable[CC[U] <: Iterable[U]](s : Strategy, t : CC[Any])(implicit cbf : CanBuildFrom[CC[Any], Any, CC[Any]]) : Option[CC[Any]] =
+ if (t.size == 0)
+ Some(t)
+ else {
+ val b = newBuilder(cbf, t)
+ b.sizeHint(t.size)
+ val (changed, _) =
+ t.foldLeft((false, 0)) {
+ case ((changed, i), ct) =>
+ s(ct) match {
+ case Some(ti) =>
+ b += ti
+ (changed || !same(ct, ti), i + 1)
+ case None =>
+ return None
+ }
+ }
+ if (changed)
+ Some(b.result())
+ else
+ Some(t)
+ }
+
+ /**
+ * Implementation of `all` for `Map` values.
+ */
+ def allMap[CC[V, W] <: Map[V, W]](s : Strategy, t : CC[Any, Any])(implicit cbf : CanBuildFrom[CC[Any, Any], (Any, Any), CC[Any, Any]]) : Option[CC[Any, Any]] =
+ if (t.size == 0)
+ Some(t)
+ else {
+ val b = newBuilder(cbf, t)
+ b.sizeHint(t.size)
+ val (changed, _) =
+ t.foldLeft((false, 0)) {
+ case ((changed, i), ct) =>
+ s(ct) match {
+ case Some(ti @ (tix, tiy)) =>
+ b += ti
+ (changed || !same(ct, ti), i + 1)
+ case _ =>
+ return None
+ }
+ }
+ if (changed)
+ Some(b.result())
+ else
+ Some(t)
+ }
+
+ /**
+ * Traversal to one child. Construct a strategy that applies `s` to the term
+ * children of the subject term. Assume that `c` is the
+ * first child on which s succeeds. Then stop applying `s` to the children and
+ * succeed, forming a new term from the constructor of the original term and
+ * the original children, except that `c` is replaced by the result of applying
+ * `s` to `c`. In the event that the strategy fails on all children, then fail.
+ * If there are no children, fail. If `s` succeeds on the one child producing
+ * the same term (by `eq` for references and by `==` for other values), then
+ * the overall strategy returns the subject term.
+ * This operation works on instances of finite `Rewritable`, `Product`, `Map`
+ * and `Iterable` values, checked for in that order.
+ * Children of a `Rewritable` (resp. `Product`, collection) value are processed
+ * in the order returned by the value's `deconstruct` (resp. `productElement`,
+ * `foreach`) method.
+ * `s` is evaluated at most once.
+ */
+ def one(s : => Strategy) : Strategy =
+ mkStrategy({
+ lazy val strat = s
+ t =>
+ t match {
+ case p : Product =>
+ oneProduct(strat, p)
+ case m : Map[_, _] =>
+ oneMap(strat, m.asInstanceOf[Map[Any, Any]])
+ case t : Iterable[_] =>
+ oneIterable(strat, t.asInstanceOf[Iterable[Any]])
+ case _ =>
+ None
+ }
+ })
+
+ /**
+ * Implementation of `one` for `Product` values.
+ */
+ def oneProduct(s : Strategy, p : Product) : Option[Any] = {
+ p.productIterator.foldLeft(0) {
+ case (i, ct) =>
+ s(ct) match {
+ case Some(ti) if same(ct, ti) =>
+ return Some(p)
+ case Some(ti) =>
+ val newchildren = p.productIterator.toArray.map(makechild)
+ newchildren(i) = makechild(ti)
+ return Some(dup(p, newchildren))
+ case None =>
+ i + 1
+ }
+ }
+ None
+ }
+
+ /**
+ * Implementation of `one` for `Iterable` values.
+ */
+ def oneIterable[CC[U] <: Iterable[U]](s : Strategy, t : CC[Any])(implicit cbf : CanBuildFrom[CC[Any], Any, CC[Any]]) : Option[CC[Any]] = {
+ val b = newBuilder(cbf, t)
+ b.sizeHint(t.size)
+ val add =
+ t.foldLeft(true) {
+ case (add, ct) =>
+ if (add)
+ s(ct) match {
+ case Some(ti) if same(ct, ti) =>
+ return Some(t)
+ case Some(ti) =>
+ b += ti
+ false
+ case None =>
+ b += ct
+ true
+ }
+ else {
+ b += ct
+ false
+ }
+ }
+ if (add)
+ None
+ else
+ Some(b.result())
+ }
+
+ /**
+ * Implementation of `one` for `Map` values.
+ */
+ def oneMap[CC[V, W] <: Map[V, W]](s : Strategy, t : CC[Any, Any])(implicit cbf : CanBuildFrom[CC[Any, Any], (Any, Any), CC[Any, Any]]) : Option[CC[Any, Any]] = {
+ val b = newBuilder(cbf, t)
+ b.sizeHint(t.size)
+ val add =
+ t.foldLeft(true) {
+ case (add, ct) =>
+ if (add)
+ s(ct) match {
+ case Some(ti @ (tix, tiy)) if same(ct, ti) =>
+ return Some(t)
+ case Some(ti @ (tix, tiy)) =>
+ b += ti
+ false
+ case Some(ti) =>
+ sys.error(s"oneMap: got non-pair $ti")
+ case None =>
+ b += ct
+ true
+ }
+ else {
+ b += ct
+ false
+ }
+ }
+ if (add)
+ None
+ else
+ Some(b.result())
+ }
+
+ /**
+ * Traversal to as many children as possible, but at least one. Construct a
+ * strategy that applies `s` to the term children of the subject term.
+ * If `s` succeeds on any of the children, then succeed,
+ * forming a new term from the constructor of the original term and the result
+ * of `s` for each succeeding child, with other children unchanged. In the event
+ * that `s` fails on all children, then fail. If there are no
+ * children, fail. If `s` succeeds on children producing the same terms (by `eq`
+ * for references and by `==` for other values), then the overall strategy
+ * returns the subject term.
+ * This operation works on instances of finite `Rewritable`, `Product`, `Map` and
+ * `Iterable` values, checked for in that order.
+ * Children of a `Rewritable` (resp. `Product`, collection) value are processed
+ * in the order returned by the value's `deconstruct` (resp. `productElement`,
+ * `foreach`) method.
+ * `s` is evaluated at most once.
+ */
+ def some(s : => Strategy) : Strategy =
+ mkStrategy({
+ lazy val strat = s
+ t =>
+ t match {
+ case p : Product =>
+ someProduct(strat, p)
+ case m : Map[_, _] =>
+ someMap(strat, m.asInstanceOf[Map[Any, Any]])
+ case t : Iterable[_] =>
+ someIterable(strat, t.asInstanceOf[Iterable[Any]])
+ case _ =>
+ None
+ }
+ })
+
+ /**
+ * Implementation of `some` for `Product` values.
+ */
+ def someProduct(s : Strategy, p : Product) : Option[Any] = {
+ val numchildren = p.productArity
+ if (numchildren == 0)
+ None
+ else {
+ val newchildren = Array.newBuilder[AnyRef]
+ val (success, changed) =
+ p.productIterator.foldLeft((false, false)) {
+ case ((success, changed), ct) =>
+ s(ct) match {
+ case Some(ti) =>
+ newchildren += makechild(ti)
+ (true, changed || !same(ct, ti))
+ case None =>
+ newchildren += makechild(ct)
+ (success, changed)
+ }
+ }
+ if (success)
+ if (changed)
+ Some(dup(p, newchildren.result()))
+ else
+ Some(p)
+ else
+ None
+ }
+ }
+
+ /**
+ * Implementation of `some` for `Iterable` values.
+ */
+ def someIterable[CC[U] <: Iterable[U]](s : Strategy, t : CC[Any])(implicit cbf : CanBuildFrom[CC[Any], Any, CC[Any]]) : Option[CC[Any]] =
+ if (t.size == 0)
+ None
+ else {
+ val b = newBuilder(cbf, t)
+ b.sizeHint(t.size)
+ val (success, changed) =
+ t.foldLeft((false, false)) {
+ case ((success, changed), ct) =>
+ s(ct) match {
+ case Some(ti) =>
+ b += ti
+ (true, changed || !same(ct, ti))
+ case None =>
+ b += ct
+ (success, changed)
+ }
+ }
+ if (success)
+ if (changed)
+ Some(b.result())
+ else
+ Some(t)
+ else
+ None
+ }
+
+ /**
+ * Implementation of `some` for `Map` values.
+ */
+ def someMap[CC[V, W] <: Map[V, W]](s : Strategy, t : CC[Any, Any])(implicit cbf : CanBuildFrom[CC[Any, Any], (Any, Any), CC[Any, Any]]) : Option[CC[Any, Any]] =
+ if (t.size == 0)
+ None
+ else {
+ val b = newBuilder(cbf, t)
+ b.sizeHint(t.size)
+ val (success, changed) =
+ t.foldLeft((false, false)) {
+ case ((success, changed), ct) =>
+ s(ct) match {
+ case Some(ti @ (tix, tiy)) =>
+ b += ti
+ (true, changed || !same(ct, ti))
+ case _ =>
+ b += ct
+ (success, changed)
+ }
+ }
+ if (success)
+ if (changed)
+ Some(b.result())
+ else
+ Some(t)
+ else
+ None
+ }
+
+ // Extractors
+
+ /**
+ * Generic term deconstruction.
+ */
+ object Term {
+
+ /**
+ * Generic term deconstruction. An extractor that decomposes `Product`
+ * `Rewritable` or `Seq` values into the value itself and a vector of
+ * its children. Terms that are not of these types are not decomposable
+ * (i.e., the children will be empty).
+ */
+ def unapply(t : Any) : Some[(Any, Vector[Any])] = {
+ t match {
+ case p : Product =>
+ Some((p, p.productIterator.toVector))
+ case s : Seq[_] =>
+ Some((s, s.toVector))
+ case _ =>
+ Some((t, Vector()))
+ }
+ }
+
+ }
+
+ // Library combinators
+
+ /**
+ * `and(s1, s2)` applies `s1` and `s2` to the subject
+ * term and succeeds if both succeed. `s2` will always
+ * be applied, i.e., and is ''not'' a short-circuit
+ * operator.
+ */
+ def and(s1 : Strategy, s2 : Strategy) : Strategy =
+ where(s1) < (test(s2) + (test(s2) <* fail))
+
+ /**
+ * Construct a strategy that applies `s`, yielding the result of `s` if it
+ * succeeds, otherwise leave the original subject term unchanged. In
+ * Stratego library this strategy is called `try`.
+ */
+ def attempt(s : Strategy) : Strategy =
+ s <+ id
+
+ /**
+ * Construct a strategy that applies `s` in a bottom-up, postfix fashion
+ * to the subject term.
+ */
+ def bottomup(s : Strategy) : Strategy =
+ all(bottomup(s)) <* s
+
+ /**
+ * A strategy that tests whether the two sub-terms of a pair of terms are equal.
+ */
+ val eq : Strategy =
+ rule[(Any, Any)]({
+ case t @ (x, y) if x == y => t
+ })
+
+ /**
+ * Construct a strategy that tests whether the two sub-terms of a
+ * pair of terms are equal. Synonym for `eq`.
+ */
+ val equal : Strategy =
+ eq
+
+ /**
+ * Same as `everywheretd`.
+ */
+ def everywhere(s : Strategy) : Strategy =
+ everywheretd(s)
+
+ /**
+ * Construct a strategy that applies `s` at all terms in a bottom-up fashion
+ * regardless of failure. Terms for which the strategy fails are left
+ * unchanged.
+ */
+ def everywherebu(s : Strategy) : Strategy =
+ bottomup(attempt(s))
+
+ /**
+ * Construct a strategy that applies `s` at all terms in a top-down fashion
+ * regardless of failure. Terms for which the strategy fails are left
+ * unchanged.
+ */
+ def everywheretd(s : Strategy) : Strategy =
+ topdown(attempt(s))
+
+ /**
+ * Construct a strategy that while `r` succeeds applies `s`. This operator
+ * is called `while` in the Stratego library.
+ */
+ def loop(c : Strategy, s : Strategy) : Strategy = {
+ lazy val result : Strategy = attempt(c <* s <* result)
+ mkStrategy(result)
+ }
+
+ /**
+ * Construct a strategy that applies `s(i)` for each integer `i` from `low` to
+ * `high` (inclusive). This operator is called `for` in the Stratego library.
+ */
+ def loopiter(s : Int => Strategy, low : Int, high : Int) : Strategy = {
+ lazy val result =
+ if (low <= high)
+ s(low) <* loopiter(s, low + 1, high)
+ else
+ id
+ mkStrategy(result)
+ }
+
+ /**
+ * Construct a strategy that applies `s` to each element of a finite
+ * sequence (type `Seq`) returning a new sequence of the results if
+ * all of the applications succeed, otherwise fail. If all of the
+ * applications succeed without change, return the input sequence.
+ */
+ def map(s : Strategy) : Strategy =
+ strategy[Seq[_]]({
+ case l : Seq[_] =>
+ allIterable[Seq](s, l)
+ })
+
+ /**
+ * Construct a strategy that applies `s`, then fails if `s` succeeded or, if `s`
+ * failed, succeeds with the subject term unchanged, I.e., it tests if
+ * `s` applies, but has no effect on the subject term.
+ */
+ def not(s : Strategy) : Strategy =
+ s < (fail + id)
+
+ /**
+ * `or(s1, s2)` is similar to `ior(s1, s2)`, but the application
+ * of the strategies is only tested.
+ */
+ def or(s1 : Strategy, s2 : Strategy) : Strategy =
+ where(s1) < (attempt(test(s2)) + test(s2))
+
+ /**
+ * Construct a strategy that applies `s` repeatedly to subterms
+ * until it fails on all of them.
+ */
+ def reduce(s : Strategy) : Strategy = {
+ lazy val inner : Strategy = some(inner) + s
+ repeat(inner)
+ }
+
+ /**
+ * Construct a strategy that applies `s` repeatedly until it fails.
+ */
+ def repeat(s : Strategy) : Strategy = {
+ lazy val result : Strategy = attempt(s <* result)
+ mkStrategy(result)
+ }
+
+ /**
+ * Construct a strategy that applies `s` repeatedly exactly `n` times. If
+ * `s` fails at some point during the n applications, the entire strategy
+ * fails. The result of the strategy is that of the ''nth'' application of
+ * `s`.
+ */
+ def repeat(s : Strategy, n : Int) : Strategy = {
+ lazy val result = if (n == 0) id else s <* repeat(s, n - 1)
+ mkStrategy(result)
+ }
+
+ /**
+ * Construct a strategy that tests whether strategy `s` succeeds,
+ * restoring the original term on success. A synonym for `where`.
+ */
+ def test(s : Strategy) : Strategy =
+ where(s)
+
+ /**
+ * Construct a strategy that applies `s` in a top-down, prefix fashion
+ * to the subject term.
+ */
+ def topdown(s : Strategy) : Strategy = {
+ lazy val result : Strategy = s <* all(result)
+ mkStrategy(result)
+ }
+
+ /**
+ * Construct a strategy that tests whether strategy `s` succeeds,
+ * restoring the original term on success. This is similar
+ * to Stratego's `where`, except that in this version any effects on
+ * bindings are not visible outside `s`.
+ */
+ def where(s : Strategy) : Strategy =
+ strategyf(t => (s <* build(t))(t))
+
+ // Queries below here
+
+ /**
+ * Collect query results in a Iterable collection. Run the function
+ * `f` as a top-down left-to-right query on the subject term. Each
+ * application of `f` returns a single value. All of these values are
+ * accumulated in the collection.
+ */
+ def collect[CC[X] <: Iterable[X], U](f : Any ==> U)(implicit cbf : Factory[U, CC[U]]) : Any => CC[U] =
+ (t : Any) => {
+ val b = newBuilder(cbf)
+ val add = (u : U) => { b += u; () }
+ (everywhere(query(f andThen add)))(t)
+ b.result()
+ }
+
+ /**
+ * Count function results. Run the function `f` as a top-down query on
+ * the subject term. Sum the integer values returned by `f` from all
+ * applications.
+ */
+ def count(f : Any ==> Int) : Any => Int =
+ everything(0)(_ + _)(f)
+
+ /**
+ * Apply the function at every term in `t` in a top-down, left-to-right order.
+ * Collect the resulting `T` values by accumulating them using `f` with initial
+ * left value `v`. Return the final value of the accumulation.
+ */
+ def everything[T](v : T)(f : (T, T) => T)(g : Any ==> T)(t : Any) : T = {
+ val collector = collect[List, T](g)
+ collector(t).foldLeft(v)(f)
+ }
+
+}
+
+/**
+ * Strategy-based term rewriting for arbitrary terms.
+ */
+object Rewriter extends Rewriter
diff --git a/common/src/main/scala/sigmastate/kiama/rewriting/Strategy.scala b/common/src/main/scala/sigmastate/kiama/rewriting/Strategy.scala
new file mode 100644
index 0000000000..faf856e8d7
--- /dev/null
+++ b/common/src/main/scala/sigmastate/kiama/rewriting/Strategy.scala
@@ -0,0 +1,94 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2008-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama
+package rewriting
+
+/**
+ * Any-rewriting strategies. A strategy is a function that takes a term
+ * of any type as input and either succeeds producing a new term (`Some`),
+ * or fails (`None`).
+ */
+abstract class Strategy extends (Any => Option[Any]) {
+
+ /**
+ * Alias this strategy as `p` to make it easier to refer to in the
+ * combinator definitions.
+ */
+ p =>
+
+ /**
+ * Make one of these strategies with the body `f`.
+ */
+ def mkStrategy(f : Any => Option[Any]) : Strategy =
+ new Strategy {
+ def apply(t : Any) =
+ f(t)
+ }
+
+ /**
+ * Sequential composition. Construct a strategy that first applies
+ * this strategy. If it succeeds, then apply `q` to the new subject
+ * term. Otherwise fail. `q` is evaluated at most once.
+ */
+ def <*(q : => Strategy) : Strategy =
+ mkStrategy(
+ t1 =>
+ p(t1) match {
+ case Some(t2) => q(t2)
+ case None => None
+ }
+ )
+
+ /**
+ * Deterministic choice. Construct a strategy that first applies
+ * this strategy. If it succeeds, succeed with the resulting term.
+ * Otherwise, apply `q` to the original subject term. `q` is
+ * evaluated at most once.
+ */
+ def <+(q : => Strategy) : Strategy =
+ mkStrategy(
+ (t1 : Any) =>
+ p(t1) match {
+ case Some(t2) => Some(t2)
+ case None => q(t1)
+ }
+ )
+
+ /**
+ * Non-deterministic choice. Normally, construct a strategy that
+ * first applies either this strategy or the given strategy. If it
+ * succeeds, succeed with the resulting term. Otherwise, apply `q`.
+ * Currently implemented as deterministic choice, but this behaviour
+ * should not be relied upon.
+ * When used as the argument to the `<` conditional choice
+ * combinator, `+` just serves to hold the two strategies that are
+ * chosen between by the conditional choice.
+ * `q` is evaluated at most once.
+ */
+ def +(q : => Strategy) : PlusStrategy =
+ new PlusStrategy(p, q)
+
+ /**
+ * Conditional choice: `c < l + r`. Construct a strategy that first
+ * applies this strategy (`c`). If `c` succeeds, the strategy applies
+ * `l` to the resulting term, otherwise it applies `r` to the original
+ * subject term. `lr` is evaluated at most once.
+ */
+ def <(lr : => PlusStrategy) : Strategy =
+ mkStrategy(
+ t1 =>
+ p(t1) match {
+ case Some(t2) => lr.left(t2)
+ case None => lr.right(t1)
+ }
+ )
+
+}
diff --git a/common/src/main/scala/sigmastate/kiama/util/Comparison.scala b/common/src/main/scala/sigmastate/kiama/util/Comparison.scala
new file mode 100644
index 0000000000..91d302a76a
--- /dev/null
+++ b/common/src/main/scala/sigmastate/kiama/util/Comparison.scala
@@ -0,0 +1,117 @@
+/*
+ * This file is part of Kiama.
+ *
+ * Copyright (C) 2014-2021 Anthony M Sloane, Macquarie University.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package sigmastate.kiama
+package util
+
+/**
+ * Utility module for comparison routines.
+ */
+object Comparison {
+
+ import scala.collection.mutable.TreeSet
+
+ /**
+ * Compare two arbitrary values. If they are both references and not
+ * tuples, use reference equality. If they are tuples, use `same` to
+ * compare the components. Otherwise use value equality.
+ */
+ def same(v1 : Any, v2 : Any) : Boolean =
+ if (v1 == null)
+ v2 == null
+ else if (v2 == null)
+ false
+ else
+ (v1, v2) match {
+ case (d1 : Double, d2 : Double) =>
+ d1 == d2
+ case (f1 : Float, f2 : Float) =>
+ f1 == f2
+ case (i1 : Int, i2 : Int) =>
+ i1 == i2
+ case (l1 : Long, l2 : Long) =>
+ l1 == l2
+ case ((l1, r1), (l2, r2)) =>
+ same(l1, l2) && same(r1, r2)
+ case (r1 : AnyRef, r2 : AnyRef) =>
+ r1 eq r2
+ case _ =>
+ sys.error(s"same: comparison of $v1 and $v2, should not be reached")
+ }
+
+ /**
+ * An ordering that says two values are equal if `same` says they
+ * are, otherwise earlier elements are greater than later ones.
+ */
+ class TOrdering[T] extends Ordering[T] {
+ def compare(a : T, b : T) : Int =
+ if (same(a, b)) 0 else 1
+ }
+
+ /**
+ * Compare two `Iterable` collections or options and tuples containing that kind of
+ * collection. Use `same` to compare the individual elements in the same order.
+ */
+ def sameCollection(v1 : Any, v2 : Any) : Boolean =
+ if (v1 == null)
+ v2 == null
+ else if (v2 == null)
+ false
+ else
+ (v1, v2) match {
+ case (Some(s1), Some(s2)) =>
+ sameCollection(s1, s2)
+ case ((t1, t2), (t3, t4)) =>
+ sameCollection(t1, t3) && sameCollection(t2, t4)
+ case (t1 : Iterable[_], t2 : Iterable[_]) =>
+ (t1.size == t2.size) && t1.zip(t2).forall(Function.tupled(sameCollection))
+ case _ =>
+ same(v1, v2)
+ }
+
+ /**
+ * Compare two `Seq` collections or options and tuples containing that kind of
+ * collection. Use `same` to compare the individual elements in any order.
+ */
+ def sameElements[T](t1 : Seq[_], t2 : Seq[_]) : Boolean =
+ (t1.size == t2.size) && (t1.forall(contains(t2, _)))
+
+ /**
+ * Does the iterable `s` contain `t`? Equality is tested using `same`.
+ */
+ def contains[T](s : Iterable[T], t : T) : Boolean =
+ s.exists(same(_, t))
+
+ /**
+ * Return a vector with only the distinct elements from the sequence `s`.
+ * "distinct" in this case means compare using `same`.
+ */
+ def distinct[T](s : Seq[T]) : Vector[T] = {
+ val set = new TreeSet[T]()(new TOrdering[T])
+ set ++= s
+ set.toVector
+ }
+
+ /**
+ * Return the first zero-based index at which `elem` occurs in `s` using `same`
+ * to perform comparisons, or -1 if `elem` does not occur in `s`.
+ */
+ def indexOf[T](s : Seq[T], elem : T) : Int =
+ s.indexWhere(same(_, elem))
+
+ /**
+ * Return the last zero-based index at which `elem` occurs in `s` using `same`
+ * to perform comparisons, or -1 if `elem` does not occur in `s`.
+ */
+ def lastIndexOf[T](s : Seq[T], elem : T) : Int =
+ s.lastIndexWhere(same(_, elem))
+
+}
+
diff --git a/common/src/test/scala/scalan/BaseTests.scala b/common/src/test/scala/scalan/BaseTests.scala
index 905adda285..64a8c7f615 100644
--- a/common/src/test/scala/scalan/BaseTests.scala
+++ b/common/src/test/scala/scalan/BaseTests.scala
@@ -1,27 +1,30 @@
package scalan
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.funspec.AnyFunSpec
+
import scala.language.implicitConversions
-import org.scalatest.words.ResultOfStringPassedToVerb
-import org.scalatest.{FlatSpec, _}
+import org.scalatest.verbs.ResultOfStringPassedToVerb
+import org.scalatest.funsuite.AnyFunSuite
/**
* Standard base class for most test suites. See BaseNestedTests and BaseShouldTests for alternatives
*
* See http://doc.scalatest.org/2.2.4/#org.scalatest.FunSuite.
*/
-abstract class BaseTests extends FunSuite with TestUtils
+abstract class BaseTests extends AnyFunSuite with TestUtils
/**
* Standard base class for test suites with nested tests.
*
* See http://doc.scalatest.org/2.2.4/#org.scalatest.FunSpec.
*/
-abstract class BaseNestedTests extends FunSpec with TestUtils
+abstract class BaseNestedTests extends AnyFunSpec with TestUtils
/**
* See http://doc.scalatest.org/2.2.4/#org.scalatest.FlatSpec.
*/
-abstract class BaseShouldTests extends FlatSpec with TestUtils {
+abstract class BaseShouldTests extends AnyFlatSpec with TestUtils {
protected final class InAndIgnoreMethods2(resultOfStringPassedToVerb: ResultOfStringPassedToVerb) {
import resultOfStringPassedToVerb.rest
diff --git a/common/src/test/scala/scalan/TestUtils.scala b/common/src/test/scala/scalan/TestUtils.scala
index 0e1645f71d..a583f590af 100644
--- a/common/src/test/scala/scalan/TestUtils.scala
+++ b/common/src/test/scala/scalan/TestUtils.scala
@@ -2,7 +2,8 @@ package scalan
import scalan.util.FileUtil
import org.scalactic.TripleEquals
-import org.scalatest.{Inside, Matchers, TestSuite}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.{Inside, TestSuite}
import scalan.util.StringUtil.StringUtilExtensions
/**
diff --git a/common/src/test/scala/sigmastate/VersionTestingProperty.scala b/common/src/test/scala/sigmastate/VersionTestingProperty.scala
index f6d8b6c400..bfa6cace28 100644
--- a/common/src/test/scala/sigmastate/VersionTestingProperty.scala
+++ b/common/src/test/scala/sigmastate/VersionTestingProperty.scala
@@ -1,13 +1,14 @@
package sigmastate
import org.scalactic.source.Position
-import org.scalatest.{PropSpec, Tag}
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatest.Tag
/** Decorator trait which allows to redefine `property` so that it is executed repeatedly for each valid
* [[VersionContext]], which is properly initialized.
* Thus, the properties can be versioned using `VersionContext.current`.
*/
-trait VersionTestingProperty extends PropSpec with VersionTesting {
+trait VersionTestingProperty extends AnyPropSpec with VersionTesting {
/** Redefine `property` so that testFun is executed repeatedly for each valid
* [[VersionContext]] */
diff --git a/core/src/main/scala/scalan/TypeDescs.scala b/core/src/main/scala/scalan/TypeDescs.scala
index fb3c276001..97689c169d 100644
--- a/core/src/main/scala/scalan/TypeDescs.scala
+++ b/core/src/main/scala/scalan/TypeDescs.scala
@@ -233,15 +233,6 @@ abstract class TypeDescs extends Base { self: Scalan =>
final def unapply[T, E <: Elem[T]](s: Ref[T]): Nullable[E] = Nullable(s.elem.asInstanceOf[E])
- /** Get unique method name suitable to be used as HashMap key. */
- def methodKey(m: Method) = {
- val ann = m.getDeclaredAnnotation(classOf[OverloadId])
- if (ann != null)
- s"${m.getName}_${ann.value}"
- else
- m.getName
- }
-
/** Build a mapping between methods of staged class and the corresponding methods of source class.
* The methods are related using names.
* The computed mapping can be used to project MethodCalls IR nodes back to the corresponding
@@ -255,7 +246,7 @@ abstract class TypeDescs extends Base { self: Scalan =>
def declaredMethods(cls: Class[_], srcCls: Class[_], methodNames: Set[String]): Seq[(Method, MethodDesc)] = {
val rmethods = cls.getDeclaredMethods.filter(m => methodNames.contains(m.getName))
val smethods = srcCls.getDeclaredMethods.filter(m => methodNames.contains(m.getName))
- val mapping = CollectionUtil.joinSeqs(rmethods, smethods)(methodKey, methodKey)
+ val mapping = CollectionUtil.joinSeqs(rmethods, smethods)(_.getName, _.getName)
mapping.map { case (rm, sm) =>
(rm, RMethodDesc(sm))
}.toSeq
@@ -273,7 +264,7 @@ abstract class TypeDescs extends Base { self: Scalan =>
val specCls = wrapSpec.getClass
val wMethods = wcls.getDeclaredMethods.filter(m => methodNames.contains(m.getName))
val specMethods = specCls.getDeclaredMethods.filter(m => methodNames.contains(m.getName))
- val mapping = CollectionUtil.joinSeqs(wMethods, specMethods)(methodKey, methodKey)
+ val mapping = CollectionUtil.joinSeqs(wMethods, specMethods)(_.getName, _.getName)
mapping.map { case (wm, sm) =>
(wm, WMethodDesc(wrapSpec, sm))
}.toSeq
diff --git a/core/src/main/scala/scalan/primitives/Thunks.scala b/core/src/main/scala/scalan/primitives/Thunks.scala
index c6d7eb63e1..6f1dc80918 100644
--- a/core/src/main/scala/scalan/primitives/Thunks.scala
+++ b/core/src/main/scala/scalan/primitives/Thunks.scala
@@ -2,7 +2,7 @@ package scalan.primitives
import scala.language.{existentials, implicitConversions}
import scalan.compilation.{GraphVizConfig, GraphVizExport}
-import scalan.{Liftable => _, _}
+import scalan._
import debox.{Set => DSet, Buffer => DBuffer}
import debox.cfor
diff --git a/docs/LangSpec.md b/docs/LangSpec.md
index b564744b8d..77f03e7023 100644
--- a/docs/LangSpec.md
+++ b/docs/LangSpec.md
@@ -56,7 +56,7 @@ The following sections describe ErgoScript and its operations.
#### ErgoScript language features overview
-- syntax borrowed from Scala and Kotlin
+- syntax borrowed from Scala
- standard syntax and semantics for well known constructs (operations, code blocks, if branches etc.)
- high-order language with first-class lambdas which are used in collection operations
- call-by-value (eager evaluation)
@@ -105,11 +105,11 @@ Type Name | Description
`Coll[T]` | a collection of arbitrary length with all values of type `T`
`(T1,T2)` | a pair of values where T1, T2 can be different types
-The type constructors `Coll`, `Option`, `(_,_)` can be used to construct complex
+The type constructors `Coll`, `(_,_)` can be used to construct complex
types as in the following example.
```scala
{
- val keyValues = OUTPUTS(0).R4[Coll[(Int, Option[Int])]].get
+ val keyValues = OUTPUTS(0).R4[Coll[(Int, (Byte, Long))]].get
...
}
```
@@ -170,8 +170,8 @@ class Numeric {
}
```
-All the predefined numeric types inherit Numeric class and its method.
-Internally they are pre-defined like the following.
+All the predefined numeric types inherit Numeric class and its methods.
+They can be thought as being pre-defined like the following.
```scala
class Byte extends Numeric
@@ -208,7 +208,10 @@ class Context {
/** Box whose proposition is being currently executing */
def SELF: Box
-
+
+ /** Zero based index in `inputs` of `selfBox` */
+ def selfBoxIndex: Int
+
/** A collection of inputs of the current transaction, the transaction where
* selfBox is one of the inputs.
*/
@@ -235,7 +238,13 @@ class Context {
def headers: Coll[Header]
/** Header fields that are known before the block is mined. */
- def preHeader: PreHeader
+ def preHeader: PreHeader
+
+ /** Bytes of encoded miner's public key.
+ * Same as `preHeader.minerPk.getEncoded`
+ */
+ def minerPubKey: Coll[Byte]
+
}
/** Represents data of the block headers available in scripts. */
@@ -313,7 +322,7 @@ class PreHeader {
/** Block height */
def height: Int
- /** Miner public key. Should be used to collect block rewards. */
+ /** Miner's public key. Should be used to collect block rewards. */
def minerPk: GroupElement
/** Miner votes for changing system parameters. */
@@ -424,9 +433,16 @@ class Box {
Besides properties, every box can have up to 10 numbered registers.
The following syntax is supported to access registers on box objects:
```
-box.R3[Int].get // access R3 register, check that its value of type Int and return it
-box.R3[Int].isDefined // check that value of R3 is defined and has type Int
-box.R3[Int].getOrElse(d) // access R3 value if defined, otherwise return `d`
+// access R3 register, check that its value of type Int and return it
+box.R3[Int].get
+
+// check that value of R3 is defined and has type Int
+box.R3[Int].isDefined
+
+// access R3 register, if it is defined and of type Int then return it,
+// if not of type Int then throw exception,
+// if not defined then return `d`
+box.R3[Int].getOrElse(d)
```
#### GroupElement
@@ -453,6 +469,40 @@ class GroupElement {
}
```
+#### SigmaProp
+```scala
+/** Proposition which can be proven and verified by sigma protocol. */
+trait SigmaProp {
+ /** Serialized bytes of this sigma proposition.
+ * In order to have comparisons like `box.propositionBytes == prop.propBytes`
+ * this SigmaProp is converted to ErgoTree as:
+ * 1. prop converted to [[SigmaPropConstant]]
+ * 2. new ErgoTree created with with ErgoTree.DefaultHeader, EmptyConstant and SigmaPropConstant as the root
+ *
+ * Thus obtained ErgoTree is serialized using DefaultSerializer and compared with `box.propositionBytes`.
+ */
+ def propBytes: Coll[Byte]
+
+ /** Logical AND between this SigmaProp and the `other` SigmaProp.
+ * This constructs a new CAND node of a sigma tree with two children. */
+ def &&(other: SigmaProp): SigmaProp
+
+ /** Logical AND between this `SigmaProp` and the `Boolean` value on the right.
+ * The boolean value will be wrapped into `SigmaProp` using the `sigmaProp` function.
+ * This constructs a new CAND node of a sigma tree with two children. */
+ def &&(other: Boolean): SigmaProp
+
+ /** Logical OR between this SigmaProp and the other SigmaProp.
+ * This constructs a new COR node of sigma tree with two children. */
+ def ||(other: SigmaProp): SigmaProp
+
+ /** Logical OR between this `SigmaProp` and the `Boolean` value on the right.
+ * The boolean value will be wrapped into `SigmaProp` using the `sigmaProp` function.
+ * This constructs a new COR node of a sigma tree with two children. */
+ def ||(other: Boolean): SigmaProp
+}
+```
+
#### AvlTree
```scala
@@ -818,23 +868,8 @@ def xorOf(conditions: Coll[Boolean]): Boolean
*/
def atLeast(k: Int, properties: Coll[SigmaProp]): SigmaProp
-/** Special function to represent explicit Zero Knowledge Scope in ErgoScript code.
- * Compiler checks Zero Knowledge properties and issue error message is case of violations.
- * ZK-scoping is optional, it can be used when the user want to ensure Zero Knowledge of
- * specific set of operations.
- * Usually it will require simple restructuring of the code to make the scope body explicit.
- * Invariants checked by the compiler:
- * - single ZKProof in ErgoTree in a root position
- * - no boolean operations in the body, because otherwise the result may be disclosed
- * - all the operations are over SigmaProp values
- *
- * For motivation and details see
- * https://github.com/ScorexFoundation/sigmastate-interpreter/issues/236
- */
-def ZKProof(block: SSigmaProp): Boolean
-
/** Embedding of Boolean values to SigmaProp values. As an example, this
- * operation allows boolean experesions to be used as arguments of
+ * operation allows boolean expressions to be used as arguments of
* `atLeast(..., sigmaProp(myCondition), ...)` operation.
*/
def sigmaProp(condition: Boolean): SigmaProp
@@ -867,8 +902,7 @@ def decodePoint(bytes: Coll[Byte]): GroupElement
* evaluate to a valid value of the `Option[Int]` type.
*
* For example `val x = getVar[Int](10)` expects the variable, if it is present, to have
- * type `Int`. At runtime the corresponding type descriptor is passed as `cT`
- * parameter.
+ * type `Int`.
*
* There are three cases:
* 1) If the variable doesn't exist.
@@ -894,13 +928,13 @@ def decodePoint(bytes: Coll[Byte]): GroupElement
* val tag = tagOpt.get
* if (tag == 1) {
* val x = getVar[Int](id2).get
- * // compute res using value x is of type Int
+ * // compute res when value x is of type Int
* } else if (tag == 2) {
* val x = getVar[GroupElement](id2).get
- * // compute res using value x is of type GroupElement
+ * // compute res when value x is of type GroupElement
* } else if (tag == 3) {
* val x = getVar[ Array[Byte] ](id2).get
- * // compute res using value x of type Array[Byte]
+ * // compute res when value x of type Array[Byte]
* } else {
* // compute `res` when `tag` is not 1, 2 or 3
* }
diff --git a/docs/notes.md b/docs/notes.md
index 059336de58..cc75f1065d 100644
--- a/docs/notes.md
+++ b/docs/notes.md
@@ -5,15 +5,7 @@ These dependencies can be removed with refactoring
| Jar | Size, Kb |
|---------------|---------------|
-| kiama_2.12-2.1.0.jar | 652 |
| - jline-2.14.3.jar | 268 |
-| - scallop_2.12-2.1.1.jar | 348 |
-| - dsprofile_2.12-0.4.0.jar | 49 |
-| - dsprofile_2.12-0.4.0.jar | 49 |
-| - dsinfo_2.12-0.4.0.jar | 15 |
-| - jsr305-3.0.2.jar | 20 |
-| com.typesafe.config:config-1.3.3.jar | 286 |
-| commons-io-2.5.jar | 209 |
| cats-core_2.12-1.4.0.jar | 4400 |
| - cats-kernel_2.12-1.4.0.jar | 3200 |
| - algebra_2.12-0.7.0.jar | 1100 |
diff --git a/library-api/src/main/scala/special/SpecialPredef.scala b/library-api/src/main/scala/special/SpecialPredef.scala
index 9c0bbdca99..9152f55d09 100644
--- a/library-api/src/main/scala/special/SpecialPredef.scala
+++ b/library-api/src/main/scala/special/SpecialPredef.scala
@@ -1,7 +1,7 @@
package special
import scala.reflect.ClassTag
-import scalan.{Reified, RType}
+import scalan.RType
object SpecialPredef {
def loopUntil[A](s1: A, isMatch: A => Boolean, step: A => A): A = {
@@ -15,7 +15,7 @@ object SpecialPredef {
def some[A](x: A): Option[A] = Some(x)
- @Reified("A") def none[A](implicit tA: RType[A]): Option[A] = Option.empty[A]
+ def none[A](implicit tA: RType[A]): Option[A] = Option.empty[A]
def optionGetOrElse[A](opt: Option[A], default: A): A = opt.getOrElse(default)
diff --git a/library-api/src/main/scala/special/collection/Colls.scala b/library-api/src/main/scala/special/collection/Colls.scala
index a2b7630e9e..555be23415 100644
--- a/library-api/src/main/scala/special/collection/Colls.scala
+++ b/library-api/src/main/scala/special/collection/Colls.scala
@@ -322,7 +322,7 @@ trait CollBuilder {
/** Construct a new collection from the given list of arguments.
* The arguments should be of the same type for which there should be
* an implicit type descriptor at the call site. */
- @Reified("T") def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T]
+ def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T]
/** Deconstruct collection of (A,B) pairs into pair of collections.
* If `xs` is represented as PairColl, then this is O(1) operation (no data is touched). */
diff --git a/library-api/src/main/scala/special/wrappers/WrappersSpec.scala b/library-api/src/main/scala/special/wrappers/WrappersSpec.scala
index baefa6aa3e..0765ba3358 100644
--- a/library-api/src/main/scala/special/wrappers/WrappersSpec.scala
+++ b/library-api/src/main/scala/special/wrappers/WrappersSpec.scala
@@ -1,8 +1,6 @@
package special.wrappers
-import scala.reflect.ClassTag
-import special.SpecialPredef
-import scalan.{NeverInline, RType, WrapSpec}
+import scalan.{RType, WrapSpec}
trait WrapSpecBase extends WrapSpec {
}
@@ -10,14 +8,14 @@ trait WrapSpecBase extends WrapSpec {
/** Wrappers spec for Option */
trait OptionWrapSpec extends WrapSpecBase {
def get[A](xs: Option[A]): A = xs.get
- @NeverInline // TODO codegen: convertion to Thunk is required
+ // TODO codegen: convertion to Thunk is required
def getOrElse[A](xs: Option[A], default: => A): A = xs.getOrElse(default)
def map[A,B](xs: Option[A], f: A => B): Option[B] = xs.map(f)
def flatMap[A,B](xs: Option[A], f: A => Option[B]): Option[B] = xs.flatMap(f)
def filter[A](xs: Option[A], f: A => Boolean): Option[A] = xs.filter(f)
def isDefined[A](xs: Option[A]): Boolean = xs.isDefined
def isEmpty[A](xs: Option[A]): Boolean = xs.isEmpty
- @NeverInline // TODO codegen: fold should have single section, and convertion to Thunk is required
+ // TODO codegen: fold should have single section, and convertion to Thunk is required
def fold[A,B](xs: Option[A], ifEmpty: =>B, f: A => B): B = xs.fold(ifEmpty)(f)
};
diff --git a/library-impl/src/main/scala/special/collection/CollsOverArrays.scala b/library-impl/src/main/scala/special/collection/CollsOverArrays.scala
index 97ef53ed17..6f7c87695d 100644
--- a/library-impl/src/main/scala/special/collection/CollsOverArrays.scala
+++ b/library-impl/src/main/scala/special/collection/CollsOverArrays.scala
@@ -1,13 +1,9 @@
package special.collection
import java.util
-import java.util.Objects
-import special.SpecialPredef
-
-import scala.reflect.ClassTag
import scalan._
import scalan.util.CollectionUtil
-import scalan.{RType, Reified}
+import scalan.RType
import Helpers._
import debox.Buffer
import scalan.RType._
@@ -187,7 +183,6 @@ class CollOverArrayBuilder extends CollBuilder { builder =>
pairCollFromArrays(resA, resB)(tA, tB)
}
- @Reified("T")
override def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T] = cT match {
case pt: PairType[a,b] =>
val tA = pt.tFst
diff --git a/library/src/main/scala/special/collection/CollsUnit.scala b/library/src/main/scala/special/collection/CollsUnit.scala
index 5571d4b8f6..f43e31e689 100644
--- a/library/src/main/scala/special/collection/CollsUnit.scala
+++ b/library/src/main/scala/special/collection/CollsUnit.scala
@@ -6,7 +6,7 @@ package special.collection {
import CollBuilder._;
import PairColl._;
import WOption._;
- @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait Coll[A] extends Def[Coll[A]] {
+ trait Coll[A] extends Def[Coll[A]] {
implicit def eA: Elem[A];
def builder: Ref[CollBuilder];
def length: Ref[Int];
@@ -25,22 +25,22 @@ package special.collection {
def indices: Ref[Coll[Int]];
def flatMap[B](f: Ref[scala.Function1[A, Coll[B]]]): Ref[Coll[B]];
def segmentLength(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int];
- @NeverInline def find(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = delayInvoke;
+ def find(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = delayInvoke;
def indexWhere(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int];
- @NeverInline def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = delayInvoke;
+ def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = delayInvoke;
def lastIndexWhere(p: Ref[scala.Function1[A, Boolean]], end: Ref[Int]): Ref[Int];
def take(n: Ref[Int]): Ref[Coll[A]];
def patch(from: Ref[Int], patch: Ref[Coll[A]], replaced: Ref[Int]): Ref[Coll[A]];
def updated(index: Ref[Int], elem: Ref[A]): Ref[Coll[A]];
def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[A]]): Ref[Coll[A]];
def unionSet(that: Ref[Coll[A]]): Ref[Coll[A]];
- @NeverInline def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke;
- @NeverInline def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke;
+ def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke;
+ def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke;
def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[A]];
def append(other: Ref[Coll[A]]): Ref[Coll[A]];
def reverse: Ref[Coll[A]]
};
- @WithMethodCallRecognizers trait PairColl[L, R] extends Coll[scala.Tuple2[L, R]] {
+ trait PairColl[L, R] extends Coll[scala.Tuple2[L, R]] {
implicit def eL: Elem[L];
implicit def eR: Elem[R];
def ls: Ref[Coll[L]];
@@ -48,9 +48,9 @@ package special.collection {
def mapFirst[T1](f: Ref[scala.Function1[L, T1]]): Ref[Coll[scala.Tuple2[T1, R]]];
def mapSecond[T1](f: Ref[scala.Function1[R, T1]]): Ref[Coll[scala.Tuple2[L, T1]]]
};
- @Liftable @WithMethodCallRecognizers trait CollBuilder extends Def[CollBuilder] {
+ trait CollBuilder extends Def[CollBuilder] {
def pairColl[A, B](as: Ref[Coll[A]], bs: Ref[Coll[B]]): Ref[PairColl[A, B]];
- @Reified(value = "T") def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]];
+ def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]];
def unzip[A, B](xs: Ref[Coll[scala.Tuple2[A, B]]]): Ref[scala.Tuple2[Coll[A], Coll[B]]];
def xor(left: Ref[Coll[Byte]], right: Ref[Coll[Byte]]): Ref[Coll[Byte]];
def replicate[T](n: Ref[Int], v: Ref[T]): Ref[Coll[T]];
diff --git a/library/src/main/scala/wrappers/scala/WOptions.scala b/library/src/main/scala/wrappers/scala/WOptions.scala
index 02b9082aa0..34c7a26035 100644
--- a/library/src/main/scala/wrappers/scala/WOptions.scala
+++ b/library/src/main/scala/wrappers/scala/WOptions.scala
@@ -4,16 +4,16 @@ package wrappers.scala {
import special.wrappers.WrappersModule
trait WOptions extends Base { self: WrappersModule =>
- @External("Option") @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait WOption[A] extends Def[WOption[A]] {
+ trait WOption[A] extends Def[WOption[A]] {
implicit def eA: Elem[A];
- @External def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B];
- @External def isEmpty: Ref[Boolean];
- @External def isDefined: Ref[Boolean];
- @External def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]];
- @External def flatMap[B](f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]];
- @External def map[B](f: Ref[scala.Function1[A, B]]): Ref[WOption[B]];
- @External def getOrElse[B](default: Ref[Thunk[B]]): Ref[B];
- @External def get: Ref[A]
+ def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B];
+ def isEmpty: Ref[Boolean];
+ def isDefined: Ref[Boolean];
+ def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]];
+ def flatMap[B](f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]];
+ def map[B](f: Ref[scala.Function1[A, B]]): Ref[WOption[B]];
+ def getOrElse[B](default: Ref[Thunk[B]]): Ref[B];
+ def get: Ref[A]
};
trait WOptionCompanion
}
diff --git a/library/src/main/scala/wrappers/scalan/WRTypes.scala b/library/src/main/scala/wrappers/scalan/WRTypes.scala
index 26566be4a7..07795cdada 100644
--- a/library/src/main/scala/wrappers/scalan/WRTypes.scala
+++ b/library/src/main/scala/wrappers/scalan/WRTypes.scala
@@ -13,9 +13,9 @@ package wrappers.scalan {
trait WRTypes extends Base { self: WrappersModule =>
import WRType._;
- @External("RType") @Liftable @WithMethodCallRecognizers trait WRType[A] extends Def[WRType[A]] {
+ trait WRType[A] extends Def[WRType[A]] {
implicit def eA: Elem[A];
- @External def name: Ref[String]
+ def name: Ref[String]
};
trait WRTypeCompanion
}
diff --git a/library/src/main/scala/wrappers/special/WSpecialPredefs.scala b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala
index fc7f0c7401..6a5731fa06 100644
--- a/library/src/main/scala/wrappers/special/WSpecialPredefs.scala
+++ b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala
@@ -6,13 +6,13 @@ package wrappers.special {
trait WSpecialPredefs extends Base { self: WrappersModule =>
import WOption._;
import WSpecialPredef._;
- @External("SpecialPredef") @WithMethodCallRecognizers trait WSpecialPredef extends Def[WSpecialPredef];
+ trait WSpecialPredef extends Def[WSpecialPredef];
trait WSpecialPredefCompanion {
- @External def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A];
- @External def none[@Reified A](implicit emA: Elem[A]): Ref[WOption[A]];
- @External def some[A](x: Ref[A]): Ref[WOption[A]];
- @External def cast[@Reified T](v: Ref[Any])(implicit emT: Elem[T]): Ref[WOption[T]];
- @External def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A]
+ def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A];
+ def none[A](implicit emA: Elem[A]): Ref[WOption[A]];
+ def some[A](x: Ref[A]): Ref[WOption[A]];
+ def cast[T](v: Ref[Any])(implicit emT: Elem[T]): Ref[WOption[T]];
+ def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A]
}
}
}
\ No newline at end of file
diff --git a/library/src/test/scala/special/collections/CollsTests.scala b/library/src/test/scala/special/collections/CollsTests.scala
index b22822e2aa..b8a8339276 100644
--- a/library/src/test/scala/special/collections/CollsTests.scala
+++ b/library/src/test/scala/special/collections/CollsTests.scala
@@ -2,7 +2,8 @@ package special.collections
import org.scalacheck.Gen
import org.scalatest.exceptions.TestFailedException
-import org.scalatest.{Matchers, PropSpec}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import scalan._
import sigmastate.{VersionContext, VersionTestingProperty}
@@ -10,7 +11,7 @@ import special.collection.{Coll, CollOverArray, PairOfCols}
import scala.language.{existentials, implicitConversions}
-class CollsTests extends PropSpec with ScalaCheckPropertyChecks with Matchers with CollGens with VersionTestingProperty { testSuite =>
+class CollsTests extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with CollGens with VersionTestingProperty { testSuite =>
import Gen._
import special.collection.ExtensionMethods._
diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala
index 8b265e3310..a6864a3302 100644
--- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala
+++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala
@@ -2,7 +2,6 @@ package special.sigma
import java.math.BigInteger
-import org.bouncycastle.math.ec.ECPoint
import special.collection._
import scalan._
import scorex.crypto.authds.{ADDigest, ADValue}
@@ -15,8 +14,6 @@ import scala.util.Try
* which is used for all cryptographic operations).
* So it is globally and implicitly used in all methods.
* */
-@scalan.Liftable
-@WithMethodCallRecognizers
trait BigInt {
/** Convert this BigInt value to Byte.
* @throws ArithmeticException if overflow happens.
@@ -99,7 +96,7 @@ trait BigInt {
* @return { @code this + that}
*/
def add(that: BigInt): BigInt
- @Internal def +(that: BigInt): BigInt = add(that)
+ def +(that: BigInt): BigInt = add(that)
/** Returns a BigInt whose value is {@code (this - that)}.
*
@@ -107,7 +104,7 @@ trait BigInt {
* @return { @code this - that}
*/
def subtract(that: BigInt): BigInt
- @Internal def -(that: BigInt): BigInt = subtract(that)
+ def -(that: BigInt): BigInt = subtract(that)
/** Returns a BigInt whose value is {@code (this * that)}.
*
@@ -117,7 +114,7 @@ trait BigInt {
* @return { @code this * that}
*/
def multiply(that: BigInt): BigInt
- @Internal def *(that: BigInt): BigInt = multiply(that)
+ def *(that: BigInt): BigInt = multiply(that)
/** Returns a BigInt whose value is {@code (this / that)}.
*
@@ -126,7 +123,7 @@ trait BigInt {
* @throws ArithmeticException if { @code that} is zero.
*/
def divide(that: BigInt): BigInt
- @Internal def /(that: BigInt): BigInt = divide(that)
+ def /(that: BigInt): BigInt = divide(that)
/**
* Returns a BigInt whose value is {@code (this mod m}). This method
@@ -139,7 +136,7 @@ trait BigInt {
* @see #remainder
*/
def mod(m: BigInt): BigInt
- @Internal def %(m: BigInt): BigInt = mod(m)
+ def %(m: BigInt): BigInt = mod(m)
/**
* Returns a BigInt whose value is {@code (this % that)}.
@@ -182,7 +179,7 @@ trait BigInt {
* @return `this & that`
*/
def and(that: BigInt): BigInt
- @Internal def &(that: BigInt): BigInt = and(that)
+ def &(that: BigInt): BigInt = and(that)
/** Returns a BigInteger whose value is `(this | that)`. (This
* method returns a negative BigInteger if and only if either `this` or `that`` is
@@ -192,15 +189,14 @@ trait BigInt {
* @return `this | that`
*/
def or(that: BigInt): BigInt
- @Internal def |(that: BigInt): BigInt = or(that)
+ def |(that: BigInt): BigInt = or(that)
}
/** Base class for points on elliptic curves.
*/
-@scalan.Liftable
-@WithMethodCallRecognizers
trait GroupElement {
- def isInfinity: Boolean
+ /** Checks if the provided element is an identity element. */
+ def isIdentity: Boolean
/** Exponentiate this GroupElement
to the given number.
* @param k The power.
@@ -224,8 +220,6 @@ trait GroupElement {
}
/** Proposition which can be proven and verified by sigma protocol. */
-@scalan.Liftable
-@WithMethodCallRecognizers
trait SigmaProp {
def isValid: Boolean
/** Serialized bytes of this sigma proposition taken as ErgoTree and then serialized. */
@@ -233,26 +227,14 @@ trait SigmaProp {
/** Logical AND between this SigmaProp and other SigmaProp.
* This constructs a new CAND node of sigma tree with two children. */
- @OverloadId("and_sigma") def &&(other: SigmaProp): SigmaProp
-
- /** Logical AND between this `SigmaProp` and `Boolean` value on the right.
- * The boolean value will be wrapped into `SigmaProp` using `sigmaProp` function.
- * This constructs a new CAND node of sigma tree with two children. */
- @OverloadId("and_bool") def &&(other: Boolean): SigmaProp
+ def &&(other: SigmaProp): SigmaProp
/** Logical OR between this SigmaProp and other SigmaProp.
* This constructs a new COR node of sigma tree with two children. */
- @OverloadId("or_sigma") def ||(other: SigmaProp): SigmaProp
-
- /** Logical OR between this `SigmaProp` and `Boolean` value on the right.
- * The boolean value will be wrapped into `SigmaProp` using `sigmaProp` function.
- * This constructs a new COR node of sigma tree with two children. */
- @OverloadId("or_bool") def ||(other: Boolean): SigmaProp
+ def ||(other: SigmaProp): SigmaProp
}
/** Represents any value paired with type descriptor. */
-@scalan.Liftable
-@WithMethodCallRecognizers
trait AnyValue {
/** The data value wrapped by this instance. */
def value: Any
@@ -263,8 +245,6 @@ trait AnyValue {
/** Runtime representation of Ergo boxes used during execution of ErgoTree operations.
* @see [[org.ergoplatform.ErgoBox]]
*/
-@scalan.Liftable
-@WithMethodCallRecognizers
trait Box {
/** Blake2b256 hash of this box's content, basically equals to `blake2b256(bytes)` */
def id: Coll[Byte]
@@ -341,32 +321,32 @@ trait Box {
* different from cT.
* @since 2.0
*/
- def getReg[@Reified T](i: Int)(implicit cT: RType[T]): Option[T]
+ def getReg[T](i: Int)(implicit cT: RType[T]): Option[T]
/** Mandatory: Monetary value, in Ergo tokens */
- def R0[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](0)
+ def R0[T](implicit cT:RType[T]): Option[T] = this.getReg[T](0)
/** Mandatory: Guarding script */
- def R1[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](1)
+ def R1[T](implicit cT:RType[T]): Option[T] = this.getReg[T](1)
/** Mandatory: Secondary tokens */
- def R2[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](2)
+ def R2[T](implicit cT:RType[T]): Option[T] = this.getReg[T](2)
/** Mandatory: Reference to transaction and output id where the box was created */
- def R3[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](3)
+ def R3[T](implicit cT:RType[T]): Option[T] = this.getReg[T](3)
/** Non-mandatory register */
- def R4[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](4)
+ def R4[T](implicit cT:RType[T]): Option[T] = this.getReg[T](4)
/** Non-mandatory register */
- def R5[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](5)
+ def R5[T](implicit cT:RType[T]): Option[T] = this.getReg[T](5)
/** Non-mandatory register */
- def R6[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](6)
+ def R6[T](implicit cT:RType[T]): Option[T] = this.getReg[T](6)
/** Non-mandatory register */
- def R7[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](7)
+ def R7[T](implicit cT:RType[T]): Option[T] = this.getReg[T](7)
/** Non-mandatory register */
- def R8[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](8)
+ def R8[T](implicit cT:RType[T]): Option[T] = this.getReg[T](8)
/** Non-mandatory register */
- def R9[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](9)
+ def R9[T](implicit cT:RType[T]): Option[T] = this.getReg[T](9)
/** Secondary tokens */
def tokens: Coll[(Coll[Byte], Long)]
@@ -384,9 +364,8 @@ trait Box {
* @return result of the script execution in the current context
* @since Mainnet
*/
- def executeFromRegister[@Reified T](regId: Byte)(implicit cT:RType[T]): T
+ def executeFromRegister[T](regId: Byte)(implicit cT:RType[T]): T
- @Internal
override def toString = s"Box(id=$id; value=$value; regs=$registers)"
}
@@ -399,7 +378,6 @@ trait Box {
*
* This interface is used as runtime representation of the AvlTree type of ErgoTree.
*/
-@scalan.Liftable
trait AvlTree {
/** Returns digest of the state represented by this tree.
* Authenticated tree digest = root hash bytes ++ tree height
@@ -554,7 +532,6 @@ trait AvlTreeVerifier {
/** Only header fields that can be predicted by a miner.
* @since 2.0
*/
-@scalan.Liftable
trait PreHeader { // Testnet2
/** Block version, to be increased on every soft and hardfork. */
def version: Byte
@@ -582,7 +559,6 @@ trait PreHeader { // Testnet2
/** Represents data of the block header available in Sigma propositions.
* @since 2.0
*/
-@scalan.Liftable
trait Header {
/** Bytes representation of ModifierId of this Header */
def id: Coll[Byte]
@@ -636,8 +612,6 @@ trait Header {
/** Runtime representation of Context ErgoTree type.
* Represents data available in Sigma language using `CONTEXT` global variable.
*/
-@scalan.Liftable
-@WithMethodCallRecognizers
trait Context {
def builder: SigmaDslBuilder
@@ -656,22 +630,21 @@ trait Context {
/** Box whose proposition is being currently executing */
def SELF: Box
- /** Zero based index in `inputs` of `selfBox`. -1 if self box is not in the INPUTS collection. */
+ /** Zero based index in `inputs` of `selfBox`. */
def selfBoxIndex: Int
/** Authenticated dynamic dictionary digest representing Utxo state before current state. */
def LastBlockUtxoRootHash: AvlTree
- /** A fixed number of last block headers in descending order (first header is the newest one)
- * @since 2.0
- */
+ /** A fixed number of last block headers in descending order (first header is the newest one) */
def headers: Coll[Header]
- /**
- * @since 2.0
- */
+ /** Fields of a new block header, that can be predicted by a miner before block's formation */
def preHeader: PreHeader
+ /** Bytes of encoded miner's public key.
+ * Same as `preHeader.minerPk.getEncoded`
+ */
def minerPubKey: Coll[Byte]
/** Extracts Context variable by id and type.
@@ -743,12 +716,9 @@ trait Context {
def currentErgoTreeVersion: Byte
}
-@scalan.Liftable
trait SigmaContract {
def builder: SigmaDslBuilder
- @NeverInline
- @Reified("T")
def Collection[T](items: T*)(implicit cT: RType[T]): Coll[T] = this.builder.Colls.fromItems[T](items:_*)
/** !!! all methods should delegate to builder */
@@ -779,7 +749,6 @@ trait SigmaContract {
def decodePoint(encoded: Coll[Byte]): GroupElement = this.builder.decodePoint(encoded)
- @Reified("T")
def substConstants[T](scriptBytes: Coll[Byte],
positions: Coll[Int],
newValues: Coll[T]): Coll[Byte] = this.builder.substConstants(scriptBytes, positions, newValues)
@@ -795,8 +764,6 @@ trait SigmaContract {
*
* @see SGlobal.WrappedType, CostingSigmaDslBuilder
*/
-@scalan.Liftable
-@WithMethodCallRecognizers
trait SigmaDslBuilder {
/** Access to collection operations. */
@@ -887,7 +854,6 @@ trait SigmaDslBuilder {
* @param newValues new values to be injected into the corresponding positions in ErgoTree.constants array
* @return original scriptBytes array where only specified constants are replaced and all other bytes remain exactly the same
*/
- @Reified("T")
def substConstants[T](scriptBytes: Coll[Byte], positions: Coll[Int], newValues: Coll[T]): Coll[Byte]
/** Decodes the given bytes to the corresponding GroupElement using default serialization.
@@ -897,10 +863,10 @@ trait SigmaDslBuilder {
def decodePoint(encoded: Coll[Byte]): GroupElement
/** Create DSL big integer from existing `java.math.BigInteger`*/
- @Internal def BigInt(n: BigInteger): BigInt
+ def BigInt(n: BigInteger): BigInt
/** Extract `java.math.BigInteger` from DSL's `BigInt` type*/
- @Internal def toBigInteger(n: BigInt): BigInteger
+ def toBigInteger(n: BigInt): BigInteger
/** Construct a new authenticated dictionary with given parameters and tree root digest. */
def avlTree(operationFlags: Byte, digest: Coll[Byte], keyLength: Int, valueLengthOpt: Option[Int]): AvlTree
diff --git a/sigma-api/src/main/scala/special/sigma/package.scala b/sigma-api/src/main/scala/special/sigma/package.scala
index b02b187ea5..dcbb71ef64 100644
--- a/sigma-api/src/main/scala/special/sigma/package.scala
+++ b/sigma-api/src/main/scala/special/sigma/package.scala
@@ -2,7 +2,6 @@ package special
import java.math.BigInteger
-import org.bouncycastle.math.ec.ECPoint
import scalan.RType
import scalan.RType.GeneralType
@@ -30,5 +29,4 @@ package object sigma {
implicit val SigmaDslBuilderRType: RType[SigmaDslBuilder] = RType.fromClassTag(classTag[SigmaDslBuilder])
implicit val BigIntegerRType: RType[BigInteger] = GeneralType(classTag[BigInteger])
- implicit val ECPointRType: RType[ECPoint] = GeneralType(classTag[ECPoint])
}
\ No newline at end of file
diff --git a/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala
index 5634a05d6d..5bd2ad784b 100644
--- a/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala
+++ b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala
@@ -3,7 +3,7 @@ package special.sigma {
import scalan._
trait SigmaDsl extends Base { self: SigmaLibrary =>
- @Liftable @WithMethodCallRecognizers trait BigInt extends Def[BigInt] {
+ trait BigInt extends Def[BigInt] {
def toByte: Ref[Byte];
def toShort: Ref[Short];
def toInt: Ref[Int];
@@ -28,28 +28,24 @@ package special.sigma {
def max(that: Ref[BigInt]): Ref[BigInt];
def negate: Ref[BigInt]
};
- @Liftable @WithMethodCallRecognizers trait GroupElement extends Def[GroupElement] {
+ trait GroupElement extends Def[GroupElement] {
def isInfinity: Ref[Boolean];
def exp(k: Ref[BigInt]): Ref[GroupElement];
def multiply(that: Ref[GroupElement]): Ref[GroupElement];
def negate: Ref[GroupElement];
def getEncoded: Ref[Coll[Byte]]
};
- @Liftable @WithMethodCallRecognizers trait SigmaProp extends Def[SigmaProp] {
+ trait SigmaProp extends Def[SigmaProp] {
def isValid: Ref[Boolean];
def propBytes: Ref[Coll[Byte]];
- @OverloadId(value = "and_sigma") def &&(other: Ref[SigmaProp]): Ref[SigmaProp];
- // manual fix
- @OverloadId(value = "and_bool") def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp];
- @OverloadId(value = "or_sigma") def ||(other: Ref[SigmaProp]): Ref[SigmaProp];
- // manual fix
- @OverloadId(value = "or_bool") def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp];
+ def &&(other: Ref[SigmaProp]): Ref[SigmaProp];
+ def ||(other: Ref[SigmaProp]): Ref[SigmaProp];
};
- @Liftable @WithMethodCallRecognizers trait AnyValue extends Def[AnyValue] {
+ trait AnyValue extends Def[AnyValue] {
def value: Ref[Any];
def tVal: Ref[WRType[Any]]
};
- @Liftable @WithMethodCallRecognizers trait Box extends Def[Box] {
+ trait Box extends Def[Box] {
def id: Ref[Coll[Byte]];
def value: Ref[Long];
def propositionBytes: Ref[Coll[Byte]];
@@ -71,7 +67,7 @@ package special.sigma {
def creationInfo: Ref[scala.Tuple2[Int, Coll[Byte]]];
def executeFromRegister[T](regId: Ref[Byte])(implicit cT: Elem[T]): Ref[T]
};
- @Liftable trait AvlTree extends Def[AvlTree] {
+ trait AvlTree extends Def[AvlTree] {
def digest: Ref[Coll[Byte]];
def enabledOperations: Ref[Byte];
def keyLength: Ref[Int];
@@ -88,7 +84,7 @@ package special.sigma {
def update(operations: Ref[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]];
def remove(operations: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]]
};
- @Liftable trait PreHeader extends Def[PreHeader] {
+ trait PreHeader extends Def[PreHeader] {
def version: Ref[Byte];
def parentId: Ref[Coll[Byte]];
def timestamp: Ref[Long];
@@ -97,7 +93,7 @@ package special.sigma {
def minerPk: Ref[GroupElement];
def votes: Ref[Coll[Byte]]
};
- @Liftable trait Header extends Def[Header] {
+ trait Header extends Def[Header] {
def id: Ref[Coll[Byte]];
def version: Ref[Byte];
def parentId: Ref[Coll[Byte]];
@@ -114,7 +110,7 @@ package special.sigma {
def powDistance: Ref[BigInt];
def votes: Ref[Coll[Byte]]
};
- @Liftable @WithMethodCallRecognizers trait Context extends Def[Context] {
+ trait Context extends Def[Context] {
def builder: Ref[SigmaDslBuilder];
def OUTPUTS: Ref[Coll[Box]];
def INPUTS: Ref[Coll[Box]];
@@ -129,7 +125,7 @@ package special.sigma {
def getVar[T](id: Ref[Byte])(implicit cT: Elem[T]): Ref[WOption[T]];
def vars: Ref[Coll[AnyValue]]
};
- @Liftable @WithMethodCallRecognizers trait SigmaDslBuilder extends Def[SigmaDslBuilder] {
+ trait SigmaDslBuilder extends Def[SigmaDslBuilder] {
def Colls: Ref[CollBuilder];
def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean];
def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp];
@@ -147,7 +143,7 @@ package special.sigma {
def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp];
def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp];
def groupGenerator: Ref[GroupElement];
- @Reified(value = "T") def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]]): Ref[Coll[Byte]];
+ def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]]): Ref[Coll[Byte]];
def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement];
def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree];
def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]]
diff --git a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala
index efdbd3fc23..8195aed696 100644
--- a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala
+++ b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala
@@ -908,14 +908,6 @@ object SigmaProp extends EntityObject("SigmaProp") {
true, false, element[SigmaProp]))
}
- // manual fix &&
- override def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = {
- asRep[SigmaProp](mkMethodCall(self,
- SigmaPropClass.getMethod("$amp$amp", classOf[Sym], classOf[Overloaded1]),
- Array[AnyRef](other, o),
- true, false, element[SigmaProp]))
- }
-
// manual fix ||
override def ||(other: Ref[SigmaProp]): Ref[SigmaProp] = {
asRep[SigmaProp](mkMethodCall(self,
@@ -923,14 +915,6 @@ object SigmaProp extends EntityObject("SigmaProp") {
Array[AnyRef](other),
true, false, element[SigmaProp]))
}
-
- // manual fix ||
- override def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = {
- asRep[SigmaProp](mkMethodCall(self,
- SigmaPropClass.getMethod("$bar$bar", classOf[Sym], classOf[Overloaded1]),
- Array[AnyRef](other, o),
- true, false, element[SigmaProp]))
- }
}
implicit object LiftableSigmaProp
@@ -978,14 +962,6 @@ object SigmaProp extends EntityObject("SigmaProp") {
true, true, element[SigmaProp]))
}
- // manual fix &&
- def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = {
- asRep[SigmaProp](mkMethodCall(source,
- SigmaPropClass.getMethod("$amp$amp", classOf[Sym], classOf[Overloaded1]),
- Array[AnyRef](other, o),
- true, true, element[SigmaProp]))
- }
-
// manual fix ||
def ||(other: Ref[SigmaProp]): Ref[SigmaProp] = {
asRep[SigmaProp](mkMethodCall(source,
@@ -994,28 +970,6 @@ object SigmaProp extends EntityObject("SigmaProp") {
true, true, element[SigmaProp]))
}
- // manual fix ||
- def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = {
- asRep[SigmaProp](mkMethodCall(source,
- SigmaPropClass.getMethod("$bar$bar", classOf[Sym], classOf[Overloaded1]),
- Array[AnyRef](other, o),
- true, true, element[SigmaProp]))
- }
-
- def lazyAnd(other: Ref[Thunk[SigmaProp]]): Ref[SigmaProp] = {
- asRep[SigmaProp](mkMethodCall(source,
- SigmaPropClass.getMethod("lazyAnd", classOf[Sym]),
- Array[AnyRef](other),
- true, true, element[SigmaProp]))
- }
-
- def lazyOr(other: Ref[Thunk[SigmaProp]]): Ref[SigmaProp] = {
- asRep[SigmaProp](mkMethodCall(source,
- SigmaPropClass.getMethod("lazyOr", classOf[Sym]),
- Array[AnyRef](other),
- true, true, element[SigmaProp]))
- }
-
// manual fix
def builder: Ref[SigmaDslBuilder] = {
asRep[SigmaDslBuilder](mkMethodCall(source,
@@ -1040,7 +994,7 @@ object SigmaProp extends EntityObject("SigmaProp") {
override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = {
super.collectMethods ++
Elem.declaredMethods(classOf[SigmaProp], classOf[SSigmaProp], Set(
- "isValid", "propBytes", "$amp$amp", "$amp$amp", "$bar$bar", "$bar$bar"
+ "isValid", "propBytes", "$amp$amp", "$bar$bar"
))
}
}
@@ -1084,7 +1038,7 @@ object SigmaProp extends EntityObject("SigmaProp") {
object and_sigma_&& {
def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = d match {
- case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_sigma" } =>
+ case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] =>
val res = (receiver, args(0))
Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[SigmaProp])]]
case _ => Nullable.None
@@ -1092,35 +1046,15 @@ object SigmaProp extends EntityObject("SigmaProp") {
def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = unapply(exp.node)
}
- object and_bool_&& {
- def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[Boolean])] = d match {
- case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_bool" } =>
- val res = (receiver, args(0))
- Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[Boolean])]]
- case _ => Nullable.None
- }
- def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[Boolean])] = unapply(exp.node)
- }
-
object or_sigma_|| {
def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = d match {
- case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_sigma" } =>
+ case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] =>
val res = (receiver, args(0))
Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[SigmaProp])]]
case _ => Nullable.None
}
def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = unapply(exp.node)
}
-
- object or_bool_|| {
- def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[Boolean])] = d match {
- case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_bool" } =>
- val res = (receiver, args(0))
- Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[Boolean])]]
- case _ => Nullable.None
- }
- def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[Boolean])] = unapply(exp.node)
- }
}
object SigmaPropCompanionMethods {
diff --git a/sigmastate/src/main/java/gf2t/GF2_192.java b/sigmastate/src/main/java/gf2t/GF2_192.java
deleted file mode 100644
index dc0c166bcf..0000000000
--- a/sigmastate/src/main/java/gf2t/GF2_192.java
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- By Leonid Reyzin
-
- This is free and unencumbered software released into the public domain.
-
- Anyone is free to copy, modify, publish, use, compile, sell, or
- distribute this software, either in source code form or as a compiled
- binary, for any purpose, commercial or non-commercial, and by any
- means.
-
- In jurisdictions that recognize copyright laws, the author or authors
- of this software dedicate any and all copyright interest in the
- software to the public domain. We make this dedication for the benefit
- of the public at large and to the detriment of our heirs and
- successors. We intend this dedication to be an overt act of
- relinquishment in perpetuity of all present and future rights to this
- software under copyright law.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
- For more information, please refer to
- */
-package gf2t;
-
-import java.util.Arrays;
-
-public class GF2_192 {
- private final long [] word = new long[3];
-
- /**
- *
- * @param obj the field element with which to compare
- * @return true if and only if this and that represent the same field element
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true; // equal references
- if (obj instanceof GF2_192) {
- GF2_192 that = (GF2_192)obj;
- return this.word[0]==that.word[0] && this.word[1]==that.word[1] && this.word[2]==that.word[2];
- }
- return false; // different types
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(word);
- }
-
- // using irreducible polynomial x^192+x^7+x^2+x+1
- // We need only the last word
- static private final long irredPentanomial = (1L<<7) | (1L<<2) | (1L<<1) | 1L;
-
- // irredPentanomial times 0, 1, x, x+1, x^2, x^2+1, x^2+x, x^2+x+1, x^3, x^3+1, x^3+x, x^3+x+1, x^3+x^2, x^3+x^2+1, x^3+x^2+x, x^3+x^2x+1,
- // Need only the last word, because the leading two words are 0
- static private final long [] irredMuls = {0L, irredPentanomial, irredPentanomial<<1, (irredPentanomial<<1)^irredPentanomial,
- irredPentanomial<<2, (irredPentanomial<<2)^irredPentanomial, (irredPentanomial<<2)^(irredPentanomial<<1), (irredPentanomial<<2)^(irredPentanomial<<1)^irredPentanomial,
- irredPentanomial<<3, (irredPentanomial<<3)^irredPentanomial, (irredPentanomial<<3)^(irredPentanomial<<1), (irredPentanomial<<3)^(irredPentanomial<<1)^irredPentanomial,
- (irredPentanomial<<3)^(irredPentanomial<<2), (irredPentanomial<<3)^(irredPentanomial<<2)^irredPentanomial, (irredPentanomial<<3)^(irredPentanomial<<2)^(irredPentanomial<<1), (irredPentanomial<<3)^(irredPentanomial<<2)^(irredPentanomial<<1)^irredPentanomial
-
- };
-
- /**
- * returns the 0 field element
- */
- public GF2_192() {
- }
-
- /**
- * returns a copy of the field element
- * @param that element to copy
- */
- public GF2_192(GF2_192 that) {
- this.word[0] = that.word[0];
- this.word[1] = that.word[1];
- this.word[2] = that.word[2];
- }
-
- /**
- * returns the field element whose 32 least significant bits are bits of that and rest are 0
- * @param that lower 32 bits
- */
- public GF2_192(int that) {
- this.word[0] = ((long) that) & 0xFFFFFFFFL;
- }
-
- /**
- * returns the field element whose bits are given by the long array
- * @param that must be length 3
- */
- public GF2_192(long [] that) {
- assert (that.length == 3);
- this.word[0] = that[0];
- this.word[1] = that[1];
- this.word[2] = that[2];
- }
-
- /**
- * returns the field element whose bits are given by the byte array that
- * @param that must be length 24
- */
- public GF2_192(byte [] that) {
- this(that, 0);
- }
-
- /**
- * returns the field element whose bits are given by the byte array that[pos]...that[pos+23]
- * @param that must be length at least pos+24
- */
- public GF2_192(byte [] that, int pos) {
- assert (that.length >= pos+24);
- for (int i = 0; i<8; i++) {
- word[0] |= (((long)that[i+pos] & 0xFF))<<(i<<3);
- }
- for (int i = 0; i<8; i++) {
- word[1] |= (((long)that[i+pos+8] & 0xFF))<<(i<<3);
- }
- for (int i = 0; i<8; i++) {
- word[2] |= (((long)that[i+pos+16] & 0xFF))<<(i<<3);
- }
- }
-
- /**
- *
- * @return long array of length 3 containing the three words of the field element
- */
- public long [] toLongArray() {
- long [] ret = new long[3];
- ret[0] = word[0];
- ret[1] = word[1];
- ret[2] = word[2];
- return ret;
- }
-
- /**
- *
- * @return byte array of length 24 containing the two words of the field element
- */
- public byte[] toByteArray() {
- byte [] ret = new byte[24];
- toByteArray(ret, 0);
- return ret;
- }
-
- /**
- * @param ret bytes of the field element will go into ret[pos]...ret[pos+23]
- */
- public void toByteArray(byte[] ret, int pos) {
- assert(ret.length>=pos+24);
- for (int j = 0; j<3; j++) {
- for (int i = 0; i < 8; i++) {
- ret[pos+i+8*j] = (byte) ((word[j] >> (i << 3)) & 0xFF);
- }
- }
- }
-
-
-
- /**
- *
- * @return true if this == 0, false otherwise
- */
- public boolean isZero () {
- return word[0]==0L && word[1]==0L && word[2]==0L;
- }
-
- /**
- *
- * @return true if this == 1, false otherwise
- */
- public boolean isOne () {
- return word[0]==1L && word[1]==0L && word[2]==0L;
- }
-
- /**
- * Computes a plus b and puts the result into res.
- * @param res output; must be not null; may be equal to a and/or b
- * @param a multiplicand; may be equal to res, in which case will get overwritten
- * @param b multiplier; may be equal to res, in which case will get overwritten
- */
-
- public static void add (GF2_192 res, GF2_192 a, GF2_192 b) {
- res.word[0] = a.word[0]^b.word[0];
- res.word[1] = a.word[1]^b.word[1];
- res.word[2] = a.word[2]^b.word[2];
- }
-
-
-
- /**
- * Computes a times b and puts the result into res.
- * Uses table lookups, which may not preserve
- * the secrecy of the inputs in case of side-channel attacks.
- *
- * @param res output; must be not null; may be equal to a and/or b
- * @param a multiplicand; may be equal to res, in which case will get overwritten
- * @param b multiplier; may be equal to res, in which case will get overwritten
- */
- public static void mul (GF2_192 res, GF2_192 a, GF2_192 b) {
-
- // Implements a sort of times-x-and-add algorithm, except instead of multiplying by x
- // we multiply by x^4 and then add one of possible 16 precomputed values
-
- // contains a*0, a*1, a*x, a*(x+1), a*x^2, a*(x^2+1), a*(x^2+x), a*(x^2+x+1)
- // a*x^3, a*(x^3+1), a*(x^3+x), a*(x^3+x+1), a*(x^3+x^2), a*(x^3+x^2+1), a*(x^3+x^2+x), a*(x^3+x^2+x+1), all mod reduced
- // First word of each is in a0 muls, second word of each is in a1muls, third word of each is in a2muls
- long [] a0muls = new long[16];
- long [] a1muls = new long[16];
- long [] a2muls = new long[16];
-
- // a0muls[0], a1muls[0] and a2muls[0] are already correctly initialized to 0
-
- a0muls[1] = a.word[0];
- a1muls[1] = a.word[1];
- a2muls[1] = a.word[2];
-
- // a*x, a*x^2, a*x^3
- for (int i = 2; i<=8; i*=2) {
- // multiply a*x^{log_2 i/2} by x to get a*x^{log_2 i}
- int prev = i / 2;
- a0muls[i] = a0muls[prev] << 1;
- a1muls[i] = (a1muls[prev] << 1) | (a0muls[prev] >>> 63);
- a2muls[i] = (a2muls[prev] << 1) | (a1muls[prev] >>> 63);
- // mod reduce
- a0muls[i] ^= irredMuls[(int) (a2muls[prev] >>> 63)];
- }
-
- // a*(x+1)
- a0muls[3] = a0muls[1] ^ a0muls[2];
- a1muls[3] = a1muls[1] ^ a1muls[2];
- a2muls[3] = a2muls[1] ^ a2muls[2];
-
-
- // a*(x^2+1), a*(x^2+x), a*(x^2+x+1)
- for (int i = 1; i<4; i++) {
- a0muls[4|i] = a0muls[4]^a0muls[i];
- a1muls[4|i] = a1muls[4]^a1muls[i];
- a2muls[4|i] = a2muls[4]^a2muls[i];
- }
-
- // a*(x^3+1), a*(x^3+x), a*(x^3+x+1), a*(x^3+x^2), a*(x^3+x^2+1), a*(x^3+x^2+x), a*(x^3+x^2+x+1)
- for (int i = 1; i<8; i++) {
- a0muls[8|i] = a0muls[8]^a0muls[i];
- a1muls[8|i] = a1muls[8]^a1muls[i];
- a2muls[8|i] = a2muls[8]^a2muls[i];
- }
-
- long w0 = 0, w1 = 0, w2 = 0;
- for (int j = 2; j>=0; j--) {
- long multiplier = b.word[j];
- for (int i = 60; i >= 0; i -= 4) {
- // Multiply by x^4
- int modReduceIndex = (int) (w2 >>> 60);
- w2 = (w2 << 4) | (w1 >>> 60);
- w1 = (w1 << 4) | (w0 >>> 60);
- // MOD REDUCE ACCORDING TO modReduceIndex by XORing the right value
- w0 = (w0 << 4) ^ irredMuls[modReduceIndex];
- //w0 = (w0<<4)^(irredPentanomial*(modReduceIndex&8))^(irredPentanomial*(modReduceIndex&4))^(irredPentanomial*(modReduceIndex&2))^(irredPentanomial*(modReduceIndex&1));
-
- // Add the correct multiple of a
- int index = (int) ((multiplier >>> i) & 15);
- w0 ^= a0muls[index];
- w1 ^= a1muls[index];
- w2 ^= a2muls[index];
- }
- }
- res.word[0] = w0;
- res.word[1] = w1;
- res.word[2] = w2;
- }
-
- /**
- * Computes a times b and puts the result into res. More efficient than mul(res, a, new GF2_192(b))
- * @param res output; must be not null; may be equal to a and/or b
- * @param a multiplicand; may be equal to res, in which case will get overwritten
- * @param b multiplier; may be equal to res, in which case will get overwritten
- */
- public static void mul (GF2_192 res, GF2_192 a, byte b) {
-
- long w0 = 0, w1 = 0, w2 = 0, w3=0;
-
- for (int i = 7; i >= 0; i--) {
- w3 = w2 >>> 63;
- w2 = (w2 << 1) | (w1 >>> 63);
- w1 = (w1 << 1) | (w0 >>> 63);
- w0 <<= 1;
- long t = (b >>> i) & 1;
- w2 ^= a.word[2] * t;
- w1 ^= a.word[1] * t;
- w0 ^= (a.word[0] * t) ^ (irredPentanomial * w3); // mod reduce
- }
- res.word[0] = w0;
- res.word[1] = w1;
- res.word[2] = w2;
- }
-
-
- public static void invert (GF2_192 res, GF2_192 z) {
- // Computes z^{2^192-2} = z^{exponent written in binary as 191 ones followed by a single zero}
- // (by Fermat's little theorem, this is the correct inverse)
-
- // contains z raised to the power whose binary representation is 2^k ones
- GF2_192 zTo2ToK1s = new GF2_192(z);
-
- // Square res to get its exponent to be 10 in binary
- mul(res, z, z);
-
- // contains z raised to the power whose binary representation is 2^k ones followed by 2^k zeros
- GF2_192 zTo2ToK1s2ToK0s = new GF2_192(res);
-
-
- // Loop invariant
- // res contains z raised to the power whose binary representation is 2^{k+1}-1 ones followed by a single zero
- // zTo2ToK1s contains z raised to the power whose binary representation is 2^k ones
- // zTo2ToK1s2ToK0s contains z raised to the power whose binary representation is 2^k ones followed by 2^k zeros
- int k = 0;
- while (k<6) {
- k++;
- // Fill in the zeros in the exponent of zTo2ToK1s2ToK0s with ones
- mul(zTo2ToK1s, zTo2ToK1s2ToK0s, zTo2ToK1s);
- // zTo2ToK1s2ToK0s = power2To2ToK with 2^k zeros appended to the exponent
- power2To2ToK(zTo2ToK1s2ToK0s, zTo2ToK1s, k);
- // prepend 2^k ones to res
- mul(res, res, zTo2ToK1s2ToK0s);
- }
- // Prepened another 64 ones to res
- power2To2ToK(zTo2ToK1s2ToK0s, zTo2ToK1s2ToK0s, k);
- mul(res, res, zTo2ToK1s2ToK0s);
- }
-
-
-
- // These tables are used in power2To2ToK and sqr -- see explanation in power2To2ToK. They take up about about 14KB.
-
- private static final long [][] powTable0 = {
- {1L,4L,16L,64L,256L,1024L,4096L,16384L,65536L,262144L,1048576L,4194304L,16777216L,67108864L,268435456L,1073741824L,4294967296L,17179869184L,68719476736L,274877906944L,1099511627776L,4398046511104L,17592186044416L,70368744177664L,281474976710656L,1125899906842624L,4503599627370496L,18014398509481984L,72057594037927936L,288230376151711744L,1152921504606846976L,4611686018427387904L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,135L,540L,2160L,8640L,34560L,138240L,552960L,2211840L,8847360L,35389440L,141557760L,566231040L,2264924160L,9059696640L,36238786560L,144955146240L,579820584960L,2319282339840L,9277129359360L,37108517437440L,148434069749760L,593736278999040L,2374945115996160L,9499780463984640L,37999121855938560L,151996487423754240L,607985949695016960L,2431943798780067840L,-8718968878589280256L,2017612633061982208L,8070450532247928832L,-4611686018427387904L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,270L,1080L,4199L,},
- {1L,16L,256L,4096L,65536L,1048576L,16777216L,268435456L,4294967296L,68719476736L,1099511627776L,17592186044416L,281474976710656L,4503599627370496L,72057594037927936L,1152921504606846976L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,135L,2160L,34560L,552960L,8847360L,141557760L,2264924160L,36238786560L,579820584960L,9277129359360L,148434069749760L,2374945115996160L,37999121855938560L,607985949695016960L,-8718968878589280256L,8070450532247928832L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,1080L,16405L,262480L,4199680L,67194880L,1075118080L,17201889280L,275230228480L,4403683655680L,70458938490880L,1127343015854080L,18037488253665280L,288599812058644480L,4617596992938311680L,94575592174780416L,1513209474796486656L,5764607523034234880L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,540L,8640L,138375L,2214635L,35434160L,566946560L,9071144960L,145138319360L,2322213109760L,37155409756160L,594486556098560L,9511784897576960L,152188558361231360L,2435016933779701760L,2066782793056124928L,-3824963458521104384L,-5859183115209015296L,-1513209474796486656L,-5764607523034234880L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,270L,4199L,65620L,1048694L,16777290L,},
- {1L,65536L,4294967296L,281474976710656L,0L,0L,0L,0L,0L,0L,0L,0L,135L,8847360L,579820584960L,37999121855938560L,0L,0L,0L,0L,0L,0L,0L,0L,16405L,1075118080L,70458938490880L,4617596992938311680L,0L,0L,0L,0L,0L,0L,0L,0L,2214635L,145138319360L,9511784897576960L,-3824963458521104384L,0L,0L,0L,0L,0L,0L,0L,4199L,268435729L,17592203935744L,1152922677132918784L,76842668642009088L,0L,0L,0L,0L,0L,0L,0L,552960L,36238823415L,2374947531325440L,8070608823267622912L,-8072983807038324736L,0L,0L,0L,0L,0L,0L,1080L,67194880L,4403688133701L,288600105530228736L,5783840476780036096L,6072259672578981888L,0L,0L,0L,0L,0L,0L,138375L,9071137756L,594486085783387L,2066751970480947200L,-7784595809881817088L,-8116893903405187072L,0L,0L,0L,0L,0L,270L,16777290L,1099511627845L,72057594037993729L,4311810048L,282578783305728L,72339069014638592L,0L,0L,0L,0L,0L,34560L,2264924160L,148434069749895L,-8718968878580398201L,582094356480L,38148135746273280L,-8680969756733341696L,0L,0L,0L,0L,0L,4199680L,275230228480L,18037488253681685L,1513209475875820821L,70735243837440L,4635704940130467840L,6130806467734798336L,0L,0L,0L,0L,8640L,566946560L,37155409756160L,2435016933781924651L,-1513209329119911445L,9547060033028096L,-1513172181595455488L,2444047222778626048L,0L,0L,0L,0L,1048694L,68719546624L,4503604207554663L,300166943871232L,1224996759836561425L,1157443864920915968L,1229500363472633856L,1157706579210928128L,0L,0L,0L,2160L,141557895L,9277138794240L,607986568019867760L,40522537422618480L,-646134085450172169L,8680969174647242752L,-38147594580393984L,8716435603798884352L,0L,0L,0L,262480L,17201906733L,1127344162226488L,94650720833590632L,4923631783780892776L,4685244537110860101L,6130877201840930816L,4635630379498209280L,1244400872037810176L,0L,0L,540L,35434160L,2322211272620L,152188437960410523L,-5867073703402003989L,-608753751841641685L,5021550739930207323L,2435017087666290688L,-1503124363304501248L,-3144919914788159488L,0L,0L,65620L,4294967417L,281474976710691L,16L,118L,65641L,},
- {1L,0L,0L,268435729L,0L,0L,72057594037993729L,0L,8640L,1224996759836561425L,0L,2322211272620L,4295032833L,0L,-3824963458521104384L,1152940269605290257L,67194880L,-8116893903405048697L,72340168543043841L,18037488253681685L,2444084377648024256L,1152940269335812193L,4923631783780892776L,8706684044243276764L,575525617665L,0L,2214635L,6917686146403139857L,0L,594486068876182L,109923151000961281L,0L,-1508668585977835444L,-42651198216466415L,17201907249L,-1503124363304500630L,37718226699878401L,4617597137004134400L,-3834029160147512970L,-79200059939786479L,5542457468742751288L,72653179618366162L,-8718686828065942650L,6157755589565773013L,-427524231241125731L,-7636548200255303383L,2349380831670242920L,-1503122247285515780L,1L,16405L,36240966940L,268435729L,4403688133701L,-8718374392512378660L,72057594037993729L,1513209475874772323L,2019996756866529500L,1224996759976022166L,4684963044965832011L,5021552416478667632L,37999126150971393L,4684939972385783829L,-4989366934530337413L,-6920043528899271987L,72339069031416121L,-8680822410973408226L,-6391613922127811155L,1153203052884328721L,5891559298491384716L,-7528422813418094127L,35172261L,-608824726141909180L,575525617798L,9441498026213649L,3487211355411353591L,6917686182105090782L,-4416945885376472588L,6063073012436278090L,-8753160638328035514L,-5605497289716500368L,-5610075583180945114L,90149276037394458L,339026464814167628L,369965729453364929L,-3860411569319034860L,-7219661873698413202L,-7217141859998432150L,1806743557951716919L,-8790878027314019100L,-8686366285709925551L,-9018771827274447141L,-3500033589960484657L,-6239661070421212278L,-7022774006793486301L,-5486222289147287496L,6557835543537224962L,1L,4403688117328L,268435729L,268435729L,1513213877407514960L,72057594037993729L,72057594179551622L,6054338822752200080L,1224996759836570065L,1262995881831960726L,4685176399308498684L,2326506170314L,-8110982924599230463L,-7012597109688626096L,-2672024288427437773L,1760926221464557073L,-8193431732091728425L,-8188932805459047229L,-702248183304599069L,2358520128326754357L,3596724480578929564L,2653562374675748729L,7558329885135416404L,8706684602589025248L,611764439881L,-4354323463508992325L,6917686146405354490L,-1801282968903807655L,9071577101557338822L,109381790017557217L,8696092877002101742L,-4668327226503048164L,1475308329743286364L,128146801688724317L,-8390330629760215797L,-1531869438861569413L,-4617320090730090391L,5541920254930687988L,3761689569789112577L,-2327319826622658605L,-6182158405047794621L,-41970731974321979L,-4950437438052009930L,-3752274221890333889L,1476151931308439890L,5613176216134850767L,289726897646273736L,-1503122247017080678L,594453066058452L,4437244711257L,72057630278829085L,7782810071065752468L,-7925740857026315255L,-7637528022863553386L,-3839220191352824283L,6705067445074182019L,6637312287860931618L,-2154173082950753382L,-8117068327749574457L,4645236792527042077L,3567261728918198996L,-1570715894964224286L,3851762367547029496L,-1282481202581286367L,604372413954671920L,7336273916715742398L,8984291365106642911L,-3520346153016046579L,-3001672072993760708L,5487223282412062341L,3220238017403266817L,-7526201328351032492L,-6651737113209978849L,-876842992662428725L,2730222910065286284L,4666291884953713058L,27885208784216435L,-3464689086048100177L,9074463908856611112L,6089525621414736771L,-344374184071824754L,-4138339726157814851L,90460192285484837L,7003316425532605053L,2325362866034789830L,6377579351440235774L,-5484290407194710110L,3204252260295655770L,4952583157325034207L,-8782555314696362611L,-2316049681279009322L,-1127600795797440159L,7751601582170687883L,-6463181785702448409L,7121056025054547704L,6485777949499231279L,},
- {1L,-3006172399682371634L,2600966637154804214L,8641L,8525113116679455864L,-2145144163292000430L,2019996756799457565L,-1850476282776554867L,-4889822090580977265L,909561413152654253L,-25001132819151504L,7726439241120171362L,7303489125464870298L,4332131768403656981L,2962048663402138678L,-2892279489278463047L,-4733651509025142792L,1063143929388429494L,-1197895461363724390L,3525840681984842667L,-4695277565342099683L,5146529997701558317L,7435951619486932058L,-2724786844429777139L,40504930336318985L,876946985023164340L,5608484252067120944L,-6816077621382648259L,-4033654809715777901L,-4081572395912436435L,-8636364450456842826L,7120123665156854152L,-2739360841521830815L,4179210361336297309L,-5035580621240300693L,5024856697532411216L,-5583726119146644383L,1447126495187071743L,-2586987284404803098L,8837846401203718243L,6684981609574125625L,1540466829568951558L,-4848578993616133096L,531411902399629160L,-8097992882751386397L,5836923291160128631L,2657822116024759531L,5082038816076700909L,7237486007293790522L,5252165852497928096L,-6943891580396708852L,-2358876157997055033L,2004344792661408502L,6922719691033397220L,-6115771057843578790L,-882977230851385180L,4445218069992821756L,5905786485590667688L,-8952895028275913749L,6335857422495481096L,-1336747599306330073L,-295017526585807725L,6427842712075527612L,6136969228259728187L,8790718804228268581L,-7649524091336109629L,-5994405249073919640L,4313678309655720149L,1583534994170157977L,5606445082714174951L,6853837681080604556L,-8485637026077231303L,7790525872849806729L,5940658092022763209L,8602473577714766584L,2936249914771413453L,-5521212179187796747L,4711968172455986094L,-4922856425548406499L,130141881968551392L,3536227681426168034L,1538274929948045556L,2319096648797621624L,-390137264770768181L,8029329512101034001L,-7020589058068074770L,3265911137432880136L,8114665243288440240L,1727024161912275448L,7211866768629281013L,-3130723513389854793L,-7216856759928143716L,3533195878158403511L,3984449705890310687L,-8379049565896909567L,-8388101802220698225L,-1001505570555522767L,-2621811112096768870L,603025228237669646L,-4855786637640829169L,-8861801597506211630L,5171117103964917160L,-6016899467464669218L,574486107801798403L,1346751909104125183L,6265319601178024276L,3065092470199993307L,-3544361000120591516L,-6311655751958887780L,5850322626671860616L,-2175699856332693179L,2849507709866937883L,-5020421862032512214L,-4568858551591370457L,-2431265188066595845L,-8732538833975482925L,49029378622487761L,948188484528056399L,685766231005340987L,-6108229294291709748L,-6619503736528295873L,2499319692519687998L,-8241104250166498648L,-6283823462790380478L,-1799922584861092054L,-6240401189323759144L,5497064944286443280L,6723566846653152186L,-7200823809060633542L,-8991399666593498102L,3696845228942259783L,5525150667579715560L,949595271893899961L,4431634865357028469L,-7719973862985677490L,-6034475957088628470L,-4268733492881789978L,6756633516157056278L,-1957554544632307580L,7121101677918762223L,-2926994538817486764L,5070148293018691908L,-3164346027824263021L,-8065527601021753218L,-7393579279100902671L,1578925030408104064L,-5470498100570909442L,-9059484745764947078L,8728828886428453065L,876414647339389056L,-4691346483920214801L,271068101201614328L,-1328948676306083414L,-601927494426833593L,-1580410200329916588L,-4326051892200391110L,5551955200782384943L,214408676534699021L,892732170117421280L,-6779792031755998944L,8533716818059729780L,873315600166044946L,8844237596764485904L,4304845159865160138L,5606488036825769410L,425090181770096226L,-1135909175464444990L,-4725116773226449403L,5897643684611700155L,1650595387261410562L,-7317473568888247260L,-8317376280642525522L,524782793988048123L,-6713202495631135192L,-4939556292506913402L,-5609869695293186861L,-4230589026387944683L,-724065909912518572L,-2110301323783658314L,1029673643630214818L,-5297873999180537788L,-8928073349900829853L,7277641038077141425L,6527157727335254212L,-3946003823558145331L,8063768130289328687L,4522053259152859193L,675627983587702560L,-1137165482193899852L,8414663288495567717L,-8436820189876267996L,7876837133135388570L,},
- {1L,-5169860002514781635L,-2589809952505784534L,8777364680166470481L,-8830656417429304044L,3176782973934494582L,109797415759816827L,1076956885061792565L,7914398690249482831L,8011904680480159185L,8410793115243855507L,6266439534501642392L,-336875557465114730L,4038138302048025623L,-8101148793053570270L,1124933003446523927L,8391412732637477197L,2199881538445059432L,719775327569887587L,-4825086212853447750L,-7314323185577824224L,4891665885256984545L,7598126349271893834L,-3239373303059569532L,-659203789875424936L,7692138112394859210L,-193023354580355438L,1661409395237152970L,-867709405024660660L,-4774852438416084051L,1013518333030173816L,3485843496410831696L,188315317670329959L,-7626348485928744434L,4785373727715537048L,-2557360640145528783L,815573462730278215L,2725495643400585416L,763815832452911292L,-1234416280134845253L,3031628907175299520L,6164952807644926203L,-6906157987463386683L,8750285495619286011L,-2944268397760272112L,-8571087382226582932L,7349937386463951048L,7786267339579184516L,337223540666190292L,1366638621193514276L,5979097440737272663L,-8229072190234731287L,-7464767416008336370L,2196188713781264658L,-6606956754260663431L,8497668204436713713L,7806277383834821447L,591641631205476095L,6045490875774248095L,456224709346991991L,-7218871130131209394L,580163022797824109L,-3693397793970743538L,-1855672627986562453L,1785325366189117080L,-5612555377205332105L,-294341367983285122L,2445160339032774813L,7132278192002140706L,878326058396851309L,3921174184439993950L,5853022697017928950L,-2825405099755624515L,-7030859599219471492L,-8473806211642996024L,-8498195465917087535L,-4182645819142121229L,726866375401350017L,-4123860299531460321L,67135272333132065L,238539200704091067L,9069168069279185101L,-8554967853203633945L,-1798135605252717890L,-359730572749547446L,4493519132539194015L,4958647882027071589L,-911149761898967393L,-5156659928190548061L,1295304005530223213L,-6977343558102121156L,6922621878872799870L,6666583055979266042L,7292171483456095852L,-1969457853973942746L,-6898392144047603629L,5756338153240882170L,6504592230467093280L,169954543499997878L,8244762795686741102L,-7702335274149853320L,170612181012260678L,-1167924627447415726L,6330133554527618692L,-670458599026908667L,-5475429905606927886L,-4407322762187867157L,-8580599370684241560L,3285212811372363965L,7894963086517678484L,8569304869073834915L,-6544807253825008820L,-5996237358893605511L,-3042468804887085356L,2374190430796422836L,3894653610967932827L,3898642019578338045L,-5362019755573200863L,4402246476084717913L,3291977739464152007L,3674469931224113236L,-44278192132845207L,-146130534644405364L,5382065438553845456L,6785308159791913441L,4538149016807450869L,8422045206362267535L,-751406355315423454L,8999771730341663411L,-990169186945997877L,1777800203227879507L,-4856230533325857618L,6591273902673649307L,4756065680746518619L,-8504746896788247085L,4474109455375415963L,7512977545114097664L,-4994667515641620176L,-4624712674055432963L,-7581435093848090518L,-3374583368016299959L,-6772163028506140599L,-4597352927609652442L,7074576231879668500L,8699761606660221174L,-1460827062303528567L,8015141181709918285L,-1169566320418753181L,-4781112204804977330L,1888326456844245676L,8052564071464611668L,8677658026519325509L,8196795344534159240L,-6189127939919551760L,-756836619992549632L,3275904360037766197L,8063439441889441129L,-7331287930982412507L,5909316323417099098L,7555764543220595192L,5975647989155847506L,3542169932787954825L,3572787110578921974L,-4910033269362933281L,4127048709984103372L,-8249546761957136187L,2136513283148217767L,6914147571605817471L,-1401967832836965144L,8407424200159619086L,3198875950909199105L,2570623872214327259L,6598776223519113019L,-8548723600459949403L,1542874467657402904L,5132064706814079464L,-8697292868739094825L,7457266453233910833L,-1093418532865160497L,3247028061820159553L,-1424542897552112257L,5068257691790424406L,5880873780866162489L,-3102632713002543235L,1263997674554416274L,5364397535996490566L,-6980107079961147736L,-3471995143361337385L,6641708940048027257L,1135429108619021836L,5387343206428796059L,-6804247660018484977L,},
- {1L,1073223059898794450L,-2038813369256918412L,5304323081406240818L,3303538589997961255L,-8242543733483560526L,-3361776038394087875L,-7966401800695747134L,3661948208390050674L,6880986284844289330L,2763308461018415133L,1781656665212037754L,6138182394991053453L,-7512225217435664149L,-2696439080506022889L,-2583065046819908147L,-3131915636955022563L,-2889357217172249387L,-5802605454962117101L,-2436895282174351119L,-1766568650463350318L,-377122117525974673L,1776581853777064707L,-308611149542073169L,-540314814780534625L,8467843478952328360L,3468583091456007095L,505744836808219017L,-5428914123150493339L,-7776987036728855764L,-6102268671949303457L,3494341367960380577L,2418782979535889063L,4679473505413000143L,-6441695285033044392L,6265164336385959504L,-7246211974952246812L,-531598530841805554L,7617543382550044362L,7304030873573479981L,-32281324903020730L,5445701030230371763L,252311267739668938L,7731413305529340107L,4792829355971906114L,3012742833337443711L,7376323673068462242L,2937445380659696069L,9159469984575429466L,4180661836353763848L,9102205873245014544L,-9157654341755851144L,-5917184808139238532L,-913012161319772394L,3520965615244733154L,1105108204046932414L,3640346287517683383L,2610854371735641718L,3369140582718399805L,-167503450741461836L,7612537899180910062L,4647612969614095840L,3109561378106990004L,8745335350416839074L,-298291418130746473L,-2193685336892597509L,-3205646479549694138L,-6912700853529572321L,-5285985482282474664L,-8011420405948338685L,-20608671900365787L,2461277845240147045L,-8794182113545320389L,-4143692325726628162L,-5206060059250865124L,-7341828269574673748L,5997074990730119543L,-6983875851493091721L,5190016632970933241L,-1133665158084916157L,-7711757776416462528L,958657918611969015L,2998347888694802671L,-176777484057504605L,5157771292309956459L,-8999461217390585327L,4257577863211723393L,-3385462713578387432L,5581805654425926531L,-6981668768611461067L,6619449109488021267L,8273870493873208839L,6305391702152098821L,-7738026482851978733L,-7424370079506352431L,1130290113791392248L,5736936187682728875L,-1889540322116193194L,6918453404219483036L,-258362754443186269L,1740351069027290592L,2990762037699987674L,2598835903464008375L,-6081928830422087295L,5388584501900900268L,-3101635458397415306L,5560630914118636896L,5540181403154305832L,-5050504706493546867L,2482421493273885212L,8345872426056290435L,-114929197746482490L,-1411535166620560130L,1955447843789378400L,-4415727728018118178L,174849678320512726L,-5578523943478722759L,5785969583518444021L,-2232487152186233036L,3347165569852915762L,8597084251364200641L,-8637378221001354125L,1905787365039574668L,-5764297333239831537L,-6887855556896782846L,-7466419285184801288L,3561228892785125799L,-6025847770670435502L,7880903838892214728L,4831723645980851507L,-8700410925103051535L,5167047152144011193L,-5589950774695842572L,-6975863374495850197L,8636325743490381438L,-5393462740365964783L,758109935525139289L,8449824526047483324L,2882040775719318333L,8722862970638278922L,652288902771973384L,-5889783177719394690L,-3211436433657712007L,1362735929528070085L,8025013999877916656L,8057121196213509424L,-597152196419816458L,-3731606026680532941L,-6814641654656904693L,-2513538531416010165L,-1449817420573805572L,7983703381157839238L,4136435098211692276L,-1331213617861613522L,-289183771021882356L,-3100859045837937046L,536889653442631647L,1933334157013614393L,-3378838522188481907L,59059052034778512L,-9070778615901588520L,-8561634908355121490L,8646082716902511799L,-7190394898230747028L,2223190096772479452L,-625200368095748196L,-7695499964415613072L,-2925720374223602748L,7859320007538329711L,-8590024973885119823L,8447867896928955011L,-8341487853447061366L,1319006032904755853L,5631657808401138749L,2597687022492864406L,7575706244535104411L,-5270921382190007475L,3486972365953290955L,67197056587467249L,-542829327793657434L,-8188837871581890476L,-3908705513843534551L,-8566981112648480966L,-6798624665298914527L,9174760941175519307L,-5792872140589943835L,-2219700069287782459L,-6440926725540882731L,687123600828336407L,6695459205124198333L,5752186679888935902L,3823361293471306013L,},
- };
- private static final long [][] powTable1 = {
- {0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,1L,4L,16L,64L,256L,1024L,4096L,16384L,65536L,262144L,1048576L,4194304L,16777216L,67108864L,268435456L,1073741824L,4294967296L,17179869184L,68719476736L,274877906944L,1099511627776L,4398046511104L,17592186044416L,70368744177664L,281474976710656L,1125899906842624L,4503599627370496L,18014398509481984L,72057594037927936L,288230376151711744L,1152921504606846976L,4611686018427387904L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,2L,8L,33L,135L,540L,2160L,8640L,34560L,138240L,552960L,2211840L,8847360L,35389440L,141557760L,566231040L,2264924160L,9059696640L,36238786560L,144955146240L,579820584960L,2319282339840L,9277129359360L,37108517437440L,148434069749760L,593736278999040L,2374945115996160L,9499780463984640L,37999121855938560L,151996487423754240L,607985949695016960L,2431943798780067840L,-8718968878589280256L,2017612633061982208L,8070450532247928832L,-4611686018427387904L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,},
- {0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,1L,16L,256L,4096L,65536L,1048576L,16777216L,268435456L,4294967296L,68719476736L,1099511627776L,17592186044416L,281474976710656L,4503599627370496L,72057594037927936L,1152921504606846976L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,8L,135L,2160L,34560L,552960L,8847360L,141557760L,2264924160L,36238786560L,579820584960L,9277129359360L,148434069749760L,2374945115996160L,37999121855938560L,607985949695016960L,-8718968878589280256L,8070450532247928832L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,4L,64L,1025L,16405L,262480L,4199680L,67194880L,1075118080L,17201889280L,275230228480L,4403683655680L,70458938490880L,1127343015854080L,18037488253665280L,288599812058644480L,4617596992938311680L,94575592174780416L,1513209474796486656L,5764607523034234880L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,2L,33L,540L,8650L,138414L,2214635L,35434160L,566946560L,9071144960L,145138319360L,2322213109760L,37155409756160L,594486556098560L,9511784897576960L,152188558361231360L,2435016933779701760L,2066782793056124928L,-3824963458521104384L,-5859183115209015296L,-1513209474796486656L,-5764607523034234880L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,},
- {0L,0L,0L,0L,1L,65536L,4294967296L,281474976710656L,0L,0L,0L,0L,0L,0L,0L,0L,135L,8847360L,579820584960L,37999121855938560L,0L,0L,0L,0L,0L,0L,0L,0L,16405L,1075118080L,70458938490880L,4617596992938311680L,0L,0L,0L,0L,0L,0L,0L,33L,2214635L,145138319360L,9511784897576960L,-3824963458521104384L,0L,0L,0L,0L,0L,0L,0L,4096L,268435729L,17592203935744L,1152922677132918784L,76842668642009088L,0L,0L,0L,0L,0L,0L,8L,552960L,36238823415L,2374947531325440L,8070608823267622912L,-8072983807038324736L,0L,0L,0L,0L,0L,0L,1025L,67194948L,4403688133701L,288600105530228736L,5783840476780036096L,6072259672578981888L,0L,0L,0L,0L,0L,2L,138414L,9071137783L,594486085783387L,2066751970480947200L,-7784595809881817088L,-8116893903405187072L,0L,0L,0L,0L,0L,256L,16777216L,1099511627777L,72057594037993729L,4311810048L,282578783305728L,72339069014638592L,0L,0L,0L,0L,0L,34560L,2264924160L,148434069749895L,-8718968878580398201L,582094356480L,38148135746273280L,-8680969756733341696L,0L,0L,0L,0L,64L,4199680L,275230228480L,18037488253681749L,1513209475875820821L,70735243837440L,4635704940130467840L,6130806467734798336L,0L,0L,0L,0L,8650L,566946560L,37155409756193L,2435016933781924608L,-1513209329119911445L,9547060033028096L,-1513172181595455488L,2444047222778626048L,0L,0L,0L,16L,1048577L,68719546624L,4503604207554576L,300166943871248L,1224996759836561425L,1157443864920915968L,1229500363472633856L,1157706579210928128L,0L,0L,0L,2160L,141557903L,9277138794248L,607986568019867768L,40522537422618488L,-646134085450172169L,8680969174647242752L,-38147594580393984L,8716435603798884352L,0L,0L,4L,262480L,17201906772L,1127344162226437L,94650720833590549L,4923631783780892757L,4685244537110860101L,6130877201840930816L,4635630379498209280L,1244400872037810176L,0L,0L,540L,35434131L,2322211272589L,152188437960410544L,-5867073703402004022L,-608753751841641693L,5021550739930207323L,2435017087666290688L,-1503124363304501248L,-3144919914788159488L,0L,1L,65536L,4294967296L,},
- {0L,135L,0L,0L,36238823415L,0L,0L,-8718968878580398201L,0L,1048577L,-646134085450172169L,0L,281474976710656L,579829432455L,33L,76842668642009088L,8072983807037771767L,9071137783L,72339069031416064L,-8680821320398633081L,2435016933781924608L,1153203052884328721L,8072983770657683879L,-608753751841642177L,1L,70995809403015L,0L,268435737L,2325224901419503607L,0L,72057596286140673L,-4047941590536714361L,8650L,1828479723647826040L,5198580908436257015L,2322211206545L,281479271743623L,4652851823974482055L,-3824945721178980319L,1229782974218235903L,-8359203940994719823L,-7785153702193098917L,-8790878036300495359L,1551279595255904722L,1157478821306368048L,-1231840126630824042L,-2244067483645952701L,-5867073703402004022L,16404L,135L,2214635L,4403419698516L,36238823415L,594486085783387L,1441151881837827092L,-8718968878580398137L,-1513209329246797650L,5766090787059466581L,-646134068292338525L,4987494515535258582L,351930695303188L,4617597572767748231L,4989366934530869954L,4995636651726742868L,2616027333969501107L,-8680969754468382976L,6148982769688008083L,-3255113792571260030L,8108459549707964399L,6110225865917094366L,2616023978973555122L,4330401300L,9440922232176661L,70995809419410L,1162434420959906814L,-6650882093460728755L,2325229302423405341L,1510550969824680745L,-4696143385879816939L,-3255272293030243662L,299538383934670116L,899585657599261095L,-6421298510395728011L,4987212465024951234L,-8439804607159910222L,4722974330230397517L,2604241862179011578L,2945765058557585494L,-4172586336866215245L,-7908298668497926605L,3292917456527349333L,-1778416807812019587L,-2687845494699988046L,-1568533776661182301L,-7153308993320401295L,-751561123640744348L,135L,135L,594486083601840L,36238823415L,36238823351L,-1512615122307666256L,-8718968878580398201L,-8718968861378493549L,-5859145822004578895L,-646134085451220746L,-5251909112208802653L,5012764771064815280L,282054806696071L,1463670458724844711L,-8184224933876447855L,8149678041610583920L,8167559115579133249L,-8179721325835109289L,-8788221579835704968L,-2069077196422502013L,-4705347465926991951L,6955256496823371726L,-7524108394299359031L,7563110548872886158L,70995809403014L,75399497649272L,-8947147165825350487L,2325224901151067886L,3838472271485441641L,-8942843533514592335L,-4119999182185003507L,4329109129124827895L,-6421336103236948990L,5891272723926220804L,-1804055540449515934L,8460564669008640934L,-3753081440134336504L,-3860138431806531030L,-7856653449343714193L,-7595651990768072831L,-4052283364874674317L,5532806268997719779L,5288704387223848300L,-8744239686539652327L,-8855053725810232034L,6006015969448097578L,1347435800541178025L,2211897868760481646L,36238839779L,72061997459758636L,590093403544079L,-8718964475161218279L,360860506022940844L,-72057449430616578L,-2087283856937846165L,2955844742563665725L,1563985813813261386L,-7320240988429897084L,-6688021649094603968L,123717882122878262L,-370210050093239481L,6069896046897945042L,-8123643723470492874L,3483026182173742943L,-7835963269163963083L,629692079040326967L,-2397767918274165203L,2307919561648830965L,-44914365399010368L,599544380208996432L,-597294467434364901L,-6964430688229133911L,2334920026170350992L,-5605342300067343405L,3551021258077608539L,609035323518161084L,-6721022405297278944L,3504310508963389432L,-7283152471191799613L,-8722198899053206729L,-1250874794737731711L,9074608179003201540L,1810628635239662178L,-6451776899373758723L,-4615694538393549295L,-4362275103790198702L,-3792222432303245256L,-1559692666614209616L,-98431217577796539L,-9029920801466639058L,-7109365235188542407L,-946677770089042793L,-182592247182753593L,-2637452241563314774L,6124864149863968072L,5021550739898464339L,},
- {0L,-675700754464725196L,-7400245184483749183L,2325224865180680192L,4308854149351096230L,4087632387066765743L,-7275283868590567591L,998815193966931967L,-2143796421407463834L,6056625504733376525L,-4045721824789864836L,-858530229944418774L,94575875809256316L,-7495074221927422752L,-3628564631334774117L,-6872602957773652666L,-8837670072557268635L,2150855273413160557L,5842706246122142201L,-8874354114744897075L,-7498620451270880714L,8345255364170114647L,8675725534108615393L,-628718379448202296L,7213058728673621187L,8697600085574001635L,569941992076422209L,2101729217045010600L,-869272563270581351L,6349834165615373008L,-8278423197265695468L,-289667629372155284L,-4996188247313713002L,-4193590892988300734L,-7808747067947116470L,5740222723455656079L,-1004293179227928657L,-7378027571087326870L,1850676172401126584L,4102071215454560899L,7259757191991660866L,-3263750637324313573L,-7101095927535849009L,2960944838505603741L,7960409200978162151L,-1380919195139420544L,-7265787777315546970L,8696134004788876257L,4459615944721376107L,357711267766598467L,-6591463393386029767L,6213350576813261001L,2844246054154448404L,-3029083139417290328L,2245638225067189479L,8617601719125400457L,2128220270181946136L,3470499785866555218L,132066871132521002L,5517882414738609434L,-2003374013673959323L,3739836398962945633L,4448468942318558050L,5616161409774106646L,-1642714353533004129L,3432917397076393183L,-7631234578304800051L,1381553953950798900L,4023962110129311253L,8644710097507238632L,-1197417248055046378L,-9214470001404003712L,1609372195130461718L,-1978500250962778826L,-4911048255582930948L,6141651141653126100L,-2210543824408560838L,-6093993786564968581L,-2331300188278471014L,301965068498387180L,-4793576488484320667L,-5125824936144379883L,-5544211551818536164L,4552272197317892247L,-7837278238339183834L,-8761637332466461638L,147364084060044539L,-6064825681333790105L,-9198755709530655411L,-1778124120876162064L,-1861492150822659393L,4745713929342438769L,6861768606120208380L,5182389685193931296L,-8534340902764341615L,-3590390582013687815L,30073544289745672L,5662918870480130927L,8401074218837039520L,-3162537045663256753L,-3696184205999945570L,-4122514099598642296L,-7789756672013896695L,-287966903401783401L,-6507490048846866302L,-4916032157138151070L,-5141347076922627105L,-5155040494742911856L,7430428299516436592L,7568914190360801521L,8976947262451327251L,-823811253246772689L,3192421721340291099L,-2321904427011346487L,-7001545068850142391L,-8141745164608837714L,-8484695803346689573L,-5018197261793538831L,-4680980064014602375L,-3442898850200611643L,-5222684558521265456L,7664587417491999280L,-1184664264514778096L,-6690427770995712658L,-4105408088494675476L,-4179651232527412888L,4672902529451387521L,-4929725195951149496L,1568605474300434685L,9132692739037808736L,1067330377231330106L,6234823338025250317L,5513535159769997480L,-6296592138893575335L,1857768573899923229L,-7795052510154389180L,-7305898577268848196L,-4018600913292308304L,5464682203804131280L,4913993492957390835L,7057555747515730451L,-4522471330477326797L,4668369156558985260L,4477286195984166923L,7381389311118714077L,-7376279152378820185L,2001470970870984953L,-6267077529255448638L,2308580872094892292L,-3732951464203912308L,6769597213437287237L,7233920586946777352L,2580562194308495651L,-5163189941835227305L,6315713421482690203L,4098234801449939167L,-209812842733548776L,-7894469765614518540L,-2554059219807878625L,1903444257061664607L,9182030862387586589L,-3109633788736425272L,6389430618268296347L,2129494461042385878L,6329472897410366361L,-91499458815143634L,1221682685580272771L,9196639794739742553L,3102002862952173801L,-2224431388243524627L,346567882230063653L,-5437991707734288744L,-2709888611820883348L,-2920666756321254869L,4930390194078211174L,-6753455264900793669L,8186033625824413668L,2517429022687892375L,-591051196767852614L,-4262657608111575498L,-3159880638279040943L,-5917782714799358545L,-2681282764713948442L,-2318918853231809968L,-6811170076728669460L,3266419467001559315L,-515756142318178599L,-3869312023589911625L,1976731212099439882L,-8842932614801981568L,3225246888378129325L,8664993276476894618L,},
- {0L,6888918647020560317L,6616704076946383887L,72307319579008765L,5019028484594594082L,-3189487582568884878L,2134511505384836107L,-8664850887478530773L,4653976163382426028L,-7552953056849816027L,6722895949646321714L,-6956540475216209151L,-5858062716999869069L,-6264590843552634074L,5887677734908074113L,2474629020427595354L,-7967281225152887102L,185220160216387872L,-5760623994813845340L,-2535719245014115912L,5111362823887419820L,8505227612259241925L,9012934128161153438L,-3454844884687058304L,2688606500979393393L,257493182509576689L,3669454563593192799L,-5918660207704940910L,989805058886100772L,-7949845614554438917L,-8650932953258294805L,3719293863967856435L,5524498832277079871L,-8204898049315048076L,7429706311125713887L,-3392350091536387004L,8803967679232678927L,-6709573047928675008L,3993787092655773756L,-3869147372389115171L,-5407630961212543773L,-3635696971192372537L,-4123255486571580111L,7821261793194743720L,-8259701755427194463L,8778804536940933206L,-2390355563131639991L,-6022268794344148517L,-7704290986577360513L,-5411054657730165929L,6563199634835578546L,-6179985290346013130L,-1779710405126312658L,3860946749005281310L,2894361089265489575L,3315776251307050326L,6320628998837644363L,-4720130451255879792L,-7396858832460579381L,4947792566457792928L,-771597949057082277L,-6283874120936860908L,7751617974029105049L,-3171781932687118992L,-4986583824628389869L,7554891199116256466L,440872917012743287L,8832529013462318719L,6930378999847853276L,-6172476313572563251L,6597889588190964693L,-3923014422236362697L,4997044127822541429L,-7107806937807475144L,-6289965583375946716L,-3044570048596622809L,-582961432760897161L,-5961388502855958672L,-7194944488185970118L,-2808201162094710660L,2825505208148432617L,-7328788671423443242L,-981277169914054735L,5488327868523545998L,8289151770336172410L,4907413581236102050L,-5687370805778312995L,59381471987291070L,-6444452561966471140L,8634477550854188789L,6207648744164223412L,-101963300189371393L,7848638498504197321L,3498348962566120926L,-5579914395407433825L,-2545139183283670919L,5130648017855629422L,563110260262788563L,2135475898455702366L,7684314690515735551L,-7002326702731443230L,3880977581557303704L,-8637342854207977051L,8496120004406519552L,8560768772188447329L,2594230810807943255L,4337654442994597095L,-4585888647597749639L,-7892855638664835779L,1565051773613738620L,-1693518853642867805L,5567975317132003788L,2962765293309317965L,-3913616984206243549L,-5558808830930587106L,-8050075131445890472L,-8457438218982837752L,-2386212332821275776L,6035074888470767028L,-7849778513431525815L,3298946049141257047L,7780989528292148686L,7259205837724911376L,4482330118862142166L,-6537500962732474747L,-3022706756077921906L,7148848233164372316L,5077131755656950340L,7912726786975152439L,4848423276587831069L,-3830309290120570642L,4508033649949774926L,6846300513888811901L,6242882741110337747L,4170945278743029343L,-8127216801805486969L,-7852480183891607774L,3990619336327845960L,-5983515027675199463L,-5175175724494917100L,-1281849133123778903L,6285841989812053065L,-6067528458241089448L,7576477052240298304L,-36164364831076984L,-60994174189450074L,-8529533350870615239L,-4817148324041097753L,-4640927619693149134L,1872208642623965689L,5240297214938900007L,1572132602803588846L,-650696111471122406L,-6683156123433455837L,4545617032206292763L,-5495059938487344780L,6556517553578965713L,-2511396774410513113L,-2176872386175367579L,-8143603626268702413L,-8219576026727867109L,5228455090572155705L,-8048532819979278350L,-2942421454182291603L,-7739452100314543781L,5339545143011211455L,431828781909893989L,6504224558731934448L,1325434730767337764L,9044277964768096581L,-2012199912615250454L,2239476923138147060L,5446470907191488828L,-8988608972356041587L,318526050097438911L,4497994325831131702L,2421970446587647365L,8944762431294272394L,-1575644653468915716L,-7480808359693534377L,-8386442038249850993L,-4826695226202864144L,-2040524201209064254L,1185655104167734601L,9208155472300323928L,5181480307949496453L,7213432351073135570L,3512466954668360697L,-4638794086271207228L,-5040741222494255775L,2246055029297786978L,-2407449019420128263L,},
- {0L,4331831946986922092L,5039137575310318944L,6572365103720100214L,-3372926667923484384L,-804959452957560038L,5319341503317224386L,6670307960034794050L,9122331677505366914L,8132210050240438928L,1856212684185378577L,-2418012329048383413L,2221935190602818642L,-686940626615845117L,1911412200771311721L,-8073430757900621106L,3214975954359082910L,-4390346519891573401L,-3501449563817128233L,2931745286610574473L,6196837566508069630L,-7985185842868269260L,-242763400354519042L,-4762972334960522653L,-1128709856992935914L,-3133210263897755440L,-6300878854527293186L,7341789762184517091L,-742546840681255590L,-7168808549419220445L,-4984050358805078354L,5072732112695304142L,2078982868474422173L,-6351627917229293982L,-5889560863851129253L,-6131615849942787808L,6542639951406636963L,8480740463682186660L,183168288556720330L,-336660061516138115L,-1410356938699911649L,926150233093626212L,-2881764498566629282L,-1145487279366622181L,2351884447002867207L,-5662126631020168770L,-2882202962071256822L,6804440515561204260L,-7645812423207814611L,4621144061789925334L,-2353433576646516057L,-664832534192041661L,-554535101160684318L,-2377767015672774851L,2162245627601598447L,7482066041309690120L,8259346317988151315L,-3846765727327599638L,1731326869372517225L,-1980000664251113326L,800694689332165758L,2515205999128895054L,-1997432734072953419L,4672602758053323554L,6952202226827626829L,1161365306867490106L,-8384523961905918605L,-733116767785239559L,5682995397931390212L,-3325241677131986932L,-7594435646578169790L,1216932035765251873L,7076597346109630370L,4335245905675328559L,-8507624828826261297L,-6137869528790051691L,-2990757269081501860L,8207981314338567695L,-211809688264439807L,-3940005235808670096L,1182929724269347747L,4877641380646887291L,-7648008948030491945L,6628446266965226465L,-2970852163554202170L,-4670164336893474473L,-153630879029846201L,-3309814009518565346L,1753932513542224524L,-5251791855420722187L,-6759963098607779538L,-8872083893346595943L,-3120155793324540715L,5978602003840494141L,7512687430188190283L,562835420304739569L,4904579120205325277L,-3683422392650008109L,7042500995660740987L,-1972180833418385981L,6346437281268254654L,-2243185610911458224L,9026737040177775190L,4993647529943791743L,288019624394432352L,-4353118648656339247L,-5420873398923132591L,1549704053713244983L,3614498467424513972L,-9027385653029153084L,1629718615812967730L,-2759637422881662616L,8432531436503595927L,611355542547437884L,-3281181767178975456L,-6653389075112192169L,-6767829238387607677L,-18377277181334064L,3726999606378779346L,8982897182547291075L,-7270818405218871784L,7385860370779663565L,8974928614734018492L,291006976587948877L,5300536609199764342L,-5751424882775853301L,4349796007363489739L,-6969537113022603028L,6155372982161835515L,2778638126408133418L,-5347543214912549170L,-9027306700095574549L,30249368683249826L,7438665593684814940L,2922690888626912628L,-8180978412153428577L,-7237995582212279627L,416623024707852752L,-6898030889740364442L,7422011222211524550L,-1171936184535606480L,-6766055360615975733L,1731128074959168128L,-4607795217355720589L,-3213029979791539367L,-5255952104659057192L,-2314414383739670603L,4396632171704966086L,3006711910774356251L,5778933548260329613L,4157127632653091975L,7318697691457423286L,569409338780015498L,4153168956437659929L,-1756599119278225307L,-3314455936932684387L,342118048129659290L,-7569984731692337361L,7663926015038805676L,-7070277473562255822L,289945662752184113L,7974238619106446240L,738352690694983924L,831937267866542901L,-7662231404878724479L,-6989417225990538386L,4271423021483837384L,-4850149730195086768L,3731768127773306728L,7364897548779496026L,-2756767884644196684L,-1753950093378288022L,7143078809577818863L,4597090775987743317L,7848087705354908100L,1905884943523277834L,-6153674769862497703L,7016308115898147045L,-1899771811690011877L,7221196628836046154L,-4199539233852873704L,-8773468848938902681L,3961256666769655818L,-3407671319284954837L,3336711503507566638L,1628300123613068774L,-6944467362566050167L,5759866442005474216L,-2680310850292804557L,-8904643492625661829L,6625111154478727695L,-8756613211059540532L,},
- };
- private static final long [][] powTable2 = {
- {0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,1L,4L,16L,64L,256L,1024L,4096L,16384L,65536L,262144L,1048576L,4194304L,16777216L,67108864L,268435456L,1073741824L,4294967296L,17179869184L,68719476736L,274877906944L,1099511627776L,4398046511104L,17592186044416L,70368744177664L,281474976710656L,1125899906842624L,4503599627370496L,18014398509481984L,72057594037927936L,288230376151711744L,1152921504606846976L,4611686018427387904L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,2L,8L,33L,135L,540L,2160L,8640L,34560L,138240L,552960L,2211840L,8847360L,35389440L,141557760L,566231040L,2264924160L,9059696640L,36238786560L,144955146240L,579820584960L,2319282339840L,9277129359360L,37108517437440L,148434069749760L,593736278999040L,2374945115996160L,9499780463984640L,37999121855938560L,151996487423754240L,607985949695016960L,2431943798780067840L,-8718968878589280256L,2017612633061982208L,8070450532247928832L,-4611686018427387904L,},
- {0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,1L,16L,256L,4096L,65536L,1048576L,16777216L,268435456L,4294967296L,68719476736L,1099511627776L,17592186044416L,281474976710656L,4503599627370496L,72057594037927936L,1152921504606846976L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,8L,135L,2160L,34560L,552960L,8847360L,141557760L,2264924160L,36238786560L,579820584960L,9277129359360L,148434069749760L,2374945115996160L,37999121855938560L,607985949695016960L,-8718968878589280256L,8070450532247928832L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,4L,64L,1025L,16405L,262480L,4199680L,67194880L,1075118080L,17201889280L,275230228480L,4403683655680L,70458938490880L,1127343015854080L,18037488253665280L,288599812058644480L,4617596992938311680L,94575592174780416L,1513209474796486656L,5764607523034234880L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,2L,33L,540L,8650L,138414L,2214635L,35434160L,566946560L,9071144960L,145138319360L,2322213109760L,37155409756160L,594486556098560L,9511784897576960L,152188558361231360L,2435016933779701760L,2066782793056124928L,-3824963458521104384L,-5859183115209015296L,-1513209474796486656L,-5764607523034234880L,},
- {0L,0L,0L,0L,0L,0L,0L,0L,1L,65536L,4294967296L,281474976710656L,0L,0L,0L,0L,0L,0L,0L,0L,135L,8847360L,579820584960L,37999121855938560L,0L,0L,0L,0L,0L,0L,0L,0L,16405L,1075118080L,70458938490880L,4617596992938311680L,0L,0L,0L,0L,0L,0L,0L,33L,2214635L,145138319360L,9511784897576960L,-3824963458521104384L,0L,0L,0L,0L,0L,0L,0L,4096L,268435729L,17592203935744L,1152922677132918784L,76842668642009088L,0L,0L,0L,0L,0L,0L,8L,552960L,36238823415L,2374947531325440L,8070608823267622912L,-8072983807038324736L,0L,0L,0L,0L,0L,0L,1025L,67194948L,4403688133701L,288600105530228736L,5783840476780036096L,6072259672578981888L,0L,0L,0L,0L,0L,2L,138414L,9071137783L,594486085783387L,2066751970480947200L,-7784595809881817088L,-8116893903405187072L,0L,0L,0L,0L,0L,256L,16777216L,1099511627777L,72057594037993729L,4311810048L,282578783305728L,72339069014638592L,0L,0L,0L,0L,0L,34560L,2264924160L,148434069749895L,-8718968878580398201L,582094356480L,38148135746273280L,-8680969756733341696L,0L,0L,0L,0L,64L,4199680L,275230228480L,18037488253681749L,1513209475875820821L,70735243837440L,4635704940130467840L,6130806467734798336L,0L,0L,0L,0L,8650L,566946560L,37155409756193L,2435016933781924608L,-1513209329119911445L,9547060033028096L,-1513172181595455488L,2444047222778626048L,0L,0L,0L,16L,1048577L,68719546624L,4503604207554576L,300166943871248L,1224996759836561425L,1157443864920915968L,1229500363472633856L,1157706579210928128L,0L,0L,0L,2160L,141557903L,9277138794248L,607986568019867768L,40522537422618488L,-646134085450172169L,8680969174647242752L,-38147594580393984L,8716435603798884352L,0L,0L,4L,262480L,17201906772L,1127344162226437L,94650720833590549L,4923631783780892757L,4685244537110860101L,6130877201840930816L,4635630379498209280L,1244400872037810176L,0L,0L,540L,35434131L,2322211272589L,152188437960410544L,-5867073703402004022L,-608753751841641693L,5021550739930207323L,2435017087666290688L,-1503124363304501248L,-3144919914788159488L,},
- {0L,0L,16405L,0L,0L,4403688133701L,0L,0L,1513209475875820821L,0L,141557903L,4685244537110860101L,0L,37999121855938560L,70460013625365L,4096L,-8072983807038324728L,6072259672646177861L,1099511627777L,-8680969754468382976L,6148844231222908181L,300166943871248L,8108459549707964415L,6072264093493673942L,0L,135L,9441497757794325L,0L,36238822398L,-4344883889898761147L,0L,-8718968601253017721L,-4731747198132988651L,1048577L,-132789517139225323L,-1552739068514332347L,281474985492480L,37999701685387285L,-8439804064927760332L,79200023969402880L,-4437309755392L,5541920255199135408L,72340746325590273L,-7908297577503485241L,-6110106313622404075L,8676465578921629935L,-326184747196674646L,-3477858389994040487L,1L,2214508L,16405L,268435729L,594453068185772L,4403688133701L,72057594037993793L,7782220301781673580L,1513209475875828959L,1224996777003865156L,-5568602317731943389L,4685246687521203912L,4617315522256633857L,46947281589357164L,-3824892998506958796L,4995636651659171088L,8116893894401741024L,-2657538287028282471L,6130806742969226560L,27400700751995177L,6195590254004767622L,1157782445580441636L,-3782275202737413550L,-2658220304921737954L,575525634069L,1162363457633372907L,9441497759976190L,6917681753729944802L,-5498814577540363438L,-4345476997192759376L,1551110792602277236L,5891520892378292651L,6144410812500239428L,634601418098493862L,1774375360755843061L,132652009187043017L,4653133841193683532L,-2595690203251959175L,72110664981553453L,-1230337829717287256L,-6188909812282035538L,6456071231484419289L,-2320958359203443879L,1835508870757419369L,2040370669282281878L,6661217468141030217L,-8423640389371565403L,-8499405260925408371L,268435728L,16405L,16405L,72057594306428944L,4403688133701L,4403688142223L,1152939165798699280L,1513209475875820821L,1513211798084813650L,1224996764271055007L,4685244537241932234L,-8363651757808097592L,1190939387166195984L,38069581936595025L,5021584044531862713L,-6992383705976074216L,-2597990945295154084L,-363348139508661757L,-7600368554163986847L,-7582301154678812143L,894948077087235353L,6955255921298015887L,6959836035952832632L,3211452494295328458L,6917685570877522327L,9441497757794450L,10016896989796619L,7027313512938572782L,-4344883925063770117L,2927870116789082016L,8786239407365985943L,4131336578943587486L,-4726948581212862695L,127865309502915844L,6074982671291646492L,-3775267067956559256L,-79200059939802875L,-8744009164630305692L,4615764723498800113L,-8718682424587484521L,-6158288432344557974L,-5261638342178675313L,-9059672762503245484L,5519878846588365914L,-4436464087703865944L,1518927025456563280L,1468085383922929905L,2639105496201891805L,270650237L,4403690315305L,-8718374425263534908L,72652047106048429L,1513803926786430456L,-7346953228811164402L,9007217061455705778L,3243811299122139894L,6753230224894884636L,-5602660768557635367L,-883519440648577041L,-116177230604955516L,-2323053257641285469L,-8482307462680691891L,-5549874877820869559L,958020971772365464L,-4991544269364360344L,6363309982556444943L,7331190440433981494L,5015726139678737532L,-2043388114386413778L,5482647037605624617L,1206745860518513047L,2086309373276999127L,8079745281175912599L,-3273465508891764574L,315336160138416834L,3834475922849262099L,38021128702995733L,3474027448873074912L,-4358775760477723763L,-5618657038833202186L,-1545654340300590546L,-2631227852331219336L,-8776825519658677635L,-2327823662365475282L,5194557473419685442L,-4092526298777937177L,-916312845293823853L,-2363175478922554126L,-4978193684293897722L,-6320440829497657480L,-2670705166203992950L,8762236708630736962L,-5599128477180867553L,5323899568776667617L,-5564129564103000826L,-3382740581917399352L,},
- {0L,2716622788963031847L,40846672993527025L,1513209509967159019L,4621053680045158388L,-2903996173352235569L,-8072983807038316094L,-7575455417369363805L,8071326617522633051L,-7258922398541384564L,8704697640774031947L,-6681570071551204221L,-1562641326068657855L,-883532926705604284L,956268130454475388L,1215539162648774541L,-426414134220978363L,5270683299884762747L,2330181287926686005L,6134726476362434106L,-2325959145524659347L,4329716150192313480L,-8392881078967907522L,-1802165835817182982L,-8100388729951545868L,1867951006267200589L,7919618595933494384L,-8980269885778783131L,4071040395359672573L,-312862961573357955L,-2941873227506952960L,-8115294874401740510L,5303426865933611246L,2958139355704065308L,1463694019776869652L,-8976074711962363925L,5268644657139266566L,6964861625476310538L,-1517608123673286513L,-2915846685277558710L,5550751346972347727L,2112780311210561748L,-1828007150056065159L,6384500303152980510L,-906389597981947895L,4410709334475405688L,-6483486400246371702L,-8147255517704438781L,-6120938892653523797L,3199011783477797964L,-6761726043452623010L,-7047017470580974912L,1462717182584096488L,-7023268205675315115L,-2989303706422286108L,3180460850976781138L,-298416058831618501L,-7266836423948921205L,6663350365655515731L,-8359063233001334572L,9056022989288353575L,7798619345308693609L,-44616847615569961L,3192155203687896874L,1239389723220221729L,-4986248400106757818L,4108171716624422170L,-4173733134437352158L,-8125352421416488169L,-1185374074307245661L,-2966673101544610810L,2704683786991607858L,1515177657563554330L,5601341054180475457L,2983614494542029933L,3582348994995344418L,-7227381997475091214L,375800204207924206L,2993383011336056468L,-8189001996079290037L,682068580983257903L,948844863510518846L,-5027244184536956601L,1827155836971693192L,-1870457681157527590L,1442861833621761616L,-7501553589451368346L,7570278778816122784L,2996106664946480472L,-8781991581739643752L,-1791985321944155905L,-867682135916918265L,-3280503815586869540L,323928290362912952L,-5799577295755596577L,7265376777009662712L,-5900142203173808917L,-1517427944723435699L,8119832848073844820L,-3536200579017813566L,-3797880052796029066L,2953127755774818207L,7848593138406357335L,-3561467074012037304L,-7337175485261886469L,5807093610353856481L,4150266656318619307L,5586315349794142210L,3173004702088493577L,-4041319562043822090L,3864667468337058586L,3273021938862095623L,1830503478934844635L,3749676212788847170L,3555683139611306856L,2307286949526856026L,-6923475262585040711L,-701796416470938392L,-1858770742650766417L,5567697607330176830L,-7615393280240676601L,8367577308384162142L,1289903960876064367L,2964316419676655924L,103719735714153803L,115707662404946645L,7038009716978659739L,6993618381930301556L,-4413073683489083550L,-5009032023647056184L,8984906013653963103L,4426963583202880421L,-6178068367693439722L,3477129417051532148L,-6090672487045910366L,-6135241880902941518L,-1212340631615108657L,-3815125365865109228L,-9071677335252123805L,-1160367325517043426L,2955609817225945308L,-1003634050197601548L,5820534109579904411L,-2426268040301780073L,-8146151533873453013L,606046764860835901L,6365109532573370147L,-6149510524360813181L,8739343454238347465L,-2972886873342710445L,-8078313491105835340L,-8453826761140217942L,2610148900125924178L,4094047797743140623L,1798485114169935380L,4998884408623716905L,8950537777569088369L,1259580490436590913L,-315040158391152316L,4404501065226543846L,8146418735010981422L,-3207553747699863543L,8675392909711600921L,2405040524590938945L,3011427288135051459L,-7505026985532373362L,-717246331947472893L,-1249163693485939994L,-5296945757900320134L,4406943265523691209L,-7262817264707461431L,4641142375242104030L,974365924473300426L,5883429614278840526L,1752533021582360374L,4682777309199078800L,3204063093503561410L,-363155732334907633L,-2346835733169282527L,-8137667428439140060L,-5206973815505988715L,-6974909107915889500L,8764043288183918255L,-4092038371708175209L,3554060350791641111L,8798581772638267674L,683285472572572424L,7214985925390295205L,-2157639133813705666L,-1448249137206045231L,3845284593116750432L,-491254275194118919L,},
- {0L,-9067886894117383031L,-8765631554449913793L,-351960140370164101L,-3809828891435867380L,709347176573105019L,6367995667762707277L,-2306580641000201140L,-3294298272065609853L,4371465194278568200L,2607306921379681548L,-417323118857018121L,-7881922716238547623L,1742624878807396150L,6417633233153038438L,7245011226171800446L,8165326897970180555L,-3243122380933127165L,-6714040292093312106L,5299517670423801760L,1162621650998540887L,-2644879706039864385L,5228558976169295831L,-4391072266260069004L,5007015542307306646L,4682900706152011413L,-2123901141179325738L,-1563119241267841448L,-7901984116490304069L,3479726911851668567L,2328631765004444895L,4163098372279135427L,-1162220268661065413L,7829988552306176969L,3774955113097750561L,-2924095674636243058L,-3804005518905654993L,4738269630527809961L,5850935874683467236L,8655960374699796185L,-9059189580654183421L,4147746414725146890L,24509238664879977L,-7300123086118785535L,4751556328478914134L,1176138900156266839L,-2121425120505405076L,7247247000762229134L,9000592214487314811L,-889874608502765498L,7236795550799772071L,4974622482278556577L,-420560834611630453L,-3768646734241421044L,-6934105751774839201L,2969065130293732380L,1157896836976407312L,-1559291870109505818L,-2713062981234471322L,-7531022569765588290L,885491871452046438L,8154994685434777085L,-6183517998680799133L,-1006560964259624252L,-3294584533985251232L,8399396859432285260L,4941554285858435526L,-6156845871586263088L,-3284695794597124922L,1532126679216399071L,8710324980140137084L,-5829657872686309788L,-8769115779063538072L,6935866645975431778L,3597238061932133376L,2900308539208720779L,-2048705180801093564L,7055281952541030950L,-7002220757486340324L,964568490678066690L,-8767317763140366030L,-7051357021415343791L,-4942724421035409788L,-3480567531822663066L,97030438992350687L,6148848201715609829L,8190673576143502363L,-582873467951437833L,2647318604324937637L,-6741961242409679499L,-3005976745528477871L,6997691635910859134L,-1554393429201478263L,5312146010243409080L,8436439012567294277L,-6630723209210577509L,-8673971494977105192L,3562527997978101964L,3222754741725930251L,-5514361182259644100L,8086871624387515496L,-1467927774684365475L,8787210120862734018L,3868688879557973489L,6456800047903216186L,2070752891678043017L,-2941591783186713651L,-8183443290798012978L,8647945886161088410L,-1841819063379755142L,7860120982846312859L,-8493947801835772681L,-8772774970693045973L,-5241215312398964897L,-2611583395517621586L,-6102100345907364588L,1496816916737236359L,-7037938107874011031L,1848097601417926664L,-3280842067707319343L,9059361377927179923L,3282174138875773780L,-4916481664416226618L,3886169231649272478L,-1162360497370278599L,637220995047853939L,2885978966316747573L,6728781912350490111L,2328479630147269651L,5554304721491051724L,-6390247834560005501L,678119673988273692L,8651416760092589714L,3253782092936323383L,-1172981379019092788L,-2681934234447846106L,2685869215896638688L,3821621354052583845L,-2684383087845706054L,8084097633656028849L,-8363538709557862805L,-4959083379007699006L,-636423994845221856L,-6174337185251636501L,-8181624222422079238L,5775773648593308303L,2958061024555050145L,-5902970918704504061L,-2311021221920430097L,-1163971532460119016L,7608815371737216021L,-2151017459333583787L,-4990542649899559495L,-7513884523432741003L,4393693670759726766L,-6124974036012512535L,4359543309307998296L,-7037830908455507891L,9041027053538546397L,-4965851250845680310L,-2710962042488783523L,-8360351447962823382L,8718758072633673592L,6091137861253238579L,3170648231776465081L,7255519673286422939L,-7053661224901986133L,-915340883967460252L,58498294164417086L,-3484407801438382424L,-5784099705119286635L,4125777477825819372L,-6146926288831583310L,-3273005006573409355L,3494948349508696583L,-5006780570108823652L,1464644271341482461L,8662100360049866867L,-8213718696027725861L,6111700097284965138L,8732551933992222890L,-2625466519519768621L,7604239518435423389L,-7828716348124971154L,-7235290890666697460L,5948056974595294574L,1526856277675902747L,6112243656016507212L,-5496701154568696152L,-3510748376081434273L,-8169496792421316254L,-8879479780209390885L,},
- {0L,3140177619151565L,1460417631189212726L,2353554947493303907L,-8202113219766144441L,-6445610874707668273L,608805251577783707L,5576331011745724676L,-4616645954249110408L,-8150056064724481814L,-4375043884813768089L,61489915732671441L,2417003783109232201L,-5797177228338315992L,2030419241542275643L,3535467551177747619L,8160953148558434627L,3783933582983994877L,-395558155134838237L,-9037492967799507046L,-5583543374553761415L,-3766787778222337249L,83690989555392614L,586532773118624438L,6753062925187026745L,-8948265279136309565L,-6410106965476177336L,4682508874368457020L,-295508894803101770L,8755364544425811426L,-6946865691886399246L,-4998699326132353090L,-4913666944514812110L,6656002279105587104L,-4102330896140732563L,4073773542208959172L,1868016903708504679L,5519576265667760424L,-4364728854253647198L,-4053216048524447777L,6663500710558038858L,6972529717731021777L,-3207571042298769577L,-3888399221174842362L,420006135991670627L,8470075279405824658L,7027685758317034910L,2040544246752732537L,-3800680914792011602L,2040759759708548109L,-9015248103296315503L,652011287933867814L,-7782739132326567829L,-2317801922460293066L,2611886844620986012L,-8984631646102328554L,891896526125902634L,-367951637747449086L,-3497113700860363823L,5236614907167581294L,4114633954038032258L,-7512497826449542169L,3242179150310062402L,5331743182358224881L,7796816641120626796L,-2424392677330210781L,-8144516314316042367L,675811259852555579L,-4634618573840023378L,4925946102011935067L,-4976229192152584784L,-3306578665043743720L,-6377989030567179047L,3293903018441646805L,618512784046332063L,53396408973512940L,-972771490037569515L,-6449609039165015841L,-4713122490770203220L,5807317894024892376L,-2670957669784138572L,3253385083202136062L,4051471174117632380L,-6471306451500783400L,6958488026378472944L,-5240312948719888335L,-8730122111509150856L,-391530967442739522L,5304728157073167586L,-8727565006975506202L,-2051755253763667777L,-3562176666377319713L,7612155015414030601L,1518046426766570808L,-307960163954445386L,-4612626700850755125L,-7636305212757699943L,697133298319656099L,-4630649231468148194L,5297521963269776703L,-9050284098059359704L,-9005170998800333392L,2690681881609407239L,-6345572204046605232L,5811140775354848418L,-7583858705664828398L,883333908996047580L,-3023430280093746546L,1253866782730544252L,-2652541341293732240L,-3271892520967689019L,-3752005443895063020L,4447917552968482513L,-3824236721243846818L,5600139313482945383L,-999779136651389228L,-8469897042294769427L,7796143214715526711L,406420894930862997L,-2962130523947052332L,-1278282830806339692L,-8447450042751963291L,634287000685320862L,-4988625188634368073L,7264114668740343559L,604237143730786090L,1470443674382315935L,7627286917302141493L,6193255306513896806L,-88995703250039083L,5251413380424095294L,-896519829376623449L,-1255840563362049523L,-6375440828517507443L,2331875313404929916L,8954805250915502220L,7208472503953793396L,-4921350084320109520L,8682056056407108854L,-588986527289762379L,9058761110104874970L,5619968217006612529L,3556136729690226244L,2636161296644079035L,-8961930654928536483L,-5855381532408164884L,8378124878485911957L,-2362426267959965117L,2730324786590578227L,-7828512552827125787L,6135910401929572633L,7539770217393522009L,2966065950377957666L,-2096713473244396849L,-7604673598994665387L,-7219768014399086113L,2704497122794833704L,-2967228398298959366L,-6762901644464291495L,-1553630643759993924L,1564603397139288648L,6116811891197961186L,3562368697804772802L,-3199395829836276360L,-1165308188865718640L,-2427793488252231210L,-8760734042314058841L,-7857272506160709120L,3203259669013418168L,-946026787142432929L,4945843407304527756L,-3777254025118911417L,-8496811611764847693L,6997957085954944184L,6393220067418700989L,1296680119038768392L,5852192073241482937L,-4072182146803896176L,-6966297004098237683L,-5487642568473235337L,-1519244559474694756L,3811374754853013692L,-2605325301426890003L,-2885808776371324742L,6661350203815069651L,1327657210385814471L,-3825923588202089762L,-7915987217397706762L,6735184013381996252L,1519213888176055875L,8382345159179417209L,1911513965813618260L,},
- };
-
- //The tables above were generated by the code below. The code is no longer needed.
-
- /* *******************************************************************************************
-
-
- static long [][] powTable0 = new long [7] [];
- static long [][] powTable1 = new long [7] [];
- static long [][] powTable2 = new long [7] [];
-
- public static void genPowTable() {
- GF2_192 z = new GF2_192();
- int i;
-
- powTable0[0] = new long [192];
- powTable1[0] = new long [192];
- powTable2[0] = new long [192];
- i = 0;
- for (; i<64; i++) {
- z.word[0] = 1L<=7) {
- // By Fermat's little theorem, z^{2^{2^k}} = z^{2^{2^k} mod (2^{192}-1)}
- // If k>=7, then 2^{2^k} mod (2^{192}-1) = 2^64 when k is even and 2^128 when k is odd (proof below),
- // so that's what we compute.
- // Note that we have no precomputed table for k=7 (i.e., 2^128), because we don't expect
- // this to be needed -- only up to k=6 is used in inversion.
- // Here's the proof: let m = 64. 2^{2^k} mod (2^{192}-1) = 2^{mn} mod (2^{3m}-1) for n = 2^{k-6}.
- // Let d = n div 3 and r = n mod 3.
- // Then 2^{mn} = (2^{3m}-1) (2^{m(n-3}}+2^{m(n-6)}+...+2^{m-nd})+2^{nr}
- // So the remainder is 2^{nr}. r is 2 when k is odd and 1 when k is even.
-
- power2To2ToK (res, z, 6);
- if (k%2 == 1) {
- power2To2ToK(res, res, 6);
- }
- }
- else {
- // powTable0[k][i] contains the result of raising x^i to the power 2^k for i = 0...63
- // powTable0[k][i-64] contains the result of raising x^i to the power 2^k for i = 64...127
- // powTable0[k][i-128] contains the result of raising x^i to the power 2^k for i = 128...191
- // Because raising to the power 2^k is linear over any field of characteristic 2,
- // we just need to XOR the values in these tables at indices i where z is 1.
- // This selection is done via multiplication by 0 or 1, to avoid having an input-dependent path
- // through the code, thus reducing the chance of side-channel attacks.
- //
- // Note that more efficient tables can be precomputed -- for example, the result of raising
- // every one of 16 possible 4-bit nibbles at every one of 32 possible nibble positions.
- // But indexing into these tables will be input-dependent, which may make side-channel attacks easier.
-
- long t0 = 0;
- long t1 = 0;
- long t2 = 0;
- int maxIndex = 0, i = 0;
- for (long w : z.word) {
- maxIndex += 64;
- for (; i < maxIndex; i++) {
- long multiplier = (w & 1);
- // No "if w&1 == 0" here, to avoid a data-dependent path through the code,
- // thus reducing the chance of side channel attacks
- t0 ^= powTable0[k][i] * multiplier;
- t1 ^= powTable1[k][i] * multiplier;
- t2 ^= powTable2[k][i] * multiplier;
- w >>>= 1;
- }
- }
- res.word[0] = t0;
- res.word[1] = t1;
- res.word[2] = t2;
- }
- }
-
-
- /**
- *
- * @return bits of this in hexadecimal notation, most significant on the left
- */
- public String toString() {
- return String.format("%016X", word[2])+String.format("%016X", word[1])+String.format("%016X", word[0]);
- }
-
-
-}
diff --git a/sigmastate/src/main/java/gf2t/GF2_192_Poly.java b/sigmastate/src/main/java/gf2t/GF2_192_Poly.java
deleted file mode 100644
index d3ccd61fc3..0000000000
--- a/sigmastate/src/main/java/gf2t/GF2_192_Poly.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- By Leonid Reyzin
-
- This is free and unencumbered software released into the public domain.
-
- Anyone is free to copy, modify, publish, use, compile, sell, or
- distribute this software, either in source code form or as a compiled
- binary, for any purpose, commercial or non-commercial, and by any
- means.
-
- In jurisdictions that recognize copyright laws, the author or authors
- of this software dedicate any and all copyright interest in the
- software to the public domain. We make this dedication for the benefit
- of the public at large and to the detriment of our heirs and
- successors. We intend this dedication to be an overt act of
- relinquishment in perpetuity of all present and future rights to this
- software under copyright law.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
- For more information, please refer to
- */
-
-package gf2t;
-
-import java.util.Arrays;
-
-public class GF2_192_Poly {
- private final GF2_192 [] c; // must be not null and of length at least 1
-
- private int deg; // must be >=0. actual degree is <= deg. c[deg+1]...c[c.length-1] must be 0 or null
- // deg of the 0 polynomial is 0
-
- /**
- * Constructs the polynomial given the byte array representation of the coefficients.
- * Coefficient of degree zero is given separately. Each coefficient should be given
- * as a 24-byte representation of a GF2_192 value. Coefficient of degree 1 should
- * start at moreCoeffs[0].
- * @param coeff0 byte array representing lowest coefficient (24 bytes)
- * @param moreCoeffs byte array with concatenation of byte-converted coefficients
- * (24 bytes each) from degree 1 to the highest
- */
- public GF2_192_Poly (byte[] coeff0, byte[] moreCoeffs) {
- deg = moreCoeffs.length/24;
- c = new GF2_192[deg+1];
- c[0] = new GF2_192(coeff0);
- for (int i = 1; i<=deg; i++) {
- c[i] = new GF2_192(moreCoeffs, (i-1)*24);
- }
- }
-
- /**
- * Factory constructor -- same as GF2_192_Poly(coeff0, moreCoeffs)
- * @param coeff0 byte array representing lowest coefficient (24 bytes)
- * @param moreCoeffs byte array with concatenation of byte-converted coefficients
- * (24 bytes each) from degree 1 to the highest
- * @return new polynomial with the given coefficients
- */
- public static GF2_192_Poly fromByteArray(byte[] coeff0, byte[] moreCoeffs) {
- return new GF2_192_Poly(coeff0, moreCoeffs);
- }
-
-
- /**
- * Interpolates the polynomial at given points (and at point 0, if valueAt0!=null).
- * If points are not all distinct, or if 0 is in the points array and valueAt0!=null, behavior is undefined.
- * valueAt0 is separated only for efficiency reason; the caller can treat 0 like any other point instead
- * (i.e., the points array can include 0 if valueAt0==null, but computation will be slightly less efficient).
- * If points is null, or values is null, or if lengths of points and values arrays differ,
- * or if the arrays are 0 length and valueAt0 is null, returns null.
- *
- * @param points the set of distinct inputs to the returned polynomial
- * (last byte of the field element only; all other bits are assumed to be 0)
- * @param values values[i] will be the result evaluating the returned polynomial at points[i]. values[i] must not be null.
- * @param valueAt0 if not null, then valueAt0 will be the result of evaluating the returned polynomial at 0
- * @return the unique lowest-degree polynomial p such that for every i, p(points[i]) = values[i] and p(0)=valueAt0
- * (if valueAt0!=null)
- */
- public static GF2_192_Poly interpolate (byte[] points, GF2_192 [] values, GF2_192 valueAt0) {
- if (points == null || values == null || (values.length == 0 && valueAt0 == null) || values.length!=points.length) return null;
-
- int resultDegree = values.length-1;
- if (valueAt0!=null) {
- resultDegree++;
- }
-
- GF2_192_Poly result = new GF2_192_Poly(resultDegree, 0);
- GF2_192_Poly vanishingPoly = new GF2_192_Poly(resultDegree, 1);
-
- for (int i = 0; i < points.length; i++) {
- GF2_192 t = result.evaluate(points[i]);
- GF2_192 s = vanishingPoly.evaluate(points[i]);
-
- // need to find r such that currentValue+r*valueOfVanishingPoly = values[i]
- GF2_192.add(t, t, values[i]);
- GF2_192.invert(s, s);
- GF2_192.mul(t, t, s);
-
- result.addMonicTimesConstantTo(vanishingPoly, t);
-
- if (i < points.length - 1 || valueAt0!=null) {
- vanishingPoly.monicTimesMonomial(points[i]);
- }
- }
-
- if (valueAt0!=null) { // the last point is 0
- GF2_192 t = new GF2_192(result.c[0]); // evaluating at 0 is easy
- GF2_192 s = new GF2_192(vanishingPoly.c[0]); // evaluating at 0 is easy
-
- // need to find r such that currentValue+r*valueOfVanishingPoly = valueAt0]
- GF2_192.add(t, t, valueAt0);
- GF2_192.invert(s, s);
- GF2_192.mul(t, t, s);
- result.addMonicTimesConstantTo(vanishingPoly, t);
- }
- return result;
- }
-
- /**
- * Evaluates the polynomial at a given point
- * @param x the last byte of a field element (all other bits are assumed to be 0)
- * @return the value of this polynomial evaluated at the field element
- */
- public GF2_192 evaluate (byte x) {
- GF2_192 res = new GF2_192(c[deg]);
- for (int d = deg-1; d>=0; d--) {
- GF2_192.mul(res, res, x);
- GF2_192.add(res, res, c[d]);
- }
- return res;
- }
-
- /**
- * adds r*p to this; assumes p is monic, c.length>p.deg, and (p.deg == this.deg+1, or this==0 and p==1)
- * @param p the monic polynomial being added to this
- * @param r the constant by which p is multiplied before being added
- */
- private void addMonicTimesConstantTo (GF2_192_Poly p, GF2_192 r) {
- GF2_192 t = new GF2_192();
- for (int i = 0; i 0; i--) {
- // c[i] = c[i-1]+r*c[i]
- GF2_192.mul(c[i], c[i], r);
- GF2_192.add(c[i], c[i], c[i - 1]);
- }
- GF2_192.mul(c[0], c[0], r);
- }
-
-
- /**
- * Constructs a constant polynomial
- *
- * @param maxDeg the maximum degree this polynomial could possibly have (to allocate space)
- * @param constantTerm the polynomial is initially created with degree 0 and given constantTerm
- */
- private GF2_192_Poly (int maxDeg, int constantTerm) {
- c = new GF2_192[maxDeg+1];
- c[0] = new GF2_192(constantTerm);
- deg = 0;
- }
-
- /**
- *
- * @return this represented in usual polynomial notation (but possibly leading 0s), with X as the free variable
- */
- public String toString() {
- String ret = "";
- if (deg>=2) {
- ret+= c[deg].toString() + "*X^"+deg;
- int i;
- for (i = deg - 1; i >= 2; i--) {
- ret += " + " + c[i]+"*X^"+i;
- }
- ret+= " + ";
- }
- if (deg>=1) {
- ret += c[1] + "*X" + " + ";
- }
- ret+=c[0];
- return ret;
- }
-
-
- /**
- * Returns a byte array that contains the concatenation of all the coefficients
- * (except possibly the degree-0 coefficient, which is omitted if coeff0 is false).
- * Lowest-degree coefficient (0 or 1 depending on coeff0) starts at index 0 of the returned array.
- * Each coefficient takes 24 bytes, for a total of degree*24 bytes if coeff0 is false,
- * or (degree+1)*24 bytes if coeff0 is true
- * @param coeff0 whether to include coeff0
- * @return array of all coefficients (except possibly 0th depending on coeff0)
- */
- public byte[] toByteArray(Boolean coeff0) {
- int c0;
- if (coeff0) c0 = 0;
- else c0=1;
- byte [] ret = new byte[(deg+1-c0)*24];
- for (int i=c0; i<=deg; i++) {
- c[i].toByteArray(ret, (i-c0)*24);
-
- }
- return ret;
- }
-
- /**
- * @return The degree-0 coefficient, converted to an array of 24 bytes
- */
- public byte[] coeff0Bytes() {
- return c[0].toByteArray();
- }
-
- @Override
- public int hashCode() {
- return 31 * Arrays.deepHashCode(c) + deg;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj instanceof GF2_192_Poly) {
- GF2_192_Poly that = (GF2_192_Poly)obj;
- return Arrays.deepEquals(c, that.c) && deg == that.deg;
- }
- return false;
- }
-}
diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala
index 0a9fdfb49c..251df04e1f 100644
--- a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala
+++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala
@@ -1,6 +1,8 @@
package org.ergoplatform
-import com.google.common.primitives.Ints
+import java.util
+
+import scorex.utils.Ints
import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix
import scorex.crypto.hash.{Digest32, Blake2b256}
import scorex.util.encode.Base58
@@ -123,7 +125,7 @@ object P2PKAddress {
/** Constructs [[P2PKAddress]] instance using the public key of the given [[ProveDlog]]. */
def apply(pubkey: ProveDlog)(implicit encoder: ErgoAddressEncoder): P2PKAddress = {
- val bs = GroupElementSerializer.toBytes(pubkey.h)
+ val bs = GroupElementSerializer.toBytes(pubkey.value)
new P2PKAddress(pubkey, bs)
}
}
diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala
index e097a6302f..256f643d93 100644
--- a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala
+++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala
@@ -1,6 +1,6 @@
package org.ergoplatform
-import com.google.common.primitives.{Ints, Shorts}
+import scorex.utils.{Ints, Shorts}
import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId}
import org.ergoplatform.settings.ErgoAlgos
import scorex.crypto.authds.ADKey
@@ -61,7 +61,7 @@ class ErgoBox(
import ErgoBox._
/** Blake2b256 hash of the serialized `bytes`. */
- lazy val id: BoxId = ADKey @@ Blake2b256.hash(bytes)
+ lazy val id: BoxId = ADKey @@@ Blake2b256.hash(bytes)
override def get(identifier: RegisterId): Option[Value[SType]] = {
identifier match {
diff --git a/sigmastate/src/main/scala/sigmastate/SigSerializer.scala b/sigmastate/src/main/scala/sigmastate/SigSerializer.scala
index d7f3875337..92c18463dc 100644
--- a/sigmastate/src/main/scala/sigmastate/SigSerializer.scala
+++ b/sigmastate/src/main/scala/sigmastate/SigSerializer.scala
@@ -1,8 +1,7 @@
package sigmastate
import com.typesafe.scalalogging.LazyLogging
-import gf2t.GF2_192_Poly
-import org.bouncycastle.util.BigIntegers
+import sigmastate.crypto.{BigIntegers, GF2_192_Poly}
import scorex.util.encode.Base16
import sigmastate.Values.SigmaBoolean
import sigmastate.basics.DLogProtocol.{ProveDlog, SecondDLogProverMessage}
@@ -11,7 +10,7 @@ import sigmastate.basics.{ProveDHTuple, SecondDiffieHellmanTupleProverMessage}
import sigmastate.interpreter.ErgoTreeEvaluator.{fixedCostOp, perItemCostOp}
import sigmastate.interpreter.{CryptoConstants, ErgoTreeEvaluator, NamedDesc, OperationCostInfo}
import sigmastate.lang.exceptions.SerializerException
-import sigmastate.serialization.{SigmaSerializer}
+import sigmastate.serialization.SigmaSerializer
import sigmastate.util.safeNewArray
import sigmastate.utils.{Helpers, SigmaByteReader, SigmaByteWriter}
import debox.cfor
diff --git a/sigmastate/src/main/scala/sigmastate/UncheckedTree.scala b/sigmastate/src/main/scala/sigmastate/UncheckedTree.scala
index f932f7d77f..365a1f85a7 100644
--- a/sigmastate/src/main/scala/sigmastate/UncheckedTree.scala
+++ b/sigmastate/src/main/scala/sigmastate/UncheckedTree.scala
@@ -4,8 +4,8 @@ import java.util.Arrays
import sigmastate.basics.DLogProtocol.{FirstDLogProverMessage, ProveDlog, SecondDLogProverMessage}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.Values.SigmaBoolean
-import gf2t.GF2_192_Poly
import sigmastate.basics.{FirstDiffieHellmanTupleProverMessage, ProveDHTuple, SecondDiffieHellmanTupleProverMessage}
+import sigmastate.crypto.GF2_192_Poly
sealed trait UncheckedTree extends ProofTree
diff --git a/sigmastate/src/main/scala/sigmastate/UnprovenTree.scala b/sigmastate/src/main/scala/sigmastate/UnprovenTree.scala
index 8d4dc83f6d..6e600b927b 100644
--- a/sigmastate/src/main/scala/sigmastate/UnprovenTree.scala
+++ b/sigmastate/src/main/scala/sigmastate/UnprovenTree.scala
@@ -1,8 +1,6 @@
package sigmastate
import java.math.BigInteger
-
-import gf2t.GF2_192_Poly
import sigmastate.Values.{ErgoTree, SigmaBoolean, SigmaPropConstant}
import sigmastate.basics.DLogProtocol.{FirstDLogProverMessage, ProveDlog}
import sigmastate.basics.VerifierMessage.Challenge
@@ -13,7 +11,7 @@ import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer
import sigmastate.serialization.SigmaSerializer
import sigmastate.utils.SigmaByteWriter
import debox.cfor
-
+import sigmastate.crypto.GF2_192_Poly
import scala.language.existentials
object ConjectureType extends Enumeration {
diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala
index 7544107216..0a70c43783 100644
--- a/sigmastate/src/main/scala/sigmastate/Values.scala
+++ b/sigmastate/src/main/scala/sigmastate/Values.scala
@@ -2,7 +2,7 @@ package sigmastate
import java.math.BigInteger
import java.util.{Arrays, Objects}
-import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{count, everywherebu, strategy}
+import sigmastate.kiama.rewriting.Rewriter.{count, everywherebu, strategy}
import org.ergoplatform.settings.ErgoAlgos
import org.ergoplatform.validation.ValidationException
import scalan.{Nullable, RType}
diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala
index 2fb7583a67..f4b9b4c8f3 100644
--- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala
+++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala
@@ -1,28 +1,29 @@
package sigmastate.basics
import java.math.BigInteger
-import org.bouncycastle.asn1.x9.X9ECParameters
-import org.bouncycastle.crypto.ec.CustomNamedCurves
-import org.bouncycastle.math.ec.custom.sec.SecP256K1Point
-import org.bouncycastle.math.ec.ECPoint
-import org.bouncycastle.util.BigIntegers
+import sigmastate.crypto.BigIntegers
import debox.cfor
+import sigmastate.crypto.{CryptoContext, CryptoFacade}
-import scala.collection.{Seq, mutable}
-import scala.util.Try
+import scala.collection.mutable
-abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) extends DlogGroup[ElemType] {
- lazy val curve = x9params.getCurve
+/** Base class for EC-based groups where DLOG problem is hard (with bouncycastle-like interface).
+ * @param ctx context which abstracts basic operations with curve and elements.
+ */
+abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup {
+ /** Characteristic of the finite field of the underlying curve. */
+ lazy val p: BigInteger = ctx.fieldCharacteristic
- //modulus of the field
- lazy val p: BigInteger = curve.getField.getCharacteristic
-
- //order of the group
- lazy val q = x9params.getN
+ /** Order of the group as defined in ASN.1 def for Elliptic-Curve ECParameters structure.
+ * See X9.62, for further details.
+ * For reference implementation see `org.bouncycastle.asn1.x9.X9ECParameters.getN`.
+ */
+ lazy val q: BigInteger = ctx.order
- //Now that we have p, we can calculate k which is the maximum length in bytes
- // of a string to be converted to a Group Element of this group.
+ /** Now that we have p, we can calculate k which is the maximum length in bytes
+ * of a string to be converted to a Group Element of this group.
+ */
lazy val k = calcK(p)
/**
@@ -31,15 +32,15 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
* It is composed of two main elements. The group element for which the optimized computations
* are built for, called the base and a vector of group elements that are the result of
* exponentiations of order 1,2,4,8,
- */
- private class GroupElementsExponentiations(base: ElemType) //group element for which the optimized computations are built for
- /**
+ *
* The constructor creates a map structure in memory.
* Then calculates the exponentiations of order 1,2,4,8 for the given base and save them in the map.
*
- * @param base
+ * @param base group element for which the optimized computations are built for
* @throws IllegalArgumentException
- */ { // build new vector of exponentiations
+ *
+ */
+ private class GroupElementsExponentiations(base: ElemType) {
private val exponentiations = new mutable.ListBuffer[ElemType]()
@@ -99,22 +100,11 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
private val exponentiationsCache = mutable.Map[ElemType, GroupElementsExponentiations]()
- //Create the generator
- //Assume that (x,y) are the coordinates of a point that is indeed a generator but check that (x,y) are the coordinates of a point.
- override lazy val generator: ElemType = x9params.getG.asInstanceOf[ElemType]
-
- /**
- * Checks if the given x and y represent a valid point on the given curve,
- * i.e. if the point (x, y) is a solution of the curves equation.
- *
- * @param x coefficient of the point
- * @param y coefficient of the point
- * @return true if the given x and y represented a valid point on the given curve
+ /** Creates the generator.
+ * Assume that (x,y) are the coordinates of a point that is indeed a generator but
+ * check that (x,y) are the coordinates of a point.
*/
- def checkCurveMembership(x: BigInteger, y: BigInteger): Boolean = {
- Try(curve.validatePoint(x, y)).isSuccess
- }
-
+ override lazy val generator: ElemType = ctx.generator
/**
* This function calculates k, the maximum length in bytes of a string to be converted to a Group Element of this group.
@@ -132,16 +122,14 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
}
/**
- *
* @return the order of this Dlog group
*/
- override lazy val order: BigInteger = x9params.getN
+ override lazy val order: BigInteger = ctx.order
/**
- *
* @return the identity of this Dlog group
*/
- override lazy val identity: ElemType = curve.getInfinity.asInstanceOf[ElemType]
+ override lazy val identity: ElemType = ctx.infinity.asInstanceOf[ElemType]
/**
* Calculates the inverse of the given GroupElement.
@@ -151,7 +139,7 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
* @throws IllegalArgumentException
**/
override def inverseOf(groupElement: ElemType): ElemType =
- groupElement.negate().asInstanceOf[ElemType]
+ CryptoFacade.negatePoint(groupElement)
/**
* Raises the base GroupElement to the exponent. The result is another GroupElement.
@@ -163,16 +151,12 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
*/
override def exponentiate(base: ElemType, exponent: BigInteger): ElemType = {
//infinity remains the same after any exponentiate
- if (base.isInfinity) return base
+ if (CryptoFacade.isInfinityPoint(base)) return base
//If the exponent is negative, convert it to be the exponent modulus q.
val exp = if (exponent.compareTo(BigInteger.ZERO) < 0) exponent.mod(order) else exponent
- /*
- * BC treats EC as additive group while we treat that as multiplicative group.
- * Therefore, exponentiate point is multiply.
- */
- base.multiply(exp).asInstanceOf[ElemType]
+ CryptoFacade.exponentiatePoint(base, exp)
}
@@ -186,7 +170,7 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
//However, if a specific Dlog Group has a more efficient implementation then is it advised to override this function in that concrete
//Dlog group. For example we do so in CryptoPpDlogZpSafePrime.
val one = BigInteger.ONE
- val qMinusOne = x9params.getN.subtract(one)
+ val qMinusOne = ctx.order.subtract(one)
// choose a random number x in Zq*
val randNum = BigIntegers.createRandomInRange(one, qMinusOne, secureRandom)
// compute g^x to get a new element
@@ -213,22 +197,7 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
* @throws IllegalArgumentException
*/
override def multiplyGroupElements(groupElement1: ElemType, groupElement2: ElemType): ElemType =
- groupElement1.add(groupElement2).asInstanceOf[ElemType]
-
-
- /**
- * Computes the product of several exponentiations with distinct bases
- * and distinct exponents.
- * Instead of computing each part separately, an optimization is used to
- * compute it simultaneously.
- *
- * @param groupElements
- * @param exponentiations
- * @return the exponentiation result
- */
- override def simultaneousMultipleExponentiations(groupElements: Array[ElemType],
- exponentiations: Array[BigInteger]): ElemType =
- computeLL(groupElements, exponentiations)
+ CryptoFacade.multiplyPoints(groupElement1, groupElement2)
/**
* Computes the product of several exponentiations of the same base
@@ -273,113 +242,7 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex
*/
override lazy val maxLengthOfByteArrayForEncoding: Int = k
-
- /*
- * Computes the simultaneousMultiplyExponentiate using a naive algorithm
- */
- protected def computeNaive(groupElements: Array[ElemType], exponentiations: Array[BigInteger]): ElemType =
- groupElements.zip(exponentiations)
- .iterator
- .map { case (base, exp) => exponentiate(base, exp) }
- .foldLeft(identity) { case (r, elem) => multiplyGroupElements(elem, r) }
-
-
- /*
- * Compute the simultaneousMultiplyExponentiate by LL algorithm.
- * The code is taken from the pseudo code of LL algorithm in http://dasan.sejong.ac.kr/~chlim/pub/multi_exp.ps.
- */
- protected def computeLL(groupElements: Array[ElemType], exponentiations: Array[BigInteger]): ElemType = {
- val n = groupElements.length
- //get the biggest exponent
- val bigExp = exponentiations.max
- val t = bigExp.bitLength //num bits of the biggest exponent.
- val w = getLLW(t) //window size, choose it according to the value of t
-
- //h = n/w
- val h = if ((n % w) == 0) n / w else (n / w) + 1
-
- //create pre computation table
- val preComp = createLLPreCompTable(groupElements, w, h)
-
- //holds the computation result
- var result: ElemType = computeLoop(exponentiations, w, h, preComp, identity, t - 1)
- //computes the first loop of the algorithm. This loop returns in the next part of the algorithm with one single tiny change.
-
- //computes the third part of the algorithm
- (t - 2).to(0, -1).foreach { j =>
- //Y = Y^2
- result = exponentiate(result, new BigInteger("2"))
- //computes the inner loop
- result = computeLoop(exponentiations, w, h, preComp, result, j)
- }
- result
- }
-
- /*
- * Computes the loop the repeats in the algorithm.
- * for k=0 to h-1
- * e=0
- * for i=kw to kw+w-1
- * if the bitIndex bit in ci is set:
- * calculate e += 2^(i-kw)
- * result = result *preComp[k][e]
- *
- */
- private def computeLoop(exponentiations: Array[BigInteger], w: Int, h: Int, preComp: Seq[Seq[ElemType]], result: ElemType, bitIndex: Int) = {
- var res = result
- cfor(0)(_ < h, _ + 1) { k =>
- var e = 0
- cfor(k * w)(_ < (k * w + w), _ + 1) { i =>
- if (i < exponentiations.length) { //if the bit is set, change the e value
- if (exponentiations(i).testBit(bitIndex)) {
- val twoPow = Math.pow(2, i - k * w).toInt
- e += twoPow
- }
- }
- }
- res = multiplyGroupElements(res, preComp(k)(e))
- }
- res
- }
-
- /*
- * Creates the preComputation table.
- */
- private def createLLPreCompTable(groupElements: Array[ElemType], w: Int, h: Int) = {
- val twoPowW = Math.pow(2, w).toInt
- //create the pre-computation table of size h*(2^(w))
- val preComp: Seq[mutable.Seq[ElemType]] = Seq.fill(h)(mutable.Seq.fill(twoPowW)(identity))
-
- cfor(0)(_ < h, _ + 1) { k =>
- cfor(0)(_ < twoPowW, _ + 1) { e =>
- cfor(0)(_ < w, _ + 1) { i =>
- val baseIndex = k * w + i
- if (baseIndex < groupElements.length) {
- val base = groupElements(baseIndex)
- //if bit i in e is set, change preComp[k][e]
- if ((e & (1 << i)) != 0) { //bit i is set
- preComp(k)(e) = multiplyGroupElements(preComp(k)(e), base)
- }
- }
- }
- }
- }
- preComp
- }
-
- /*
- * returns the w value according to the given t
- */
- private def getLLW(t: Int): Int = {
- if (t <= 10) 2
- else if (t <= 24) 3
- else if (t <= 60) 4
- else if (t <= 144) 5
- else if (t <= 342) 6
- else if (t <= 797) 7
- else if (t <= 1828) 8
- else 9
- }
}
-object SecP256K1 extends BcDlogGroup[SecP256K1Point](CustomNamedCurves.getByName("secp256k1"))
\ No newline at end of file
+/** Implementation of [[BcDlogGroup]] using SecP256K1 curve. */
+object SecP256K1Group extends BcDlogGroup(CryptoFacade.createCryptoContext())
\ No newline at end of file
diff --git a/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala b/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala
index 75db9c69d2..38cfe1d8cb 100644
--- a/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala
+++ b/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala
@@ -2,7 +2,7 @@ package sigmastate.basics
import java.math.BigInteger
-import org.bouncycastle.util.BigIntegers
+import sigmastate.crypto.BigIntegers
import sigmastate.Values._
import Value.PropositionCode
import scorex.util.encode.Base16
@@ -27,8 +27,8 @@ object DLogProtocol {
extends SigmaProofOfKnowledgeLeaf[DLogSigmaProtocol, DLogProverInput] {
override def size: Int = 1
override val opCode: OpCode = OpCodes.ProveDlogCode
- lazy val h: EcPointType = value
- lazy val pkBytes: Array[Byte] = GroupElementSerializer.toBytes(h)
+ /** Serialized bytes of the elliptic curve point (using GroupElementSerializer). */
+ lazy val pkBytes: Array[Byte] = GroupElementSerializer.toBytes(value)
}
object ProveDlog {
@@ -102,6 +102,7 @@ object DLogProtocol {
SecondDLogProverMessage(z)
}
+ /** Simulation of sigma protocol. */
def simulate(publicInput: ProveDlog, challenge: Challenge): (FirstDLogProverMessage, SecondDLogProverMessage) = {
val qMinusOne = dlogGroup.order.subtract(BigInteger.ONE)
@@ -111,7 +112,7 @@ object DLogProtocol {
//COMPUTE a = g^z*h^(-e) (where -e here means -e mod q)
val e: BigInteger = new BigInteger(1, challenge)
val minusE = dlogGroup.order.subtract(e)
- val hToE = dlogGroup.exponentiate(publicInput.h, minusE)
+ val hToE = dlogGroup.exponentiate(publicInput.value, minusE)
val gToZ = dlogGroup.exponentiate(dlogGroup.generator, z)
val a = dlogGroup.multiplyGroupElements(gToZ, hToE)
FirstDLogProverMessage(a) -> SecondDLogProverMessage(z)
@@ -133,7 +134,7 @@ object DLogProtocol {
challenge: Challenge,
secondMessage: SecondDLogProverMessage): EcPointType = {
val g = dlogGroup.generator
- val h = proposition.h
+ val h = proposition.value
dlogGroup.multiplyGroupElements(
dlogGroup.exponentiate(g, secondMessage.z.underlying()),
diff --git a/sigmastate/src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala b/sigmastate/src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala
index 5316bc70c9..9122cc78cd 100644
--- a/sigmastate/src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala
+++ b/sigmastate/src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala
@@ -2,7 +2,7 @@ package sigmastate.basics
import java.math.BigInteger
-import org.bouncycastle.util.BigIntegers
+import sigmastate.crypto.BigIntegers
import sigmastate.Values.Value.PropositionCode
import sigmastate._
import sigmastate.basics.VerifierMessage.Challenge
diff --git a/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala
index 8df0f87e00..f7df1c8e3c 100644
--- a/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala
+++ b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala
@@ -2,7 +2,7 @@ package sigmastate.basics
import java.math.BigInteger
import java.security.SecureRandom
-import org.bouncycastle.math.ec.ECPoint
+import sigmastate.crypto.{CryptoFacade, Ecp}
/**
@@ -19,7 +19,9 @@ import org.bouncycastle.math.ec.ECPoint
*
* @tparam ElemType is concrete type
*/
-trait DlogGroup[ElemType <: ECPoint] {
+trait DlogGroup {
+ /** The type of the elements of this Dlog group */
+ type ElemType = Ecp
val secureRandom = new SecureRandom()
@@ -95,23 +97,12 @@ trait DlogGroup[ElemType <: ECPoint] {
// if the given element is the identity, get a new random element
while ( {
- randGen.isInfinity
+ CryptoFacade.isInfinityPoint(randGen)
}) randGen = createRandomElement()
randGen
}
- /**
- * Computes the product of several exponentiations with distinct bases
- * and distinct exponents.
- * Instead of computing each part separately, an optimization is used to
- * compute it simultaneously.
- * @param groupElements
- * @param exponentiations
- * @return the exponentiation result
- */
- def simultaneousMultipleExponentiations(groupElements: Array[ElemType], exponentiations: Array[BigInteger]): ElemType
-
/**
* Computes the product of several exponentiations of the same base
* and distinct exponents.
diff --git a/sigmastate/src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala b/sigmastate/src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala
index 199cdd1bf8..3327d94ebf 100644
--- a/sigmastate/src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala
+++ b/sigmastate/src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala
@@ -1,15 +1,7 @@
package sigmastate.basics
-import java.security.SecureRandom
-
-import sigmastate.basics.VerifierMessage.Challenge
-import sigmastate.interpreter.CryptoConstants
-import sigmastate.{SigmaProofOfKnowledgeLeaf, UncheckedTree}
import supertagged.TaggedType
-import scala.concurrent.Future
-
-
/*
Abstracting Sigma protocols
Functionality to get:
@@ -59,93 +51,10 @@ trait SigmaProtocol[SP <: SigmaProtocol[SP]] {
trait SigmaProtocolCommonInput[SP <: SigmaProtocol[SP]] {
- val soundness: Int = CryptoConstants.soundnessBits
}
trait SigmaProtocolPrivateInput[SP <: SigmaProtocol[SP], CI <: SigmaProtocolCommonInput[SP]] {
def publicImage: CI
}
-/**
- * common interface for both Prover and Verifier
- */
-trait Party[SP <: SigmaProtocol[SP], CI <: SigmaProtocolCommonInput[SP]] {
- val publicInput: CI
-}
-
-//implement it as a FSM-DSL waitfor - then - action - then - waitfor - etc
-trait InteractiveParty
-
-trait Prover[SP <: SigmaProtocol[SP],
-CI <: SigmaProtocolCommonInput[SP],
-PI <: SigmaProtocolPrivateInput[SP, CI]] extends Party[SP, CI] {
- val privateInputOpt: Option[PI]
-}
-
-
-trait InteractiveProver[SP <: SigmaProtocol[SP], CI <: SigmaProtocolCommonInput[SP], PI <: SigmaProtocolPrivateInput[SP, CI]]
- extends Prover[SP, CI, PI] with InteractiveParty {
-
- def firstMessage: SP#A
- def secondMessage(challenge: Challenge): SP#Z
-
- def simulate(challenge: Challenge): (SP#A, SP#Z)
-}
-
-trait SimulatingProver[SP <: SigmaProtocol[SP], CI <: SigmaProtocolCommonInput[SP]] {
- val challenge: Challenge
-}
-
-
-trait ZeroKnowledgeProofOfKnowledge[SP <: SigmaProtocol[SP]]
-
-trait NonInteractiveProver[SP <: SigmaProtocol[SP],
- PI <: SigmaProtocolPrivateInput[SP, CI],
- CI <: SigmaProofOfKnowledgeLeaf[SP, PI],
- P <: UncheckedTree]
- extends Prover[SP, CI, PI] {
-
- def prove(challenge: Array[Byte]): P
-}
-
-trait Verifier[SP <: SigmaProtocol[SP], CI <: SigmaProtocolCommonInput[SP]] extends Party[SP, CI] {
- type P <: Prover[SP, CI, _]
- type ST <: SigmaProtocolTranscript[SP, CI]
-
- lazy val challenge = Challenge({
- val ch = new Array[Byte](publicInput.soundness / 8)
- new SecureRandom().nextBytes(ch) //modifies ch
- ch
- })
-
- val publicInput: CI
-
- def prover: P
-
- def transcript: Future[Option[ST]]
-}
-
-/**
- * Sigma Protocol transcript enough for verification
- *
- * @tparam SP
- * @tparam CI
- */
-trait SigmaProtocolTranscript[SP <: SigmaProtocol[SP], CI <: SigmaProtocolCommonInput[SP]] {
-
- /** Common input known to both prover and verifier. */
- val x: CI
-
- /** First prover message */
- val a: SP#A
-
- /** Challenge created by verifier and sent to prover */
- val e: Challenge
-
- /** Second prover message - response to the challenge */
- val z: SP#Z
-
- /** Returns true if the verifier has accepted the prover's reponse to the challenge. */
- def accepted: Boolean
-}
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala
new file mode 100644
index 0000000000..0e55f12532
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala
@@ -0,0 +1,104 @@
+package sigmastate.crypto
+
+import java.math.BigInteger
+import java.security.SecureRandom
+
+/** Re-implementation in Scala of select set of utility methods from
+ * org.bouncycastle.util.BigIntegers.
+ */
+object BigIntegers {
+
+ /** The value 0 as a BigInteger. */
+ val ZERO: BigInteger = BigInteger.valueOf(0)
+
+ private val MAX_ITERATIONS = 1000
+
+ /** Create the given number of random bits.
+ * @param bitLength the number of random bits to create.
+ * @param random a source of randomness.
+ * @return a byte array containing random bits.
+ */
+ @throws[IllegalArgumentException]
+ def createRandom(bitLength: Int, random: SecureRandom): Array[Byte] = {
+ if (bitLength < 1) throw new IllegalArgumentException("bitLength must be at least 1")
+ val nBytes = (bitLength + 7) / 8
+ val rv = new Array[Byte](nBytes)
+ random.nextBytes(rv)
+
+ // strip off any excess bits in the MSB
+ val xBits = 8 * nBytes - bitLength
+ rv(0) = (rv(0) & 255 >>> xBits).toByte
+ rv
+ }
+
+ /**
+ * Return a positive BigInteger in the range of 0 to 2**bitLength - 1.
+ *
+ * @param bitLength maximum bit length for the generated BigInteger.
+ * @param random a source of randomness.
+ * @return a positive BigInteger
+ */
+ def createRandomBigInteger(
+ bitLength: Int,
+ random: SecureRandom): BigInteger = {
+ new BigInteger(1, createRandom(bitLength, random))
+ }
+
+ /**
+ * Return a random BigInteger not less than 'min' and not greater than 'max'
+ *
+ * @param min the least value that may be generated
+ * @param max the greatest value that may be generated
+ * @param random the source of randomness
+ * @return a random BigInteger value in the range [min,max]
+ */
+ def createRandomInRange(
+ min: BigInteger,
+ max: BigInteger,
+ random: SecureRandom): BigInteger = {
+ val cmp = min.compareTo(max)
+ if (cmp >= 0) {
+ if (cmp > 0) throw new IllegalArgumentException("'min' may not be greater than 'max'")
+ return min
+ }
+
+ if (min.bitLength > max.bitLength / 2)
+ return createRandomInRange(ZERO, max.subtract(min), random).add(min)
+
+ for ( i <- 0 until MAX_ITERATIONS ) {
+ val x = createRandomBigInteger(max.bitLength, random)
+ if (x.compareTo(min) >= 0 && x.compareTo(max) <= 0) return x
+ }
+ // fall back to a faster (restricted) method
+ createRandomBigInteger(max.subtract(min).bitLength - 1, random).add(min)
+ }
+
+ /**
+ * Return the passed in value as an unsigned byte array of the specified length, padded with
+ * leading zeros as necessary..
+ *
+ * @param length the fixed length of the result
+ * @param value the value to be converted.
+ * @return a byte array padded to a fixed length with leading zeros.
+ */
+ def asUnsignedByteArray(length: Int, value: BigInteger): Array[Byte] = {
+ val bytes = value.toByteArray
+ if (bytes.length == length) return bytes
+ val start = if (bytes(0) == 0) 1 else 0
+
+ val count = bytes.length - start
+ if (count > length)
+ throw new IllegalArgumentException("standard length exceeded for value")
+
+ val tmp = new Array[Byte](length)
+ System.arraycopy(bytes, start, tmp, tmp.length - count, count)
+ tmp
+ }
+
+ /** Converts a byte array to a BigInteger, treating the array as bits of the unsigned
+ * integer.
+ * @param buf the byte array to convert
+ * @return the resulting positive BigInteger
+ */
+ def fromUnsignedByteArray(buf: Array[Byte]) = new BigInteger(1, buf)
+}
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala
new file mode 100644
index 0000000000..b5aceec849
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala
@@ -0,0 +1,30 @@
+package sigmastate.crypto
+
+import java.math.BigInteger
+
+/** A context for cryptographic operations. */
+abstract class CryptoContext {
+ /** The characteristics of the underlying finite field. */
+ def fieldCharacteristic: BigInteger
+
+ /** The order of the underlying group. */
+ def order: BigInteger
+
+ /** Validates a point.
+ * @param x the x-coordinate of the point
+ * @param y the y-coordinate of the point
+ * @return the point if it is valid
+ * @throws IllegalArgumentException if the coordinates do not represent a valid point
+ */
+ def validatePoint(x: BigInteger, y: BigInteger): Ecp
+
+ /** The point at infinity. */
+ def infinity(): Ecp
+
+ /** Decodes a point from its byte representation. */
+ def decodePoint(encoded: Array[Byte]): Ecp
+
+ /** The generator of the underlying group. */
+ def generator: Ecp
+}
+
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala
new file mode 100644
index 0000000000..6a3420242f
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala
@@ -0,0 +1,30 @@
+package sigmastate.crypto
+
+import org.bouncycastle.asn1.x9.X9ECParameters
+
+import java.math.BigInteger
+
+/** JVM implementation of context for cryptographic operations using Bouncycastle. */
+class CryptoContextJvm(x9params: X9ECParameters) extends CryptoContext {
+ private lazy val curve = x9params.getCurve
+
+ override def fieldCharacteristic: BigInteger = curve.getField.getCharacteristic
+
+ override def order: BigInteger = x9params.getN
+
+ override def generator: Ecp = {
+ Platform.Ecp(x9params.getG)
+ }
+
+ override def validatePoint(x: BigInteger, y: BigInteger): Ecp = {
+ Platform.Ecp(curve.validatePoint(x, y))
+ }
+
+ override def infinity(): Ecp = {
+ Platform.Ecp(curve.getInfinity)
+ }
+
+ override def decodePoint(encoded: Array[Byte]): Ecp = {
+ Platform.Ecp(curve.decodePoint(encoded))
+ }
+}
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala
new file mode 100644
index 0000000000..54ec07940c
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala
@@ -0,0 +1,86 @@
+package sigmastate.crypto
+
+import java.math.BigInteger
+
+/** A facade for cryptographic operations. The concrete implementation is delegated to the
+ * Platform object, which is resolved by the compiler to either JVM or JS implementation.
+ * Cross-platform code should use this facade instead of the Platform object directly.
+ */
+object CryptoFacade {
+ /** Create a new context for cryptographic operations. */
+ def createCryptoContext(): CryptoContext = Platform.createContext()
+
+ /** * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
+ * coordinates reflect those of the equivalent point in an affine coordinate system.
+ *
+ * @return a new ECPoint instance representing the same point, but with normalized coordinates
+ */
+ def normalizePoint(p: Ecp): Ecp = Platform.normalizePoint(p)
+
+ /** Negate a point. */
+ def negatePoint(p: Ecp): Ecp = Platform.negatePoint(p)
+
+ /** Check if a point is infinity. */
+ def isInfinityPoint(p: Ecp): Boolean = Platform.isInfinityPoint(p)
+
+ /** Exponentiate a point.
+ *
+ * @param p point to exponentiate
+ * @param n exponent
+ * @return p to the power of n (`p^n`)
+ */
+ def exponentiatePoint(p: Ecp, n: BigInteger): Ecp = Platform.exponentiatePoint(p, n)
+
+ /** Multiply two points.
+ *
+ * @param p1 first point
+ * @param p2 second point
+ * @return group multiplication (p1 * p2)
+ */
+ def multiplyPoints(p1: Ecp, p2: Ecp): Ecp = Platform.multiplyPoints(p1, p2)
+
+ /** Return simplified string representation of the point (used only for debugging) */
+ def showPoint(p: Ecp): String = Platform.showPoint(p)
+
+ /** Returns the sign of the field element. */
+ def signOf(p: ECFieldElem): Boolean = Platform.signOf(p)
+
+ /** Returns byte representation of the given field element. */
+ def encodeFieldElem(p: ECFieldElem): Array[Byte] = Platform.encodeFieldElem(p)
+
+ /** Returns the x-coordinate.
+ *
+ * Caution: depending on the curve's coordinate system, this may not be the same value as in an
+ * affine coordinate system; use normalize() to get a point where the coordinates have their
+ * affine values, or use getAffineXCoord() if you expect the point to already have been
+ * normalized.
+ *
+ * @return the x-coordinate of this point
+ */
+ def getXCoord(p: Ecp): ECFieldElem = Platform.getXCoord(p)
+
+ /** Returns the y-coordinate.
+ *
+ * Caution: depending on the curve's coordinate system, this may not be the same value as in an
+ * affine coordinate system; use normalize() to get a point where the coordinates have their
+ * affine values, or use getAffineYCoord() if you expect the point to already have been
+ * normalized.
+ *
+ * @return the y-coordinate of this point
+ */
+ def getYCoord(p: Ecp): ECFieldElem = Platform.getYCoord(p)
+
+ /** Returns the affine x-coordinate after checking that this point is normalized.
+ *
+ * @return The affine x-coordinate of this point
+ * @throws IllegalStateException if the point is not normalized
+ */
+ def getAffineXCoord(p: Ecp): ECFieldElem = Platform.getAffineXCoord(p)
+
+ /** Returns the affine y-coordinate after checking that this point is normalized
+ *
+ * @return The affine y-coordinate of this point
+ * @throws IllegalStateException if the point is not normalized
+ */
+ def getAffineYCoord(p: Ecp): ECFieldElem = Platform.getAffineYCoord(p)
+}
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala
new file mode 100644
index 0000000000..36e8343e2b
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala
@@ -0,0 +1,577 @@
+/*
+ By Leonid Reyzin
+
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ For more information, please refer to
+ */
+package sigmastate.crypto
+
+import debox.cfor
+
+import java.util
+
+class GF2_192 extends AnyRef {
+ private[crypto] val word: Array[Long] = new Array[Long](3)
+
+ /**
+ * returns a copy of the field element
+ *
+ * @param that element to copy
+ */
+ def this(that: GF2_192) {
+ this()
+ this.word(0) = that.word(0)
+ this.word(1) = that.word(1)
+ this.word(2) = that.word(2)
+ }
+
+ /**
+ * returns the field element whose 32 least significant bits are bits of that and rest are 0
+ *
+ * @param that lower 32 bits
+ */
+ def this(that: Int) {
+ this()
+ this.word(0) = that.toLong & 0xFFFFFFFFL
+ }
+
+ /**
+ * returns the field element whose bits are given by the long array
+ *
+ * @param that must be length 3
+ */
+ def this(that: Array[Long]) {
+ this()
+ require(that.length == 3)
+ this.word(0) = that(0)
+ this.word(1) = that(1)
+ this.word(2) = that(2)
+ }
+
+ /**
+ * returns the field element whose bits are given by the byte array that[pos]...that[pos+23]
+ *
+ * @param that must be length at least pos+24
+ */
+ def this(that: Array[Byte], pos: Int) {
+ this()
+ assert(that.length >= pos + 24)
+ cfor(0)(_ < 8, _ + 1) { i =>
+ word(0) |= (that(i + pos).toLong & 0xFF) << (i << 3)
+ }
+ cfor(0)(_ < 8, _ + 1) { i =>
+ word(1) |= (that(i + pos + 8).toLong & 0xFF) << (i << 3)
+ }
+ cfor(0)(_ < 8, _ + 1) { i =>
+ word(2) |= (that(i + pos + 16).toLong & 0xFF) << (i << 3)
+ }
+ }
+
+ /**
+ * returns the field element whose bits are given by the byte array that
+ *
+ * @param that must be length 24
+ */
+ def this(that: Array[Byte]) {
+ this(that, 0)
+ }
+
+
+ /**
+ *
+ * @param obj the field element with which to compare
+ * @return true if and only if this and that represent the same field element
+ */
+ override def equals(obj: Any): Boolean = {
+ if (this eq obj.asInstanceOf[AnyRef]) return true // equal references
+ obj match {
+ case that: GF2_192 =>
+ this.word(0) == that.word(0) && this.word(1) == that.word(1) && this.word(2) == that.word(2)
+ case _ => false
+ }
+ }
+
+ override def hashCode = util.Arrays.hashCode(word)
+
+ /**
+ *
+ * @return long array of length 3 containing the three words of the field element
+ */
+ def toLongArray: Array[Long] = {
+ val ret = new Array[Long](3)
+ ret(0) = word(0)
+ ret(1) = word(1)
+ ret(2) = word(2)
+ ret
+ }
+
+ /**
+ *
+ * @return byte array of length 24 containing the two words of the field element
+ */
+ def toByteArray: Array[Byte] = {
+ val ret = new Array[Byte](24)
+ toByteArray(ret, 0)
+ ret
+ }
+
+ /**
+ * @param ret bytes of the field element will go into ret[pos]...ret[pos+23]
+ */
+ def toByteArray(ret: Array[Byte], pos: Int): Unit = {
+ assert(ret.length >= pos + 24)
+ cfor (0)(_ < 3, _ + 1) { j =>
+ cfor(0)(_ < 8, _ + 1) { i =>
+ ret(pos + i + 8 * j) = ((word(j) >> (i << 3)) & 0xFF).toByte
+ }
+ }
+ }
+
+ /**
+ *
+ * @return true if this == 0, false otherwise
+ */
+ def isZero: Boolean = word(0) == 0L && word(1) == 0L && word(2) == 0L
+
+ /**
+ *
+ * @return true if this == 1, false otherwise
+ */
+ def isOne: Boolean = word(0) == 1L && word(1) == 0L && word(2) == 0L
+
+ //The tables above were generated by the code below. The code is no longer needed.
+ /* *******************************************************************************************
+
+
+ static long [][] powTable0 = new long [7] [];
+ static long [][] powTable1 = new long [7] [];
+ static long [][] powTable2 = new long [7] [];
+
+ public static void genPowTable() {
+ GF2_192 z = new GF2_192();
+ int i;
+
+ powTable0[0] = new long [192];
+ powTable1[0] = new long [192];
+ powTable2[0] = new long [192];
+ i = 0;
+ for (; i<64; i++) {
+ z.word[0] = 1L<= 0, _ - 1) { i =>
+ w3 = w2 >>> 63
+ w2 = (w2 << 1) | (w1 >>> 63)
+ w1 = (w1 << 1) | (w0 >>> 63)
+ w0 <<= 1
+ val t: Long = (b >>> i) & 1
+ w2 ^= a.word(2) * t
+ w1 ^= a.word(1) * t
+ w0 ^= (a.word(0) * t) ^ (irredPentanomial * w3) // mod reduce
+ }
+ res.word(0) = w0
+ res.word(1) = w1
+ res.word(2) = w2
+ }
+
+ /**
+ * Computes a plus b and puts the result into res.
+ *
+ * @param res output; must be not null; may be equal to a and/or b
+ * @param a multiplicand; may be equal to res, in which case will get overwritten
+ * @param b multiplier; may be equal to res, in which case will get overwritten
+ */
+ def add(res: GF2_192, a: GF2_192, b: GF2_192): Unit = {
+ res.word(0) = a.word(0) ^ b.word(0)
+ res.word(1) = a.word(1) ^ b.word(1)
+ res.word(2) = a.word(2) ^ b.word(2)
+ }
+
+ /**
+ * Computes a times b and puts the result into res.
+ * Uses table lookups, which may not preserve
+ * the secrecy of the inputs in case of side-channel attacks.
+ *
+ * @param res output; must be not null; may be equal to a and/or b
+ * @param a multiplicand; may be equal to res, in which case will get overwritten
+ * @param b multiplier; may be equal to res, in which case will get overwritten
+ */
+ def mul(res: GF2_192,
+ a: GF2_192,
+ b: GF2_192): Unit = {
+ // Implements a sort of times-x-and-add algorithm, except instead of multiplying by x
+ // we multiply by x^4 and then add one of possible 16 precomputed values
+ // contains a*0, a*1, a*x, a*(x+1), a*x^2, a*(x^2+1), a*(x^2+x), a*(x^2+x+1)
+ // a*x^3, a*(x^3+1), a*(x^3+x), a*(x^3+x+1), a*(x^3+x^2), a*(x^3+x^2+1), a*(x^3+x^2+x), a*(x^3+x^2+x+1), all mod reduced
+ // First word of each is in a0 muls, second word of each is in a1muls, third word of each is in a2muls
+ val a0muls = new Array[Long](16)
+ val a1muls = new Array[Long](16)
+ val a2muls = new Array[Long](16)
+
+ // a0muls[0], a1muls[0] and a2muls[0] are already correctly initialized to 0
+ a0muls(1) = a.word(0)
+ a1muls(1) = a.word(1)
+ a2muls(1) = a.word(2)
+ // a*x, a*x^2, a*x^3
+ var i = 2
+ while (i <= 8) {
+ // multiply a*x^{log_2 i/2} by x to get a*x^{log_2 i}
+ val prev = i / 2
+ a0muls(i) = a0muls(prev) << 1
+ a1muls(i) = (a1muls(prev) << 1) | (a0muls(prev) >>> 63)
+ a2muls(i) = (a2muls(prev) << 1) | (a1muls(prev) >>> 63)
+ // mod reduce
+ a0muls(i) ^= irredMuls((a2muls(prev) >>> 63).toInt)
+ i *= 2
+ }
+
+ // a*(x+1)
+ a0muls(3) = a0muls(1) ^ a0muls(2)
+ a1muls(3) = a1muls(1) ^ a1muls(2)
+ a2muls(3) = a2muls(1) ^ a2muls(2)
+
+ // a*(x^2+1), a*(x^2+x), a*(x^2+x+1)
+ cfor(1)(_ < 4, _ + 1) { i =>
+ a0muls(4 | i) = a0muls(4) ^ a0muls(i)
+ a1muls(4 | i) = a1muls(4) ^ a1muls(i)
+ a2muls(4 | i) = a2muls(4) ^ a2muls(i)
+ }
+
+ // a*(x^3+1), a*(x^3+x), a*(x^3+x+1), a*(x^3+x^2), a*(x^3+x^2+1), a*(x^3+x^2+x), a*(x^3+x^2+x+1)
+ cfor(1)(_ < 8, _ + 1) { i =>
+ a0muls(8 | i) = a0muls(8) ^ a0muls(i)
+ a1muls(8 | i) = a1muls(8) ^ a1muls(i)
+ a2muls(8 | i) = a2muls(8) ^ a2muls(i)
+ }
+ var w0: Long = 0
+ var w1: Long = 0
+ var w2: Long = 0
+ cfor(2)(_ >= 0, _ - 1) { j =>
+ val multiplier = b.word(j)
+ var i = 60
+ while (i >= 0) {
+ // Multiply by x^4
+ val modReduceIndex = (w2 >>> 60).toInt
+ w2 = (w2 << 4) | (w1 >>> 60)
+ w1 = (w1 << 4) | (w0 >>> 60)
+ // MOD REDUCE ACCORDING TO modReduceIndex by XORing the right value
+ w0 = (w0 << 4) ^ irredMuls(modReduceIndex)
+ //w0 = (w0<<4)^(irredPentanomial*(modReduceIndex&8))^(irredPentanomial*(modReduceIndex&4))^(irredPentanomial*(modReduceIndex&2))^(irredPentanomial*(modReduceIndex&1));
+ // Add the correct multiple of a
+ val index = ((multiplier >>> i) & 15).toInt
+ w0 ^= a0muls(index)
+ w1 ^= a1muls(index)
+ w2 ^= a2muls(index)
+ i -= 4
+ }
+ }
+ res.word(0) = w0
+ res.word(1) = w1
+ res.word(2) = w2
+ }
+
+ def invert(res: GF2_192,
+ z: GF2_192): Unit = {
+ // Computes z^{2^192-2} = z^{exponent written in binary as 191 ones followed by a single zero}
+ // (by Fermat's little theorem, this is the correct inverse)
+ // contains z raised to the power whose binary representation is 2^k ones
+ val zTo2ToK1s = new GF2_192(z)
+
+ // Square res to get its exponent to be 10 in binary
+ mul(res, z, z)
+ // contains z raised to the power whose binary representation is 2^k ones followed by 2^k zeros
+ val zTo2ToK1s2ToK0s = new GF2_192(res)
+ // Loop invariant
+ // res contains z raised to the power whose binary representation is 2^{k+1}-1 ones followed by a single zero
+ // zTo2ToK1s contains z raised to the power whose binary representation is 2^k ones
+ // zTo2ToK1s2ToK0s contains z raised to the power whose binary representation is 2^k ones followed by 2^k zeros
+ var k = 0
+ while (k < 6) {
+ k += 1
+ // Fill in the zeros in the exponent of zTo2ToK1s2ToK0s with ones
+ mul(zTo2ToK1s, zTo2ToK1s2ToK0s, zTo2ToK1s)
+ // zTo2ToK1s2ToK0s = power2To2ToK with 2^k zeros appended to the exponent
+ power2To2ToK(zTo2ToK1s2ToK0s, zTo2ToK1s, k)
+ // prepend 2^k ones to res
+ mul(res, res, zTo2ToK1s2ToK0s)
+ }
+ // Prepened another 64 ones to res
+ power2To2ToK(zTo2ToK1s2ToK0s, zTo2ToK1s2ToK0s, k)
+ mul(res, res, zTo2ToK1s2ToK0s)
+ }
+
+ /**
+ * Squares z and puts the result into res. Same as power2To2ToK(res, z, 0).
+ * About same efficiency as mul(res, z, z) (more efficient implementations are possible,
+ * but not provided here because of risk of side-channel attacks)
+ *
+ * @param res output; must be not null; may be equal to z
+ * @param z input to be squared; may be equal to res, in which case will get overwritten
+ */
+ def sqr(res: GF2_192,
+ z: GF2_192): Unit = {
+ // It is possible to precompute the square of every byte value in every byte position
+ // (only bytes a few byte positions are needed -- squares of bytes in other positions
+ // can be figured out by shifting squares of bytes in positions 0 and 16). This will result in a slightly
+ // bigger table and several times more efficient squaring. However, because table lookups will
+ // be input-dependent, this gives a higher risk of side-channel attacks that reveal z.
+ // Hence, it's not implemented.
+ //
+ power2To2ToK(res, z, 0)
+ }
+
+ /**
+ * Raises z to the power 2^{2^k} and puts the result into res. Same sqr(z, z) 2^k times.
+ * Takes only about as much time as mul(res, z, z) (even more efficient implementations are possible,
+ * but not provided here because of risk of side-channel attacks)
+ * @param res output; must be not null; may be equal to z
+ * @param z input to be squared; may be equal to res, in which case will get overwritten
+ */
+ def power2To2ToK(res: GF2_192, z: GF2_192, k: Int): Unit = {
+ if (k >= 7) {
+ // By Fermat's little theorem, z^{2^{2^k}} = z^{2^{2^k} mod (2^{192}-1)}
+ // If k>=7, then 2^{2^k} mod (2^{192}-1) = 2^64 when k is even and 2^128 when k is odd (proof below),
+ // so that's what we compute.
+ // Note that we have no precomputed table for k=7 (i.e., 2^128), because we don't expect
+ // this to be needed -- only up to k=6 is used in inversion.
+ // Here's the proof: let m = 64. 2^{2^k} mod (2^{192}-1) = 2^{mn} mod (2^{3m}-1) for n = 2^{k-6}.
+ // Let d = n div 3 and r = n mod 3.
+ // Then 2^{mn} = (2^{3m}-1) (2^{m(n-3}}+2^{m(n-6)}+...+2^{m-nd})+2^{nr}
+ // So the remainder is 2^{nr}. r is 2 when k is odd and 1 when k is even.
+ power2To2ToK(res, z, 6)
+ if (k % 2 == 1) {
+ power2To2ToK(res, res, 6)
+ }
+ } else {
+ // powTable0[k][i] contains the result of raising x^i to the power 2^k for i = 0...63
+ // powTable0[k][i-64] contains the result of raising x^i to the power 2^k for i = 64...127
+ // powTable0[k][i-128] contains the result of raising x^i to the power 2^k for i = 128...191
+ // Because raising to the power 2^k is linear over any field of characteristic 2,
+ // we just need to XOR the values in these tables at indices i where z is 1.
+ // This selection is done via multiplication by 0 or 1, to avoid having an input-dependent path
+ // through the code, thus reducing the chance of side-channel attacks.
+ //
+ // Note that more efficient tables can be precomputed -- for example, the result of raising
+ // every one of 16 possible 4-bit nibbles at every one of 32 possible nibble positions.
+ // But indexing into these tables will be input-dependent, which may make side-channel attacks easier.
+ var t0: Long = 0
+ var t1: Long = 0
+ var t2: Long = 0
+ var maxIndex = 0
+ var i = 0
+ cfor(0)(_ < z.word.length, _ + 1) { iW =>
+ var w = z.word(iW)
+ maxIndex += 64
+ while (i < maxIndex) {
+ val multiplier: Long = w & 1
+ // No "if w&1 == 0" here, to avoid a data-dependent path through the code,
+ // thus reducing the chance of side channel attacks
+ t0 ^= powTable0(k)(i) * multiplier
+ t1 ^= powTable1(k)(i) * multiplier
+ t2 ^= powTable2(k)(i) * multiplier
+ w >>>= 1
+ i += 1
+ }
+ }
+ res.word(0) = t0
+ res.word(1) = t1
+ res.word(2) = t2
+ }
+ }
+}
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala
new file mode 100644
index 0000000000..dc0617ea29
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala
@@ -0,0 +1,257 @@
+/*
+ By Leonid Reyzin
+
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ For more information, please refer to
+ */
+
+package sigmastate.crypto
+
+import debox.cfor
+
+import java.util
+import java.util.Arrays
+
+class GF2_192_Poly {
+ final private var c: Array[GF2_192] = null // must be not null and of length at least 1
+
+ private var deg: Int = 0 // must be >=0. actual degree is <= deg. c[deg+1]...c[c.length-1] must be 0 or null
+ // deg of the 0 polynomial is 0
+
+ /**
+ * Constructs the polynomial given the byte array representation of the coefficients.
+ * Coefficient of degree zero is given separately. Each coefficient should be given
+ * as a 24-byte representation of a GF2_192 value. Coefficient of degree 1 should
+ * start at moreCoeffs[0].
+ *
+ * @param coeff0 byte array representing lowest coefficient (24 bytes)
+ * @param moreCoeffs byte array with concatenation of byte-converted coefficients
+ * (24 bytes each) from degree 1 to the highest
+ */
+ def this(coeff0: Array[Byte], moreCoeffs: Array[Byte]) {
+ this()
+ deg = moreCoeffs.length / 24
+ c = new Array[GF2_192](deg + 1)
+ c(0) = new GF2_192(coeff0)
+ cfor(1)(_ <= deg, _ + 1) { i =>
+ c(i) = new GF2_192(moreCoeffs, (i - 1) * 24)
+ }
+ }
+
+ /**
+ * Evaluates the polynomial at a given point
+ *
+ * @param x the last byte of a field element (all other bits are assumed to be 0)
+ * @return the value of this polynomial evaluated at the field element
+ */
+ def evaluate(x: Byte): GF2_192 = {
+ val res = new GF2_192(c(deg))
+ cfor(deg - 1)(_ >= 0, _ - 1) { d =>
+ GF2_192.mul(res, res, x)
+ GF2_192.add(res, res, c(d))
+ }
+ res
+ }
+
+ /**
+ * adds r*p to this; assumes p is monic, c.length>p.deg, and (p.deg == this.deg+1, or this==0 and p==1)
+ *
+ * @param p the monic polynomial being added to this
+ * @param r the constant by which p is multiplied before being added
+ */
+ private def addMonicTimesConstantTo(p: GF2_192_Poly, r: GF2_192): Unit = {
+ val t: GF2_192 = new GF2_192
+ cfor(0)(_ < p.deg, _ + 1) { i =>
+ GF2_192.mul(t, p.c(i), r)
+ GF2_192.add(c(i), c(i), t)
+ }
+ deg = p.deg
+ c(deg) = new GF2_192(r)
+ }
+
+ /**
+ * multiplies this by (x+r), assuming this is monic of degree deg (i.e. assumed c[deg]==1)
+ *
+ * @param r the constant term of the monomial
+ */
+ private def monicTimesMonomial(r: Byte): Unit = {
+ deg += 1
+ c(deg) = new GF2_192(1)
+ cfor(deg - 1)(_ > 0, _ - 1) { i =>
+ // c[i] = c[i-1]+r*c[i]
+ GF2_192.mul(c(i), c(i), r)
+ GF2_192.add(c(i), c(i), c(i - 1))
+ }
+ GF2_192.mul(c(0), c(0), r)
+ }
+
+ /**
+ * Constructs a constant polynomial
+ *
+ * @param maxDeg the maximum degree this polynomial could possibly have (to allocate space)
+ * @param constantTerm the polynomial is initially created with degree 0 and given constantTerm
+ */
+ def this(maxDeg: Int, constantTerm: Int) {
+ this()
+ c = new Array[GF2_192](maxDeg + 1)
+ c(0) = new GF2_192(constantTerm)
+ deg = 0
+ }
+
+ /**
+ *
+ * @return this represented in usual polynomial notation (but possibly leading 0s), with X as the free variable
+ */
+ override def toString: String = {
+ var ret: String = ""
+ if (deg >= 2) {
+ ret += c(deg).toString + "*X^" + deg
+ cfor(deg - 1)(_ >= 2, _ - 1) { i =>
+ ret += " + " + c(i) + "*X^" + i
+ }
+ ret += " + "
+ }
+ if (deg >= 1) {
+ ret += c(1) + "*X" + " + "
+ }
+ ret += c(0)
+ ret
+ }
+
+ /**
+ * Returns a byte array that contains the concatenation of all the coefficients
+ * (except possibly the degree-0 coefficient, which is omitted if coeff0 is false).
+ * Lowest-degree coefficient (0 or 1 depending on coeff0) starts at index 0 of the returned array.
+ * Each coefficient takes 24 bytes, for a total of degree*24 bytes if coeff0 is false,
+ * or (degree+1)*24 bytes if coeff0 is true
+ *
+ * @param coeff0 whether to include coeff0
+ * @return array of all coefficients (except possibly 0th depending on coeff0)
+ */
+ def toByteArray(coeff0: Boolean): Array[Byte] = {
+ val c0 = if (coeff0) 0 else 1
+ val ret: Array[Byte] = new Array[Byte]((deg + 1 - c0) * 24)
+ cfor(c0)(_ <= deg, _ + 1) { i =>
+ c(i).toByteArray(ret, (i - c0) * 24)
+ }
+ ret
+ }
+
+ /**
+ * @return The degree-0 coefficient, converted to an array of 24 bytes
+ */
+ def coeff0Bytes: Array[Byte] = c(0).toByteArray
+
+ override def hashCode: Int = {
+ 31 * util.Arrays.deepHashCode(c.asInstanceOf[Array[AnyRef]]) + deg
+ }
+
+ override def equals(obj: Any): Boolean = {
+ if (this eq obj.asInstanceOf[AnyRef]) return true
+ obj match {
+ case that: GF2_192_Poly =>
+ util.Arrays.deepEquals(c.asInstanceOf[Array[AnyRef]], that.c.asInstanceOf[Array[AnyRef]]) &&
+ deg == that.deg
+ case _ => false
+ }
+ }
+}
+
+object GF2_192_Poly {
+ /**
+ * Factory constructor -- same as GF2_192_Poly(coeff0, moreCoeffs)
+ *
+ * @param coeff0 byte array representing lowest coefficient (24 bytes)
+ * @param moreCoeffs byte array with concatenation of byte-converted coefficients
+ * (24 bytes each) from degree 1 to the highest
+ * @return new polynomial with the given coefficients
+ */
+ // deg of the 0 polynomial is 0
+ def fromByteArray(coeff0: Array[Byte], moreCoeffs: Array[Byte]): GF2_192_Poly = {
+ val res = new GF2_192_Poly(coeff0, moreCoeffs)
+ res
+ }
+
+ /**
+ * Interpolates the polynomial at given points (and at point 0, if valueAt0!=null).
+ * If points are not all distinct, or if 0 is in the points array and valueAt0!=null, behavior is undefined.
+ * valueAt0 is separated only for efficiency reason; the caller can treat 0 like any other point instead
+ * (i.e., the points array can include 0 if valueAt0==null, but computation will be slightly less efficient).
+ * If points is null, or values is null, or if lengths of points and values arrays differ,
+ * or if the arrays are 0 length and valueAt0 is null, returns null.
+ *
+ * @param points the set of distinct inputs to the returned polynomial
+ * (last byte of the field element only; all other bits are assumed to be 0)
+ * @param values values[i] will be the result evaluating the returned polynomial at points[i]. values[i] must not be null.
+ * @param valueAt0 if not null, then valueAt0 will be the result of evaluating the returned polynomial at 0
+ * @return the unique lowest-degree polynomial p such that for every i, p(points[i]) = values[i] and p(0)=valueAt0
+ * (if valueAt0!=null)
+ */
+ def interpolate(points: Array[Byte],
+ values: Array[GF2_192],
+ valueAt0: GF2_192): GF2_192_Poly = {
+ if (points == null || values == null ||
+ (values.length == 0 && valueAt0 == null) ||
+ values.length != points.length) return null
+
+ var resultDegree = values.length - 1
+ if (valueAt0 != null) resultDegree += 1
+
+ val result = new GF2_192_Poly(resultDegree, 0)
+ val vanishingPoly = new GF2_192_Poly(resultDegree, 1)
+
+ cfor (0)(_ < points.length, _ + 1) { i =>
+ val t = result.evaluate(points(i))
+ val s = vanishingPoly.evaluate(points(i))
+
+ // need to find r such that currentValue+r*valueOfVanishingPoly = values[i]
+ GF2_192.add(t, t, values(i))
+ GF2_192.invert(s, s)
+ GF2_192.mul(t, t, s)
+
+ result.addMonicTimesConstantTo(vanishingPoly, t)
+
+ if (i < points.length - 1 || valueAt0 != null) {
+ vanishingPoly.monicTimesMonomial(points(i))
+ }
+ }
+
+ if (valueAt0 != null) {
+ // the last point is 0
+ val t = new GF2_192(result.c(0)) // evaluating at 0 is easy
+ val s = new GF2_192(vanishingPoly.c(0))
+
+ // need to find r such that currentValue+r*valueOfVanishingPoly = valueAt0]
+ GF2_192.add(t, t, valueAt0)
+ GF2_192.invert(s, s)
+ GF2_192.mul(t, t, s)
+ result.addMonicTimesConstantTo(vanishingPoly, t)
+ }
+
+ result
+ }
+
+}
+
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala
new file mode 100644
index 0000000000..5cb4a9f345
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala
@@ -0,0 +1,106 @@
+package sigmastate.crypto
+
+import org.bouncycastle.crypto.ec.CustomNamedCurves
+import org.bouncycastle.math.ec.{ECFieldElement, ECPoint}
+
+import java.math.BigInteger
+
+/** JVM specific implementation of crypto methods*/
+object Platform {
+ /** Returns the x-coordinate.
+ *
+ * Caution: depending on the curve's coordinate system, this may not be the same value as in an
+ * affine coordinate system; use normalize() to get a point where the coordinates have their
+ * affine values, or use getAffineXCoord() if you expect the point to already have been
+ * normalized.
+ *
+ * @return the x-coordinate of this point
+ */
+ def getXCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getXCoord)
+
+ /** Returns the y-coordinate.
+ *
+ * Caution: depending on the curve's coordinate system, this may not be the same value as in an
+ * affine coordinate system; use normalize() to get a point where the coordinates have their
+ * affine values, or use getAffineYCoord() if you expect the point to already have been
+ * normalized.
+ *
+ * @return the y-coordinate of this point
+ */
+ def getYCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getYCoord)
+
+ /** Returns the affine x-coordinate after checking that this point is normalized.
+ *
+ * @return The affine x-coordinate of this point
+ * @throws IllegalStateException if the point is not normalized
+ */
+ def getAffineXCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getAffineXCoord)
+
+ /** Returns the affine y-coordinate after checking that this point is normalized
+ *
+ * @return The affine y-coordinate of this point
+ * @throws IllegalStateException if the point is not normalized
+ */
+ def getAffineYCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getAffineYCoord)
+
+ /** Returns byte representation of the given field element. */
+ def encodeFieldElem(p: ECFieldElem): Array[Byte] = p.value.getEncoded
+
+ /** Returns the value of bit 0 in BigInteger representation of this point. */
+ def signOf(p: ECFieldElem): Boolean = p.value.testBitZero()
+
+ /** * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
+ * coordinates reflect those of the equivalent point in an affine coordinate system.
+ *
+ * @return a new ECPoint instance representing the same point, but with normalized coordinates
+ */
+ def normalizePoint(p: Ecp): Ecp = Ecp(p.value.normalize())
+
+ /** Return simplified string representation of the point (used only for debugging) */
+ def showPoint(p: Ecp): String = {
+ val rawX = p.value.getRawXCoord.toString.substring(0, 6)
+ val rawY = p.value.getRawYCoord.toString.substring(0, 6)
+ s"ECPoint($rawX,$rawY,...)"
+ }
+
+ /** Multiply two points.
+ * @param p1 first point
+ * @param p2 second point
+ * @return group multiplication (p1 * p2)
+ */
+ def multiplyPoints(p1: Ecp, p2: Ecp): Ecp = {
+ /*
+ * BC treats EC as additive group while we treat that as multiplicative group.
+ */
+ Ecp(p1.value.add(p2.value))
+ }
+
+ /** Exponentiate a point.
+ * @param p point to exponentiate
+ * @param n exponent
+ * @return p to the power of n (p^n)
+ */
+ def exponentiatePoint(p: Ecp, n: BigInteger): Ecp = {
+ /*
+ * BC treats EC as additive group while we treat that as multiplicative group.
+ * Therefore, exponentiate point is multiply.
+ */
+ Ecp(p.value.multiply(n))
+ }
+
+ /** Check if a point is infinity. */
+ def isInfinityPoint(p: Ecp): Boolean = p.value.isInfinity
+
+ /** Negate a point. */
+ def negatePoint(p: Ecp): Ecp = Ecp(p.value.negate())
+
+ /** Wrapper for point type. */
+ case class Ecp(private[crypto] val value: ECPoint)
+
+ /** Wrapper for field element type. */
+ case class ECFieldElem(value: ECFieldElement)
+
+ /** Create a new context for cryptographic operations. */
+ def createContext(): CryptoContext = new CryptoContextJvm(CustomNamedCurves.getByName("secp256k1"))
+
+}
diff --git a/sigmastate/src/main/scala/sigmastate/crypto/package.scala b/sigmastate/src/main/scala/sigmastate/crypto/package.scala
new file mode 100644
index 0000000000..24d797be6f
--- /dev/null
+++ b/sigmastate/src/main/scala/sigmastate/crypto/package.scala
@@ -0,0 +1,8 @@
+package sigmastate
+
+package object crypto {
+ /** Instance of Elliptic Curve point. */
+ type Ecp = Platform.Ecp
+ /** Instance of Elliptic Curve field element. */
+ type ECFieldElem = Platform.ECFieldElem
+}
diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala
index c152cb1716..76bafd2fa2 100644
--- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala
+++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala
@@ -1,10 +1,9 @@
package sigmastate.eval
-import com.google.common.primitives.{Ints, Longs}
+import scorex.utils.{Ints, Longs}
import java.math.BigInteger
import java.util.Arrays
-import org.bouncycastle.math.ec.ECPoint
import org.ergoplatform.{ErgoBox, SigmaConstants}
import org.ergoplatform.validation.ValidationRules
import scalan.OverloadHack.Overloaded1
@@ -27,6 +26,7 @@ import scorex.crypto.hash.{Blake2b256, Digest32, Sha256}
import sigmastate.Values.ErgoTree.EmptyConstants
import sigmastate.basics.DLogProtocol.ProveDlog
import sigmastate.basics.ProveDHTuple
+import sigmastate.crypto.{CryptoFacade, Ecp}
import sigmastate.lang.TransformingSigmaBuilder
import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer
import sigmastate.serialization.{GroupElementSerializer, SigmaSerializer}
@@ -96,7 +96,7 @@ case class CBigInt(override val wrappedValue: BigInteger) extends BigInt with Wr
/** A default implementation of [[GroupElement]] interface.
* @see [[GroupElement]] for detailed descriptions
*/
-case class CGroupElement(override val wrappedValue: EcPointType) extends GroupElement with WrapperOf[ECPoint] {
+case class CGroupElement(override val wrappedValue: Ecp) extends GroupElement with WrapperOf[Ecp] {
val dsl = CostingSigmaDslBuilder
override def toString: String = s"GroupElement(${Extensions.showECPoint(wrappedValue)})"
@@ -104,16 +104,16 @@ case class CGroupElement(override val wrappedValue: EcPointType) extends GroupEl
override def getEncoded: Coll[Byte] =
dsl.Colls.fromArray(GroupElementSerializer.toBytes(wrappedValue))
- override def isInfinity: Boolean = wrappedValue.isInfinity
+ override def isIdentity: Boolean = CryptoFacade.isInfinityPoint(wrappedValue)
override def exp(k: BigInt): GroupElement =
- dsl.GroupElement(wrappedValue.multiply(k.asInstanceOf[CBigInt].wrappedValue))
+ dsl.GroupElement(CryptoFacade.exponentiatePoint(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue))
override def multiply(that: GroupElement): GroupElement =
- dsl.GroupElement(wrappedValue.add(that.asInstanceOf[CGroupElement].wrappedValue))
+ dsl.GroupElement(CryptoFacade.multiplyPoints(wrappedValue, that.asInstanceOf[CGroupElement].wrappedValue))
override def negate: GroupElement =
- dsl.GroupElement(wrappedValue.negate())
+ dsl.GroupElement(CryptoFacade.negatePoint(wrappedValue))
}
/** A default implementation of [[SigmaProp]] interface.
@@ -131,6 +131,7 @@ case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[
override def propBytes: Coll[Byte] = {
// in order to have comparisons like `box.propositionBytes == pk.propBytes` we need to make sure
// the same serialization method is used in both cases
+ // TODO v6.0: add `pk.propBytes(version)`
val root = sigmaTree.toSigmaProp
val ergoTree = new ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, Right(root), 0, null, None)
val bytes = DefaultSerializer.serializeErgoTree(ergoTree)
@@ -142,19 +143,11 @@ case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[
CSigmaProp(CAND.normalized(Array(sigmaTree, other.sigmaTree)))
}
- // TODO refactor: remove this (it shouldn't be used in interpreter)
- override def &&(other: Boolean): SigmaProp =
- CSigmaProp(CAND.normalized(Array(sigmaTree, TrivialProp(other))))
-
override def ||(other: SigmaProp): SigmaProp = other match {
case other: CSigmaProp =>
CSigmaProp(COR.normalized(Array(sigmaTree, other.sigmaTree)))
}
- // TODO refactor: remove this (it shouldn't be used in interpreter)
- override def ||(other: Boolean): SigmaProp =
- CSigmaProp(COR.normalized(Array(sigmaTree, TrivialProp(other))))
-
override def toString: String = s"SigmaProp(${wrappedValue.showToString})"
}
@@ -509,7 +502,8 @@ class CostingSigmaDslBuilder extends SigmaDslBuilder { dsl =>
override def toBigInteger(n: BigInt): BigInteger = n.asInstanceOf[CBigInt].wrappedValue
- def GroupElement(p: ECPoint): GroupElement = p match {
+ /** Wraps the given elliptic curve point into GroupElement type. */
+ def GroupElement(p: Ecp): GroupElement = p match {
case ept: EcPointType => CGroupElement(ept)
case m => sys.error(s"Point of type ${m.getClass} is not supported")
}
@@ -523,9 +517,12 @@ class CostingSigmaDslBuilder extends SigmaDslBuilder { dsl =>
/** Extract `sigmastate.AvlTreeData` from DSL's `AvlTree` type. */
def toAvlTreeData(p: AvlTree): AvlTreeData = p.asInstanceOf[CAvlTree].treeData
- /** Extract `org.bouncycastle.math.ec.ECPoint` from DSL's `GroupElement` type. */
- def toECPoint(ge: GroupElement): ECPoint = ge.asInstanceOf[CGroupElement].wrappedValue
+ /** Extract `sigmastate.crypto.Ecp` from DSL's `GroupElement` type. */
+ def toECPoint(ge: GroupElement): Ecp = ge.asInstanceOf[CGroupElement].wrappedValue
+ /** Creates a new AvlTree instance with the given parameters.
+ * @see AvlTreeData for details
+ */
override def avlTree(operationFlags: Byte, digest: Coll[Byte], keyLength: Int, valueLengthOpt: Option[Int]): CAvlTree = {
val treeData = AvlTreeData(ADDigest @@ digest.toArray, AvlTreeFlags(operationFlags), keyLength, valueLengthOpt)
CAvlTree(treeData)
diff --git a/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala b/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala
index 830d6817d8..d54c2e8f7a 100644
--- a/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala
+++ b/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala
@@ -1,6 +1,5 @@
package sigmastate.eval
-import org.bouncycastle.math.ec.ECPoint
import org.ergoplatform._
import scalan.RType
import scalan.RType._
@@ -99,7 +98,6 @@ object Evaluation {
case BigIntegerRType => SBigInt
case BigIntRType => SBigInt
- case ECPointRType => SGroupElement
case GroupElementRType => SGroupElement
case AvlTreeRType => SAvlTree
@@ -147,7 +145,6 @@ object Evaluation {
case _: BigInteger => BigIntegerRType
case _: special.sigma.BigInt => BigIntRType
- case _: ECPoint => ECPointRType
case _: GroupElement => GroupElementRType
case _: ErgoBox => ErgoBoxRType
diff --git a/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala
index bf982e3269..a5d93ba25c 100644
--- a/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala
+++ b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala
@@ -1,7 +1,5 @@
package sigmastate.eval
-import org.bouncycastle.math.ec.ECPoint
-
import java.math.BigInteger
import scalan.RType
import sigmastate.{SCollection, SCollectionType, SType}
@@ -13,6 +11,7 @@ import sigmastate.SType.AnyOps
import org.ergoplatform.ErgoBox
import debox.{Buffer => DBuffer}
import debox.cfor
+import sigmastate.crypto.{CryptoFacade, Ecp}
object Extensions {
private val Colls = CostingSigmaDslBuilder.Colls
@@ -89,14 +88,12 @@ object Extensions {
}
/** Shortened String representation of `source` GroupElement. */
- def showECPoint(p: ECPoint): String = {
- if (p.isInfinity) {
- "INF"
+ def showECPoint(p: Ecp): String = {
+ if (p.isIdentity) {
+ "IDENTITY"
}
else {
- val rawX = p.getRawXCoord.toString.substring(0, 6)
- val rawY = p.getRawYCoord.toString.substring(0, 6)
- s"ECPoint($rawX,$rawY,...)"
+ CryptoFacade.showPoint(p)
}
}
diff --git a/sigmastate/src/main/scala/sigmastate/eval/Profiler.scala b/sigmastate/src/main/scala/sigmastate/eval/Profiler.scala
index b3fad46020..2f0e7f3e0c 100644
--- a/sigmastate/src/main/scala/sigmastate/eval/Profiler.scala
+++ b/sigmastate/src/main/scala/sigmastate/eval/Profiler.scala
@@ -7,7 +7,6 @@ import sigmastate.serialization.OpCodes.OpCode
import sigmastate.serialization.ValueSerializer.getSerializer
import scalan.util.Extensions.ByteOps
import debox.{Buffer => DBuffer, Map => DMap}
-import org.apache.commons.math3.util.Precision
import debox.sp
import sigmastate.eval.Extensions.DBufferOps
import sigmastate.interpreter.{CostItem, FixedCostItem, SeqCostItem, TypeBasedCostItem}
@@ -335,7 +334,7 @@ class Profiler {
.map { case (opName, error, cost, time, count) =>
val key = s"$opName".padTo(30, ' ')
val warn = if (cost < time) "!!!" else ""
- val err = Precision.round(error, 4)
+ val err = f"$error%4.4f"
s"$key -> ($err, $cost$warn, $time), // count = $count "
}
.mkString("\n")
diff --git a/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala
index 4f8501606f..25f909e8bc 100644
--- a/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala
+++ b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala
@@ -319,10 +319,6 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext =>
case OM.isDefined(In(optionSym)) =>
mkOptionIsDefined(optionSym.asValue[SOption[SType]])
- case SigmaM.and_bool_&&(In(prop), In(cond)) => // TODO refactor: remove or cover by tests: it is never executed
- SigmaAnd(Seq(prop.asSigmaProp, mkBoolToSigmaProp(cond.asBoolValue)))
- case SigmaM.or_bool_||(In(prop), In(cond)) => // TODO refactor: remove or cover by tests: it is never executed
- SigmaOr(Seq(prop.asSigmaProp, mkBoolToSigmaProp(cond.asBoolValue)))
case SigmaM.and_sigma_&&(In(p1), In(p2)) =>
SigmaAnd(Seq(p1.asSigmaProp, p2.asSigmaProp))
case SigmaM.or_sigma_||(In(p1), In(p2)) =>
diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala
index 1da6c8c27e..1d4a3a2d28 100644
--- a/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala
+++ b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala
@@ -2,17 +2,21 @@ package sigmastate.interpreter
import java.math.BigInteger
import java.security.SecureRandom
+import sigmastate.basics.{BcDlogGroup, SecP256K1Group}
+import sigmastate.crypto.Ecp
-import org.bouncycastle.math.ec.custom.sec.SecP256K1Point
-import sigmastate.basics.{BcDlogGroup, SecP256K1}
-
+/** Constants used in crypto operations implementation. */
object CryptoConstants {
- type EcPointType = SecP256K1Point
+ /** Type of group elements used in the signature scheme. */
+ type EcPointType = Ecp
+ /** Length of encoded group element in bytes. */
val EncodedGroupElementLength: Byte = 33
- val dlogGroup: BcDlogGroup[EcPointType] = SecP256K1
+ /** Group used in the signature scheme. */
+ val dlogGroup: BcDlogGroup = SecP256K1Group
+ /** Secure random generator used in the signature scheme. */
val secureRandom: SecureRandom = dlogGroup.secureRandom
/** Size of the binary representation of any group element (2 ^ groupSizeBits == ) */
@@ -27,6 +31,7 @@ object CryptoConstants {
/** Length of hash function used in the signature scheme. Blake2b hash function is used. */
val hashLengthBits = 256
+ /** Length of hash in bytes. */
val hashLength: Int = hashLengthBits / 8
/** A size of challenge in Sigma protocols, in bits.
@@ -37,6 +42,10 @@ object CryptoConstants {
*/
implicit val soundnessBits: Int = 192.ensuring(_ < groupSizeBits, "2^t < q condition is broken!")
+ /** Generates random bytes using secure random generator.
+ * @param howMany number of bytes to generate
+ * @return generated bytes in a new array
+ */
def secureRandomBytes(howMany: Int): Array[Byte] = {
val bytes = new Array[Byte](howMany)
secureRandom.nextBytes(bytes)
diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ErgoTreeEvaluator.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ErgoTreeEvaluator.scala
index d28ec31c3f..bdd59eb850 100644
--- a/sigmastate/src/main/scala/sigmastate/interpreter/ErgoTreeEvaluator.scala
+++ b/sigmastate/src/main/scala/sigmastate/interpreter/ErgoTreeEvaluator.scala
@@ -6,7 +6,7 @@ import sigmastate.{PerItemCost, VersionContext, TypeBasedCost, FixedCost, SType,
import sigmastate.Values._
import sigmastate.eval.Profiler
import sigmastate.interpreter.ErgoTreeEvaluator.DataEnv
-import sigmastate.interpreter.Interpreter.JitReductionResult
+import sigmastate.interpreter.Interpreter.ReductionResult
import special.sigma.{Context, SigmaProp}
import scalan.util.Extensions._
import sigmastate.interpreter.EvalSettings._
@@ -460,7 +460,7 @@ object ErgoTreeEvaluator {
* @param evalSettings evaluation settings
* @return a sigma protocol proposition (as [[SigmaBoolean]]) and accumulated JIT cost estimation.
*/
- def evalToCrypto(context: ErgoLikeContext, ergoTree: ErgoTree, evalSettings: EvalSettings): JitReductionResult = {
+ def evalToCrypto(context: ErgoLikeContext, ergoTree: ErgoTree, evalSettings: EvalSettings): ReductionResult = {
val (res, cost) = eval(context, ergoTree.constants, ergoTree.toProposition(replaceConstants = false), evalSettings)
val sb = res match {
case sp: SigmaProp =>
@@ -468,7 +468,7 @@ object ErgoTreeEvaluator {
case sb: SigmaBoolean => sb
case _ => error(s"Expected SigmaBoolean but was: $res")
}
- JitReductionResult(sb, cost)
+ ReductionResult(sb, cost)
}
/** Evaluate the given expression in the given Ergo context using the given settings.
diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala
index 4f9ba46e05..1276849e60 100644
--- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala
+++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala
@@ -1,12 +1,12 @@
package sigmastate.interpreter
import java.util
-import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, rule, strategy}
-import org.bitbucket.inkytonik.kiama.rewriting.Strategy
+import sigmastate.kiama.rewriting.Rewriter.{everywherebu, rule, strategy}
+import sigmastate.kiama.rewriting.Strategy
import org.ergoplatform.ErgoLikeContext
import org.ergoplatform.validation.SigmaValidationSettings
import org.ergoplatform.validation.ValidationRules._
-import scorex.util.ScorexLogging
+import sigmastate.basics.DLogProtocol.ProveDlog
import sigmastate.SCollection.SByteArray
import sigmastate.Values._
import sigmastate.basics.DLogProtocol.{ProveDlog, DLogInteractiveProver, FirstDLogProverMessage}
@@ -46,7 +46,7 @@ import scala.util.{Try, Success}
* The interpreter has evaluationMode which defines how it should execute scripts.
* @see verify, fullReduction
*/
-trait Interpreter extends ScorexLogging {
+trait Interpreter {
type CTX <: InterpreterContext
@@ -63,6 +63,11 @@ trait Interpreter extends ScorexLogging {
println(msg)
}
+ protected def logMessage(msg: String, t: Throwable) = {
+ println(msg)
+ t.printStackTrace(System.out)
+ }
+
/** The cost of Value[T] deserialization is O(n), where n is the length of its bytes
* array. To evaluate [[DeserializeContext]] and
* [[sigmastate.utxo.DeserializeRegister]] we add the following cost of deserialization
@@ -159,9 +164,9 @@ trait Interpreter extends ScorexLogging {
* @return result of script reduction
* @see `ReductionResult`
*/
- protected def reduceToCryptoJITC(context: CTX, env: ScriptEnv, exp: SigmaPropValue): Try[JitReductionResult] = Try {
+ protected def reduceToCryptoJITC(context: CTX, env: ScriptEnv, exp: SigmaPropValue): Try[ReductionResult] = Try {
implicit val vs = context.validationSettings
- trySoftForkable[JitReductionResult](whenSoftFork = WhenSoftForkJitReductionResult(context.initCost)) {
+ trySoftForkable[ReductionResult](whenSoftFork = WhenSoftForkReductionResult(context.initCost)) {
val (resProp, cost) = {
val ctx = context.asInstanceOf[ErgoLikeContext]
@@ -172,7 +177,7 @@ trait Interpreter extends ScorexLogging {
}
}
- JitReductionResult(SigmaDsl.toSigmaBoolean(resProp), cost.toLong)
+ ReductionResult(SigmaDsl.toSigmaBoolean(resProp), cost.toLong)
}
}
@@ -193,7 +198,7 @@ trait Interpreter extends ScorexLogging {
*/
def fullReduction(ergoTree: ErgoTree,
ctx: CTX,
- env: ScriptEnv): FullReductionResult = {
+ env: ScriptEnv): ReductionResult = {
implicit val vs: SigmaValidationSettings = ctx.validationSettings
val context = ctx.withErgoTreeVersion(ergoTree.version).asInstanceOf[CTX]
VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) {
@@ -206,14 +211,13 @@ trait Interpreter extends ScorexLogging {
// NOTE, evaluator cost unit needs to be scaled to the cost unit of context
val evalCost = Eval_SigmaPropConstant.costKind.cost.toBlockCost
val resCost = Evaluation.addCostChecked(context.initCost, evalCost, context.costLimit)
- val jitRes = JitReductionResult(sb, resCost)
- FullReductionResult(jitRes)
+ ReductionResult(sb, resCost)
case _ if !ergoTree.hasDeserialize =>
val ctx = context.asInstanceOf[ErgoLikeContext]
- val jitRes = VersionContext.withVersions(ctx.activatedScriptVersion, ergoTree.version) {
+ val res = VersionContext.withVersions(ctx.activatedScriptVersion, ergoTree.version) {
ErgoTreeEvaluator.evalToCrypto(ctx, ergoTree, evalSettings)
}
- FullReductionResult(jitRes)
+ res
case _ =>
reductionWithDeserialize(ergoTree, prop, context, env)
}
@@ -225,7 +229,7 @@ trait Interpreter extends ScorexLogging {
* which encodes either a sigma-protocol proposition or a boolean (true or false) value.
* See other overload for details.
*/
- def fullReduction(ergoTree: ErgoTree, ctx: CTX): FullReductionResult = {
+ def fullReduction(ergoTree: ErgoTree, ctx: CTX): ReductionResult = {
fullReduction(ergoTree, ctx, Interpreter.emptyEnv)
}
@@ -233,9 +237,9 @@ trait Interpreter extends ScorexLogging {
private def reductionWithDeserialize(ergoTree: ErgoTree,
prop: SigmaPropValue,
context: CTX,
- env: ScriptEnv): FullReductionResult = {
+ env: ScriptEnv): ReductionResult = {
implicit val vs: SigmaValidationSettings = context.validationSettings
- val jitRes = VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) {
+ val res = VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) {
val deserializeSubstitutionCost = java7.compat.Math.multiplyExact(ergoTree.bytes.length, CostPerTreeByte)
val currCost = Evaluation.addCostChecked(context.initCost, deserializeSubstitutionCost, context.costLimit)
val context1 = context.withInitCost(currCost).asInstanceOf[CTX]
@@ -248,7 +252,7 @@ trait Interpreter extends ScorexLogging {
reduceToCryptoJITC(context2, env, propTree).getOrThrow
}
- FullReductionResult(jitRes)
+ res
}
/** Adds the cost to verify sigma protocol proposition.
@@ -259,7 +263,7 @@ trait Interpreter extends ScorexLogging {
* @param costLimit total cost limit to check and raise exception if exceeded
* @return computed jitRes.cost + crypto verification cost
*/
- protected def addCryptoCost(jitRes: JitReductionResult, costLimit: Long) = {
+ protected def addCryptoCost(jitRes: ReductionResult, costLimit: Long) = {
val cryptoCost = estimateCryptoVerifyCost(jitRes.value).toBlockCost // scale JitCost to tx cost
// Note, jitRes.cost is already scaled in fullReduction
@@ -352,7 +356,7 @@ trait Interpreter extends ScorexLogging {
case TrivialProp.TrueProp => (true, reduced.cost)
case TrivialProp.FalseProp => (false, reduced.cost)
case _ =>
- val fullJitCost = addCryptoCost(reduced.jitRes, context.costLimit)
+ val fullCost = addCryptoCost(reduced, context.costLimit)
val ok = if (evalSettings.isMeasureOperationTime) {
val E = ErgoTreeEvaluator.forProfiling(verifySignatureProfiler, evalSettings)
@@ -360,7 +364,7 @@ trait Interpreter extends ScorexLogging {
} else {
verifySignature(reduced.value, message, proof)(null)
}
- (ok, fullJitCost)
+ (ok, fullCost)
}
}
}
@@ -459,7 +463,7 @@ trait Interpreter extends ScorexLogging {
// NOTE, property("handle improper signature") doesn't lead to exception
// because the current implementation of parseAndComputeChallenges doesn't throw
// an exception
- log.warn("Improper signature: ", t);
+ logMessage("Improper signature: ", t);
false
}
}
@@ -473,34 +477,14 @@ object Interpreter {
* The second component is the estimated cost of contract execution. */
type VerificationResult = (Boolean, Long)
- /** Result of ErgoTree reduction procedure (see `fullReduction`) */
- abstract class ReductionResult {
- /** The value of SigmaProp type which represents a logical statement verifiable via
- * sigma protocol.
- */
- def value: SigmaBoolean
-
- /** Estimated cost of the contract execution.*/
- def cost: Long
- }
-
- /** Result of ErgoTree reduction procedure by JIT-based interpreter (see
+ /** Result of ErgoTree reduction procedure by JIT-based interpreter (see `fullReduction`,
* `reduceToCrypto` and friends).
*
* @param value the value of SigmaProp type which represents a logical statement
* verifiable via sigma protocol.
* @param cost the estimated cost of the contract execution (in block's scale).
*/
- case class JitReductionResult(value: SigmaBoolean, cost: Long) extends ReductionResult
-
- /** Result of fullReduction to sigma tree with costing. */
- case class FullReductionResult(
- private[sigmastate] val jitRes: JitReductionResult
- ) extends ReductionResult {
- require(jitRes != null, s"JIT result must be defined: $this")
- override def value: SigmaBoolean = jitRes.value
- override def cost: Long = jitRes.cost
- }
+ case class ReductionResult(value: SigmaBoolean, cost: Long)
/** Represents properties of interpreter invocation. */
type ScriptEnv = Map[String, Any]
@@ -514,7 +498,7 @@ object Interpreter {
/** The result of script reduction when soft-fork condition is detected by the old node,
* in which case the script is reduced to the trivial true proposition and takes up 0 cost.
*/
- def WhenSoftForkJitReductionResult(cost: Long): JitReductionResult = JitReductionResult(TrivialProp.TrueProp, cost)
+ def WhenSoftForkReductionResult(cost: Long): ReductionResult = ReductionResult(TrivialProp.TrueProp, cost)
/** Represents the cost of computing DLogInteractiveProver.computeCommitment. */
final val ComputeCommitments_Schnorr = OperationCostInfo(
diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala
index 00d4bf5cc3..d49cba76f3 100644
--- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala
+++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala
@@ -1,9 +1,7 @@
package sigmastate.interpreter
-import gf2t.{GF2_192, GF2_192_Poly}
-import org.bitbucket.inkytonik.kiama.attribution.UncachedAttribution.attr
-import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule}
-import org.bitbucket.inkytonik.kiama.rewriting.Strategy
+import sigmastate.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule}
+import sigmastate.kiama.rewriting.Strategy
import scalan.util.CollectionUtil._
import sigmastate.TrivialProp.{FalseProp, TrueProp}
import sigmastate.Values._
@@ -12,6 +10,7 @@ import sigmastate._
import sigmastate.basics.DLogProtocol._
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.basics._
+import sigmastate.crypto.{GF2_192, GF2_192_Poly}
import sigmastate.lang.exceptions.InterpreterException
import sigmastate.utils.Helpers
@@ -129,7 +128,7 @@ trait ProverInterpreter extends Interpreter with ProverUtils {
VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) {
val (resValue, resCost) = {
val reduced = fullReduction(ergoTree, context, env)
- val fullCost = addCryptoCost(reduced.jitRes, context.costLimit)
+ val fullCost = addCryptoCost(reduced, context.costLimit)
(reduced.value, fullCost)
}
@@ -470,7 +469,7 @@ trait ProverInterpreter extends Interpreter with ProverUtils {
val newChildren = t.children.foldLeft(Seq[ProofTree](), 1) {
case ((s, count), child) =>
val newChild = child match {
- case r: UnprovenTree if r.real => r.withChallenge(Challenge @@ q.evaluate(count.toByte).toByteArray())
+ case r: UnprovenTree if r.real => r.withChallenge(Challenge @@ q.evaluate(count.toByte).toByteArray)
case p: ProofTree => p
}
(s :+ newChild, count + 1)
@@ -556,7 +555,7 @@ trait ProverInterpreter extends Interpreter with ProverUtils {
case ut: UnprovenTree => ut
case t: ProofTree =>
- log.warn("Wrong input in prove(): ", t);
+ logMessage(s"Wrong input in prove(): $t");
???
})
@@ -578,7 +577,7 @@ trait ProverInterpreter extends Interpreter with ProverUtils {
}
//converts ProofTree => UncheckedSigmaTree
- val convertToUnchecked: ProofTree => UncheckedSigmaTree = attr {
+ def convertToUnchecked(proofTree: ProofTree): UncheckedSigmaTree = proofTree match {
case and: CAndUnproven =>
CAndUncheckedNode(and.challengeOpt.get, and.children.map(convertToUnchecked))
case or: COrUnproven =>
diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaBinder.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaBinder.scala
index 214a4abb01..eac3794eda 100644
--- a/sigmastate/src/main/scala/sigmastate/lang/SigmaBinder.scala
+++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaBinder.scala
@@ -2,7 +2,7 @@ package sigmastate.lang
import java.lang.reflect.InvocationTargetException
-import org.bitbucket.inkytonik.kiama.rewriting.CallbackRewriter
+import sigmastate.kiama.rewriting.CallbackRewriter
import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix
import org.ergoplatform._
import scalan.Nullable
diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala
index b51163fb00..ebe3118fb0 100644
--- a/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala
+++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala
@@ -2,7 +2,7 @@ package sigmastate.lang
import fastparse.Parsed
import fastparse.Parsed.Success
-import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, rewrite, rule}
+import sigmastate.kiama.rewriting.Rewriter.{everywherebu, rewrite, rule}
import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix
import org.ergoplatform.Global
import sigmastate.Values.{SValue, Value}
@@ -82,13 +82,6 @@ class SigmaCompiler(settings: CompilerSettings) {
typecheck(env, parsed)
}
- private[sigmastate] def compileWithoutCosting(env: ScriptEnv, code: String): Value[SType] = {
- val typed = typecheck(env, code)
- val spec = new SigmaSpecializer(builder)
- val ir = spec.specialize(typed)
- ir
- }
-
/** Compiles the given ErgoScript source code. */
def compile(env: ScriptEnv, code: String)(implicit IR: IRContext): CompilerResult[IR.type] = {
val typed = typecheck(env, code)
diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaPrinter.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaPrinter.scala
deleted file mode 100644
index 456878b981..0000000000
--- a/sigmastate/src/main/scala/sigmastate/lang/SigmaPrinter.scala
+++ /dev/null
@@ -1,92 +0,0 @@
-package sigmastate.lang
-
-import sigmastate._
-import sigmastate.Values._
-import sigmastate.lang.Terms._
-import scala.collection.immutable.{Seq => ImmSeq}
-
-/** Sigma pretty printing. */
-class SigmaPrinter extends org.bitbucket.inkytonik.kiama.output.PrettyPrinter {
-
- import org.bitbucket.inkytonik.kiama.output.PrettyPrinterTypes.Document
-
- /** Format a lambda expression. */
- def format(t : SValue) : Document =
- pretty(toDoc(t))
-
- /** The layout from formatting a lambda expression. */
- def formattedLayout(t : SValue) : String =
- format(t).layout
-
- /** Format a type. */
- def format(t : SType) : Document =
- pretty(typeToDoc(t))
-
- /** The layout from formatting a type. */
- def formattedLayout(t : SType) : String =
- format(t).layout
-
- /**
- * Convert an expression node to a pretty-printing document in
- * fully-parenthesised style.
- */
- def toDoc(t : SValue) : Doc =
- t match {
- case LongConstant(d) => value(d)
- case Ident(i,_) => i
- case Lambda(_, args, tLam, Some(e)) =>
- parens('\\' <> parens(lsep(
- ImmSeq(args.map { case (n, targ) => n <+> ": " <+> typedeclToDoc(targ) }:_*),
- comma)) <>
- typedeclToDoc(tLam) <+> '.' <+>
- group(nest(toDoc(e))))
- case Apply(e, args) =>
- parens(toDoc(e) <+> parens(lsep(ImmSeq(args.map(toDoc):_*), comma)))
-
-// case Opn(l, AddOp(), r) => binToDoc(l, "+", r)
-// case Opn(l, SubOp(), r) => binToDoc(l, "-", r)
-
-// case Val(i, t, e1, e2) =>
-// parens("let" <+> i <> typedeclToDoc(t) <+> '=' <>
-// nest(line <> toDoc(e1)) <+> "in" <>
-// nest(line <> toDoc(e2)))
-// case Valp(bs, e) =>
-// parens("letp" <>
-// nest(line <> vsep(bs.map(b => b.i <+> '=' <+> toDoc(b.e)))) <+>
-// "in" <>
-// nest(line <> toDoc(e)))
- }
-
- /**
- * Return a pretty-printing document for an instance of a type declaration.
- */
- def typedeclToDoc(t : SType) : Doc =
- if (t == NoType)
- emptyDoc
- else
- space <> ':' <+> typeToDoc(t)
-
- /**
- * Return a pretty-printing document for an instance of a type.
- */
- def typeToDoc(t : SType) : Doc =
- t match {
- case SLong => "Int"
- case SFunc(dom, t2, _) =>
- parens(lsep(ImmSeq(dom.map(typeToDoc):_*), comma)) <+> "->" <+> typeToDoc(t2)
- case NoType => "NoType" // Not used
- case _ => s""
- }
-
- /**
- * Return a pretty-printing document for an instance of a binary expression.
- */
- def binToDoc(l : SValue, op : String, r : SValue) : Doc =
- parens(toDoc(l) <+> op <+> toDoc(r))
-
-}
-
-/**
- * Lambda calculus pretty printing.
- */
-object SigmaPrinter extends SigmaPrinter
diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaSpecializer.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaSpecializer.scala
deleted file mode 100644
index 22e6ce5a2b..0000000000
--- a/sigmastate/src/main/scala/sigmastate/lang/SigmaSpecializer.scala
+++ /dev/null
@@ -1,169 +0,0 @@
-package sigmastate.lang
-
-import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{reduce, rewrite, strategy}
-import org.ergoplatform._
-import sigmastate.SCollection._
-import sigmastate.Values.Value.Typed
-import sigmastate.Values._
-import sigmastate._
-import sigmastate.lang.SigmaPredef._
-import sigmastate.lang.Terms.{Apply, Block, Ident, Lambda, Select, Val, ValueOps}
-import sigmastate.lang.exceptions.SpecializerException
-import sigmastate.utxo._
-
-class SigmaSpecializer(val builder: SigmaBuilder) {
- import SigmaSpecializer._
- import builder._
-
- private implicit val predefFuncRegistry: PredefinedFuncRegistry = new PredefinedFuncRegistry(builder)
-
- /** Create name -> TaggedXXX(tag) pair to be used in environment. */
- def mkTagged(name: String, tpe: SType, tag: Byte): TaggedVariable[SType] = {
- val tagged = mkTaggedVariable(tag, tpe)
- tagged
- }
-
- /** Rewriting of AST with respect to environment to resolve all references
- * to let bound and lambda bound names. */
- private def eval(env: Map[String, SValue], e: SValue): SValue = rewrite(reduce(strategy[Any]({
- case Ident(n, _) => env.get(n)
-
- case _ @ Block(binds, res) =>
- var curEnv = env
- for (v @ Val(n, _, b) <- binds) {
- if (curEnv.contains(n)) error(s"${v.sourceContext} Variable $n already defined ($n = ${curEnv(n)}")
- val b1 = eval(curEnv, b)
- curEnv = curEnv + (n -> b1)
- }
- val res1 = eval(curEnv, res)
- Some(res1)
-
- case Upcast(Constant(value, _), toTpe: SNumericType) =>
- Some(mkConstant(toTpe.upcast(value.asInstanceOf[AnyVal]), toTpe))
-
- case Downcast(Constant(value, _), toTpe: SNumericType) =>
- Some(mkConstant(toTpe.downcast(value.asInstanceOf[AnyVal]), toTpe))
-
- // Rule: numeric.to* casts
- case Select(obj, method, Some(tRes: SNumericType))
- if obj.tpe.isNumType && obj.asNumValue.tpe.isCastMethod(method) =>
- val numValue = obj.asNumValue
- if (numValue.tpe == tRes)
- Some(numValue)
- else if ((numValue.tpe max tRes) == numValue.tpe)
- Some(mkDowncast(numValue, tRes))
- else
- Some(mkUpcast(numValue, tRes))
-
- // Rule: col.size --> SizeOf(col)
- case Select(obj, SizeMethod.name, _) =>
- if (obj.tpe.isCollectionLike)
- Some(mkSizeOf(obj.asValue[SCollection[SType]]))
- else
- error(s"The type of $obj is expected to be Collection to select 'size' property")
-
- // Rule: proof.isProven --> IsValid(proof)
- case Select(p, SSigmaProp.IsProven, _) if p.tpe == SSigmaProp =>
- Some(SigmaPropIsProven(p.asSigmaProp))
-
- // Rule: proof.propBytes --> ProofBytes(proof)
- case Select(p, SSigmaProp.PropBytes, _) if p.tpe == SSigmaProp =>
- Some(SigmaPropBytes(p.asSigmaProp))
-
- case sel @ Select(Typed(box, SBox), regName, Some(SOption(valType))) if regName.startsWith("R") =>
- val reg = ErgoBox.registerByName.getOrElse(regName,
- error(s"Invalid register name $regName in expression $sel"))
- Some(mkExtractRegisterAs(box.asBox, reg, SOption(valType)).asValue[SOption[valType.type]])
-
- case Select(nrv: NotReadyValue[SOption[SType]]@unchecked, SOption.Get, _) =>
- Some(mkOptionGet(nrv))
-
- case Apply(Select(nrv: NotReadyValue[SOption[SType]]@unchecked, SOption.GetOrElse, _), Seq(arg)) =>
- Some(mkOptionGetOrElse(nrv, arg))
-
- case Select(nrv: NotReadyValue[SOption[SType]]@unchecked, SOption.IsDefined, _) =>
- Some(mkOptionIsDefined(nrv))
-
- case sel @ Select(obj, field, _) if obj.tpe == SBox =>
- (obj.asValue[SBox.type], field) match {
- case (box, SBox.Value) => Some(mkExtractAmount(box))
- case (box, SBox.PropositionBytes) => Some(mkExtractScriptBytes(box))
- case (box, SBox.Id) => Some(mkExtractId(box))
- case (box, SBox.Bytes) => Some(mkExtractBytes(box))
- case (box, SBox.BytesWithoutRef) => Some(mkExtractBytesWithNoRef(box))
- case (box, SBox.CreationInfo) => Some(mkExtractCreationInfo(box))
- case (box, _) if box.tpe.hasMethod(field) =>
- None // leave it as it is and handle on a level of parent node
- case _ => error(s"Invalid access to Box property in $sel: field $field is not found")
- }
-
-// case node @ Select(obj: SigmaBoolean, field, _) =>
-// field match {
-// case SigmaBoolean.PropBytes => Some(ByteArrayConstant(obj.bytes))
-// case _ => None
-// }
-
- case Select(tuple, fn, _) if tuple.tpe.isTuple && fn.startsWith("_") =>
- val index = fn.substring(1).toByte
- Some(mkSelectField(tuple.asTuple, index))
-
- case Apply(Select(col, SliceMethod.name, _), Seq(from, until)) =>
- Some(mkSlice(col.asValue[SCollection[SType]], from.asIntValue, until.asIntValue))
-
- case Apply(Select(col, FilterMethod.name, _), Seq(l @ Lambda(_, _, _, _))) =>
- Some(mkFilter(col.asValue[SCollection[SType]], l))
-
- case Apply(Select(col, ExistsMethod.name, _), Seq(l @ Lambda(_, _, _, _))) =>
- Some(mkExists(col.asValue[SCollection[SType]], l))
-
- case Apply(Select(col, ForallMethod.name, _), Seq(l @ Lambda(_, _, _, _))) =>
- Some(mkForAll(col.asValue[SCollection[SType]], l))
-
- case Apply(Select(col, MapMethod.name, _), Seq(l @ Lambda(_, _, _, _))) =>
- Some(mkMapCollection(col.asValue[SCollection[SType]], l))
-
- case Apply(Select(col, FoldMethod.name, _), Seq(zero, l @ Lambda(_, _, _, _))) =>
- Some(mkFold(col.asValue[SCollection[SType]], zero, l))
-
- case Apply(col, Seq(index)) if col.tpe.isCollection =>
- Some(ByIndex(col.asCollection[SType], index.asValue[SInt.type]))
-
- case opt: OptionValue[_] =>
- error(s"Option constructors are not supported: $opt")
-
- case AND(ConcreteCollection(items, SBoolean)) if items.exists(_.isInstanceOf[AND]) =>
- Some(mkAND(
- mkConcreteCollection(
- items.flatMap {
- case AND(ConcreteCollection(innerItems, SBoolean)) => innerItems
- case v => IndexedSeq(v)
- }, SBoolean)))
-
- case OR(ConcreteCollection(items, SBoolean)) if items.exists(_.isInstanceOf[OR]) =>
- Some(mkOR(
- mkConcreteCollection(
- items.flatMap {
- case OR(ConcreteCollection(innerItems, SBoolean)) => innerItems
- case v => IndexedSeq(v)
- }, SBoolean)))
-
- case PredefinedFuncApply(irNode) =>
- Some(irNode)
-
- })))(e)
-
- def specialize(typed: SValue): SValue = {
- specialize(Map(), typed)
- }
-
- def specialize(env: Map[String, SValue], typed: SValue): SValue = {
- val res = eval(env, typed)
- res
- }
-}
-
-object SigmaSpecializer {
-
- def error(msg: String) = throw new SpecializerException(msg, None)
- def error(msg: String, srcCtx: SourceContext) = throw new SpecializerException(msg, Some(srcCtx))
-}
diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala
index 60ac7c04f0..06928adb28 100644
--- a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala
+++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala
@@ -1,19 +1,19 @@
package sigmastate.lang
-import org.bitbucket.inkytonik.kiama.rewriting.Rewriter._
+import sigmastate.kiama.rewriting.Rewriter._
import org.ergoplatform._
import sigmastate.SCollection._
import sigmastate.Values._
import sigmastate._
import SCollection.SBooleanArray
import scalan.Nullable
+import scalan.util.Extensions.Ensuring
import sigmastate.lang.Terms._
import sigmastate.lang.exceptions._
import sigmastate.lang.SigmaPredef._
import sigmastate.serialization.OpCodes
import sigmastate.utxo._
-import scala.collection.compat.immutable.ArraySeq
import scala.collection.mutable.ArrayBuffer
/**
@@ -521,7 +521,9 @@ class SigmaTyper(val builder: SigmaBuilder,
case v @ Select(_, _, Some(_)) => v
case v =>
error(s"Don't know how to assignType($v)", v.sourceContext)
- }).withEnsuredSrcCtx(bound.sourceContext)
+ }).ensuring(v => v.tpe != NoType,
+ v => s"Errors found while assigning types to expression $bound: $v assigned NoType")
+ .withEnsuredSrcCtx(bound.sourceContext)
def assignConcreteCollection(cc: ConcreteCollection[SType], newItems: Seq[Value[SType]]) = {
val types = newItems.map(_.tpe).distinct
@@ -609,17 +611,6 @@ class SigmaTyper(val builder: SigmaBuilder,
if (assigned.tpe == NoType)
error(s"No type can be assigned to expression $assigned", bound.sourceContext)
- // traverse the tree bottom-up checking that all the nodes have a type
- var untyped: SValue = null
- rewrite(everywherebu(rule[Any]{
- case v: SValue =>
- if (v.tpe == NoType) untyped = v
- v
- }))(assigned)
-
- if (untyped != null)
- error(s"Errors found in $bound while assigning types to expression: $untyped assigned NoType", untyped.sourceContext)
-
assigned
}
}
diff --git a/sigmastate/src/main/scala/sigmastate/lang/Terms.scala b/sigmastate/src/main/scala/sigmastate/lang/Terms.scala
index 75cd14d251..9b90d62577 100644
--- a/sigmastate/src/main/scala/sigmastate/lang/Terms.scala
+++ b/sigmastate/src/main/scala/sigmastate/lang/Terms.scala
@@ -1,6 +1,6 @@
package sigmastate.lang
-import org.bitbucket.inkytonik.kiama.rewriting.Rewriter._
+import sigmastate.kiama.rewriting.Rewriter._
import scalan.Nullable
import sigmastate.SCollection.{SIntArray, SByteArray}
import sigmastate.Values._
diff --git a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala
index d004d42566..b8523cb430 100644
--- a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala
+++ b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala
@@ -1,5 +1,6 @@
package sigmastate.serialization
+import sigmastate.crypto.CryptoFacade
import sigmastate.interpreter.CryptoConstants
import sigmastate.interpreter.CryptoConstants.EcPointType
import sigmastate.util.safeNewArray
@@ -21,12 +22,12 @@ object GroupElementSerializer extends SigmaSerializer[EcPointType, EcPointType]
private lazy val identityPointEncoding = Array.fill(encodingSize)(0: Byte)
override def serialize(point: EcPointType, w: SigmaByteWriter): Unit = {
- val bytes = if (point.isInfinity) {
+ val bytes = if (CryptoFacade.isInfinityPoint(point)) {
identityPointEncoding
} else {
- val normed = point.normalize()
- val ySign = normed.getAffineYCoord.testBitZero()
- val X = normed.getXCoord.getEncoded
+ val normed = CryptoFacade.normalizePoint(point)
+ val ySign = CryptoFacade.signOf(CryptoFacade.getAffineYCoord(normed))
+ val X = CryptoFacade.encodeFieldElem(CryptoFacade.getXCoord(normed))
val PO = safeNewArray[Byte](X.length + 1)
PO(0) = (if (ySign) 0x03 else 0x02).toByte
System.arraycopy(X, 0, PO, 1, X.length)
@@ -38,7 +39,7 @@ object GroupElementSerializer extends SigmaSerializer[EcPointType, EcPointType]
override def parse(r: SigmaByteReader): EcPointType = {
val encoded = r.getBytes(encodingSize)
if (encoded(0) != 0) {
- curve.curve.decodePoint(encoded).asInstanceOf[EcPointType]
+ curve.ctx.decodePoint(encoded)
} else {
curve.identity
}
diff --git a/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala b/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala
index 8d8d8d9927..24ee381108 100644
--- a/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala
+++ b/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala
@@ -1,6 +1,6 @@
package sigmastate.utils
-import com.google.common.primitives.{Ints, Longs, Shorts}
+import scorex.utils.{Ints, Longs, Shorts}
import sigmastate.eval.SigmaDsl
import special.collection.Coll
diff --git a/sigmastate/src/test/java/gf2t/GF2_192Test.java b/sigmastate/src/test/java/gf2t/GF2_192Test.java
deleted file mode 100644
index 46a4110b82..0000000000
--- a/sigmastate/src/test/java/gf2t/GF2_192Test.java
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- By Leonid Reyzin
-
- This is free and unencumbered software released into the public domain.
-
- Anyone is free to copy, modify, publish, use, compile, sell, or
- distribute this software, either in source code form or as a compiled
- binary, for any purpose, commercial or non-commercial, and by any
- means.
-
- In jurisdictions that recognize copyright laws, the author or authors
- of this software dedicate any and all copyright interest in the
- software to the public domain. We make this dedication for the benefit
- of the public at large and to the detriment of our heirs and
- successors. We intend this dedication to be an overt act of
- relinquishment in perpetuity of all present and future rights to this
- software under copyright law.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
- For more information, please refer to
- */
-package gf2t;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Random;
-import java.util.Arrays;
-
-import static org.junit.Assert.assertFalse;
-
-@RunWith(ReadableTest.class)
-public class GF2_192Test {
-
- private static class GF2t_slow {
-
- private long[] x;
-
- public boolean isOne() {
- if (x[0] != 1l) return false;
- for (int i = 1; i < x.length; i++) {
- if (x[i] != 0l) return false;
- }
- return true;
- }
-
- public boolean equals(long[] that) {
- int i;
- for (i = 0; i < Math.min(x.length, that.length); i++) {
- if (x[i] != that[i])
- return false;
- }
- for (; i < x.length; i++) {
- if (x[i] != 0) {
- return false;
- }
- }
- for (; i < that.length; i++) {
- if (that[i] != 0) {
- return false;
- }
- }
- return true;
- }
-
-
- public static void mulBits(GF2t_slow ret, long[] a, long[] b) {
- long[] c = new long[a.length + b.length];
-
-
- for (int i = 0; i < a.length; i++) {
- for (int i1 = 0; i1 < 64; i1++) {
- for (int j = 0; j < b.length; j++) {
- for (int j1 = 0; j1 < 64; j1++) {
- if ((a[i] & (1l << i1)) != 0 && (b[j] & (1l << j1)) != 0) {
- int cPosition = i * 64 + i1 + j * 64 + j1;
- c[cPosition / 64] ^= 1l << (cPosition % 64);
- }
- }
- }
- }
- }
- ret.x = c;
- }
-
- private static void modReduce(GF2t_slow poly, Modulus mod) {
- for (int i = poly.x.length * 64 - 1; i >= mod.degree; i--) {
- if ((poly.x[i >> 6] & (1l << (i & 63))) != 0) {
- for (int j = 0; j < mod.offset.length; j++) {
- int k = i - mod.offset[j];
- poly.x[k >> 6] ^= (1l << (k & 63));
- }
- }
- }
- }
-
- public String toString() {
- String ret = "";
- for (int i = x.length - 1; i >= 0; i--) {
- ret += x[i];
- }
- return ret;
- }
-
- public static class Modulus {
- // represented as an array of bit positions
- // where coefficient = 1, counting from degree down
- private final int[] offset;
- private final int degree;
-
- Modulus(int[] sparseModulus) {
- degree = sparseModulus[0];
- offset = new int[sparseModulus.length];
- offset[0] = 0;
- for (int i = 1; i < sparseModulus.length; i++) {
- offset[i] = degree - sparseModulus[i];
- }
- }
- }
- }
-
- private static long[][] testValues = null;
- private static GF2_192 zero = new GF2_192(0);
- private static GF2_192 one = new GF2_192(1);
- private static int[] pentanomial = {192, 7, 2, 1, 0};
- private static GF2t_slow.Modulus m = new GF2t_slow.Modulus(pentanomial);
- static {genTestValues();}
- private static void genTestValues() {
- if (testValues == null) {
- testValues = new long[250][];
-
- for (int i = 0; i < testValues.length; i++) {
- testValues[i] = new long[3];
- }
-
-
- // Test single 1s in every bit position but last
- // (1s in last bit position -- i.e., just the value of 1 -- will be tested separately)
- int j = 0;
- for (int i = 1; i < 64; i++, j++) {
- testValues[j][0] = 1L << i;
- testValues[j][1] = 0;
- testValues[j][2] = 0;
- }
- for (int i = 0; i < 64; i++, j++) {
- testValues[j][0] = 0;
- testValues[j][1] = 1L << i;
- testValues[j][2] = 0;
- }
- for (int i = 0; i < 64; i++, j++) {
- testValues[j][0] = 0;
- testValues[j][1] = 0;
- testValues[j][2] = 1L << i;
- }
-
- // Test first word zero, last two words random,
- // and first word random, last two words 0
- // and first word random, second word 1, last word 0
- // and last word random, first two words 0
-
- Random rand = new Random();
-
- for (int i = 0; i < 5; i++, j++) {
- testValues[j][0] = 0;
- testValues[j][1] = rand.nextLong();
- testValues[j][2] = rand.nextLong();
- }
-
- for (int i = 0; i < 5; i++, j++) {
- testValues[j][0] = rand.nextLong();
- testValues[j][1] = 0;
- testValues[j][2] = 0;
- }
-
-
- for (int i = 0; i < 5; i++, j++) {
- testValues[j][0] = rand.nextLong();
- testValues[j][1] = 1;
- testValues[j][2] = 0;
- }
-
- for (int i = 0; i < 5; i++, j++) {
- testValues[j][0] = 0;
- testValues[j][1] = 1;
- testValues[j][2] = rand.nextLong();
- }
-
- // Test all three words random
- while (j < testValues.length) {
- testValues[j][0] = rand.nextLong();
- testValues[j][1] = rand.nextLong();
- testValues[j++][2] = rand.nextLong();
- }
- }
- }
-
- @Test
- public void constructorAndEqualityTest() {
- GF2_192 t = new GF2_192();
- long[] r = t.toLongArray();
- assertFalse("Fail: empty constructor.", !t.isZero() || r.length != 3 || r[0] != 0L || r[1] != 0L || r[2] != 0L);
-
- t = new GF2_192(0);
- r = t.toLongArray();
- assertFalse("Fail: constructor on 0 int",!t.isZero() || r.length != 3 || r[0] != 0L || r[1] != 0L || r[2] != 0L);
-
- t = new GF2_192(1);
- r = t.toLongArray();
- assertFalse("Fail: constructor on 1 int", !t.isOne() || r.length != 3 || r[0] != 1L || r[1] != 0L || r[2] != 0L);
-
- t = new GF2_192(-1);
- r = t.toLongArray();
- assertFalse("Fail: constructor on 0xFFFFFFFF int " + t, r[0] != 0xFFFFFFFFL || r[1] != 0L || r[2]!=0L);
-
- long[] s = new long[3];
-
- s[0] = 123345L;
- s[1] = 123567891234567L;
- s[2] = 487237823242367L;
-
- t = new GF2_192(s);
-
- GF2_192 t1 = new GF2_192(t);
-
- r = t.toLongArray();
- assertFalse("Fail: constructor on long array", r[0] != s[0] || r[1] != s[1] || r[2] != s[2]);
-
-
- r = t1.toLongArray();
- assertFalse ("Fail: copy constructor",r[0] != s[0] || r[1] != s[1] || r[2] != s[2]) ;
-
- byte[] b = new byte[24];
- for (int i = 0; i < 8; i++) {
- b[i] = (byte) (r[0] >>> (i * 8));
- }
-
- for (int i = 0; i < 8; i++) {
- b[i + 8] = (byte) (r[1] >>> (i * 8));
- }
-
- for (int i = 0; i < 8; i++) {
- b[i + 16] = (byte) (r[2] >>> (i * 8));
- }
- t = new GF2_192(b);
- s = t.toLongArray();
-
- assertFalse("Fail: constructor on byte array",r[0] != s[0] || r[1] != s[1] || r[2] != s[2]);
- byte [] c = t.toByteArray();
- assertFalse("Fail: toByteArray", !Arrays.equals(b, c));
-
- byte [] b2 = new byte[30];
- for (int i=0; i<24; i++) {
- b2[i+6]=b[i];
- }
- t = new GF2_192(b2, 6);
- s = t.toLongArray();
- assertFalse("Fail: constructor on byte array with offset", r[0] != s[0] || r[1] != s[1] || r[2]!=s[2]);
-
- byte [] b1 = t.toByteArray();
- assertFalse("Fail: toByteArray", !Arrays.equals(b, b1));
-
-
- byte [] b3 = new byte [40];
- t.toByteArray(b3, 10);
- for (int i = 0; i>> (i * 8));
- }
-
- for (int i = 0; i < 8; i++) {
- b[i + 8] = (byte) (r[1] >>> (i * 8));
- }
- for (int i = 0; i < 8; i++) {
- b[i + 16] = (byte) (r[2] >>> (i * 8));
- }
-
-
- t = new GF2_192(b);
- s = t.toLongArray();
- assertFalse("Fail: constructor on byte array of all 1s", r[0] != s[0] || r[1] != s[1] || r[2]!=s[2]);
-
- b1 = t.toByteArray();
- assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1));
-
- b2 = new byte[30];
- for (int i=0; i<24; i++) {
- b2[i+6]=b[i];
- }
- t = new GF2_192(b2, 6);
- s = t.toLongArray();
- assertFalse("Fail: constructor on byte array with offset of all 1s", r[0] != s[0] || r[1] != s[1] || r[2]!=s[2]);
-
- b1 = t.toByteArray();
- assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1));
-
- b3 = new byte [40];
- t.toByteArray(b3, 10);
- for (int i = 0; i klass) throws InitializationError {
- super(klass);
- }
-
- public static LinkedList splitCamelCaseString(String s) {
- LinkedList result = new LinkedList();
- for (String w : s.split("(?
ProveDlog(
- CryptoConstants.dlogGroup.curve.decodePoint(point).asInstanceOf[CryptoConstants.EcPointType]
+ CryptoConstants.dlogGroup.ctx.decodePoint(point).asInstanceOf[CryptoConstants.EcPointType]
)
}.get
val regs = Map(
diff --git a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala
index 183dc971a5..3b46ba4371 100644
--- a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala
+++ b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala
@@ -1,13 +1,14 @@
package sigmastate
-import org.scalatest.{PropSpecLike, Tag}
+import org.scalatest.Tag
import org.scalactic.source.Position
import sigmastate.eval.Profiler
import debox.cfor
+import org.scalatest.propspec.AnyPropSpecLike
import scala.util.DynamicVariable
-trait CrossVersionProps extends PropSpecLike with TestsBase {
+trait CrossVersionProps extends AnyPropSpecLike with TestsBase {
/** Number of times each test property is warmed up (i.e. executed before final execution). */
def perTestWarmUpIters: Int = 0
diff --git a/sigmastate/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sigmastate/src/test/scala/sigmastate/ErgoTreeSpecification.scala
index f3b45766c5..38e89b1212 100644
--- a/sigmastate/src/test/scala/sigmastate/ErgoTreeSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/ErgoTreeSpecification.scala
@@ -1,8 +1,8 @@
package sigmastate
import org.ergoplatform.settings.ErgoAlgos
-import org.ergoplatform.validation.{ValidationRules, ValidationException}
-import org.ergoplatform.{ErgoAddressEncoder, ErgoBox, Self, ErgoLikeContext}
+import org.ergoplatform.validation.{ValidationException, ValidationRules}
+import org.ergoplatform.{ErgoAddressEncoder, ErgoBox, ErgoLikeContext, Self}
import scalan.RType.asType
import scalan.{Nullable, RType}
import sigmastate.SCollection.{SByteArray, checkValidFlatmap}
@@ -11,10 +11,10 @@ import sigmastate.VersionContext._
import sigmastate.eval.{CostingBox, Evaluation, Profiler}
import sigmastate.helpers.{ErgoLikeContextTesting, SigmaPPrint}
import sigmastate.interpreter.ErgoTreeEvaluator
-import sigmastate.interpreter.Interpreter.JitReductionResult
+import sigmastate.interpreter.Interpreter.ReductionResult
import sigmastate.lang.SourceContext
import sigmastate.lang.Terms._
-import sigmastate.lang.exceptions.{InterpreterException, CostLimitException}
+import sigmastate.lang.exceptions.{CostLimitException, InterpreterException}
import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer
import sigmastate.utils.Helpers.TryOps
import sigmastate.utxo._
@@ -685,7 +685,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit {
VersionContext.withVersions(activatedVersion = 1, tree.version) {
// v4.x behavior
val res = ErgoTreeEvaluator.evalToCrypto(createCtx, tree, evalSettings)
- res shouldBe JitReductionResult(TrivialProp(true), 3)
+ res shouldBe ReductionResult(TrivialProp(true), 3)
}
VersionContext.withVersions(activatedVersion = 2, tree.version) {
diff --git a/sigmastate/src/test/scala/sigmastate/SigmaProtocolSpecification.scala b/sigmastate/src/test/scala/sigmastate/SigmaProtocolSpecification.scala
index b5381c2780..96931f5e84 100644
--- a/sigmastate/src/test/scala/sigmastate/SigmaProtocolSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/SigmaProtocolSpecification.scala
@@ -1,7 +1,7 @@
package sigmastate
-import gf2t.{GF2_192_Poly, GF2_192}
import sigmastate.basics.VerifierMessage.Challenge
+import sigmastate.crypto.{GF2_192, GF2_192_Poly}
import special.sigma.SigmaTestingData
class SigmaProtocolSpecification extends SigmaTestingData {
diff --git a/sigmastate/src/test/scala/sigmastate/TestsBase.scala b/sigmastate/src/test/scala/sigmastate/TestsBase.scala
index e2e952855b..8e7425cd1f 100644
--- a/sigmastate/src/test/scala/sigmastate/TestsBase.scala
+++ b/sigmastate/src/test/scala/sigmastate/TestsBase.scala
@@ -2,7 +2,7 @@ package sigmastate
import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix
import org.ergoplatform.ErgoScriptPredef
-import org.scalatest.Matchers
+import org.scalatest.matchers.should.Matchers
import sigmastate.Values.{ErgoTree, SValue, SigmaBoolean, SigmaPropValue, Value}
import sigmastate.eval.IRContext
import sigmastate.helpers.SigmaPPrint
@@ -65,9 +65,6 @@ trait TestsBase extends Matchers with VersionTesting {
}
}
- def compileWithoutCosting(env: ScriptEnv, code: String): Value[SType] =
- compiler.compileWithoutCosting(env, code)
-
/** Compile the given code to ErgoTree expression. */
def compile(env: ScriptEnv, code: String)(implicit IR: IRContext): Value[SType] = {
val res = compiler.compile(env, code)
diff --git a/sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala b/sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala
new file mode 100644
index 0000000000..b415fc99bd
--- /dev/null
+++ b/sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala
@@ -0,0 +1,693 @@
+package sigmastate.crypto
+
+import org.junit.Assert.assertFalse
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
+
+import java.util
+import java.util.{Arrays, Random}
+
+class GF2_192_Specification extends AnyPropSpec
+ with ScalaCheckDrivenPropertyChecks
+ with Matchers {
+
+ private object GF2t_slow {
+ def mulBits(ret: GF2t_slow, a: Array[Long], b: Array[Long]): Unit = {
+ val c = new Array[Long](a.length + b.length)
+
+ for ( i <- 0 until a.length ) {
+ for ( i1 <- 0 until 64 ) {
+ for ( j <- 0 until b.length ) {
+ for ( j1 <- 0 until 64 ) {
+ if ((a(i) & (1l << i1)) != 0 && (b(j) & (1l << j1)) != 0) {
+ val cPosition = i * 64 + i1 + j * 64 + j1
+ c(cPosition / 64) ^= 1l << (cPosition % 64)
+ }
+ }
+ }
+ }
+ }
+ ret.x = c
+ }
+
+ def modReduce(poly: GF2t_slow, mod: GF2t_slow.Modulus): Unit = {
+ for (i <- poly.x.length * 64 - 1 to mod.degree by -1) {
+ if ((poly.x(i >> 6) & (1l << (i & 63))) != 0) {
+ for ( j <- 0 until mod.offset.length ) {
+ val k = i - mod.offset(j)
+ poly.x(k >> 6) ^= (1l << (k & 63))
+ }
+ }
+ }
+ }
+
+ class Modulus private[crypto](val sparseModulus: Array[Int]) {
+ // represented as an array of bit positions
+ // where coefficient = 1, counting from degree down
+ final private[crypto] var offset: Array[Int] = new Array[Int](sparseModulus.length)
+ final private[crypto] var degree: Int = sparseModulus(0)
+
+ offset(0) = 0
+ for ( i <- 1 until sparseModulus.length ) {
+ offset(i) = degree - sparseModulus(i)
+ }
+ }
+ }
+
+ private class GF2t_slow {
+ var x: Array[Long] = null
+
+ def isOne: Boolean = {
+ if (x(0) != 1l) return false
+ for ( i <- 1 until x.length ) {
+ if (x(i) != 0l) return false
+ }
+ true
+ }
+
+ def equals(that: Array[Long]): Boolean = {
+ var i = 0
+ while ( i < Math.min(x.length, that.length) ) {
+ if (x(i) != that(i)) return false
+ i += 1
+ }
+ while ( i < x.length ) {
+ if (x(i) != 0) return false
+ i += 1
+ }
+ while ( i < that.length ) {
+ if (that(i) != 0) return false
+ i += 1
+ }
+ true
+ }
+
+ override def toString: String = {
+ var ret = ""
+ for ( i <- x.length - 1 to 0 by -1 ) {
+ ret += x(i)
+ }
+ ret
+ }
+ }
+
+ private var testValues: Array[Array[Long]] = null
+ private val zero = new GF2_192(0)
+ private val one = new GF2_192(1)
+ private val pentanomial = Array(192, 7, 2, 1, 0)
+ private val m = new GF2t_slow.Modulus(pentanomial)
+ genTestValues()
+
+ private def genTestValues(): Unit = {
+ if (testValues == null) {
+ testValues = new Array[Array[Long]](250)
+ for ( i <- 0 until testValues.length ) {
+ testValues(i) = new Array[Long](3)
+ }
+
+ // Test single 1s in every bit position but last
+ // (1s in last bit position -- i.e., just the value of 1 -- will be tested separately)
+
+ var j = 0
+ var i = 1
+ while ( i < 64 ) {
+ testValues(j)(0) = 1L << i
+ testValues(j)(1) = 0
+ testValues(j)(2) = 0
+ i += 1
+ j += 1
+ }
+ i = 0
+ while ( i < 64 ) {
+ testValues(j)(0) = 0
+ testValues(j)(1) = 1L << i
+ testValues(j)(2) = 0
+ i += 1
+ j += 1
+ }
+ i = 0
+ while ( i < 64 ) {
+ testValues(j)(0) = 0
+ testValues(j)(1) = 0
+ testValues(j)(2) = 1L << i
+ i += 1
+ j += 1
+ }
+
+ // Test first word zero, last two words random,
+ // and first word random, last two words 0
+ // and first word random, second word 1, last word 0
+ // and last word random, first two words 0
+ val rand = new Random
+
+ i = 0
+ while ( i < 5 ) {
+ testValues(j)(0) = 0
+ testValues(j)(1) = rand.nextLong
+ testValues(j)(2) = rand.nextLong
+ i += 1
+ j += 1
+ }
+ i = 0
+ while ( i < 5 ) {
+ testValues(j)(0) = rand.nextLong
+ testValues(j)(1) = 0
+ testValues(j)(2) = 0
+ i += 1
+ j += 1
+ }
+ i = 0
+ while ( i < 5 ) {
+ testValues(j)(0) = rand.nextLong
+ testValues(j)(1) = 1
+ testValues(j)(2) = 0
+ i += 1
+ j += 1
+ }
+
+ i = 0
+ while ( i < 5 ) {
+ testValues(j)(0) = 0
+ testValues(j)(1) = 1
+ testValues(j)(2) = rand.nextLong
+ i += 1
+ j += 1
+ }
+ // Test all three words random
+ while ( j < testValues.length ) {
+ testValues(j)(0) = rand.nextLong
+ testValues(j)(1) = rand.nextLong
+ testValues(j)(2) = rand.nextLong
+ j += 1
+ }
+ }
+ }
+
+ property("constructorAndEqualityTest") {
+ var t = new GF2_192
+ var r = t.toLongArray
+ assertFalse("Fail: empty constructor.", !t.isZero || r.length != 3 || r(0) != 0L || r(1) != 0L || r(2) != 0L)
+
+ t = new GF2_192(0)
+ r = t.toLongArray
+ assertFalse("Fail: constructor on 0 int", !t.isZero || r.length != 3 || r(0) != 0L || r(1) != 0L || r(2) != 0L)
+
+ t = new GF2_192(1)
+ r = t.toLongArray
+ assertFalse("Fail: constructor on 1 int", !t.isOne || r.length != 3 || r(0) != 1L || r(1) != 0L || r(2) != 0L)
+
+ t = new GF2_192(-1)
+ r = t.toLongArray
+ assertFalse("Fail: constructor on 0xFFFFFFFF int " + t, r(0) != 0xFFFFFFFFL || r(1) != 0L || r(2) != 0L)
+
+ var s = new Array[Long](3)
+
+ s(0) = 123345L
+ s(1) = 123567891234567L
+ s(2) = 487237823242367L
+
+ t = new GF2_192(s)
+ var t1 = new GF2_192(t)
+
+ r = t.toLongArray
+ assertFalse("Fail: constructor on long array", r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ r = t1.toLongArray
+ assertFalse("Fail: copy constructor", r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ val b = new Array[Byte](24)
+ for ( i <- 0 until 8 ) {
+ b(i) = (r(0) >>> (i * 8)).toByte
+ }
+ for ( i <- 0 until 8 ) {
+ b(i + 8) = (r(1) >>> (i * 8)).toByte
+ }
+ for ( i <- 0 until 8 ) {
+ b(i + 16) = (r(2) >>> (i * 8)).toByte
+ }
+
+ t = new GF2_192(b)
+ s = t.toLongArray
+ assertFalse("Fail: constructor on byte array",
+ r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ val c = t.toByteArray
+ assertFalse("Fail: toByteArray", !Arrays.equals(b, c))
+
+ var b2 = new Array[Byte](30)
+ for ( i <- 0 until 24 ) {
+ b2(i + 6) = b(i)
+ }
+
+ t = new GF2_192(b2, 6)
+ s = t.toLongArray
+ assertFalse("Fail: constructor on byte array with offset",
+ r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ var b1 = t.toByteArray
+ assertFalse("Fail: toByteArray", !Arrays.equals(b, b1))
+
+ var b3 = new Array[Byte](40)
+ t.toByteArray(b3, 10)
+ for ( i <- 0 until b.length ) {
+ assertFalse("Fail: toByteArray with offset",
+ b3(i + 10) != b(i))
+ }
+
+ s(0) = 0xFFFFFFFFFFFFFFFFL
+ s(1) = 0xFFFFFFFFFFFFFFFFL
+ s(2) = 0xFFFFFFFFFFFFFFFFL
+ t = new GF2_192(s)
+ t1 = new GF2_192(t)
+
+ r = t.toLongArray
+ assertFalse("Fail: constructor on long array of all 1s",
+ r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ r = t1.toLongArray
+ assertFalse("Fail: copy constructor",
+ r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ for ( i <- 0 until 8 ) {
+ b(i) = (r(0) >>> (i * 8)).toByte
+ }
+
+ for ( i <- 0 until 8 ) {
+ b(i + 8) = (r(1) >>> (i * 8)).toByte
+ }
+
+ for ( i <- 0 until 8 ) {
+ b(i + 16) = (r(2) >>> (i * 8)).toByte
+ }
+
+ t = new GF2_192(b)
+ s = t.toLongArray
+ assertFalse("Fail: constructor on byte array of all 1s",
+ r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ b1 = t.toByteArray
+ assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1))
+
+ b2 = new Array[Byte](30)
+ for ( i <- 0 until 24 ) {
+ b2(i + 6) = b(i)
+ }
+ t = new GF2_192(b2, 6)
+ s = t.toLongArray
+ assertFalse("Fail: constructor on byte array with offset of all 1s",
+ r(0) != s(0) || r(1) != s(1) || r(2) != s(2))
+
+ b1 = t.toByteArray
+ assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1))
+
+ b3 = new Array[Byte](40)
+ t.toByteArray(b3, 10)
+ for ( i <- 0 until b.length ) {
+ assertFalse("Fail: toByteArray all 1s with offset", b3(i + 10) != b(i))
+ }
+ }
+
+ property("pow2To2ToKTest") {
+ // includes squaring test
+ val res = new GF2_192
+ var z: GF2_192 = null
+ val maxK = 15
+ for ( k <- 0 until maxK ) {
+ GF2_192.power2To2ToK(res, zero, k)
+ assertFalse("Fail: power2To2ToK of 0 for k=" + k, !res.isZero)
+
+ z = new GF2_192(zero)
+ GF2_192.power2To2ToK(z, z, k)
+ assertFalse("Fail: power2To2ToK of 0 in place for k=" + k, !z.isZero)
+
+ GF2_192.power2To2ToK(res, one, k)
+ assertFalse("Fail: power2To2ToK of 1 for k=" + k, !res.isOne)
+
+ z = new GF2_192(one)
+ GF2_192.power2To2ToK(z, z, k)
+ assertFalse("Fail: power2To2ToK of 1 in place for k=" + k, !z.isOne)
+ }
+
+ GF2_192.sqr(res, zero)
+ assertFalse("Fail: sqr of 0", !res.isZero)
+
+ z = new GF2_192(zero)
+ GF2_192.sqr(z, z)
+ assertFalse("Fail: sqr of 0 in place", !z.isZero)
+
+ GF2_192.sqr(res, one)
+ assertFalse("Fail: sqr of 1", !res.isOne)
+
+ z = new GF2_192(one)
+ GF2_192.sqr(z, z)
+ assertFalse("Fail: sqr of 1 in place", !z.isOne)
+
+ val res1 = new GF2_192
+ val res2 = new GF2_192
+ for ( p <- testValues ) {
+ for ( k <- 0 until maxK ) {
+ z = new GF2_192(p)
+ GF2_192.power2To2ToK(res, z, k)
+ if (k == 0) {
+ // Ground truth for squaring: self-multiply
+ GF2_192.mul(res1, z, z) // sqr should equal power2To2ToK with k = 0
+ assertFalse("Fail: power2To2To1 " + z, !(res == res1))
+ GF2_192.sqr(res2, z) // sqr should equal self-multiply with k = 0
+ assertFalse("Fail: sqr for k = " + k + " value = " + z, !(res == res2))
+ }
+ else {
+ // res1 is the ground truth, computed using smaller values of k than is currently being tested
+ GF2_192.power2To2ToK(res1, res1, k - 1)
+ assertFalse("Fail: power2To2ToK for k = " + k + " value = " + z, !(res == res1))
+ }
+
+ // Input location = output location tests
+ GF2_192.power2To2ToK(z, z, k) // power2To2ToK into same location
+ assertFalse("Fail: power2To2ToK in place for k = " + k + " value = " + new GF2_192(p), !(res == z))
+ if (k == 0) {
+ z = new GF2_192(p)
+ GF2_192.sqr(z, z) // sqr into same location
+ assertFalse("Fail: sqr in place " + new GF2_192(p), !(res == z))
+ }
+ }
+ }
+ }
+
+ property("specialMultTest") {
+ val res = new GF2_192
+ val res1 = new GF2t_slow
+
+ // Run everything times 0 and 0 times everything
+ // and everything times 1 and 1 times everything
+ // where 0 and 1 are GF2_192
+
+ for ( p <- testValues ) {
+ var p1 = new GF2_192(p)
+ GF2_192.mul(res, p1, zero)
+ assertFalse("Fail: " + p1 + " * 0", !res.isZero)
+ GF2_192.mul(p1, p1, zero)
+ assertFalse("Fail: " + p1 + " * 0" + " in place ", !p1.isZero)
+ p1 = new GF2_192(p)
+ GF2_192.mul(res, zero, p1)
+ assertFalse("Fail: 0 * " + p1, !res.isZero)
+ GF2_192.mul(p1, zero, p1)
+ assertFalse("Fail: 0 * " + p1 + " in place ", !p1.isZero)
+ p1 = new GF2_192(p)
+ GF2_192.mul(res, p1, one)
+ assertFalse("Fail: " + p1 + " * 1", !(res == p1))
+ GF2_192.mul(p1, p1, one)
+ assertFalse("Fail: " + p1 + " * 1 in place", !(res == p1))
+ GF2_192.mul(res, one, p1)
+ assertFalse("Fail: 1 * " + p1, !(res == p1))
+ GF2_192.mul(p1, one, p1)
+ assertFalse("Fail: 1 * " + p1 + " in place", !(res == p1))
+ }
+
+ // Run everything times 0
+ // and everything times 1
+ // where 0 and 1 are bytes
+ for ( p <- testValues ) {
+ val p1 = new GF2_192(p)
+ GF2_192.mul(res, p1, 1.toByte)
+ assertFalse("Fail: " + p1 + " * 1 byte ", !(res == p1))
+ GF2_192.mul(p1, p1, 1.toByte)
+ assertFalse("Fail: " + p1 + " * 1 byte in place", !(res == p1))
+ GF2_192.mul(res, p1, 0.toByte)
+ assertFalse("Fail: " + p1 + " * 0 byte", !res.isZero)
+ GF2_192.mul(p1, p1, 0.toByte)
+ assertFalse("Fail: " + p1 + " * 0 byte in place", !p1.isZero)
+ }
+
+ // Run everything times every byte
+ val temp = new Array[Long](1)
+ for ( p <- testValues ) {
+ for ( i <- 2 until 256 ) {
+ val p1 = new GF2_192(p)
+ temp(0) = i
+ GF2_192.mul(res, p1, i.toByte)
+ GF2t_slow.mulBits(res1, p, temp)
+ GF2t_slow.modReduce(res1, m)
+ assertFalse("Fail: " + p1 + " * " + i + " byte", !res1.equals(res.toLongArray))
+ GF2_192.mul(p1, p1, i.toByte)
+ assertFalse("Fail: " + p1 + " * " + i + " byte in place", !(res == p1))
+ }
+ }
+ }
+
+ property("specialAddTest") {
+ val res = new GF2_192
+
+ // Run everything plus 0 and 0 plus everything
+ // where 0 is GF2_192
+ for ( p <- testValues ) {
+ val p1 = new GF2_192(p)
+ GF2_192.add(res, p1, zero)
+ assertFalse(s"Fail: $p1 + 0", !(res == p1))
+ GF2_192.add(p1, p1, zero)
+ assertFalse(s"Fail: $p1 + 0 in place", !(res == p1))
+ GF2_192.add(res, zero, p1)
+ assertFalse(s"Fail: 0 + $p1", !(res == p1))
+ GF2_192.add(p1, zero, p1)
+ assertFalse(s"Fail: $p1 + 0 in place", !(res == p1))
+ }
+ }
+
+ property("generalAddTest") {
+ val res = new GF2_192
+ val res1 = new GF2t_slow
+ res1.x = new Array[Long](3)
+
+ // Try everything plus everything in the test array
+ for ( p <- testValues ) {
+ var p1 = new GF2_192(p)
+ for ( q <- testValues ) {
+ val q1 = new GF2_192(q)
+ GF2_192.add(res, p1, q1)
+ res1.x(0) = p(0) ^ q(0)
+ res1.x(1) = p(1) ^ q(1)
+ res1.x(2) = p(2) ^ q(2)
+ assertFalse(s"Fail: $p1 + $q1 = $res not $res1",
+ !res1.equals(res.toLongArray))
+
+ GF2_192.add(p1, p1, q1)
+ assertFalse(s"Fail: $p1 + $q1 in place 1 ", !(res == p1))
+
+ p1 = new GF2_192(p)
+ GF2_192.add(q1, p1, q1)
+ assertFalse(s"Fail: $p1 + $q1 in place 2 ", !(res == q1))
+ }
+ }
+
+ // Try everything plus self in the test array, both in place and not, and make sure you get zeros
+ for ( p <- testValues ) {
+ val p1 = new GF2_192(p)
+ GF2_192.add(res, p1, p1)
+ assertFalse(s"Fail: $p1 + self", !res.isZero)
+
+ GF2_192.add(p1, p1, p1)
+ assertFalse(s"Fail: $p1 self in place", !p1.isZero)
+ }
+ }
+
+ property("generalMultTest") {
+ val res = new GF2_192
+ val res1 = new GF2t_slow
+
+ // Now run everything times everything in the test array
+ // TODO: speed this up
+ for ( p <- testValues ) {
+ var p1 = new GF2_192(p)
+ for ( q <- testValues ) {
+ val q1 = new GF2_192(q)
+ GF2_192.mul(res, p1, q1)
+ GF2t_slow.mulBits(res1, p, q)
+ GF2t_slow.modReduce(res1, m)
+ assertFalse(s"Fail: $p1 * $q1", !res1.equals(res.toLongArray))
+
+ GF2_192.mul(p1, p1, q1)
+ assertFalse(s"Fail: $p1 * $q1 in place 1 ", !(res == p1))
+
+ p1 = new GF2_192(p)
+ GF2_192.mul(q1, p1, q1)
+ assertFalse(s"Fail: $p1 * $q1 in place 2 ", !(res == q1))
+ }
+ }
+
+ // Try everything times self in the test array, in place
+ for ( p <- testValues ) {
+ val p1 = new GF2_192(p)
+ GF2_192.sqr(res, p1)
+ GF2_192.mul(p1, p1, p1)
+ assertFalse(s"Fail: $p1 * self in place", !(res == p1))
+ }
+ }
+
+ property("inversionTest") {
+ val res = new GF2_192
+ val res2 = new GF2_192
+ val res1 = new GF2t_slow
+
+ // Test inversion of 1
+ GF2_192.invert(res, one)
+ assertFalse("Fail: inversion of 1", !res.isOne)
+
+ // Test inversion of everything
+ for ( p <- testValues ) {
+ val p1 = new GF2_192(p)
+ if (!p1.isZero) {
+ GF2_192.invert(res, p1)
+ GF2_192.mul(res2, p1, res)
+ assertFalse(s"Fail: inversion of $p1 self-test ", !res2.isOne)
+
+ GF2t_slow.mulBits(res1, res.toLongArray, p)
+ GF2t_slow.modReduce(res1, m)
+ assertFalse(s"Fail: inversion of $p1 GF2t_slow-test", !res1.isOne)
+
+ GF2_192.invert(p1, p1)
+ assertFalse(s"Fail: inversion of $p1 in place ", !(p1 == res))
+ }
+ }
+ }
+
+ property("interpolateTest") {
+ // Test for null inputs, arrays of unequal length, etc.
+ val optArray: Array[GF2_192] = new Array[GF2_192](2)
+ optArray(0) = null
+ optArray(1) = new GF2_192(17)
+
+ var res: GF2_192_Poly = null
+ val rand: Random = new Random
+
+ // Try with arrays of length 0
+ var p = GF2_192_Poly.interpolate(
+ new Array[Byte](0), new Array[GF2_192](0), new GF2_192(0))
+ assertFalse("Zero polynomial should be 0 at 0", !p.evaluate(0.toByte).isZero)
+ assertFalse("Zero polynomial should be 0 at 5", !p.evaluate(5.toByte).isZero)
+
+ val val17 = new GF2_192(17)
+ p = GF2_192_Poly.interpolate(new Array[Byte](0), new Array[GF2_192](0), val17)
+ assertFalse("Constant 17 polynomial should be 17 at 0", !(p.evaluate(0.toByte) == val17))
+ assertFalse("Constant 17 polynomial should be 17 at 5", !(p.evaluate(5.toByte) == val17))
+
+ for ( len <- 1 until 100 ) {
+ val points = new Array[Byte](len)
+ val values = new Array[GF2_192](len)
+ val temp = new Array[Byte](24)
+ for ( i <- 0 until len ) {
+ // generate a byte that is not equal to anything in the array nor 0
+ var doLoop = true
+ while (doLoop) {
+ var b: Byte = 0
+ do b = rand.nextInt.toByte while ( b == 0.toByte )
+ var j: Int = 0
+ var doBreak = false
+ while (!doBreak && j < i) {
+ if (b == points(j)) { // detected equality with something in the array
+ doBreak = true
+ } else {
+ j += 1
+ }
+ }
+ if (j == i) { // did not detect equality with anything in the array
+ points(i) = b
+ doLoop = false
+ }
+ }
+ }
+ for ( i <- 0 until len ) {
+ rand.nextBytes(temp)
+ values(i) = new GF2_192(temp)
+ }
+
+ res = GF2_192_Poly.interpolate(points, values, null)
+ for ( i <- 0 until len ) {
+ val t = res.evaluate(points(i))
+ assertFalse(s"Interpolation error on length = $len at input point number $i", !(t == values(i)))
+ }
+ rand.nextBytes(temp)
+ val valueAt0 = new GF2_192(temp)
+ res = GF2_192_Poly.interpolate(points, values, valueAt0)
+ for ( i <- 0 until len ) {
+ val t = res.evaluate(points(i))
+ assertFalse(s"Interpolation error on length = $len at input point number $i(with optional 0)", !(t == values(i)))
+ }
+ val t = res.evaluate(0.toByte)
+ assertFalse(s"Interpolation error on length = $len at input optional 0", !(t == valueAt0))
+
+ val b = res.toByteArray(false)
+ val t1 = GF2_192_Poly.fromByteArray(valueAt0.toByteArray, b)
+ val b1 = t1.toByteArray(false)
+ assertFalse(
+ s"To byte array round trip error ${util.Arrays.toString(b)} ${util.Arrays.toString(b1)}",
+ !Arrays.equals(b, b1))
+
+ val b2 = t1.toByteArray(true)
+ assertFalse("To byte array round trip error at coeff0",
+ !Arrays.equals(valueAt0.toByteArray, Arrays.copyOfRange(b2, 0, 24)))
+ assertFalse("To byte array round trip error with coeff0 at later coeff",
+ !Arrays.equals(b1, Arrays.copyOfRange(b2, 24, b2.length)))
+
+ val b3 = t1.coeff0Bytes
+ assertFalse("To byte array round trip error on coeff0",
+ !Arrays.equals(b3, valueAt0.toByteArray))
+ }
+
+ for ( len <- 1 until 100 ) {
+ val points = new Array[Byte](len)
+ val values = new Array[GF2_192](len)
+ val temp = new Array[Byte](24)
+
+ for ( i <- 0 until len ) {
+ // generate a byte that is not equal to anything in the array (but may be 0)
+ var okLoop = true
+ while (okLoop) {
+ val b = rand.nextInt.toByte
+ var j = 0
+ j = 0
+ var doBreak = false
+ while (!doBreak && j < i) {
+ if (b == points(j)) {
+ doBreak = true
+ } else {
+ j += 1
+ }
+ }
+ if (j == i) {
+ points(i) = b
+ okLoop = false
+ }
+ }
+ }
+ for ( i <- 0 until len ) {
+ rand.nextBytes(temp)
+ values(i) = new GF2_192(temp)
+ }
+
+ res = GF2_192_Poly.interpolate(points, values, null)
+ for ( i <- 0 until len ) {
+ val t = res.evaluate(points(i))
+ assertFalse(s"Interpolation error on length = $len $i(with 0 allowed but not additional)", !(t == values(i)))
+ }
+
+ for ( opt <- optArray ) {
+ res = GF2_192_Poly.interpolate(null, values, opt)
+ assertFalse("Fail: interpolate should output null on points = null", res != null)
+ res = GF2_192_Poly.interpolate(points, null, opt)
+ assertFalse("Fail: interpolate should output null on values = null", res != null)
+ res = GF2_192_Poly.interpolate(points, new Array[GF2_192](0), opt)
+ assertFalse("Fail: interpolate should output null on values of length 0", res != null)
+ res = GF2_192_Poly.interpolate(new Array[Byte](0), values, opt)
+ assertFalse("Fail: interpolate should output null on points of length 0", res != null)
+ res = GF2_192_Poly.interpolate(new Array[Byte](len - 1), values, opt)
+ assertFalse("Fail: interpolate should output null on not enough points", res != null)
+ res = GF2_192_Poly.interpolate(new Array[Byte](len + 1), values, opt)
+ assertFalse("Fail: interpolate should output null on too many points", res != null)
+ }
+ }
+ for ( opt <- optArray ) {
+ res = GF2_192_Poly.interpolate(null, null, opt)
+ assertFalse("Fail: interpolate should output null on both points and values = null", res != null)
+ }
+ }
+}
diff --git a/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala
index b77d3c5b0a..b5b0b8b33b 100644
--- a/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala
@@ -1,11 +1,11 @@
package sigmastate.crypto
import java.math.BigInteger
-
import org.scalacheck.Gen
-import sigmastate.helpers.SigmaTestingCommons
+import sigmastate.helpers.{SigmaPPrint, SigmaTestingCommons}
import sigmastate.interpreter.CryptoConstants
import sigmastate.interpreter.CryptoConstants.EcPointType
+import sigmastate.utils.Helpers
import scala.util.Random
@@ -54,4 +54,52 @@ class GroupLawsSpecification extends SigmaTestingCommons {
}
}
+ private def printPoints(points: Seq[(String, Any)]) = {
+ points.foreach { case (name, p) =>
+ println(s"val $name = ${SigmaPPrint.apply(p).plainText}")
+ }
+ }
+
+// uncommment to generate new test vectors
+//
+// property("generate initial points") {
+// printPoints(Seq(
+// "identity" -> group.identity,
+// "order" -> group.order,
+// "p1" -> group.createRandomElement(),
+// "p2" -> group.createRandomElement(),
+// "p3" -> group.createRandomElement()
+// ))
+// }
+
+ val p1: Ecp = Helpers.decodeECPoint("0381c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac")
+ val p2 = Helpers.decodeECPoint("02198064ec24024bb8b300e20dd18e33cc1fccb0fea73940bd9a1d3d9d6c3ddd8f")
+ val p3 = Helpers.decodeECPoint("02e135f5f905fb843698d48959c6c792b2c6f9605b90be2280d53b4b69ef23e8a9")
+
+// uncommment to generate new test vectors
+ property("generate op results") {
+ printPoints(Seq(
+ "p1" -> p1,
+ "p2" -> p2,
+ "p3" -> p3,
+ "p1.add(p2)" -> CryptoFacade.multiplyPoints(p1, p2),
+ "p1.multiply(order)" -> CryptoFacade.exponentiatePoint(p1, group.order),
+ "p1.multiply(order + 1)" -> CryptoFacade.exponentiatePoint(p1, group.order.add(BigInteger.ONE)),
+ "p1.inverse" -> CryptoFacade.negatePoint(p1)
+ ))
+ }
+
+ property("check test vectors") {
+ CryptoFacade.multiplyPoints(p1, p2) shouldBe
+ Helpers.decodeECPoint("03de5e9c2806c05cd45a57d18c469743f42a0d2c84370b6662eb39d8a2990abed8")
+
+ CryptoFacade.exponentiatePoint(p1, group.order) shouldBe
+ Helpers.decodeECPoint("000000000000000000000000000000000000000000000000000000000000000000")
+
+ CryptoFacade.exponentiatePoint(p1, group.order.add(BigInteger.ONE)) shouldBe
+ Helpers.decodeECPoint("0381c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac")
+
+ CryptoFacade.negatePoint(p1) shouldBe
+ Helpers.decodeECPoint("0281c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac")
+ }
}
diff --git a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala
index 4d024fc33d..d4f05a4050 100644
--- a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala
+++ b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala
@@ -1,14 +1,16 @@
package sigmastate.eval
+import org.scalatest.funsuite.AnyFunSuite
+import org.scalatest.matchers.should.Matchers
+
import java.math.BigInteger
-import org.bouncycastle.crypto.ec.CustomNamedCurves
-import org.scalatest.{FunSuite, Matchers}
import sigmastate.TrivialProp
+import sigmastate.basics.SecP256K1Group
import special.sigma.{ContractsTestkit, SigmaDslBuilder, SigmaProp}
import scala.language.implicitConversions
-class BasicOpsTests extends FunSuite with ContractsTestkit with Matchers {
+class BasicOpsTests extends AnyFunSuite with ContractsTestkit with Matchers {
override val SigmaDsl: SigmaDslBuilder = CostingSigmaDslBuilder
implicit def boolToSigma(b: Boolean): SigmaProp = TrivialProp(b)
@@ -33,7 +35,7 @@ class BasicOpsTests extends FunSuite with ContractsTestkit with Matchers {
// TODO this is valid for BigIntModQ type (https://github.com/ScorexFoundation/sigmastate-interpreter/issues/554)
ignore("ByteArrayToBigInt should always produce big int less than dlog group order") {
- val groupOrder = CustomNamedCurves.getByName("secp256k1").getN
+ val groupOrder = SecP256K1Group.ctx.order
SigmaDsl.byteArrayToBigInt(
Colls.fromArray(groupOrder.subtract(BigInteger.ONE).toByteArray)
diff --git a/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala
index 798def6b18..25d7a9e384 100644
--- a/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala
+++ b/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala
@@ -1,10 +1,11 @@
package sigmastate.helpers
-import org.scalatest.Matchers
import scala.annotation.tailrec
import scala.util.{Failure, Success, Try}
import debox.cfor
+import org.scalatest.matchers.should.Matchers
+
import scala.reflect.ClassTag
trait NegativeTesting extends Matchers {
diff --git a/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala
index f9a5e64885..3122e2f5f0 100644
--- a/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala
+++ b/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala
@@ -1,7 +1,6 @@
package sigmastate.helpers
import java.math.BigInteger
-import gf2t.GF2_192_Poly
import org.ergoplatform.ErgoBox
import org.ergoplatform.ErgoBox.RegisterId
import org.ergoplatform.settings.ErgoAlgos
@@ -11,6 +10,7 @@ import scalan.RType.PrimitiveType
import sigmastate.SCollection._
import sigmastate.Values.{ConstantNode, ErgoTree, FuncValue, ValueCompanion}
import sigmastate._
+import sigmastate.crypto.GF2_192_Poly
import sigmastate.interpreter.CryptoConstants.EcPointType
import sigmastate.lang.SigmaTyper
import sigmastate.lang.Terms.MethodCall
@@ -111,7 +111,7 @@ object SigmaPPrint extends PPrinter {
Tree.Apply("BigInt", treeifyMany(v.toString(16), 16))
case poly: GF2_192_Poly =>
- val c0 = poly.coeff0Bytes()
+ val c0 = poly.coeff0Bytes
val others = poly.toByteArray(false) // don't output
Tree.Apply("GF2_192_Poly.fromByteArray", treeifyMany(c0, others))
diff --git a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala
index b9fa6ffaba..69ed1a9c78 100644
--- a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala
+++ b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala
@@ -6,8 +6,10 @@ import org.ergoplatform.validation.ValidationRules.CheckSerializableTypeCode
import org.ergoplatform.validation.{ValidationException, ValidationSpecification}
import org.scalacheck.Arbitrary.arbByte
import org.scalacheck.Gen
-import org.scalatest.prop.{GeneratorDrivenPropertyChecks, PropertyChecks}
-import org.scalatest.{Assertion, Matchers, PropSpec}
+import org.scalatest.Assertion
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.{ScalaCheckDrivenPropertyChecks, ScalaCheckPropertyChecks}
import scalan.util.BenchmarkUtil
import scalan.{RType, TestContexts, TestUtils}
import scorex.crypto.hash.Blake2b256
@@ -27,9 +29,9 @@ import scala.language.implicitConversions
import scala.reflect.ClassTag
import scala.util.DynamicVariable
-trait SigmaTestingCommons extends PropSpec
- with PropertyChecks
- with GeneratorDrivenPropertyChecks
+trait SigmaTestingCommons extends AnyPropSpec
+ with ScalaCheckPropertyChecks
+ with ScalaCheckDrivenPropertyChecks
with Matchers with TestUtils with TestContexts with ValidationSpecification
with NegativeTesting
with TestsBase {
diff --git a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala
index 634bb8f103..a512b25de9 100644
--- a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala
+++ b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala
@@ -1,12 +1,11 @@
package sigmastate.lang
-import sigmastate.lang.Terms.{MethodCallLike, Ident}
-import sigmastate.Values.{LongConstant, SValue, Value, SigmaBoolean, ConcreteCollection}
+import org.scalatest.matchers.should.Matchers
+import sigmastate.lang.Terms.{Ident, MethodCallLike}
+import sigmastate.Values.{ConcreteCollection, LongConstant, SValue, SigmaBoolean, Value}
import sigmastate._
-import java.math.BigInteger
-import org.bouncycastle.math.ec.ECPoint
-import org.scalatest.Matchers
+import java.math.BigInteger
import sigmastate.basics.DLogProtocol.ProveDlog
import sigmastate.SCollection.SByteArray
import sigmastate.basics.ProveDHTuple
@@ -39,10 +38,10 @@ trait LangTests extends Matchers with NegativeTesting {
val ecp2 = dlog.multiplyGroupElements(ecp1, ecp1)
val ecp3 = dlog.multiplyGroupElements(ecp2, ecp2)
val ecp4 = dlog.multiplyGroupElements(ecp3, ecp3)
- val g1 = CostingSigmaDslBuilder.GroupElement(ecp1.asInstanceOf[ECPoint])
- val g2 = CostingSigmaDslBuilder.GroupElement(ecp2.asInstanceOf[ECPoint])
- val g3 = CostingSigmaDslBuilder.GroupElement(ecp3.asInstanceOf[ECPoint])
- val g4 = CostingSigmaDslBuilder.GroupElement(ecp4.asInstanceOf[ECPoint])
+ val g1 = CostingSigmaDslBuilder.GroupElement(ecp1)
+ val g2 = CostingSigmaDslBuilder.GroupElement(ecp2)
+ val g3 = CostingSigmaDslBuilder.GroupElement(ecp3)
+ val g4 = CostingSigmaDslBuilder.GroupElement(ecp4)
protected val n1: BigInt = BigInt(10).underlying()
protected val n2: BigInt = BigInt(20).underlying()
@@ -75,7 +74,7 @@ trait LangTests extends Matchers with NegativeTesting {
def ty(s: String): SType = SigmaParser.parseType(s)
def assertSrcCtxForAllNodes(tree: SValue): Unit = {
- import org.bitbucket.inkytonik.kiama.rewriting.Rewriter._
+ import sigmastate.kiama.rewriting.Rewriter._
rewrite(everywherebu(rule[Any] {
case node: SValue =>
withClue(s"Missing sourceContext for $node") { node.sourceContext.isDefined shouldBe true }
diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala
index ad8db1ef17..a9404048ed 100644
--- a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala
+++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala
@@ -2,8 +2,9 @@ package sigmastate.lang
import org.ergoplatform.{Height, Inputs, Outputs, Self}
import org.ergoplatform.ErgoAddressEncoder._
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{Matchers, PropSpec}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import sigmastate.Values._
import sigmastate._
import sigmastate.interpreter.Interpreter.ScriptEnv
@@ -12,7 +13,7 @@ import sigmastate.lang.Terms._
import sigmastate.lang.exceptions.BinderException
import sigmastate.eval._
-class SigmaBinderTest extends PropSpec with PropertyChecks with Matchers with LangTests {
+class SigmaBinderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with LangTests {
import StdSigmaBuilder._
def bind(env: ScriptEnv, x: String): SValue = {
diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala
index 07061743c4..3e25700816 100644
--- a/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala
+++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala
@@ -1,13 +1,14 @@
package sigmastate.lang
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{Matchers, PropSpec}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import sigmastate.Values._
import sigmastate._
import sigmastate.lang.exceptions.ConstraintFailed
import sigmastate.serialization.OpCodes
-class SigmaBuilderTest extends PropSpec with PropertyChecks with Matchers with LangTests {
+class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with LangTests {
property("StdSigmaBuilder construct nodes") {
import StdSigmaBuilder._
diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala
index 2d16830bb0..605082437f 100644
--- a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala
+++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala
@@ -21,20 +21,12 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe
private def comp(env: ScriptEnv, x: String): Value[SType] = compile(env, x)
private def comp(x: String): Value[SType] = compile(env, x)
- private def compWOCosting(x: String): Value[SType] = compileWithoutCosting(env, x)
private def testMissingCosting(script: String, expected: SValue): Unit = {
- val tree = compWOCosting(script)
- tree shouldBe expected
- checkSerializationRoundTrip(tree)
- // when implemented in coster this should be changed to a positive expectation
an [CosterException] should be thrownBy comp(env, script)
}
private def testMissingCostingWOSerialization(script: String, expected: SValue): Unit = {
- val tree = compWOCosting(script)
- tree shouldBe expected
- // when implemented in coster this should be changed to a positive expectation
an [CosterException] should be thrownBy comp(env, script)
}
diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala
index 7807a546a0..4b5680af0a 100644
--- a/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala
+++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala
@@ -2,8 +2,9 @@ package sigmastate.lang
import fastparse.Parsed
import org.ergoplatform.{ErgoAddressEncoder, ErgoBox}
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{PropSpec, Matchers}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import sigmastate.SCollection._
import sigmastate.Values._
import sigmastate._
@@ -12,7 +13,7 @@ import sigmastate.lang.Terms._
import sigmastate.lang.syntax.ParserException
import sigmastate.serialization.OpCodes
-class SigmaParserTest extends PropSpec with PropertyChecks with Matchers with LangTests {
+class SigmaParserTest extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with LangTests {
import StdSigmaBuilder._
private val predefFuncRegistry = new PredefinedFuncRegistry(StdSigmaBuilder)
diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala
deleted file mode 100644
index b661ae5924..0000000000
--- a/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala
+++ /dev/null
@@ -1,229 +0,0 @@
-package sigmastate.lang
-
-import org.ergoplatform.ErgoAddressEncoder.{NetworkPrefix, TestnetNetworkPrefix}
-import org.ergoplatform.ErgoBox.R4
-import org.ergoplatform._
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{Matchers, PropSpec}
-import sigmastate.Values._
-import sigmastate._
-import sigmastate.lang.SigmaPredef.PredefinedFuncRegistry
-import sigmastate.lang.Terms.{Ident, ZKProofBlock}
-import sigmastate.lang.exceptions.SpecializerException
-import sigmastate.serialization.generators.{ConcreteCollectionGenerators, TransformerGenerators, ObjectGenerators}
-import sigmastate.utxo._
-import sigmastate.lang.Terms._
-
-class SigmaSpecializerTest extends PropSpec
- with PropertyChecks
- with Matchers
- with LangTests
- with ObjectGenerators
- with ConcreteCollectionGenerators
- with TransformerGenerators {
-
- private def countANDORInputNodes(root: Transformer[SCollection[SBoolean.type], SBoolean.type]): Int =
- root.input.items.foldLeft(0) { (sum, item) =>
- item match {
- case r@AND(_) => sum + countANDORInputNodes(r)
- case r@OR(_) => sum + countANDORInputNodes(r)
- case _ => sum + 1
- }
- }
-
- def typed(env: Map[String, SValue], x: String): SValue = {
- val builder = TransformingSigmaBuilder
- val parsed = SigmaParser(x, builder).get.value
- val predefinedFuncRegistry = new PredefinedFuncRegistry(builder)
- val binder = new SigmaBinder(env, builder, TestnetNetworkPrefix, predefinedFuncRegistry)
- val bound = binder.bind(parsed)
- val typer = new SigmaTyper(builder, predefinedFuncRegistry, lowerMethodCalls = true)
- val typed = typer.typecheck(bound)
- typed
- }
- def spec(env: Map[String, SValue], typed: SValue, networkPrefix: NetworkPrefix = TestnetNetworkPrefix): SValue = {
- val spec = new SigmaSpecializer(TransformingSigmaBuilder)
- spec.specialize(env, typed)
- }
- def spec(code: String): SValue = {
- spec(Map(), typed(Map(), code))
- }
- def fail(env: Map[String, SValue], code: String, messageSubstr: String = ""): Unit = {
- try {
- spec(env, typed(env, code))
- assert(false, s"Should fail: $code")
- } catch {
- case e: SpecializerException =>
- if (messageSubstr.nonEmpty)
- if (!e.getMessage.contains(messageSubstr)) {
- throw new AssertionError(s"Error message '${e.getMessage}' doesn't contain '$messageSubstr'.", e)
- }
- }
- }
-
- property("resolve let-bound names and substitute") {
- spec(Map("X" -> LongConstant(10)),
- Ident("X", SLong)) shouldBe LongConstant(10)
- spec(Map("X" -> LongConstant(10)),
- Plus(Ident("X", SLong).asValue[SLong.type], LongConstant(1))) shouldBe Plus(10L, 1L)
- }
-
- property("substitute all val expressions in block result") {
- spec("{ val X = 10; X }") shouldBe IntConstant(10)
- spec("{ val X = 10; val Y = 20; X + Y }") shouldBe Plus(10, 20)
- spec("{ val X = 10; val Y = 20; X + Y + X }") shouldBe Plus(Plus(10, 20), 10)
- spec("{ val X = 10 + 1; X + X}") shouldBe Plus(Plus(10, 1), Plus(10, 1))
- spec("{ val X = 10; val Y = X; Y}") shouldBe IntConstant(10)
- spec("{ val X = 10; val Y = X; val Z = Y; Z }") shouldBe IntConstant(10)
- spec("{ val X = 10; val Y = X + 1; val Z = Y + X; Z + Y + X }") shouldBe
- Plus(Plus(/*Z=*/Plus(/*Y=*/Plus(10, 1), 10), /*Y=*/Plus(10, 1)), 10)
- }
-
- property("Tuple operations") {
- spec("(1, 2L)._1") shouldBe SelectField(Tuple(IntConstant(1), LongConstant(2L)), 1)
- spec("(1, 2L)._2") shouldBe SelectField(Tuple(IntConstant(1), LongConstant(2L)), 2)
- spec("(1, 2L, 3)._3") shouldBe SelectField(Tuple(IntConstant(1), LongConstant(2L), IntConstant(3)), 3)
-
- // tuple as collection
- spec("(1, 2L).size") shouldBe SizeOf(Tuple(IntConstant(1), LongConstant(2L)))
-// spec(env, "(1, 2L)(0)") shouldBe SInt
-// spec(env, "(1, 2L)(1)") shouldBe SLong
-// spec(env, "(1, 2L).getOrElse(2, 3)") shouldBe SAny
-// spec(env, "(1, 2L).slice(0, 2)") shouldBe SCollection(SAny)
-// spec(env, "fun (a: Int) = (1, 2L)(a)") shouldBe SFunc(IndexedSeq(SInt), SAny)
- }
-
- property("Option constructors") {
- fail(Map(), "None", "Option constructors are not supported")
- fail(Map(), "Some(10)", "Option constructors are not supported")
- }
-
- property("generic methods of arrays") {
- spec("OUTPUTS.map({ (out: Box) => out.value >= 10 })") shouldBe
- MapCollection(Outputs, Lambda(Vector(("out", SBox)), SBoolean, GE(ExtractAmount(Ident("out", SBox).asBox), LongConstant(10))))
- spec("OUTPUTS.exists({ (out: Box) => out.value >= 10 })") shouldBe
- Exists(Outputs, Lambda(Vector(("out", SBox)), SBoolean, GE(ExtractAmount(Ident("out", SBox).asBox), LongConstant(10))))
- spec("OUTPUTS.forall({ (out: Box) => out.value >= 10 })") shouldBe
- ForAll(Outputs, Lambda(Vector(("out", SBox)), SBoolean, GE(ExtractAmount(Ident("out", SBox).asBox), LongConstant(10))))
- spec("{ val arr = Coll(1,2); arr.fold(0, { (n1: Int, n2: Int) => n1 + n2 })}") shouldBe
- Fold(ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)),
- IntConstant(0),
- Lambda(Vector(("n1", SInt), ("n2", SInt)), SInt, Plus(Ident("n1", SInt).asNumValue, Ident("n2", SInt).asNumValue)))
- spec("{ val arr = Coll(1,2); arr.fold(true, {(n1: Boolean, n2: Int) => n1 && (n2 > 1)})}") shouldBe
- Fold(ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)),
- TrueLeaf,
- Lambda(Vector(("n1", SBoolean), ("n2", SInt)), SBoolean,
- BinAnd(Ident("n1", SBoolean).asBoolValue, GT(Ident("n2", SInt), IntConstant(1))))
- )
- spec("OUTPUTS.slice(0, 10)") shouldBe
- Slice(Outputs, IntConstant(0), IntConstant(10))
- spec("OUTPUTS.filter({ (out: Box) => out.value >= 10 })") shouldBe
- Filter(Outputs, Lambda(Vector(("out", SBox)), SBoolean, GE(ExtractAmount(Ident("out", SBox).asBox), LongConstant(10))))
- }
-
- property("AND flattening predefined") {
- spec("true && true") shouldBe BinAnd(TrueLeaf, TrueLeaf)
- spec("true && false") shouldBe BinAnd(TrueLeaf, FalseLeaf)
- spec("true && (true && 10 == 10)") shouldBe
- BinAnd(TrueLeaf, BinAnd(TrueLeaf, EQ(IntConstant(10), IntConstant(10))))
- spec("true && true && true") shouldBe BinAnd(BinAnd(TrueLeaf, TrueLeaf), TrueLeaf)
- spec("true && (true && (true && true)) && true") shouldBe
- BinAnd(BinAnd(TrueLeaf, BinAnd(TrueLeaf, BinAnd(TrueLeaf, TrueLeaf))), TrueLeaf)
- }
-
- property("AND flattening, CAND/COR untouched") {
- val sigmaBooleans1 = AND(Array(TrueLeaf, CAND(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven))
- spec(Map(), sigmaBooleans1) shouldBe sigmaBooleans1
- val sigmaBooleans2 = AND(Array(TrueLeaf, COR(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven))
- spec(Map(), sigmaBooleans2) shouldBe sigmaBooleans2
- }
-
- property("AND flattening") {
- forAll(logicalExprTreeNodeGen(Seq(AND.apply))) { tree =>
- val out = spec(Map(), tree).asInstanceOf[AND]
- out.input.items.forall(!_.isInstanceOf[AND]) shouldBe true
- countANDORInputNodes(tree) shouldBe out.input.items.length
- }
- }
-
- property("OR flattening predefined") {
- spec("true || true || true") shouldBe BinOr(BinOr(TrueLeaf, TrueLeaf), TrueLeaf)
- spec("true || (true || true) || true") shouldBe
- BinOr(BinOr(TrueLeaf, BinOr(TrueLeaf, TrueLeaf)), TrueLeaf)
- }
-
- property("XOR flattening predefined") {
- spec("true ^ true ^ true") shouldBe BinXor(BinXor(TrueLeaf, TrueLeaf), TrueLeaf)
- spec("true ^ (true ^ true) ^ true") shouldBe
- BinXor(BinXor(TrueLeaf, BinXor(TrueLeaf, TrueLeaf)), TrueLeaf)
- }
-
- property("OR flattening, CAND/COR untouched") {
- val sigmaBooleans1 = OR(Array(TrueLeaf, CAND(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven))
- spec(Map(), sigmaBooleans1) shouldBe sigmaBooleans1
- val sigmaBooleans2 = OR(Array(TrueLeaf, COR(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven))
- spec(Map(), sigmaBooleans2) shouldBe sigmaBooleans2
- }
-
- property("OR flattening") {
- forAll(logicalExprTreeNodeGen(Seq(OR.apply))) { tree =>
- val out = spec(Map(), tree).asInstanceOf[OR]
- out.input.items.forall(!_.isInstanceOf[OR]) shouldBe true
- countANDORInputNodes(tree) shouldBe out.input.items.length
- }
- }
-
- property("numeric casts") {
- spec("1.toByte") shouldBe ByteConstant(1)
- spec("1.toLong") shouldBe LongConstant(1)
- spec("1.toBigInt") shouldBe BigIntConstant(1)
- spec("HEIGHT.toLong") shouldBe Upcast(Height, SLong)
- spec("HEIGHT.toByte") shouldBe Downcast(Height, SByte)
- spec("INPUTS.size.toLong") shouldBe Upcast(SizeOf(Inputs), SLong)
- spec("INPUTS.size.toBigInt") shouldBe Upcast(SizeOf(Inputs), SBigInt)
- }
-
- property("failed numeric casts for constants") {
- an[ArithmeticException] should be thrownBy spec("999.toByte")
- an[ArithmeticException] should be thrownBy spec("999.toShort.toByte")
- an[ArithmeticException] should be thrownBy spec(s"${Int.MaxValue}.toShort")
- an[ArithmeticException] should be thrownBy spec(s"${Long.MaxValue}L.toInt")
- }
-
- property("ExtractRegisterAs") {
- spec("SELF.R4[Int]") shouldBe ExtractRegisterAs[SInt.type](Self, R4)
- }
-
- property("OptionIsDefined") {
- spec("SELF.R4[Int].isDefined") shouldBe ExtractRegisterAs[SInt.type](Self, R4).isDefined
- spec("getVar[Int](1).isDefined") shouldBe GetVarInt(1).isDefined
- }
-
- property("OptionGet") {
- spec("SELF.R4[Int].get") shouldBe ExtractRegisterAs[SInt.type](Self, R4).get
- spec("getVar[Int](1).get") shouldBe GetVarInt(1).get
- }
-
- property("OptionGetOrElse") {
- spec("SELF.R4[Int].getOrElse(0)") shouldBe ExtractRegisterAs[SInt.type](Self, R4).getOrElse(IntConstant(0))
- spec("getVar[Int](1).getOrElse(0)") shouldBe GetVarInt(1).getOrElse(IntConstant(0))
- }
-
- property("string concat") {
- spec(""" "a" + "b" """) shouldBe StringConstant("ab")
- }
-
- property("ExtractCreationInfo") {
- spec("SELF.creationInfo") shouldBe ExtractCreationInfo(Self)
- spec("SELF.creationInfo._1") shouldBe SelectField(ExtractCreationInfo(Self), 1)
- spec("SELF.creationInfo._2") shouldBe SelectField(ExtractCreationInfo(Self), 2)
- }
-
- property("sigmaProp") {
- spec("sigmaProp(HEIGHT > 1000)") shouldBe BoolToSigmaProp(GT(Height, IntConstant(1000)))
- }
-
- property("ZKProof") {
- spec("ZKProof { sigmaProp(HEIGHT > 1000) }") shouldBe ZKProofBlock(BoolToSigmaProp(GT(Height, IntConstant(1000))))
- }
-}
diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala
index fc680bfcf9..3153344bbe 100644
--- a/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala
+++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala
@@ -2,8 +2,9 @@ package sigmastate.lang
import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix
import org.ergoplatform._
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{Matchers, PropSpec}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import sigmastate.SCollection._
import sigmastate.Values._
import sigmastate._
@@ -19,7 +20,8 @@ import sigmastate.serialization.ErgoTreeSerializer
import sigmastate.serialization.generators.ObjectGenerators
import sigmastate.utxo.{Append, ExtractCreationInfo}
-class SigmaTyperTest extends PropSpec with PropertyChecks with Matchers with LangTests with ObjectGenerators {
+class SigmaTyperTest extends AnyPropSpec
+ with ScalaCheckPropertyChecks with Matchers with LangTests with ObjectGenerators {
private val predefFuncRegistry = new PredefinedFuncRegistry(StdSigmaBuilder)
import predefFuncRegistry._
diff --git a/sigmastate/src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala
index 3c09275a1b..ed3382fa10 100644
--- a/sigmastate/src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala
@@ -45,7 +45,7 @@ class AvlTreeSpecification extends SerializationSpecification {
val k = Blake2b256.hash("1")
val v = k
- avlProver.performOneOperation(Insert(ADKey @@ k, ADValue @@ v))
+ avlProver.performOneOperation(Insert(ADKey @@@ k, ADValue @@@ v))
val proof = avlProver.generateProof()
val resTree = tree.insert(Array(k.toColl -> v.toColl).toColl, proof.toColl).get
diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala
index d8733d89a9..22be862da2 100644
--- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala
+++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala
@@ -403,10 +403,10 @@ class DeserializationResilience extends SerializationSpecification
val tree = SigmaDsl.avlTree(treeData)
val k = Blake2b256.hash("1")
val v = k
- avlProver.performOneOperation(Insert(ADKey @@ k, ADValue @@ v))
+ avlProver.performOneOperation(Insert(ADKey @@@ k, ADValue @@@ v))
val proof = avlProver.generateProof()
val verifier = tree.createVerifier(Colls.fromArray(proof))
- verifier.performOneOperation(Insert(ADKey @@ k, ADValue @@ v)).isFailure shouldBe true
+ verifier.performOneOperation(Insert(ADKey @@@ k, ADValue @@@ v)).isFailure shouldBe true
// NOTE, even though performOneOperation fails, some AvlTree$ methods used in Interpreter
// (remove_eval, update_eval, contains_eval) won't throw, while others will.
}
diff --git a/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala
index dd17ce069f..5be6cc5ff9 100644
--- a/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala
@@ -1,5 +1,6 @@
package sigmastate.serialization
+import sigmastate.crypto.CryptoFacade
import sigmastate.interpreter.CryptoConstants
import sigmastate.eval._
@@ -12,7 +13,7 @@ class GroupElementSerializerSpecification extends SerializationSpecification {
val bytes = GroupElementSerializer.toBytes(identity)
bytes.length shouldBe CryptoConstants.EncodedGroupElementLength
bytes.forall(_ == 0) shouldBe true
- GroupElementSerializer.parse(SigmaSerializer.startReader(bytes, 0)).isInfinity shouldBe true
+ GroupElementSerializer.parse(SigmaSerializer.startReader(bytes, 0)).isIdentity shouldBe true
}
property("point roundtrip") {
@@ -20,8 +21,10 @@ class GroupElementSerializerSpecification extends SerializationSpecification {
val bytes = GroupElementSerializer.toBytes(ge.value)
bytes.length shouldBe CryptoConstants.EncodedGroupElementLength
val restored = GroupElementSerializer.parse(SigmaSerializer.startReader(bytes, 0))
- restored.normalize().getAffineXCoord shouldBe ge.value.normalize().getAffineXCoord
- restored.normalize().getAffineYCoord shouldBe ge.value.normalize().getAffineYCoord
+ CryptoFacade.getAffineXCoord(CryptoFacade.normalizePoint(restored)) shouldBe
+ CryptoFacade.getAffineXCoord(CryptoFacade.normalizePoint(ge.value))
+ CryptoFacade.getAffineYCoord(CryptoFacade.normalizePoint(restored)) shouldBe
+ CryptoFacade.getAffineYCoord(CryptoFacade.normalizePoint(ge.value))
}
}
}
diff --git a/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala
index 5ffc800191..03b8801459 100644
--- a/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala
@@ -2,17 +2,20 @@ package sigmastate.serialization
import org.ergoplatform.validation.ValidationSpecification
import org.scalacheck.Gen
-import org.scalatest.prop.{PropertyChecks, TableDrivenPropertyChecks, GeneratorDrivenPropertyChecks}
-import org.scalatest.{PropSpec, Assertion, Matchers}
+import org.scalatest.prop.TableDrivenPropertyChecks
+import org.scalatest.Assertion
import org.scalacheck.Arbitrary._
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.{ScalaCheckDrivenPropertyChecks, ScalaCheckPropertyChecks}
import sigmastate.Values._
import sigmastate.SType
import sigmastate.helpers.NegativeTesting
import sigmastate.serialization.generators._
-trait SerializationSpecification extends PropSpec
- with PropertyChecks
- with GeneratorDrivenPropertyChecks
+trait SerializationSpecification extends AnyPropSpec
+ with ScalaCheckPropertyChecks
+ with ScalaCheckDrivenPropertyChecks
with TableDrivenPropertyChecks
with Matchers
with ObjectGenerators
diff --git a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala
index 57a578174a..dbaa64f57e 100644
--- a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala
@@ -2,8 +2,6 @@ package sigmastate.serialization
import java.math.BigInteger
import java.util
-
-import gf2t.GF2_192_Poly
import org.ergoplatform.settings.ErgoAlgos
import org.scalacheck.{Arbitrary, Gen}
import org.scalatest.Assertion
@@ -12,6 +10,7 @@ import sigmastate._
import sigmastate.basics.DLogProtocol.{ProveDlog, SecondDLogProverMessage}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.basics.{ProveDHTuple, SecondDiffieHellmanTupleProverMessage}
+import sigmastate.crypto.GF2_192_Poly
import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTransactionTesting, SigmaTestingCommons}
import sigmastate.interpreter.Interpreter
import sigmastate.serialization.generators.ObjectGenerators
diff --git a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala
index 537c616b05..b776bd8682 100644
--- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala
+++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala
@@ -188,7 +188,7 @@ trait ObjectGenerators extends TypeGenerators
def additionalTokensGen(cnt: Int): Seq[Gen[(Digest32, Long)]] =
(0 until cnt).map { _ =>
for {
- id <- Digest32 @@ boxIdGen
+ id <- Digest32 @@@ boxIdGen
amt <- Gen.oneOf(1, 500, 20000, 10000000, Long.MaxValue)
} yield id -> amt
}
@@ -202,8 +202,8 @@ trait ObjectGenerators extends TypeGenerators
val unsignedShortGen: Gen[Short] = Gen.chooseNum(0, Short.MaxValue).map(_.toShort)
val contextExtensionGen: Gen[ContextExtension] = for {
- values <- Gen.sequence(contextExtensionValuesGen(0, 5))
- } yield ContextExtension(values.asScala.toMap)
+ values <- Gen.sequence(contextExtensionValuesGen(0, 5))(Buildable.buildableSeq)
+ } yield ContextExtension(values.toMap)
val serializedProverResultGen: Gen[ProverResult] = for {
length <- Gen.chooseNum(1, 100)
@@ -252,7 +252,7 @@ trait ObjectGenerators extends TypeGenerators
flags <- avlTreeFlagsGen
keyLength <- unsignedIntGen
vl <- arbOption[Int](Arbitrary(unsignedIntGen)).arbitrary
- } yield AvlTreeData(ADDigest @@ digest, flags, keyLength, vl)
+ } yield AvlTreeData(ADDigest @@@ digest, flags, keyLength, vl)
def avlTreeGen: Gen[AvlTree] = avlTreeDataGen.map(SigmaDsl.avlTree)
@@ -315,14 +315,14 @@ trait ObjectGenerators extends TypeGenerators
tId <- modifierIdGen
boxId <- unsignedShortGen
tokensCount <- Gen.chooseNum[Int](0, MaxTokens)
- tokens <- Gen.sequence(additionalTokensGen(tokensCount)).map(_.asScala.map(_._1))
+ tokens <- Gen.sequence(additionalTokensGen(tokensCount))(Buildable.buildableSeq).map(_.map(_._1))
candidate <- ergoBoxCandidateGen(tokens.toSeq)
} yield candidate.toBox(tId, boxId)
val additionalRegistersGen: Gen[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] = for {
regNum <- Gen.chooseNum[Byte](0, ErgoBox.nonMandatoryRegistersCount)
- regs <- Gen.sequence(additionalRegistersGen(regNum))
- } yield regs.asScala.toMap
+ regs <- Gen.sequence(additionalRegistersGen(regNum))(Buildable.buildableSeq)
+ } yield regs.toMap
def arrayOfN[T](n: Int, g: Gen[T])(implicit evb: Buildable[T,Array[T]]): Gen[Array[T]] = {
Gen.containerOfN[Array, T](n, g)
diff --git a/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala b/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala
index 3ce1f60473..2578553c9f 100644
--- a/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala
+++ b/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala
@@ -1,11 +1,12 @@
package sigmastate.utils
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{PropSpec, Matchers}
import sigmastate.serialization.generators.ObjectGenerators
import Helpers._
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-class HelpersTests extends PropSpec with PropertyChecks with Matchers with ObjectGenerators {
+class HelpersTests extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with ObjectGenerators {
property("xorU") {
forAll(arrayGen[Byte]) { arr =>
diff --git a/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala b/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala
index b1f6a5705f..0f6b69b78f 100644
--- a/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala
@@ -1,13 +1,14 @@
package sigmastate.utils
import org.scalacheck.{Arbitrary, Gen}
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{Matchers, PropSpec}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import sigmastate.serialization.generators.ObjectGenerators
-class SparseArrayContainerSpecification extends PropSpec
+class SparseArrayContainerSpecification extends AnyPropSpec
with ObjectGenerators
- with PropertyChecks
+ with ScalaCheckPropertyChecks
with Matchers {
private val distinctCodeValuePairsGen: Gen[Seq[(Byte, Long)]] = for {
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala
index e7abf54a0a..8d4ac696be 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala
@@ -1,6 +1,6 @@
package sigmastate.utxo
-import com.google.common.primitives.Longs
+import scorex.utils.Longs
import org.ergoplatform._
import org.ergoplatform.dsl.{ContractSpec, SigmaContractSyntax, TestContractSpec}
import scorex.crypto.authds.avltree.batch._
@@ -31,8 +31,8 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons
private val reg1 = ErgoBox.nonMandatoryRegisters(0)
private val reg2 = ErgoBox.nonMandatoryRegisters(1)
- def genKey(str: String): ADKey = ADKey @@ Blake2b256("key: " + str)
- def genValue(str: String): ADValue = ADValue @@ Blake2b256("val: " + str)
+ def genKey(str: String): ADKey = ADKey @@@ Blake2b256("key: " + str)
+ def genValue(str: String): ADValue = ADValue @@@ Blake2b256("val: " + str)
val inKey = genKey("init key")
val inValue = genValue("init value")
@@ -231,7 +231,7 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons
property("avl tree - contains key satisfying condition") {
val elements = Seq(123, 22)
- val treeElements = elements.map(i => Longs.toByteArray(i)).map(s => (ADKey @@ Blake2b256(s), ADValue @@ s))
+ val treeElements = elements.map(i => Longs.toByteArray(i)).map(s => (ADKey @@@ Blake2b256(s), ADValue @@ s))
val avlProver = new BatchAVLProver[Digest32, Blake2b256.type](keyLength = 32, None)
treeElements.foreach(s => avlProver.performOneOperation(Insert(s._1, s._2)))
avlProver.generateProof()
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala
index 11ba35d60c..d9b3453777 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala
@@ -1,6 +1,6 @@
package sigmastate.utxo
-import com.google.common.primitives.Bytes
+import scorex.utils.Bytes
import org.ergoplatform.ErgoBox.R4
import org.ergoplatform._
import org.ergoplatform.validation.ValidationException
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ProverSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ProverSpecification.scala
index d5f76503b4..88b29bac4f 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/ProverSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/ProverSpecification.scala
@@ -5,7 +5,7 @@ import scorex.crypto.hash.Blake2b256
import sigmastate.Values.SigmaBoolean
import sigmastate._
import sigmastate.basics.DLogProtocol.FirstDLogProverMessage
-import sigmastate.basics.{FirstDiffieHellmanTupleProverMessage, SecP256K1}
+import sigmastate.basics.{FirstDiffieHellmanTupleProverMessage, SecP256K1Group}
import sigmastate.helpers.{ErgoLikeTestProvingInterpreter, SigmaTestingCommons}
import sigmastate.interpreter.{HintsBag, ProverInterpreter}
import sigmastate.lang.exceptions.InterpreterException
@@ -38,7 +38,7 @@ class ProverSpecification extends SigmaTestingCommons {
val r = h.ownCommitments.head.secretRandomness
// g^r == a
- SecP256K1.exponentiate(SecP256K1.generator, r) shouldBe a.ecData
+ SecP256K1Group.exponentiate(SecP256K1Group.generator, r) shouldBe a.ecData
val h2 = prover.generateCommitmentsFor(pk3, Seq(pk))
h2.hints.size shouldBe 2
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala b/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala
index 5165517071..3bf3f0cf08 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala
@@ -1,17 +1,18 @@
package sigmastate.utxo
import org.ergoplatform._
-import org.scalatest.prop.GeneratorDrivenPropertyChecks
-import org.scalatest.{PropSpec, Matchers}
import scalan.util.BenchmarkUtil
import sigmastate.helpers.SigmaTestingCommons
-import sigmastate.interpreter.{ProverResult, ContextExtension}
+import sigmastate.interpreter.{ContextExtension, ProverResult}
import sigmastate.serialization.generators.ObjectGenerators
import debox.{Buffer => DBuffer}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
import sigmastate.util.{MaxArrayLength, safeNewArray}
-class SerializationRoundTripSpec extends PropSpec
- with GeneratorDrivenPropertyChecks
+class SerializationRoundTripSpec extends AnyPropSpec
+ with ScalaCheckDrivenPropertyChecks
with Matchers
with ObjectGenerators
with SigmaTestingCommons {
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala
index ecf843efe1..17de1cd96f 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala
@@ -26,7 +26,7 @@ case class AssetsAtomicExchange[Spec <: ContractSpec]
lazy val buyerProp = proposition("buyer", { ctx: Context =>
import ctx._
- (HEIGHT > deadline && pkA) || {
+ (HEIGHT > deadline && pkA) || sigmaProp({
val tokenData = OUTPUTS(0).R2[Coll[(Coll[Byte], Long)]].get(0)
val knownId = OUTPUTS(0).R4[Coll[Byte]].get == SELF.id
allOf(Coll(
@@ -35,7 +35,7 @@ case class AssetsAtomicExchange[Spec <: ContractSpec]
OUTPUTS(0).propositionBytes == pkA.propBytes,
knownId
))
- }
+ })
},
"""{
| (HEIGHT > deadline && pkA) || {
@@ -52,14 +52,14 @@ case class AssetsAtomicExchange[Spec <: ContractSpec]
lazy val sellerProp = proposition("seller", {ctx: Context =>
import ctx._
- (HEIGHT > deadline && pkB) || {
+ (HEIGHT > deadline && pkB) || sigmaProp({
val knownBoxId = OUTPUTS(1).R4[Coll[Byte]].get == SELF.id
allOf(Coll(
OUTPUTS(1).value >= 100L,
knownBoxId,
OUTPUTS(1).propositionBytes == pkB.propBytes
))
- }
+ })
},
"""{
| (HEIGHT > deadline && pkB) ||
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala
index 5724ac2fe4..448f9e4801 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala
@@ -21,7 +21,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec]
lazy val buyerProp = proposition("buyer", { ctx: Context =>
import ctx._
- (HEIGHT > deadline && pkA) || {
+ (HEIGHT > deadline && pkA) || sigmaProp({
val outIdx = getVar[Short](127).get
val out = OUTPUTS(outIdx)
@@ -38,7 +38,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec]
out.propositionBytes == pkA.propBytes,
out.R4[Coll[Byte]].get == SELF.id
))
- }
+ })
},
"""(HEIGHT > deadline && pkA) || {
|
@@ -62,7 +62,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec]
lazy val sellerProp = proposition("seller", {ctx: Context =>
import ctx._
- (HEIGHT > deadline && pkB) || {
+ (HEIGHT > deadline && pkB) || sigmaProp({
val outIdx = getVar[Short](127).get
val out = OUTPUTS(outIdx)
@@ -88,7 +88,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec]
outR4 == SELF.id,
out.propositionBytes == pkB.propBytes
))
- }
+ })
},
""" (HEIGHT > deadline && pkB) || {
| val outIdx = getVar[Short](127).get
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala
index cba2d96e96..9b585a823b 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala
@@ -2,9 +2,8 @@ package sigmastate.utxo.examples
import org.ergoplatform._
import org.ergoplatform.settings.ErgoAlgos
-import scorex.util.ScorexLogging
-import sigmastate.Values.{ErgoTree, IntConstant}
-import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons}
+import sigmastate.Values.{BlockValue, ErgoTree, IntConstant, LongConstant, ValDef, ValUse}
+import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaPPrint, SigmaTestingCommons}
import sigmastate.helpers.TestingHelpers._
import sigmastate.interpreter.ContextExtension
import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv}
@@ -22,7 +21,7 @@ import sigmastate.eval._
* defined in ErgoScriptPredef.
*/
class CoinEmissionSpecification extends SigmaTestingCommons
- with ScorexLogging with CrossVersionProps {
+ with CrossVersionProps {
// don't use TestingIRContext, this suite also serves the purpose of testing the RuntimeIRContext
implicit lazy val IR: TestingIRContext = new TestingIRContext {
// uncomment if you want to log script evaluation
@@ -30,6 +29,10 @@ class CoinEmissionSpecification extends SigmaTestingCommons
saveGraphsInFile = false
}
+ protected def logMessage(msg: String) = {
+ println(msg)
+ }
+
private val reg1 = ErgoBox.nonMandatoryRegisters.head
private val coinsInOneErgo: Long = 100000000
@@ -90,7 +93,7 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661
val register = reg1
val prover = new ContextEnrichingTestProvingInterpreter()
- val rewardOut = ByIndex(Outputs, IntConstant(0))
+ val rewardOut = ValUse(1, SBox)
val epoch =
Upcast(
@@ -103,14 +106,24 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661
)
val sameScriptRule = EQ(ExtractScriptBytes(Self), ExtractScriptBytes(rewardOut))
val heightCorrect = EQ(ExtractRegisterAs[SInt.type](rewardOut, register).get, Height)
- val heightIncreased = GT(Height, ExtractRegisterAs[SInt.type](Self, register).get)
- val correctCoinsConsumed = EQ(coinsToIssue, Minus(ExtractAmount(Self), ExtractAmount(rewardOut)))
- val lastCoins = LE(ExtractAmount(Self), s.oneEpochReduction)
-
- val prop = BinOr(
- AND(heightCorrect, heightIncreased, sameScriptRule, correctCoinsConsumed),
- BinAnd(heightIncreased, lastCoins)
- ).toSigmaProp
+ val correctCoinsConsumed = EQ(
+ coinsToIssue,
+ Minus(ValUse(3, SLong), ExtractAmount(rewardOut))
+ )
+
+ val prop = BlockValue(
+ Array(
+ ValDef(1, List(), ByIndex(Outputs, IntConstant(0), None)),
+ ValDef(2, List(), GT(Height, OptionGet(ExtractRegisterAs(Self, ErgoBox.R4, SOption(SInt))))),
+ ValDef(3, List(), ExtractAmount(Self))
+ ),
+ BoolToSigmaProp(BinOr(
+ AND(heightCorrect, ValUse(2, SBoolean), sameScriptRule, correctCoinsConsumed),
+ BinAnd(
+ ValUse(2, SBoolean),
+ LE(ValUse(3, SLong), LongConstant(s.oneEpochReduction)))
+ ))
+ ).asSigmaProp
val tree = mkTestErgoTree(prop)
val env = Map("fixedRatePeriod" -> s.fixedRatePeriod,
@@ -118,7 +131,7 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661
"fixedRate" -> s.fixedRate,
"oneEpochReduction" -> s.oneEpochReduction)
- val prop1 = compileWithoutCosting(env,
+ val prop1 = compile(env,
"""{
| val epoch = 1 + ((HEIGHT - fixedRatePeriod) / epochLength)
| val out = OUTPUTS(0)
@@ -208,7 +221,7 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661
val newEmissionBox = newState.boxesReader.byId(tx.outputs.head.id).get
chainGen(newState, newEmissionBox, height + 1, hLimit)
} else {
- log.debug(s"Emission box is consumed at height $height")
+ logMessage(s"Emission box is consumed at height $height")
}
}
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala
index 8e3e015d7d..ebbf021fb8 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala
@@ -25,7 +25,7 @@ case class CrowdFunding[Spec <: ContractSpec]
}
val fundraisingSuccess = HEIGHT < deadline &&
pkProject &&
- OUTPUTS.exists(enoughRaised)
+ sigmaProp(OUTPUTS.exists(enoughRaised))
fundraisingFailure || fundraisingSuccess
},
@@ -52,9 +52,9 @@ case class CrowdFunding[Spec <: ContractSpec]
val c1 = HEIGHT >= deadline && pkBacker
val c2 =
HEIGHT < deadline && pkProject &&
- OUTPUTS.exists({ (out: Box) =>
+ sigmaProp(OUTPUTS.exists({ (out: Box) =>
out.value >= minToRaise && out.propositionBytes == pkProject.propBytes
- })
+ }))
c1 || c2
},
"""
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala
index 8cd017d6e9..657beb98ab 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala
@@ -35,7 +35,7 @@ class DHTupleExampleSpecification extends SigmaTestingCommons
val x:BigInteger = alice.dlogSecrets.head.w // x is Alice's private key
- val g_x = alicePubKey.h // g_x is Alice's public key (g_x = g^x)
+ val g_x = alicePubKey.value // g_x is Alice's public key (g_x = g^x)
val env = Map(
ScriptNameProp -> "env",
@@ -63,7 +63,7 @@ class DHTupleExampleSpecification extends SigmaTestingCommons
val y:BigInteger = bob.dlogSecrets.head.w // y is Bob's private key
val bobPubKey: ProveDlog = bob.dlogSecrets.head.publicImage
- val g_y = GroupElementConstant(bobPubKey.h) // Bob's public key g^y
+ val g_y = GroupElementConstant(bobPubKey.value) // Bob's public key g^y
val g_xy = GroupElementConstant(dlogGroup.exponentiate(g_x, y)) // g^xy
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala
index 2a2f2b2f7b..8e1cf9936a 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala
@@ -31,7 +31,7 @@ class DummyExamplesSpecification extends SigmaTestingCommons { suite =>
}
def getRoot(item: Coll[Byte]):Coll[Byte] = path.foldLeft(item, xor)
- pkA && getRoot(oldItem) == oldRoot && getRoot(newItem) == newRoot
+ pkA && sigmaProp(getRoot(oldItem) == oldRoot) && sigmaProp(getRoot(newItem) == newRoot)
val dummy = Coll[Byte]()
val isValid = {(b:Box) => b.propositionBytes == dummy}
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala
index 790cf69afc..5b47961119 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala
@@ -1,6 +1,6 @@
package sigmastate.utxo.examples
-import com.google.common.primitives.Longs
+import scorex.utils.Longs
import org.ergoplatform.ErgoBox.{R4, R5}
import org.ergoplatform._
import org.ergoplatform.dsl.TestContractSpec
@@ -440,7 +440,7 @@ class IcoExample extends SigmaTestingCommons
val projectBoxBeforeClosing = testBox(10, issuanceTree, 0, Seq(),
Map(R4 -> ByteArrayConstant(Array.emptyByteArray), R5 -> AvlTreeConstant(openTreeData)))
- val tokenId = Digest32 @@ projectBoxBeforeClosing.id
+ val tokenId = Digest32 @@@ projectBoxBeforeClosing.id
val closedTreeData = SigmaDsl.avlTree(new AvlTreeData(digest, AvlTreeFlags.RemoveOnly, 32, None))
val projectBoxAfterClosing = testBox(1, withdrawalTree, 0,
@@ -481,7 +481,7 @@ class IcoExample extends SigmaTestingCommons
}
funderKvs.foreach { case (k, v) =>
- avlProver.performOneOperation(Insert(ADKey @@ k, ADValue @@ v))
+ avlProver.performOneOperation(Insert(ADKey @@@ k, ADValue @@ v))
}
val digest = avlProver.digest
val fundersTree = new AvlTreeData(digest, AvlTreeFlags.RemoveOnly, 32, None)
@@ -492,12 +492,12 @@ class IcoExample extends SigmaTestingCommons
avlProver.generateProof()
withdrawals.foreach { case (k, _) =>
- avlProver.performOneOperation(Lookup(ADKey @@ k))
+ avlProver.performOneOperation(Lookup(ADKey @@@ k))
}
val lookupProof = avlProver.generateProof()
withdrawals.foreach { case (k, _) =>
- avlProver.performOneOperation(Remove(ADKey @@ k))
+ avlProver.performOneOperation(Remove(ADKey @@@ k))
}
val removalProof = avlProver.generateProof()
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala
index 2639522f64..63182e2a1a 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala
@@ -291,9 +291,9 @@ class LetsSpecification extends SigmaTestingCommons with CrossVersionProps { sui
R4 -> AvlTreeConstant(SigmaDsl.avlTree(initTreeData)),
R5 -> SigmaPropConstant(TrivialProp.TrueProp)))
- val userTokenId = Digest32 @@ projectBoxBefore.id
+ val userTokenId = Digest32 @@@ projectBoxBefore.id
- avlProver.performOneOperation(Insert(ADKey @@ userTokenId, ADValue @@ Array.emptyByteArray))
+ avlProver.performOneOperation(Insert(ADKey @@@ userTokenId, ADValue @@ Array.emptyByteArray))
val proof = avlProver.generateProof()
val endTree = new AvlTreeData(avlProver.digest, AvlTreeFlags.InsertOnly, 32, None)
@@ -330,14 +330,14 @@ class LetsSpecification extends SigmaTestingCommons with CrossVersionProps { sui
val userTokenId1 = Digest32 @@ Array.fill(32)(Random.nextInt(100).toByte)
val avlProver = new BatchAVLProver[Digest32, Blake2b256.type](keyLength = 32, None)
- avlProver.performOneOperation(Insert(ADKey @@ userTokenId0, ADValue @@ Array.emptyByteArray))
- avlProver.performOneOperation(Insert(ADKey @@ userTokenId1, ADValue @@ Array.emptyByteArray))
+ avlProver.performOneOperation(Insert(ADKey @@@ userTokenId0, ADValue @@ Array.emptyByteArray))
+ avlProver.performOneOperation(Insert(ADKey @@@ userTokenId1, ADValue @@ Array.emptyByteArray))
val digest = avlProver.digest
avlProver.generateProof()
val initTreeData = new AvlTreeData(digest, AvlTreeFlags.InsertOnly, 32, None)
- avlProver.performOneOperation(Lookup(ADKey @@ userTokenId0))
- avlProver.performOneOperation(Lookup(ADKey @@ userTokenId1))
+ avlProver.performOneOperation(Lookup(ADKey @@@ userTokenId0))
+ avlProver.performOneOperation(Lookup(ADKey @@@ userTokenId1))
val proof = avlProver.generateProof()
val managementTree = mkTestErgoTree(managementScript)
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala
index 3a5d28b45c..2de3395431 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala
@@ -83,7 +83,7 @@ class MASTExampleSpecification extends SigmaTestingCommons
val allSecrets = (0 until 5).map(_ => Random.nextString(32).getBytes("UTF-8"))
val scriptBranches = allSecrets.map(s => EQ(ByteArrayConstant(s), GetVarByteArray(secretId).get))
val scriptBranchesBytes = scriptBranches.map(b => ValueSerializer.serialize(b))
- val treeElements: Seq[(ADKey, ADValue)] = scriptBranchesBytes.map(s => (ADKey @@ Blake2b256(s), ADValue @@ s))
+ val treeElements: Seq[(ADKey, ADValue)] = scriptBranchesBytes.map(s => (ADKey @@@ Blake2b256(s), ADValue @@ s))
val knownSecretTreeKey = treeElements.head._1
val knownSecret = ByteArrayConstant(allSecrets.head)
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala
index b626751312..99806ca35b 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala
@@ -30,7 +30,7 @@ class MixExampleSpecification extends SigmaTestingCommons
val x: BigInteger = alice.dlogSecrets.head.w // x is Alice's private key
- val gX = alicePubKey.h // g_x is Alice's public key (g_x = g^x)
+ val gX = alicePubKey.value // g_x is Alice's public key (g_x = g^x)
// Alternative 1:
// val g_x = alicePubKey.value
// Alternative 2:
@@ -118,7 +118,7 @@ class MixExampleSpecification extends SigmaTestingCommons
val y: BigInteger = bob.dlogSecrets.head.w // y is Bob's private key
- val gY = GroupElementConstant(bobPubKey.h) // g^y
+ val gY = GroupElementConstant(bobPubKey.value) // g^y
val gY_alt = GroupElementConstant(dlogGroup.exponentiate(g, y))
gY shouldBe gY_alt
diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala
index 3774e5ddc2..5ec589587f 100644
--- a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala
+++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala
@@ -2,7 +2,7 @@ package sigmastate.utxo.examples
import java.security.SecureRandom
-import com.google.common.primitives.Longs
+import scorex.utils.Longs
import org.ergoplatform.ErgoBox.RegisterId
import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Lookup}
import scorex.crypto.authds.{ADKey, ADValue}
@@ -114,7 +114,7 @@ class OracleExamplesSpecification extends SigmaTestingCommons
val avlProver = new BatchAVLProver[Digest32, Blake2b256.type](keyLength = 32, None)
- avlProver.performOneOperation(Insert(ADKey @@ oracleBox.id, ADValue @@ oracleBox.bytes))
+ avlProver.performOneOperation(Insert(ADKey @@@ oracleBox.id, ADValue @@ oracleBox.bytes))
avlProver.generateProof()
val lastBlockUtxoDigest = avlProver.digest
@@ -153,7 +153,7 @@ class OracleExamplesSpecification extends SigmaTestingCommons
),
contractLogic)
- avlProver.performOneOperation(Lookup(ADKey @@ oracleBox.id))
+ avlProver.performOneOperation(Lookup(ADKey @@@ oracleBox.id))
val proof = avlProver.generateProof()
val newBox1 = testBox(20, alicePubKey, 0, boxIndex = 2)
diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala
index 5b6b29b665..0e0b50dacd 100644
--- a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala
+++ b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala
@@ -3949,15 +3949,6 @@ class SigmaDslSpecification extends SigmaDslTesting
FuncValue(Vector((1, SByteArray)), ByteArrayToLong(ValUse(1, SByteArray)))))
}
- // TODO soft-fork: related to https://github.com/ScorexFoundation/sigmastate-interpreter/issues/427
- // TODO costing: expression t._1(t._2) cannot be costed because t is lambda argument
- // ignore("Func context variable") {
- // val doApply = checkEq(func[(Int => Int, Int), Int]("{ (t: (Int => Int, Int)) => t._1(t._2) }")) { (t: (Int => Int, Int)) => t._1(t._2) }
- // val code = compileWithCosting(emptyEnv, s"{ (x: Int) => x + 1 }")
- // val ctx = ErgoLikeContext.dummy(fakeSelf)
- // doApply((CFunc[Int, Int](ctx, code), 10))
- // }
-
property("Box properties equivalence") {
verifyCases(
{
diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala
index 9a25237682..1b93729e93 100644
--- a/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala
+++ b/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala
@@ -48,7 +48,8 @@ class SigmaDslStaginTests extends BaseCtxTests with ErgoScriptTestkit with BaseL
cake.check(boxA1, { env: EnvRep[RBox] => for { obj <- env; arg <- lifted(1) } yield obj.getReg[Coll[Byte]](arg) }, boxA1.getReg[special.collection.Coll[Byte]](1))
cake.check(boxA1, { env: EnvRep[RBox] => for { obj <- env } yield obj.registers }, boxA1.registers)
- cake.check(p1, { env: EnvRep[RSigmaProp] => for { p1 <- env; arg <- lifted(true) } yield p1 && arg }, p1 && true)
- cake.check(p1, { env: EnvRep[RSigmaProp] => for { p1 <- env; arg <- lifted(p2) } yield p1 && arg }, p1 && p2)
+ cake.check(p1, { env: EnvRep[RSigmaProp] =>
+ for { p1 <- env; arg <- lifted(p2) } yield p1 && arg
+ }, p1 && p2)
}
}
diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala
index 664f3ec64a..281355ccd2 100644
--- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala
+++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala
@@ -9,8 +9,6 @@ import org.scalacheck.Arbitrary._
import org.scalacheck.Gen.frequency
import org.scalacheck.{Arbitrary, Gen}
import org.scalatest.exceptions.TestFailedException
-import org.scalatest.prop.PropertyChecks
-import org.scalatest.{Matchers, PropSpec}
import scalan.RType
import scalan.RType._
import scalan.util.BenchmarkUtil
@@ -35,14 +33,17 @@ import sigmastate.utxo.{DeserializeContext, DeserializeRegister, GetVar, OptionG
import sigmastate.{SOption, SSigmaProp, SType, VersionContext, eval}
import special.collection.{Coll, CollType}
import debox.cfor
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.propspec.AnyPropSpec
+import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import java.util
import scala.collection.mutable
import scala.reflect.ClassTag
import scala.util.{Failure, Success, Try}
-class SigmaDslTesting extends PropSpec
- with PropertyChecks
+class SigmaDslTesting extends AnyPropSpec
+ with ScalaCheckPropertyChecks
with Matchers
with SigmaTestingData with SigmaContractSyntax
with ObjectGenerators { suite =>