Skip to content

Commit

Permalink
toBits tests for Long and BigInt(failing)
Browse files Browse the repository at this point in the history
  • Loading branch information
kushti committed Jul 8, 2024
1 parent ee59083 commit 3fde5fa
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 15 deletions.
2 changes: 0 additions & 2 deletions data/shared/src/main/scala/sigma/data/BigIntegerOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ object NumericOps {
override def divisionRemainder(x: BigInt, y: BigInt): BigInt = x.mod(y)

override def toBigEndianBytes(x: BigInt): Coll[Byte] = Colls.fromArray(x.toBigInteger.toByteArray)

override def toBits(x: BigInt): Coll[Boolean] = ???
}

/** The instance of [[scalan.ExactOrdering]] typeclass for [[BigInt]]. */
Expand Down
11 changes: 0 additions & 11 deletions data/shared/src/main/scala/sigma/data/ExactIntegral.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ object ExactIntegral {
override def minus(x: Byte, y: Byte): Byte = x.subtractExact(y)
override def times(x: Byte, y: Byte): Byte = x.multiplyExact(y)
override def toBigEndianBytes(x: Byte): Coll[Byte] = Colls.fromItems(x)
override def toBits(x: Byte): Coll[Boolean] = {
def byte2Bools(b: Byte): Array[Boolean] = (0 to 7).toArray.reverse.map(isBitSet(b))

def isBitSet(byte: Byte)(bit: Int): Boolean = ((byte >> bit) & 1) == 1

Colls.fromArray(byte2Bools(x))
}
}

implicit object ShortIsExactIntegral extends ExactIntegral[Short] {
Expand All @@ -54,7 +47,6 @@ object ExactIntegral {
override def minus(x: Short, y: Short): Short = x.subtractExact(y)
override def times(x: Short, y: Short): Short = x.multiplyExact(y)
override def toBigEndianBytes(x: Short): Coll[Byte] = Colls.fromItems((x >> 8).toByte, x.toByte)
override def toBits(x: Short): Coll[Boolean] = ???
}

implicit object IntIsExactIntegral extends ExactIntegral[Int] {
Expand All @@ -64,7 +56,6 @@ object ExactIntegral {
override def times(x: Int, y: Int): Int = java7.compat.Math.multiplyExact(x, y)
override def toBigEndianBytes(x: Int): Coll[Byte] =
Colls.fromItems((x >> 24).toByte, (x >> 16).toByte, (x >> 8).toByte, x.toByte)
override def toBits(x: Int): Coll[Boolean] = ???
}

implicit object LongIsExactIntegral extends ExactIntegral[Long] {
Expand All @@ -74,7 +65,5 @@ object ExactIntegral {
override def times(x: Long, y: Long): Long = java7.compat.Math.multiplyExact(x, y)
override def toBigEndianBytes(x: Long): Coll[Byte] =
Colls.fromItems((x >> 56).toByte, (x >> 48).toByte, (x >> 40).toByte, (x >> 32).toByte, (x >> 24).toByte, (x >> 16).toByte, (x >> 8).toByte, x.toByte)

override def toBits(x: Long): Coll[Boolean] = ???
}
}
19 changes: 17 additions & 2 deletions data/shared/src/main/scala/sigma/data/ExactNumeric.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package sigma.data

import sigma.Coll
import sigma.{Coll, Colls}
import sigma.data.ExactIntegral._

import scala.collection.mutable

/** Numeric operations with overflow checks.
* Raise exception when overflow is detected.
* Each instance of this typeclass overrides three methods `plus`, `minus`, `times`.
Expand Down Expand Up @@ -37,7 +39,20 @@ trait ExactNumeric[T] {
*/
def toBigEndianBytes(x: T): Coll[Byte]

def toBits(x: T): Coll[Boolean]
def toBits(x: T): Coll[Boolean] = {
def byte2Bools(b: Byte): Array[Boolean] = (0 to 7).toArray.reverse.map(isBitSet(b))

def isBitSet(byte: Byte)(bit: Int): Boolean = ((byte >> bit) & 1) == 1

val bytes = toBigEndianBytes(x)
val builder = mutable.ArrayBuilder.make[Boolean]
val l = bytes.length
(0 until l).foreach{i=>
val b = bytes(i)
builder.addAll(byte2Bools(b))
}
Colls.fromArray(builder.result())
}

/** A value of type T which corresponds to integer 0. */
lazy val zero: T = fromInt(0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,42 @@ class BasicOpsSpecification extends CompilerTestingCommons
}
}

property("Long.toBits") {
def toBitsTest() = test("Long.toBits", env, ext,
"""{
| val b = 1L
| val ba = b.toBits
|
| // only rightmost bit is set
| ba.size == 64 && ba(63) == true && ba.slice(0, 63).forall({ (b: Boolean ) => b == false })
|}""".stripMargin,
null
)

if (VersionContext.current.isV6SoftForkActivated) {
toBitsTest()
} else {
an[Exception] shouldBe thrownBy(toBitsTest())
}
}

property("BigInt.toBits") {
def toBitsTest() = test("BigInt.toBits", env, ext,
s"""{
| val b = bigInt("${CryptoConstants.groupOrder.divide(new BigInteger("2"))}")
| val ba = b.toBits
| ba.size == 256
|}""".stripMargin,
null
)

if (VersionContext.current.isV6SoftForkActivated) {
toBitsTest()
} else {
an[Exception] shouldBe thrownBy(toBitsTest())
}
}

property("Unit register") {
// TODO frontend: implement missing Unit support in compiler
// https://github.com/ScorexFoundation/sigmastate-interpreter/issues/820
Expand Down

0 comments on commit 3fde5fa

Please sign in to comment.