Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.0] UnsignedBigInt implementation #997

Merged
merged 64 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
3d47f2a
initial raw, buggy & unversioned unsigned bit int impl
kushti May 24, 2024
b13cef6
failing schnorr sig check w. unsigned
kushti May 24, 2024
7ce2446
merging w. 6.0.0
kushti Jun 3, 2024
744d8a5
conversion test stub
kushti Jun 3, 2024
a30e068
Merge branch 'v6.0.0' of github.com:ScorexFoundation/sigmastate-inter…
kushti Jun 3, 2024
2acc6db
more todos
kushti Jun 4, 2024
15f4f67
removing modq methods
kushti Jun 7, 2024
303f969
expUnsigned impl (test still failing)
kushti Jun 8, 2024
982f32f
schnorr sig example passed
kushti Jun 9, 2024
eb47d17
eq test, DataValueComparer
kushti Jun 9, 2024
ea468c9
initial stubs along first todos for bulletproofs contracts
kushti Jun 11, 2024
e9b3253
original code
kushti Jun 12, 2024
e71d7c2
modInverse
kushti Jun 13, 2024
e989665
plusMod
kushti Jun 13, 2024
d776db3
multiplyMod
kushti Jun 13, 2024
72db85b
toUnsigned & toUnsignedMod
kushti Jun 14, 2024
fc6d856
mod, toSigned, subtractMod
kushti Jun 17, 2024
6bb7fe7
merging w. 6.0.0
kushti Aug 20, 2024
bcfb24d
removing unused CSigmaDslBuilder.validationSettings
kushti Aug 25, 2024
9a10d17
merging w. i1006 (numeric methods)
kushti Sep 9, 2024
89d4477
Merge branch 'i1006' of github.com:ScorexFoundation/sigmastate-interp…
kushti Sep 12, 2024
343a385
Merge branch 'i1006' of github.com:ScorexFoundation/sigmastate-interp…
kushti Sep 17, 2024
1c2b99d
more polishing in UnsignedBigInt impl
kushti Sep 17, 2024
cb51ba8
removing access to type before 6.0, more tests
kushti Sep 17, 2024
7b48ddd
merging w. 6.0.0
kushti Oct 8, 2024
09ec5f1
ignoring bulletproof test, impoving comments
kushti Oct 18, 2024
06fff23
merging w. 6.0.0
kushti Oct 24, 2024
a160997
UnsignedBigInt support in DataSerializerSpecification
kushti Oct 31, 2024
fdf712e
ErgoTreeSpecification update
kushti Oct 31, 2024
dde7f6e
fixing DataJsonEncoderSpecification
kushti Oct 31, 2024
a18967c
SigmaTyperTest fix
kushti Oct 31, 2024
2d8af9d
adding UnsignedBigInt to JS reflection , pt1
kushti Nov 1, 2024
933b2cc
improving UnsignedBigInt support in JS
kushti Nov 1, 2024
3a5c6d6
JS tests fixed
kushti Nov 4, 2024
b1d2b17
toUnsigned test in LSV6
kushti Nov 4, 2024
f84bce5
toUnsignedMod test in LSV6, more tests in BOS
kushti Nov 4, 2024
1496770
tests for .toBytes, UnsignedBigInt support added to to new Numeric me…
kushti Nov 5, 2024
ac4bbbc
unsigned encoding, .toBytes & .toBits tests passing
kushti Nov 5, 2024
a87bfb3
bitwiseInverse
kushti Nov 5, 2024
77be8a6
more .toBytes and .toBits tests
kushti Nov 11, 2024
626edc8
bitwise or/and/xor and tests
kushti Nov 11, 2024
aa246c3
shiftLeft/shiftRight and tests
kushti Nov 11, 2024
7fdcdbd
more tests for shiftLeft/shiftRight
kushti Nov 11, 2024
9566177
LSV6 tests for UnsignedBigInt
kushti Nov 13, 2024
503f0c7
bitwiseInverse fix, tests fixes
kushti Nov 13, 2024
6a15e5f
expUnsigned test
kushti Nov 13, 2024
b0e41a8
mod ops tests
kushti Nov 14, 2024
8da5f89
_eval mathods removed
kushti Nov 14, 2024
11bc3d0
More descriptions, some code cleaning
kushti Nov 14, 2024
8c5172b
costing
kushti Nov 14, 2024
dd33642
arith test
kushti Nov 14, 2024
8109a28
embeddable type list / serializers versioning, code cleaning , toUnsi…
kushti Nov 14, 2024
ae0421a
fixing JS test
kushti Nov 14, 2024
aa3fbbd
JS test comment
kushti Nov 14, 2024
cedcfbe
fixing tupleGen
kushti Nov 15, 2024
a66ab55
compilation err fix
kushti Nov 15, 2024
4c03c24
merging w. 6.0.0
kushti Nov 19, 2024
46433f8
merging w. 6.0.0
kushti Nov 22, 2024
42d7fc7
merging w. 6.0.0
kushti Nov 27, 2024
912a523
Update core/js/src/main/scala/sigma/js/Type.scala
kushti Nov 29, 2024
0af752d
Update core/shared/src/main/scala/sigma/SigmaDsl.scala
kushti Nov 29, 2024
b545aa5
Update sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala
kushti Nov 29, 2024
ad3506e
addressing review comments
kushti Nov 29, 2024
847e4bb
Merge branch 'i554' of github.com:ScorexFoundation/sigmastate-interpr…
kushti Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/js/src/main/scala/sigma/crypto/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ object Platform {
case _: Boolean => tpe == SBoolean
case _: Byte | _: Short | _: Int | _: Long => tpe.isInstanceOf[SNumericType]
case _: BigInt => tpe == SBigInt
case _: UnsignedBigInt => tpe == SUnsignedBigInt
case _: String => tpe == SString
case _: GroupElement => tpe.isGroupElement
case _: SigmaProp => tpe.isSigmaProp
Expand Down
14 changes: 13 additions & 1 deletion core/js/src/main/scala/sigma/js/Isos.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package sigma.js

import sigma.{Coll, Colls}
import sigma.data.{CBigInt, Iso, RType}
import sigma.data.{CBigInt, CUnsignedBigInt, Iso, RType}

import java.math.BigInteger
import scala.reflect.ClassTag
Expand Down Expand Up @@ -42,6 +42,18 @@ object Isos {
}
}

implicit val isoUnsignedBigInt: Iso[js.BigInt, sigma.UnsignedBigInt] = new Iso[js.BigInt, sigma.UnsignedBigInt] {
override def to(x: js.BigInt): sigma.UnsignedBigInt = {
CUnsignedBigInt(new BigInteger(x.toString(10)))
}

override def from(x: sigma.UnsignedBigInt): js.BigInt = {
val bi = x.asInstanceOf[CUnsignedBigInt].wrappedValue
val s = bi.toString(10)
js.BigInt(s)
}
}

implicit val isoBigIntToLong: Iso[js.BigInt, Long] = new Iso[js.BigInt, Long] {
override def to(x: js.BigInt): Long = java.lang.Long.parseLong(x.toString(10))

Expand Down
3 changes: 3 additions & 0 deletions core/js/src/main/scala/sigma/js/Type.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ object Type extends js.Object {
/** Descriptor of ErgoScript type BigInt. */
val BigInt = new Type(sigma.BigIntRType)

/** Descriptor of ErgoScript type UnsignedBigInt. */
val UnsignedBigInt = new Type(sigma.UnsignedBigIntRType)

/** Descriptor of ErgoScript type GroupElement. */
val GroupElement = new Type(sigma.GroupElementRType)

Expand Down
1 change: 1 addition & 0 deletions core/jvm/src/main/scala/sigma/crypto/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ object Platform {
case _: Int => tpe == SInt
case _: Long => tpe == SLong
case _: BigInt => tpe == SBigInt
case _: UnsignedBigInt => tpe == SUnsignedBigInt
case _: String => tpe == SString // TODO v6.0: remove this case (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/905)
case _: GroupElement => tpe.isGroupElement
case _: SigmaProp => tpe.isSigmaProp
Expand Down
2 changes: 2 additions & 0 deletions core/shared/src/main/scala/sigma/Evaluation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ object Evaluation {
case SAny => AnyType
case SUnit => UnitType
case SBigInt => BigIntRType
case SUnsignedBigInt => UnsignedBigIntRType
case SBox => BoxRType
case SContext => ContextRType
case SGlobal => SigmaDslBuilderRType
Expand Down Expand Up @@ -67,6 +68,7 @@ object Evaluation {
case AnyType => SAny
case UnitType => SUnit
case BigIntRType => SBigInt
case UnsignedBigIntRType => SUnsignedBigInt
case GroupElementRType => SGroupElement
case AvlTreeRType => SAvlTree
case ot: OptionType[_] => SOption(rtypeToSType(ot.tA))
Expand Down
193 changes: 191 additions & 2 deletions core/shared/src/main/scala/sigma/SigmaDsl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import java.math.BigInteger
import sigma.data._

/**
* Functions defined for 256-bit signed integers
* */
* Base class for signed 256-bits integers
*/
trait BigInt {
/** Convert this BigInt value to Byte.
* @throws ArithmeticException if overflow happens.
Expand Down Expand Up @@ -167,8 +167,188 @@ trait BigInt {
* @return a 256-bit signed integer whose value is (this >> n). `n` should be in 0..255 range (inclusive).
*/
def shiftRight(n: Int): BigInt

/**
* @return unsigned representation of this BigInt, or exception if its value is negative
*/
def toUnsigned: UnsignedBigInt

/**
* @return unsigned representation of this BigInt modulo `m`. Cryptographic mod operation is done, so result is
* always non-negative
*/
def toUnsignedMod(m: UnsignedBigInt): UnsignedBigInt
}

/**
* Base class for unsigned 256-bits integers
*/
trait UnsignedBigInt {
/** Convert this BigInt value to Byte.
* @throws ArithmeticException if overflow happens.
*/
def toByte: Byte

/** Convert this BigInt value to Short.
* @throws ArithmeticException if overflow happens.
*/
def toShort: Short

/** Convert this BigInt value to Int.
* @throws ArithmeticException if overflow happens.
*/
def toInt: Int

/** Convert this BigInt value to Int.
* @throws ArithmeticException if overflow happens.
*/
def toLong: Long

/** Returns a big-endian representation of this BigInt in a collection of bytes.
* For example, the value {@code 0x1213141516171819} would yield the
* byte array {@code {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}}.
*/
def toBytes: Coll[Byte]


/** Compares this numeric with that numeric for order. Returns a negative integer, zero, or a positive integer as the
* `this` is less than, equal to, or greater than `that`.
*/
def compareTo(that: UnsignedBigInt): Int

/** Returns a BigInt whose value is {@code (this + that)}, or exception if result does not fit into 256 bits
* (consider using plusMod to avoid exception)
*
* @param that value to be added to this BigInt.
* @return { @code this + that}
*/
def add(that: UnsignedBigInt): UnsignedBigInt
aslesarenko marked this conversation as resolved.
Show resolved Hide resolved
def +(that: UnsignedBigInt): UnsignedBigInt = add(that)

/** Returns a BigInt whose value is {@code (this - that)}, or exception if result is negative
* (consider using plusMod to avoid exception)
*
* @param that value to be subtracted from this BigInt.
* @return { @code this - that}
*/
def subtract(that: UnsignedBigInt): UnsignedBigInt

def -(that: UnsignedBigInt): UnsignedBigInt = subtract(that)

/** Returns a BigInt whose value is {@code (this * that)} , or exception if result does not fit into 256 bits
* (consider using multiplyMod to avoid exception)
*
* @implNote An implementation may offer better algorithmic
* performance when { @code that == this}.
* @param that value to be multiplied by this BigInt.
* @return { @code this * that}
*/
def multiply(that: UnsignedBigInt): UnsignedBigInt
def *(that: UnsignedBigInt): UnsignedBigInt = multiply(that)

/** Returns a BigInt whose value is {@code (this / that)}.
*
* @param that value by which this BigInt is to be divided.
* @return { @code this / that}
* @throws ArithmeticException if { @code that} is zero.
*/
def divide(that: UnsignedBigInt): UnsignedBigInt
def /(that: UnsignedBigInt): UnsignedBigInt = divide(that)

/**
* Returns a BigInt whose value is {@code (this mod m}). This method
* differs from {@code remainder} in that it always returns a
* <i>non-negative</i> BigInteger.
*
* @param m the modulus.
* @return { @code this mod m}
* @throws ArithmeticException { @code m} &le; 0
* @see #remainder
*/
def mod(m: UnsignedBigInt): UnsignedBigInt
def %(m: UnsignedBigInt): UnsignedBigInt = mod(m)

/**
* Returns the minimum of this BigInteger and {@code val}.
*
* @param that value with which the minimum is to be computed.
* @return the BigInteger whose value is the lesser of this BigInteger and
* { @code val}. If they are equal, either may be returned.
*/
def min(that: UnsignedBigInt): UnsignedBigInt

/**
* Returns the maximum of this BigInteger and {@code val}.
*
* @param that value with which the maximum is to be computed.
* @return the BigInteger whose value is the greater of this and
* { @code val}. If they are equal, either may be returned.
*/
def max(that: UnsignedBigInt): UnsignedBigInt

/** Returns a BigInteger whose value is `(this & that)`.
* @param that value to be AND'ed with this BigInteger.
* @return `this & that`
*/
def and(that: UnsignedBigInt): UnsignedBigInt
def &(that: UnsignedBigInt): UnsignedBigInt = and(that)

/** Returns a BigInteger whose value is `(this | that)`.
*
* @param that value to be OR'ed with this BigInteger.
* @return `this | that`
*/
def or(that: UnsignedBigInt): UnsignedBigInt
def |(that: UnsignedBigInt): UnsignedBigInt = or(that)

def modInverse(m: UnsignedBigInt): UnsignedBigInt

/**
* @return this + that mod m , where mod is cryptographic mod operation
*/
def plusMod(that: UnsignedBigInt, m: UnsignedBigInt): UnsignedBigInt

/**
* @return this - that mod m , where mod is cryptographic mod operation, so result is always non-negative
*/
def subtractMod(that: UnsignedBigInt, m: UnsignedBigInt): UnsignedBigInt

/**
* @return this * that mod m , where mod is cryptographic mod operation
*/
def multiplyMod(that: UnsignedBigInt, m: UnsignedBigInt): UnsignedBigInt

/**
* @return an unsigned big integer whose value is `this xor that`
*/
def xor(that: UnsignedBigInt): UnsignedBigInt

/**
* @return a 256-bit unsigned integer whose value is (this << n). The shift distance, n, may be negative,
* in which case this method performs a right shift. (Computes floor(this * 2n).)
*/
def shiftLeft(n: Int): UnsignedBigInt

/**
* @return a 256-bit unsigned integer whose value is (this >> n). Sign extension is performed. The shift distance, n,
* may be negative, in which case this method performs a left shift. (Computes floor(this / 2n).)
*/
def shiftRight(n: Int): UnsignedBigInt

/**
* @return an unsigned big integer value which is inverse of this (every bit is flipped)
*/
def bitwiseInverse(): UnsignedBigInt

/**
* @return signed version of the same value, or exception if the value does not fit into signed type (since it is
* also about 256 bits, but one bit is encoding sign)
*/
def toSigned(): BigInt
aslesarenko marked this conversation as resolved.
Show resolved Hide resolved
}



/** Base class for points on elliptic curves. */
trait GroupElement {
/** Checks if the provided element is an identity element. */
Expand All @@ -181,6 +361,12 @@ trait GroupElement {
*/
def exp(k: BigInt): GroupElement

/** Exponentiate this <code>GroupElement</code> to the given unsigned 256 bit integer.
* @param k The power.
* @return <code>this to the power of k</code>.
*/
def expUnsigned(k: UnsignedBigInt): GroupElement

/** Group operation. */
def multiply(that: GroupElement): GroupElement

Expand Down Expand Up @@ -775,6 +961,9 @@ trait SigmaDslBuilder {
/** Create DSL big integer from existing `java.math.BigInteger`*/
def BigInt(n: BigInteger): BigInt

/** Create DSL unsigned big integer from existing `java.math.BigInteger`*/
def UnsignedBigInt(n: BigInteger): UnsignedBigInt
aslesarenko marked this conversation as resolved.
Show resolved Hide resolved

/** Extract `java.math.BigInteger` from DSL's `BigInt` type*/
def toBigInteger(n: BigInt): BigInteger

Expand Down
Loading
Loading