From 7301cee157d8b156f1968a7fb9a2060b83ddf2f0 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 15:10:29 +0200 Subject: [PATCH 01/64] v5.x-restructure: FullReductionResult removed --- .../interpreter/ErgoTreeEvaluator.scala | 6 +- .../sigmastate/interpreter/Interpreter.scala | 55 ++++++------------- .../interpreter/ProverInterpreter.scala | 2 +- 3 files changed, 21 insertions(+), 42 deletions(-) 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 9e328a05ff..d7615c0d2a 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -147,9 +147,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] @@ -160,7 +160,7 @@ trait Interpreter extends ScorexLogging { } } - JitReductionResult(SigmaDsl.toSigmaBoolean(resProp), cost.toLong) + ReductionResult(SigmaDsl.toSigmaBoolean(resProp), cost.toLong) } } @@ -181,7 +181,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) { @@ -194,14 +194,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) } @@ -213,7 +212,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) } @@ -221,9 +220,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 (propTree, context2) = trySoftForkable[(SigmaPropValue, CTX)](whenSoftFork = (TrueSigmaProp, context)) { applyDeserializeContextJITC(context, prop) } @@ -233,7 +232,7 @@ trait Interpreter extends ScorexLogging { reduceToCryptoJITC(context2, env, propTree).getOrThrow } - FullReductionResult(jitRes) + res } /** Adds the cost to verify sigma protocol proposition. @@ -244,7 +243,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 @@ -337,7 +336,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) @@ -345,7 +344,7 @@ trait Interpreter extends ScorexLogging { } else { verifySignature(reduced.value, message, proof)(null) } - (ok, fullJitCost) + (ok, fullCost) } } } @@ -458,34 +457,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] @@ -499,7 +478,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..bc2f0c5ffd 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -129,7 +129,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) } From bad93b290f670b5cff9012f056531311fcdddc1a Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 17:00:31 +0200 Subject: [PATCH 02/64] v5.x-restructure: commons-io dependency removed --- build.sbt | 3 +- .../src/main/scala/scalan/util/FileUtil.scala | 73 +------------------ 2 files changed, 2 insertions(+), 74 deletions(-) diff --git a/build.sbt b/build.sbt index 17c443832f..2dfd6c5235 100644 --- a/build.sbt +++ b/build.sbt @@ -59,7 +59,6 @@ val debox = "org.scorexfoundation" %% "debox" % "0.9.0" val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" val kiama = "org.bitbucket.inkytonik.kiama" %% "kiama" % "2.5.0" 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" @@ -146,7 +145,7 @@ lazy val common = Project("common", file("common")) .settings(commonSettings ++ testSettings, libraryDependencies ++= Seq( "org.scala-lang" % "scala-reflect" % scalaVersion.value, - debox, commonsIo, scalaCompat + debox, scalaCompat )) .settings(publish / skip := true) diff --git a/common/src/main/scala/scalan/util/FileUtil.scala b/common/src/main/scala/scalan/util/FileUtil.scala index 56e138e85f..895c99e4b4 100644 --- a/common/src/main/scala/scalan/util/FileUtil.scala +++ b/common/src/main/scala/scalan/util/FileUtil.scala @@ -6,15 +6,13 @@ 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 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 +51,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 +93,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 +165,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 => From 499c24eea0a1b2dd1f7be62423db3fc192b2c8e9 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 17:02:59 +0200 Subject: [PATCH 03/64] v5.x-restructure: commons-math dependency removed --- build.sbt | 3 +-- common/src/main/scala/scalan/util/FileUtil.scala | 3 --- sigmastate/src/main/scala/sigmastate/eval/Profiler.scala | 3 +-- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/build.sbt b/build.sbt index 2dfd6c5235..f2015309ac 100644 --- a/build.sbt +++ b/build.sbt @@ -59,7 +59,6 @@ val debox = "org.scorexfoundation" %% "debox" % "0.9.0" val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" val kiama = "org.bitbucket.inkytonik.kiama" %% "kiama" % "2.5.0" val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" -val commonsMath3 = "org.apache.commons" % "commons-math3" % "3.2" val scalaCompat = "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0" val testingDependencies = Seq( @@ -201,7 +200,7 @@ lazy val sigmastate = (project in file("sigmastate")) .dependsOn(sigmalibrary % allConfigDependency) .settings(libraryDefSettings) .settings(libraryDependencies ++= Seq( - scorexUtil, kiama, fastparse, commonsMath3, + scorexUtil, kiama, fastparse, if (scalaVersion.value == scala211) circeCore211 else circeCore, if (scalaVersion.value == scala211) circeGeneric211 else circeGeneric, if (scalaVersion.value == scala211) circeParser211 else circeParser diff --git a/common/src/main/scala/scalan/util/FileUtil.scala b/common/src/main/scala/scalan/util/FileUtil.scala index 895c99e4b4..89a596ed28 100644 --- a/common/src/main/scala/scalan/util/FileUtil.scala +++ b/common/src/main/scala/scalan/util/FileUtil.scala @@ -2,11 +2,8 @@ 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 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") From 0be6c5872d8f555cbafd0f1090653a40a89c7484 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 18:11:55 +0200 Subject: [PATCH 04/64] v5.x-restructure: junit-interface removed --- build.sbt | 3 +-- docs/notes.md | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index f2015309ac..7c3d8d810b 100644 --- a/build.sbt +++ b/build.sbt @@ -67,8 +67,7 @@ val testingDependencies = Seq( "org.scalacheck" %% "scalacheck" % "1.14.3" % Test, "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( diff --git a/docs/notes.md b/docs/notes.md index 059336de58..ca4999e0ca 100644 --- a/docs/notes.md +++ b/docs/notes.md @@ -12,8 +12,6 @@ These dependencies can be removed with refactoring | - 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 | From 70cbe6914b62d1760b33cc3c4350e17000fe1516 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 18:17:20 +0200 Subject: [PATCH 05/64] v5.x-restructure: SigmaPrinter.scala removed --- .../scala/sigmastate/lang/SigmaPrinter.scala | 92 ------------------- 1 file changed, 92 deletions(-) delete mode 100644 sigmastate/src/main/scala/sigmastate/lang/SigmaPrinter.scala 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 From 9c306fdad8f392cdbec56f82c0675bbc9f496485 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 18:56:34 +0200 Subject: [PATCH 06/64] v5.x-restructure: avoid using kiama.attribution.UncachedAttribution.attr --- .../main/scala/sigmastate/interpreter/ProverInterpreter.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index bc2f0c5ffd..44d34a6c8c 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -1,7 +1,6 @@ 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 scalan.util.CollectionUtil._ @@ -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 => From 20efb844d528e70de3ee744a4025a017df98fc7b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 18:57:09 +0200 Subject: [PATCH 07/64] v5.x-restructure: avoid using compileWithoutCosting --- .../examples/CoinEmissionSpecification.scala | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index cba2d96e96..de71cb6007 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -3,8 +3,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} @@ -90,7 +90,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 +103,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 +128,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) From a632918ff828e2477c4b92b53bb22fa76e57b00f Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 21:05:08 +0200 Subject: [PATCH 08/64] v5.x-restructure: removed SigmaSpecializer --- .../scala/sigmastate/lang/SigmaCompiler.scala | 7 - .../sigmastate/lang/SigmaSpecializer.scala | 169 ------------- .../src/test/scala/sigmastate/TestsBase.scala | 3 - .../sigmastate/lang/SigmaCompilerTest.scala | 8 - .../lang/SigmaSpecializerTest.scala | 229 ------------------ 5 files changed, 416 deletions(-) delete mode 100644 sigmastate/src/main/scala/sigmastate/lang/SigmaSpecializer.scala delete mode 100644 sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala index 6cc5bd3425..53f12a7cb2 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala @@ -70,13 +70,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/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/test/scala/sigmastate/TestsBase.scala b/sigmastate/src/test/scala/sigmastate/TestsBase.scala index 3cb378e7ec..829054c32c 100644 --- a/sigmastate/src/test/scala/sigmastate/TestsBase.scala +++ b/sigmastate/src/test/scala/sigmastate/TestsBase.scala @@ -65,9 +65,6 @@ trait TestsBase extends Matchers with VersionTesting { } } - def compileWithoutCosting(env: ScriptEnv, code: String): Value[SType] = - compiler.compileWithoutCosting(env, code) - def compile(env: ScriptEnv, code: String)(implicit IR: IRContext): Value[SType] = { val res = compiler.compile(env, code) checkCompilerResult(res) diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala index ec9a528635..2ed1b0f7cf 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/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)))) - } -} From 0b38ffd7df8f6932d6c21d9982b5c25873b04781 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 3 Sep 2022 21:54:21 +0200 Subject: [PATCH 09/64] v5.x-restructure: avoid traversal and usage of kiama --- .../src/main/scala/scalan/util/Extensions.scala | 8 +++++++- .../main/scala/sigmastate/lang/SigmaTyper.scala | 17 ++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/common/src/main/scala/scalan/util/Extensions.scala b/common/src/main/scala/scalan/util/Extensions.scala index d144d6dc96..47403055de 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,11 @@ object Extensions { None } } + + implicit final class Ensuring[A](private val self: A) extends AnyVal { + def ensuring(cond: A => Boolean, msg: A => Any): A = { + assert(cond(self), msg(self)) + self + } + } } diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala index 60ac7c04f0..8cfc0f651c 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala @@ -7,13 +7,13 @@ 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 } } From 0ed957d65164ad7019ba52d4d8c8fced04dc4f8b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 4 Sep 2022 21:46:20 +0200 Subject: [PATCH 10/64] v5.x-restructure: removed kiama dependency and replaced with sigmastate.kiama package --- build.sbt | 8 +- .../main/scala/sigmastate/kiama/kiama.scala | 29 + .../kiama/rewriting/CallbackRewriter.scala | 71 + .../kiama/rewriting/PlusStrategy.scala | 42 + .../sigmastate/kiama/rewriting/Rewriter.scala | 1643 +++++++++++++++++ .../sigmastate/kiama/rewriting/Strategy.scala | 94 + .../sigmastate/kiama/util/Collections.scala | 42 + .../sigmastate/kiama/util/Comparison.scala | 145 ++ .../src/main/scala/sigmastate/Values.scala | 2 +- .../sigmastate/interpreter/Interpreter.scala | 4 +- .../interpreter/ProverInterpreter.scala | 4 +- .../scala/sigmastate/lang/SigmaBinder.scala | 2 +- .../scala/sigmastate/lang/SigmaCompiler.scala | 2 +- .../scala/sigmastate/lang/SigmaTyper.scala | 2 +- .../main/scala/sigmastate/lang/Terms.scala | 2 +- .../scala/sigmastate/lang/LangTests.scala | 2 +- 16 files changed, 2080 insertions(+), 14 deletions(-) create mode 100644 common/src/main/scala/sigmastate/kiama/kiama.scala create mode 100644 common/src/main/scala/sigmastate/kiama/rewriting/CallbackRewriter.scala create mode 100644 common/src/main/scala/sigmastate/kiama/rewriting/PlusStrategy.scala create mode 100644 common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala create mode 100644 common/src/main/scala/sigmastate/kiama/rewriting/Strategy.scala create mode 100644 common/src/main/scala/sigmastate/kiama/util/Collections.scala create mode 100644 common/src/main/scala/sigmastate/kiama/util/Comparison.scala diff --git a/build.sbt b/build.sbt index 7c3d8d810b..569636568d 100644 --- a/build.sbt +++ b/build.sbt @@ -57,8 +57,8 @@ 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" -val kiama = "org.bitbucket.inkytonik.kiama" %% "kiama" % "2.5.0" val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" +val guava = "com.google.guava" % "guava" % "30.1.1-jre" val scalaCompat = "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0" val testingDependencies = Seq( @@ -83,7 +83,7 @@ libraryDependencies ++= Seq( scrypto, scorexUtil, "org.bouncycastle" % "bcprov-jdk15on" % "1.+", - kiama, fastparse, debox, spireMacros, scalaCompat + fastparse, debox, spireMacros, scalaCompat ) ++ testingDependencies lazy val circeCore211 = "io.circe" %% "circe-core" % "0.10.0" @@ -143,7 +143,7 @@ lazy val common = Project("common", file("common")) .settings(commonSettings ++ testSettings, libraryDependencies ++= Seq( "org.scala-lang" % "scala-reflect" % scalaVersion.value, - debox, scalaCompat + debox, scalaCompat, guava )) .settings(publish / skip := true) @@ -199,7 +199,7 @@ lazy val sigmastate = (project in file("sigmastate")) .dependsOn(sigmalibrary % allConfigDependency) .settings(libraryDefSettings) .settings(libraryDependencies ++= Seq( - scorexUtil, kiama, fastparse, + scorexUtil, fastparse, if (scalaVersion.value == scala211) circeCore211 else circeCore, if (scalaVersion.value == scala211) circeGeneric211 else circeGeneric, if (scalaVersion.value == scala211) circeParser211 else circeParser 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..301166a12b --- /dev/null +++ b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala @@ -0,0 +1,1643 @@ +/* + * 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 + +/** + * 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 org.bitbucket.inkytonik.kiama.relation.{EnsureTree, Tree, TreeShape} + import sigmastate.kiama.util.Collections.{CanBuildFrom, Factory, newBuilder} + import sigmastate.kiama.util.Comparison.same +// import org.bitbucket.inkytonik.kiama.util.{Emitter, OutputEmitter} + import scala.collection.immutable.Seq + + /** + * 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 + } + } + + /** + * Rewrite a tree. Apply the strategy `s` to the root of a tree returning the + * a tree formed from the result term if `s` succeeds, otherwise return the + * original tree. + * + * The `shape` parameter specifies the tree shape that should be used + * when creating the new tree. The default is `EnsureTree` since it is + * likely that rewrites will result in node sharing that should be removed. + */ +// def rewriteTree[T <: AnyRef with Product, U <: T](s : Strategy)(t : Tree[T, U], shape : TreeShape = EnsureTree) : Tree[T, U] = { +// s(t.root) match { +// case Some(t1) => +// new Tree[T, U](t1.asInstanceOf[U], shape) +// 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 succeeds with the subject term unchanged (i.e., + * this is the identity strategy) with the side-effect that the subject + * term is printed to the given emitter, prefixed by the string `s`. The + * emitter defaults to one that writes to standard output. + */ +// def debug(msg : String, emitter : Emitter = new OutputEmitter) : Strategy = +// strategyf(t => { emitter.emitln(msg + t); Some(t) }) + + /** + * A strategy that always fails. + */ + val fail : Strategy = + mkStrategy(_ => None) + + /** + * A strategy that always succeeds. + */ + val id : Strategy = + mkStrategy(Some(_)) + + /** + * Create a logging strategy based on a strategy `s`. The returned strategy + * succeeds or fails exactly as `s` does, but also prints the provided message, + * the subject term, the success or failure status, and on success, the result + * term, to the provided emitter. `s` is evaluated at most once. + */ +// def log(s : Strategy, msg : String, emitter : Emitter) : Strategy = { +// lazy val strat = s +// mkStrategy( +// t1 => { +// emitter.emit(msg + t1) +// val r = strat(t1) +// r match { +// case Some(t2) => +// emitter.emitln(s" succeeded with $t2") +// case None => +// emitter.emitln(" failed") +// } +// r +// } +// ) +// } + + /** + * Create a logging strategy based on a strategy `s`. The returned strategy + * succeeds or fails exactly as `s` does, but if `s` fails, also prints the + * provided message and the subject term to the provided emitter. `s` is + * evaluated at most once. + */ +// def logfail[T](s : Strategy, msg : String, emitter : Emitter) : Strategy = { +// lazy val strat = s +// mkStrategy( +// t1 => { +// val r = strat(t1) +// r match { +// case Some(t2) => +// // Do nothing +// case None => +// emitter.emitln(s"$msg$t1 failed") +// } +// r +// } +// ) +// } + + /** + * Return a strategy that behaves as `s` does, but memoises its arguments and + * results. In other words, if `memo(s)` is called on a term `t` twice, the + * second time will return the same result as the first, without having to + * invoke `s`. For best results, it is important that `s` should have no side + * effects. `s` is evaluated at most once. + */ +// def memo(s : Strategy) : Strategy = { +// +// import com.google.common.base.Function +// import com.google.common.cache.{CacheBuilder, CacheLoader} +// +// lazy val strat = s +// +// val cache = +// CacheBuilder.newBuilder.build[AnyRef, Option[Any]]( +// CacheLoader.from( +// new Function[AnyRef, Option[Any]] { +// def apply(t : AnyRef) : Option[Any] = +// strat(t) +// } +// ) +// ) +// +// mkStrategy(t => cache.get(t.asInstanceOf[AnyRef])) +// +// } + + /** + * Construct a strategy from an option value `o`. The strategy succeeds + * or fails depending on whether `o` is a Some or None, respectively. + * If `o` is a `Some`, then the subject term is changed to the term that + * is wrapped by the `Some`. `o` is evaluated at most once. + */ + def option(o : Option[Any]) : Strategy = + strategyf(_ => o) + + /** + * 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 term query by a function `f`. The query always succeeds with + * no effect on the subject term but applies the given (possibly partial) + * function `f` to the subject term. In other words, the strategy runs + * `f` for its side-effects. + */ + def queryf(f : Any => Unit) : Strategy = + mkStrategy( + t => { + f(t) + Some(t) + } + ) + + /** + * 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 com.google.common.base.Function + import com.google.common.cache.{CacheBuilder, CacheLoader} + import java.lang.{Class, IllegalArgumentException, NoSuchFieldException} + import java.lang.reflect.Constructor + + type Duper = (Any, Array[AnyRef]) => Any + + object MakeDuper extends Function[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 + } + + } + + val cache = CacheBuilder.newBuilder.weakKeys.build( + CacheLoader.from(MakeDuper) + ) + + def apply[T <: Product](t : T, children : Array[AnyRef]) : T = { + val duper = cache.get(t.getClass) + 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 r : Rewritable => +// allRewritable(strat, r) + 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 `Rewritable` values. + */ +// def allRewritable(s : Strategy, r : Rewritable) : Option[Any] = { +// val numchildren = r.arity +// if (numchildren == 0) +// Some(r) +// else { +// val newchildren = Seq.newBuilder[Any] +// val changed = +// r.deconstruct.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(r.reconstruct(newchildren.result())) +// else +// Some(r) +// } +// } + + /** + * 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 r : Rewritable => +// oneRewritable(strat, r) + 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 `Rewritable` values. + */ +// def oneRewritable(s : Strategy, r : Rewritable) : Option[Any] = { +// val children = r.deconstruct +// children.foldLeft(0) { +// case (i, ct) => +// s(ct) match { +// case Some(ti) if same(ct, ti) => +// return Some(r) +// case Some(ti) => +// val newchildren = children.updated(i, ti) +// return Some(r.reconstruct(newchildren)) +// case None => +// i + 1 +// } +// } +// 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 r : Rewritable => +// someRewritable(strat, r) + 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 `Rewritable` values. + */ +// def someRewritable(s : Strategy, r : Rewritable) : Option[Any] = { +// val numchildren = r.arity +// if (numchildren == 0) +// None +// else { +// val newchildren = Seq.newBuilder[Any] +// val (success, changed) = +// r.deconstruct.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(r.reconstruct(newchildren.result())) +// else +// Some(r) +// else +// 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 + } + + /** + * Make a strategy that applies the elements of ss pairwise to the + * children of the subject term, returning a new term if all of the + * strategies succeed, otherwise failing. The constructor of the new + * term is the same as that of the original term and the children + * are the results of the strategies. If the length of `ss` is not + * the same as the number of children, then `congruence(ss)` fails. + * If the argument strategies succeed 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 `Product` values. + */ + def congruence(ss : Strategy*) : Strategy = + mkStrategy( + t => + t match { + case p : Product => + congruenceProduct(p, ss : _*) + case _ => + Some(t) + } + ) + + /** + * Implementation of `congruence` for `Product` values. + */ + def congruenceProduct(p : Product, ss : Strategy*) : Option[Any] = { + val numchildren = p.productArity + if (numchildren == ss.length) { + val newchildren = Array.newBuilder[AnyRef] + val (changed, _) = + p.productIterator.foldLeft((false, 0)) { + case ((changed, i), ct) => + (ss(i))(ct) match { + case Some(ti) => + newchildren += makechild(ti) + (changed || !same(ct, ti), i + 1) + case None => + return None + } + } + if (changed) + Some(dup(p, newchildren.result())) + else + Some(p) + } 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 r : Rewritable => +// Some((r, r.deconstruct.toVector)) + case p : Product => + Some((p, p.productIterator.toVector)) + case s : Seq[_] => + Some((s, s.toVector)) + case _ => + Some((t, Vector())) + } + } + + } + + // Library combinators + + /** + * Construct a strategy that applies `s` in a bottom-up fashion to all + * subterms at each level, stopping at a frontier where s succeeds. + */ + def allbu(s : Strategy) : Strategy = { + lazy val result : Strategy = all(result) <+ s + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` in a top-down fashion, stopping + * at a frontier where s succeeds. + */ + def alltd(s : Strategy) : Strategy = { + lazy val result : Strategy = s <+ all(result) + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s1` in a top-down, prefix fashion + * stopping at a frontier where `s1` succeeds. `s2` is applied in a bottom-up, + * postfix fashion to the result. + */ + def alldownup2(s1 : Strategy, s2 : Strategy) : Strategy = { + lazy val result : Strategy = (s1 <+ all(result)) <* s2 + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s1` in a top-down, prefix fashion + * stopping at a frontier where `s1` succeeds. `s2` is applied in a bottom-up, + * postfix fashion to the results of the recursive calls. + */ + def alltdfold(s1 : Strategy, s2 : Strategy) : Strategy = { + lazy val result : Strategy = s1 <+ (all(result) <* s2) + mkStrategy(result) + } + + /** + * `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 + + /** + * Construct a strategy that applies `s` in a bottom-up, postfix fashion + * to the subject term but stops when the strategy produced by `stop` + * succeeds. `stop` is given the whole strategy itself as its argument. + */ + def bottomupS(s : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { + lazy val result : Strategy = (stop(result) <+ all(result)) <* s + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` in breadth first order. This + * strategy does not apply `s` to the root of the subject term. + * + * It is called `breadthfirst` to follow Stratego's library, but is not + * really conducting a breadth-first traversal since all of the + * descendants of the first child of a term are visited before any of + * the descendants of the second child of a term. + */ + def breadthfirst(s : Strategy) : Strategy = { + lazy val result : Strategy = all(s) <* all(result) + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` at least once and then repeats `s` + * while `r` succeeds. This operator is called `do-while` in the Stratego + * library. + */ + def doloop(s : Strategy, r : Strategy) : Strategy = + s <* (loop(r, s)) + + /** + * A unit for `topdownS`, `bottomupS` and `downupS`. For example, `topdown(s)` + * is equivalent to `topdownS(s, dontstop)`. + */ + def dontstop(s : => Strategy) : Strategy = + fail + + /** + * Construct a strategy that applies `s` in a combined top-down and + * bottom-up fashion (i.e., both prefix and postfix) to the subject + * term. + */ + def downup(s : Strategy) : Strategy = { + lazy val result : Strategy = s <* all(result) <* s + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s1` in a top-down, prefix fashion + * and `s2` in a bottom-up, postfix fashion to the subject term. + */ + def downup(s1 : Strategy, s2 : Strategy) : Strategy = { + lazy val result : Strategy = s1 <* all(result) <* s2 + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` in a combined top-down and + * bottom-up fashion (i.e., both prefix and postfix) to the subject + * but stops when the strategy produced by `stop` succeeds. `stop` is + * given the whole strategy itself as its argument. + */ + def downupS(s : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { + lazy val result : Strategy = s <* (stop(result) <+ all(result) <* s) + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s1` in a top-down, prefix fashion + * and `s2` in a bottom-up, postfix fashion to the subject term but stops + * when the strategy produced by `stop` succeeds. `stop` is given the whole + * strategy itself as its argument. + */ + def downupS(s1 : Strategy, s2 : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { + lazy val result : Strategy = s1 <* (stop(result) <+ all(result) <* s2) + mkStrategy(result) + } + + /** + * 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 applies `s` repeatedly to the innermost + * (i.e., lowest and left-most) (sub-)term to which it applies. + * Stop with the subject term if `s` doesn't apply anywhere. + */ + def innermost(s : Strategy) : Strategy = { + lazy val result : Strategy = bottomup(attempt(s <* result)) + mkStrategy(result) + } + + /** + * An alternative version of `innermost`. + */ + def innermost2(s : Strategy) : Strategy = + repeat(oncebu(s)) + + /** + * `ior(s1, s2)` implements inclusive OR, that is, the + * inclusive choice of `s1` and `s2`. It first tries `s1`. If + * that fails it applies `s2` (just like `s1 <+ s2`). However, + * when `s1` succeeds it also tries to apply `s2`. + */ + def ior(s1 : Strategy, s2 : Strategy) : Strategy = + (s1 <* attempt(s2)) <+ s2 + + /** + * Construct a strategy that succeeds if the current term has at + * least one direct subterm. + */ + val isinnernode : Strategy = + mkStrategy(one(id)) + + /** + * Construct a strategy that succeeds if the current term has no + * direct subterms. + */ + val isleaf : Strategy = + mkStrategy(all(fail)) + + /** + * Construct a strategy that succeeds when applied to a pair `(x,y)` + * if `x` is a sub-term of `y` but is not equal to `y`. + */ + val ispropersubterm : Strategy = + mkStrategy(not(eq) <* issubterm) + + /** + * Construct a strategy that succeeds when applied to a pair `(x,y)` + * if `x` is a sub-term of `y`. + */ + val issubterm : Strategy = + mkStrategy({ + case (x, y) => + where(oncetd(term(x)))(y) + case _ => + None + }) + + /** + * Construct a strategy that succeeds when applied to a pair `(x,y)` + * if `x` is a superterm of `y`. + */ + val issuperterm : Strategy = + mkStrategy({ + case (x, y) => + issubterm((y, x)) + case _ => + None + }) + + /** + * Construct a strategy that succeeds when applied to a pair `(x,y)` + * if `x` is a super-term of `y` but is not equal to `y`. + */ + val ispropersuperterm : Strategy = + mkStrategy(not(eq) <* issuperterm) + + /** + * Applies `s` followed by `f` whether `s` failed or not. + * This operator is called `finally` in the Stratego library. + */ + def lastly(s : Strategy, f : Strategy) : Strategy = + s < (where(f) + (where(f) <* fail)) + + /** + * Construct a strategy that applies to all of the leaves of the + * subject term, using `isleaf` as the leaf predicate. + */ + def leaves(s : Strategy, isleaf : Strategy) : Strategy = { + lazy val result : Strategy = (isleaf <* s) <+ all(result) + mkStrategy(result) + } + + /** + * Construct a strategy that applies to all of the leaves of the + * subject term, using `isleaf` as the leaf predicate, skipping + * subterms for which `skip` when applied to the result succeeds. + */ + def leaves(s : Strategy, isleaf : Strategy, skip : Strategy => Strategy) : Strategy = { + lazy val result : Strategy = (isleaf <* s) <+ skip(result) <+ all(result) + mkStrategy(result) + } + + /** + * 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 repeats application of `s` while `r` fails, after + * initialization with `i`. This operator is called `for` in the Stratego + * library. + */ + def loopiter(i : Strategy, r : Strategy, s : Strategy) : Strategy = + i <* loopnot(r, s) + + /** + * 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 while `r` does not succeed applies `s`. This + * operator is called `while-not` in the Stratego library. + */ + def loopnot(r : Strategy, s : Strategy) : Strategy = { + lazy val result : Strategy = r <+ (s <* result) + 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` as many times as possible, but + * at least once, in bottom up order. + */ + def manybu(s : Strategy) : Strategy = { + lazy val result : Strategy = some(result) <* attempt(s) <+ s + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` as many times as possible, but + * at least once, in top down order. + */ + def manytd(s : Strategy) : Strategy = { + lazy val result : Strategy = s <* all(attempt(result)) <+ some(result) + mkStrategy(result) + } + + /** + * 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) + + /** + * Construct a strategy that applies `s` in a bottom-up fashion to one + * subterm at each level, stopping as soon as it succeeds once (at + * any level). + */ + def oncebu(s : Strategy) : Strategy = { + lazy val result : Strategy = one(result) <+ s + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` in a top-down fashion to one + * subterm at each level, stopping as soon as it succeeds once (at + * any level). + */ + def oncetd(s : Strategy) : Strategy = { + lazy val result : Strategy = s <+ one(result) + mkStrategy(result) + } + + /** + * `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 in a top-down fashion + * stopping each time as soon as it succeeds once (at any level). The + * outermost fails when `s` fails to apply to any (sub-)term. + */ + def outermost(s : Strategy) : Strategy = + repeat(oncetd(s)) + + /** + * 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 repeatedly applies `s` until it fails and + * then terminates with application of `r`. + */ + def repeat(s : Strategy, r : Strategy) : Strategy = { + lazy val result : Strategy = (s <* result) <+ r + 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 repeatedly applies `s` (at least once). + */ + def repeat1(s : Strategy) : Strategy = + repeat1(s, id) + + /** + * Construct a strategy that repeatedly applies `s` (at least once) and + * terminates with application of `c`. + */ + def repeat1(s : Strategy, r : Strategy) : Strategy = { + lazy val result : Strategy = s <* (result <+ r) + mkStrategy(result) + } + + /** + * Construct a strategy that repeatedly applies `s` until `c` succeeds. + */ + def repeatuntil(s : Strategy, r : Strategy) : Strategy = { + lazy val result : Strategy = s <* (r <+ result) + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s`, then applies the restoring action + * `rest` if `s` fails (and then fail). Otherwise, let the result of `s` stand. + * Typically useful if `s` performs side effects that should be restored or + * undone when `s` fails. + */ + def restore(s : Strategy, rest : Strategy) : Strategy = + s <+ (rest <* fail) + + /** + * Construct a strategy that applies `s`, then applies the restoring action + * `rest` regardless of the success or failure of `s`. The whole strategy + * preserves the success or failure of `s`. Typically useful if `s` performs + * side effects that should be restored always, e.g., when maintaining scope + * information. + */ + def restorealways(s : Strategy, rest : Strategy) : Strategy = + s < (rest + (rest <* fail)) + + /** + * Construct a strategy that applies `s` in a bottom-up fashion to some + * subterms at each level, stopping as soon as it succeeds once (at + * any level). + */ + def somebu(s : Strategy) : Strategy = { + lazy val result : Strategy = some(result) <+ s + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` in a top-down, prefix fashion + * stopping at a frontier where `s` succeeds on some children. `s` is then + * applied in a bottom-up, postfix fashion to the result. + */ + def somedownup(s : Strategy) : Strategy = { + lazy val result : Strategy = (s <* all(result) <* (attempt(s))) <+ some(result) <+ attempt(s) + mkStrategy(result) + } + + /** + * Construct a strategy that applies `s` in a top-down fashion to some + * subterms at each level, stopping as soon as it succeeds once (at + * any level). + */ + def sometd(s : Strategy) : Strategy = { + lazy val result : Strategy = s <+ some(result) + 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 applies `s` in a top-down, prefix fashion + * to the subject term but stops when the strategy produced by `stop` + * succeeds. `stop` is given the whole strategy itself as its argument. + */ + def topdownS(s : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { + lazy val result : Strategy = s <* (stop(result) <+ 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() + } + + /** + * 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 collection of values. All of these values + * are accumulated in the collection. + */ + def collectall[CC[X] <: Iterable[X], U](f : Any ==> CC[U])(implicit cbf : Factory[U, CC[U]]) : Any => CC[U] = + (t : Any) => { + val b = newBuilder(cbf) + val addall = (us : CC[U]) => { b ++= us; () } + (everywhere(query(f andThen addall)))(t) + b.result() + } + + /** + * Collect query results in a list. Run the function `f` as a top-down + * left-to-right query on the subject term. Accumulate the values + * produced by the function in a list and return the final value of + * the list. + */ + def collectl[U](f : Any ==> U) : Any => List[U] = + collect[List, U](f) + + /** + * Collect query results in a set. Run the function `f` as a top-down + * left-to-right query on the subject term. Accumulate the values + * produced by the function in a set and return the final value of + * the set. + */ + def collects[U](f : Any ==> U) : Any => Set[U] = + collect[Set, U](f) + + /** + * 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/Collections.scala b/common/src/main/scala/sigmastate/kiama/util/Collections.scala new file mode 100644 index 0000000000..347a996452 --- /dev/null +++ b/common/src/main/scala/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/sigmastate/kiama/util/Comparison.scala b/common/src/main/scala/sigmastate/kiama/util/Comparison.scala new file mode 100644 index 0000000000..16e087ac94 --- /dev/null +++ b/common/src/main/scala/sigmastate/kiama/util/Comparison.scala @@ -0,0 +1,145 @@ +/* + * 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, _))) + + /** + * As for `same`, except that if the two values are `Some` options + * containing references, they are unwrapped first and the contents are + * compared by reference. + */ + def optsame(v1 : Any, v2 : Any) : Boolean = + if (v1 == null) + v2 == null + else if (v2 == null) + false + else + (v1, v2) match { + case (Some(r1 : AnyRef), Some(r2 : AnyRef)) => + r1 eq r2 + case _ => + same(v1, v2) + } + + /** + * 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 + } + + /** + * As for `distinct` but works over a sequence of sequences. + */ + def flatDistinct[T](ss : Seq[Seq[T]]) : Vector[T] = { + val set = new TreeSet[T]()(new TOrdering[T]) + for (s <- ss) + 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/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index bb217a9c25..7fdf6dccb2 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/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index d7615c0d2a..6a33ec747f 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -1,8 +1,8 @@ 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._ diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index 44d34a6c8c..6752d9299d 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -1,8 +1,8 @@ package sigmastate.interpreter import gf2t.{GF2_192, GF2_192_Poly} -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._ 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 53f12a7cb2..e27a67e778 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} diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala index 8cfc0f651c..06928adb28 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala @@ -1,6 +1,6 @@ package sigmastate.lang -import org.bitbucket.inkytonik.kiama.rewriting.Rewriter._ +import sigmastate.kiama.rewriting.Rewriter._ import org.ergoplatform._ import sigmastate.SCollection._ import sigmastate.Values._ diff --git a/sigmastate/src/main/scala/sigmastate/lang/Terms.scala b/sigmastate/src/main/scala/sigmastate/lang/Terms.scala index 7a4c86cfc1..9621e79134 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.{SByteArray, SIntArray} import sigmastate.Values._ diff --git a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala index 634bb8f103..945816aab2 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala @@ -75,7 +75,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 } From eef8a9e5f17e0d37bf36054bb5fd3ecb1e2bd203 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 5 Sep 2022 17:46:32 +0200 Subject: [PATCH 11/64] v5.x-restructure: fix compilation for all Scala versions --- build.sbt | 2 +- .../sigmastate/kiama/util/Collections.scala | 0 .../sigmastate/kiama/util/Collections.scala | 42 +++++++++++++++++++ .../sigmastate/kiama/util/Collections.scala | 42 +++++++++++++++++++ .../sigmastate/kiama/rewriting/Rewriter.scala | 13 +++--- 5 files changed, 90 insertions(+), 9 deletions(-) rename common/src/main/{scala => scala-2.11}/sigmastate/kiama/util/Collections.scala (100%) create mode 100644 common/src/main/scala-2.12/sigmastate/kiama/util/Collections.scala create mode 100644 common/src/main/scala-2.13/sigmastate/kiama/util/Collections.scala diff --git a/build.sbt b/build.sbt index 569636568d..edc71ee083 100644 --- a/build.sbt +++ b/build.sbt @@ -14,7 +14,7 @@ lazy val allConfigDependency = "compile->compile;test->test" lazy val commonSettings = Seq( organization := "org.scorexfoundation", crossScalaVersions := Seq(scala213, scala212, scala211), - scalaVersion := scala212, + scalaVersion := scala213, resolvers += Resolver.sonatypeRepo("public"), licenses := Seq("CC0" -> url("https://creativecommons.org/publicdomain/zero/1.0/legalcode")), homepage := Some(url("https://github.com/ScorexFoundation/sigmastate-interpreter")), diff --git a/common/src/main/scala/sigmastate/kiama/util/Collections.scala b/common/src/main/scala-2.11/sigmastate/kiama/util/Collections.scala similarity index 100% rename from common/src/main/scala/sigmastate/kiama/util/Collections.scala rename to common/src/main/scala-2.11/sigmastate/kiama/util/Collections.scala 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/sigmastate/kiama/rewriting/Rewriter.scala b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala index 301166a12b..5527a9279b 100644 --- a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala +++ b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala @@ -21,11 +21,8 @@ package rewriting */ trait Rewriter { -// import org.bitbucket.inkytonik.kiama.relation.{EnsureTree, Tree, TreeShape} - import sigmastate.kiama.util.Collections.{CanBuildFrom, Factory, newBuilder} import sigmastate.kiama.util.Comparison.same -// import org.bitbucket.inkytonik.kiama.util.{Emitter, OutputEmitter} - import scala.collection.immutable.Seq + import sigmastate.kiama.util.Collections.{CanBuildFrom, Factory, newBuilder} /** * Rewrite a term. Apply the strategy `s` to a term returning the result term @@ -1605,8 +1602,8 @@ trait Rewriter { * produced by the function in a list and return the final value of * the list. */ - def collectl[U](f : Any ==> U) : Any => List[U] = - collect[List, U](f) +// def collectl[U](f : Any ==> U) : Any => List[U] = +// collect[List, U](f) /** * Collect query results in a set. Run the function `f` as a top-down @@ -1614,8 +1611,8 @@ trait Rewriter { * produced by the function in a set and return the final value of * the set. */ - def collects[U](f : Any ==> U) : Any => Set[U] = - collect[Set, U](f) +// def collects[U](f : Any ==> U) : Any => Set[U] = +// collect[Set, U](f) /** * Count function results. Run the function `f` as a top-down query on From 431bd1d9780026b63636e8365c6c56d7b668e476 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 5 Sep 2022 19:42:29 +0200 Subject: [PATCH 12/64] v5.x-restructure: codecov set fail_ci_if_error: false --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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' From b46edf71227f28e43a3e574a001f6732931edf68 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 5 Sep 2022 20:33:31 +0200 Subject: [PATCH 13/64] v5.x-restructure: remove unused methods from sigmastate.kiama --- .../sigmastate/kiama/rewriting/Rewriter.scala | 588 ------------------ docs/notes.md | 6 - 2 files changed, 594 deletions(-) diff --git a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala index 5527a9279b..cc97baa503 100644 --- a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala +++ b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala @@ -37,24 +37,6 @@ trait Rewriter { } } - /** - * Rewrite a tree. Apply the strategy `s` to the root of a tree returning the - * a tree formed from the result term if `s` succeeds, otherwise return the - * original tree. - * - * The `shape` parameter specifies the tree shape that should be used - * when creating the new tree. The default is `EnsureTree` since it is - * likely that rewrites will result in node sharing that should be removed. - */ -// def rewriteTree[T <: AnyRef with Product, U <: T](s : Strategy)(t : Tree[T, U], shape : TreeShape = EnsureTree) : Tree[T, U] = { -// s(t.root) match { -// case Some(t1) => -// new Tree[T, U](t1.asInstanceOf[U], shape) -// case None => -// t -// } -// } - // Strategy creation /** @@ -75,15 +57,6 @@ trait Rewriter { def build(t : Any) : Strategy = rulef(_ => t) - /** - * A strategy that always succeeds with the subject term unchanged (i.e., - * this is the identity strategy) with the side-effect that the subject - * term is printed to the given emitter, prefixed by the string `s`. The - * emitter defaults to one that writes to standard output. - */ -// def debug(msg : String, emitter : Emitter = new OutputEmitter) : Strategy = -// strategyf(t => { emitter.emitln(msg + t); Some(t) }) - /** * A strategy that always fails. */ @@ -96,88 +69,6 @@ trait Rewriter { val id : Strategy = mkStrategy(Some(_)) - /** - * Create a logging strategy based on a strategy `s`. The returned strategy - * succeeds or fails exactly as `s` does, but also prints the provided message, - * the subject term, the success or failure status, and on success, the result - * term, to the provided emitter. `s` is evaluated at most once. - */ -// def log(s : Strategy, msg : String, emitter : Emitter) : Strategy = { -// lazy val strat = s -// mkStrategy( -// t1 => { -// emitter.emit(msg + t1) -// val r = strat(t1) -// r match { -// case Some(t2) => -// emitter.emitln(s" succeeded with $t2") -// case None => -// emitter.emitln(" failed") -// } -// r -// } -// ) -// } - - /** - * Create a logging strategy based on a strategy `s`. The returned strategy - * succeeds or fails exactly as `s` does, but if `s` fails, also prints the - * provided message and the subject term to the provided emitter. `s` is - * evaluated at most once. - */ -// def logfail[T](s : Strategy, msg : String, emitter : Emitter) : Strategy = { -// lazy val strat = s -// mkStrategy( -// t1 => { -// val r = strat(t1) -// r match { -// case Some(t2) => -// // Do nothing -// case None => -// emitter.emitln(s"$msg$t1 failed") -// } -// r -// } -// ) -// } - - /** - * Return a strategy that behaves as `s` does, but memoises its arguments and - * results. In other words, if `memo(s)` is called on a term `t` twice, the - * second time will return the same result as the first, without having to - * invoke `s`. For best results, it is important that `s` should have no side - * effects. `s` is evaluated at most once. - */ -// def memo(s : Strategy) : Strategy = { -// -// import com.google.common.base.Function -// import com.google.common.cache.{CacheBuilder, CacheLoader} -// -// lazy val strat = s -// -// val cache = -// CacheBuilder.newBuilder.build[AnyRef, Option[Any]]( -// CacheLoader.from( -// new Function[AnyRef, Option[Any]] { -// def apply(t : AnyRef) : Option[Any] = -// strat(t) -// } -// ) -// ) -// -// mkStrategy(t => cache.get(t.asInstanceOf[AnyRef])) -// -// } - - /** - * Construct a strategy from an option value `o`. The strategy succeeds - * or fails depending on whether `o` is a Some or None, respectively. - * If `o` is a `Some`, then the subject term is changed to the term that - * is wrapped by the `Some`. `o` is evaluated at most once. - */ - def option(o : Option[Any]) : Strategy = - strategyf(_ => o) - /** * Perform a paramorphism over a value. This is a fold in which the * recursive step may refer to the recursive component of the value @@ -218,20 +109,6 @@ trait Rewriter { ) } - /** - * Define a term query by a function `f`. The query always succeeds with - * no effect on the subject term but applies the given (possibly partial) - * function `f` to the subject term. In other words, the strategy runs - * `f` for its side-effects. - */ - def queryf(f : Any => Unit) : Strategy = - mkStrategy( - t => { - f(t) - Some(t) - } - ) - /** * 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 @@ -341,7 +218,6 @@ trait Rewriter { import com.google.common.base.Function import com.google.common.cache.{CacheBuilder, CacheLoader} - import java.lang.{Class, IllegalArgumentException, NoSuchFieldException} import java.lang.reflect.Constructor type Duper = (Any, Array[AnyRef]) => Any @@ -534,8 +410,6 @@ trait Rewriter { lazy val strat = s t => t match { -// case r : Rewritable => -// allRewritable(strat, r) case p : Product => allProduct(strat, p) case m : Map[_, _] => @@ -547,33 +421,6 @@ trait Rewriter { } }) - /** - * Implementation of `all` for `Rewritable` values. - */ -// def allRewritable(s : Strategy, r : Rewritable) : Option[Any] = { -// val numchildren = r.arity -// if (numchildren == 0) -// Some(r) -// else { -// val newchildren = Seq.newBuilder[Any] -// val changed = -// r.deconstruct.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(r.reconstruct(newchildren.result())) -// else -// Some(r) -// } -// } - /** * Implementation of `all` for `Product` values. */ @@ -675,8 +522,6 @@ trait Rewriter { lazy val strat = s t => t match { -// case r : Rewritable => -// oneRewritable(strat, r) case p : Product => oneProduct(strat, p) case m : Map[_, _] => @@ -688,26 +533,6 @@ trait Rewriter { } }) - /** - * Implementation of `one` for `Rewritable` values. - */ -// def oneRewritable(s : Strategy, r : Rewritable) : Option[Any] = { -// val children = r.deconstruct -// children.foldLeft(0) { -// case (i, ct) => -// s(ct) match { -// case Some(ti) if same(ct, ti) => -// return Some(r) -// case Some(ti) => -// val newchildren = children.updated(i, ti) -// return Some(r.reconstruct(newchildren)) -// case None => -// i + 1 -// } -// } -// None -// } - /** * Implementation of `one` for `Product` values. */ @@ -814,8 +639,6 @@ trait Rewriter { lazy val strat = s t => t match { -// case r : Rewritable => -// someRewritable(strat, r) case p : Product => someProduct(strat, p) case m : Map[_, _] => @@ -827,37 +650,6 @@ trait Rewriter { } }) - /** - * Implementation of `some` for `Rewritable` values. - */ -// def someRewritable(s : Strategy, r : Rewritable) : Option[Any] = { -// val numchildren = r.arity -// if (numchildren == 0) -// None -// else { -// val newchildren = Seq.newBuilder[Any] -// val (success, changed) = -// r.deconstruct.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(r.reconstruct(newchildren.result())) -// else -// Some(r) -// else -// None -// } -// } - /** * Implementation of `some` for `Product` values. */ @@ -949,29 +741,6 @@ trait Rewriter { None } - /** - * Make a strategy that applies the elements of ss pairwise to the - * children of the subject term, returning a new term if all of the - * strategies succeed, otherwise failing. The constructor of the new - * term is the same as that of the original term and the children - * are the results of the strategies. If the length of `ss` is not - * the same as the number of children, then `congruence(ss)` fails. - * If the argument strategies succeed 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 `Product` values. - */ - def congruence(ss : Strategy*) : Strategy = - mkStrategy( - t => - t match { - case p : Product => - congruenceProduct(p, ss : _*) - case _ => - Some(t) - } - ) - /** * Implementation of `congruence` for `Product` values. */ @@ -1028,44 +797,6 @@ trait Rewriter { // Library combinators - /** - * Construct a strategy that applies `s` in a bottom-up fashion to all - * subterms at each level, stopping at a frontier where s succeeds. - */ - def allbu(s : Strategy) : Strategy = { - lazy val result : Strategy = all(result) <+ s - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` in a top-down fashion, stopping - * at a frontier where s succeeds. - */ - def alltd(s : Strategy) : Strategy = { - lazy val result : Strategy = s <+ all(result) - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s1` in a top-down, prefix fashion - * stopping at a frontier where `s1` succeeds. `s2` is applied in a bottom-up, - * postfix fashion to the result. - */ - def alldownup2(s1 : Strategy, s2 : Strategy) : Strategy = { - lazy val result : Strategy = (s1 <+ all(result)) <* s2 - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s1` in a top-down, prefix fashion - * stopping at a frontier where `s1` succeeds. `s2` is applied in a bottom-up, - * postfix fashion to the results of the recursive calls. - */ - def alltdfold(s1 : Strategy, s2 : Strategy) : Strategy = { - lazy val result : Strategy = s1 <+ (all(result) <* s2) - mkStrategy(result) - } - /** * `and(s1, s2)` applies `s1` and `s2` to the subject * term and succeeds if both succeed. `s2` will always @@ -1090,86 +821,6 @@ trait Rewriter { def bottomup(s : Strategy) : Strategy = all(bottomup(s)) <* s - /** - * Construct a strategy that applies `s` in a bottom-up, postfix fashion - * to the subject term but stops when the strategy produced by `stop` - * succeeds. `stop` is given the whole strategy itself as its argument. - */ - def bottomupS(s : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { - lazy val result : Strategy = (stop(result) <+ all(result)) <* s - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` in breadth first order. This - * strategy does not apply `s` to the root of the subject term. - * - * It is called `breadthfirst` to follow Stratego's library, but is not - * really conducting a breadth-first traversal since all of the - * descendants of the first child of a term are visited before any of - * the descendants of the second child of a term. - */ - def breadthfirst(s : Strategy) : Strategy = { - lazy val result : Strategy = all(s) <* all(result) - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` at least once and then repeats `s` - * while `r` succeeds. This operator is called `do-while` in the Stratego - * library. - */ - def doloop(s : Strategy, r : Strategy) : Strategy = - s <* (loop(r, s)) - - /** - * A unit for `topdownS`, `bottomupS` and `downupS`. For example, `topdown(s)` - * is equivalent to `topdownS(s, dontstop)`. - */ - def dontstop(s : => Strategy) : Strategy = - fail - - /** - * Construct a strategy that applies `s` in a combined top-down and - * bottom-up fashion (i.e., both prefix and postfix) to the subject - * term. - */ - def downup(s : Strategy) : Strategy = { - lazy val result : Strategy = s <* all(result) <* s - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s1` in a top-down, prefix fashion - * and `s2` in a bottom-up, postfix fashion to the subject term. - */ - def downup(s1 : Strategy, s2 : Strategy) : Strategy = { - lazy val result : Strategy = s1 <* all(result) <* s2 - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` in a combined top-down and - * bottom-up fashion (i.e., both prefix and postfix) to the subject - * but stops when the strategy produced by `stop` succeeds. `stop` is - * given the whole strategy itself as its argument. - */ - def downupS(s : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { - lazy val result : Strategy = s <* (stop(result) <+ all(result) <* s) - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s1` in a top-down, prefix fashion - * and `s2` in a bottom-up, postfix fashion to the subject term but stops - * when the strategy produced by `stop` succeeds. `stop` is given the whole - * strategy itself as its argument. - */ - def downupS(s1 : Strategy, s2 : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { - lazy val result : Strategy = s1 <* (stop(result) <+ all(result) <* s2) - mkStrategy(result) - } - /** * A strategy that tests whether the two sub-terms of a pair of terms are equal. */ @@ -1207,52 +858,6 @@ trait Rewriter { def everywheretd(s : Strategy) : Strategy = topdown(attempt(s)) - /** - * Construct a strategy that applies `s` repeatedly to the innermost - * (i.e., lowest and left-most) (sub-)term to which it applies. - * Stop with the subject term if `s` doesn't apply anywhere. - */ - def innermost(s : Strategy) : Strategy = { - lazy val result : Strategy = bottomup(attempt(s <* result)) - mkStrategy(result) - } - - /** - * An alternative version of `innermost`. - */ - def innermost2(s : Strategy) : Strategy = - repeat(oncebu(s)) - - /** - * `ior(s1, s2)` implements inclusive OR, that is, the - * inclusive choice of `s1` and `s2`. It first tries `s1`. If - * that fails it applies `s2` (just like `s1 <+ s2`). However, - * when `s1` succeeds it also tries to apply `s2`. - */ - def ior(s1 : Strategy, s2 : Strategy) : Strategy = - (s1 <* attempt(s2)) <+ s2 - - /** - * Construct a strategy that succeeds if the current term has at - * least one direct subterm. - */ - val isinnernode : Strategy = - mkStrategy(one(id)) - - /** - * Construct a strategy that succeeds if the current term has no - * direct subterms. - */ - val isleaf : Strategy = - mkStrategy(all(fail)) - - /** - * Construct a strategy that succeeds when applied to a pair `(x,y)` - * if `x` is a sub-term of `y` but is not equal to `y`. - */ - val ispropersubterm : Strategy = - mkStrategy(not(eq) <* issubterm) - /** * Construct a strategy that succeeds when applied to a pair `(x,y)` * if `x` is a sub-term of `y`. @@ -1265,51 +870,6 @@ trait Rewriter { None }) - /** - * Construct a strategy that succeeds when applied to a pair `(x,y)` - * if `x` is a superterm of `y`. - */ - val issuperterm : Strategy = - mkStrategy({ - case (x, y) => - issubterm((y, x)) - case _ => - None - }) - - /** - * Construct a strategy that succeeds when applied to a pair `(x,y)` - * if `x` is a super-term of `y` but is not equal to `y`. - */ - val ispropersuperterm : Strategy = - mkStrategy(not(eq) <* issuperterm) - - /** - * Applies `s` followed by `f` whether `s` failed or not. - * This operator is called `finally` in the Stratego library. - */ - def lastly(s : Strategy, f : Strategy) : Strategy = - s < (where(f) + (where(f) <* fail)) - - /** - * Construct a strategy that applies to all of the leaves of the - * subject term, using `isleaf` as the leaf predicate. - */ - def leaves(s : Strategy, isleaf : Strategy) : Strategy = { - lazy val result : Strategy = (isleaf <* s) <+ all(result) - mkStrategy(result) - } - - /** - * Construct a strategy that applies to all of the leaves of the - * subject term, using `isleaf` as the leaf predicate, skipping - * subterms for which `skip` when applied to the result succeeds. - */ - def leaves(s : Strategy, isleaf : Strategy, skip : Strategy => Strategy) : Strategy = { - lazy val result : Strategy = (isleaf <* s) <+ skip(result) <+ all(result) - mkStrategy(result) - } - /** * Construct a strategy that while `r` succeeds applies `s`. This operator * is called `while` in the Stratego library. @@ -1319,14 +879,6 @@ trait Rewriter { mkStrategy(result) } - /** - * Construct a strategy that repeats application of `s` while `r` fails, after - * initialization with `i`. This operator is called `for` in the Stratego - * library. - */ - def loopiter(i : Strategy, r : Strategy, s : Strategy) : Strategy = - i <* loopnot(r, s) - /** * 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. @@ -1361,24 +913,6 @@ trait Rewriter { allIterable[Seq](s, l) }) - /** - * Construct a strategy that applies `s` as many times as possible, but - * at least once, in bottom up order. - */ - def manybu(s : Strategy) : Strategy = { - lazy val result : Strategy = some(result) <* attempt(s) <+ s - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` as many times as possible, but - * at least once, in top down order. - */ - def manytd(s : Strategy) : Strategy = { - lazy val result : Strategy = s <* all(attempt(result)) <+ some(result) - mkStrategy(result) - } - /** * 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 @@ -1414,14 +948,6 @@ trait Rewriter { def or(s1 : Strategy, s2 : Strategy) : Strategy = where(s1) < (attempt(test(s2)) + test(s2)) - /** - * Construct a strategy that applies `s` repeatedly in a top-down fashion - * stopping each time as soon as it succeeds once (at any level). The - * outermost fails when `s` fails to apply to any (sub-)term. - */ - def outermost(s : Strategy) : Strategy = - repeat(oncetd(s)) - /** * Construct a strategy that applies `s` repeatedly to subterms * until it fails on all of them. @@ -1439,15 +965,6 @@ trait Rewriter { mkStrategy(result) } - /** - * Construct a strategy that repeatedly applies `s` until it fails and - * then terminates with application of `r`. - */ - def repeat(s : Strategy, r : Strategy) : Strategy = { - lazy val result : Strategy = (s <* result) <+ r - 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 @@ -1459,12 +976,6 @@ trait Rewriter { mkStrategy(result) } - /** - * Construct a strategy that repeatedly applies `s` (at least once). - */ - def repeat1(s : Strategy) : Strategy = - repeat1(s, id) - /** * Construct a strategy that repeatedly applies `s` (at least once) and * terminates with application of `c`. @@ -1474,63 +985,6 @@ trait Rewriter { mkStrategy(result) } - /** - * Construct a strategy that repeatedly applies `s` until `c` succeeds. - */ - def repeatuntil(s : Strategy, r : Strategy) : Strategy = { - lazy val result : Strategy = s <* (r <+ result) - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s`, then applies the restoring action - * `rest` if `s` fails (and then fail). Otherwise, let the result of `s` stand. - * Typically useful if `s` performs side effects that should be restored or - * undone when `s` fails. - */ - def restore(s : Strategy, rest : Strategy) : Strategy = - s <+ (rest <* fail) - - /** - * Construct a strategy that applies `s`, then applies the restoring action - * `rest` regardless of the success or failure of `s`. The whole strategy - * preserves the success or failure of `s`. Typically useful if `s` performs - * side effects that should be restored always, e.g., when maintaining scope - * information. - */ - def restorealways(s : Strategy, rest : Strategy) : Strategy = - s < (rest + (rest <* fail)) - - /** - * Construct a strategy that applies `s` in a bottom-up fashion to some - * subterms at each level, stopping as soon as it succeeds once (at - * any level). - */ - def somebu(s : Strategy) : Strategy = { - lazy val result : Strategy = some(result) <+ s - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` in a top-down, prefix fashion - * stopping at a frontier where `s` succeeds on some children. `s` is then - * applied in a bottom-up, postfix fashion to the result. - */ - def somedownup(s : Strategy) : Strategy = { - lazy val result : Strategy = (s <* all(result) <* (attempt(s))) <+ some(result) <+ attempt(s) - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` in a top-down fashion to some - * subterms at each level, stopping as soon as it succeeds once (at - * any level). - */ - def sometd(s : Strategy) : Strategy = { - lazy val result : Strategy = s <+ some(result) - mkStrategy(result) - } - /** * Construct a strategy that tests whether strategy `s` succeeds, * restoring the original term on success. A synonym for `where`. @@ -1547,16 +1001,6 @@ trait Rewriter { mkStrategy(result) } - /** - * Construct a strategy that applies `s` in a top-down, prefix fashion - * to the subject term but stops when the strategy produced by `stop` - * succeeds. `stop` is given the whole strategy itself as its argument. - */ - def topdownS(s : Strategy, stop : (=> Strategy) => Strategy) : Strategy = { - lazy val result : Strategy = s <* (stop(result) <+ all(result)) - mkStrategy(result) - } - /** * Construct a strategy that tests whether strategy `s` succeeds, * restoring the original term on success. This is similar @@ -1582,38 +1026,6 @@ trait Rewriter { b.result() } - /** - * 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 collection of values. All of these values - * are accumulated in the collection. - */ - def collectall[CC[X] <: Iterable[X], U](f : Any ==> CC[U])(implicit cbf : Factory[U, CC[U]]) : Any => CC[U] = - (t : Any) => { - val b = newBuilder(cbf) - val addall = (us : CC[U]) => { b ++= us; () } - (everywhere(query(f andThen addall)))(t) - b.result() - } - - /** - * Collect query results in a list. Run the function `f` as a top-down - * left-to-right query on the subject term. Accumulate the values - * produced by the function in a list and return the final value of - * the list. - */ -// def collectl[U](f : Any ==> U) : Any => List[U] = -// collect[List, U](f) - - /** - * Collect query results in a set. Run the function `f` as a top-down - * left-to-right query on the subject term. Accumulate the values - * produced by the function in a set and return the final value of - * the set. - */ -// def collects[U](f : Any ==> U) : Any => Set[U] = -// collect[Set, U](f) - /** * 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 diff --git a/docs/notes.md b/docs/notes.md index ca4999e0ca..cc75f1065d 100644 --- a/docs/notes.md +++ b/docs/notes.md @@ -5,13 +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 | | 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 | From 8dcc48c69596f0ff3fd0e3f7802e2d7cbf371901 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 7 Sep 2022 20:11:21 +0200 Subject: [PATCH 14/64] v5.x-restructure: avoid using ScorexLogging --- .../scala/sigmastate/interpreter/Interpreter.scala | 10 +++++++--- .../sigmastate/interpreter/ProverInterpreter.scala | 2 +- .../utxo/examples/CoinEmissionSpecification.scala | 9 ++++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 6a33ec747f..4072b7f442 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -7,7 +7,6 @@ import org.ergoplatform.ErgoLikeContext import org.ergoplatform.validation.SigmaValidationSettings import org.ergoplatform.validation.ValidationRules._ import sigmastate.basics.DLogProtocol.ProveDlog -import scorex.util.ScorexLogging import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate.basics.DLogProtocol.{DLogInteractiveProver, FirstDLogProverMessage} @@ -47,7 +46,7 @@ import scala.util.{Success, Try} * The interpreter has evaluationMode which defines how it should execute scripts. * @see verify, fullReduction */ -trait Interpreter extends ScorexLogging { +trait Interpreter { type CTX <: InterpreterContext @@ -64,6 +63,11 @@ trait Interpreter extends ScorexLogging { println(msg) } + protected def logMessage(msg: String, t: Throwable) = { + println(msg) + t.printStackTrace(System.out) + } + /** Deserializes given script bytes using ValueSerializer (i.e. assuming expression tree format). * It also measures tree complexity adding to the total estimated cost of script execution. * The new returned context contains increased `initCost` and should be used for further processing. @@ -443,7 +447,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 } } diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index 6752d9299d..c6aead2b29 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -555,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"); ??? }) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index de71cb6007..9b585a823b 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -2,7 +2,6 @@ package sigmastate.utxo.examples import org.ergoplatform._ import org.ergoplatform.settings.ErgoAlgos -import scorex.util.ScorexLogging import sigmastate.Values.{BlockValue, ErgoTree, IntConstant, LongConstant, ValDef, ValUse} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaPPrint, SigmaTestingCommons} import sigmastate.helpers.TestingHelpers._ @@ -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 @@ -218,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") } } From a99872322b3995ee21852a219b9182e87a05e1b2 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 18 Sep 2022 14:06:42 +0200 Subject: [PATCH 15/64] v5.x-restructure: snapshot deps --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index edc71ee083..f95cfb3784 100644 --- a/build.sbt +++ b/build.sbt @@ -56,6 +56,8 @@ 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 scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT" +//val debox = "org.scorexfoundation" %% "debox" % "0.9.0-8-3da95c40-SNAPSHOT" val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" val guava = "com.google.guava" % "guava" % "30.1.1-jre" From c94093ef0239d42c549c7e4dfb6cb7e8ec540359 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 20 Sep 2022 14:13:38 +0200 Subject: [PATCH 16/64] v5.x-restructure: clean sigma-api from dependence on ECPoint --- sigma-api/src/main/scala/special/sigma/SigmaDsl.scala | 1 - sigma-api/src/main/scala/special/sigma/package.scala | 2 -- sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala | 2 -- 3 files changed, 5 deletions(-) diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index 8b265e3310..e9aeb9ddf6 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} 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/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala b/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala index 6d0118c8c9..5f1b18d371 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala @@ -96,7 +96,6 @@ object Evaluation { case BigIntegerRType => SBigInt case BigIntRType => SBigInt - case ECPointRType => SGroupElement case GroupElementRType => SGroupElement case AvlTreeRType => SAvlTree @@ -144,7 +143,6 @@ object Evaluation { case _: BigInteger => BigIntegerRType case _: special.sigma.BigInt => BigIntRType - case _: ECPoint => ECPointRType case _: GroupElement => GroupElementRType case _: ErgoBox => ErgoBoxRType From 7fcdc2775725725043e44598e589c6b779ff2002 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 22 Sep 2022 20:50:17 +0200 Subject: [PATCH 17/64] v5.x-restructure: introduce crypto package with Platform, CryptoFacade and CryptoContext --- .../scala/sigmastate/basics/BcDlogGroup.scala | 31 +++++++++---------- .../sigmastate/crypto/CryptoContext.scala | 19 ++++++++++++ .../sigmastate/crypto/CryptoContextJvm.scala | 27 ++++++++++++++++ .../sigmastate/crypto/CryptoFacade.scala | 5 +++ .../scala/sigmastate/crypto/Platform.scala | 10 ++++++ .../scala/sigmastate/crypto/package.scala | 10 ++++++ .../sigmastate/eval/CostingDataContext.scala | 1 + .../GroupElementSerializer.scala | 2 +- .../ergoplatform/JsonSerializationSpec.scala | 2 +- 9 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/Platform.scala create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/package.scala diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 6cc66d2678..f347b5d9d6 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -7,21 +7,20 @@ import org.bouncycastle.math.ec.custom.sec.SecP256K1Point import org.bouncycastle.math.ec.ECPoint import org.bouncycastle.util.BigIntegers import debox.cfor +import sigmastate.crypto.{CryptoContext, CryptoFacade} import scala.collection.{Seq, mutable} import scala.util.Try import scala.collection.compat.immutable.ArraySeq -abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) extends DlogGroup[ElemType] { - - lazy val curve = x9params.getCurve +abstract class BcDlogGroup[ElemType <: ECPoint](val ctx: CryptoContext) extends DlogGroup[ElemType] { //modulus of the field - lazy val p: BigInteger = curve.getField.getCharacteristic + lazy val p: BigInteger = ctx.getModulus //order of the group - lazy val q = x9params.getN + lazy val q: BigInteger = ctx.getOrder //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. @@ -33,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]() @@ -103,7 +102,7 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex //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] + override lazy val generator: ElemType = ctx.getGenerator.asInstanceOf[ElemType] /** * Checks if the given x and y represent a valid point on the given curve, @@ -114,7 +113,7 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex * @return true if the given x and y represented a valid point on the given curve */ def checkCurveMembership(x: BigInteger, y: BigInteger): Boolean = { - Try(curve.validatePoint(x, y)).isSuccess + Try(ctx.validatePoint(x, y)).isSuccess } @@ -137,13 +136,13 @@ 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.getOrder /** * * @return the identity of this Dlog group */ - override lazy val identity: ElemType = curve.getInfinity.asInstanceOf[ElemType] + override lazy val identity: ElemType = ctx.getInfinity.asInstanceOf[ElemType] /** * Calculates the inverse of the given GroupElement. @@ -188,7 +187,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.getOrder.subtract(one) // choose a random number x in Zq* val randNum = BigIntegers.createRandomInRange(one, qMinusOne, secureRandom) // compute g^x to get a new element @@ -384,4 +383,4 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val x9params: X9ECParameters) ex } } -object SecP256K1 extends BcDlogGroup[SecP256K1Point](CustomNamedCurves.getByName("secp256k1")) \ No newline at end of file +object SecP256K1 extends BcDlogGroup[SecP256K1Point](CryptoFacade.createCryptoContext()) \ No newline at end of file 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..a2c37ada81 --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala @@ -0,0 +1,19 @@ +package sigmastate.crypto + +import java.math.BigInteger + +abstract class CryptoContext { + def getModulus: BigInteger + + def getOrder: BigInteger + + def validatePoint(x: BigInteger, + y: BigInteger): Ecp + + def getInfinity(): Ecp + + def decodePoint(encoded: Array[Byte]): Ecp + + def getGenerator: 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..207e23e3da --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala @@ -0,0 +1,27 @@ +package sigmastate.crypto + +import org.bouncycastle.asn1.x9.X9ECParameters +import org.bouncycastle.math.ec.ECPoint + +import java.math.BigInteger + +class CryptoContextJvm(x9params: X9ECParameters) extends CryptoContext { + lazy val curve = x9params.getCurve + + override def getModulus: BigInteger = curve.getField.getCharacteristic + override def getOrder: BigInteger = x9params.getN + override def getGenerator: ECPoint = { + x9params.getG + } + override def validatePoint(x: BigInteger, y: BigInteger): ECPoint = { + curve.validatePoint(x, y) + } + + override def getInfinity(): ECPoint = { + curve.getInfinity + } + + override def decodePoint(encoded: Array[Byte]): ECPoint = { + 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..cd0387608e --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala @@ -0,0 +1,5 @@ +package sigmastate.crypto + +object CryptoFacade { + def createCryptoContext(): CryptoContext = Platform.createContext() +} 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..aecf1623db --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala @@ -0,0 +1,10 @@ +package sigmastate.crypto + +import org.bouncycastle.crypto.ec.CustomNamedCurves +import org.bouncycastle.math.ec.ECPoint + +/** JVM specific implementation of crypto methods*/ +object Platform { + type Ecp = ECPoint + 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..907d0e32be --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/package.scala @@ -0,0 +1,10 @@ +package sigmastate + +import org.bouncycastle.math.ec.ECPoint + +package object crypto { + /** Instance of Elliptic Curve point. */ + type Ecp = Platform.Ecp + + +} diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index c152cb1716..4c7156e5e3 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -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) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala index d004d42566..f4dabb9a15 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala @@ -38,7 +38,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).asInstanceOf[EcPointType] } else { curve.identity } diff --git a/sigmastate/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala index ee33061c68..8fbd80987f 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -123,7 +123,7 @@ class JsonSerializationSpec extends SigmaTestingCommons with SerializationSpecif val minerPkHex = "0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942" val minerPk = Base16.decode(minerPkHex).map { point => ProveDlog( - CryptoConstants.dlogGroup.curve.decodePoint(point).asInstanceOf[CryptoConstants.EcPointType] + CryptoConstants.dlogGroup.ctx.decodePoint(point).asInstanceOf[CryptoConstants.EcPointType] ) }.get val regs = Map( From 9b5972f2ff712b687f47dc96a84216c22111dc34 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 23 Sep 2022 15:40:13 +0200 Subject: [PATCH 18/64] v5.x-restructure: free sigmastate.basics from direct bouncycastle usages --- .../scala/sigmastate/basics/BcDlogGroup.scala | 13 +-- .../sigmastate/basics/DLogProtocol.scala | 2 +- .../basics/DiffieHellmanTupleProtocol.scala | 2 +- .../scala/sigmastate/basics/DlogGroup.scala | 5 +- .../basics/SigmaProtocolFunctions.scala | 91 ------------------- .../scala/sigmastate/crypto/BigIntegers.scala | 66 ++++++++++++++ .../interpreter/CryptoConstants.scala | 9 +- .../sigmastate/utxo/ProverSpecification.scala | 4 +- 8 files changed, 81 insertions(+), 111 deletions(-) create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index f347b5d9d6..94c5c2b607 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -1,11 +1,7 @@ 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} @@ -14,8 +10,7 @@ import scala.util.Try import scala.collection.compat.immutable.ArraySeq -abstract class BcDlogGroup[ElemType <: ECPoint](val ctx: CryptoContext) extends DlogGroup[ElemType] { - +abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { //modulus of the field lazy val p: BigInteger = ctx.getModulus @@ -102,7 +97,7 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val ctx: CryptoContext) extends //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 = ctx.getGenerator.asInstanceOf[ElemType] + override lazy val generator: ElemType = ctx.getGenerator /** * Checks if the given x and y represent a valid point on the given curve, @@ -383,4 +378,4 @@ abstract class BcDlogGroup[ElemType <: ECPoint](val ctx: CryptoContext) extends } } -object SecP256K1 extends BcDlogGroup[SecP256K1Point](CryptoFacade.createCryptoContext()) \ No newline at end of file +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..b2ee643bce 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 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..5223a77a53 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.Ecp /** @@ -19,7 +19,8 @@ import org.bouncycastle.math.ec.ECPoint * * @tparam ElemType is concrete type */ -trait DlogGroup[ElemType <: ECPoint] { +trait DlogGroup { + type ElemType = Ecp val secureRandom = new SecureRandom() 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..4ad615726d --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala @@ -0,0 +1,66 @@ +package sigmastate.crypto + +import java.math.BigInteger +import java.security.SecureRandom + +object BigIntegers { + + val ZERO: BigInteger = BigInteger.valueOf(0) + + private val MAX_ITERATIONS = 1000 + + @throws[IllegalArgumentException] + def createRandom(bitLength: Int, random: SecureRandom) = { + 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) + } +} diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala index 1da6c8c27e..deeb60b4ce 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala @@ -2,16 +2,15 @@ package sigmastate.interpreter import java.math.BigInteger import java.security.SecureRandom - -import org.bouncycastle.math.ec.custom.sec.SecP256K1Point -import sigmastate.basics.{BcDlogGroup, SecP256K1} +import sigmastate.basics.{BcDlogGroup, SecP256K1Group} +import sigmastate.crypto.Ecp object CryptoConstants { - type EcPointType = SecP256K1Point + type EcPointType = Ecp val EncodedGroupElementLength: Byte = 33 - val dlogGroup: BcDlogGroup[EcPointType] = SecP256K1 + val dlogGroup: BcDlogGroup = SecP256K1Group val secureRandom: SecureRandom = dlogGroup.secureRandom 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 From 1216d2a3e2f584f6f9120caae1e4dc4f59022373 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 23 Sep 2022 16:32:16 +0200 Subject: [PATCH 19/64] v5.x-restructure: avoid org.bouncycastle direct usages outside sigmastate.crypto package --- .../main/scala/sigmastate/SigSerializer.scala | 2 +- .../scala/sigmastate/crypto/BigIntegers.scala | 24 +++++++++++++++++++ .../sigmastate/eval/CostingDataContext.scala | 10 ++++---- .../scala/sigmastate/eval/Evaluation.scala | 1 - .../scala/sigmastate/eval/Extensions.scala | 5 ++-- .../scala/sigmastate/eval/BasicOpsTests.scala | 4 ++-- .../scala/sigmastate/lang/LangTests.scala | 9 ++++--- 7 files changed, 38 insertions(+), 17 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/SigSerializer.scala b/sigmastate/src/main/scala/sigmastate/SigSerializer.scala index d7f3875337..045274e75b 100644 --- a/sigmastate/src/main/scala/sigmastate/SigSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/SigSerializer.scala @@ -2,7 +2,7 @@ package sigmastate import com.typesafe.scalalogging.LazyLogging import gf2t.GF2_192_Poly -import org.bouncycastle.util.BigIntegers +import sigmastate.crypto.BigIntegers import scorex.util.encode.Base16 import sigmastate.Values.SigmaBoolean import sigmastate.basics.DLogProtocol.{ProveDlog, SecondDLogProverMessage} diff --git a/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala index 4ad615726d..981af1e1c5 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala @@ -63,4 +63,28 @@ object BigIntegers { // 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 + } + + def fromUnsignedByteArray(buf: Array[Byte]) = new BigInteger(1, buf) } diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 4c7156e5e3..c2a7e2fdfe 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -4,7 +4,6 @@ import com.google.common.primitives.{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.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)})" @@ -510,7 +510,7 @@ class CostingSigmaDslBuilder extends SigmaDslBuilder { dsl => override def toBigInteger(n: BigInt): BigInteger = n.asInstanceOf[CBigInt].wrappedValue - def GroupElement(p: ECPoint): GroupElement = p match { + 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") } @@ -524,8 +524,8 @@ 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 override def avlTree(operationFlags: Byte, digest: Coll[Byte], keyLength: Int, valueLengthOpt: Option[Int]): CAvlTree = { val treeData = AvlTreeData(ADDigest @@ digest.toArray, AvlTreeFlags(operationFlags), keyLength, valueLengthOpt) diff --git a/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala b/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala index 5f1b18d371..df8177939f 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._ diff --git a/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala index d3ba9b4132..791d094692 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.Ecp object Extensions { private val Colls = CostingSigmaDslBuilder.Colls @@ -88,7 +87,7 @@ object Extensions { } } - def showECPoint(p: ECPoint): String = { + def showECPoint(p: Ecp): String = { if (p.isInfinity) { "INF" } diff --git a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala index 4d024fc33d..393d473e8f 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala @@ -1,9 +1,9 @@ package sigmastate.eval 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 @@ -33,7 +33,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.getOrder SigmaDsl.byteArrayToBigInt( Colls.fromArray(groupOrder.subtract(BigInteger.ONE).toByteArray) diff --git a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala index 945816aab2..e6889e9c32 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala @@ -5,7 +5,6 @@ import sigmastate.Values.{LongConstant, SValue, Value, SigmaBoolean, ConcreteCol import sigmastate._ import java.math.BigInteger -import org.bouncycastle.math.ec.ECPoint import org.scalatest.Matchers import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.SCollection.SByteArray @@ -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() From a7823e573599a52a3709c78e3a8b7c637eaf1f86 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 23 Sep 2022 21:06:32 +0200 Subject: [PATCH 20/64] v5.x-restructure: abstract EC operations behind CryptoFacade --- .../scala/sigmastate/basics/BcDlogGroup.scala | 8 ++-- .../scala/sigmastate/basics/DlogGroup.scala | 4 +- .../sigmastate/crypto/CryptoContextJvm.scala | 16 ++++---- .../sigmastate/crypto/CryptoFacade.scala | 15 ++++++++ .../scala/sigmastate/crypto/Platform.scala | 37 ++++++++++++++++++- .../scala/sigmastate/crypto/package.scala | 1 + .../sigmastate/eval/CostingDataContext.scala | 10 ++--- .../scala/sigmastate/eval/Extensions.scala | 6 +-- .../GroupElementSerializer.scala | 11 +++--- .../GroupElementSerializerSpecification.scala | 7 +++- 10 files changed, 83 insertions(+), 32 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 94c5c2b607..9488dc6aa7 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -147,7 +147,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { * @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. @@ -159,7 +159,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { */ 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 @@ -168,7 +168,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { * BC treats EC as additive group while we treat that as multiplicative group. * Therefore, exponentiate point is multiply. */ - base.multiply(exp).asInstanceOf[ElemType] + CryptoFacade.multiplyPoint(base, exp) } @@ -209,7 +209,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { * @throws IllegalArgumentException */ override def multiplyGroupElements(groupElement1: ElemType, groupElement2: ElemType): ElemType = - groupElement1.add(groupElement2).asInstanceOf[ElemType] + CryptoFacade.addPoint(groupElement1, groupElement2) /** diff --git a/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala index 5223a77a53..ab6d177c89 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 sigmastate.crypto.Ecp +import sigmastate.crypto.{CryptoFacade, Ecp} /** @@ -96,7 +96,7 @@ trait DlogGroup { // if the given element is the identity, get a new random element while ( { - randGen.isInfinity + CryptoFacade.isInfinityPoint(randGen) }) randGen = createRandomElement() randGen diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala index 207e23e3da..5af4cff117 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala @@ -10,18 +10,18 @@ class CryptoContextJvm(x9params: X9ECParameters) extends CryptoContext { override def getModulus: BigInteger = curve.getField.getCharacteristic override def getOrder: BigInteger = x9params.getN - override def getGenerator: ECPoint = { - x9params.getG + override def getGenerator: Ecp = { + Platform.Ecp(x9params.getG) } - override def validatePoint(x: BigInteger, y: BigInteger): ECPoint = { - curve.validatePoint(x, y) + override def validatePoint(x: BigInteger, y: BigInteger): Ecp = { + Platform.Ecp(curve.validatePoint(x, y)) } - override def getInfinity(): ECPoint = { - curve.getInfinity + override def getInfinity(): Ecp = { + Platform.Ecp(curve.getInfinity) } - override def decodePoint(encoded: Array[Byte]): ECPoint = { - curve.decodePoint(encoded) + 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 index cd0387608e..5a1dd693bb 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala @@ -1,5 +1,20 @@ package sigmastate.crypto +import java.math.BigInteger + object CryptoFacade { + def normalizePoint(p: Ecp): Ecp = Platform.normalizePoint(p) + def createCryptoContext(): CryptoContext = Platform.createContext() + def negatePoint(p: Ecp): Ecp = Platform.negatePoint(p) + def isInfinityPoint(p: Ecp): Boolean = Platform.isInfinityPoint(p) + def multiplyPoint(p: Ecp, n: BigInteger): Ecp = Platform.multiplyPoint(p, n) + def addPoint(p1: Ecp, p2: Ecp): Ecp = Platform.addPoint(p1, p2) + def showPoint(p: Ecp): String = Platform.showPoint(p) + def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = Platform.testBitZeroOfFieldElem(p) + def getEncodedOfFieldElem(p: ECFieldElem): Array[Byte] = Platform.getEncodedOfFieldElem(p) + def getXCoord(p: Ecp): ECFieldElem = Platform.getXCoord(p) + def getYCoord(p: Ecp): ECFieldElem = Platform.getYCoord(p) + def getAffineXCoord(p: Ecp): ECFieldElem = Platform.getAffineXCoord(p) + def getAffineYCoord(p: Ecp): ECFieldElem = Platform.getAffineYCoord(p) } diff --git a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala index aecf1623db..a598f5f9c4 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala @@ -1,10 +1,43 @@ package sigmastate.crypto import org.bouncycastle.crypto.ec.CustomNamedCurves -import org.bouncycastle.math.ec.ECPoint +import org.bouncycastle.math.ec.{ECFieldElement, ECPoint} +import sigmastate.crypto + +import java.math.BigInteger /** JVM specific implementation of crypto methods*/ object Platform { - type Ecp = ECPoint + def getXCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getXCoord) + def getYCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getYCoord) + def getAffineXCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getAffineXCoord) + def getAffineYCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getAffineYCoord) + + def getEncodedOfFieldElem(p: ECFieldElem): Array[Byte] = p.value.getEncoded + + def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = p.value.testBitZero() + + def normalizePoint(p: Ecp): Ecp = Ecp(p.value.normalize()) + + 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,...)" + } + + def addPoint(p1: Ecp, p2: Ecp): Ecp = Ecp(p1.value.add(p2.value)) + + def multiplyPoint(p: Ecp, n: BigInteger): Ecp = Ecp(p.value.multiply(n)) + + def isInfinityPoint(p: Ecp): Boolean = p.value.isInfinity + + def negatePoint(p: Ecp): Ecp = Ecp(p.value.negate()) + + /** Opaque point type. */ + case class Ecp(private[crypto] val value: ECPoint) + + case class ECFieldElem(value: ECFieldElement) + 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 index 907d0e32be..e5dcc135ff 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/package.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/package.scala @@ -5,6 +5,7 @@ import org.bouncycastle.math.ec.ECPoint package object crypto { /** Instance of Elliptic Curve point. */ type Ecp = Platform.Ecp + 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 c2a7e2fdfe..3bb6d4d557 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -26,7 +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.Ecp +import sigmastate.crypto.{CryptoFacade, Ecp} import sigmastate.lang.TransformingSigmaBuilder import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer import sigmastate.serialization.{GroupElementSerializer, SigmaSerializer} @@ -104,16 +104,16 @@ case class CGroupElement(override val wrappedValue: Ecp) extends GroupElement wi override def getEncoded: Coll[Byte] = dsl.Colls.fromArray(GroupElementSerializer.toBytes(wrappedValue)) - override def isInfinity: Boolean = wrappedValue.isInfinity + override def isInfinity: Boolean = CryptoFacade.isInfinityPoint(wrappedValue) override def exp(k: BigInt): GroupElement = - dsl.GroupElement(wrappedValue.multiply(k.asInstanceOf[CBigInt].wrappedValue)) + dsl.GroupElement(CryptoFacade.multiplyPoint(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue)) override def multiply(that: GroupElement): GroupElement = - dsl.GroupElement(wrappedValue.add(that.asInstanceOf[CGroupElement].wrappedValue)) + dsl.GroupElement(CryptoFacade.addPoint(wrappedValue, that.asInstanceOf[CGroupElement].wrappedValue)) override def negate: GroupElement = - dsl.GroupElement(wrappedValue.negate()) + dsl.GroupElement(CryptoFacade.negatePoint(wrappedValue)) } /** A default implementation of [[SigmaProp]] interface. diff --git a/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala index 791d094692..7f92a81266 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala @@ -11,7 +11,7 @@ import sigmastate.SType.AnyOps import org.ergoplatform.ErgoBox import debox.{Buffer => DBuffer} import debox.cfor -import sigmastate.crypto.Ecp +import sigmastate.crypto.{CryptoFacade, Ecp} object Extensions { private val Colls = CostingSigmaDslBuilder.Colls @@ -92,9 +92,7 @@ object Extensions { "INF" } 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/serialization/GroupElementSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala index f4dabb9a15..3e5774d1bc 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.testBitZeroOfFieldElem(CryptoFacade.getAffineYCoord(normed)) + val X = CryptoFacade.getEncodedOfFieldElem(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.ctx.decodePoint(encoded).asInstanceOf[EcPointType] + curve.ctx.decodePoint(encoded) } else { curve.identity } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala index dd17ce069f..f876cb9bbe 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._ @@ -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)) } } } From 794d426eb2f1e6a66cd4067b6252926cc99ef4d0 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 24 Sep 2022 17:04:36 +0200 Subject: [PATCH 21/64] v5.x-restructure: test vectors for CryptoFacade --- .../crypto/GroupLawsSpecification.scala | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala index b77d3c5b0a..c224f9282a 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 { } } + 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.addPoint(p1, p2), + "p1.multiply(order)" -> CryptoFacade.multiplyPoint(p1, group.order), + "p1.multiply(order + 1)" -> CryptoFacade.multiplyPoint(p1, group.order.add(BigInteger.ONE)), + "p1.inverse" -> CryptoFacade.negatePoint(p1) + )) + } + + property("check test vectors") { + CryptoFacade.addPoint(p1, p2) shouldBe + Helpers.decodeECPoint("03de5e9c2806c05cd45a57d18c469743f42a0d2c84370b6662eb39d8a2990abed8") + + CryptoFacade.multiplyPoint(p1, group.order) shouldBe + Helpers.decodeECPoint("000000000000000000000000000000000000000000000000000000000000000000") + + CryptoFacade.multiplyPoint(p1, group.order.add(BigInteger.ONE)) shouldBe + Helpers.decodeECPoint("0381c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac") + + CryptoFacade.negatePoint(p1) shouldBe + Helpers.decodeECPoint("0281c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac") + } } From 88ab6f30cd75d5ad339aa45e9766fcbd7a51f0b2 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 24 Sep 2022 17:23:17 +0200 Subject: [PATCH 22/64] v5.x-restructure: test vectors for CryptoFacade --- .../scala/sigmastate/basics/BcDlogGroup.scala | 8 ++------ .../scala/sigmastate/crypto/CryptoFacade.scala | 7 +++---- .../main/scala/sigmastate/crypto/Platform.scala | 15 +++++++++++++-- .../sigmastate/eval/CostingDataContext.scala | 4 ++-- .../crypto/GroupLawsSpecification.scala | 12 ++++++------ 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 9488dc6aa7..99f71c4549 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -164,11 +164,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { //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. - */ - CryptoFacade.multiplyPoint(base, exp) + CryptoFacade.exponentiatePoint(base, exp) } @@ -209,7 +205,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { * @throws IllegalArgumentException */ override def multiplyGroupElements(groupElement1: ElemType, groupElement2: ElemType): ElemType = - CryptoFacade.addPoint(groupElement1, groupElement2) + CryptoFacade.multiplyPoints(groupElement1, groupElement2) /** diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala index 5a1dd693bb..f2ba6edf01 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala @@ -3,13 +3,12 @@ package sigmastate.crypto import java.math.BigInteger object CryptoFacade { - def normalizePoint(p: Ecp): Ecp = Platform.normalizePoint(p) - def createCryptoContext(): CryptoContext = Platform.createContext() + def normalizePoint(p: Ecp): Ecp = Platform.normalizePoint(p) def negatePoint(p: Ecp): Ecp = Platform.negatePoint(p) def isInfinityPoint(p: Ecp): Boolean = Platform.isInfinityPoint(p) - def multiplyPoint(p: Ecp, n: BigInteger): Ecp = Platform.multiplyPoint(p, n) - def addPoint(p1: Ecp, p2: Ecp): Ecp = Platform.addPoint(p1, p2) + def exponentiatePoint(p: Ecp, n: BigInteger): Ecp = Platform.exponentiatePoint(p, n) + def multiplyPoints(p1: Ecp, p2: Ecp): Ecp = Platform.multiplyPoints(p1, p2) def showPoint(p: Ecp): String = Platform.showPoint(p) def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = Platform.testBitZeroOfFieldElem(p) def getEncodedOfFieldElem(p: ECFieldElem): Array[Byte] = Platform.getEncodedOfFieldElem(p) diff --git a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala index a598f5f9c4..23301d810c 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala @@ -25,9 +25,20 @@ object Platform { s"ECPoint($rawX,$rawY,...)" } - def addPoint(p1: Ecp, p2: Ecp): Ecp = Ecp(p1.value.add(p2.value)) + 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)) + } - def multiplyPoint(p: Ecp, n: BigInteger): Ecp = Ecp(p.value.multiply(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)) + } def isInfinityPoint(p: Ecp): Boolean = p.value.isInfinity diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 3bb6d4d557..62b659d560 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -107,10 +107,10 @@ case class CGroupElement(override val wrappedValue: Ecp) extends GroupElement wi override def isInfinity: Boolean = CryptoFacade.isInfinityPoint(wrappedValue) override def exp(k: BigInt): GroupElement = - dsl.GroupElement(CryptoFacade.multiplyPoint(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue)) + dsl.GroupElement(CryptoFacade.exponentiatePoint(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue)) override def multiply(that: GroupElement): GroupElement = - dsl.GroupElement(CryptoFacade.addPoint(wrappedValue, that.asInstanceOf[CGroupElement].wrappedValue)) + dsl.GroupElement(CryptoFacade.multiplyPoints(wrappedValue, that.asInstanceOf[CGroupElement].wrappedValue)) override def negate: GroupElement = dsl.GroupElement(CryptoFacade.negatePoint(wrappedValue)) diff --git a/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala index c224f9282a..907a3ae1fb 100644 --- a/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala @@ -82,21 +82,21 @@ class GroupLawsSpecification extends SigmaTestingCommons { "p1" -> p1, "p2" -> p2, "p3" -> p3, - "p1.add(p2)" -> CryptoFacade.addPoint(p1, p2), - "p1.multiply(order)" -> CryptoFacade.multiplyPoint(p1, group.order), - "p1.multiply(order + 1)" -> CryptoFacade.multiplyPoint(p1, group.order.add(BigInteger.ONE)), + "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.addPoint(p1, p2) shouldBe + CryptoFacade.multiplyPoints(p1, p2) shouldBe Helpers.decodeECPoint("03de5e9c2806c05cd45a57d18c469743f42a0d2c84370b6662eb39d8a2990abed8") - CryptoFacade.multiplyPoint(p1, group.order) shouldBe + CryptoFacade.exponentiatePoint(p1, group.order) shouldBe Helpers.decodeECPoint("000000000000000000000000000000000000000000000000000000000000000000") - CryptoFacade.multiplyPoint(p1, group.order.add(BigInteger.ONE)) shouldBe + CryptoFacade.exponentiatePoint(p1, group.order.add(BigInteger.ONE)) shouldBe Helpers.decodeECPoint("0381c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac") CryptoFacade.negatePoint(p1) shouldBe From b91588fd0dd33149f17d7b1c6a09fa35e96fa495 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 24 Sep 2022 20:51:46 +0200 Subject: [PATCH 23/64] v5.x-restructure: remove ProvDlog.h --- .../src/main/scala/org/ergoplatform/ErgoAddress.scala | 2 +- .../src/main/scala/sigmastate/basics/DLogProtocol.scala | 7 +++---- .../utxo/examples/DHTupleExampleSpecification.scala | 4 ++-- .../sigmastate/utxo/examples/MixExampleSpecification.scala | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala index 1116b9fbf4..ce13b530f4 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala @@ -125,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/sigmastate/basics/DLogProtocol.scala b/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala index b2ee643bce..96218e1b5f 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala @@ -27,8 +27,7 @@ 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) + lazy val pkBytes: Array[Byte] = GroupElementSerializer.toBytes(value) } object ProveDlog { @@ -111,7 +110,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 +132,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/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/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 From c8d048ca9b6c5c33444fea7299c949a92d3a0eec Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 24 Sep 2022 21:17:57 +0200 Subject: [PATCH 24/64] v5.x-restructure: remove unused methods from sigmastate.basics --- .../scala/sigmastate/basics/BcDlogGroup.scala | 138 +----------------- .../scala/sigmastate/basics/DlogGroup.scala | 11 -- 2 files changed, 1 insertion(+), 148 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 99f71c4549..e75346b43b 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -5,8 +5,7 @@ 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 import scala.collection.compat.immutable.ArraySeq @@ -99,19 +98,6 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { //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 = ctx.getGenerator - /** - * 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 - */ - def checkCurveMembership(x: BigInteger, y: BigInteger): Boolean = { - Try(ctx.validatePoint(x, y)).isSuccess - } - - /** * This function calculates k, the maximum length in bytes of a string to be converted to a Group Element of this group. * @@ -207,21 +193,6 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { override def multiplyGroupElements(groupElement1: ElemType, groupElement2: ElemType): ElemType = CryptoFacade.multiplyPoints(groupElement1, groupElement2) - - /** - * 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) - /** * Computes the product of several exponentiations of the same base * and distinct exponents. @@ -265,113 +236,6 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { */ 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 SecP256K1Group extends BcDlogGroup(CryptoFacade.createCryptoContext()) \ No newline at end of file diff --git a/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala index ab6d177c89..cfacbc352e 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala @@ -102,17 +102,6 @@ trait DlogGroup { 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. From 8f988b71b1c0e949c423d3c18eabdf8f35e6f345 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 25 Sep 2022 00:49:28 +0200 Subject: [PATCH 25/64] v5.x-restructure: GF_192.java migrated to Scala --- .../scala/sigmastate/crypto/GF2_192.scala | 552 ++++++++++++++++++ 1 file changed, 552 insertions(+) create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala 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..1f8ce7143f --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala @@ -0,0 +1,552 @@ +package sigmastate.crypto + +import debox.cfor + +import java.util + +class GF2_192 { + private 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) + + // using irreducible polynomial x^192+x^7+x^2+x+1 + // We need only the last word + private val 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 + private val irredMuls = Array( + 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 + ) + + /** + * + * @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 + + /** + * 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 + } + + /** + * 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 + */ + def mul(res: GF2_192, a: GF2_192, b: Byte): Unit = { + var w0: Long = 0 + var w1: Long = 0 + var w2: Long = 0 + var w3: Long = 0 + cfor(7)(_ >= 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 + } + + 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) + } + + // These tables are used in power2To2ToK and sqr -- see explanation in power2To2ToK. They take up about about 14KB. + private val powTable0: Array[Array[Long]] = Array( + Array(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), + Array(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), + Array(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), + Array(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), + Array(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), + Array(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), + Array(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 val powTable1: Array[Array[Long]] = Array( + Array(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 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), + Array(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), + Array(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), + Array(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), + Array(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), + Array(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), + Array(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 val powTable2: Array[Array[Long]] = Array( + Array(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 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), + Array(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 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), + Array(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), + Array(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), + Array(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), + Array(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), + Array(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. + 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 => + val 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 + z.word(iW) = w >>> 1 + i += 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 + */ + override def toString: String = + String.format("%016X", word(2)) + + String.format("%016X", word(1)) + + String.format("%016X", word(0)) +} \ No newline at end of file From 1e25036f04b49909cfaf9b7bad03a2800fb2974b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 25 Sep 2022 10:51:05 +0200 Subject: [PATCH 26/64] v5.x-restructure: GF_192.java migrated to Scala (tests fixed) --- .../main/scala/sigmastate/SigSerializer.scala | 5 +- .../main/scala/sigmastate/UncheckedTree.scala | 2 +- .../main/scala/sigmastate/UnprovenTree.scala | 4 +- .../scala/sigmastate/crypto/GF2_192.scala | 436 +++++++++--------- .../scala/sigmastate/crypto/GF2_192_Poly.java | 247 ++++++++++ .../interpreter/ProverInterpreter.scala | 4 +- .../src/test/java/gf2t/GF2_192Test.java | 2 + .../SigmaProtocolSpecification.scala | 2 +- .../sigmastate/helpers/SigmaPPrint.scala | 2 +- .../SigSerializerSpecification.scala | 3 +- 10 files changed, 475 insertions(+), 232 deletions(-) create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.java diff --git a/sigmastate/src/main/scala/sigmastate/SigSerializer.scala b/sigmastate/src/main/scala/sigmastate/SigSerializer.scala index 045274e75b..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 sigmastate.crypto.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/crypto/GF2_192.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala index 1f8ce7143f..662a2c2939 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala @@ -87,26 +87,6 @@ class GF2_192 { override def hashCode = util.Arrays.hashCode(word) - // using irreducible polynomial x^192+x^7+x^2+x+1 - // We need only the last word - private val 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 - private val irredMuls = Array( - 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 - ) - /** * * @return long array of length 3 containing the three words of the field element @@ -153,6 +133,216 @@ class GF2_192 { */ 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. * @@ -191,7 +381,6 @@ class GF2_192 { 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) { @@ -223,7 +412,6 @@ class GF2_192 { 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 @@ -238,7 +426,6 @@ class GF2_192 { // 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) @@ -252,33 +439,6 @@ class GF2_192 { 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 - */ - def mul(res: GF2_192, a: GF2_192, b: Byte): Unit = { - var w0: Long = 0 - var w1: Long = 0 - var w2: Long = 0 - var w3: Long = 0 - cfor(7)(_ >= 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 - } - 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} @@ -288,10 +448,8 @@ class GF2_192 { // 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 @@ -311,158 +469,6 @@ class GF2_192 { mul(res, res, zTo2ToK1s2ToK0s) } - // These tables are used in power2To2ToK and sqr -- see explanation in power2To2ToK. They take up about about 14KB. - private val powTable0: Array[Array[Long]] = Array( - Array(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), - Array(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), - Array(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), - Array(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), - Array(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), - Array(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), - Array(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 val powTable1: Array[Array[Long]] = Array( - Array(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 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), - Array(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), - Array(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), - Array(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), - Array(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), - Array(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), - Array(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 val powTable2: Array[Array[Long]] = Array( - Array(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 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), - Array(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 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), - Array(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), - Array(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), - Array(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), - Array(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), - Array(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< - val w = z.word(iW) + cfor(0)(_ < z.word.length, _ + 1) { iW => + var w = z.word(iW) maxIndex += 64 - while (i < maxIndex ) { + 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 - z.word(iW) = w >>> 1 + w >>>= 1 i += 1 } } @@ -540,13 +547,4 @@ class GF2_192 { res.word(2) = t2 } } - - /** - * - * @return bits of this in hexadecimal notation, most significant on the left - */ - override def toString: String = - String.format("%016X", word(2)) + - String.format("%016X", word(1)) + - String.format("%016X", word(0)) -} \ No newline at end of file +} diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.java b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.java new file mode 100644 index 0000000000..4da5b16f12 --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.java @@ -0,0 +1,247 @@ +/* + 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 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/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index c6aead2b29..d49cba76f3 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -1,6 +1,5 @@ package sigmastate.interpreter -import gf2t.{GF2_192, GF2_192_Poly} import sigmastate.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule} import sigmastate.kiama.rewriting.Strategy import scalan.util.CollectionUtil._ @@ -11,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 @@ -469,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) diff --git a/sigmastate/src/test/java/gf2t/GF2_192Test.java b/sigmastate/src/test/java/gf2t/GF2_192Test.java index 46a4110b82..f438907efe 100644 --- a/sigmastate/src/test/java/gf2t/GF2_192Test.java +++ b/sigmastate/src/test/java/gf2t/GF2_192Test.java @@ -30,6 +30,8 @@ import org.junit.Test; import org.junit.runner.RunWith; +import sigmastate.crypto.GF2_192; +import sigmastate.crypto.GF2_192_Poly; import java.util.Random; import java.util.Arrays; 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/helpers/SigmaPPrint.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala index f9a5e64885..6d08428d9c 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 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 From 8204d119ee4cf691d87b0765d2c8dabafa9e9e13 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 25 Sep 2022 12:18:57 +0200 Subject: [PATCH 27/64] v5.x-restructure: GF_192.java migrated to Scala (tests fixed 2) --- sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala index 662a2c2939..abbbecd4c2 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala @@ -258,10 +258,9 @@ class GF2_192 { * * @return bits of this in hexadecimal notation, most significant on the left */ - override def toString: String = - String.format("%016X", word(2)) + - String.format("%016X", word(1)) + - String.format("%016X", word(0)) + override def toString: String = { + f"${word(2)}%016X${word(1)}%016X${word(0)}%016X" + } } object GF2_192 { From 300d90df4a76f1ce2468ecbbeb7a953ba3813db9 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 25 Sep 2022 16:20:06 +0200 Subject: [PATCH 28/64] v5.x-restructure: GF_192_Poly.java migrated to Scala --- sigmastate/src/main/java/gf2t/GF2_192.java | 2 +- .../src/main/java/gf2t/GF2_192_Poly.java | 4 +- .../scala/sigmastate/crypto/GF2_192.scala | 32 ++- .../scala/sigmastate/crypto/GF2_192_Poly.java | 247 ---------------- .../sigmastate/crypto/GF2_192_Poly.scala | 263 ++++++++++++++++++ .../sigmastate/helpers/SigmaPPrint.scala | 2 +- 6 files changed, 297 insertions(+), 253 deletions(-) delete mode 100644 sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.java create mode 100644 sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala diff --git a/sigmastate/src/main/java/gf2t/GF2_192.java b/sigmastate/src/main/java/gf2t/GF2_192.java index dc0c166bcf..b882894c30 100644 --- a/sigmastate/src/main/java/gf2t/GF2_192.java +++ b/sigmastate/src/main/java/gf2t/GF2_192.java @@ -31,7 +31,7 @@ import java.util.Arrays; public class GF2_192 { - private final long [] word = new long[3]; + public final long [] word = new long[3]; /** * diff --git a/sigmastate/src/main/java/gf2t/GF2_192_Poly.java b/sigmastate/src/main/java/gf2t/GF2_192_Poly.java index d3ccd61fc3..555c2694fe 100644 --- a/sigmastate/src/main/java/gf2t/GF2_192_Poly.java +++ b/sigmastate/src/main/java/gf2t/GF2_192_Poly.java @@ -32,9 +32,9 @@ import java.util.Arrays; public class GF2_192_Poly { - private final GF2_192 [] c; // must be not null and of length at least 1 + public 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 + public 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 /** diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala index abbbecd4c2..36e8343e2b 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala @@ -1,11 +1,39 @@ +/* + 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 { - private val word: Array[Long] = new Array[Long](3) +class GF2_192 extends AnyRef { + private[crypto] val word: Array[Long] = new Array[Long](3) /** * returns a copy of the field element diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.java b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.java deleted file mode 100644 index 4da5b16f12..0000000000 --- a/sigmastate/src/main/scala/sigmastate/crypto/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 sigmastate.crypto; - -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/sigmastate/crypto/GF2_192_Poly.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala new file mode 100644 index 0000000000..1729980ad1 --- /dev/null +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala @@ -0,0 +1,263 @@ +/* + 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] = { + var 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) + val resOld = new gf2t.GF2_192_Poly(coeff0, moreCoeffs) + assert(res.deg == resOld.deg && + res.c.length == resOld.c.length && + res.c.zip(resOld.c).forall { case (x, y) => + Arrays.equals(x.word, y.word) + } + ) + 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/test/scala/sigmastate/helpers/SigmaPPrint.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala index 6d08428d9c..3122e2f5f0 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/SigmaPPrint.scala @@ -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)) From b9667f0f5bfcb1cffc276b980b56bae1f5de7b03 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 25 Sep 2022 17:39:36 +0200 Subject: [PATCH 29/64] v5.x-restructure: test migrated GF2_192_Poly.scala against "old" Java version. --- .../src/main/java/gf2t/GF2_192_Poly.java | 9 ++++- .../scala/sigmastate/crypto/GF2_192.scala | 4 ++ .../sigmastate/crypto/GF2_192_Poly.scala | 40 +++++++++++++++---- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/sigmastate/src/main/java/gf2t/GF2_192_Poly.java b/sigmastate/src/main/java/gf2t/GF2_192_Poly.java index 555c2694fe..aee50cff8d 100644 --- a/sigmastate/src/main/java/gf2t/GF2_192_Poly.java +++ b/sigmastate/src/main/java/gf2t/GF2_192_Poly.java @@ -37,6 +37,11 @@ public class GF2_192_Poly { public 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 + public GF2_192_Poly(GF2_192[] _c, int _deg) { + c = _c; + deg = _deg; + } + /** * Constructs the polynomial given the byte array representation of the coefficients. * Coefficient of degree zero is given separately. Each coefficient should be given @@ -141,7 +146,7 @@ public GF2_192 evaluate (byte x) { * @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) { + public void addMonicTimesConstantTo (GF2_192_Poly p, GF2_192 r) { GF2_192 t = new GF2_192(); for (int i = 0; i 0; i--) { diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala index 36e8343e2b..5aeece875b 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala @@ -35,6 +35,10 @@ import java.util class GF2_192 extends AnyRef { private[crypto] val word: Array[Long] = new Array[Long](3) + def toOld: gf2t.GF2_192 = new gf2t.GF2_192(word.clone()) + + def equalsOld(old: gf2t.GF2_192) = util.Arrays.equals(word, old.word) + /** * returns a copy of the field element * diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala index 1729980ad1..097dd07d67 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala @@ -40,6 +40,8 @@ class GF2_192_Poly { 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 + def toOld: gf2t.GF2_192_Poly = new gf2t.GF2_192_Poly(c.map(gf => if (gf == null) null else gf.toOld), deg) + /** * Constructs the polynomial given the byte array representation of the coefficients. * Coefficient of degree zero is given separately. Each coefficient should be given @@ -72,6 +74,8 @@ class GF2_192_Poly { GF2_192.mul(res, res, x) GF2_192.add(res, res, c(d)) } + val resOld = this.toOld.evaluate(x) + assert(res.equalsOld(resOld)) res } @@ -82,6 +86,7 @@ class GF2_192_Poly { * @param r the constant by which p is multiplied before being added */ private def addMonicTimesConstantTo(p: GF2_192_Poly, r: GF2_192): Unit = { + val old = this.toOld val t: GF2_192 = new GF2_192 cfor(0)(_ < p.deg, _ + 1) { i => GF2_192.mul(t, p.c(i), r) @@ -89,6 +94,10 @@ class GF2_192_Poly { } deg = p.deg c(deg) = new GF2_192(r) + + // TODO remove after committed and tests pass + old.addMonicTimesConstantTo(p.toOld, r.toOld) + assert(this.equalsOld(old)) } /** @@ -97,6 +106,7 @@ class GF2_192_Poly { * @param r the constant term of the monomial */ private def monicTimesMonomial(r: Byte): Unit = { + val old = this.toOld deg += 1 c(deg) = new GF2_192(1) cfor(deg - 1)(_ > 0, _ - 1) { i => @@ -105,6 +115,10 @@ class GF2_192_Poly { GF2_192.add(c(i), c(i), c(i - 1)) } GF2_192.mul(c(0), c(0), r) + + // TODO remove after committed and tests pass + old.monicTimesMonomial(r) + assert(this.equalsOld(old)) } /** @@ -151,11 +165,15 @@ class GF2_192_Poly { * @return array of all coefficients (except possibly 0th depending on coeff0) */ def toByteArray(coeff0: Boolean): Array[Byte] = { - var c0 = if (coeff0) 0 else 1 + 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) } + + // TODO remove after committed and tests pass + assert(Arrays.equals(ret, this.toOld.toByteArray(coeff0))) + ret } @@ -177,6 +195,12 @@ class GF2_192_Poly { case _ => false } } + + def equalsOld(old: gf2t.GF2_192_Poly): Boolean = { + deg == old.deg && + c.length == old.c.length && + c.zip(old.c).forall { case (x, y) => if (x == null) y == null else x.equalsOld(y) } + } } object GF2_192_Poly { @@ -192,12 +216,7 @@ object GF2_192_Poly { def fromByteArray(coeff0: Array[Byte], moreCoeffs: Array[Byte]): GF2_192_Poly = { val res = new GF2_192_Poly(coeff0, moreCoeffs) val resOld = new gf2t.GF2_192_Poly(coeff0, moreCoeffs) - assert(res.deg == resOld.deg && - res.c.length == resOld.c.length && - res.c.zip(resOld.c).forall { case (x, y) => - Arrays.equals(x.word, y.word) - } - ) + assert(res.equalsOld(resOld)) res } @@ -256,6 +275,13 @@ object GF2_192_Poly { GF2_192.mul(t, t, s) result.addMonicTimesConstantTo(vanishingPoly, t) } + + // TODO remove after committed and tests pass + val resOld = gf2t.GF2_192_Poly.interpolate(points, + values.map(_.toOld), + if (valueAt0 == null) null else valueAt0.toOld) + assert(result.equalsOld(resOld)) + result } From 3cc629b7a16f59820d81ade06a9a84f4749e22d1 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 25 Sep 2022 20:54:25 +0200 Subject: [PATCH 30/64] v5.x-restructure: remove old vs new testing code --- sigmastate/src/main/java/gf2t/GF2_192.java | 580 ------------------ .../src/main/java/gf2t/GF2_192_Poly.java | 252 -------- .../scala/sigmastate/crypto/GF2_192.scala | 4 - .../sigmastate/crypto/GF2_192_Poly.scala | 32 - 4 files changed, 868 deletions(-) delete mode 100644 sigmastate/src/main/java/gf2t/GF2_192.java delete mode 100644 sigmastate/src/main/java/gf2t/GF2_192_Poly.java 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 b882894c30..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 { - public 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 aee50cff8d..0000000000 --- a/sigmastate/src/main/java/gf2t/GF2_192_Poly.java +++ /dev/null @@ -1,252 +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 { - public final GF2_192 [] c; // must be not null and of length at least 1 - - public 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 - - public GF2_192_Poly(GF2_192[] _c, int _deg) { - c = _c; - deg = _deg; - } - - /** - * 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 - */ - public 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/sigmastate/crypto/GF2_192.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala index 5aeece875b..36e8343e2b 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192.scala @@ -35,10 +35,6 @@ import java.util class GF2_192 extends AnyRef { private[crypto] val word: Array[Long] = new Array[Long](3) - def toOld: gf2t.GF2_192 = new gf2t.GF2_192(word.clone()) - - def equalsOld(old: gf2t.GF2_192) = util.Arrays.equals(word, old.word) - /** * returns a copy of the field element * diff --git a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala index 097dd07d67..dc0617ea29 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala @@ -40,8 +40,6 @@ class GF2_192_Poly { 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 - def toOld: gf2t.GF2_192_Poly = new gf2t.GF2_192_Poly(c.map(gf => if (gf == null) null else gf.toOld), deg) - /** * Constructs the polynomial given the byte array representation of the coefficients. * Coefficient of degree zero is given separately. Each coefficient should be given @@ -74,8 +72,6 @@ class GF2_192_Poly { GF2_192.mul(res, res, x) GF2_192.add(res, res, c(d)) } - val resOld = this.toOld.evaluate(x) - assert(res.equalsOld(resOld)) res } @@ -86,7 +82,6 @@ class GF2_192_Poly { * @param r the constant by which p is multiplied before being added */ private def addMonicTimesConstantTo(p: GF2_192_Poly, r: GF2_192): Unit = { - val old = this.toOld val t: GF2_192 = new GF2_192 cfor(0)(_ < p.deg, _ + 1) { i => GF2_192.mul(t, p.c(i), r) @@ -94,10 +89,6 @@ class GF2_192_Poly { } deg = p.deg c(deg) = new GF2_192(r) - - // TODO remove after committed and tests pass - old.addMonicTimesConstantTo(p.toOld, r.toOld) - assert(this.equalsOld(old)) } /** @@ -106,7 +97,6 @@ class GF2_192_Poly { * @param r the constant term of the monomial */ private def monicTimesMonomial(r: Byte): Unit = { - val old = this.toOld deg += 1 c(deg) = new GF2_192(1) cfor(deg - 1)(_ > 0, _ - 1) { i => @@ -115,10 +105,6 @@ class GF2_192_Poly { GF2_192.add(c(i), c(i), c(i - 1)) } GF2_192.mul(c(0), c(0), r) - - // TODO remove after committed and tests pass - old.monicTimesMonomial(r) - assert(this.equalsOld(old)) } /** @@ -170,10 +156,6 @@ class GF2_192_Poly { cfor(c0)(_ <= deg, _ + 1) { i => c(i).toByteArray(ret, (i - c0) * 24) } - - // TODO remove after committed and tests pass - assert(Arrays.equals(ret, this.toOld.toByteArray(coeff0))) - ret } @@ -195,12 +177,6 @@ class GF2_192_Poly { case _ => false } } - - def equalsOld(old: gf2t.GF2_192_Poly): Boolean = { - deg == old.deg && - c.length == old.c.length && - c.zip(old.c).forall { case (x, y) => if (x == null) y == null else x.equalsOld(y) } - } } object GF2_192_Poly { @@ -215,8 +191,6 @@ object GF2_192_Poly { // 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) - val resOld = new gf2t.GF2_192_Poly(coeff0, moreCoeffs) - assert(res.equalsOld(resOld)) res } @@ -276,12 +250,6 @@ object GF2_192_Poly { result.addMonicTimesConstantTo(vanishingPoly, t) } - // TODO remove after committed and tests pass - val resOld = gf2t.GF2_192_Poly.interpolate(points, - values.map(_.toOld), - if (valueAt0 == null) null else valueAt0.toOld) - assert(result.equalsOld(resOld)) - result } From 5bd5dd6c003399b55896b04a1f7ab8317c55ad46 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 27 Sep 2022 20:00:54 +0200 Subject: [PATCH 31/64] v5.x-restructure: update dependencies --- build.sbt | 12 ++++++------ .../src/main/scala/org/ergoplatform/ErgoBox.scala | 2 +- .../serialization/AvlTreeSpecification.scala | 2 +- .../serialization/generators/ObjectGenerators.scala | 4 ++-- .../utxo/AVLTreeScriptsSpecification.scala | 6 +++--- .../scala/sigmastate/utxo/examples/IcoExample.scala | 8 ++++---- .../sigmastate/utxo/examples/LetsSpecification.scala | 12 ++++++------ .../utxo/examples/MASTExampleSpecification.scala | 2 +- .../utxo/examples/OracleExamplesSpecification.scala | 4 ++-- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/build.sbt b/build.sbt index f95cfb3784..002204c143 100644 --- a/build.sbt +++ b/build.sbt @@ -52,12 +52,12 @@ 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 scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT" -//val debox = "org.scorexfoundation" %% "debox" % "0.9.0-8-3da95c40-SNAPSHOT" +val bouncycastleBcprov = "org.bouncycastle" % "bcprov-jdk15on" % "1.66" +val scrypto = "org.scorexfoundation" %% "scrypto" % "2.2.1-25-dafca54c-SNAPSHOT" +//val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8" +//val debox = "org.scorexfoundation" %% "debox" % "0.9.0" +val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8-19-0331a3d9-SNAPSHOT" +val debox = "org.scorexfoundation" %% "debox" % "0.9.0-8-3da95c40-SNAPSHOT" val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" val guava = "com.google.guava" % "guava" % "30.1.1-jre" diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala index e097a6302f..f1c883ab60 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -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/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/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 537c616b05..1693a302e4 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 } @@ -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) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index e7abf54a0a..a9b07f8b00 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -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/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala index 790cf69afc..a52c4d2999 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala @@ -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/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index 3774e5ddc2..178d053bd2 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -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) From 17b1f4c168a6a509fd25d3da986e0005ed97dd6d Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 27 Sep 2022 20:09:05 +0200 Subject: [PATCH 32/64] v5.x-restructure: replace import com.google.common.primitives with scorex.utils --- sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala | 2 +- sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala | 2 +- .../src/main/scala/sigmastate/eval/CostingDataContext.scala | 2 +- sigmastate/src/main/scala/sigmastate/utils/Extensions.scala | 2 +- .../scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala | 2 +- .../sigmastate/utxo/ErgoLikeInterpreterSpecification.scala | 2 +- .../src/test/scala/sigmastate/utxo/examples/IcoExample.scala | 2 +- .../sigmastate/utxo/examples/OracleExamplesSpecification.scala | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala index ce13b530f4..2e9e8ef805 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala @@ -2,7 +2,7 @@ package org.ergoplatform import java.util -import com.google.common.primitives.Ints +import scorex.utils.Ints import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix import scorex.crypto.hash.{Digest32, Blake2b256} import scorex.util.encode.Base58 diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala index f1c883ab60..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 diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 62b659d560..58c1aa41e3 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -1,6 +1,6 @@ package sigmastate.eval -import com.google.common.primitives.{Ints, Longs} +import scorex.utils.{Ints, Longs} import java.math.BigInteger import java.util.Arrays 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/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index a9b07f8b00..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._ 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/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala index a52c4d2999..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 diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index 178d053bd2..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} From 4b21c37588fda4bf1d2f88e40189c5d923def861 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 28 Sep 2022 11:09:46 +0200 Subject: [PATCH 33/64] v5.x-restructure: migrate GF2 tests to Scala --- .../src/test/java/gf2t/GF2_192Test.java | 713 ------------------ .../src/test/java/gf2t/ReadableTest.java | 37 - .../crypto/GF2_192_Specification.scala | 692 +++++++++++++++++ 3 files changed, 692 insertions(+), 750 deletions(-) delete mode 100644 sigmastate/src/test/java/gf2t/GF2_192Test.java delete mode 100644 sigmastate/src/test/java/gf2t/ReadableTest.java create mode 100644 sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala 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 f438907efe..0000000000 --- a/sigmastate/src/test/java/gf2t/GF2_192Test.java +++ /dev/null @@ -1,713 +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 sigmastate.crypto.GF2_192; -import sigmastate.crypto.GF2_192_Poly; - -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("(?> 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) + } + } +} From 2d186951a890adf59ea2cb4202fa256258391e90 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 28 Sep 2022 22:40:10 +0200 Subject: [PATCH 34/64] v5.x-restructure: remove guava dependence --- build.sbt | 2 +- .../sigmastate/kiama/rewriting/Rewriter.scala | 27 ++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index 002204c143..517bfc7931 100644 --- a/build.sbt +++ b/build.sbt @@ -145,7 +145,7 @@ lazy val common = Project("common", file("common")) .settings(commonSettings ++ testSettings, libraryDependencies ++= Seq( "org.scala-lang" % "scala-reflect" % scalaVersion.value, - debox, scalaCompat, guava + debox, scalaCompat )) .settings(publish / skip := true) diff --git a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala index cc97baa503..c30d9668b1 100644 --- a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala +++ b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala @@ -11,6 +11,8 @@ 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 @@ -216,13 +218,11 @@ trait Rewriter { */ object Duplicator { - import com.google.common.base.Function - import com.google.common.cache.{CacheBuilder, CacheLoader} import java.lang.reflect.Constructor type Duper = (Any, Array[AnyRef]) => Any - object MakeDuper extends Function[Class[_], Duper] { + object MakeDuper extends (Class[_] => Duper) { def apply(clazz : Class[_]) : Duper = try { @@ -280,12 +280,25 @@ trait Rewriter { } - val cache = CacheBuilder.newBuilder.weakKeys.build( - CacheLoader.from(MakeDuper) - ) + 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 duper = cache.get(t.getClass) + val clazz = t.getClass + val duper = getDuper(clazz) duper(t, children).asInstanceOf[T] } From ae79c7af9dbdfc391a9a1cecbdc174a2ec2aae07 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 2 Oct 2022 12:03:56 +0200 Subject: [PATCH 35/64] v5.x-restructure: cleanup build.sbt --- build.sbt | 122 ++++-------------------------------------------------- 1 file changed, 9 insertions(+), 113 deletions(-) diff --git a/build.sbt b/build.sbt index 517bfc7931..b4c32397ab 100644 --- a/build.sbt +++ b/build.sbt @@ -60,7 +60,6 @@ val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8-19-033 val debox = "org.scorexfoundation" %% "debox" % "0.9.0-8-3da95c40-SNAPSHOT" val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" -val guava = "com.google.guava" % "guava" % "30.1.1-jre" val scalaCompat = "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0" val testingDependencies = Seq( @@ -86,7 +85,11 @@ libraryDependencies ++= Seq( scorexUtil, "org.bouncycastle" % "bcprov-jdk15on" % "1.+", fastparse, debox, spireMacros, scalaCompat -) ++ testingDependencies +) ++ 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" @@ -96,24 +99,8 @@ 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") -// set bytecode version to 8 to fix NoSuchMethodError for various ByteBuffer methods -// see https://github.com/eclipse/jetty.project/issues/3244 -// these options applied only in "compile" task since scalac crashes on scaladoc compilation with "-release 8" -// see https://github.com/scala/community-builds/issues/796#issuecomment-423395500 -//javacOptions in(Compile, compile) ++= Seq("-target", "8", "-source", "8" ) -//scalacOptions in(Compile, compile) ++= Seq("-release", "8") - -//uncomment lines below if the Scala compiler hangs to see where it happens -//scalacOptions in Compile ++= Seq("-Xprompt", "-Ydebug", "-verbose" ) - parallelExecution in Test := false publishArtifact in Test := true @@ -142,7 +129,7 @@ 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, scalaCompat @@ -163,14 +150,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) @@ -229,94 +216,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 -} From 2b88c3e50276f27021c02762032351067457df24 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 2 Oct 2022 14:15:41 +0200 Subject: [PATCH 36/64] v5.x-restructure: updated scalatest, scalacheck deps --- build.sbt | 7 ++++--- common/src/test/scala/scalan/BaseTests.scala | 13 ++++++++----- common/src/test/scala/scalan/TestUtils.scala | 3 ++- .../scala/sigmastate/VersionTestingProperty.scala | 5 +++-- .../test/scala/special/collections/CollsTests.scala | 5 +++-- .../test/scala/sigmastate/CrossVersionProps.scala | 5 +++-- .../src/test/scala/sigmastate/TestsBase.scala | 2 +- .../sigmastate/crypto/GF2_192_Specification.scala | 5 +++-- .../test/scala/sigmastate/eval/BasicOpsTests.scala | 6 ++++-- .../scala/sigmastate/helpers/NegativeTesting.scala | 3 ++- .../sigmastate/helpers/SigmaTestingCommons.scala | 12 +++++++----- .../src/test/scala/sigmastate/lang/LangTests.scala | 8 ++++---- .../scala/sigmastate/lang/SigmaBinderTest.scala | 7 ++++--- .../scala/sigmastate/lang/SigmaBuilderTest.scala | 7 ++++--- .../scala/sigmastate/lang/SigmaParserTest.scala | 7 ++++--- .../test/scala/sigmastate/lang/SigmaTyperTest.scala | 8 +++++--- .../serialization/SerializationSpecification.scala | 13 ++++++++----- .../serialization/generators/ObjectGenerators.scala | 10 +++++----- .../test/scala/sigmastate/utils/HelpersTests.scala | 7 ++++--- .../utils/SparseArrayContainerSpecification.scala | 9 +++++---- .../utxo/SerializationRoundTripSpec.scala | 11 ++++++----- .../test/scala/special/sigma/SigmaDslTesting.scala | 9 +++++---- 22 files changed, 94 insertions(+), 68 deletions(-) diff --git a/build.sbt b/build.sbt index b4c32397ab..89fd3dc0ee 100644 --- a/build.sbt +++ b/build.sbt @@ -63,9 +63,10 @@ val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" 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 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/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/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/TestsBase.scala b/sigmastate/src/test/scala/sigmastate/TestsBase.scala index 829054c32c..9511722a07 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 diff --git a/sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala b/sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala index 677dc3f342..b415fc99bd 100644 --- a/sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala +++ b/sigmastate/src/test/scala/sigmastate/crypto/GF2_192_Specification.scala @@ -1,13 +1,14 @@ package sigmastate.crypto import org.junit.Assert.assertFalse -import org.scalatest.{Matchers, PropSpec} +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 PropSpec +class GF2_192_Specification extends AnyPropSpec with ScalaCheckDrivenPropertyChecks with Matchers { diff --git a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala index 393d473e8f..5dfcfb75aa 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.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) diff --git a/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala index e80ed50594..5ab6a39ad7 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/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 e6889e9c32..a512b25de9 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala @@ -1,11 +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.scalatest.Matchers +import java.math.BigInteger import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.SCollection.SByteArray import sigmastate.basics.ProveDHTuple 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/SigmaParserTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala index 88e5f69a94..b0cbe2f6c7 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/SigmaTyperTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala index ca6bcbadc3..f7b86f35fc 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/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/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 1693a302e4..b776bd8682 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -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) @@ -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/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/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index 3d98c8a110..4a4fe026be 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 => From d4f80bbbbfacb8ba21edeb8eabc841f721e7ec40 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 2 Oct 2022 19:47:14 +0200 Subject: [PATCH 37/64] v5.x-restructure: remove ReflectionUtil.scala --- .../scala/scalan/util/ReflectionUtil.scala | 41 ------------------- core/src/main/scala/scalan/Entities.scala | 3 +- core/src/main/scala/scalan/TypeDescs.scala | 5 +-- 3 files changed, 3 insertions(+), 46 deletions(-) delete mode 100644 common/src/main/scala/scalan/util/ReflectionUtil.scala diff --git a/common/src/main/scala/scalan/util/ReflectionUtil.scala b/common/src/main/scala/scalan/util/ReflectionUtil.scala deleted file mode 100644 index c463e8a787..0000000000 --- a/common/src/main/scala/scalan/util/ReflectionUtil.scala +++ /dev/null @@ -1,41 +0,0 @@ -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 { - private def isSpecialChar(c: Char): Boolean = { - ('0' <= c && c <= '9') || c == '$' - } - def safeSimpleName: String = { - if (cl.getEnclosingClass == null) return cl.getSimpleName - val simpleName = cl.getName.substring(cl.getEnclosingClass.getName.length) - val length = simpleName.length - var index = 0 - while (index < length && isSpecialChar(simpleName.charAt(index))) { index += 1 } - // Eventually, this is the empty string iff this is an anonymous class - simpleName.substring(index) - } - } -} diff --git a/core/src/main/scala/scalan/Entities.scala b/core/src/main/scala/scalan/Entities.scala index 376bd5a529..6c1c062f4c 100644 --- a/core/src/main/scala/scalan/Entities.scala +++ b/core/src/main/scala/scalan/Entities.scala @@ -1,7 +1,6 @@ package scalan import scala.language.higherKinds -import scalan.util.ReflectionUtil.ClassOps /** A slice in the Scalan cake with base classes for various descriptors. */ trait Entities extends TypeDescs { self: Scalan => @@ -14,7 +13,7 @@ trait Entities extends TypeDescs { self: Scalan => def parent: Option[Elem[_]] = None /** Name of the entity type without `Elem` suffix. */ def entityName: String = { - val n = this.getClass.safeSimpleName.stripSuffix("Elem") + val n = this.getClass.getSimpleName.stripSuffix("Elem") n } def convert(x: Ref[Def[_]]): Ref[A] = !!!("should not be called") diff --git a/core/src/main/scala/scalan/TypeDescs.scala b/core/src/main/scala/scalan/TypeDescs.scala index fb3c276001..219af2a21a 100644 --- a/core/src/main/scala/scalan/TypeDescs.scala +++ b/core/src/main/scala/scalan/TypeDescs.scala @@ -6,7 +6,6 @@ import scala.annotation.implicitNotFound import scala.collection.immutable.ListMap import scalan.util._ import scalan.RType._ -import scalan.util.ReflectionUtil.ClassOps import scala.collection.mutable import debox.cfor @@ -108,7 +107,7 @@ abstract class TypeDescs extends Base { self: Scalan => lazy val name: String = getName(_.name) // <> to delimit because: [] is used inside name; {} looks bad with structs. - override def toString = s"${getClass.safeSimpleName}<$name>" + override def toString = s"${getClass.getSimpleName}<$name>" } /** Type descriptor of staged types, which correspond to source (unstaged) RTypes @@ -134,7 +133,7 @@ abstract class TypeDescs extends Base { self: Scalan => be.sourceType.name case e => val cl = e.getClass - val name = cl.safeSimpleName.stripSuffix("Elem") + val name = cl.getSimpleName.stripSuffix("Elem") name } if (typeArgs.isEmpty) From 7a5b0f03c92fb77a4417d065c6f0a2e20a348081 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 2 Oct 2022 21:05:29 +0200 Subject: [PATCH 38/64] v5.x-restructure: remove unused annotation types --- common/src/main/java/scalan/Builtin.java | 17 ----------------- common/src/main/java/scalan/Constructor.java | 14 -------------- common/src/main/java/scalan/Convertible.java | 12 ------------ common/src/main/java/scalan/InlineAt.java | 18 ------------------ common/src/main/java/scalan/Isospec.java | 12 ------------ 5 files changed, 73 deletions(-) delete mode 100644 common/src/main/java/scalan/Builtin.java delete mode 100644 common/src/main/java/scalan/Constructor.java delete mode 100644 common/src/main/java/scalan/Convertible.java delete mode 100644 common/src/main/java/scalan/InlineAt.java delete mode 100644 common/src/main/java/scalan/Isospec.java 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/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/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/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 { -} From 810d48d105aca089a23841b5bee0acbcba56db54 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 3 Oct 2022 18:19:29 +0200 Subject: [PATCH 39/64] v5.x-restructure: remove unused annotations (part 2) --- .../src/main/java/scalan/ContainerType.java | 14 ---- common/src/main/java/scalan/FunctorType.java | 13 ---- common/src/main/java/scalan/Internal.java | 14 ---- common/src/main/java/scalan/Liftable.java | 12 ---- common/src/main/java/scalan/NeverInline.java | 12 ---- common/src/main/java/scalan/Reified.java | 19 ------ .../scalan/WithMethodCallRecognizers.java | 17 ----- .../main/scala/scalan/primitives/Thunks.scala | 2 +- .../main/scala/special/SpecialPredef.scala | 4 +- .../main/scala/special/collection/Colls.scala | 2 +- .../scala/special/wrappers/WrappersSpec.scala | 8 +-- .../special/collection/CollsOverArrays.scala | 7 +- .../scala/special/collection/CollsUnit.scala | 16 ++--- .../main/scala/wrappers/scala/WOptions.scala | 2 +- .../main/scala/wrappers/scalan/WRTypes.scala | 2 +- .../wrappers/special/WSpecialPredefs.scala | 6 +- .../main/scala/special/sigma/SigmaDsl.scala | 65 ++++++------------- .../scala/special/sigma/SigmaDslUnit.scala | 22 +++---- 18 files changed, 53 insertions(+), 184 deletions(-) delete mode 100644 common/src/main/java/scalan/ContainerType.java delete mode 100644 common/src/main/java/scalan/FunctorType.java delete mode 100644 common/src/main/java/scalan/Internal.java delete mode 100644 common/src/main/java/scalan/Liftable.java delete mode 100644 common/src/main/java/scalan/NeverInline.java delete mode 100644 common/src/main/java/scalan/Reified.java delete mode 100644 common/src/main/java/scalan/WithMethodCallRecognizers.java 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/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/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/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/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/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/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..fdc63dd8f7 100644 --- a/library/src/main/scala/wrappers/scala/WOptions.scala +++ b/library/src/main/scala/wrappers/scala/WOptions.scala @@ -4,7 +4,7 @@ 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]] { + @External("Option") 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]; diff --git a/library/src/main/scala/wrappers/scalan/WRTypes.scala b/library/src/main/scala/wrappers/scalan/WRTypes.scala index 26566be4a7..79067608da 100644 --- a/library/src/main/scala/wrappers/scalan/WRTypes.scala +++ b/library/src/main/scala/wrappers/scalan/WRTypes.scala @@ -13,7 +13,7 @@ package wrappers.scalan { trait WRTypes extends Base { self: WrappersModule => import WRType._; - @External("RType") @Liftable @WithMethodCallRecognizers trait WRType[A] extends Def[WRType[A]] { + @External("RType") trait WRType[A] extends Def[WRType[A]] { implicit def eA: Elem[A]; @External def name: Ref[String] }; diff --git a/library/src/main/scala/wrappers/special/WSpecialPredefs.scala b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala index fc7f0c7401..bc528fedb4 100644 --- a/library/src/main/scala/wrappers/special/WSpecialPredefs.scala +++ b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala @@ -6,12 +6,12 @@ package wrappers.special { trait WSpecialPredefs extends Base { self: WrappersModule => import WOption._; import WSpecialPredef._; - @External("SpecialPredef") @WithMethodCallRecognizers trait WSpecialPredef extends Def[WSpecialPredef]; + @External("SpecialPredef") 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 none[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 cast[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] } } diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index e9aeb9ddf6..6cc6d47439 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -14,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. @@ -98,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)}. * @@ -106,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)}. * @@ -116,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)}. * @@ -125,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 @@ -138,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)}. @@ -181,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 @@ -191,13 +189,11 @@ 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 @@ -223,8 +219,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. */ @@ -250,8 +244,6 @@ trait SigmaProp { } /** Represents any value paired with type descriptor. */ -@scalan.Liftable -@WithMethodCallRecognizers trait AnyValue { /** The data value wrapped by this instance. */ def value: Any @@ -262,8 +254,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] @@ -340,32 +330,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)] @@ -383,9 +373,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)" } @@ -398,7 +387,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 @@ -553,7 +541,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 @@ -581,7 +568,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] @@ -635,8 +621,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 @@ -742,12 +726,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 */ @@ -778,7 +759,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) @@ -794,8 +774,6 @@ trait SigmaContract { * * @see SGlobal.WrappedType, CostingSigmaDslBuilder */ -@scalan.Liftable -@WithMethodCallRecognizers trait SigmaDslBuilder { /** Access to collection operations. */ @@ -886,7 +864,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. @@ -896,10 +873,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-library/src/main/scala/special/sigma/SigmaDslUnit.scala b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala index 5634a05d6d..51f905db1f 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,14 +28,14 @@ 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]; @@ -45,11 +45,11 @@ package special.sigma { // manual fix @OverloadId(value = "or_bool") def ||(other: Ref[Boolean])(implicit o: Overloaded1): 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 +71,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 +88,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 +97,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 +114,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 +129,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 +147,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]] From c5b0441c11149816975e3ba959681e762831c0ce Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 3 Oct 2022 19:01:43 +0200 Subject: [PATCH 40/64] v5.x-restructure: translate java7.compat.Math to Scala --- common/src/main/java/java7/compat/Math.java | 159 ------------------- common/src/main/java/java7/compat/Math.scala | 126 +++++++++++++++ 2 files changed, 126 insertions(+), 159 deletions(-) delete mode 100644 common/src/main/java/java7/compat/Math.java create mode 100644 common/src/main/java/java7/compat/Math.scala 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/java7/compat/Math.scala b/common/src/main/java/java7/compat/Math.scala new file mode 100644 index 0000000000..0672f1a744 --- /dev/null +++ b/common/src/main/java/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 + } +} \ No newline at end of file From b6f7b43afb504e7fd78a1f0288bbcc31fe2dd57b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 4 Oct 2022 11:15:41 +0200 Subject: [PATCH 41/64] v5.x-restructure: remove unused annotations (part 3) --- common/src/main/java/scalan/External.java | 15 --------------- .../{java => scala}/java7/compat/Math.scala | 16 ++++++++-------- .../main/scala/wrappers/scala/WOptions.scala | 18 +++++++++--------- .../main/scala/wrappers/scalan/WRTypes.scala | 4 ++-- .../wrappers/special/WSpecialPredefs.scala | 12 ++++++------ 5 files changed, 25 insertions(+), 40 deletions(-) delete mode 100644 common/src/main/java/scalan/External.java rename common/src/main/{java => scala}/java7/compat/Math.scala (93%) 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/java7/compat/Math.scala b/common/src/main/scala/java7/compat/Math.scala similarity index 93% rename from common/src/main/java/java7/compat/Math.scala rename to common/src/main/scala/java7/compat/Math.scala index 0672f1a744..a1a7ce1296 100644 --- a/common/src/main/java/java7/compat/Math.scala +++ b/common/src/main/scala/java7/compat/Math.scala @@ -19,14 +19,14 @@ object Math { * @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 + 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, @@ -123,4 +123,4 @@ object Math { } r } -} \ No newline at end of file +} diff --git a/library/src/main/scala/wrappers/scala/WOptions.scala b/library/src/main/scala/wrappers/scala/WOptions.scala index fdc63dd8f7..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") 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 79067608da..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") 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 bc528fedb4..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") 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[A](implicit emA: Elem[A]): Ref[WOption[A]]; - @External def some[A](x: Ref[A]): Ref[WOption[A]]; - @External def cast[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 From f609767f47b0128f90d847af3c5991137fd05050 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 4 Oct 2022 15:12:12 +0200 Subject: [PATCH 42/64] v5.x-restructure: remove OverloadId annotation --- common/src/main/java/scalan/OverloadId.java | 13 ----- core/src/main/scala/scalan/TypeDescs.scala | 13 +---- .../main/scala/special/sigma/SigmaDsl.scala | 8 ++-- .../scala/special/sigma/SigmaDslUnit.scala | 8 +--- .../special/sigma/impl/SigmaDslImpl.scala | 48 +------------------ .../scala/sigmastate/eval/TreeBuilding.scala | 4 -- .../special/sigma/SigmaDslStaginTests.scala | 5 +- 7 files changed, 13 insertions(+), 86 deletions(-) delete mode 100644 common/src/main/java/scalan/OverloadId.java 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/core/src/main/scala/scalan/TypeDescs.scala b/core/src/main/scala/scalan/TypeDescs.scala index 219af2a21a..de1e314b24 100644 --- a/core/src/main/scala/scalan/TypeDescs.scala +++ b/core/src/main/scala/scalan/TypeDescs.scala @@ -232,15 +232,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 @@ -254,7 +245,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 @@ -272,7 +263,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/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index 6cc6d47439..26b5335a8f 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -226,21 +226,21 @@ 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 + 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: Boolean): 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 + 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: Boolean): SigmaProp } /** Represents any value paired with type descriptor. */ diff --git a/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala index 51f905db1f..5bd2ad784b 100644 --- a/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala +++ b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala @@ -38,12 +38,8 @@ package special.sigma { 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]; }; trait AnyValue extends Def[AnyValue] { def value: Ref[Any]; 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..657d7aa130 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, @@ -1084,7 +1060,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 +1068,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/scala/sigmastate/eval/TreeBuilding.scala b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala index d4d96b4142..08aa9b8f0c 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -286,10 +286,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/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) } } From e090920f8a59397c2d01c760118486fe4360d72f Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 8 Dec 2022 22:32:20 +0100 Subject: [PATCH 43/64] update-langspec: LangSpec.md updated + more ScalaDocs --- docs/LangSpec.md | 53 ++++++++----------- .../main/scala/special/sigma/SigmaDsl.scala | 13 +++-- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/docs/LangSpec.md b/docs/LangSpec.md index 15ff4ea31c..442d69a26e 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. */ @@ -426,7 +435,7 @@ 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` +box.R3[Int].getOrElse(d) // access R3 register, check that its value of type Int, return it if defined, otherwise return `d` ``` #### GroupElement @@ -818,23 +827,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 +861,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 +887,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/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index 37c86d9049..4bd9e99e08 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -695,22 +695,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. From fe4ac81519d8720383cf80ce6cf7b317e616d64d Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 13 Dec 2022 20:04:18 +0100 Subject: [PATCH 44/64] update-langspec: fixes for review --- docs/LangSpec.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/LangSpec.md b/docs/LangSpec.md index 442d69a26e..362f32d082 100644 --- a/docs/LangSpec.md +++ b/docs/LangSpec.md @@ -433,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 register, check that its value of type Int, return it 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 From f132de25f7aab3c975efa2be05a3dbd1ef91c18b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 25 Jan 2023 18:53:39 +0100 Subject: [PATCH 45/64] sdk-separate-interpreters: fixes after merge --- .../scala/sigmastate/interpreter/Interpreter.scala | 2 +- .../test/scala/sigmastate/ErgoTreeSpecification.scala | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 5bf62607b9..1276849e60 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -239,7 +239,7 @@ trait Interpreter { context: CTX, 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] 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) { From 44e5b2b8164fa47be56b0a7f9ac5491d1507e6e0 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 25 Jan 2023 20:12:41 +0100 Subject: [PATCH 46/64] restructure-part1: code cleanup --- build.sbt | 2 - .../scala/sigmastate/VersionContext.scala | 4 - .../sigmastate/kiama/rewriting/Rewriter.scala | 78 ------------------- .../sigmastate/kiama/util/Comparison.scala | 28 ------- 4 files changed, 112 deletions(-) diff --git a/build.sbt b/build.sbt index ce15591450..92030ae535 100644 --- a/build.sbt +++ b/build.sbt @@ -64,8 +64,6 @@ 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 scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT" -//val debox = "org.scorexfoundation" %% "debox" % "0.9.0-8-3da95c40-SNAPSHOT" val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" val guava = "com.google.guava" % "guava" % "30.1.1-jre" 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/rewriting/Rewriter.scala b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala index cc97baa503..57ce44d5b0 100644 --- a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala +++ b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala @@ -741,32 +741,6 @@ trait Rewriter { None } - /** - * Implementation of `congruence` for `Product` values. - */ - def congruenceProduct(p : Product, ss : Strategy*) : Option[Any] = { - val numchildren = p.productArity - if (numchildren == ss.length) { - val newchildren = Array.newBuilder[AnyRef] - val (changed, _) = - p.productIterator.foldLeft((false, 0)) { - case ((changed, i), ct) => - (ss(i))(ct) match { - case Some(ti) => - newchildren += makechild(ti) - (changed || !same(ct, ti), i + 1) - case None => - return None - } - } - if (changed) - Some(dup(p, newchildren.result())) - else - Some(p) - } else - None - } - // Extractors /** @@ -782,8 +756,6 @@ trait Rewriter { */ def unapply(t : Any) : Some[(Any, Vector[Any])] = { t match { -// case r : Rewritable => -// Some((r, r.deconstruct.toVector)) case p : Product => Some((p, p.productIterator.toVector)) case s : Seq[_] => @@ -858,18 +830,6 @@ trait Rewriter { def everywheretd(s : Strategy) : Strategy = topdown(attempt(s)) - /** - * Construct a strategy that succeeds when applied to a pair `(x,y)` - * if `x` is a sub-term of `y`. - */ - val issubterm : Strategy = - mkStrategy({ - case (x, y) => - where(oncetd(term(x)))(y) - case _ => - None - }) - /** * Construct a strategy that while `r` succeeds applies `s`. This operator * is called `while` in the Stratego library. @@ -892,15 +852,6 @@ trait Rewriter { mkStrategy(result) } - /** - * Construct a strategy that while `r` does not succeed applies `s`. This - * operator is called `while-not` in the Stratego library. - */ - def loopnot(r : Strategy, s : Strategy) : Strategy = { - lazy val result : Strategy = r <+ (s <* result) - 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 @@ -921,26 +872,6 @@ trait Rewriter { def not(s : Strategy) : Strategy = s < (fail + id) - /** - * Construct a strategy that applies `s` in a bottom-up fashion to one - * subterm at each level, stopping as soon as it succeeds once (at - * any level). - */ - def oncebu(s : Strategy) : Strategy = { - lazy val result : Strategy = one(result) <+ s - mkStrategy(result) - } - - /** - * Construct a strategy that applies `s` in a top-down fashion to one - * subterm at each level, stopping as soon as it succeeds once (at - * any level). - */ - def oncetd(s : Strategy) : Strategy = { - lazy val result : Strategy = s <+ one(result) - mkStrategy(result) - } - /** * `or(s1, s2)` is similar to `ior(s1, s2)`, but the application * of the strategies is only tested. @@ -976,15 +907,6 @@ trait Rewriter { mkStrategy(result) } - /** - * Construct a strategy that repeatedly applies `s` (at least once) and - * terminates with application of `c`. - */ - def repeat1(s : Strategy, r : Strategy) : Strategy = { - lazy val result : Strategy = s <* (result <+ r) - mkStrategy(result) - } - /** * Construct a strategy that tests whether strategy `s` succeeds, * restoring the original term on success. A synonym for `where`. diff --git a/common/src/main/scala/sigmastate/kiama/util/Comparison.scala b/common/src/main/scala/sigmastate/kiama/util/Comparison.scala index 16e087ac94..91d302a76a 100644 --- a/common/src/main/scala/sigmastate/kiama/util/Comparison.scala +++ b/common/src/main/scala/sigmastate/kiama/util/Comparison.scala @@ -83,24 +83,6 @@ object Comparison { def sameElements[T](t1 : Seq[_], t2 : Seq[_]) : Boolean = (t1.size == t2.size) && (t1.forall(contains(t2, _))) - /** - * As for `same`, except that if the two values are `Some` options - * containing references, they are unwrapped first and the contents are - * compared by reference. - */ - def optsame(v1 : Any, v2 : Any) : Boolean = - if (v1 == null) - v2 == null - else if (v2 == null) - false - else - (v1, v2) match { - case (Some(r1 : AnyRef), Some(r2 : AnyRef)) => - r1 eq r2 - case _ => - same(v1, v2) - } - /** * Does the iterable `s` contain `t`? Equality is tested using `same`. */ @@ -117,16 +99,6 @@ object Comparison { set.toVector } - /** - * As for `distinct` but works over a sequence of sequences. - */ - def flatDistinct[T](ss : Seq[Seq[T]]) : Vector[T] = { - val set = new TreeSet[T]()(new TOrdering[T]) - for (s <- ss) - 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`. From 935168a47624d1d3f36d578e0128873e8ba60137 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 8 Feb 2023 12:05:14 +0100 Subject: [PATCH 47/64] ScalaDoc for Ensuring --- common/src/main/scala/scalan/util/Extensions.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/common/src/main/scala/scalan/util/Extensions.scala b/common/src/main/scala/scalan/util/Extensions.scala index 47403055de..5b0c70987a 100644 --- a/common/src/main/scala/scalan/util/Extensions.scala +++ b/common/src/main/scala/scalan/util/Extensions.scala @@ -216,7 +216,17 @@ object Extensions { } } + /** 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 From 7e38069f8036f8d300277eb330f6fbda3d845796 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 10 Feb 2023 12:44:39 +0100 Subject: [PATCH 48/64] update-langspec: added SigmaProp doc --- docs/LangSpec.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/LangSpec.md b/docs/LangSpec.md index 362f32d082..76abdd687b 100644 --- a/docs/LangSpec.md +++ b/docs/LangSpec.md @@ -469,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 From a537c430a6137dc52839c57e108cca199d0e8bc8 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 15 Feb 2023 00:52:29 +0100 Subject: [PATCH 49/64] restructure-part2: add ScalaDocs + cleanups --- .../main/scala/special/sigma/SigmaDsl.scala | 1 + .../scala/sigmastate/basics/BcDlogGroup.scala | 25 ++++--- .../sigmastate/basics/DLogProtocol.scala | 2 + .../scala/sigmastate/basics/DlogGroup.scala | 1 + .../scala/sigmastate/crypto/BigIntegers.scala | 14 ++++ .../sigmastate/crypto/CryptoContext.scala | 10 ++- .../sigmastate/crypto/CryptoContextJvm.scala | 7 +- .../sigmastate/crypto/CryptoFacade.scala | 67 +++++++++++++++++++ .../scala/sigmastate/crypto/Platform.scala | 56 +++++++++++++++- .../scala/sigmastate/crypto/package.scala | 5 +- .../sigmastate/eval/CostingDataContext.scala | 4 ++ .../interpreter/CryptoConstants.scala | 10 +++ .../crypto/GroupLawsSpecification.scala | 2 +- 13 files changed, 182 insertions(+), 22 deletions(-) diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index 7d8c13f73f..5327a35d1f 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -199,6 +199,7 @@ trait BigInt { @scalan.Liftable @WithMethodCallRecognizers trait GroupElement { + /** Checks if this is the point at infinity. */ def isInfinity: Boolean /** Exponentiate this GroupElement to the given number. diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 484a2aff0f..9128406660 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -5,20 +5,22 @@ import sigmastate.crypto.BigIntegers import debox.cfor import sigmastate.crypto.{CryptoContext, CryptoFacade} -import scala.collection.{Seq, mutable} -import scala.util.Try -import scala.collection.compat.immutable.ArraySeq +import scala.collection.mutable +/** Base class for all dlog groups (with bouncycastle-like interface). + * @param ctx context which abstracts basic operations with curve and elements. + */ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { - //modulus of the field + /** Modulus of the finite field of the underlying curve. */ lazy val p: BigInteger = ctx.getModulus - //order of the group + /** Order of the group (parameter N of the elliptic curve). */ lazy val q: BigInteger = ctx.getOrder - //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) /** @@ -95,8 +97,10 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { 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. + /** 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. + */ override lazy val generator: ElemType = ctx.getGenerator /** @@ -115,13 +119,11 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { } /** - * * @return the order of this Dlog group */ override lazy val order: BigInteger = ctx.getOrder /** - * * @return the identity of this Dlog group */ override lazy val identity: ElemType = ctx.getInfinity.asInstanceOf[ElemType] @@ -239,4 +241,5 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { } +/** 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 96218e1b5f..38cfe1d8cb 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala @@ -27,6 +27,7 @@ object DLogProtocol { extends SigmaProofOfKnowledgeLeaf[DLogSigmaProtocol, DLogProverInput] { override def size: Int = 1 override val opCode: OpCode = OpCodes.ProveDlogCode + /** Serialized bytes of the elliptic curve point (using GroupElementSerializer). */ lazy val pkBytes: Array[Byte] = GroupElementSerializer.toBytes(value) } @@ -101,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) diff --git a/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala index cfacbc352e..f7df1c8e3c 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala @@ -20,6 +20,7 @@ import sigmastate.crypto.{CryptoFacade, Ecp} * @tparam ElemType is concrete type */ trait DlogGroup { + /** The type of the elements of this Dlog group */ type ElemType = Ecp val secureRandom = new SecureRandom() diff --git a/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala index 981af1e1c5..2fba10b5ba 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala @@ -3,12 +3,21 @@ 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) = { if (bitLength < 1) throw new IllegalArgumentException("bitLength must be at least 1") @@ -86,5 +95,10 @@ object BigIntegers { 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 index a2c37ada81..d0d5272bff 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala @@ -2,18 +2,24 @@ package sigmastate.crypto import java.math.BigInteger +/** A context for cryptographic operations. */ abstract class CryptoContext { + /** The order of the underlying finite field. */ def getModulus: BigInteger + /** The order of the underlying group. */ def getOrder: BigInteger - def validatePoint(x: BigInteger, - y: BigInteger): Ecp + /** The generator of the underlying group. */ + def validatePoint(x: BigInteger, y: BigInteger): Ecp + /** The point at infinity. */ def getInfinity(): Ecp + /** Decodes a point from its byte representation. */ def decodePoint(encoded: Array[Byte]): Ecp + /** The generator of the underlying group. */ def getGenerator: Ecp } diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala index 5af4cff117..05fa9f1d57 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala @@ -1,18 +1,21 @@ package sigmastate.crypto import org.bouncycastle.asn1.x9.X9ECParameters -import org.bouncycastle.math.ec.ECPoint import java.math.BigInteger +/** JVM implementation of context for cryptographic operations using Bouncycastle. */ class CryptoContextJvm(x9params: X9ECParameters) extends CryptoContext { - lazy val curve = x9params.getCurve + private lazy val curve = x9params.getCurve override def getModulus: BigInteger = curve.getField.getCharacteristic + override def getOrder: BigInteger = x9params.getN + override def getGenerator: Ecp = { Platform.Ecp(x9params.getG) } + override def validatePoint(x: BigInteger, y: BigInteger): Ecp = { Platform.Ecp(curve.validatePoint(x, y)) } diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala index f2ba6edf01..8546bf34f4 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala @@ -2,18 +2,85 @@ 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 value of bit 0 in BigInteger representation of this point. */ def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = Platform.testBitZeroOfFieldElem(p) + + /** Returns byte representation of the given field element. */ def getEncodedOfFieldElem(p: ECFieldElem): Array[Byte] = Platform.getEncodedOfFieldElem(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/Platform.scala b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala index 23301d810c..b809cac2cc 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala @@ -2,29 +2,72 @@ package sigmastate.crypto import org.bouncycastle.crypto.ec.CustomNamedCurves import org.bouncycastle.math.ec.{ECFieldElement, ECPoint} -import sigmastate.crypto 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 getEncodedOfFieldElem(p: ECFieldElem): Array[Byte] = p.value.getEncoded + /** Returns the value of bit 0 in BigInteger representation of this point. */ def testBitZeroOfFieldElem(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. @@ -32,6 +75,11 @@ object Platform { 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. @@ -40,15 +88,19 @@ object Platform { 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()) - /** Opaque point type. */ + /** 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 index e5dcc135ff..24d797be6f 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/package.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/package.scala @@ -1,11 +1,8 @@ package sigmastate -import org.bouncycastle.math.ec.ECPoint - 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 62b659d560..81250e5485 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -510,6 +510,7 @@ class CostingSigmaDslBuilder extends SigmaDslBuilder { dsl => override def toBigInteger(n: BigInt): BigInteger = n.asInstanceOf[CBigInt].wrappedValue + /** 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") @@ -527,6 +528,9 @@ class CostingSigmaDslBuilder extends SigmaDslBuilder { dsl => /** 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/interpreter/CryptoConstants.scala b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala index deeb60b4ce..d7d00451ba 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala @@ -5,13 +5,18 @@ import java.security.SecureRandom import sigmastate.basics.{BcDlogGroup, SecP256K1Group} import sigmastate.crypto.Ecp +/** Constants used in crypto operations implementation. */ object CryptoConstants { + /** Type of group elements used in the signature scheme. */ type EcPointType = Ecp + /** Length of encoded group elements in bytes. */ val EncodedGroupElementLength: Byte = 33 + /** 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 == ) */ @@ -26,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. @@ -36,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/test/scala/sigmastate/crypto/GroupLawsSpecification.scala b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala index 907a3ae1fb..b5b0b8b33b 100644 --- a/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala @@ -54,7 +54,7 @@ class GroupLawsSpecification extends SigmaTestingCommons { } } - def printPoints(points: Seq[(String, Any)]) = { + private def printPoints(points: Seq[(String, Any)]) = { points.foreach { case (name, p) => println(s"val $name = ${SigmaPPrint.apply(p).plainText}") } From b164a5c8219d5527d056312116ccffc5f676958d Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 16 Feb 2023 19:26:43 +0100 Subject: [PATCH 50/64] restructure-part2: addressing review comments --- .../src/main/scala/sigmastate/basics/BcDlogGroup.scala | 7 +++++-- .../src/main/scala/sigmastate/crypto/CryptoFacade.scala | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 9128406660..6cc45d29dc 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -8,14 +8,17 @@ import sigmastate.crypto.{CryptoContext, CryptoFacade} import scala.collection.mutable -/** Base class for all dlog groups (with bouncycastle-like interface). +/** 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 { /** Modulus of the finite field of the underlying curve. */ lazy val p: BigInteger = ctx.getModulus - /** Order of the group (parameter N of the elliptic curve). */ + /** 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.getOrder /** Now that we have p, we can calculate k which is the maximum length in bytes diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala index 8546bf34f4..c820cb81e5 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala @@ -42,7 +42,7 @@ object CryptoFacade { /** Return simplified string representation of the point (used only for debugging) */ def showPoint(p: Ecp): String = Platform.showPoint(p) - /** Returns the value of bit 0 in BigInteger representation of this point. */ + /** Returns the sign of the field element. */ def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = Platform.testBitZeroOfFieldElem(p) /** Returns byte representation of the given field element. */ From 29d44db4a2754dcbeb50b32f8a5e18e05320e24e Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 20 Feb 2023 22:39:25 +0100 Subject: [PATCH 51/64] restructure-part2: renamed isInfinity --- sigma-api/src/main/scala/special/sigma/SigmaDsl.scala | 3 +-- .../src/main/scala/sigmastate/eval/CostingDataContext.scala | 2 +- sigmastate/src/main/scala/sigmastate/eval/Extensions.scala | 4 ++-- .../serialization/GroupElementSerializerSpecification.scala | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index 5327a35d1f..ce9d956c36 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -199,8 +199,7 @@ trait BigInt { @scalan.Liftable @WithMethodCallRecognizers trait GroupElement { - /** Checks if this is the point at infinity. */ - def isInfinity: Boolean + def isIdentity: Boolean /** Exponentiate this GroupElement to the given number. * @param k The power. diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 81250e5485..09912c7588 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -104,7 +104,7 @@ case class CGroupElement(override val wrappedValue: Ecp) extends GroupElement wi override def getEncoded: Coll[Byte] = dsl.Colls.fromArray(GroupElementSerializer.toBytes(wrappedValue)) - override def isInfinity: Boolean = CryptoFacade.isInfinityPoint(wrappedValue) + override def isIdentity: Boolean = CryptoFacade.isInfinityPoint(wrappedValue) override def exp(k: BigInt): GroupElement = dsl.GroupElement(CryptoFacade.exponentiatePoint(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue)) diff --git a/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala index 57ad388a20..a5d93ba25c 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala @@ -89,8 +89,8 @@ object Extensions { /** Shortened String representation of `source` GroupElement. */ def showECPoint(p: Ecp): String = { - if (p.isInfinity) { - "INF" + if (p.isIdentity) { + "IDENTITY" } else { CryptoFacade.showPoint(p) diff --git a/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala index f876cb9bbe..5be6cc5ff9 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala @@ -13,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") { From 2d9be2de41a4205727eb0e4098f70cb934db2a9a Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 20 Feb 2023 22:46:52 +0100 Subject: [PATCH 52/64] restructure-part2: renamed getModulus --- sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala | 2 +- .../src/main/scala/sigmastate/crypto/CryptoContext.scala | 4 ++-- .../src/main/scala/sigmastate/crypto/CryptoContextJvm.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 6cc45d29dc..6fd37e11d1 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -13,7 +13,7 @@ import scala.collection.mutable */ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { /** Modulus of the finite field of the underlying curve. */ - lazy val p: BigInteger = ctx.getModulus + lazy val p: BigInteger = ctx.fieldCharacteristic /** Order of the group as defined in ASN.1 def for Elliptic-Curve ECParameters structure. * See X9.62, for further details. diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala index d0d5272bff..7c03ac1228 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala @@ -4,8 +4,8 @@ import java.math.BigInteger /** A context for cryptographic operations. */ abstract class CryptoContext { - /** The order of the underlying finite field. */ - def getModulus: BigInteger + /** The characteristics of the underlying finite field. */ + def fieldCharacteristic: BigInteger /** The order of the underlying group. */ def getOrder: BigInteger diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala index 05fa9f1d57..9365bc9da9 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala @@ -8,7 +8,7 @@ import java.math.BigInteger class CryptoContextJvm(x9params: X9ECParameters) extends CryptoContext { private lazy val curve = x9params.getCurve - override def getModulus: BigInteger = curve.getField.getCharacteristic + override def fieldCharacteristic: BigInteger = curve.getField.getCharacteristic override def getOrder: BigInteger = x9params.getN From 84fb72424c12fcfa9801afb7dc8f2efe11cd27f0 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 20 Feb 2023 23:08:41 +0100 Subject: [PATCH 53/64] restructure-part2: more renamings --- .../scala/sigmastate/basics/BcDlogGroup.scala | 10 +++++----- .../scala/sigmastate/crypto/BigIntegers.scala | 2 +- .../scala/sigmastate/crypto/CryptoContext.scala | 15 ++++++++++----- .../sigmastate/crypto/CryptoContextJvm.scala | 6 +++--- .../scala/sigmastate/crypto/CryptoFacade.scala | 2 +- .../main/scala/sigmastate/crypto/Platform.scala | 2 +- .../serialization/GroupElementSerializer.scala | 2 +- .../scala/sigmastate/eval/BasicOpsTests.scala | 2 +- 8 files changed, 23 insertions(+), 18 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 6fd37e11d1..164d774c1b 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -19,7 +19,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { * See X9.62, for further details. * For reference implementation see `org.bouncycastle.asn1.x9.X9ECParameters.getN`. */ - lazy val q: BigInteger = ctx.getOrder + 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. @@ -104,7 +104,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { * 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 = ctx.getGenerator + 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. @@ -124,12 +124,12 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { /** * @return the order of this Dlog group */ - override lazy val order: BigInteger = ctx.getOrder + override lazy val order: BigInteger = ctx.order /** * @return the identity of this Dlog group */ - override lazy val identity: ElemType = ctx.getInfinity.asInstanceOf[ElemType] + override lazy val identity: ElemType = ctx.infinity.asInstanceOf[ElemType] /** * Calculates the inverse of the given GroupElement. @@ -170,7 +170,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { //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 = ctx.getOrder.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 diff --git a/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala index 2fba10b5ba..0e55f12532 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/BigIntegers.scala @@ -19,7 +19,7 @@ object BigIntegers { * @return a byte array containing random bits. */ @throws[IllegalArgumentException] - def createRandom(bitLength: Int, random: SecureRandom) = { + 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) diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala index 7c03ac1228..b5aceec849 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContext.scala @@ -8,18 +8,23 @@ abstract class CryptoContext { def fieldCharacteristic: BigInteger /** The order of the underlying group. */ - def getOrder: BigInteger - - /** The generator 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 getInfinity(): Ecp + def infinity(): Ecp /** Decodes a point from its byte representation. */ def decodePoint(encoded: Array[Byte]): Ecp /** The generator of the underlying group. */ - def getGenerator: Ecp + def generator: Ecp } diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala index 9365bc9da9..6a3420242f 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoContextJvm.scala @@ -10,9 +10,9 @@ class CryptoContextJvm(x9params: X9ECParameters) extends CryptoContext { override def fieldCharacteristic: BigInteger = curve.getField.getCharacteristic - override def getOrder: BigInteger = x9params.getN + override def order: BigInteger = x9params.getN - override def getGenerator: Ecp = { + override def generator: Ecp = { Platform.Ecp(x9params.getG) } @@ -20,7 +20,7 @@ class CryptoContextJvm(x9params: X9ECParameters) extends CryptoContext { Platform.Ecp(curve.validatePoint(x, y)) } - override def getInfinity(): Ecp = { + override def infinity(): Ecp = { Platform.Ecp(curve.getInfinity) } diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala index c820cb81e5..e2965b1eb7 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala @@ -46,7 +46,7 @@ object CryptoFacade { def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = Platform.testBitZeroOfFieldElem(p) /** Returns byte representation of the given field element. */ - def getEncodedOfFieldElem(p: ECFieldElem): Array[Byte] = Platform.getEncodedOfFieldElem(p) + def encodeFieldElem(p: ECFieldElem): Array[Byte] = Platform.encodeFieldElem(p) /** Returns the x-coordinate. * diff --git a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala index b809cac2cc..e01311b605 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala @@ -44,7 +44,7 @@ object Platform { def getAffineYCoord(p: Ecp): ECFieldElem = ECFieldElem(p.value.getAffineYCoord) /** Returns byte representation of the given field element. */ - def getEncodedOfFieldElem(p: ECFieldElem): Array[Byte] = p.value.getEncoded + def encodeFieldElem(p: ECFieldElem): Array[Byte] = p.value.getEncoded /** Returns the value of bit 0 in BigInteger representation of this point. */ def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = p.value.testBitZero() diff --git a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala index 3e5774d1bc..96c2e63ae8 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala @@ -27,7 +27,7 @@ object GroupElementSerializer extends SigmaSerializer[EcPointType, EcPointType] } else { val normed = CryptoFacade.normalizePoint(point) val ySign = CryptoFacade.testBitZeroOfFieldElem(CryptoFacade.getAffineYCoord(normed)) - val X = CryptoFacade.getEncodedOfFieldElem(CryptoFacade.getXCoord(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) diff --git a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala index 393d473e8f..58da469c82 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala @@ -33,7 +33,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 = SecP256K1Group.ctx.getOrder + val groupOrder = SecP256K1Group.ctx.order SigmaDsl.byteArrayToBigInt( Colls.fromArray(groupOrder.subtract(BigInteger.ONE).toByteArray) From c424648bbcc47e95dcea9dfb3b7d61f970370026 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 20 Feb 2023 23:21:32 +0100 Subject: [PATCH 54/64] restructure-part2: fixes --- .../src/main/scala/sigmastate/interpreter/CryptoConstants.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala index d7d00451ba..1d4a3a2d28 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala @@ -10,7 +10,7 @@ object CryptoConstants { /** Type of group elements used in the signature scheme. */ type EcPointType = Ecp - /** Length of encoded group elements in bytes. */ + /** Length of encoded group element in bytes. */ val EncodedGroupElementLength: Byte = 33 /** Group used in the signature scheme. */ From ae49202fc591dde94f031b1a212e81f4cbc598ea Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 20 Feb 2023 23:50:24 +0100 Subject: [PATCH 55/64] restructure-part2: fix Scala 2.11 compilation --- build.sbt | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/build.sbt b/build.sbt index 2a4c9da3a6..7fd9727c9a 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 From 90f1c180bc2388ccad099e37a40839ba47ac29e8 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 21 Feb 2023 20:41:01 +0100 Subject: [PATCH 56/64] restructure-part2: more renamings --- sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala | 2 +- sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala | 2 +- sigmastate/src/main/scala/sigmastate/crypto/Platform.scala | 2 +- .../scala/sigmastate/serialization/GroupElementSerializer.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala index 164d774c1b..f4b9b4c8f3 100644 --- a/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala +++ b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala @@ -12,7 +12,7 @@ import scala.collection.mutable * @param ctx context which abstracts basic operations with curve and elements. */ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup { - /** Modulus of the finite field of the underlying curve. */ + /** Characteristic of the finite field of the underlying curve. */ lazy val p: BigInteger = ctx.fieldCharacteristic /** Order of the group as defined in ASN.1 def for Elliptic-Curve ECParameters structure. diff --git a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala index e2965b1eb7..54ec07940c 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/CryptoFacade.scala @@ -43,7 +43,7 @@ object CryptoFacade { def showPoint(p: Ecp): String = Platform.showPoint(p) /** Returns the sign of the field element. */ - def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = Platform.testBitZeroOfFieldElem(p) + 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) diff --git a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala index e01311b605..5cb4a9f345 100644 --- a/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala +++ b/sigmastate/src/main/scala/sigmastate/crypto/Platform.scala @@ -47,7 +47,7 @@ object Platform { def encodeFieldElem(p: ECFieldElem): Array[Byte] = p.value.getEncoded /** Returns the value of bit 0 in BigInteger representation of this point. */ - def testBitZeroOfFieldElem(p: ECFieldElem): Boolean = p.value.testBitZero() + 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. diff --git a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala index 96c2e63ae8..b8523cb430 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala @@ -26,7 +26,7 @@ object GroupElementSerializer extends SigmaSerializer[EcPointType, EcPointType] identityPointEncoding } else { val normed = CryptoFacade.normalizePoint(point) - val ySign = CryptoFacade.testBitZeroOfFieldElem(CryptoFacade.getAffineYCoord(normed)) + 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 From 250922beb4d12fe6b4247b2b08d710570d205d00 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 22 Feb 2023 13:51:21 +0100 Subject: [PATCH 57/64] restructure-part2: scaladoc for isIdentity --- sigma-api/src/main/scala/special/sigma/SigmaDsl.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index ce9d956c36..38ef31700c 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -199,6 +199,7 @@ trait BigInt { @scalan.Liftable @WithMethodCallRecognizers trait GroupElement { + /** Checks if the provided element is an identity element. */ def isIdentity: Boolean /** Exponentiate this GroupElement to the given number. From f9c2078c44463ddfbc24baca5ceee1ad93a1f0af Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 22 Feb 2023 22:41:22 +0100 Subject: [PATCH 58/64] restructure-part3: fix compilation --- .../sigmastate/serialization/DeserializationResilience.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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. } From 0f4fa860d6bfe702bd44e43a845753202b8e93a8 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 26 Feb 2023 23:08:23 +0100 Subject: [PATCH 59/64] restructure-part3: update deps --- build.sbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 67fefe3720..f9f58c0c91 100644 --- a/build.sbt +++ b/build.sbt @@ -70,9 +70,9 @@ dynverSonatypeSnapshots in ThisBuild := true dynverSeparator in ThisBuild := "-" val bouncycastleBcprov = "org.bouncycastle" % "bcprov-jdk15on" % "1.66" -val scrypto = "org.scorexfoundation" %% "scrypto" % "2.2.1-25-dafca54c-SNAPSHOT" -val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8-19-0331a3d9-SNAPSHOT" -val debox = "org.scorexfoundation" %% "debox" % "0.9.0-8-3da95c40-SNAPSHOT" +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 guava = "com.google.guava" % "guava" % "30.1.1-jre" From ce8d37d590d58ef5b776317b24d13905c6601939 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 6 Oct 2022 23:25:06 +0200 Subject: [PATCH 60/64] v5.x-restructure: removed overloadded methods of SigmaProp && and || --- sigma-api/src/main/scala/special/sigma/SigmaDsl.scala | 10 ---------- .../scala/sigmastate/eval/CostingDataContext.scala | 8 -------- .../utxo/examples/AssetsAtomicExchange.scala | 8 ++++---- .../utxo/examples/AssetsPartialFilling.scala | 8 ++++---- .../scala/sigmastate/utxo/examples/CrowdFunding.scala | 6 +++--- .../utxo/examples/DummyExamplesSpecification.scala | 2 +- 6 files changed, 12 insertions(+), 30 deletions(-) diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index 2c2f52baca..a6864a3302 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -229,19 +229,9 @@ trait SigmaProp { * This constructs a new CAND node of sigma tree with two children. */ 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. */ - def &&(other: Boolean): SigmaProp - /** Logical OR between this SigmaProp and other SigmaProp. * This constructs a new COR node of sigma tree with two children. */ 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. */ - def ||(other: Boolean): SigmaProp } /** Represents any value paired with type descriptor. */ diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 246c15080b..76bafd2fa2 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -143,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})" } 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/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/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} From 38b70a5301032b2cdefc4d3799210fada465253d Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 27 Feb 2023 23:15:54 +0100 Subject: [PATCH 61/64] restructure-part3: remove unnecessary SigmaProp methods --- .../special/sigma/impl/SigmaDslImpl.scala | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) 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 657d7aa130..8195aed696 100644 --- a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -970,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, @@ -1016,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" )) } } From 9791ceaebdb54b55047239b03428444f1101d848 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 3 Mar 2023 14:49:52 +0100 Subject: [PATCH 62/64] restructure-part4: rollback safeSimpleName in ReflectionUtil --- .../scala/scalan/util/ReflectionUtil.scala | 21 +++++++++++++++++++ core/src/main/scala/scalan/Entities.scala | 3 ++- core/src/main/scala/scalan/TypeDescs.scala | 5 +++-- 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 common/src/main/scala/scalan/util/ReflectionUtil.scala diff --git a/common/src/main/scala/scalan/util/ReflectionUtil.scala b/common/src/main/scala/scalan/util/ReflectionUtil.scala new file mode 100644 index 0000000000..dd98f3069e --- /dev/null +++ b/common/src/main/scala/scalan/util/ReflectionUtil.scala @@ -0,0 +1,21 @@ +package scalan.util + +import scala.language.existentials + +object ReflectionUtil { + + implicit class ClassOps(val cl: Class[_]) extends AnyVal { + private def isSpecialChar(c: Char): Boolean = { + ('0' <= c && c <= '9') || c == '$' + } + def safeSimpleName: String = { + if (cl.getEnclosingClass == null) return cl.getSimpleName + val simpleName = cl.getName.substring(cl.getEnclosingClass.getName.length) + val length = simpleName.length + var index = 0 + while (index < length && isSpecialChar(simpleName.charAt(index))) { index += 1 } + // Eventually, this is the empty string iff this is an anonymous class + simpleName.substring(index) + } + } +} diff --git a/core/src/main/scala/scalan/Entities.scala b/core/src/main/scala/scalan/Entities.scala index 6c1c062f4c..376bd5a529 100644 --- a/core/src/main/scala/scalan/Entities.scala +++ b/core/src/main/scala/scalan/Entities.scala @@ -1,6 +1,7 @@ package scalan import scala.language.higherKinds +import scalan.util.ReflectionUtil.ClassOps /** A slice in the Scalan cake with base classes for various descriptors. */ trait Entities extends TypeDescs { self: Scalan => @@ -13,7 +14,7 @@ trait Entities extends TypeDescs { self: Scalan => def parent: Option[Elem[_]] = None /** Name of the entity type without `Elem` suffix. */ def entityName: String = { - val n = this.getClass.getSimpleName.stripSuffix("Elem") + val n = this.getClass.safeSimpleName.stripSuffix("Elem") n } def convert(x: Ref[Def[_]]): Ref[A] = !!!("should not be called") diff --git a/core/src/main/scala/scalan/TypeDescs.scala b/core/src/main/scala/scalan/TypeDescs.scala index de1e314b24..97689c169d 100644 --- a/core/src/main/scala/scalan/TypeDescs.scala +++ b/core/src/main/scala/scalan/TypeDescs.scala @@ -6,6 +6,7 @@ import scala.annotation.implicitNotFound import scala.collection.immutable.ListMap import scalan.util._ import scalan.RType._ +import scalan.util.ReflectionUtil.ClassOps import scala.collection.mutable import debox.cfor @@ -107,7 +108,7 @@ abstract class TypeDescs extends Base { self: Scalan => lazy val name: String = getName(_.name) // <> to delimit because: [] is used inside name; {} looks bad with structs. - override def toString = s"${getClass.getSimpleName}<$name>" + override def toString = s"${getClass.safeSimpleName}<$name>" } /** Type descriptor of staged types, which correspond to source (unstaged) RTypes @@ -133,7 +134,7 @@ abstract class TypeDescs extends Base { self: Scalan => be.sourceType.name case e => val cl = e.getClass - val name = cl.getSimpleName.stripSuffix("Elem") + val name = cl.safeSimpleName.stripSuffix("Elem") name } if (typeArgs.isEmpty) From 257ed7fcbfa05a51ecd1e9d02697f586f9be2152 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 3 Mar 2023 16:57:05 +0100 Subject: [PATCH 63/64] restructure-part4: cleanup test case --- .../test/scala/special/sigma/SigmaDslSpecification.scala | 9 --------- 1 file changed, 9 deletions(-) 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( { From 637a7f01027711ab08a0ae5c0c1a00e54f1546b8 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 3 Mar 2023 17:05:37 +0100 Subject: [PATCH 64/64] restructure-part4: more ScalaDocs --- common/src/main/scala/scalan/util/ReflectionUtil.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/src/main/scala/scalan/util/ReflectionUtil.scala b/common/src/main/scala/scalan/util/ReflectionUtil.scala index dd98f3069e..15c73b0548 100644 --- a/common/src/main/scala/scalan/util/ReflectionUtil.scala +++ b/common/src/main/scala/scalan/util/ReflectionUtil.scala @@ -5,9 +5,15 @@ import scala.language.existentials object ReflectionUtil { 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)