From 6eae6e783472d3f7c90a3bccd2bbcda1b6aa23e1 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 9 Sep 2022 17:35:28 +0200 Subject: [PATCH 01/36] scala-js: update dependencies --- build.sbt | 19 ++++++++++--------- project/build.properties | 2 +- .../authds/avltree/batch/BatchAVLProver.scala | 8 ++++---- .../avltree/batch/BatchAVLVerifier.scala | 2 +- .../legacy/avltree/AVLModifyProof.scala | 2 +- .../authds/legacy/avltree/AVLTree.scala | 2 +- .../crypto/authds/legacy/treap/Treap.scala | 2 +- .../legacy/treap/TreapModifyProof.scala | 2 +- .../scorex/crypto/signatures/Curve25519.scala | 7 +++---- src/main/scala/scorex/utils/package.scala | 3 --- .../avltree/batch/AVLBatchSpecification.scala | 8 ++++---- .../avltree/batch/BatchingPlayground.scala | 10 +++++----- .../SigningFunctionsSpecification.scala | 4 ++-- 13 files changed, 34 insertions(+), 37 deletions(-) diff --git a/build.sbt b/build.sbt index 0fda21c6..f85143f2 100644 --- a/build.sbt +++ b/build.sbt @@ -3,12 +3,12 @@ import sbt.Keys.{homepage, scalaVersion} name := "scrypto" description := "Cryptographic primitives for Scala" +lazy val scala213 = "2.13.8" lazy val scala212 = "2.12.15" lazy val scala211 = "2.11.12" -lazy val scala213 = "2.13.7" crossScalaVersions := Seq(scala212, scala211, scala213) -scalaVersion := scala212 +scalaVersion := scala213 javacOptions ++= "-source" :: "1.8" :: @@ -37,12 +37,12 @@ lazy val commonSettings = Seq( ) libraryDependencies ++= Seq( - "org.rudogma" %% "supertagged" % "1.5", + "org.rudogma" %% "supertagged" % "2.0-RC2", "com.google.guava" % "guava" % "23.0", "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2", "org.whispersystems" % "curve25519-java" % "0.5.0", "org.bouncycastle" % "bcprov-jdk15to18" % "1.66", - "org.scorexfoundation" %% "scorex-util" % "0.1.8" + "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT" ) libraryDependencies ++= Seq( @@ -60,12 +60,13 @@ publishTo := sonatypePublishToBundle.value pomIncludeRepository := { _ => false } -lazy val scrypto = (project in file(".")).settings(commonSettings: _*) +lazy val scrypto = (project in file(".")) + .settings(commonSettings: _*) -lazy val benchmarks = (project in file("benchmarks")) - .settings(commonSettings, name := "scrypto-benchmarks") - .dependsOn(scrypto) - .enablePlugins(JmhPlugin) +//lazy val benchmarks = (project in file("benchmarks")) +// .settings(commonSettings, name := "scrypto-benchmarks") +// .dependsOn(scrypto) +// .enablePlugins(JmhPlugin) credentials ++= (for { username <- Option(System.getenv().get("SONATYPE_USERNAME")) diff --git a/project/build.properties b/project/build.properties index e2820dd8..14095e16 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.2.8 +sbt.version=1.5.4 diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala index a1505efb..57eb08da 100644 --- a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala +++ b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala @@ -1,14 +1,14 @@ package scorex.crypto.authds.avltree.batch import com.google.common.primitives.Ints +import com.typesafe.scalalogging.StrictLogging import scorex.crypto.authds._ import scorex.crypto.hash.{Blake2b256, CryptographicHash, Digest} -import scorex.util.ScorexLogging import scorex.utils.ByteArray import scala.annotation.tailrec import scala.collection.mutable -import scala.util.{Failure, Random, Success, Try} +import scala.util.{Random, Try, Success, Failure} /** @@ -27,7 +27,7 @@ class BatchAVLProver[D <: Digest, HF <: CryptographicHash[D]](val keyLength: Int oldRootAndHeight: Option[(ProverNodes[D], Int)] = None, val collectChangedNodes: Boolean = true) (implicit val hf: HF = Blake2b256) - extends AuthenticatedTreeOps[D] with ToStringHelper with ScorexLogging { + extends AuthenticatedTreeOps[D] with ToStringHelper with StrictLogging { protected val labelLength: Int = hf.DigestSize @@ -446,7 +446,7 @@ class BatchAVLProver[D <: Digest, HF <: CryptographicHash[D]](val keyLength: Int if (!t) { var x = rNode.key(0).toInt if (x < 0) x = x + 256 - log.error("Tree failed at key = " + x + ": " + s) + logger.error("Tree failed at key = " + x + ": " + s) fail = true } } diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala index 270dd0e6..dfb70767 100644 --- a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala +++ b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala @@ -189,7 +189,7 @@ class BatchAVLVerifier[D <: Digest, HF <: CryptographicHash[D]](startingDigest: previousLeaf = None case LeafInPackagedProof => val key = if (previousLeaf.nonEmpty) { - ADKey @@ previousLeaf.get.nextLeafKey + ADKey @@@ previousLeaf.get.nextLeafKey } else { val start = i diff --git a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala b/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala index 1a30fa8e..1440f31b 100644 --- a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala +++ b/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala @@ -213,7 +213,7 @@ case class AVLModifyProof(key: ADKey, proofSeq: Seq[AVLProofElement]) initializeIterator() val (newTopNode, _, _, oldLabel) = verifyHelper(updateFn) - if (oldLabel sameElements digest) Some(ADDigest @@ newTopNode.label) else None + if (oldLabel sameElements digest) Some(ADDigest @@@ newTopNode.label) else None }.getOrElse(None) /** diff --git a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala b/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala index 74f028e1..cf7f483d 100644 --- a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala +++ b/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala @@ -22,7 +22,7 @@ class AVLTree[HF <: CryptographicHash[_ <: Digest]](keyLength: Int, private var topNode: ProverNodes = rootOpt.getOrElse(DefaultTopNode) - def rootHash(): ADDigest = ADDigest @@ topNode.label + def rootHash(): ADDigest = ADDigest @@@ topNode.label override def run[O <: Operation](operation: O): Try[AVLModifyProof] = Try { val key = operation.key diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala b/src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala index d9c68d75..f1e5d4e8 100644 --- a/src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala +++ b/src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala @@ -18,7 +18,7 @@ class Treap[HF <: CryptographicHash[_ <: Digest]](rootOpt: Option[Leaf] = None) var topNode: ProverNodes = rootOpt.getOrElse(Leaf(NegativeInfinity._1, NegativeInfinity._2, PositiveInfinity._1)) - def rootHash(): ADDigest = ADDigest @@ topNode.label + def rootHash(): ADDigest = ADDigest @@@ topNode.label override def run[O <: Operation](operation: O): Try[TreapModifyProof] = Try { val key = operation.key diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala b/src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala index 616d1c4c..4baef73b 100644 --- a/src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala +++ b/src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala @@ -111,7 +111,7 @@ case class TreapModifyProof(key: ADKey, proofSeq: Seq[WTProofElement]) val (newTopNode, changeHappened, oldLabel) = verifyHelper() if (oldLabel sameElements digest) { - Some(ADDigest @@ newTopNode.label) + Some(ADDigest @@@ newTopNode.label) } else { None } diff --git a/src/main/scala/scorex/crypto/signatures/Curve25519.scala b/src/main/scala/scorex/crypto/signatures/Curve25519.scala index 75718fcc..08b96403 100644 --- a/src/main/scala/scorex/crypto/signatures/Curve25519.scala +++ b/src/main/scala/scorex/crypto/signatures/Curve25519.scala @@ -4,12 +4,11 @@ import java.lang.reflect.Constructor import org.whispersystems.curve25519.OpportunisticCurve25519Provider import scorex.crypto.hash.Sha256 -import scorex.util.ScorexLogging +import com.typesafe.scalalogging.StrictLogging import scala.util.{Failure, Try} -object Curve25519 extends EllipticCurveSignatureScheme with ScorexLogging { - +object Curve25519 extends EllipticCurveSignatureScheme with StrictLogging { val SignatureLength25519 = 64 val KeyLength25519 = 32 @@ -45,7 +44,7 @@ object Curve25519 extends EllipticCurveSignatureScheme with ScorexLogging { require(publicKey.length == KeyLength) provider.verifySignature(publicKey, message, signature) }.recoverWith { case e => - log.debug("Error while message signature verification", e) + logger.debug("Error while message signature verification", e) Failure(e) }.getOrElse(false) diff --git a/src/main/scala/scorex/utils/package.scala b/src/main/scala/scorex/utils/package.scala index 39f18064..d1cbdf3e 100644 --- a/src/main/scala/scorex/utils/package.scala +++ b/src/main/scala/scorex/utils/package.scala @@ -2,9 +2,6 @@ package scorex package object utils { - @deprecated("Use scorex.util.ScorexLogging instead.", "scorex-util 0.1.0") - type ScryptoLogging = scorex.util.ScorexLogging - @deprecated("Use scorex.util.ScorexEncoding instead.", "scorex-util 0.1.1") type ScorexEncoding = scorex.util.ScorexEncoding } diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala b/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala index 9c16e758..f7298c25 100644 --- a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala +++ b/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala @@ -202,7 +202,7 @@ class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChe val digest = prover.digest val keyValues = (0 until InitialTreeSize) map { i => val aValue = Keccak256(i.toString.getBytes("UTF-8")) - (ADKey @@ aValue.take(KL), ADValue @@ aValue) + (ADKey @@ aValue.take(KL), ADValue @@@ aValue) } keyValues.foreach(kv => prover.performOneOperation(Insert(kv._1, kv._2))) @@ -220,7 +220,7 @@ class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChe (0 until InitialTreeSize) foreach { i => val aValue = Keccak256(i.toString.getBytes("UTF-8")) - verifier.performOneOperation(Insert(ADKey @@ aValue.take(KL), ADValue @@ aValue)) + verifier.performOneOperation(Insert(ADKey @@ aValue.take(KL), ADValue @@@ aValue)) } //extract all leafs val allLeafs = verifier.extractNodes(nonInfiniteLeaf) @@ -237,7 +237,7 @@ class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChe val digest = prover.digest val keyValues = (0 until InitialTreeSize) map { i => val aValue = Keccak256(i.toString.getBytes("UTF-8")) - (ADKey @@ aValue.take(KL), ADValue @@ aValue) + (ADKey @@ aValue.take(KL), ADValue @@@ aValue) } keyValues.foreach(kv => prover.performOneOperation(Insert(kv._1, kv._2))) @@ -504,7 +504,7 @@ class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChe digest = p.digest val key = randomKey(KL) - p.performOneOperation(Insert(ADKey @@ key, randomValue(8))) + p.performOneOperation(Insert(ADKey @@@ key, randomValue(8))) pf = p.generateProof() p.checkTree() diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala b/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala index 511010b3..9add988a 100644 --- a/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala +++ b/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala @@ -54,7 +54,7 @@ object BatchingPlayground extends App with BatchTestingHelpers with Matchers { System.gc() val toRemove = elements.slice(i * toRemoveSize, (i + 1) * toRemoveSize).map(e => Remove(e._1)) val toInsert = (0 until toInsertSize).map(j => Sha256(s"$i-$j")) - .map(k => Insert(ADKey @@ k, ADValue @@ k.take(8))) + .map(k => Insert(ADKey @@@ k, ADValue @@ k.take(8))) val treeSize = startTreeSize + i * (toInsert.length - toRemove.length) val oldTop = prover.topNode val mods = toRemove ++ toInsert @@ -93,7 +93,7 @@ object BatchingPlayground extends App with BatchTestingHelpers with Matchers { val ElementsToInsert = 100000 val elements = (0 until ElementsToInsert) .map(i => Sha256(i.toString)) - .map(k => (ADKey @@ k, ADValue @@ k.take(8))) + .map(k => (ADKey @@@ k, ADValue @@ k.take(8))) elements.foreach(e => prover.performOneOperation(Insert(e._1, e._2))) prover.generateProof() @@ -690,7 +690,7 @@ object BatchingPlayground extends App with BatchTestingHelpers with Matchers { for (i <- 0 until testAtTheEnd) { val key = randomKey() keys += key - val m = Insert(ADKey @@ key, randomValue(8)) + val m = Insert(ADKey @@@ key, randomValue(8)) newProver.performOneOperation(m) len += newProver.generateProof().length } @@ -700,7 +700,7 @@ object BatchingPlayground extends App with BatchTestingHelpers with Matchers { len = 0 for (i <- 0 until testAtTheEnd) { val j = Random.randomBytes(3) - val key = ADKey @@ keys( + val key = ADKey @@@ keys( (j(0).toInt.abs + j(1).toInt.abs * 128 + j(2).toInt.abs * 128 * 128) % keys.size) keys -= key val m = Remove(key) @@ -786,7 +786,7 @@ object BatchingPlayground extends App with BatchTestingHelpers with Matchers { digest = p.digest val key = randomKey() - p.performOneOperation(Insert(ADKey @@ key, randomValue(8))) + p.performOneOperation(Insert(ADKey @@@ key, randomValue(8))) pf = p.generateProof() p.checkTree() diff --git a/src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala b/src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala index 2eb1821a..99c43274 100644 --- a/src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala +++ b/src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala @@ -39,8 +39,8 @@ class SigningFunctionsSpecification extends AnyPropSpec val shared = Curve25519.createSharedSecret(keyPair1._1, keyPair2._2) val sharedWithKeysReversed = Curve25519.createSharedSecret(keyPair2._1, keyPair1._2) - val badSharedSecret1 = Curve25519.createSharedSecret(PrivateKey @@ keyPair2._2, keyPair1._2) - val badSharedSecret2 = Curve25519.createSharedSecret(PrivateKey @@ keyPair2._2, keyPair1._2) + val badSharedSecret1 = Curve25519.createSharedSecret(PrivateKey @@@ keyPair2._2, keyPair1._2) + val badSharedSecret2 = Curve25519.createSharedSecret(PrivateKey @@@ keyPair2._2, keyPair1._2) shared.sameElements(sharedWithKeysReversed) should be(true) From 74d88c4aeb4b393a03345ed755e7d9c79f9ada21 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 10 Sep 2022 15:01:14 +0200 Subject: [PATCH 02/36] scala-js: added scorex.utils.Bytes, Ints, Longs --- .../authds/avltree/batch/BatchAVLProver.scala | 3 +- .../avltree/batch/BatchAVLVerifier.scala | 2 +- .../BatchAVLProverSerializer.scala | 7 +-- .../legacy/avltree/AVLModifyProof.scala | 5 +- .../BatchMerkleProofSerializer.scala | 2 +- src/main/scala/scorex/utils/Bytes.scala | 33 ++++++++++ src/main/scala/scorex/utils/Ints.scala | 43 +++++++++++++ src/main/scala/scorex/utils/Longs.scala | 61 +++++++++++++++++++ .../avltree/batch/AVLBatchSpecification.scala | 9 ++- .../batch/AVLBatchStatefulSpecification.scala | 5 +- .../avltree/batch/BatchingPlayground.scala | 10 +-- 11 files changed, 156 insertions(+), 24 deletions(-) create mode 100644 src/main/scala/scorex/utils/Bytes.scala create mode 100644 src/main/scala/scorex/utils/Ints.scala create mode 100644 src/main/scala/scorex/utils/Longs.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala index 57eb08da..e607d2da 100644 --- a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala +++ b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala @@ -1,10 +1,9 @@ package scorex.crypto.authds.avltree.batch -import com.google.common.primitives.Ints import com.typesafe.scalalogging.StrictLogging import scorex.crypto.authds._ import scorex.crypto.hash.{Blake2b256, CryptographicHash, Digest} -import scorex.utils.ByteArray +import scorex.utils.{ByteArray, Ints} import scala.annotation.tailrec import scala.collection.mutable diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala index dfb70767..e4ccb63f 100644 --- a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala +++ b/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds.avltree.batch -import com.google.common.primitives.Ints +import scorex.utils.Ints import scorex.crypto.authds._ import scorex.crypto.hash._ import scorex.utils.ByteArray diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala b/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala index d3bc0176..414df5bf 100644 --- a/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala +++ b/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala @@ -1,11 +1,10 @@ package scorex.crypto.authds.avltree.batch.serialization -import com.google.common.primitives.{Bytes, Ints} -import scorex.crypto.authds.avltree.batch.{BatchAVLProver, InternalProverNode, ProverLeaf, ProverNodes} -import scorex.crypto.authds.{ADKey, ADValue, Balance} +import scorex.crypto.authds.avltree.batch.{BatchAVLProver, ProverLeaf, InternalProverNode, ProverNodes} +import scorex.crypto.authds.{ADValue, ADKey, Balance} import scorex.crypto.hash.{CryptographicHash, Digest} import scorex.util.encode.Base16 -import scorex.utils.ByteArray +import scorex.utils.{Bytes, ByteArray, Ints} import scala.util.Try diff --git a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala b/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala index 1440f31b..441c07cc 100644 --- a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala +++ b/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala @@ -1,12 +1,11 @@ package scorex.crypto.authds.legacy.avltree -import com.google.common.primitives.Bytes import scorex.crypto.authds._ import scorex.crypto.authds.avltree.batch.Modification import scorex.crypto.hash.{CryptographicHash, _} -import scorex.utils.ByteArray +import scorex.utils.{ByteArray, Bytes} -import scala.util.{Failure, Success, Try} +import scala.util.{Try, Success, Failure} case class AVLModifyProof(key: ADKey, proofSeq: Seq[AVLProofElement]) (implicit hf: CryptographicHash[_ <: Digest]) extends TwoPartyProof { diff --git a/src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala b/src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala index 7d156a23..4602289b 100644 --- a/src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala +++ b/src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds.merkle.serialization -import com.google.common.primitives.{Bytes, Ints} +import scorex.utils.{Bytes, Ints} import scorex.crypto.authds.merkle.BatchMerkleProof import scorex.crypto.authds.{EmptyByteArray, Side} import scorex.crypto.hash.{CryptographicHash, Digest, Digest32} diff --git a/src/main/scala/scorex/utils/Bytes.scala b/src/main/scala/scorex/utils/Bytes.scala new file mode 100644 index 00000000..a274400e --- /dev/null +++ b/src/main/scala/scorex/utils/Bytes.scala @@ -0,0 +1,33 @@ +package scorex.utils + +object Bytes { + + /** + * Returns the values from each provided array combined into a single array. For example, + * {@code concat(new byte[] {a, b}, new byte[] {}, new byte[] {c}} returns the array {@code {a, b, + * c}}. + * + * @param arrays zero or more {@code byte} arrays + * @return a single array containing all the values from the source arrays, in order + */ + def concat(arrays: Array[Byte]*): Array[Byte] = { + var length = 0 + val nArrays = arrays.length + var i = 0 + while (i < nArrays) { + length += arrays(i).length + i += 1 + } + val result = new Array[Byte](length) + var pos = 0 + i = 0 + while (i < nArrays) { + val array = arrays(i) + System.arraycopy(array, 0, result, pos, array.length) + pos += array.length + i += 1 + } + result + } + +} diff --git a/src/main/scala/scorex/utils/Ints.scala b/src/main/scala/scorex/utils/Ints.scala new file mode 100644 index 00000000..927ffa40 --- /dev/null +++ b/src/main/scala/scorex/utils/Ints.scala @@ -0,0 +1,43 @@ +package scorex.utils + +object Ints { + /** + * The number of bytes required to represent a primitive {@code int} value. + * + *

Java 8 users: use {@link Integer# BYTES} instead. + */ + val BYTES: Int = Integer.SIZE / java.lang.Byte.SIZE + + /** + * Returns a big-endian representation of {@code value} in a 4-element byte array; equivalent to + * {@code ByteBuffer.allocate(4).putInt(value).array()}. For example, the input value + * {@code 0x12131415} would yield the byte array {@code {0x12, 0x13, 0x14, 0x15}}. + */ + def toByteArray(value: Int): Array[Byte] = { + Array[Byte]((value >> 24).toByte, (value >> 16).toByte, (value >> 8).toByte, value.toByte) + } + + /** + * Returns the {@code int} value whose big-endian representation is stored in the first 4 bytes of + * {@code bytes}; equivalent to {@code ByteBuffer.wrap(bytes).getInt()}. For example, the input + * byte array {@code {0x12, 0x13, 0x14, 0x15, 0x33}} would yield the {@code int} value + * {@code 0x12131415}. + * + * @throws IllegalArgumentException if {@code bytes} has fewer than 4 elements + */ + def fromByteArray(bytes: Array[Byte]): Int = { + require(bytes.length >= BYTES, s"array too small: ${bytes.length} < $BYTES") + fromBytes(bytes(0), bytes(1), bytes(2), bytes(3)) + } + + /** + * Returns the {@code int} value whose byte representation is the given 4 bytes, in big-endian + * order; equivalent to {@code Ints.fromByteArray(new byte[] {b1, b2, b3, b4})}. + */ + def fromBytes(b1: Byte, + b2: Byte, + b3: Byte, + b4: Byte): Int = { + b1 << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF) + } +} diff --git a/src/main/scala/scorex/utils/Longs.scala b/src/main/scala/scorex/utils/Longs.scala new file mode 100644 index 00000000..0dd8b7b1 --- /dev/null +++ b/src/main/scala/scorex/utils/Longs.scala @@ -0,0 +1,61 @@ +package scorex.utils + +/** Operations with long values. The implementation is based on com.google.common.primitives.Longs. */ +object Longs { + /** + * The number of bytes required to represent a primitive {@code long} value. + * + *

Java 8 users: use {@link Long# BYTES} instead. + */ + val BYTES: Int = java.lang.Long.SIZE / java.lang.Byte.SIZE + + /** + * Returns a big-endian representation of {@code value} in an 8-element byte array; equivalent to + * {@code ByteBuffer.allocate(8).putLong(value).array()}. For example, the input value + * {@code 0x1213141516171819L} would yield the byte array {@code {0x12, 0x13, 0x14, 0x15, 0x16, + * 0x17, 0x18, 0x19}}. + */ + def toByteArray(value: Long): Array[Byte] = { + // Note that this code needs to stay compatible with GWT, which has known + // bugs when narrowing byte casts of long values occur. + var v = value + val result = new Array[Byte](8) + var i = 7 + while (i >= 0) { + result(i) = (v & 0xffL).toByte + v >>= 8 + i -= 1 + } + result + } + + /** + * Returns the {@code long} value whose big-endian representation is stored in the first 8 bytes + * of {@code bytes}; equivalent to {@code ByteBuffer.wrap(bytes).getLong()}. For example, the + * input byte array {@code {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}} would yield the + * {@code long} value {@code 0x1213141516171819L}. + * + * @throws IllegalArgumentException if {@code bytes} has fewer than 8 elements + */ + def fromByteArray(bytes: Array[Byte]): Long = { + require(bytes.length >= BYTES, s"array too small: ${bytes.length} < $BYTES") + fromBytes(bytes(0), bytes(1), bytes(2), bytes(3), bytes(4), bytes(5), bytes(6), bytes(7)) + } + + /** + * Returns the {@code long} value whose byte representation is the given 8 bytes, in big-endian + * order; equivalent to {@code Longs.fromByteArray(new byte[] {b1, b2, b3, b4, b5, b6, b7, b8})}. + * + * @since 7.0 + */ + def fromBytes(b1: Byte, + b2: Byte, + b3: Byte, + b4: Byte, + b5: Byte, + b6: Byte, + b7: Byte, + b8: Byte): Long = { + (b1 & 0xFFL) << 56 | (b2 & 0xFFL) << 48 | (b3 & 0xFFL) << 40 | (b4 & 0xFFL) << 32 | (b5 & 0xFFL) << 24 | (b6 & 0xFFL) << 16 | (b7 & 0xFFL) << 8 | (b8 & 0xFFL) + } +} diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala b/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala index f7298c25..602ea0be 100644 --- a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala +++ b/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala @@ -1,17 +1,16 @@ package scorex.crypto.authds.avltree.batch -import com.google.common.primitives.Longs -import org.scalacheck.{Arbitrary, Gen} +import org.scalacheck.{Gen, Arbitrary} import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import scorex.crypto.authds.legacy.avltree.AVLTree import scorex.crypto.authds._ -import scorex.util.encode.{Base16, Base58} +import scorex.util.encode.{Base58, Base16} import scorex.crypto.hash._ -import scorex.utils.{ByteArray, Random} +import scorex.utils.{Random, ByteArray, Longs} import scala.util.Random.{nextInt => randomInt} -import scala.util.{Failure, Try} +import scala.util.{Try, Failure} class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChecks with TwoPartyTests with BatchTestingHelpers { diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala b/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala index e4061b7b..8efb0b9b 100644 --- a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala +++ b/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala @@ -1,14 +1,13 @@ package scorex.crypto.authds.avltree.batch -import com.google.common.primitives.Longs import org.scalacheck.commands.Commands import org.scalacheck.{Gen, Prop} import org.scalatest.propspec.AnyPropSpec import scorex.crypto.authds._ import scorex.crypto.hash.{Blake2b256, Digest32} -import scorex.utils.{Random => RandomBytes} +import scorex.utils.{Longs, Random => RandomBytes} -import scala.util.{Failure, Random, Success, Try} +import scala.util.{Random, Try, Success, Failure} class AVLBatchStatefulSpecification extends AnyPropSpec { diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala b/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala index 9add988a..945fd545 100644 --- a/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala +++ b/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds.avltree.batch -import com.google.common.primitives.Longs +import scorex.utils.Longs import org.scalatest.matchers.should.Matchers import scorex.crypto.authds.legacy.avltree.{AVLModifyProof, AVLTree} import scorex.crypto.authds.{ADDigest, ADKey, ADValue} @@ -1032,16 +1032,16 @@ object BatchingPlayground extends App with BatchTestingHelpers with Matchers { val key1 = ADKey @@ Array(1: Byte) val key2 = ADKey @@ Array(2: Byte) val key3 = ADKey @@ Array(3: Byte) - val op1 = Insert(key1, ADValue @@ Longs.toByteArray(10)) - val op2 = Insert(key2, ADValue @@ Longs.toByteArray(20)) - val op3 = Insert(key3, ADValue @@ Longs.toByteArray(30)) + val op1 = Insert(key1, ADValue @@ Longs.toByteArray(10L)) + val op2 = Insert(key2, ADValue @@ Longs.toByteArray(20L)) + val op3 = Insert(key3, ADValue @@ Longs.toByteArray(30L)) require(prover.performOneOperation(op1).get.isEmpty) // Should return None require(prover.performOneOperation(op2).get.isEmpty) // Should return None require(prover.performOneOperation(op3).get.isEmpty) // Should return None val proof1 = prover.generateProof() val digest1 = prover.digest - val op4 = Update(key1, ADValue @@ Longs.toByteArray(50)) + val op4 = Update(key1, ADValue @@ Longs.toByteArray(50L)) val op5 = UpdateLongBy(key2, -40) val op6 = Lookup(key3) val op7 = Remove(ADKey @@ Array(5: Byte)) From a16ff85185d973d17add611372b2b27075070edb Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 10 Sep 2022 16:25:36 +0200 Subject: [PATCH 03/36] scala-js: added scorex.utils.Shorts, UnsignedBytes.scala --- README.md | 2 +- .../ByteArrayComparePerformance.scala | 2 +- .../scala/scorex.benchmarks/Helpers.scala | 2 +- build.sbt | 1 - .../authds/avltree/batch/Operation.scala | 2 +- .../crypto/authds/legacy/treap/Level.scala | 2 +- .../merkle/sparse/SparseMerkleTree.scala | 2 +- src/main/scala/scorex/utils/ByteArray.scala | 2 - src/main/scala/scorex/utils/Shorts.scala | 12 ++++ .../scala/scorex/utils/UnsignedBytes.scala | 63 +++++++++++++++++++ .../scorex/crypto/authds/TwoPartyTests.scala | 2 +- .../SparseMerkleTreeSpecification.scala | 2 +- 12 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 src/main/scala/scorex/utils/Shorts.scala create mode 100644 src/main/scala/scorex/utils/UnsignedBytes.scala diff --git a/README.md b/README.md index 934fc17a..1faf1405 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Here are code examples for generating proofs and checking them. In this example * First, we create a prover and get an initial digest from it (in a real application, this value is a public constant because anyone, including verifiers, can compute it by using the same two lines of code) ```scala - import com.google.common.primitives.Longs + import scorex.utils.Longs import scorex.crypto.authds.{ADKey, ADValue} import scorex.crypto.authds.avltree.batch._ import scorex.crypto.hash.{Blake2b256, Digest32} diff --git a/benchmarks/src/main/scala/scorex.benchmarks/ByteArrayComparePerformance.scala b/benchmarks/src/main/scala/scorex.benchmarks/ByteArrayComparePerformance.scala index ad9eb15c..a0971ab9 100644 --- a/benchmarks/src/main/scala/scorex.benchmarks/ByteArrayComparePerformance.scala +++ b/benchmarks/src/main/scala/scorex.benchmarks/ByteArrayComparePerformance.scala @@ -2,7 +2,7 @@ package scorex.benchmarks import java.util.concurrent.TimeUnit -import com.google.common.primitives.Shorts +import scorex.utils.Shorts import org.openjdk.jmh.annotations._ import org.openjdk.jmh.infra.Blackhole import scorex.utils.ByteArray diff --git a/benchmarks/src/main/scala/scorex.benchmarks/Helpers.scala b/benchmarks/src/main/scala/scorex.benchmarks/Helpers.scala index 94ee2223..0f8b804a 100644 --- a/benchmarks/src/main/scala/scorex.benchmarks/Helpers.scala +++ b/benchmarks/src/main/scala/scorex.benchmarks/Helpers.scala @@ -1,6 +1,6 @@ package scorex.benchmarks -import com.google.common.primitives.Longs +import scorex.utils.Longs import scorex.crypto.authds.{ADKey, ADValue} import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Operation, Remove} import scorex.crypto.hash.{Blake2b256, Digest32} diff --git a/build.sbt b/build.sbt index f85143f2..8c2c7c6b 100644 --- a/build.sbt +++ b/build.sbt @@ -38,7 +38,6 @@ lazy val commonSettings = Seq( libraryDependencies ++= Seq( "org.rudogma" %% "supertagged" % "2.0-RC2", - "com.google.guava" % "guava" % "23.0", "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2", "org.whispersystems" % "curve25519-java" % "0.5.0", "org.bouncycastle" % "bcprov-jdk15to18" % "1.66", diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala b/src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala index 687d0aca..3da9c80b 100644 --- a/src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala +++ b/src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds.avltree.batch -import com.google.common.primitives.Longs +import scorex.utils.Longs import scorex.crypto.authds.{ADKey, ADValue} import scorex.util.ScorexEncoding diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala b/src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala index c2ebdfb7..0e935b66 100644 --- a/src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala +++ b/src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds.legacy.treap -import com.google.common.primitives.Ints +import scorex.utils.Ints import scorex.crypto.authds.ADKey import scorex.crypto.hash.Sha256 import scorex.utils.ByteArray diff --git a/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala b/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala index 9562b707..5023524c 100644 --- a/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala +++ b/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds.merkle.sparse -import com.google.common.primitives.Longs +import scorex.utils.Longs import scorex.crypto.authds.LeafData import scorex.crypto.hash._ diff --git a/src/main/scala/scorex/utils/ByteArray.scala b/src/main/scala/scorex/utils/ByteArray.scala index a5dd4147..175b7aba 100644 --- a/src/main/scala/scorex/utils/ByteArray.scala +++ b/src/main/scala/scorex/utils/ByteArray.scala @@ -1,7 +1,5 @@ package scorex.utils -import com.google.common.primitives.UnsignedBytes - object ByteArray { def compare(buffer1: Array[Byte], buffer2: Array[Byte]): Int = diff --git a/src/main/scala/scorex/utils/Shorts.scala b/src/main/scala/scorex/utils/Shorts.scala new file mode 100644 index 00000000..534f662b --- /dev/null +++ b/src/main/scala/scorex/utils/Shorts.scala @@ -0,0 +1,12 @@ +package scorex.utils + +object Shorts { + /** + * Returns a big-endian representation of {@code value} in a 2-element byte array; equivalent to + * {@code ByteBuffer.allocate(2).putShort(value).array()}. For example, the input value {@code + * (short) 0x1234} would yield the byte array {@code {0x12, 0x34}}. + */ + def toByteArray(value: Short): Array[Byte] = { + Array[Byte]((value >> 8).toByte, value.toByte) + } +} diff --git a/src/main/scala/scorex/utils/UnsignedBytes.scala b/src/main/scala/scorex/utils/UnsignedBytes.scala new file mode 100644 index 00000000..da060898 --- /dev/null +++ b/src/main/scala/scorex/utils/UnsignedBytes.scala @@ -0,0 +1,63 @@ +package scorex.utils + +import java.util.Comparator + +/** + * Static utility methods pertaining to {@code byte} primitives that interpret values as + * unsigned (that is, any negative value {@code b} is treated as the positive value + * {@code 256 + b}). + */ +object UnsignedBytes { + + private val UNSIGNED_MASK = 0xFF + + /** + * Returns the value of the given byte as an integer, when treated as unsigned. That is, returns + * {@code value + 256} if {@code value} is negative; {@code value} itself otherwise. + */ + @inline def toInt(value: Byte): Int = value & UNSIGNED_MASK + + /** + * Compares the two specified {@code byte} values, treating them as unsigned values between 0 and + * 255 inclusive. For example, {@code (byte) -127} is considered greater than {@code (byte) 127} + * because it is seen as having the value of positive {@code 129}. + * + * @param a the first {@code byte} to compare + * @param b the second {@code byte} to compare + * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is + * greater than {@code b}; or zero if they are equal + */ + @inline def compare(a: Byte, b: Byte): Int = toInt(a) - toInt(b) + + /** + * Returns a comparator that compares two {@code byte} arrays lexicographically. That is, it + * compares, using {@link # compare ( byte, byte)}), the first pair of values that follow any common + * prefix, or when one array is a prefix of the other, treats the shorter array as the lesser. For + * example, {@code [] < [0x01] < [0x01, 0x7F] < [0x01, 0x80] < [0x02]}. Values are treated as + * unsigned. + * + *

The returned comparator is inconsistent with {@link Object# equals ( Object )} (since arrays + * support only identity equality), but it is consistent with + * {@link java.util.Arrays# equals ( byte [ ], byte[])}. + */ + // TODO optimize: use Unsafe for more efficient implementation (as in original guava) + def lexicographicalComparator(): Comparator[Array[Byte]] = PureJavaComparator + + object PureJavaComparator extends Comparator[Array[Byte]] { + + override def compare(left: Array[Byte], right: Array[Byte]): Int = { + val minLength = Math.min(left.length, right.length) + var i = 0 + while (i < minLength) { + val result = UnsignedBytes.compare(left(i), right(i)) + if (result != 0) return result + i += 1 + } + left.length - right.length + } + + } + +} + diff --git a/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala b/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala index 62157a43..b4c64be1 100644 --- a/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala +++ b/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds -import com.google.common.primitives.Longs +import scorex.utils.Longs import scorex.crypto.TestingCommons import scorex.crypto.authds.avltree.batch.{Modification, Update} import scorex.crypto.hash.Digest diff --git a/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala b/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala index 7a3857f4..9a03f49c 100644 --- a/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala +++ b/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds.merkle.sparse -import com.google.common.primitives.Longs +import scorex.utils.Longs import org.scalatest.matchers.should.Matchers import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks From c4c0805c1616ceef470e6be75637c37ef26b9d1d Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 10 Sep 2022 19:31:20 +0200 Subject: [PATCH 04/36] scala-js: removed org.whispersystems dependency and Curve25519 --- build.sbt | 1 - .../scorex/crypto/signatures/Curve25519.scala | 54 -------- .../SigningFunctionsSpecification.scala | 121 ------------------ 3 files changed, 176 deletions(-) delete mode 100644 src/main/scala/scorex/crypto/signatures/Curve25519.scala delete mode 100644 src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala diff --git a/build.sbt b/build.sbt index 8c2c7c6b..d006b49f 100644 --- a/build.sbt +++ b/build.sbt @@ -39,7 +39,6 @@ lazy val commonSettings = Seq( libraryDependencies ++= Seq( "org.rudogma" %% "supertagged" % "2.0-RC2", "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2", - "org.whispersystems" % "curve25519-java" % "0.5.0", "org.bouncycastle" % "bcprov-jdk15to18" % "1.66", "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT" ) diff --git a/src/main/scala/scorex/crypto/signatures/Curve25519.scala b/src/main/scala/scorex/crypto/signatures/Curve25519.scala deleted file mode 100644 index 08b96403..00000000 --- a/src/main/scala/scorex/crypto/signatures/Curve25519.scala +++ /dev/null @@ -1,54 +0,0 @@ -package scorex.crypto.signatures - -import java.lang.reflect.Constructor - -import org.whispersystems.curve25519.OpportunisticCurve25519Provider -import scorex.crypto.hash.Sha256 -import com.typesafe.scalalogging.StrictLogging - -import scala.util.{Failure, Try} - -object Curve25519 extends EllipticCurveSignatureScheme with StrictLogging { - val SignatureLength25519 = 64 - val KeyLength25519 = 32 - - override val SignatureLength = SignatureLength25519 - override val KeyLength = KeyLength25519 - - /* todo: dirty hack, switch to logic as described in WhisperSystem's Curve25519 tutorial when - it would be possible to pass a random seed from outside, see - https://github.com/WhisperSystems/curve25519-java/pull/7 - */ - private val provider: OpportunisticCurve25519Provider = { - val constructor = classOf[OpportunisticCurve25519Provider] - .getDeclaredConstructors - .head - .asInstanceOf[Constructor[OpportunisticCurve25519Provider]] - constructor.setAccessible(true) - constructor.newInstance() - } - - override def createKeyPair(seed: Array[Byte]): (PrivateKey, PublicKey) = { - val hashedSeed = Sha256.hash(seed) - val privateKey = PrivateKey @@ provider.generatePrivateKey(hashedSeed) - privateKey -> PublicKey @@ provider.generatePublicKey(privateKey) - } - - override def sign(privateKey: PrivateKey, message: MessageToSign): Signature = { - require(privateKey.length == KeyLength) - Signature @@ provider.calculateSignature(provider.getRandom(SignatureLength), privateKey, message) - } - - override def verify(signature: Signature, message: MessageToSign, publicKey: PublicKey): Boolean = Try { - require(signature.length == SignatureLength) - require(publicKey.length == KeyLength) - provider.verifySignature(publicKey, message, signature) - }.recoverWith { case e => - logger.debug("Error while message signature verification", e) - Failure(e) - }.getOrElse(false) - - override def createSharedSecret(privateKey: PrivateKey, publicKey: PublicKey): SharedSecret = { - SharedSecret @@ provider.calculateAgreement(privateKey, publicKey) - } -} \ No newline at end of file diff --git a/src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala b/src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala deleted file mode 100644 index 99c43274..00000000 --- a/src/test/scala/scorex/crypto/signing/SigningFunctionsSpecification.scala +++ /dev/null @@ -1,121 +0,0 @@ -package scorex.crypto.signing - - -import org.scalatest.propspec.AnyPropSpec -import org.scalatest.matchers.should.Matchers -import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks -import scorex.util.encode.Base16 -import scorex.crypto.signatures.{Curve25519, PrivateKey} - - -class SigningFunctionsSpecification extends AnyPropSpec - with ScalaCheckDrivenPropertyChecks - with Matchers { - - property("signed message should be verifiable with appropriate public key") { - forAll { (seed1: Array[Byte], seed2: Array[Byte], - message1: Array[Byte], message2: Array[Byte]) => - whenever(!seed1.sameElements(seed2) && !message1.sameElements(message2)) { - val keyPair = Curve25519.createKeyPair(seed1) - val keyPair2 = Curve25519.createKeyPair(seed2) - - val sig = Curve25519.sign(keyPair._1, message1) - - Curve25519.verify(sig, message1, keyPair._2) shouldBe true - Curve25519.verify(sig, message1, keyPair2._2) should not be true - Curve25519.verify(sig, message2, keyPair._2) should not be true - - } - } - } - - property("shared secret should be same for both parties ") { - - forAll { (seed1: Array[Byte], seed2: Array[Byte]) => - whenever(!seed1.sameElements(seed2)) { - val keyPair1 = Curve25519.createKeyPair(seed1) - val keyPair2 = Curve25519.createKeyPair(seed2) - - val shared = Curve25519.createSharedSecret(keyPair1._1, keyPair2._2) - val sharedWithKeysReversed = Curve25519.createSharedSecret(keyPair2._1, keyPair1._2) - - val badSharedSecret1 = Curve25519.createSharedSecret(PrivateKey @@@ keyPair2._2, keyPair1._2) - val badSharedSecret2 = Curve25519.createSharedSecret(PrivateKey @@@ keyPair2._2, keyPair1._2) - - shared.sameElements(sharedWithKeysReversed) should be(true) - - badSharedSecret1.sameElements(shared) shouldNot be(true) - - badSharedSecret2.sameElements(shared) shouldNot be(true) - } - } - } - - property("test vectors from https://tools.ietf.org/html/rfc8032#page-24 - test 1") { - val privKey = PrivateKey @@ Base16.decode("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60").get - val message = Array[Byte]() - val sig = Curve25519.sign(privKey, message) - val specSig = Base16.decode("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e" + - "39701cf9b46bd25bf5f0595bbe24655141438e7a100b").get - sig.sameElements(specSig) - } - - property("test vectors from https://tools.ietf.org/html/rfc8032#page-24 - test 2") { - val privKey = PrivateKey @@ Base16.decode("4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb").get - val message = Base16.decode("72").get - val sig = Curve25519.sign(privKey, message) - val specSig = Base16.decode("92a009a9f0d4cab8720e820b5f642540" + - "a2b27b5416503f8fb3762223ebdb69da" + - "085ac1e43e15996e458f3613d0f11d8c" + - "387b2eaeb4302aeeb00d291612bb0c00").get - sig.sameElements(specSig) - } - - property("test vectors from https://tools.ietf.org/html/rfc8032#page-24 - test 3") { - val privKey = PrivateKey @@ Base16.decode("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7").get - val message = Base16.decode("af82").get - val sig = Curve25519.sign(privKey, message) - val specSig = Base16.decode("6291d657deec24024827e69c3abe01a3" + - "0ce548a284743a445e3680d7db5ac3ac" + - "18ff9b538d16f290ae67f760984dc659" + - "4a7c15e9716ed28dc027beceea1ec40a").get - sig.sameElements(specSig) - } - - property("test vectors from https://tools.ietf.org/html/rfc8032#page-24 - test 1024") { - val privKey = PrivateKey @@ Base16.decode("f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5").get - val message = Base16.decode("08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50" + - "f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d65" + - "8675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199e" + - "e5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560cc" + - "b9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd" + - "7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5" + - "aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187e" + - "bb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd6" + - "2481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27a" + - "f87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c" + - "144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1" + - "ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57" + - "fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a" + - "7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd4" + - "19c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342" + - "721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246" + - "f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11" + - "faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4d" + - "c1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0").get - val sig = Curve25519.sign(privKey, message) - val specSig = Base16.decode("0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ec" + - "ea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03").get - sig.sameElements(specSig) - } - - property("test vectors from https://tools.ietf.org/html/rfc8032#page-24 - test SHA") { - val privKey = PrivateKey @@ Base16.decode("833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42").get - val message = Base16.decode("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836" + - "ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f").get - val sig = Curve25519.sign(privKey, message) - val specSig = Base16.decode("dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdf" + - "bc7c66431e0303dca179c138ac17ad9bef1177331a704").get - sig.sameElements(specSig) - } -} \ No newline at end of file From 18736a67431a786a535c612238f08bd3c3b7dbf1 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 11 Sep 2022 11:10:11 +0200 Subject: [PATCH 05/36] scala-js: configure cross-platform sbt setup --- build.sbt | 52 +++++++++++-------- project/plugins.sbt | 4 ++ .../scorex/crypto/authds/ProofIterator.scala | 0 .../crypto/authds/TwoPartyDictionary.scala | 0 .../scorex/crypto/authds/TwoPartyProof.scala | 0 .../crypto/authds/TwoPartyProofElement.scala | 0 .../scala/scorex/crypto/authds/authds.scala | 0 .../avltree/batch/AuthenticatedTreeOps.scala | 0 .../authds/avltree/batch/BatchAVLProver.scala | 0 .../avltree/batch/BatchAVLVerifier.scala | 0 .../authds/avltree/batch/BatchNode.scala | 0 .../avltree/batch/BatchProofConstants.scala | 0 .../authds/avltree/batch/Operation.scala | 0 .../batch/PersistentBatchAVLProver.scala | 0 .../authds/avltree/batch/ToStringHelper.scala | 0 .../avltree/batch/VersionedAVLStorage.scala | 0 .../BatchAVLProverManifest.scala | 0 .../BatchAVLProverSerializer.scala | 0 .../serialization/BatchAVLProverSubtree.scala | 0 .../serialization/ProxyInternalNode.scala | 0 .../legacy/avltree/AVLModifyProof.scala | 0 .../authds/legacy/avltree/AVLTree.scala | 0 .../crypto/authds/legacy/avltree/Node.scala | 0 .../authds/legacy/treap/Constants.scala | 0 .../crypto/authds/legacy/treap/Level.scala | 0 .../crypto/authds/legacy/treap/Node.scala | 0 .../crypto/authds/legacy/treap/Treap.scala | 0 .../legacy/treap/TreapModifyProof.scala | 0 .../authds/merkle/BatchMerkleProof.scala | 0 .../crypto/authds/merkle/MerkleProof.scala | 0 .../crypto/authds/merkle/MerkleTree.scala | 0 .../scorex/crypto/authds/merkle/Node.scala | 0 .../BatchMerkleProofSerializer.scala | 0 .../crypto/authds/merkle/sparse/Node.scala | 0 .../merkle/sparse/SparseMerkleTree.scala | 0 .../scala/scorex/crypto/encode/package.scala | 0 .../scala/scorex/crypto/hash/Blake2b.scala | 0 .../scala/scorex/crypto/hash/Blake2b256.scala | 0 .../scorex/crypto/hash/Blake2b256Unsafe.scala | 0 .../scala/scorex/crypto/hash/Blake2b512.scala | 0 .../scorex/crypto/hash/BouncyCastleHash.scala | 0 .../scorex/crypto/hash/CommutativeHash.scala | 0 .../crypto/hash/CryptographicHash.scala | 0 .../crypto/hash/CryptographicHash32.scala | 0 .../crypto/hash/CryptographicHash64.scala | 0 .../scala/scorex/crypto/hash/Keccak.scala | 0 .../scala/scorex/crypto/hash/Keccak256.scala | 0 .../scala/scorex/crypto/hash/Keccak512.scala | 0 .../scala/scorex/crypto/hash/Sha256.scala | 0 .../scorex/crypto/hash/Sha256Unsafe.scala | 0 .../scala/scorex/crypto/hash/Skein256.scala | 0 .../scala/scorex/crypto/hash/Skein512.scala | 0 .../scala/scorex/crypto/hash/Stribog256.scala | 0 .../scala/scorex/crypto/hash/Stribog512.scala | 0 .../scorex/crypto/hash/ThreadUnsafeHash.scala | 0 .../scala/scorex/crypto/hash/Whirlpool.scala | 0 .../main/scala/scorex/crypto/hash/hash.scala | 0 .../EllipticCurveSignatureScheme.scala | 0 .../crypto/signatures/SigningFunctions.scala | 0 .../scorex/crypto/signatures/signatures.scala | 0 .../main/scala/scorex/utils/Booleans.scala | 0 .../main/scala/scorex/utils/ByteArray.scala | 0 .../src}/main/scala/scorex/utils/Bytes.scala | 0 .../src}/main/scala/scorex/utils/Ints.scala | 0 .../src}/main/scala/scorex/utils/Longs.scala | 0 .../src}/main/scala/scorex/utils/Random.scala | 0 .../src}/main/scala/scorex/utils/Shorts.scala | 0 .../scala/scorex/utils/UnsignedBytes.scala | 0 .../main/scala/scorex/utils/package.scala | 0 .../scala/scorex/crypto/TestingCommons.scala | 0 .../scorex/crypto/authds/TwoPartyTests.scala | 0 .../avltree/AVLDeleteSpecification.scala | 0 .../authds/avltree/AVLTreeSpecification.scala | 0 .../avltree/batch/AVLBatchSpecification.scala | 0 .../batch/AVLBatchStatefulSpecification.scala | 0 .../authds/avltree/batch/BatchTesting.scala | 0 .../avltree/batch/BatchTestingHelpers.scala | 0 .../avltree/batch/BatchingPlayground.scala | 0 .../batch/VersionedAVLStorageMock.scala | 0 .../AVLBatchSerializationSpecification.scala | 0 .../legacy/treap/TreapSpecification.scala | 0 .../merkle/MerkleTreeSpecification.scala | 0 ...chMerkleProofSerializerSpecification.scala | 0 .../SparseMerkleTreeSpecification.scala | 0 .../crypto/hash/Blake2bSpecification.scala | 0 .../hash/Blake2bUnsafeSpecification.scala | 0 .../hash/CommutativeHashSpecification.scala | 0 .../scala/scorex/crypto/hash/HashTest.scala | 0 .../crypto/hash/KeccakSpecification.scala | 0 .../scorex/crypto/hash/ShaSpecification.scala | 0 .../crypto/hash/SkeinSpecification.scala | 0 .../crypto/hash/StribogSpecification.scala | 0 .../crypto/hash/WirlpoolSpecification.scala | 0 93 files changed, 34 insertions(+), 22 deletions(-) rename {src => shared/src}/main/scala/scorex/crypto/authds/ProofIterator.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/TwoPartyDictionary.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/TwoPartyProof.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/TwoPartyProofElement.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/authds.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/AuthenticatedTreeOps.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/BatchNode.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/BatchProofConstants.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/PersistentBatchAVLProver.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/ToStringHelper.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorage.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverManifest.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSubtree.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/avltree/batch/serialization/ProxyInternalNode.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/avltree/Node.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/treap/Constants.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/treap/Level.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/treap/Node.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/merkle/BatchMerkleProof.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/merkle/MerkleProof.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/merkle/MerkleTree.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/merkle/Node.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/merkle/sparse/Node.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/encode/package.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Blake2b.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Blake2b256.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Blake2b512.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/BouncyCastleHash.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/CommutativeHash.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/CryptographicHash.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/CryptographicHash32.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/CryptographicHash64.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Keccak.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Keccak256.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Keccak512.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Sha256.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Sha256Unsafe.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Skein256.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Skein512.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Stribog256.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Stribog512.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/Whirlpool.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/hash/hash.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/signatures/SigningFunctions.scala (100%) rename {src => shared/src}/main/scala/scorex/crypto/signatures/signatures.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/Booleans.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/ByteArray.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/Bytes.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/Ints.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/Longs.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/Random.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/Shorts.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/UnsignedBytes.scala (100%) rename {src => shared/src}/main/scala/scorex/utils/package.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/TestingCommons.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/TwoPartyTests.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/AVLTreeSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/batch/BatchTesting.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/batch/BatchTestingHelpers.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorageMock.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/legacy/treap/TreapSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/Blake2bSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/CommutativeHashSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/HashTest.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/KeccakSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/ShaSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/SkeinSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/StribogSpecification.scala (100%) rename {src => shared/src}/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala (100%) diff --git a/build.sbt b/build.sbt index d006b49f..d50a53b9 100644 --- a/build.sbt +++ b/build.sbt @@ -7,9 +7,6 @@ lazy val scala213 = "2.13.8" lazy val scala212 = "2.12.15" lazy val scala211 = "2.11.12" -crossScalaVersions := Seq(scala212, scala211, scala213) -scalaVersion := scala213 - javacOptions ++= "-source" :: "1.8" :: "-target" :: "1.8" :: @@ -34,32 +31,43 @@ lazy val commonSettings = Seq( "scm:git@github.com:input-output-hk/scrypto.git" ) ), + libraryDependencies ++= Seq( + "org.rudogma" %% "supertagged" % "2.0-RC2", + "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT", + "org.scalatest" %%% "scalatest" % "3.3.0-SNAP3" % Test, + "org.scalacheck" %%% "scalacheck" % "1.15.2" % Test, + "org.scalatestplus" %%% "scalacheck-1-15" % "3.3.0.0-SNAP3" % Test + ), + publishMavenStyle := true, + publishTo := sonatypePublishToBundle.value ) -libraryDependencies ++= Seq( - "org.rudogma" %% "supertagged" % "2.0-RC2", - "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2", - "org.bouncycastle" % "bcprov-jdk15to18" % "1.66", - "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT" -) - -libraryDependencies ++= Seq( - "org.scalatest" %% "scalatest" % "3.1.+" % Test, - "org.scalacheck" %% "scalacheck" % "1.14.+" % Test, - // https://mvnrepository.com/artifact/org.scalatestplus/scalatestplus-scalacheck - "org.scalatestplus" %% "scalatestplus-scalacheck" % "3.1.0.0-RC2" % Test -) -publishMavenStyle := true -publishArtifact in Test := false +Test / publishArtifact := false -publishTo := sonatypePublishToBundle.value pomIncludeRepository := { _ => false } -lazy val scrypto = (project in file(".")) +lazy val scrypto = crossProject(JVMPlatform) + .in(file(".")) .settings(commonSettings: _*) + .jvmSettings( + libraryDependencies ++= Seq( + "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2", + "org.bouncycastle" % "bcprov-jdk15to18" % "1.66" + ), + scalaVersion := scala213, + crossScalaVersions := Seq(scala211, scala212, scala213) + ) +// .jsSettings( +// scalaVersion := scala213, +// crossScalaVersions := Seq(scala213), +// libraryDependencies ++= Seq( +// ), +// parallelExecution in Test := false +// ) + //lazy val benchmarks = (project in file("benchmarks")) // .settings(commonSettings, name := "scrypto-benchmarks") @@ -72,9 +80,9 @@ credentials ++= (for { } yield Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", username, password)).toSeq // prefix version with "-SNAPSHOT" for builds without a git tag -dynverSonatypeSnapshots in ThisBuild := true +ThisBuild / dynverSonatypeSnapshots := true // use "-" instead of default "+" -dynverSeparator in ThisBuild := "-" +ThisBuild / dynverSeparator := "-" // PGP key for signing a release build published to sonatype // signing is done by sbt-pgp plugin diff --git a/project/plugins.sbt b/project/plugins.sbt index c6c825c8..6ec00c7f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -14,3 +14,7 @@ addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.8") addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.0") addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") + +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0") + +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") diff --git a/src/main/scala/scorex/crypto/authds/ProofIterator.scala b/shared/src/main/scala/scorex/crypto/authds/ProofIterator.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/ProofIterator.scala rename to shared/src/main/scala/scorex/crypto/authds/ProofIterator.scala diff --git a/src/main/scala/scorex/crypto/authds/TwoPartyDictionary.scala b/shared/src/main/scala/scorex/crypto/authds/TwoPartyDictionary.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/TwoPartyDictionary.scala rename to shared/src/main/scala/scorex/crypto/authds/TwoPartyDictionary.scala diff --git a/src/main/scala/scorex/crypto/authds/TwoPartyProof.scala b/shared/src/main/scala/scorex/crypto/authds/TwoPartyProof.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/TwoPartyProof.scala rename to shared/src/main/scala/scorex/crypto/authds/TwoPartyProof.scala diff --git a/src/main/scala/scorex/crypto/authds/TwoPartyProofElement.scala b/shared/src/main/scala/scorex/crypto/authds/TwoPartyProofElement.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/TwoPartyProofElement.scala rename to shared/src/main/scala/scorex/crypto/authds/TwoPartyProofElement.scala diff --git a/src/main/scala/scorex/crypto/authds/authds.scala b/shared/src/main/scala/scorex/crypto/authds/authds.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/authds.scala rename to shared/src/main/scala/scorex/crypto/authds/authds.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/AuthenticatedTreeOps.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/AuthenticatedTreeOps.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/AuthenticatedTreeOps.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/AuthenticatedTreeOps.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLVerifier.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchNode.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchNode.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/BatchNode.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchNode.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/BatchProofConstants.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchProofConstants.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/BatchProofConstants.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchProofConstants.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/Operation.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/PersistentBatchAVLProver.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/PersistentBatchAVLProver.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/PersistentBatchAVLProver.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/PersistentBatchAVLProver.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/ToStringHelper.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/ToStringHelper.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/ToStringHelper.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/ToStringHelper.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorage.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorage.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorage.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorage.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverManifest.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverManifest.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverManifest.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverManifest.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSubtree.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSubtree.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSubtree.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSubtree.scala diff --git a/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/ProxyInternalNode.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/ProxyInternalNode.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/avltree/batch/serialization/ProxyInternalNode.scala rename to shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/ProxyInternalNode.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLModifyProof.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/avltree/AVLTree.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/avltree/Node.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/avltree/Node.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/avltree/Node.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/avltree/Node.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/Constants.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/treap/Constants.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/treap/Constants.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/treap/Constants.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/treap/Level.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/Node.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/treap/Node.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/treap/Node.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/treap/Node.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/treap/Treap.scala diff --git a/src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala b/shared/src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala rename to shared/src/main/scala/scorex/crypto/authds/legacy/treap/TreapModifyProof.scala diff --git a/src/main/scala/scorex/crypto/authds/merkle/BatchMerkleProof.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/BatchMerkleProof.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/merkle/BatchMerkleProof.scala rename to shared/src/main/scala/scorex/crypto/authds/merkle/BatchMerkleProof.scala diff --git a/src/main/scala/scorex/crypto/authds/merkle/MerkleProof.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/MerkleProof.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/merkle/MerkleProof.scala rename to shared/src/main/scala/scorex/crypto/authds/merkle/MerkleProof.scala diff --git a/src/main/scala/scorex/crypto/authds/merkle/MerkleTree.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/MerkleTree.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/merkle/MerkleTree.scala rename to shared/src/main/scala/scorex/crypto/authds/merkle/MerkleTree.scala diff --git a/src/main/scala/scorex/crypto/authds/merkle/Node.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/Node.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/merkle/Node.scala rename to shared/src/main/scala/scorex/crypto/authds/merkle/Node.scala diff --git a/src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala rename to shared/src/main/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializer.scala diff --git a/src/main/scala/scorex/crypto/authds/merkle/sparse/Node.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/sparse/Node.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/merkle/sparse/Node.scala rename to shared/src/main/scala/scorex/crypto/authds/merkle/sparse/Node.scala diff --git a/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala similarity index 100% rename from src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala rename to shared/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala diff --git a/src/main/scala/scorex/crypto/encode/package.scala b/shared/src/main/scala/scorex/crypto/encode/package.scala similarity index 100% rename from src/main/scala/scorex/crypto/encode/package.scala rename to shared/src/main/scala/scorex/crypto/encode/package.scala diff --git a/src/main/scala/scorex/crypto/hash/Blake2b.scala b/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Blake2b.scala rename to shared/src/main/scala/scorex/crypto/hash/Blake2b.scala diff --git a/src/main/scala/scorex/crypto/hash/Blake2b256.scala b/shared/src/main/scala/scorex/crypto/hash/Blake2b256.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Blake2b256.scala rename to shared/src/main/scala/scorex/crypto/hash/Blake2b256.scala diff --git a/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala b/shared/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala rename to shared/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala diff --git a/src/main/scala/scorex/crypto/hash/Blake2b512.scala b/shared/src/main/scala/scorex/crypto/hash/Blake2b512.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Blake2b512.scala rename to shared/src/main/scala/scorex/crypto/hash/Blake2b512.scala diff --git a/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala b/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala rename to shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala diff --git a/src/main/scala/scorex/crypto/hash/CommutativeHash.scala b/shared/src/main/scala/scorex/crypto/hash/CommutativeHash.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/CommutativeHash.scala rename to shared/src/main/scala/scorex/crypto/hash/CommutativeHash.scala diff --git a/src/main/scala/scorex/crypto/hash/CryptographicHash.scala b/shared/src/main/scala/scorex/crypto/hash/CryptographicHash.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/CryptographicHash.scala rename to shared/src/main/scala/scorex/crypto/hash/CryptographicHash.scala diff --git a/src/main/scala/scorex/crypto/hash/CryptographicHash32.scala b/shared/src/main/scala/scorex/crypto/hash/CryptographicHash32.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/CryptographicHash32.scala rename to shared/src/main/scala/scorex/crypto/hash/CryptographicHash32.scala diff --git a/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala b/shared/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/CryptographicHash64.scala rename to shared/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala diff --git a/src/main/scala/scorex/crypto/hash/Keccak.scala b/shared/src/main/scala/scorex/crypto/hash/Keccak.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Keccak.scala rename to shared/src/main/scala/scorex/crypto/hash/Keccak.scala diff --git a/src/main/scala/scorex/crypto/hash/Keccak256.scala b/shared/src/main/scala/scorex/crypto/hash/Keccak256.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Keccak256.scala rename to shared/src/main/scala/scorex/crypto/hash/Keccak256.scala diff --git a/src/main/scala/scorex/crypto/hash/Keccak512.scala b/shared/src/main/scala/scorex/crypto/hash/Keccak512.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Keccak512.scala rename to shared/src/main/scala/scorex/crypto/hash/Keccak512.scala diff --git a/src/main/scala/scorex/crypto/hash/Sha256.scala b/shared/src/main/scala/scorex/crypto/hash/Sha256.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Sha256.scala rename to shared/src/main/scala/scorex/crypto/hash/Sha256.scala diff --git a/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala b/shared/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala rename to shared/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala diff --git a/src/main/scala/scorex/crypto/hash/Skein256.scala b/shared/src/main/scala/scorex/crypto/hash/Skein256.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Skein256.scala rename to shared/src/main/scala/scorex/crypto/hash/Skein256.scala diff --git a/src/main/scala/scorex/crypto/hash/Skein512.scala b/shared/src/main/scala/scorex/crypto/hash/Skein512.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Skein512.scala rename to shared/src/main/scala/scorex/crypto/hash/Skein512.scala diff --git a/src/main/scala/scorex/crypto/hash/Stribog256.scala b/shared/src/main/scala/scorex/crypto/hash/Stribog256.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Stribog256.scala rename to shared/src/main/scala/scorex/crypto/hash/Stribog256.scala diff --git a/src/main/scala/scorex/crypto/hash/Stribog512.scala b/shared/src/main/scala/scorex/crypto/hash/Stribog512.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Stribog512.scala rename to shared/src/main/scala/scorex/crypto/hash/Stribog512.scala diff --git a/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala b/shared/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala rename to shared/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala diff --git a/src/main/scala/scorex/crypto/hash/Whirlpool.scala b/shared/src/main/scala/scorex/crypto/hash/Whirlpool.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/Whirlpool.scala rename to shared/src/main/scala/scorex/crypto/hash/Whirlpool.scala diff --git a/src/main/scala/scorex/crypto/hash/hash.scala b/shared/src/main/scala/scorex/crypto/hash/hash.scala similarity index 100% rename from src/main/scala/scorex/crypto/hash/hash.scala rename to shared/src/main/scala/scorex/crypto/hash/hash.scala diff --git a/src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala b/shared/src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala similarity index 100% rename from src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala rename to shared/src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala diff --git a/src/main/scala/scorex/crypto/signatures/SigningFunctions.scala b/shared/src/main/scala/scorex/crypto/signatures/SigningFunctions.scala similarity index 100% rename from src/main/scala/scorex/crypto/signatures/SigningFunctions.scala rename to shared/src/main/scala/scorex/crypto/signatures/SigningFunctions.scala diff --git a/src/main/scala/scorex/crypto/signatures/signatures.scala b/shared/src/main/scala/scorex/crypto/signatures/signatures.scala similarity index 100% rename from src/main/scala/scorex/crypto/signatures/signatures.scala rename to shared/src/main/scala/scorex/crypto/signatures/signatures.scala diff --git a/src/main/scala/scorex/utils/Booleans.scala b/shared/src/main/scala/scorex/utils/Booleans.scala similarity index 100% rename from src/main/scala/scorex/utils/Booleans.scala rename to shared/src/main/scala/scorex/utils/Booleans.scala diff --git a/src/main/scala/scorex/utils/ByteArray.scala b/shared/src/main/scala/scorex/utils/ByteArray.scala similarity index 100% rename from src/main/scala/scorex/utils/ByteArray.scala rename to shared/src/main/scala/scorex/utils/ByteArray.scala diff --git a/src/main/scala/scorex/utils/Bytes.scala b/shared/src/main/scala/scorex/utils/Bytes.scala similarity index 100% rename from src/main/scala/scorex/utils/Bytes.scala rename to shared/src/main/scala/scorex/utils/Bytes.scala diff --git a/src/main/scala/scorex/utils/Ints.scala b/shared/src/main/scala/scorex/utils/Ints.scala similarity index 100% rename from src/main/scala/scorex/utils/Ints.scala rename to shared/src/main/scala/scorex/utils/Ints.scala diff --git a/src/main/scala/scorex/utils/Longs.scala b/shared/src/main/scala/scorex/utils/Longs.scala similarity index 100% rename from src/main/scala/scorex/utils/Longs.scala rename to shared/src/main/scala/scorex/utils/Longs.scala diff --git a/src/main/scala/scorex/utils/Random.scala b/shared/src/main/scala/scorex/utils/Random.scala similarity index 100% rename from src/main/scala/scorex/utils/Random.scala rename to shared/src/main/scala/scorex/utils/Random.scala diff --git a/src/main/scala/scorex/utils/Shorts.scala b/shared/src/main/scala/scorex/utils/Shorts.scala similarity index 100% rename from src/main/scala/scorex/utils/Shorts.scala rename to shared/src/main/scala/scorex/utils/Shorts.scala diff --git a/src/main/scala/scorex/utils/UnsignedBytes.scala b/shared/src/main/scala/scorex/utils/UnsignedBytes.scala similarity index 100% rename from src/main/scala/scorex/utils/UnsignedBytes.scala rename to shared/src/main/scala/scorex/utils/UnsignedBytes.scala diff --git a/src/main/scala/scorex/utils/package.scala b/shared/src/main/scala/scorex/utils/package.scala similarity index 100% rename from src/main/scala/scorex/utils/package.scala rename to shared/src/main/scala/scorex/utils/package.scala diff --git a/src/test/scala/scorex/crypto/TestingCommons.scala b/shared/src/test/scala/scorex/crypto/TestingCommons.scala similarity index 100% rename from src/test/scala/scorex/crypto/TestingCommons.scala rename to shared/src/test/scala/scorex/crypto/TestingCommons.scala diff --git a/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala b/shared/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/TwoPartyTests.scala rename to shared/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/AVLTreeSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/AVLTreeSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/AVLTreeSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/AVLTreeSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/BatchTesting.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/BatchTesting.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/batch/BatchTesting.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/batch/BatchTesting.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/BatchTestingHelpers.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/BatchTestingHelpers.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/batch/BatchTestingHelpers.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/batch/BatchTestingHelpers.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/batch/BatchingPlayground.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorageMock.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorageMock.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorageMock.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/batch/VersionedAVLStorageMock.scala diff --git a/src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/legacy/treap/TreapSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/legacy/treap/TreapSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/legacy/treap/TreapSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/legacy/treap/TreapSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala diff --git a/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala rename to shared/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/CommutativeHashSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/CommutativeHashSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/CommutativeHashSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/CommutativeHashSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/HashTest.scala b/shared/src/test/scala/scorex/crypto/hash/HashTest.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/HashTest.scala rename to shared/src/test/scala/scorex/crypto/hash/HashTest.scala diff --git a/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/KeccakSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/ShaSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/ShaSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/ShaSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/ShaSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/SkeinSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/StribogSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/StribogSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/StribogSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/StribogSpecification.scala diff --git a/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala b/shared/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala similarity index 100% rename from src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala rename to shared/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala From b79798ca56cd24781a54e318bc380d5a32ea15bf Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 15:03:28 +0200 Subject: [PATCH 06/36] scala-js: update scorex-util dependency --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index d50a53b9..d107054a 100644 --- a/build.sbt +++ b/build.sbt @@ -33,7 +33,7 @@ lazy val commonSettings = Seq( ), libraryDependencies ++= Seq( "org.rudogma" %% "supertagged" % "2.0-RC2", - "org.scorexfoundation" %% "scorex-util" % "0.1.8-18-4f4d3c60-SNAPSHOT", + "org.scorexfoundation" %% "scorex-util" % "0.1.8-19-0331a3d9-SNAPSHOT", "org.scalatest" %%% "scalatest" % "3.3.0-SNAP3" % Test, "org.scalacheck" %%% "scalacheck" % "1.15.2" % Test, "org.scalatestplus" %%% "scalacheck-1-15" % "3.3.0.0-SNAP3" % Test From 89add8a26af2f093804dd4c9126816987af5e995 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 15:05:13 +0200 Subject: [PATCH 07/36] scala-js: remove unused declarations --- .../EllipticCurveSignatureScheme.scala | 3 --- .../crypto/signatures/SigningFunctions.scala | 23 ----------------- .../scorex/crypto/signatures/signatures.scala | 25 ------------------- 3 files changed, 51 deletions(-) delete mode 100644 shared/src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala delete mode 100644 shared/src/main/scala/scorex/crypto/signatures/SigningFunctions.scala delete mode 100644 shared/src/main/scala/scorex/crypto/signatures/signatures.scala diff --git a/shared/src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala b/shared/src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala deleted file mode 100644 index 31c77c4b..00000000 --- a/shared/src/main/scala/scorex/crypto/signatures/EllipticCurveSignatureScheme.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scorex.crypto.signatures - -trait EllipticCurveSignatureScheme extends SigningFunctions diff --git a/shared/src/main/scala/scorex/crypto/signatures/SigningFunctions.scala b/shared/src/main/scala/scorex/crypto/signatures/SigningFunctions.scala deleted file mode 100644 index fbda0c80..00000000 --- a/shared/src/main/scala/scorex/crypto/signatures/SigningFunctions.scala +++ /dev/null @@ -1,23 +0,0 @@ -package scorex.crypto.signatures - -import java.security.SecureRandom - -trait SigningFunctions { - - val SignatureLength: Int - val KeyLength: Int - - def createKeyPair(seed: Array[Byte]): (PrivateKey, PublicKey) - - def createKeyPair: (PrivateKey, PublicKey) = { - val seed = new Array[Byte](KeyLength) - new SecureRandom().nextBytes(seed) // modifies seed - createKeyPair(seed) - } - - def sign(privateKey: PrivateKey, message: MessageToSign): Signature - - def verify(signature: Signature, message: MessageToSign, publicKey: PublicKey): Boolean - - def createSharedSecret(privateKey: PrivateKey, publicKey: PublicKey): SharedSecret -} diff --git a/shared/src/main/scala/scorex/crypto/signatures/signatures.scala b/shared/src/main/scala/scorex/crypto/signatures/signatures.scala deleted file mode 100644 index c8c222d0..00000000 --- a/shared/src/main/scala/scorex/crypto/signatures/signatures.scala +++ /dev/null @@ -1,25 +0,0 @@ -package scorex.crypto - -import supertagged.TaggedType - -package object signatures { - - object PrivateKey extends TaggedType[Array[Byte]] - - type PrivateKey = PrivateKey.Type - - object PublicKey extends TaggedType[Array[Byte]] - - type PublicKey = PublicKey.Type - - object SharedSecret extends TaggedType[Array[Byte]] - - type SharedSecret = SharedSecret.Type - - object Signature extends TaggedType[Array[Byte]] - - type Signature = Signature.Type - - type MessageToSign = Array[Byte] - -} From c99a931c27329030b7ec0c5df2233e72971eaffd Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 15:42:04 +0200 Subject: [PATCH 08/36] scala-js: remove scala-logging dependence --- build.sbt | 1 - .../authds/avltree/batch/BatchAVLProver.scala | 7 +++---- .../serialization/BatchAVLProverSerializer.scala | 9 ++++++--- shared/src/main/scala/scorex/utils/Logger.scala | 13 +++++++++++++ .../scala/scorex/crypto/authds/TwoPartyTests.scala | 4 +++- .../authds/avltree/AVLDeleteSpecification.scala | 3 ++- 6 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 shared/src/main/scala/scorex/utils/Logger.scala diff --git a/build.sbt b/build.sbt index d107054a..26f2b82a 100644 --- a/build.sbt +++ b/build.sbt @@ -54,7 +54,6 @@ lazy val scrypto = crossProject(JVMPlatform) .settings(commonSettings: _*) .jvmSettings( libraryDependencies ++= Seq( - "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2", "org.bouncycastle" % "bcprov-jdk15to18" % "1.66" ), scalaVersion := scala213, diff --git a/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala index e607d2da..8c2a0ae1 100644 --- a/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala +++ b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/BatchAVLProver.scala @@ -1,9 +1,8 @@ package scorex.crypto.authds.avltree.batch -import com.typesafe.scalalogging.StrictLogging import scorex.crypto.authds._ import scorex.crypto.hash.{Blake2b256, CryptographicHash, Digest} -import scorex.utils.{ByteArray, Ints} +import scorex.utils.{Ints, ByteArray, Logger} import scala.annotation.tailrec import scala.collection.mutable @@ -26,8 +25,8 @@ class BatchAVLProver[D <: Digest, HF <: CryptographicHash[D]](val keyLength: Int oldRootAndHeight: Option[(ProverNodes[D], Int)] = None, val collectChangedNodes: Boolean = true) (implicit val hf: HF = Blake2b256) - extends AuthenticatedTreeOps[D] with ToStringHelper with StrictLogging { - + extends AuthenticatedTreeOps[D] with ToStringHelper { + val logger: Logger = Logger.Default protected val labelLength: Int = hf.DigestSize private[batch] var topNode: ProverNodes[D] = oldRootAndHeight.map(_._1).getOrElse({ diff --git a/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala index 414df5bf..fc2ff319 100644 --- a/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala +++ b/shared/src/main/scala/scorex/crypto/authds/avltree/batch/serialization/BatchAVLProverSerializer.scala @@ -4,11 +4,12 @@ import scorex.crypto.authds.avltree.batch.{BatchAVLProver, ProverLeaf, InternalP import scorex.crypto.authds.{ADValue, ADKey, Balance} import scorex.crypto.hash.{CryptographicHash, Digest} import scorex.util.encode.Base16 -import scorex.utils.{Bytes, ByteArray, Ints} +import scorex.utils.{Bytes, Ints, ByteArray, Logger} import scala.util.Try -class BatchAVLProverSerializer[D <: Digest, HF <: CryptographicHash[D]](implicit val hf: HF) { +class BatchAVLProverSerializer[D <: Digest, HF <: CryptographicHash[D]] + (implicit val hf: HF, val logger: Logger) { serializer => private val labelLength = hf.DigestSize @@ -77,7 +78,9 @@ class BatchAVLProverSerializer[D <: Digest, HF <: CryptographicHash[D]](implicit case _: ProverLeaf[D] => } - new BatchAVLProver[D, HF](keyLength, valueLengthOpt, Some(manifest.root -> manifest.rootHeight)) + new BatchAVLProver[D, HF](keyLength, valueLengthOpt, Some(manifest.root -> manifest.rootHeight)) { + override val logger = serializer.logger + } } def manifestToBytes(manifest: BatchAVLProverManifest[D]): Array[Byte] = { diff --git a/shared/src/main/scala/scorex/utils/Logger.scala b/shared/src/main/scala/scorex/utils/Logger.scala new file mode 100644 index 00000000..4ccb8d8c --- /dev/null +++ b/shared/src/main/scala/scorex/utils/Logger.scala @@ -0,0 +1,13 @@ +package scorex.utils + +abstract class Logger { + def error(message: String): Unit +} + +object Logger { + val Default = new Logger { + override def error(message: String): Unit = { + println(message) + } + } +} diff --git a/shared/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala b/shared/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala index b4c64be1..99eda937 100644 --- a/shared/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala +++ b/shared/src/test/scala/scorex/crypto/authds/TwoPartyTests.scala @@ -1,6 +1,6 @@ package scorex.crypto.authds -import scorex.utils.Longs +import scorex.utils.{Longs, Logger} import scorex.crypto.TestingCommons import scorex.crypto.authds.avltree.batch.{Modification, Update} import scorex.crypto.hash.Digest @@ -10,6 +10,8 @@ import scala.util.Success trait TwoPartyTests extends TestingCommons { + implicit val loggerInTests: Logger = Logger.Default + def genUpd(key: ADKey) = Update(key, ADValue @@ key.take(8)) def profileTree(tree: TwoPartyDictionary, elements: Seq[ADKey], inDigest: ADDigest): Seq[Float] = { diff --git a/shared/src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala index 466e2c76..8cf73a37 100644 --- a/shared/src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala +++ b/shared/src/test/scala/scorex/crypto/authds/avltree/AVLDeleteSpecification.scala @@ -4,8 +4,9 @@ package scorex.crypto.authds.avltree import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import scorex.crypto.authds.avltree.batch._ -import scorex.crypto.authds.{ADKey, ADValue, TwoPartyTests} +import scorex.crypto.authds.{ADValue, TwoPartyTests, ADKey} import scorex.crypto.hash.{Blake2b256, Digest32, Sha256} +import scorex.utils.Logger class AVLDeleteSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChecks with TwoPartyTests { From 22b3dca4c76f809d4daa00903cb5c8cb8ecc2959 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:12:21 +0200 Subject: [PATCH 09/36] scala-js: move to JVM: Blake2b256Unsafe --- .../src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala | 0 .../scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala (100%) rename {shared => jvm}/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala (100%) diff --git a/shared/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala b/jvm/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala similarity index 100% rename from shared/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala rename to jvm/src/main/scala/scorex/crypto/hash/Blake2b256Unsafe.scala diff --git a/shared/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala b/jvm/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala similarity index 100% rename from shared/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala rename to jvm/src/test/scala/scorex/crypto/hash/Blake2bUnsafeSpecification.scala From 4fe303b616fa9f1fc9d2134a63772e765fae56ef Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:16:41 +0200 Subject: [PATCH 10/36] scala-js: move to JVM: Blake2b512Specification --- .../scorex/crypto/hash/Blake2b512Specification.scala | 9 +-------- .../scorex/crypto/hash/Blake2b256Specification.scala | 12 ++++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) rename shared/src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala => jvm/src/test/scala/scorex/crypto/hash/Blake2b512Specification.scala (73%) create mode 100644 shared/src/test/scala/scorex/crypto/hash/Blake2b256Specification.scala diff --git a/shared/src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala b/jvm/src/test/scala/scorex/crypto/hash/Blake2b512Specification.scala similarity index 73% rename from shared/src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala rename to jvm/src/test/scala/scorex/crypto/hash/Blake2b512Specification.scala index 8a655c60..ed3d650d 100644 --- a/shared/src/test/scala/scorex/crypto/hash/Blake2bSpecification.scala +++ b/jvm/src/test/scala/scorex/crypto/hash/Blake2b512Specification.scala @@ -1,6 +1,6 @@ package scorex.crypto.hash -class Blake2bSpecification extends HashTest { +class Blake2b512Specification extends HashTest { hashCheckString(Blake2b512, Map( @@ -10,11 +10,4 @@ class Blake2bSpecification extends HashTest { "abc" -> "BA80A53F981C4D0D6A2797B69F12F6E94C212F14685AC4B74B12BB6FDBFFA2D17D87C5392AAB792DC252D5DE4533CC9518D38AA8DBF1925AB92386EDD4009923") ) - hashCheckString(Blake2b256, - Map( - "" -> "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", - "abc" -> "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319" - ) - ) - } diff --git a/shared/src/test/scala/scorex/crypto/hash/Blake2b256Specification.scala b/shared/src/test/scala/scorex/crypto/hash/Blake2b256Specification.scala new file mode 100644 index 00000000..a04a8e39 --- /dev/null +++ b/shared/src/test/scala/scorex/crypto/hash/Blake2b256Specification.scala @@ -0,0 +1,12 @@ +package scorex.crypto.hash + +class Blake2b256Specification extends HashTest { + + hashCheckString(Blake2b256, + Map( + "" -> "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", + "abc" -> "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319" + ) + ) + +} From 3b9ae7230ef2ebb0aca89389678747390d68f989 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:18:23 +0200 Subject: [PATCH 11/36] scala-js: move to JVM: Blake2b512 --- .../src/main/scala/scorex/crypto/hash/Blake2b512.scala | 1 - 1 file changed, 1 deletion(-) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Blake2b512.scala (99%) diff --git a/shared/src/main/scala/scorex/crypto/hash/Blake2b512.scala b/jvm/src/main/scala/scorex/crypto/hash/Blake2b512.scala similarity index 99% rename from shared/src/main/scala/scorex/crypto/hash/Blake2b512.scala rename to jvm/src/main/scala/scorex/crypto/hash/Blake2b512.scala index 3285511c..605968f1 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Blake2b512.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Blake2b512.scala @@ -5,5 +5,4 @@ object Blake2b512 extends Blake2b[Digest64] with CryptographicHash64 { override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest64 = Digest64 @@ internalPrefixedHash(prefix, inputs: _*) - } From 2676e4bc07d01cb223ccc1ab01c1af05f9307e91 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:36:14 +0200 Subject: [PATCH 12/36] scala-js: move to JVM: KeccakSpecification --- .../scala/scorex/crypto/hash/KeccakSpecification.scala | 0 .../authds/avltree/batch/AVLBatchSpecification.scala | 6 +++--- .../crypto/authds/merkle/MerkleTreeSpecification.scala | 7 +++---- .../BatchMerkleProofSerializerSpecification.scala | 10 +++++----- 4 files changed, 11 insertions(+), 12 deletions(-) rename {shared => jvm}/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala (100%) diff --git a/shared/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala b/jvm/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala similarity index 100% rename from shared/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala rename to jvm/src/test/scala/scorex/crypto/hash/KeccakSpecification.scala diff --git a/shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala index 602ea0be..efa95f9c 100644 --- a/shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala +++ b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchSpecification.scala @@ -200,7 +200,7 @@ class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChe val prover = new BatchAVLProver[D, HF](KL, None) val digest = prover.digest val keyValues = (0 until InitialTreeSize) map { i => - val aValue = Keccak256(i.toString.getBytes("UTF-8")) + val aValue = Blake2b256(i.toString.getBytes("UTF-8")) (ADKey @@ aValue.take(KL), ADValue @@@ aValue) } keyValues.foreach(kv => prover.performOneOperation(Insert(kv._1, kv._2))) @@ -218,7 +218,7 @@ class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChe } (0 until InitialTreeSize) foreach { i => - val aValue = Keccak256(i.toString.getBytes("UTF-8")) + val aValue = Blake2b256(i.toString.getBytes("UTF-8")) verifier.performOneOperation(Insert(ADKey @@ aValue.take(KL), ADValue @@@ aValue)) } //extract all leafs @@ -235,7 +235,7 @@ class AVLBatchSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChe val prover = new BatchAVLProver[D, HF](KL, None) val digest = prover.digest val keyValues = (0 until InitialTreeSize) map { i => - val aValue = Keccak256(i.toString.getBytes("UTF-8")) + val aValue = Blake2b256(i.toString.getBytes("UTF-8")) (ADKey @@ aValue.take(KL), ADValue @@@ aValue) } keyValues.foreach(kv => prover.performOneOperation(Insert(kv._1, kv._2))) diff --git a/shared/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala index 5f025282..89d11a74 100644 --- a/shared/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala +++ b/shared/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala @@ -4,14 +4,13 @@ import org.scalatest.propspec.AnyPropSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import scorex.crypto.TestingCommons -import scorex.crypto.authds.{EmptyByteArray, LeafData} -import scorex.crypto.authds.merkle.MerkleTree.InternalNodePrefix -import scorex.crypto.hash.{Digest, Keccak256} +import scorex.crypto.authds.LeafData +import scorex.crypto.hash.Blake2b256 import scala.util.Random class MerkleTreeSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChecks with Matchers with TestingCommons { - implicit val hf = Keccak256 + implicit val hf = Blake2b256 private val LeafSize = 32 diff --git a/shared/src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala index 5fe4be7d..ef8e19cd 100644 --- a/shared/src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala +++ b/shared/src/test/scala/scorex/crypto/authds/merkle/serialization/BatchMerkleProofSerializerSpecification.scala @@ -3,9 +3,9 @@ package scorex.crypto.authds.merkle.serialization import org.scalatest.TryValues import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks -import scorex.crypto.authds.merkle.{BatchMerkleProof, Leaf, MerkleTree} -import scorex.crypto.authds.{LeafData, Side, TwoPartyTests} -import scorex.crypto.hash.{Digest, Digest32, Keccak256} +import scorex.crypto.authds.merkle.{MerkleTree, Leaf} +import scorex.crypto.authds.{Side, TwoPartyTests, LeafData} +import scorex.crypto.hash.{Digest32, Digest} import scala.util.Random @@ -15,8 +15,8 @@ class BatchMerkleProofSerializerSpecification extends AnyPropSpec with TryValues { type D = Digest32 - type HF = Keccak256.type - implicit val hf: HF = Keccak256 + type HF = scorex.crypto.hash.Blake2b256.type + implicit val hf: HF = scorex.crypto.hash.Blake2b256 private val LeafSize = 32 property("Batch proof serialization + deserialization") { From e127667da4d2a071bd995a05edcd6585ffd6b0c5 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:37:24 +0200 Subject: [PATCH 13/36] scala-js: move to JVM: Keccak --- .../src/main/scala/scorex/crypto/hash/Keccak.scala | 4 ---- .../src/main/scala/scorex/crypto/hash/Keccak256.scala | 1 - .../src/main/scala/scorex/crypto/hash/Keccak512.scala | 1 - 3 files changed, 6 deletions(-) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Keccak.scala (98%) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Keccak256.scala (99%) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Keccak512.scala (99%) diff --git a/shared/src/main/scala/scorex/crypto/hash/Keccak.scala b/jvm/src/main/scala/scorex/crypto/hash/Keccak.scala similarity index 98% rename from shared/src/main/scala/scorex/crypto/hash/Keccak.scala rename to jvm/src/main/scala/scorex/crypto/hash/Keccak.scala index a05c3b3b..8c87d451 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Keccak.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Keccak.scala @@ -5,7 +5,3 @@ import org.bouncycastle.crypto.digests.KeccakDigest trait Keccak[D <: Digest] extends BouncyCastleHash[D] { override protected lazy val digestFn = new KeccakDigest(DigestSize * 8) } - - - - diff --git a/shared/src/main/scala/scorex/crypto/hash/Keccak256.scala b/jvm/src/main/scala/scorex/crypto/hash/Keccak256.scala similarity index 99% rename from shared/src/main/scala/scorex/crypto/hash/Keccak256.scala rename to jvm/src/main/scala/scorex/crypto/hash/Keccak256.scala index 1c7db546..ec602f2a 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Keccak256.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Keccak256.scala @@ -5,5 +5,4 @@ object Keccak256 extends Keccak[Digest32] with CryptographicHash32 { override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest32 = Digest32 @@ internalPrefixedHash(prefix, inputs: _*) - } diff --git a/shared/src/main/scala/scorex/crypto/hash/Keccak512.scala b/jvm/src/main/scala/scorex/crypto/hash/Keccak512.scala similarity index 99% rename from shared/src/main/scala/scorex/crypto/hash/Keccak512.scala rename to jvm/src/main/scala/scorex/crypto/hash/Keccak512.scala index 9a477ae4..c878cb8b 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Keccak512.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Keccak512.scala @@ -5,5 +5,4 @@ object Keccak512 extends Keccak[Digest64] with CryptographicHash64 { override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest64 = Digest64 @@ internalPrefixedHash(prefix, inputs: _*) - } From 054277fb17ed1e6e3059393e0e0b5d7dfc47a3a0 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:39:47 +0200 Subject: [PATCH 14/36] scala-js: move to JVM: Whirlpool --- .../src/main/scala/scorex/crypto/hash/Whirlpool.scala | 2 -- .../test/scala/scorex/crypto/hash/WirlpoolSpecification.scala | 0 2 files changed, 2 deletions(-) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Whirlpool.scala (99%) rename {shared => jvm}/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala (100%) diff --git a/shared/src/main/scala/scorex/crypto/hash/Whirlpool.scala b/jvm/src/main/scala/scorex/crypto/hash/Whirlpool.scala similarity index 99% rename from shared/src/main/scala/scorex/crypto/hash/Whirlpool.scala rename to jvm/src/main/scala/scorex/crypto/hash/Whirlpool.scala index d10d75cd..37173bca 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Whirlpool.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Whirlpool.scala @@ -2,9 +2,7 @@ package scorex.crypto.hash import org.bouncycastle.crypto.digests.WhirlpoolDigest - object Whirlpool extends BouncyCastleHash[Digest64] with CryptographicHash64 { - override protected lazy val digestFn = new WhirlpoolDigest override def hash(input: Message): Digest64 = Digest64 @@ internalHash(input) diff --git a/shared/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala b/jvm/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala similarity index 100% rename from shared/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala rename to jvm/src/test/scala/scorex/crypto/hash/WirlpoolSpecification.scala From 0fbb8a80054ac7dac422c9954e8933153cee4662 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:42:05 +0200 Subject: [PATCH 15/36] scala-js: move to JVM: Stribog --- .../src/main/scala/scorex/crypto/hash/Stribog256.scala | 6 ------ .../src/main/scala/scorex/crypto/hash/Stribog512.scala | 6 ------ .../scala/scorex/crypto/hash/StribogSpecification.scala | 0 3 files changed, 12 deletions(-) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Stribog256.scala (98%) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Stribog512.scala (98%) rename {shared => jvm}/src/test/scala/scorex/crypto/hash/StribogSpecification.scala (100%) diff --git a/shared/src/main/scala/scorex/crypto/hash/Stribog256.scala b/jvm/src/main/scala/scorex/crypto/hash/Stribog256.scala similarity index 98% rename from shared/src/main/scala/scorex/crypto/hash/Stribog256.scala rename to jvm/src/main/scala/scorex/crypto/hash/Stribog256.scala index e468adb9..3eb1fd1b 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Stribog256.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Stribog256.scala @@ -3,16 +3,10 @@ package scorex.crypto.hash import org.bouncycastle.crypto.digests.GOST3411_2012_256Digest object Stribog256 extends BouncyCastleHash[Digest32] with CryptographicHash32 { - override protected lazy val digestFn = new GOST3411_2012_256Digest override def hash(input: Message): Digest32 = Digest32 @@ internalHash(input) override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest32 = Digest32 @@ internalPrefixedHash(prefix, inputs: _*) - } - - - - diff --git a/shared/src/main/scala/scorex/crypto/hash/Stribog512.scala b/jvm/src/main/scala/scorex/crypto/hash/Stribog512.scala similarity index 98% rename from shared/src/main/scala/scorex/crypto/hash/Stribog512.scala rename to jvm/src/main/scala/scorex/crypto/hash/Stribog512.scala index 532d6e41..d2101fcb 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Stribog512.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Stribog512.scala @@ -3,16 +3,10 @@ package scorex.crypto.hash import org.bouncycastle.crypto.digests.GOST3411_2012_512Digest object Stribog512 extends BouncyCastleHash[Digest64] with CryptographicHash64 { - override protected lazy val digestFn = new GOST3411_2012_512Digest override def hash(input: Message): Digest64 = Digest64 @@ internalHash(input) override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest64 = Digest64 @@ internalPrefixedHash(prefix, inputs: _*) - } - - - - diff --git a/shared/src/test/scala/scorex/crypto/hash/StribogSpecification.scala b/jvm/src/test/scala/scorex/crypto/hash/StribogSpecification.scala similarity index 100% rename from shared/src/test/scala/scorex/crypto/hash/StribogSpecification.scala rename to jvm/src/test/scala/scorex/crypto/hash/StribogSpecification.scala From cd4e049c2e5719330626c5a19afd9baba04fbc12 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 16:58:45 +0200 Subject: [PATCH 16/36] scala-js: move to JVM: Skein + Sha256Unsafe --- .../src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala | 0 .../src/main/scala/scorex/crypto/hash/Skein256.scala | 5 ----- .../src/main/scala/scorex/crypto/hash/Skein512.scala | 7 ------- .../test/scala/scorex/crypto/hash/SkeinSpecification.scala | 0 4 files changed, 12 deletions(-) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala (100%) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Skein256.scala (99%) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/Skein512.scala (98%) rename {shared => jvm}/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala (100%) diff --git a/shared/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala b/jvm/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala similarity index 100% rename from shared/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala rename to jvm/src/main/scala/scorex/crypto/hash/Sha256Unsafe.scala diff --git a/shared/src/main/scala/scorex/crypto/hash/Skein256.scala b/jvm/src/main/scala/scorex/crypto/hash/Skein256.scala similarity index 99% rename from shared/src/main/scala/scorex/crypto/hash/Skein256.scala rename to jvm/src/main/scala/scorex/crypto/hash/Skein256.scala index e594ab6c..8d8dbbcd 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Skein256.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Skein256.scala @@ -12,9 +12,4 @@ object Skein256 extends BouncyCastleHash[Digest32] with CryptographicHash32 { override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest32 = Digest32 @@ internalPrefixedHash(prefix, inputs: _*) - } - - - - diff --git a/shared/src/main/scala/scorex/crypto/hash/Skein512.scala b/jvm/src/main/scala/scorex/crypto/hash/Skein512.scala similarity index 98% rename from shared/src/main/scala/scorex/crypto/hash/Skein512.scala rename to jvm/src/main/scala/scorex/crypto/hash/Skein512.scala index 1a8fedeb..2a9d5ae8 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Skein512.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Skein512.scala @@ -2,18 +2,11 @@ package scorex.crypto.hash import org.bouncycastle.crypto.digests.SkeinDigest - object Skein512 extends BouncyCastleHash[Digest64] with CryptographicHash64 { - override protected lazy val digestFn = new SkeinDigest(SkeinDigest.SKEIN_512, SkeinDigest.SKEIN_512) override def hash(input: Message): Digest64 = Digest64 @@ internalHash(input) override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest64 = Digest64 @@ internalPrefixedHash(prefix, inputs: _*) - } - - - - diff --git a/shared/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala b/jvm/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala similarity index 100% rename from shared/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala rename to jvm/src/test/scala/scorex/crypto/hash/SkeinSpecification.scala From 59eedd5babc4808bc46dfec5948e2b95eeb9c636 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 17:00:58 +0200 Subject: [PATCH 17/36] scala-js: move to JVM: CryptographicHash64 + ThreadUnsafeHash --- .../src/main/scala/scorex/crypto/hash/CryptographicHash64.scala | 2 -- .../src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala | 1 - 2 files changed, 3 deletions(-) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala (99%) rename {shared => jvm}/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala (99%) diff --git a/shared/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala b/jvm/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala similarity index 99% rename from shared/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala rename to jvm/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala index 052f6afe..0b48e2e9 100644 --- a/shared/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/CryptographicHash64.scala @@ -3,12 +3,10 @@ package scorex.crypto.hash import scala.util.Try trait CryptographicHash64 extends CryptographicHash[Digest64] { - override val DigestSize: Int = 64 override def byteArrayToDigest(bytes: Array[Byte]): Try[Digest64] = Try { require(bytes.lengthCompare(DigestSize) == 0, "Incorrect digest size") Digest64 @@ bytes } - } diff --git a/shared/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala b/jvm/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala similarity index 99% rename from shared/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala rename to jvm/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala index 12369647..c6978167 100644 --- a/shared/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/ThreadUnsafeHash.scala @@ -1,6 +1,5 @@ package scorex.crypto.hash - /** * Thread-unsafe hash classes may be used for performance purposes */ From 6fa1d5779e84b92afb56065eeee6cf3480cfe396 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 19:34:29 +0200 Subject: [PATCH 18/36] scala-js: reimplement Blake2b256 via Platform.scala --- .../scala/scorex/crypto/hash/Platform.scala | 25 +++++++++++++++++++ .../scala/scorex/crypto/hash/Blake2b.scala | 4 +-- .../scorex/crypto/hash/BouncyCastleHash.scala | 16 ++++-------- .../main/scala/scorex/crypto/hash/hash.scala | 9 +++++++ 4 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 jvm/src/main/scala/scorex/crypto/hash/Platform.scala diff --git a/jvm/src/main/scala/scorex/crypto/hash/Platform.scala b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala new file mode 100644 index 00000000..40b8f1da --- /dev/null +++ b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala @@ -0,0 +1,25 @@ +package scorex.crypto.hash + +import org.bouncycastle.crypto.digests.Blake2bDigest + +object Platform { + + type Digest = org.bouncycastle.crypto.ExtendedDigest + + def createBlake2bDigest(bitSize: Int): Digest = new Blake2bDigest(bitSize) + + def updateDigest(digest: Digest, b: Byte) = digest.update(b) + + def updateDigest(digest: Digest, + in: Array[Byte], + inOff: Int, + inLen: Int) = { + digest.update(in, inOff, inLen) + } + + def doFinalDigest(digest: Digest): Array[Byte] = { + val res = new Array[Byte](digest.getDigestSize) + digest.doFinal(res, 0) + res + } +} diff --git a/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala b/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala index 7698fba8..1c26f668 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala +++ b/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala @@ -1,10 +1,8 @@ package scorex.crypto.hash -import org.bouncycastle.crypto.digests.Blake2bDigest - trait Blake2b[D <: Digest] extends BouncyCastleHash[D] { - override protected lazy val digestFn = new Blake2bDigest(DigestSize * 8) + override protected lazy val digestFn = createBlake2bDigest(DigestSize * 8) } diff --git a/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala b/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala index a64d6ff1..7b0c9a94 100644 --- a/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala +++ b/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala @@ -1,22 +1,16 @@ package scorex.crypto.hash -import org.bouncycastle.crypto.ExtendedDigest - trait BouncyCastleHash[D <: Digest] extends CryptographicHash[D] { protected def internalHash(inputs: Message*): Array[Byte] = synchronized { - inputs.foreach(i => digestFn.update(i, 0, i.length)) - val res = new Array[Byte](DigestSize) - digestFn.doFinal(res, 0) - res + inputs.foreach(i => updateDigest(digestFn, i, 0, i.length)) + doFinalDigest(digestFn) } protected def internalPrefixedHash(prefix: Byte, inputs: Message*): Array[Byte] = synchronized { - digestFn.update(prefix) - inputs.foreach(i => digestFn.update(i, 0, i.length)) - val res = new Array[Byte](DigestSize) - digestFn.doFinal(res, 0) - res + updateDigest(digestFn, prefix) + inputs.foreach(i => updateDigest(digestFn, i, 0, i.length)) + doFinalDigest(digestFn) } protected def digestFn: ExtendedDigest diff --git a/shared/src/main/scala/scorex/crypto/hash/hash.scala b/shared/src/main/scala/scorex/crypto/hash/hash.scala index 8e386384..ba59f645 100644 --- a/shared/src/main/scala/scorex/crypto/hash/hash.scala +++ b/shared/src/main/scala/scorex/crypto/hash/hash.scala @@ -20,4 +20,13 @@ package object hash { type NonStandardDigest = NonStandardDigest.Type + type ExtendedDigest = Platform.Digest + + def createBlake2bDigest(bitSize: Int): ExtendedDigest = Platform.createBlake2bDigest(bitSize) + + def updateDigest(digest: ExtendedDigest, b: Byte) = Platform.updateDigest(digest, b) + + def updateDigest(digest: ExtendedDigest, in: Array[Byte], inOff: Int, inLen: Int) = Platform.updateDigest(digest, in, inOff, inLen) + + def doFinalDigest(digest: ExtendedDigest): Array[Byte] = Platform.doFinalDigest(digest) } From 91b869f89c62dc3a516b2088dd0c8d832c3aff96 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 19:58:24 +0200 Subject: [PATCH 19/36] scala-js: reimplement Sha256 via Platform.scala --- jvm/src/main/scala/scorex/crypto/hash/Platform.scala | 4 +++- shared/src/main/scala/scorex/crypto/hash/Sha256.scala | 11 +++++++---- shared/src/main/scala/scorex/crypto/hash/hash.scala | 2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/jvm/src/main/scala/scorex/crypto/hash/Platform.scala b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala index 40b8f1da..93899924 100644 --- a/jvm/src/main/scala/scorex/crypto/hash/Platform.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala @@ -1,6 +1,6 @@ package scorex.crypto.hash -import org.bouncycastle.crypto.digests.Blake2bDigest +import org.bouncycastle.crypto.digests.{Blake2bDigest, SHA256Digest} object Platform { @@ -8,6 +8,8 @@ object Platform { def createBlake2bDigest(bitSize: Int): Digest = new Blake2bDigest(bitSize) + def createSha256Digest(): Digest = new SHA256Digest() + def updateDigest(digest: Digest, b: Byte) = digest.update(b) def updateDigest(digest: Digest, diff --git a/shared/src/main/scala/scorex/crypto/hash/Sha256.scala b/shared/src/main/scala/scorex/crypto/hash/Sha256.scala index ef204c77..a18ca31e 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Sha256.scala +++ b/shared/src/main/scala/scorex/crypto/hash/Sha256.scala @@ -1,10 +1,13 @@ package scorex.crypto.hash -import java.security.MessageDigest - /** * Hashing functions implementation with sha256 impl from Java SDK */ -object Sha256 extends CryptographicHash32 { - override def hash(input: Array[Byte]): Digest32 = Digest32 @@ MessageDigest.getInstance("SHA-256").digest(input) +object Sha256 extends CryptographicHash32 with BouncyCastleHash[Digest32] { + override def hash(input: Array[Byte]): Digest32 = Digest32 @@ internalHash(input) + + override protected lazy val digestFn = createSha256Digest() + + override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest32 = + Digest32 @@ internalPrefixedHash(prefix, inputs: _*) } \ No newline at end of file diff --git a/shared/src/main/scala/scorex/crypto/hash/hash.scala b/shared/src/main/scala/scorex/crypto/hash/hash.scala index ba59f645..1924d472 100644 --- a/shared/src/main/scala/scorex/crypto/hash/hash.scala +++ b/shared/src/main/scala/scorex/crypto/hash/hash.scala @@ -24,6 +24,8 @@ package object hash { def createBlake2bDigest(bitSize: Int): ExtendedDigest = Platform.createBlake2bDigest(bitSize) + def createSha256Digest(): ExtendedDigest = Platform.createSha256Digest() + def updateDigest(digest: ExtendedDigest, b: Byte) = Platform.updateDigest(digest, b) def updateDigest(digest: ExtendedDigest, in: Array[Byte], inOff: Int, inLen: Int) = Platform.updateDigest(digest, in, inOff, inLen) From 727c7a8dd0227ad031610d39bb1847b3f67233b4 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 20:07:42 +0200 Subject: [PATCH 20/36] scala-js: configure benchmarks project --- .../scala/scorex.benchmarks/Base16Benchmark.scala | 4 ++-- build.sbt | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/benchmarks/src/main/scala/scorex.benchmarks/Base16Benchmark.scala b/benchmarks/src/main/scala/scorex.benchmarks/Base16Benchmark.scala index a7e8ff90..98c6b996 100644 --- a/benchmarks/src/main/scala/scorex.benchmarks/Base16Benchmark.scala +++ b/benchmarks/src/main/scala/scorex.benchmarks/Base16Benchmark.scala @@ -45,12 +45,12 @@ object Base16Benchmark { .view .map(_ => Random.nextString(200).getBytes("UTF-8")) .map(Base16.encode) - .force + .force.toSeq val xab: Seq[Array[Byte]] = (1 to 1000) .view .map(_ => Random.nextString(200).getBytes("UTF-8")) - .force + .force.toSeq } } \ No newline at end of file diff --git a/build.sbt b/build.sbt index 26f2b82a..7596d431 100644 --- a/build.sbt +++ b/build.sbt @@ -68,10 +68,15 @@ lazy val scrypto = crossProject(JVMPlatform) // ) -//lazy val benchmarks = (project in file("benchmarks")) -// .settings(commonSettings, name := "scrypto-benchmarks") -// .dependsOn(scrypto) -// .enablePlugins(JmhPlugin) +lazy val benchmarks = project + .in(file("benchmarks")) + .dependsOn(scrypto.jvm) + .settings( + moduleName := "scrypto-benchmarks", + crossScalaVersions := Seq(scala211, scala212, scala213), + scalaVersion := scala213, + ) + .enablePlugins(JmhPlugin) credentials ++= (for { username <- Option(System.getenv().get("SONATYPE_USERNAME")) From dcd9953f19c17a805378eef9f26813ce21360fe4 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 20:57:08 +0200 Subject: [PATCH 21/36] scala-js: enable JSPlatform --- build.sbt | 16 +-- .../scala/scorex/crypto/hash/Platform.scala | 24 ++++ .../merkle/sparse/BlockchainSimulator.scala | 73 ++++++++++ .../authds/merkle/sparse/OpsBenchmark.scala | 43 ++++++ .../merkle/sparse/SparseMerkleTree.scala | 135 ------------------ .../SparseMerkleTreeSpecification.scala | 4 +- 6 files changed, 150 insertions(+), 145 deletions(-) create mode 100644 js/src/main/scala/scorex/crypto/hash/Platform.scala create mode 100644 jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/BlockchainSimulator.scala create mode 100644 jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/OpsBenchmark.scala diff --git a/build.sbt b/build.sbt index 7596d431..69d114a8 100644 --- a/build.sbt +++ b/build.sbt @@ -49,7 +49,7 @@ Test / publishArtifact := false pomIncludeRepository := { _ => false } -lazy val scrypto = crossProject(JVMPlatform) +lazy val scrypto = crossProject(JVMPlatform, JSPlatform) .in(file(".")) .settings(commonSettings: _*) .jvmSettings( @@ -59,13 +59,13 @@ lazy val scrypto = crossProject(JVMPlatform) scalaVersion := scala213, crossScalaVersions := Seq(scala211, scala212, scala213) ) -// .jsSettings( -// scalaVersion := scala213, -// crossScalaVersions := Seq(scala213), -// libraryDependencies ++= Seq( -// ), -// parallelExecution in Test := false -// ) + .jsSettings( + scalaVersion := scala213, + crossScalaVersions := Seq(scala213), + libraryDependencies ++= Seq( + ), + parallelExecution in Test := false + ) lazy val benchmarks = project diff --git a/js/src/main/scala/scorex/crypto/hash/Platform.scala b/js/src/main/scala/scorex/crypto/hash/Platform.scala new file mode 100644 index 00000000..86cf3b61 --- /dev/null +++ b/js/src/main/scala/scorex/crypto/hash/Platform.scala @@ -0,0 +1,24 @@ +package scorex.crypto.hash + +object Platform { + + + case class Digest() + + def createBlake2bDigest(bitSize: Int): Digest = ??? + + def createSha256Digest(): Digest = ??? + + def updateDigest(digest: Digest, b: Byte) = ??? + + def updateDigest(digest: Digest, + in: Array[Byte], + inOff: Int, + inLen: Int) = { + ??? + } + + def doFinalDigest(digest: Digest): Array[Byte] = { + ??? + } +} diff --git a/jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/BlockchainSimulator.scala b/jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/BlockchainSimulator.scala new file mode 100644 index 00000000..4cdcfc8d --- /dev/null +++ b/jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/BlockchainSimulator.scala @@ -0,0 +1,73 @@ +package scorex.crypto.authds.merkle.sparse + +import scorex.crypto.authds.LeafData + +import scala.util.Try +import scorex.crypto.hash.{CryptographicHash, Digest32, Blake2b256Unsafe} + +import scala.collection.mutable +import scorex.utils.Longs + +object BlockchainSimulator extends App { + type PubKey = Array[Byte] + val PubKeyLength = 32 + implicit val hf: CryptographicHash[Digest32] = new Blake2b256Unsafe + + case class Transaction(amount: Long, + sender: PubKey, + recipient: PubKey, + coinBalance: Long, + coinProof: SparseMerkleProof[Digest32]) + + object Transaction { + def coinBytes(pubKey: PubKey, balance: Long) = Some(LeafData @@ (pubKey ++ Longs.toByteArray(balance))) + + def process(tx: Transaction, + state: SparseMerkleTree[Digest32]): + Try[(SparseMerkleTree[Digest32], Seq[SparseMerkleProof[Digest32]])] = Try { + require(tx.amount <= tx.coinBalance) + require(tx.coinProof.leafDataOpt.get sameElements coinBytes(tx.sender, tx.coinBalance).get) + require(tx.coinProof.valid(state.rootDigest, height)) + val (state1, _) = state.update(tx.coinProof, None).get + val (state2, proofs2) = state1.update(state1.lastProof, + coinBytes(tx.recipient, tx.amount), + Seq(state1.lastProof)).get + if (tx.amount == tx.coinBalance) state2 -> proofs2 + else state2.update(state2.lastProof, + coinBytes(tx.sender, tx.coinBalance - tx.amount), + proofs2 :+ state2.lastProof).get + } + } + + case class Block(transactions: Seq[Transaction]) + + val txsCache = new mutable.ArrayBuffer() + val maxTxsCacheSize = 5000 + val txsPerBlock = 1000 + val numOfBlocks = 1000000 + val height = 30: Byte + val godAccount = Array.fill(32)(0: Byte) + val godBalance = 100000000000L //100B + val emptyState = SparseMerkleTree.emptyTree(height) + val (initialState, godProofs) = emptyState.update(emptyState.lastProof, + Transaction.coinBytes(godAccount, godBalance), + Seq(emptyState.lastProof)).get + var godProof = godProofs.head + var currentGodBalance = godBalance + val txAmount = 10 + (1 to numOfBlocks).foldLeft(initialState) { case (beforeBlocktree, blockNum) => + val (afterTree, processingTime) = (1 to txsPerBlock).foldLeft(beforeBlocktree -> 0L) { case ((tree, totalTime), txNum) => + val recipient = hf(scala.util.Random.nextString(20)) + val tx = Transaction(txAmount, godAccount, recipient, currentGodBalance, godProof) + val t0 = System.currentTimeMillis() + val (updState, proofs) = Transaction.process(tx, tree).get //we generate always valid transaction + val t = System.currentTimeMillis() + currentGodBalance = currentGodBalance - txAmount + godProof = proofs.last + updState -> (totalTime + (t - t0)) + } + println(s"Block $blockNum, processing time: $processingTime ms") + println(godProof) + afterTree + } +} diff --git a/jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/OpsBenchmark.scala b/jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/OpsBenchmark.scala new file mode 100644 index 00000000..173dd708 --- /dev/null +++ b/jvm/src/main/scala/scorex/crypto/authds/merkle/sparse/OpsBenchmark.scala @@ -0,0 +1,43 @@ +package scorex.crypto.authds.merkle.sparse + +import scorex.crypto.authds.LeafData +import scorex.crypto.hash.{CryptographicHash, Digest32, Blake2b256Unsafe} +import scorex.utils.Longs + +object OpsBenchmark extends App { + implicit val hf: CryptographicHash[Digest32] = new Blake2b256Unsafe + val height: Byte = 50 + var tree = SparseMerkleTree.emptyTree(height) + //bootstrapping + val bSize = 10000 + var proof: SparseMerkleProof[Digest32] = null + val tb0 = System.currentTimeMillis() + (0 until bSize).foreach { i => + if (i == bSize / 2) proof = tree.lastProof + val proofsToUpdate = if (i >= bSize / 2) { + Seq(proof) + } else Seq.empty[SparseMerkleProof[Digest32]] + if (i % 1000 == 0) println(s"$i elements added") + val (t, p) = tree.update(tree.lastProof, Some(LeafData @@ Longs.toByteArray(i)), proofsToUpdate).get + tree = t + if (i >= bSize / 2) proof = p.head + } + val tb = System.currentTimeMillis() + println(s"bootstrapping time: ${tb - tb0}") + val tv0 = System.currentTimeMillis() + (1 to 1000).foreach(i => proof.valid(tree)) + val tv = System.currentTimeMillis() + println(s"1000 updates time: ${tv - tv0} ms") + val te0 = System.currentTimeMillis() + (1 to 1000).foreach(_ => + tree.update(tree.lastProof, Some(LeafData @@ Longs.toByteArray(2)), Seq()) + ) + val te = System.currentTimeMillis() + val tp0 = System.currentTimeMillis() + (1 to 1000).foreach(_ => + tree.update(tree.lastProof, Some(LeafData @@ Longs.toByteArray(2)), Seq(proof)) + ) + val tp = System.currentTimeMillis() + val tu = (tp - tp0) - (te - te0) + println("1000 proof updates: " + tu) +} diff --git a/shared/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala b/shared/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala index 5023524c..4d827a31 100644 --- a/shared/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala +++ b/shared/src/main/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTree.scala @@ -1,6 +1,5 @@ package scorex.crypto.authds.merkle.sparse -import scorex.utils.Longs import scorex.crypto.authds.LeafData import scorex.crypto.hash._ @@ -174,139 +173,5 @@ case class SparseMerkleProof[D <: Digest](idx: Node.ID, def valid(tree: SparseMerkleTree[D])(implicit hf: CryptographicHash[D]): Boolean = valid(tree.rootDigest, tree.height) } -object OpsBenchmark extends App { - implicit val hf: CryptographicHash[Digest32] = new Blake2b256Unsafe - val height: Byte = 50 - var tree = SparseMerkleTree.emptyTree(height) - - //bootstrapping - - val bSize = 10000 - - var proof: SparseMerkleProof[Digest32] = null - - val tb0 = System.currentTimeMillis() - (0 until bSize).foreach {i => - if(i == bSize/2) proof = tree.lastProof - - val proofsToUpdate = if(i >= bSize/2) { - Seq(proof) - } else Seq.empty[SparseMerkleProof[Digest32]] - - if(i%1000 == 0) println(s"$i elements added") - val (t, p) = tree.update(tree.lastProof, Some(LeafData @@ Longs.toByteArray(i)), proofsToUpdate).get - - tree = t - if(i >= bSize/2) proof = p.head - } - val tb = System.currentTimeMillis() - println(s"bootstrapping time: ${tb-tb0}") - - val tv0 = System.currentTimeMillis() - (1 to 1000).foreach(i => proof.valid(tree)) - val tv = System.currentTimeMillis() - println(s"1000 updates time: ${tv-tv0} ms") - - - - val te0 = System.currentTimeMillis() - (1 to 1000).foreach(_ => - tree.update(tree.lastProof, Some(LeafData @@ Longs.toByteArray(2)), Seq()) - ) - val te = System.currentTimeMillis() - - val tp0 = System.currentTimeMillis() - (1 to 1000).foreach(_ => - tree.update(tree.lastProof, Some(LeafData @@ Longs.toByteArray(2)), Seq(proof)) - ) - val tp = System.currentTimeMillis() - - val tu = (tp-tp0) - (te-te0) - - println("1000 proof updates: " + tu) -} - -object BlockchainSimulator extends App { - - type PubKey = Array[Byte] - - val PubKeyLength = 32 - - implicit val hf: CryptographicHash[Digest32] = new Blake2b256Unsafe - - case class Transaction(amount: Long, - sender: PubKey, - recipient: PubKey, - coinBalance: Long, - coinProof: SparseMerkleProof[Digest32]) - - object Transaction { - def coinBytes(pubKey: PubKey, balance: Long) = Some(LeafData @@ (pubKey ++ Longs.toByteArray(balance))) - - def process(tx: Transaction, - state: SparseMerkleTree[Digest32]): - Try[(SparseMerkleTree[Digest32], Seq[SparseMerkleProof[Digest32]])] = Try { - - require(tx.amount <= tx.coinBalance) - require(tx.coinProof.leafDataOpt.get sameElements coinBytes(tx.sender, tx.coinBalance).get) - require(tx.coinProof.valid(state.rootDigest, height)) - - val (state1, _) = state.update(tx.coinProof, None).get - - val (state2, proofs2) = state1.update(state1.lastProof, - coinBytes(tx.recipient, tx.amount), - Seq(state1.lastProof)).get - - if (tx.amount == tx.coinBalance) state2 -> proofs2 - else state2.update(state2.lastProof, - coinBytes(tx.sender, tx.coinBalance - tx.amount), - proofs2 :+ state2.lastProof).get - } - } - - case class Block(transactions: Seq[Transaction]) - - val txsCache = new mutable.ArrayBuffer() - val maxTxsCacheSize = 5000 - - val txsPerBlock = 1000 - val numOfBlocks = 1000000 - - val height = 30: Byte - - val godAccount = Array.fill(32)(0: Byte) - val godBalance = 100000000000L //100B - - val emptyState = SparseMerkleTree.emptyTree(height) - val (initialState, godProofs) = emptyState.update(emptyState.lastProof, - Transaction.coinBytes(godAccount, godBalance), - Seq(emptyState.lastProof)).get - - var godProof = godProofs.head - var currentGodBalance = godBalance - val txAmount = 10 - - (1 to numOfBlocks).foldLeft(initialState) { case (beforeBlocktree, blockNum) => - val (afterTree, processingTime) = (1 to txsPerBlock).foldLeft(beforeBlocktree -> 0L) { case ((tree, totalTime), txNum) => - val recipient = hf(scala.util.Random.nextString(20)) - - val tx = Transaction(txAmount, godAccount, recipient, currentGodBalance, godProof) - - val t0 = System.currentTimeMillis() - val (updState, proofs) = Transaction.process(tx, tree).get //we generate always valid transaction - val t = System.currentTimeMillis() - - currentGodBalance = currentGodBalance - txAmount - godProof = proofs.last - - updState -> (totalTime + (t - t0)) - } - - println(s"Block $blockNum, processing time: $processingTime ms") - println(godProof) - - afterTree - } -} \ No newline at end of file diff --git a/shared/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala index 9a03f49c..d55fe8e7 100644 --- a/shared/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala +++ b/shared/src/test/scala/scorex/crypto/authds/merkle/sparse/SparseMerkleTreeSpecification.scala @@ -6,11 +6,11 @@ import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import scorex.crypto.TestingCommons import scorex.crypto.authds.LeafData -import scorex.crypto.hash.{Blake2b256Unsafe, CryptographicHash, Digest32} +import scorex.crypto.hash.{CryptographicHash, Digest32, Blake2b256} class SparseMerkleTreeSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyChecks with Matchers with TestingCommons { - implicit val hf: CryptographicHash[Digest32] = new Blake2b256Unsafe + implicit val hf: CryptographicHash[Digest32] = Blake2b256 property("Tree has valid last proof") { forAll { height: Byte => From e4a8d3e314bc3c7f6410505dc4d45b26b432acf5 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Sep 2022 23:25:18 +0200 Subject: [PATCH 22/36] scala-js: make code and tests compile --- build.sbt | 14 ++++++++++---- .../batch/AVLBatchStatefulSpecification.scala | 0 .../test/scala/scorex/crypto/TestingCommons.scala | 3 --- .../test/scala/scorex/crypto/hash/HashTest.scala | 11 ++++++----- 4 files changed, 16 insertions(+), 12 deletions(-) rename {shared => jvm}/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala (100%) diff --git a/build.sbt b/build.sbt index 69d114a8..408eb6a8 100644 --- a/build.sbt +++ b/build.sbt @@ -32,11 +32,15 @@ lazy val commonSettings = Seq( ) ), libraryDependencies ++= Seq( - "org.rudogma" %% "supertagged" % "2.0-RC2", - "org.scorexfoundation" %% "scorex-util" % "0.1.8-19-0331a3d9-SNAPSHOT", +// scalaOrganization.value % "scala-reflect" % scalaVersion.value % "provided", + "org.rudogma" %%% "supertagged" % "2.0-RC2", + "org.scorexfoundation" %%% "scorex-util" % "0.1.8-19-0331a3d9-SNAPSHOT", + "org.scalatest" %%% "scalatest" % "3.3.0-SNAP3" % Test, - "org.scalacheck" %%% "scalacheck" % "1.15.2" % Test, - "org.scalatestplus" %%% "scalacheck-1-15" % "3.3.0.0-SNAP3" % Test + "org.scalatest" %%% "scalatest-propspec" % "3.3.0-SNAP3" % Test, + "org.scalatest" %%% "scalatest-shouldmatchers" % "3.3.0-SNAP3" % Test, + "org.scalatestplus" %%% "scalacheck-1-15" % "3.3.0.0-SNAP3" % Test, + "org.scalacheck" %%% "scalacheck" % "1.15.2" % Test ), publishMavenStyle := true, publishTo := sonatypePublishToBundle.value @@ -63,6 +67,8 @@ lazy val scrypto = crossProject(JVMPlatform, JSPlatform) scalaVersion := scala213, crossScalaVersions := Seq(scala213), libraryDependencies ++= Seq( + "org.scala-js" %%% "scala-js-macrotask-executor" % "1.0.0", + ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13) ), parallelExecution in Test := false ) diff --git a/shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala b/jvm/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala similarity index 100% rename from shared/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala rename to jvm/src/test/scala/scorex/crypto/authds/avltree/batch/AVLBatchStatefulSpecification.scala diff --git a/shared/src/test/scala/scorex/crypto/TestingCommons.scala b/shared/src/test/scala/scorex/crypto/TestingCommons.scala index 7f0aa1f2..7b30cc86 100644 --- a/shared/src/test/scala/scorex/crypto/TestingCommons.scala +++ b/shared/src/test/scala/scorex/crypto/TestingCommons.scala @@ -8,9 +8,6 @@ import org.scalatest.matchers.should.Matchers import scala.util.Random trait TestingCommons extends Matchers { - val dirName = "/tmp/scorex-test/test/" - val treeDir = new File(dirName) - treeDir.mkdirs() def genElements(howMany: Int, seed: Long, size: Int = 32): Seq[Array[Byte]] = { val r = Random diff --git a/shared/src/test/scala/scorex/crypto/hash/HashTest.scala b/shared/src/test/scala/scorex/crypto/hash/HashTest.scala index d38613d2..4fce1e88 100644 --- a/shared/src/test/scala/scorex/crypto/hash/HashTest.scala +++ b/shared/src/test/scala/scorex/crypto/hash/HashTest.scala @@ -40,11 +40,12 @@ trait HashTest extends AnyPropSpec } } - property(s"${hash.getClass.getSimpleName} is thread safe") { - val singleThreadHashes = (0 until 100).map(i => hash.hash(i.toString)) - val multiThreadHashes = Future.sequence((0 until 100).map(i => Future(hash.hash(i.toString)))) - singleThreadHashes.map(Base16.encode(_)) shouldBe Await.result(multiThreadHashes, 1.minute).map(Base16.encode(_)) - } +// TODO refactor: reimplement hashes in a thread-safe way and remove this test +// property(s"${hash.getClass.getSimpleName} is thread safe") { +// val singleThreadHashes = (0 until 100).map(i => hash.hash(i.toString)) +// val multiThreadHashes = Future.sequence((0 until 100).map(i => Future(hash.hash(i.toString)))) +// singleThreadHashes.map(Base16.encode(_)) shouldBe Await.result(multiThreadHashes, 1.minute).map(Base16.encode(_)) +// } property(s"${hash.getClass.getSimpleName} apply method") { forAll { (string: String, bytes: Array[Byte]) => From b9f974e5d0295fb0502edee4540eb96a400c5077 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 27 Sep 2022 15:31:59 +0200 Subject: [PATCH 23/36] scala-js: Platform implemented for JS --- build.sbt | 12 +++++- .../scala/scorex/crypto/BouncycastleJs.scala | 37 +++++++++++++++++++ .../scala/scorex/crypto/hash/Platform.scala | 34 ++++++++++++----- .../scala/scorex/crypto/hash/Platform.scala | 4 +- project/plugins.sbt | 2 +- 5 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 js/src/main/scala/scorex/crypto/BouncycastleJs.scala diff --git a/build.sbt b/build.sbt index 408eb6a8..4680589d 100644 --- a/build.sbt +++ b/build.sbt @@ -70,9 +70,19 @@ lazy val scrypto = crossProject(JVMPlatform, JSPlatform) "org.scala-js" %%% "scala-js-macrotask-executor" % "1.0.0", ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13) ), - parallelExecution in Test := false + parallelExecution in Test := false, + Compile / npmDependencies ++= Seq( + "bn.js" -> "5.2.0", + "hash.js" -> "1.1.7", + "elliptic" -> "6.5.4", + "blakejs" -> "1.2.1", + "bouncycastle-js" -> "0.1.8" + ), + useYarn := true ) +lazy val scryptoJS = scrypto.js + .enablePlugins(ScalaJSBundlerPlugin) lazy val benchmarks = project .in(file("benchmarks")) diff --git a/js/src/main/scala/scorex/crypto/BouncycastleJs.scala b/js/src/main/scala/scorex/crypto/BouncycastleJs.scala new file mode 100644 index 00000000..318c27ea --- /dev/null +++ b/js/src/main/scala/scorex/crypto/BouncycastleJs.scala @@ -0,0 +1,37 @@ +package scorex.crypto + +import scala.scalajs.js +import scala.annotation.nowarn +import scala.scalajs.js.annotation.JSImport +import scala.scalajs.js.typedarray.Int8Array + +@JSImport("bouncycastle-js", JSImport.Namespace) +@js.native +object BouncycastleJs extends js.Object { + + @js.native + trait Digest extends js.Object { + @nowarn + def update(in: RtArray[Byte], inOff: Int, len: Int): Unit = js.native + @nowarn + def updateByte(b: Byte): Unit = js.native + @nowarn + def doFinal(out: RtArray[Byte], outOff: Int): Int = js.native + } + + @js.native + trait Crypto extends js.Object { + def createBlake2bDigest(size: Int): Digest + def createSha256Digest(): Digest + } + + def bouncyCastle: Crypto = js.native + + @js.native + trait RtArray[T] extends js.Object { + def data: Int8Array + } + + @nowarn + def createByteArrayFromData(data: js.Array[Byte]): RtArray[Byte] = js.native +} \ No newline at end of file diff --git a/js/src/main/scala/scorex/crypto/hash/Platform.scala b/js/src/main/scala/scorex/crypto/hash/Platform.scala index 86cf3b61..f7243865 100644 --- a/js/src/main/scala/scorex/crypto/hash/Platform.scala +++ b/js/src/main/scala/scorex/crypto/hash/Platform.scala @@ -1,24 +1,40 @@ package scorex.crypto.hash -object Platform { +import scorex.crypto.BouncycastleJs + +import scala.scalajs.js +object Platform { - case class Digest() + type Digest = BouncycastleJs.Digest - def createBlake2bDigest(bitSize: Int): Digest = ??? + def createBlake2bDigest(bitSize: Int): Digest = { + val bc = BouncycastleJs.bouncyCastle + val digest = bc.createBlake2bDigest(bitSize) + digest + } - def createSha256Digest(): Digest = ??? + def createSha256Digest(): Digest = { + val bc = BouncycastleJs.bouncyCastle + val digest = bc.createSha256Digest() + digest + } - def updateDigest(digest: Digest, b: Byte) = ??? + def updateDigest(digest: Digest, b: Byte): Unit = { + digest.updateByte(b) + } def updateDigest(digest: Digest, - in: Array[Byte], + bytes: Array[Byte], inOff: Int, - inLen: Int) = { - ??? + inLen: Int): Unit = { + val in = BouncycastleJs.createByteArrayFromData(js.Array(bytes: _*)) + digest.update(in, inOff, inLen) } def doFinalDigest(digest: Digest): Array[Byte] = { - ??? + val res = BouncycastleJs.createByteArrayFromData(new js.Array[Byte](32)) + digest.doFinal(res, 0) + res.data.toArray } } diff --git a/jvm/src/main/scala/scorex/crypto/hash/Platform.scala b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala index 93899924..bbdd1dca 100644 --- a/jvm/src/main/scala/scorex/crypto/hash/Platform.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala @@ -10,12 +10,12 @@ object Platform { def createSha256Digest(): Digest = new SHA256Digest() - def updateDigest(digest: Digest, b: Byte) = digest.update(b) + def updateDigest(digest: Digest, b: Byte): Unit = digest.update(b) def updateDigest(digest: Digest, in: Array[Byte], inOff: Int, - inLen: Int) = { + inLen: Int): Unit = { digest.update(in, inOff, inLen) } diff --git a/project/plugins.sbt b/project/plugins.sbt index 6ec00c7f..a4e663e9 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -16,5 +16,5 @@ addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.0") addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0") - addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") +addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.20.0") From 546c402fe7179c6f779939a486d8c4efefc6703b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 27 Sep 2022 15:51:56 +0200 Subject: [PATCH 24/36] scala-js: make all JS tests pass --- .../serialization/AVLBatchSerializationSpecification.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala index da0c9bbf..e94c3555 100644 --- a/shared/src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala +++ b/shared/src/test/scala/scorex/crypto/authds/avltree/batch/serialization/AVLBatchSerializationSpecification.scala @@ -36,7 +36,7 @@ class AVLBatchSerializationSpecification extends AnyPropSpec with ScalaCheckDriv } property("slice to pieces and combine tree back") { - forAll(Gen.choose(10, 100000)) { treeSize: Int => + forAll(Gen.choose(10, 10000)) { treeSize: Int => whenever(treeSize >= 10) { val tree = generateProver(treeSize) val height = tree.rootNodeHeight @@ -57,7 +57,7 @@ class AVLBatchSerializationSpecification extends AnyPropSpec with ScalaCheckDriv } property("slice to Array[Byte] pieces and combine tree back") { - forAll(Gen.choose(0, 100000)) { treeSize: Int => + forAll(Gen.choose(0, 10000)) { treeSize: Int => val serializer = new BatchAVLProverSerializer[D, HF] val tree = generateProver(treeSize) val kl = tree.keyLength @@ -83,7 +83,7 @@ class AVLBatchSerializationSpecification extends AnyPropSpec with ScalaCheckDriv property("manifest serialization") { val serializer = new BatchAVLProverSerializer[D, HF] - forAll(Gen.choose(0, 100000)) { treeSize: Int => + forAll(Gen.choose(0, 10000)) { treeSize: Int => val tree = generateProver(treeSize) val kl = tree.keyLength val digest = tree.digest From dafca54ce87c86a2d0819d23b499faf5262aa47a Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 27 Sep 2022 18:33:33 +0200 Subject: [PATCH 25/36] scala-js: setup ci.yml --- .github/workflows/ci.yml | 51 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 38d6d8d5..6e0ce9a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,13 +15,13 @@ env: jobs: build: - name: Test and publish a snapshot + name: JVM - Test and publish a snapshot env: HAS_SECRETS: ${{ secrets.SONATYPE_PASSWORD != '' }} strategy: matrix: os: [ubuntu-latest] - scala: [2.12.10, 2.11.12, 2.13.1] + scala: [2.13.8, 2.12.15, 2.11.12] java: [adopt@1.8] runs-on: ${{ matrix.os }} steps: @@ -48,11 +48,54 @@ jobs: key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - name: Runs tests - run: sbt ++${{ matrix.scala }} test + run: sbt ++${{ matrix.scala }} scryptoJVM/test - name: Publish a snapshot ${{ github.ref }} if: env.HAS_SECRETS == 'true' - run: sbt ++${{ matrix.scala }} publish + run: sbt ++${{ matrix.scala }} scryptoJVM/publish + env: + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + + buildJs: + name: JS - Test and publish a snapshot + env: + HAS_SECRETS: ${{ secrets.SONATYPE_PASSWORD != '' }} + strategy: + matrix: + os: [ubuntu-latest] + scala: [2.13.8] + java: [adopt@1.8] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout current branch (full) + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Setup Java and Scala + uses: olafurpg/setup-scala@v10 + with: + java-version: ${{ matrix.java }} + + - name: Cache sbt + uses: actions/cache@v2 + with: + path: | + ~/.sbt + ~/.ivy2/cache + ~/.coursier/cache/v1 + ~/.cache/coursier/v1 + ~/AppData/Local/Coursier/Cache/v1 + ~/Library/Caches/Coursier/v1 + key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + + - name: Runs tests + run: sbt ++${{ matrix.scala }} scryptoJS/test + + - name: Publish a snapshot ${{ github.ref }} + if: env.HAS_SECRETS == 'true' + run: sbt ++${{ matrix.scala }} scryptoJS/publish env: SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} From 27fb0711a1ccf690ac93a69adebeb7fb411d4880 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sun, 9 Oct 2022 09:42:05 +0200 Subject: [PATCH 26/36] scala-js: ScalaJsSpec.scala added --- .../src/test/scala/scorex/ScalaJsSpec.scala | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 shared/src/test/scala/scorex/ScalaJsSpec.scala diff --git a/shared/src/test/scala/scorex/ScalaJsSpec.scala b/shared/src/test/scala/scorex/ScalaJsSpec.scala new file mode 100644 index 00000000..ab2e4116 --- /dev/null +++ b/shared/src/test/scala/scorex/ScalaJsSpec.scala @@ -0,0 +1,111 @@ +package scorex + +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec + +import java.io.{StringWriter, PrintWriter} +import java.lang.annotation.{ElementType, Target} +import java.lang.reflect.{InvocationTargetException, UndeclaredThrowableException} +import java.nio.ByteBuffer +import scala.collection.mutable +import scala.reflect.ClassTag + +class ScalaJsSpec extends AnyPropSpec with Matchers { + class A { + val f: Int = 10 + def m(): String = "m.toString" + } + class Z extends A + + val x = new A + val y = new A + val z = new Z + val cls = x.getClass + val clsY = y.getClass + val clsZ = z.getClass + + property("getSimpleName") { + cls shouldNot be(null) + cls.getSimpleName shouldBe "A" + // cls.getEnclosingClass shouldNot be (null) // Referring to non-existent method java.lang.Class.getEnclosingClass() + println(cls) + } + + property("getName") { + cls.getName shouldBe "scorex.ScalaJsSpec$A" + val t = mutable.HashMap.empty[Class[_], Int] + t.put(cls, 1) + t.get(clsY) shouldBe Some(1) + } + +// property("getField") { +//// cls.getField("f") shouldNot be(null) // Referring to non-existent method java.lang.Class.getField(java.lang.String) +// } +// +// property("getConstructors") { +//// cls.getConstructors shouldNot be(null) // Referring to non-existent method java.lang.Class.getConstructors() +// } + + property("isPrimitive") { + cls.isPrimitive shouldBe false + classOf[Int].isPrimitive shouldBe true + } + + property("getSuperclass") { + cls.getSuperclass.getName shouldBe "java.lang.Object" + } + + property("isAssignableFrom") { + cls.isAssignableFrom(clsY) shouldBe true + cls.isAssignableFrom(classOf[java.lang.Object]) shouldBe false + cls.isAssignableFrom(clsZ) shouldBe true + } + + property("PrintWriter") { + val pr = new PrintWriter(new StringWriter(100)) + pr.println("test") + } + + property("ByteBuffer") { + val bytes = Array[Byte](1, 2, 3) + val buf = ByteBuffer.wrap(bytes) + buf.position() shouldBe 0 + } + +// property("InvocationTargetException") { +// // [error] Referring to non-existent class java.lang.reflect.InvocationTargetException +// an[InvocationTargetException] should be thrownBy(throw new InvocationTargetException(null)) +// } + +// property("UndeclaredThrowableException") { +// // [error] Referring to non-existent class java.lang.reflect.UndeclaredThrowableException +// an[UndeclaredThrowableException] should be thrownBy(throw new UndeclaredThrowableException(null)) +// } + + property("ExceptionInInitializerError") { + // [error] Referring to non-existent class java.lang.reflect.UndeclaredThrowableException + an[ExceptionInInitializerError] should be thrownBy(throw new ExceptionInInitializerError("error")) + } + + property("ClassTag") { + val t = ClassTag[String](classOf[String]) + t.toString() shouldBe "java.lang.String" + } + + property("ClassTag.runtimeClass") { + val t = ClassTag[String](classOf[String]) + t.runtimeClass shouldBe classOf[String] + } + + property("NoSuchMethodException") { + try { + throw new NoSuchMethodException("methodName") + assert(false) + } + catch { + case e: NoSuchMethodException => + e.getMessage shouldBe "methodName" + } + } + +} From e49a3128b1a12ef33b416fef999458b989c28e92 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 20 Oct 2022 18:06:46 +0200 Subject: [PATCH 27/36] scala-js: more tests for ScalaJsSpec --- .../src/test/scala/scorex/ScalaJsSpec.scala | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/shared/src/test/scala/scorex/ScalaJsSpec.scala b/shared/src/test/scala/scorex/ScalaJsSpec.scala index ab2e4116..8ae9ef2a 100644 --- a/shared/src/test/scala/scorex/ScalaJsSpec.scala +++ b/shared/src/test/scala/scorex/ScalaJsSpec.scala @@ -55,6 +55,10 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { cls.getSuperclass.getName shouldBe "java.lang.Object" } +// property("getDeclaringClass") { +// cls.getDeclaringClass.getName shouldBe "ScalaJsSpec" // Referring to non-existent method java.lang.Class.getDeclaringClass() +// } + property("isAssignableFrom") { cls.isAssignableFrom(clsY) shouldBe true cls.isAssignableFrom(classOf[java.lang.Object]) shouldBe false @@ -92,6 +96,11 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { t.toString() shouldBe "java.lang.String" } +// property("Class.forName") { +// val t = Class.forName("java.lang.String") // error: Referring to non-existent method static java.lang.Class.forName(java.lang.String) +// t.toString() shouldBe "java.lang.String" +// } + property("ClassTag.runtimeClass") { val t = ClassTag[String](classOf[String]) t.runtimeClass shouldBe classOf[String] @@ -108,4 +117,15 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { } } + property("NoSuchFieldException") { + try { + throw new NoSuchFieldException("fieldName") + assert(false) + } + catch { + case e: NoSuchFieldException => + e.getMessage shouldBe "fieldName" + } + } + } From e96eb006e95f6ec64ddf0a245d5ea10c1b9f2429 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 16 Nov 2022 20:47:07 +0100 Subject: [PATCH 28/36] scala-js: add Scala 2.12 to JS tests and publishing --- .github/workflows/ci.yml | 2 +- build.sbt | 6 +++--- shared/src/test/scala/scorex/ScalaJsSpec.scala | 14 +++++++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e0ce9a1..7a934a18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.8] + scala: [2.13.8, 2.12.15] java: [adopt@1.8] runs-on: ${{ matrix.os }} steps: diff --git a/build.sbt b/build.sbt index 4680589d..e158dab9 100644 --- a/build.sbt +++ b/build.sbt @@ -34,7 +34,7 @@ lazy val commonSettings = Seq( libraryDependencies ++= Seq( // scalaOrganization.value % "scala-reflect" % scalaVersion.value % "provided", "org.rudogma" %%% "supertagged" % "2.0-RC2", - "org.scorexfoundation" %%% "scorex-util" % "0.1.8-19-0331a3d9-SNAPSHOT", + "org.scorexfoundation" %%% "scorex-util" % "0.1.8-20-565873cd-SNAPSHOT", "org.scalatest" %%% "scalatest" % "3.3.0-SNAP3" % Test, "org.scalatest" %%% "scalatest-propspec" % "3.3.0-SNAP3" % Test, @@ -65,12 +65,12 @@ lazy val scrypto = crossProject(JVMPlatform, JSPlatform) ) .jsSettings( scalaVersion := scala213, - crossScalaVersions := Seq(scala213), + crossScalaVersions := Seq(scala212, scala213), libraryDependencies ++= Seq( "org.scala-js" %%% "scala-js-macrotask-executor" % "1.0.0", ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13) ), - parallelExecution in Test := false, + Test / parallelExecution := false, Compile / npmDependencies ++= Seq( "bn.js" -> "5.2.0", "hash.js" -> "1.1.7", diff --git a/shared/src/test/scala/scorex/ScalaJsSpec.scala b/shared/src/test/scala/scorex/ScalaJsSpec.scala index 8ae9ef2a..6f590d38 100644 --- a/shared/src/test/scala/scorex/ScalaJsSpec.scala +++ b/shared/src/test/scala/scorex/ScalaJsSpec.scala @@ -5,9 +5,11 @@ import org.scalatest.propspec.AnyPropSpec import java.io.{StringWriter, PrintWriter} import java.lang.annotation.{ElementType, Target} -import java.lang.reflect.{InvocationTargetException, UndeclaredThrowableException} +import java.lang.reflect.{UndeclaredThrowableException, InvocationTargetException} import java.nio.ByteBuffer +import java.util import scala.collection.mutable +import scala.io.Source import scala.reflect.ClassTag class ScalaJsSpec extends AnyPropSpec with Matchers { @@ -128,4 +130,14 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { } } + property("java.util.HashMap") { + val m = new java.util.HashMap[Int, Int]() + m.put(1, 10) + m.get(1) shouldBe 10 + } + + property("scala.io.Source") { + val lines = Source.fromString("abc").getLines.toSeq + lines.length shouldBe 1 + } } From 95e9fa51ce8d8b6c32b8311649dc670fce77db2e Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 30 Dec 2022 23:45:14 +0100 Subject: [PATCH 29/36] scala-js: replaced BouncycastleJs with @noble/hashes --- build.sbt | 18 ++--- .../scala/scorex/crypto/BouncycastleJs.scala | 37 --------- .../scala/scorex/crypto/hash/Platform.scala | 76 +++++++++++++++---- .../scala/scorex/crypto/hash/Platform.scala | 39 +++++++++- package.json | 22 ++++++ project/plugins.sbt | 1 + .../scala/scorex/crypto/hash/Blake2b.scala | 2 +- .../scorex/crypto/hash/BouncyCastleHash.scala | 12 +-- .../scala/scorex/crypto/hash/Sha256.scala | 2 +- .../src/test/scala/scorex/ScalaJsSpec.scala | 11 +++ 10 files changed, 148 insertions(+), 72 deletions(-) delete mode 100644 js/src/main/scala/scorex/crypto/BouncycastleJs.scala create mode 100644 package.json diff --git a/build.sbt b/build.sbt index e158dab9..077eecd4 100644 --- a/build.sbt +++ b/build.sbt @@ -63,7 +63,11 @@ lazy val scrypto = crossProject(JVMPlatform, JSPlatform) scalaVersion := scala213, crossScalaVersions := Seq(scala211, scala212, scala213) ) - .jsSettings( + +lazy val scryptoJS = scrypto.js + .enablePlugins(ScalaJSBundlerPlugin) + .enablePlugins(ScalablyTypedConverterExternalNpmPlugin) + .settings( scalaVersion := scala213, crossScalaVersions := Seq(scala212, scala213), libraryDependencies ++= Seq( @@ -71,19 +75,11 @@ lazy val scrypto = crossProject(JVMPlatform, JSPlatform) ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13) ), Test / parallelExecution := false, - Compile / npmDependencies ++= Seq( - "bn.js" -> "5.2.0", - "hash.js" -> "1.1.7", - "elliptic" -> "6.5.4", - "blakejs" -> "1.2.1", - "bouncycastle-js" -> "0.1.8" - ), + // how to setup ScalablyTyped https://youtu.be/hWUAVrNj65c?t=1397 + externalNpm := { println(s"baseDirectory: ${baseDirectory.value}"); file(s"${baseDirectory.value}/..") }, useYarn := true ) -lazy val scryptoJS = scrypto.js - .enablePlugins(ScalaJSBundlerPlugin) - lazy val benchmarks = project .in(file("benchmarks")) .dependsOn(scrypto.jvm) diff --git a/js/src/main/scala/scorex/crypto/BouncycastleJs.scala b/js/src/main/scala/scorex/crypto/BouncycastleJs.scala deleted file mode 100644 index 318c27ea..00000000 --- a/js/src/main/scala/scorex/crypto/BouncycastleJs.scala +++ /dev/null @@ -1,37 +0,0 @@ -package scorex.crypto - -import scala.scalajs.js -import scala.annotation.nowarn -import scala.scalajs.js.annotation.JSImport -import scala.scalajs.js.typedarray.Int8Array - -@JSImport("bouncycastle-js", JSImport.Namespace) -@js.native -object BouncycastleJs extends js.Object { - - @js.native - trait Digest extends js.Object { - @nowarn - def update(in: RtArray[Byte], inOff: Int, len: Int): Unit = js.native - @nowarn - def updateByte(b: Byte): Unit = js.native - @nowarn - def doFinal(out: RtArray[Byte], outOff: Int): Int = js.native - } - - @js.native - trait Crypto extends js.Object { - def createBlake2bDigest(size: Int): Digest - def createSha256Digest(): Digest - } - - def bouncyCastle: Crypto = js.native - - @js.native - trait RtArray[T] extends js.Object { - def data: Int8Array - } - - @nowarn - def createByteArrayFromData(data: js.Array[Byte]): RtArray[Byte] = js.native -} \ No newline at end of file diff --git a/js/src/main/scala/scorex/crypto/hash/Platform.scala b/js/src/main/scala/scorex/crypto/hash/Platform.scala index f7243865..fb22184d 100644 --- a/js/src/main/scala/scorex/crypto/hash/Platform.scala +++ b/js/src/main/scala/scorex/crypto/hash/Platform.scala @@ -1,40 +1,84 @@ package scorex.crypto.hash -import scorex.crypto.BouncycastleJs +import typings.nobleHashes.blake2Mod.BlakeOpts +import typings.nobleHashes.mod.blake2b +import typings.nobleHashes.sha256Mod.sha256 +import typings.nobleHashes.utilsMod -import scala.scalajs.js +import scala.scalajs.js.typedarray.Uint8Array +/** JS platform specific implementation of methods. + * When shared code is compiled to JS, this implementation is used. + * + * The JS implementation is based on type wrappers generated by ScalablyTyped for the + * @noble/hashes library. (See configuration in build.sbt.) + * + * @see jvm/src/main/scala/scorex/crypto/hash/Platform.scala for JVM implementation + */ object Platform { - type Digest = BouncycastleJs.Digest - + /** Represents abstract digest from @noble. + * See createBlake2bDigest, createSha256Digest methods. + */ + type Digest = utilsMod.Hash[_] + + private def bytesToShorts(xs: Array[Byte]): Array[Short] = + xs.map(x => (x & 0xFF).toShort) + + private def uint8ArrayToBytes(jsShorts: Uint8Array): Array[Byte] = { + jsShorts.toArray[Short].map(x => x.toByte) + } + + /** Creates an implementation of the cryptographic hash function Blakbe2b. + * + * @param bitSize the bit size of the digest + * @return the digest implementation + */ def createBlake2bDigest(bitSize: Int): Digest = { - val bc = BouncycastleJs.bouncyCastle - val digest = bc.createBlake2bDigest(bitSize) - digest + val opts = BlakeOpts().setDkLen(bitSize / 8) + blake2b.create(opts) } + /** Creates an implementation of the cryptographic hash function SHA-256. + * + * @return the digest implementation + */ def createSha256Digest(): Digest = { - val bc = BouncycastleJs.bouncyCastle - val digest = bc.createSha256Digest() - digest + sha256.create() } + /** Update the message digest with a single byte. + * + * @param digest the digest to be updated + * @param b the input byte to be entered. + */ def updateDigest(digest: Digest, b: Byte): Unit = { - digest.updateByte(b) + digest.update(Uint8Array.of((b & 0xFF).toShort)) } + /** Update the message digest with a block of bytes. + * + * @param digest the digest to be updated + * @param bytes the byte array containing the data. + * @param inOff the offset into the byte array where the data starts. + * @param inLen the length of the data. + */ def updateDigest(digest: Digest, bytes: Array[Byte], inOff: Int, inLen: Int): Unit = { - val in = BouncycastleJs.createByteArrayFromData(js.Array(bytes: _*)) - digest.update(in, inOff, inLen) + val in = Uint8Array.of(bytesToShorts(bytes.slice(inOff, inOff + inLen)): _*) + digest.update(in) } + /** Close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * A new array is created to store the result. + * + * @param digest the digest to be finalized + */ def doFinalDigest(digest: Digest): Array[Byte] = { - val res = BouncycastleJs.createByteArrayFromData(new js.Array[Byte](32)) - digest.doFinal(res, 0) - res.data.toArray + val res = digest.digest() + uint8ArrayToBytes(res) } } diff --git a/jvm/src/main/scala/scorex/crypto/hash/Platform.scala b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala index bbdd1dca..a6a495d2 100644 --- a/jvm/src/main/scala/scorex/crypto/hash/Platform.scala +++ b/jvm/src/main/scala/scorex/crypto/hash/Platform.scala @@ -2,16 +2,47 @@ package scorex.crypto.hash import org.bouncycastle.crypto.digests.{Blake2bDigest, SHA256Digest} +/** JVM platform specific implementation of methods. + * When shared code is compiled to JVM, this implementation is used. + * + * The JVM implementation is based on bouncycastle library. + + * @see js/src/main/scala/scorex/crypto/hash/Platform.scala for JS implementation + */ object Platform { + /** Represents abstract digest from bouncycastle. + * See createBlake2bDigest, createSha256Digest methods. + */ type Digest = org.bouncycastle.crypto.ExtendedDigest - + + /** Creates an implementation of the cryptographic hash function Blakbe2b. + * + * @param bitSize the bit size of the digest + * @return the digest implementation + */ def createBlake2bDigest(bitSize: Int): Digest = new Blake2bDigest(bitSize) + /** Creates an implementation of the cryptographic hash function SHA-256. + * + * @return the digest implementation + */ def createSha256Digest(): Digest = new SHA256Digest() + /** Update the message digest with a single byte. + * + * @param digest the digest to be updated + * @param b the input byte to be entered. + */ def updateDigest(digest: Digest, b: Byte): Unit = digest.update(b) + /** Update the message digest with a block of bytes. + * + * @param digest the digest to be updated + * @param in the byte array containing the data. + * @param inOff the offset into the byte array where the data starts. + * @param inLen the length of the data. + */ def updateDigest(digest: Digest, in: Array[Byte], inOff: Int, @@ -19,6 +50,12 @@ object Platform { digest.update(in, inOff, inLen) } + /** Close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * A new array is created to store the result. + * + * @param digest the digest to be finalized + */ def doFinalDigest(digest: Digest): Array[Byte] = { val res = new Array[Byte](digest.getDigestSize) digest.doFinal(res, 0) diff --git a/package.json b/package.json new file mode 100644 index 00000000..673c5ee8 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "scrypto-js", + "version": "0.0.1", + "description": "Scrypto.js library", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/input-output-hk/scrypto.git" + }, + "homepage": "https://github.com/input-output-hk/scrypto/README.md", + "dependencies": { + "@noble/hashes": "^1.1.4" + }, + "devDependencies": { + "jest": "^29.0.3", + "shx": "^0.3.4", + "typescript": "^4.9.4" + } +} diff --git a/project/plugins.sbt b/project/plugins.sbt index a4e663e9..c514d551 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -18,3 +18,4 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.20.0") +addSbtPlugin("org.scalablytyped.converter" % "sbt-converter" % "1.0.0-beta37") \ No newline at end of file diff --git a/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala b/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala index 1c26f668..6a66183f 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala +++ b/shared/src/main/scala/scorex/crypto/hash/Blake2b.scala @@ -2,7 +2,7 @@ package scorex.crypto.hash trait Blake2b[D <: Digest] extends BouncyCastleHash[D] { - override protected lazy val digestFn = createBlake2bDigest(DigestSize * 8) + override protected def digestFn = createBlake2bDigest(DigestSize * 8) } diff --git a/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala b/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala index 7b0c9a94..02ee97a5 100644 --- a/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala +++ b/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala @@ -3,14 +3,16 @@ package scorex.crypto.hash trait BouncyCastleHash[D <: Digest] extends CryptographicHash[D] { protected def internalHash(inputs: Message*): Array[Byte] = synchronized { - inputs.foreach(i => updateDigest(digestFn, i, 0, i.length)) - doFinalDigest(digestFn) + val digest = digestFn + inputs.foreach(i => updateDigest(digest, i, 0, i.length)) + doFinalDigest(digest) } protected def internalPrefixedHash(prefix: Byte, inputs: Message*): Array[Byte] = synchronized { - updateDigest(digestFn, prefix) - inputs.foreach(i => updateDigest(digestFn, i, 0, i.length)) - doFinalDigest(digestFn) + val digest = digestFn + updateDigest(digest, prefix) + inputs.foreach(i => updateDigest(digest, i, 0, i.length)) + doFinalDigest(digest) } protected def digestFn: ExtendedDigest diff --git a/shared/src/main/scala/scorex/crypto/hash/Sha256.scala b/shared/src/main/scala/scorex/crypto/hash/Sha256.scala index a18ca31e..ce2ddf42 100644 --- a/shared/src/main/scala/scorex/crypto/hash/Sha256.scala +++ b/shared/src/main/scala/scorex/crypto/hash/Sha256.scala @@ -6,7 +6,7 @@ package scorex.crypto.hash object Sha256 extends CryptographicHash32 with BouncyCastleHash[Digest32] { override def hash(input: Array[Byte]): Digest32 = Digest32 @@ internalHash(input) - override protected lazy val digestFn = createSha256Digest() + override protected def digestFn = createSha256Digest() override def prefixedHash(prefix: Byte, inputs: Array[Byte]*): Digest32 = Digest32 @@ internalPrefixedHash(prefix, inputs: _*) diff --git a/shared/src/test/scala/scorex/ScalaJsSpec.scala b/shared/src/test/scala/scorex/ScalaJsSpec.scala index 6f590d38..5d5122ba 100644 --- a/shared/src/test/scala/scorex/ScalaJsSpec.scala +++ b/shared/src/test/scala/scorex/ScalaJsSpec.scala @@ -12,6 +12,11 @@ import scala.collection.mutable import scala.io.Source import scala.reflect.ClassTag +/** This suite is used to check different Scala features and base libraries against + * Scala.js, i.e. whether they are supported or not. + * The `// Not supported` code fails at compile time when compiled as part of scrypto/js. + * See commented code for what is not supported. + */ class ScalaJsSpec extends AnyPropSpec with Matchers { class A { val f: Int = 10 @@ -29,6 +34,7 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { property("getSimpleName") { cls shouldNot be(null) cls.getSimpleName shouldBe "A" + // Not supported // cls.getEnclosingClass shouldNot be (null) // Referring to non-existent method java.lang.Class.getEnclosingClass() println(cls) } @@ -40,6 +46,7 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { t.get(clsY) shouldBe Some(1) } +// Not supported // property("getField") { //// cls.getField("f") shouldNot be(null) // Referring to non-existent method java.lang.Class.getField(java.lang.String) // } @@ -57,6 +64,7 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { cls.getSuperclass.getName shouldBe "java.lang.Object" } +// Not supported // property("getDeclaringClass") { // cls.getDeclaringClass.getName shouldBe "ScalaJsSpec" // Referring to non-existent method java.lang.Class.getDeclaringClass() // } @@ -78,6 +86,7 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { buf.position() shouldBe 0 } +// Not supported // property("InvocationTargetException") { // // [error] Referring to non-existent class java.lang.reflect.InvocationTargetException // an[InvocationTargetException] should be thrownBy(throw new InvocationTargetException(null)) @@ -89,6 +98,7 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { // } property("ExceptionInInitializerError") { + // Not supported // [error] Referring to non-existent class java.lang.reflect.UndeclaredThrowableException an[ExceptionInInitializerError] should be thrownBy(throw new ExceptionInInitializerError("error")) } @@ -98,6 +108,7 @@ class ScalaJsSpec extends AnyPropSpec with Matchers { t.toString() shouldBe "java.lang.String" } +// Not supported // property("Class.forName") { // val t = Class.forName("java.lang.String") // error: Referring to non-existent method static java.lang.Class.forName(java.lang.String) // t.toString() shouldBe "java.lang.String" From a44a4805b30ad73a186615fcf71b230b3b420aed Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 30 Dec 2022 23:52:59 +0100 Subject: [PATCH 30/36] scala-js: release notes updated --- build.sbt | 3 --- release-notes.md | 10 ++++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 077eecd4..db4a70b5 100644 --- a/build.sbt +++ b/build.sbt @@ -32,10 +32,8 @@ lazy val commonSettings = Seq( ) ), libraryDependencies ++= Seq( -// scalaOrganization.value % "scala-reflect" % scalaVersion.value % "provided", "org.rudogma" %%% "supertagged" % "2.0-RC2", "org.scorexfoundation" %%% "scorex-util" % "0.1.8-20-565873cd-SNAPSHOT", - "org.scalatest" %%% "scalatest" % "3.3.0-SNAP3" % Test, "org.scalatest" %%% "scalatest-propspec" % "3.3.0-SNAP3" % Test, "org.scalatest" %%% "scalatest-shouldmatchers" % "3.3.0-SNAP3" % Test, @@ -47,7 +45,6 @@ lazy val commonSettings = Seq( ) - Test / publishArtifact := false diff --git a/release-notes.md b/release-notes.md index c047ef38..5e3847bc 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,3 +1,13 @@ + +**3.0.0** +--------- + +* CI configuration for Scala.js +* configuration of SBT with necessary JS dependencies (@noble/hashes) using ScalablyTyped +* removed all Java dependencies +* necessary code changes for Scala.js cross-compilation +* some classes moved to JVM-only module + **2.2.1** --------- From b4526da75392167461fa02c5e9be6e6193e93610 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 31 Dec 2022 00:06:11 +0100 Subject: [PATCH 31/36] scala-js: ScalaDoc for BouncyCastleHash --- .../scala/scorex/crypto/hash/BouncyCastleHash.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala b/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala index 02ee97a5..04d65edc 100644 --- a/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala +++ b/shared/src/main/scala/scorex/crypto/hash/BouncyCastleHash.scala @@ -1,13 +1,22 @@ package scorex.crypto.hash +/** Default implementation of hash generation using bouncycastle-style pair of methods + * update/doFinal. + * The only thing you need to do is to provide digestFn, which creates the correct digest + * for your hash function. + */ trait BouncyCastleHash[D <: Digest] extends CryptographicHash[D] { + /** Compute the hash by creating a digest, updating it with the messages and then + * finalizing. */ protected def internalHash(inputs: Message*): Array[Byte] = synchronized { val digest = digestFn inputs.foreach(i => updateDigest(digest, i, 0, i.length)) doFinalDigest(digest) } + /** Compute the hash by creating a digest, updating it with the prefix and the messages + * and then finalizing. */ protected def internalPrefixedHash(prefix: Byte, inputs: Message*): Array[Byte] = synchronized { val digest = digestFn updateDigest(digest, prefix) @@ -15,5 +24,6 @@ trait BouncyCastleHash[D <: Digest] extends CryptographicHash[D] { doFinalDigest(digest) } + /** Should be overriden to provide appropriate Digest instance. */ protected def digestFn: ExtendedDigest } From 5150edf23d4b787014e2dc6b24f56f2c52263163 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 31 Dec 2022 00:49:18 +0100 Subject: [PATCH 32/36] scala-js: add npmDependencies --- build.sbt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.sbt b/build.sbt index db4a70b5..8acf60d5 100644 --- a/build.sbt +++ b/build.sbt @@ -74,6 +74,10 @@ lazy val scryptoJS = scrypto.js Test / parallelExecution := false, // how to setup ScalablyTyped https://youtu.be/hWUAVrNj65c?t=1397 externalNpm := { println(s"baseDirectory: ${baseDirectory.value}"); file(s"${baseDirectory.value}/..") }, + Compile / npmDependencies ++= Seq( + "@noble/hashes" -> "^1.1.4", + "typescript" -> "^4.9.4" + ), useYarn := true ) From 8837261343ffde945f70a434b7b32c469ace1352 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Sat, 31 Dec 2022 10:33:51 +0100 Subject: [PATCH 33/36] scala-js: install npm CI action --- .github/workflows/ci.yml | 12 +++++++++--- build.sbt | 5 ++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a934a18..cf8d0b3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,12 +66,18 @@ jobs: os: [ubuntu-latest] scala: [2.13.8, 2.12.15] java: [adopt@1.8] + node-version: [16.x] runs-on: ${{ matrix.os }} steps: - - name: Checkout current branch (full) - uses: actions/checkout@v2 + - uses: actions/checkout@v2 + + - name: Setup NPM + uses: pnpm/action-setup@v2 with: - fetch-depth: 0 + version: 7.21.0 + node-version: ${{ matrix.node-version }} + cache: "pnpm" + - run: pnpm install - name: Setup Java and Scala uses: olafurpg/setup-scala@v10 diff --git a/build.sbt b/build.sbt index 8acf60d5..daea97c1 100644 --- a/build.sbt +++ b/build.sbt @@ -73,10 +73,9 @@ lazy val scryptoJS = scrypto.js ), Test / parallelExecution := false, // how to setup ScalablyTyped https://youtu.be/hWUAVrNj65c?t=1397 - externalNpm := { println(s"baseDirectory: ${baseDirectory.value}"); file(s"${baseDirectory.value}/..") }, + externalNpm := { file(s"${baseDirectory.value}/..") }, Compile / npmDependencies ++= Seq( - "@noble/hashes" -> "^1.1.4", - "typescript" -> "^4.9.4" + "@noble/hashes" -> "^1.1.4" ), useYarn := true ) From cb2bee142c11d1f2fc294f7b97195749f1c9e22a Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 11 Jan 2023 15:21:34 +0100 Subject: [PATCH 34/36] scala-js: fixes in release-notes.md --- release-notes.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/release-notes.md b/release-notes.md index 5e3847bc..83e46ab4 100644 --- a/release-notes.md +++ b/release-notes.md @@ -4,9 +4,11 @@ * CI configuration for Scala.js * configuration of SBT with necessary JS dependencies (@noble/hashes) using ScalablyTyped -* removed all Java dependencies +* removed all Java dependencies in `shared` code (jvm still uses BouncyCastle) * necessary code changes for Scala.js cross-compilation -* some classes moved to JVM-only module +* the following classes moved to JVM-only module (with the corresponding tests): + Blake2b256Unsafe, Blake2b512, CryptographicHash64, Keccak, Keccak256, Keccak512, + Sha256Unsafe, Skein256, Skein512, Stribog256, Stribog512, ThreadUnsafeHash, Whirlpool **2.2.1** --------- From d54d1e1e2f45424f42246a8d4a549dcef9299b7d Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 11 Jan 2023 16:13:22 +0100 Subject: [PATCH 35/36] scala-js: getting started guidelines in the Contributing section --- README.md | 28 +++++++++++++++++++++++++++- build.sbt | 2 +- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1faf1405..a484b388 100644 --- a/README.md +++ b/README.md @@ -190,4 +190,30 @@ The code is under Public Domain CC0 license means you can do anything with it. F # Contributing -Your contributions are always welcome! Please submit a pull request or create an issue to add a new cryptographic primitives or better implementations. +Clone the repository +``` +$git clone scrypto +$cd scrypto +``` + +The code uses [Scalablytyped](https://scalablytyped.org/docs/readme) to generate Scala.js bindings +for `@noble/hashes`. This [video](https://youtu.be/hWUAVrNj65c?t=1341) explains how the +environment for ScalablyTyped is configured in this repository. + +Before compiling the library with SBT, you need to install JS dependencies for ScalablyTyped. +The configuration is in `package.json`. +``` +$npm install +added 285 packages, and audited 286 packages in 20s +found 0 vulnerabilities +``` + +Then you can compile the library with SBT and run tests. +``` +$sbt +sbt:scrypto> compile +sbt:scrypto> test +``` + +Your contributions are always welcome! +Please submit a pull request or create an issue to add a new cryptographic primitives or better implementations. diff --git a/build.sbt b/build.sbt index daea97c1..93710647 100644 --- a/build.sbt +++ b/build.sbt @@ -72,7 +72,7 @@ lazy val scryptoJS = scrypto.js ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13) ), Test / parallelExecution := false, - // how to setup ScalablyTyped https://youtu.be/hWUAVrNj65c?t=1397 + // how to setup ScalablyTyped https://youtu.be/hWUAVrNj65c?t=1341 externalNpm := { file(s"${baseDirectory.value}/..") }, Compile / npmDependencies ++= Seq( "@noble/hashes" -> "^1.1.4" From 0c849654cc8d17568ace6f302fb2efb8b5c628ff Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 19 Jan 2023 16:01:34 +0100 Subject: [PATCH 36/36] scala-js: addressed review comments --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 673c5ee8..5dd17a63 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "scrypto-js", "version": "0.0.1", "description": "Scrypto.js library", - "license": "MIT", + "license": "CC0", "publishConfig": { "access": "public" },