Skip to content

Commit

Permalink
Merge pull request #898 from ScorexFoundation/secure-random-js
Browse files Browse the repository at this point in the history
Secure random for JS
  • Loading branch information
aslesarenko authored Aug 7, 2023
2 parents 1c7b9dc + 9595070 commit 595fbb8
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}

- name: Runs tests and collect coverage
run: sbt -jvm-opts ci/ci.jvmopts ++${{ matrix.scala }} commonJS/test corelibJS/test interpreterJS/test graphirJS/test sdkJS/test
run: sbt -jvm-opts ci/ci.jvmopts ++${{ matrix.scala }} commonJS/test corelibJS/test interpreterJS/test graphirJS/test sdkJS/test scJS/test

- name: Publish a JVM snapshot ${{ github.ref }}
if: env.HAS_SECRETS == 'true'
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ lazy val commonDependenies2 = libraryDependencies ++= Seq(
"org.scala-lang.modules" %%% "scala-collection-compat" % "2.7.0"
)

val sigmajsCryptoFacadeVersion = "0.0.6"
val sigmajsCryptoFacadeVersion = "0.0.7"

lazy val common = crossProject(JVMPlatform, JSPlatform)
.in(file("common"))
Expand Down
17 changes: 13 additions & 4 deletions interpreter/js/src/main/scala/sigmastate/crypto/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,23 @@ object Platform {
def multiplyPoints(p1: Ecp, p2: Ecp): Ecp = new Ecp(CryptoFacadeJs.addPoint(p1.point, p2.point))

/** Exponentiate a point p.
* The implementation mimics the Java implementation of `AbstractECMultiplier.multiply`
* from BouncyCastle library.
*
* @param p point to exponentiate
* @param n exponent
* @return p to the power of n (`p^n`) i.e. `p + p + ... + p` (n times)
*/
def exponentiatePoint(p: Ecp, n: BigInteger): Ecp = {
val scalar = Convert.bigIntegerToBigInt(n)
new Ecp(CryptoFacadeJs.multiplyPoint(p.point, scalar))
val sign = n.signum()
if (sign == 0 || isInfinityPoint(p)) {
val ctx = new CryptoContextJs()
return new Ecp(ctx.getInfinity())
}
val scalar = Convert.bigIntegerToBigInt(n.abs())
val positive = CryptoFacadeJs.multiplyPoint(p.point, scalar)
val result = if (sign > 0) positive else CryptoFacadeJs.negatePoint(positive)
new Ecp(result)
}

/** Check if a point is infinity. */
Expand All @@ -120,7 +129,7 @@ object Platform {
class Curve

// TODO JS: Use JS library for secure source of randomness
type SecureRandom = Random
type SecureRandom = sigmastate.crypto.SecureRandomJS

/** Opaque point type. */
@js.native
Expand Down Expand Up @@ -198,7 +207,7 @@ object Platform {
}

/** Create JS specific source of secure randomness. */
def createSecureRandom(): Random = new Random()
def createSecureRandom(): SecureRandom = new SecureRandomJS

/** Computes HMAC-SHA512 hash of the given data using the specified key.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package sigmastate.crypto

import debox.cfor

import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import scala.scalajs.js.typedarray.Uint8Array
Expand Down Expand Up @@ -109,6 +111,25 @@ object CryptoFacadeJs extends js.Object {
def generatePbkdf2Key(
normalizedMnemonic: String,
normalizedPass: String): Uint8Array = js.native

/** Creates a random array of bytes of the given length. */
def getRandomBytes(length: Int): Uint8Array = js.native
}

/** This class provides a cryptographically strong generator of byte arrays. */
class SecureRandomJS {
/**
* Generates a user-specified number of random bytes.
*
* @param bytes the array to be filled in with random bytes.
*/
def nextBytes(bytes: Array[Byte]): Unit = {
val len = bytes.length
val arr = CryptoFacadeJs.getRandomBytes(len)
cfor(0)(_ < len, _ + 1) { i =>
bytes(i) = arr(i).toByte
}
}
}

/** Represents imported Point class from `sigmajs-crypto-facade` JS libarary. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import sigmastate.helpers.TestingHelpers._
import org.ergoplatform._
import org.ergoplatform.dsl.{ContractSpec, SigmaContractSyntax, StdContracts, TestContractSpec}
import sigmastate.basics.CryptoConstants
import sigmastate.crypto.CryptoFacade
import sigmastate.crypto.{BigIntegers, CryptoFacade}
import sigmastate.eval.Extensions.ArrayOps
import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv}
import sigmastate.utxo._
Expand Down Expand Up @@ -89,7 +89,8 @@ class OracleExamplesSpecification extends CompilerTestingCommons

val temperature: Long = 18

val r = BigInt.apply(128, CryptoFacade.createSecureRandom()) //128 bits random number
//create 128 bits random number
val r = BigInt(BigIntegers.createRandomBigInteger(128, CryptoFacade.createSecureRandom()))
val a = group.exponentiate(group.generator, r.bigInteger)

val ts = System.currentTimeMillis()
Expand Down

0 comments on commit 595fbb8

Please sign in to comment.