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

Rename point to element in CryptoFacade #948

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 19 additions & 20 deletions interpreter/js/src/main/scala/sigmastate/crypto/Platform.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package sigmastate.crypto

import sigma.data.RType
import scorex.util.encode.Base16
import sigmastate._
import sigma.Coll
Expand Down Expand Up @@ -72,7 +71,7 @@ object Platform {
* @see [[CryptoFacade.getASN1Encoding]]
*/
def getASN1Encoding(p: Ecp, compressed: Boolean): Array[Byte] = {
val hex = if (isInfinityPoint(p)) "00" // to ensure equality with Java implementation
val hex = if (isIdentity(p)) "00" // to ensure equality with Java implementation
else p.point.toHex(compressed)
Base16.decode(hex).get
}
Expand All @@ -85,44 +84,44 @@ object Platform {
*
* @return a new ECPoint instance representing the same point, but with normalized coordinates
*/
def normalizePoint(p: Ecp): Ecp = new Ecp(CryptoFacadeJs.normalizePoint(p.point))
def normalize(e: Ecp): Ecp = new Ecp(CryptoFacadeJs.normalizePoint(e.point))

/** Return simplified string representation of the point (used only for debugging) */
def showPoint(p: Ecp): String = CryptoFacadeJs.showPoint(p.point)
/** Return simplified string representation of the element (used only for debugging) */
def showElement(e: Ecp): String = CryptoFacadeJs.showPoint(e.point)

/** Multiply two points.
/** Multiply two elements.
*
* @param p1 first point
* @param p2 second point
* @return group multiplication (p1 * p2)
* @param e1 first element
* @param e2 second element
* @return group multiplication (e1 * e2)
*/
def multiplyPoints(p1: Ecp, p2: Ecp): Ecp = new Ecp(CryptoFacadeJs.addPoint(p1.point, p2.point))
def multiplyElements(e1: Ecp, e2: Ecp): Ecp = new Ecp(CryptoFacadeJs.addPoint(e1.point, e2.point))

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

/** Check if a point is infinity. */
def isInfinityPoint(p: Ecp): Boolean = CryptoFacadeJs.isInfinityPoint(p.point)
/** Check if a element is identity. */
def isIdentity(e: Ecp): Boolean = CryptoFacadeJs.isInfinityPoint(e.point)

/** Negates the given point by negating its y coordinate. */
def negatePoint(p: Ecp): Ecp = new Ecp(CryptoFacadeJs.negatePoint(p.point))
/** Negates the given element by negating its y coordinate. */
def inverse(e: Ecp): Ecp = new Ecp(CryptoFacadeJs.negatePoint(e.point))

/** JS implementation of Elliptic Curve. */
class Curve
Expand Down Expand Up @@ -245,7 +244,7 @@ object Platform {
def isCorrectType[T <: SType](value: Any, tpe: T): Boolean = value match {
case c: Coll[_] => tpe match {
case STuple(items) => c.tItem == sigma.AnyType && c.length == items.length
case tpeColl: SCollection[_] => true
case _: SCollection[_] => true
case _ => sys.error(s"Collection value $c has unexpected type $tpe")
}
case _: Option[_] => tpe.isOption
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ class CryptoFacadeJsSpec extends AnyPropSpec with Matchers with CryptoTesting {
}

property("CryptoFacade.normalizePoint") {
CryptoFacade.normalizePoint(new Ecp(p1)) shouldBe new Ecp(p1)
CryptoFacadeJs.normalizePoint(p1).toHex(true) shouldBe
"0381c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac"
}

property("CryptoFacade.negatePoint") {
CryptoFacadeJs.negatePoint(p1).toHex(true) shouldBe
"0281c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac"
"0281c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac"
}

property("CryptoFacade.isInfinityPoint") {
Expand Down
50 changes: 25 additions & 25 deletions interpreter/jvm/src/main/scala/sigmastate/crypto/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,48 +73,48 @@ object Platform {
/** Normalization ensures that any projective coordinate is 1, and therefore that the x, y
* coordinates reflect those of the equivalent point in an affine coordinate system.
*
* @return a new ECPoint instance representing the same point, but with normalized coordinates
* @return a new ECPoint instance representing the same element, but with normalized coordinates
*/
def normalizePoint(p: Ecp): Ecp = Ecp(p.value.normalize())
def normalize(e: Ecp): Ecp = Ecp(e.value.normalize())

/** Return simplified string representation of the point (used only for debugging) */
def showPoint(p: Ecp): String = {
val rawX = p.value.getRawXCoord.toString.substring(0, 6)
val rawY = p.value.getRawYCoord.toString.substring(0, 6)
/** Return simplified string representation of element (used only for debugging) */
def showElement(e: Ecp): String = {
val rawX = e.value.getRawXCoord.toString.substring(0, 6)
val rawY = e.value.getRawYCoord.toString.substring(0, 6)
s"ECPoint($rawX,$rawY,...)"
}

/** Multiply two points.
/** Multiply two elements.
*
* @param p1 first point
* @param p2 second point
* @return group multiplication (p1 * p2)
* @param e1 first element
* @param e2 second element
* @return group multiplication (e1 * e2)
*/
def multiplyPoints(p1: Ecp, p2: Ecp): Ecp = {
def multiplyElements(e1: Ecp, e2: Ecp): Ecp = {
/*
* BC treats EC as additive group while we treat that as multiplicative group.
*/
Ecp(p1.value.add(p2.value))
Ecp(e1.value.add(e2.value))
}

/** Exponentiate a point.
* @param p point to exponentiate
/** Exponentiate an element.
* @param e element 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 = {
def exponentiateElement(e: Ecp, n: BigInteger): Ecp = {
/*
* BC treats EC as additive group while we treat that as multiplicative group.
* Therefore, exponentiate point is multiply.
*/
Ecp(p.value.multiply(n))
Ecp(e.value.multiply(n))
}

/** Check if a point is infinity. */
def isInfinityPoint(p: Ecp): Boolean = p.value.isInfinity
/** Check if an element is infinity. */
def isIdentity(e: Ecp): Boolean = e.value.isInfinity

/** Negates the given point by negating its y coordinate. */
def negatePoint(p: Ecp): Ecp = Ecp(p.value.negate())
/** Inverse the given element by negating its y coordinate. */
def inverse(e: Ecp): Ecp = Ecp(e.value.negate())

/** Wrapper for curve descriptor. Serves as the concrete implementation of the
* [[sigmastate.crypto.Curve]] type in JVM.
Expand Down Expand Up @@ -199,11 +199,11 @@ object Platform {
}

/** This JVM specific methods are used in Ergo node which won't be JS cross-compiled. */
implicit class EcpOps(val p: Ecp) extends AnyVal {
def getCurve: ECCurve = p.value.getCurve
def isInfinity: Boolean = CryptoFacade.isInfinityPoint(p)
def add(p2: Ecp): Ecp = CryptoFacade.multiplyPoints(p, p2)
def multiply(n: BigInteger): Ecp = CryptoFacade.exponentiatePoint(p, n)
implicit class EcpOps(val e: Ecp) extends AnyVal {
def getCurve: ECCurve = e.value.getCurve
def isIdentity: Boolean = CryptoFacade.isIdentity(e)
def add(e2: Ecp): Ecp = CryptoFacade.multiplyElements(e, e2)
def multiply(n: BigInteger): Ecp = CryptoFacade.exponentiateElement(e, n)
}

/** This JVM specific methods are used in Ergo node which won't be JS cross-compiled. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup {
* @throws IllegalArgumentException
**/
override def inverseOf(groupElement: ElemType): ElemType =
CryptoFacade.negatePoint(groupElement)
CryptoFacade.inverse(groupElement)

/**
* Raises the base GroupElement to the exponent. The result is another GroupElement.
Expand All @@ -151,12 +151,12 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup {
*/
override def exponentiate(base: ElemType, exponent: BigInteger): ElemType = {
//infinity remains the same after any exponentiate
if (CryptoFacade.isInfinityPoint(base)) return base
if (CryptoFacade.isIdentity(base)) return base

//If the exponent is negative, convert it to be the exponent modulus q.
val exp = if (exponent.compareTo(BigInteger.ZERO) < 0) exponent.mod(order) else exponent

CryptoFacade.exponentiatePoint(base, exp)
CryptoFacade.exponentiateElement(base, exp)
}


Expand Down Expand Up @@ -197,7 +197,7 @@ abstract class BcDlogGroup(val ctx: CryptoContext) extends DlogGroup {
* @throws IllegalArgumentException
*/
override def multiplyGroupElements(groupElement1: ElemType, groupElement2: ElemType): ElemType =
CryptoFacade.multiplyPoints(groupElement1, groupElement2)
CryptoFacade.multiplyElements(groupElement1, groupElement2)

/**
* Computes the product of several exponentiations of the same base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,36 @@ object CryptoFacade {
def createCryptoContext(): CryptoContext = Platform.createContext()

/** Normalization ensures that any projective coordinate is 1, and therefore that the x, y
* coordinates reflect those of the equivalent point in an affine coordinate system.
* coordinates reflect those of the equivalent element in an affine coordinate system.
*
* @return a new ECPoint instance representing the same point, but with normalized coordinates
* @return a new ECPoint instance representing the same element, but with normalized coordinates
*/
def normalizePoint(p: Ecp): Ecp = Platform.normalizePoint(p)
def normalize(e: Ecp): Ecp = Platform.normalize(e)

/** Negates the given point by negating its y coordinate. */
def negatePoint(p: Ecp): Ecp = Platform.negatePoint(p)
/** Negates the given element by negating its y coordinate. */
def inverse(e: Ecp): Ecp = Platform.inverse(e)

/** Check if a point is infinity. */
def isInfinityPoint(p: Ecp): Boolean = Platform.isInfinityPoint(p)
/** Check if this is identity element. */
def isIdentity(e: Ecp): Boolean = Platform.isIdentity(e)

/** Exponentiate a point.
/** Exponentiate an element.
*
* @param p point to exponentiate
* @param e element 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 = Platform.exponentiatePoint(p, n)
def exponentiateElement(e: Ecp, n: BigInteger): Ecp = Platform.exponentiateElement(e, n)

/** Multiply two points.
*
* @param p1 first point
* @param p2 second point
* @return group multiplication (p1 * p2)
* @param e1 first element
* @param e2 second element
* @return group multiplication (e1 * e2)
*/
def multiplyPoints(p1: Ecp, p2: Ecp): Ecp = Platform.multiplyPoints(p1, p2)
def multiplyElements(e1: Ecp, e2: Ecp): Ecp = Platform.multiplyElements(e1, e2)

/** Return simplified string representation of the point (used only for debugging) */
def showPoint(p: Ecp): String = Platform.showPoint(p)
/** Return simplified string representation of element (used only for debugging) */
def showElement(e: Ecp): String = Platform.showElement(e)

/** Returns the sign of the field element. */
def signOf(p: ECFieldElem): Boolean = Platform.signOf(p)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ trait DlogGroup {

// if the given element is the identity, get a new random element
while ( {
CryptoFacade.isInfinityPoint(randGen)
CryptoFacade.isIdentity(randGen)
}) randGen = createRandomElement()

randGen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,16 @@ case class CGroupElement(override val wrappedValue: Ecp) extends GroupElement wi
override def getEncoded: Coll[Byte] =
dsl.Colls.fromArray(GroupElementSerializer.toBytes(wrappedValue))

override def isIdentity: Boolean = CryptoFacade.isInfinityPoint(wrappedValue)
override def isIdentity: Boolean = CryptoFacade.isIdentity(wrappedValue)

override def exp(k: BigInt): GroupElement =
dsl.GroupElement(CryptoFacade.exponentiatePoint(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue))
dsl.GroupElement(CryptoFacade.exponentiateElement(wrappedValue, k.asInstanceOf[CBigInt].wrappedValue))

override def multiply(that: GroupElement): GroupElement =
dsl.GroupElement(CryptoFacade.multiplyPoints(wrappedValue, that.asInstanceOf[CGroupElement].wrappedValue))
dsl.GroupElement(CryptoFacade.multiplyElements(wrappedValue, that.asInstanceOf[CGroupElement].wrappedValue))

override def negate: GroupElement =
dsl.GroupElement(CryptoFacade.negatePoint(wrappedValue))
dsl.GroupElement(CryptoFacade.inverse(wrappedValue))
}

/** A default implementation of [[SigmaProp]] interface.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ object Extensions {
"IDENTITY"
}
else {
CryptoFacade.showPoint(p)
CryptoFacade.showElement(p)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ object GroupElementSerializer extends SigmaSerializer[EcPointType, EcPointType]
private lazy val identityPointEncoding = Array.fill(encodingSize)(0: Byte)

override def serialize(point: EcPointType, w: SigmaByteWriter): Unit = {
val bytes = if (CryptoFacade.isInfinityPoint(point)) {
val bytes = if (CryptoFacade.isIdentity(point)) {
identityPointEncoding
} else {
val normed = CryptoFacade.normalizePoint(point)
val normed = CryptoFacade.normalize(point)
val ySign = CryptoFacade.signOf(CryptoFacade.getAffineYCoord(normed))
val X = CryptoFacade.encodeFieldElem(CryptoFacade.getXCoord(normed))
val PO = safeNewArray[Byte](X.length + 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ class CryptoFacadeSpecification extends AnyPropSpec with Matchers with ScalaChec
val vectors = Table(
("point", "expectedHex"),
(ctx.infinity(), "00"),
(CryptoFacade.exponentiatePoint(G, Q), "00"),
(CryptoFacade.exponentiateElement(G, Q), "00"),
(G, G_hex),
(CryptoFacade.exponentiatePoint(G, BigInteger.ONE), G_hex),
(CryptoFacade.exponentiatePoint(G, Q.subtract(BigInteger.ONE)), "0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")
(CryptoFacade.exponentiateElement(G, BigInteger.ONE), G_hex),
(CryptoFacade.exponentiateElement(G, Q.subtract(BigInteger.ONE)), "0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")
)
forAll (vectors) { (point, expectedHex) =>
val res = ErgoAlgos.encode(CryptoFacade.getASN1Encoding(point, true))
Expand All @@ -78,14 +78,14 @@ class CryptoFacadeSpecification extends AnyPropSpec with Matchers with ScalaChec
val ctx = CryptoFacade.createCryptoContext()

val inf = ctx.decodePoint(Array[Byte](0))
CryptoFacade.isInfinityPoint(inf) shouldBe true
CryptoFacade.isIdentity(inf) shouldBe true

val G = ctx.generator
ctx.decodePoint(ErgoAlgos.decode(G_hex).get) shouldBe G

val Q = ctx.order
val Q_minus_1 = Q.subtract(BigInteger.ONE)
val maxExp = CryptoFacade.exponentiatePoint(G, Q_minus_1)
val maxExp = CryptoFacade.exponentiateElement(G, Q_minus_1)
val maxExpBytes = ErgoAlgos.decode("0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798").get
ctx.decodePoint(maxExpBytes) shouldBe maxExp
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ class GroupLawsSpecification extends AnyPropSpec with ScalaCheckPropertyChecks w
// }

property("check test vectors") {
CryptoFacade.multiplyPoints(p1, p2) shouldBe
CryptoFacade.multiplyElements(p1, p2) shouldBe
Helpers.decodeECPoint("03de5e9c2806c05cd45a57d18c469743f42a0d2c84370b6662eb39d8a2990abed8")

CryptoFacade.exponentiatePoint(p1, group.order) shouldBe
CryptoFacade.exponentiateElement(p1, group.order) shouldBe
Helpers.decodeECPoint("000000000000000000000000000000000000000000000000000000000000000000")

CryptoFacade.exponentiatePoint(p1, group.order.add(BigInteger.ONE)) shouldBe
CryptoFacade.exponentiateElement(p1, group.order.add(BigInteger.ONE)) shouldBe
Helpers.decodeECPoint("0381c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac")

CryptoFacade.negatePoint(p1) shouldBe
CryptoFacade.inverse(p1) shouldBe
Helpers.decodeECPoint("0281c5275b1d50c39a0c36c4561c3a37bff1d87e37a9ad69eab029e426c0b1a8ac")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ class GroupElementSerializerSpecification extends SerializationSpecification {
val bytes = GroupElementSerializer.toBytes(ge.value)
bytes.length shouldBe CryptoConstants.EncodedGroupElementLength
val restored = GroupElementSerializer.parse(SigmaSerializer.startReader(bytes, 0))
CryptoFacade.getAffineXCoord(CryptoFacade.normalizePoint(restored)) shouldBe
CryptoFacade.getAffineXCoord(CryptoFacade.normalizePoint(ge.value))
CryptoFacade.getAffineYCoord(CryptoFacade.normalizePoint(restored)) shouldBe
CryptoFacade.getAffineYCoord(CryptoFacade.normalizePoint(ge.value))
CryptoFacade.getAffineXCoord(CryptoFacade.normalize(restored)) shouldBe
CryptoFacade.getAffineXCoord(CryptoFacade.normalize(ge.value))
CryptoFacade.getAffineYCoord(CryptoFacade.normalize(restored)) shouldBe
CryptoFacade.getAffineYCoord(CryptoFacade.normalize(ge.value))
}
}
}
Loading
Loading