Class GroupElement
- java.lang.Object
- 
- net.i2p.crypto.eddsa.math.GroupElement
 
- 
- All Implemented Interfaces:
- Serializable
 
 public class GroupElement extends Object implements Serializable A point $(x,y)$ on an EdDSA curve.Reviewed/commented by Bloody Rookie (nemproject@gmx.de) Literature: 
 [1] Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe and Bo-Yin Yang : High-speed high-security signatures
 [2] Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, Ed Dawson: Twisted Edwards Curves Revisited
 [3] Daniel J. Bernsteina, Tanja Lange: A complete set of addition laws for incomplete Edwards curves
 [4] Daniel J. Bernstein, Peter Birkner, Marc Joye, Tanja Lange and Christiane Peters: Twisted Edwards Curves
 [5] Christiane Pascale Peters: Curves, Codes, and Cryptography (PhD thesis)
 [6] Daniel J. Bernstein, Peter Birkner, Tanja Lange and Christiane Peters: Optimizing double-base elliptic-curve single-scalar multiplication- Since:
- 0.9.15
- Author:
- str4d
- See Also:
- Serialized Form
 
- 
- 
Nested Class SummaryNested Classes Modifier and Type Class Description static classGroupElement.RepresentationAvailable representations for a group element.
 - 
Field SummaryFields Modifier and Type Field Description (package private) CurvecurveVariable is package private only so that tests run.(package private) GroupElement[]dblPrecmpPrecomputed table fordoubleScalarMultiplyVariableTime(GroupElement, byte[], byte[]), filled if necessary.(package private) GroupElement[][]precmpPrecomputed table forscalarMultiply(byte[]), filled if necessary.(package private) GroupElement.RepresentationreprVariable is package private only so that tests run.(package private) FieldElementTVariable is package private only so that tests run.(package private) FieldElementXVariable is package private only so that tests run.(package private) FieldElementYVariable is package private only so that tests run.(package private) FieldElementZVariable is package private only so that tests run.
 - 
Constructor SummaryConstructors Constructor Description GroupElement(Curve curve, byte[] s)Creates a group element for a curve from a given encoded point.GroupElement(Curve curve, byte[] s, boolean precomputeSingleAndDouble)Creates a group element for a curve from a given encoded point.GroupElement(Curve curve, GroupElement.Representation repr, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T)Creates a group element for a curve, without any pre-computation.GroupElement(Curve curve, GroupElement.Representation repr, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T, boolean precomputeDouble)Creates a group element for a curve, with optional pre-computation.
 - 
Method SummaryAll Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description GroupElementadd(GroupElement q)GroupElement addition using the twisted Edwards addition law with extended coordinates (Hisil2008).static GroupElementcached(Curve curve, FieldElement YpX, FieldElement YmX, FieldElement Z, FieldElement T2d)Creates a new group element in CACHED representation.(package private) GroupElementcmov(GroupElement u, int b)Constant-time conditional move.GroupElementdbl()Doubles a given group element $p$ in $P^2$ or $P^3$ representation and returns the result in $P \times P$ representation.GroupElementdoubleScalarMultiplyVariableTime(GroupElement A, byte[] a, byte[] b)$r = a * A + b * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$, $b = b[0]+256*b[1]+\dots+256^{31} b[31]$ and $B$ is this point.booleanequals(Object obj)CurvegetCurve()Gets the curve of the group element.GroupElement.RepresentationgetRepresentation()Gets the representation of the group element.FieldElementgetT()Gets the $T$ value of the group element.FieldElementgetX()Gets the $X$ value of the group element.FieldElementgetY()Gets the $Y$ value of the group element.FieldElementgetZ()Gets the $Z$ value of the group element.inthashCode()booleanisOnCurve()Verify that a point is on its curve.booleanisOnCurve(Curve curve)Verify that a point is on the curve.GroupElementnegate()Negates this group element by subtracting it from the neutral group element.static GroupElementp1p1(Curve curve, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T)Creates a new group element in P1P1 representation.static GroupElementp2(Curve curve, FieldElement X, FieldElement Y, FieldElement Z)Creates a new group element in P2 representation.static GroupElementp3(Curve curve, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T)Creates a new group element in P3 representation, without pre-computation.static GroupElementp3(Curve curve, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T, boolean precomputeDoubleOnly)Creates a new group element in P3 representation, potentially with pre-computation.static GroupElementprecomp(Curve curve, FieldElement ypx, FieldElement ymx, FieldElement xy2d)Creates a new group element in PRECOMP representation.GroupElementscalarMultiply(byte[] a)$h = a * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$ and $B$ is this point.(package private) GroupElementselect(int pos, int b)Look up $16^i r_i B$ in the precomputed table.(package private) static byte[]slide(byte[] a)Calculates a sliding-windows base 2 representation for a given value $a$.GroupElementsub(GroupElement q)GroupElement subtraction using the twisted Edwards addition law with extended coordinates (Hisil2008).byte[]toByteArray()Converts the group element to an encoded point on the curve.GroupElementtoCached()Converts the group element to the CACHED representation.GroupElementtoP2()Converts the group element to the P2 representation.GroupElementtoP3()Converts the group element to the P3 representation.GroupElementtoP3PrecomputeDouble()Converts the group element to the P3 representation, with dblPrecmp populated.(package private) static byte[]toRadix16(byte[] a)Convert a to radix 16.StringtoString()
 
- 
- 
- 
Field Detail- 
curvefinal Curve curve Variable is package private only so that tests run.
 - 
reprfinal GroupElement.Representation repr Variable is package private only so that tests run.
 - 
Xfinal FieldElement X Variable is package private only so that tests run.
 - 
Yfinal FieldElement Y Variable is package private only so that tests run.
 - 
Zfinal FieldElement Z Variable is package private only so that tests run.
 - 
Tfinal FieldElement T Variable is package private only so that tests run.
 - 
precmpfinal GroupElement[][] precmp Precomputed table forscalarMultiply(byte[]), filled if necessary.Variable is package private only so that tests run. 
 - 
dblPrecmpfinal GroupElement[] dblPrecmp Precomputed table fordoubleScalarMultiplyVariableTime(GroupElement, byte[], byte[]), filled if necessary.Variable is package private only so that tests run. 
 
- 
 - 
Constructor Detail- 
GroupElementpublic GroupElement(Curve curve, GroupElement.Representation repr, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T) Creates a group element for a curve, without any pre-computation.- Parameters:
- curve- The curve.
- repr- The representation used to represent the group element.
- X- The $X$ coordinate.
- Y- The $Y$ coordinate.
- Z- The $Z$ coordinate.
- T- The $T$ coordinate.
 
 - 
GroupElementpublic GroupElement(Curve curve, GroupElement.Representation repr, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T, boolean precomputeDouble) Creates a group element for a curve, with optional pre-computation.- Parameters:
- curve- The curve.
- repr- The representation used to represent the group element.
- X- The $X$ coordinate.
- Y- The $Y$ coordinate.
- Z- The $Z$ coordinate.
- T- The $T$ coordinate.
- precomputeDouble- If true, populate dblPrecmp, else set to null.
- Since:
- 0.9.36
 
 - 
GroupElementpublic GroupElement(Curve curve, byte[] s) Creates a group element for a curve from a given encoded point. No pre-computation.A point $(x,y)$ is encoded by storing $y$ in bit 0 to bit 254 and the sign of $x$ in bit 255. $x$ is recovered in the following way: - $x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v}$ with $u = y^2 - 1$ and $v = d * y^2 + 1$.
- Setting $β = (u * v^3) * (u * v^7)^{((q - 5) / 8)}$ one has $β^2 = \pm(u / v)$.
- If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
- Set $x := β$.
- If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
 - Parameters:
- curve- The curve.
- s- The encoded point.
 
 - 
GroupElementpublic GroupElement(Curve curve, byte[] s, boolean precomputeSingleAndDouble) Creates a group element for a curve from a given encoded point. With optional pre-computation.A point $(x,y)$ is encoded by storing $y$ in bit 0 to bit 254 and the sign of $x$ in bit 255. $x$ is recovered in the following way: - $x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v}$ with $u = y^2 - 1$ and $v = d * y^2 + 1$.
- Setting $β = (u * v^3) * (u * v^7)^{((q - 5) / 8)}$ one has $β^2 = \pm(u / v)$.
- If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
- Set $x := β$.
- If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
 - Parameters:
- curve- The curve.
- s- The encoded point.
- precomputeSingleAndDouble- If true, populate both precmp and dblPrecmp, else set both to null.
- Since:
- 0.9.36
 
 
- 
 - 
Method Detail- 
p2public static GroupElement p2(Curve curve, FieldElement X, FieldElement Y, FieldElement Z) Creates a new group element in P2 representation.- Parameters:
- curve- The curve.
- X- The $X$ coordinate.
- Y- The $Y$ coordinate.
- Z- The $Z$ coordinate.
- Returns:
- The group element in P2 representation.
 
 - 
p3public static GroupElement p3(Curve curve, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T) Creates a new group element in P3 representation, without pre-computation.- Parameters:
- curve- The curve.
- X- The $X$ coordinate.
- Y- The $Y$ coordinate.
- Z- The $Z$ coordinate.
- T- The $T$ coordinate.
- Returns:
- The group element in P3 representation.
 
 - 
p3public static GroupElement p3(Curve curve, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T, boolean precomputeDoubleOnly) Creates a new group element in P3 representation, potentially with pre-computation.- Parameters:
- curve- The curve.
- X- The $X$ coordinate.
- Y- The $Y$ coordinate.
- Z- The $Z$ coordinate.
- T- The $T$ coordinate.
- precomputeDoubleOnly- If true, populate dblPrecmp, else set to null.
- Returns:
- The group element in P3 representation.
- Since:
- 0.9.36
 
 - 
p1p1public static GroupElement p1p1(Curve curve, FieldElement X, FieldElement Y, FieldElement Z, FieldElement T) Creates a new group element in P1P1 representation.- Parameters:
- curve- The curve.
- X- The $X$ coordinate.
- Y- The $Y$ coordinate.
- Z- The $Z$ coordinate.
- T- The $T$ coordinate.
- Returns:
- The group element in P1P1 representation.
 
 - 
precomppublic static GroupElement precomp(Curve curve, FieldElement ypx, FieldElement ymx, FieldElement xy2d) Creates a new group element in PRECOMP representation.- Parameters:
- curve- The curve.
- ypx- The $y + x$ value.
- ymx- The $y - x$ value.
- xy2d- The $2 * d * x * y$ value.
- Returns:
- The group element in PRECOMP representation.
 
 - 
cachedpublic static GroupElement cached(Curve curve, FieldElement YpX, FieldElement YmX, FieldElement Z, FieldElement T2d) Creates a new group element in CACHED representation.- Parameters:
- curve- The curve.
- YpX- The $Y + X$ value.
- YmX- The $Y - X$ value.
- Z- The $Z$ coordinate.
- T2d- The $2 * d * T$ value.
- Returns:
- The group element in CACHED representation.
 
 - 
getCurvepublic Curve getCurve() Gets the curve of the group element.- Returns:
- The curve.
 
 - 
getRepresentationpublic GroupElement.Representation getRepresentation() Gets the representation of the group element.- Returns:
- The representation.
 
 - 
getXpublic FieldElement getX() Gets the $X$ value of the group element. This is for most representation the projective $X$ coordinate.- Returns:
- The $X$ value.
 
 - 
getYpublic FieldElement getY() Gets the $Y$ value of the group element. This is for most representation the projective $Y$ coordinate.- Returns:
- The $Y$ value.
 
 - 
getZpublic FieldElement getZ() Gets the $Z$ value of the group element. This is for most representation the projective $Z$ coordinate.- Returns:
- The $Z$ value.
 
 - 
getTpublic FieldElement getT() Gets the $T$ value of the group element. This is for most representation the projective $T$ coordinate.- Returns:
- The $T$ value.
 
 - 
toByteArraypublic byte[] toByteArray() Converts the group element to an encoded point on the curve.- Returns:
- The encoded point as byte array.
 
 - 
toP2public GroupElement toP2() Converts the group element to the P2 representation.- Returns:
- The group element in the P2 representation.
 
 - 
toP3public GroupElement toP3() Converts the group element to the P3 representation.- Returns:
- The group element in the P3 representation.
 
 - 
toP3PrecomputeDoublepublic GroupElement toP3PrecomputeDouble() Converts the group element to the P3 representation, with dblPrecmp populated.- Returns:
- The group element in the P3 representation.
- Since:
- 0.9.36
 
 - 
toCachedpublic GroupElement toCached() Converts the group element to the CACHED representation.- Returns:
- The group element in the CACHED representation.
 
 - 
dblpublic GroupElement dbl() Doubles a given group element $p$ in $P^2$ or $P^3$ representation and returns the result in $P \times P$ representation. $r = 2 * p$ where $p = (X : Y : Z)$ or $p = (X : Y : Z : T)$$r$ in $P \times P$ representation: $r = ((X' : Z'), (Y' : T'))$ where - $X' = (X + Y)^2 - (Y^2 + X^2)$
- $Y' = Y^2 + X^2$
- $Z' = y^2 - X^2$
- $T' = 2 * Z^2 - (y^2 - X^2)$
 $r$ converted from $P \times P$ to $P^2$ representation: $r = (X'' : Y'' : Z'')$ where - $X'' = X' * Z' = ((X + Y)^2 - Y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$
- $Y'' = Y' * T' = (Y^2 + X^2) * (2 * Z^2 - (y^2 - X^2))$
- $Z'' = Z' * T' = (y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$
 Formula for the $P^2$ representation is in agreement with the formula given in [4] page 12 (with $a = -1$) up to a common factor -1 which does not matter: $$ B = (X + Y)^2; C = X^2; D = Y^2; E = -C = -X^2; F := E + D = Y^2 - X^2; H = Z^2; J = F − 2 * H; \\ X3 = (B − C − D) · J = X' * (-T'); \\ Y3 = F · (E − D) = Z' * (-Y'); \\ Z3 = F · J = Z' * (-T'). $$ - Returns:
- The P1P1 representation
 
 - 
addpublic GroupElement add(GroupElement q) GroupElement addition using the twisted Edwards addition law with extended coordinates (Hisil2008).this must be in $P^3$ representation and $q$ in CACHED representation. $r = p + q$ where $p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z, q.T) = (Y2 + X2, Y2 - X2, Z2, 2 * d * T2)$ $r$ in $P \times P$ representation: - $X' = (Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)$
- $Y' = (Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)$
- $Z' = 2 * Z1 * Z2 + 2 * d * T1 * T2$
- $T' = 2 * Z1 * T2 - 2 * d * T1 * T2$
 Setting $A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2$ we get - $X' = (B - A)$
- $Y' = (B + A)$
- $Z' = (D + C)$
- $T' = (D - C)$
 Same result as in madd(net.i2p.crypto.eddsa.math.GroupElement)(up to a common factor which does not matter).- Parameters:
- q- the CACHED representation of the GroupElement to add.
- Returns:
- the P1P1 representation of the result.
 
 - 
subpublic GroupElement sub(GroupElement q) GroupElement subtraction using the twisted Edwards addition law with extended coordinates (Hisil2008).$r = p - q$ Negating $q$ means negating the value of the coordinate $X2$ and $T2$. The formula is in accordance to the above addition.- Parameters:
- q- the PRECOMP representation of the GroupElement to subtract.
- Returns:
- the P1P1 representation of the result.
 
 - 
negatepublic GroupElement negate() Negates this group element by subtracting it from the neutral group element.TODO-CR BR: why not simply negate the coordinates $X$ and $T$? - Returns:
- The negative of this group element.
 
 - 
toRadix16static byte[] toRadix16(byte[] a) Convert a to radix 16.Method is package private only so that tests run. - Parameters:
- a- $= a[0]+256*a[1]+...+256^{31} a[31]$
- Returns:
- 64 bytes, each between -8 and 7
 
 - 
cmovGroupElement cmov(GroupElement u, int b) Constant-time conditional move.Replaces this with $u$ if $b == 1$. 
 Replaces this with this if $b == 0$.Method is package private only so that tests run. - Parameters:
- u- The group element to return if $b == 1$.
- b- in $\{0, 1\}$
- Returns:
- $u$ if $b == 1$; this if $b == 0$. Results undefined if $b$ is not in $\{0, 1\}$.
 
 - 
selectGroupElement select(int pos, int b) Look up $16^i r_i B$ in the precomputed table.No secret array indices, no secret branching. Constant time. Must have previously precomputed. Method is package private only so that tests run. - Parameters:
- pos- $= i/2$ for $i$ in $\{0, 2, 4,..., 62\}$
- b- $= r_i$
- Returns:
- the GroupElement
 
 - 
scalarMultiplypublic GroupElement scalarMultiply(byte[] a) $h = a * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$ and $B$ is this point. If its lookup table has not been precomputed, it will be at the start of the method (and cached for later calls). Constant time.Preconditions: (TODO: Check this applies here) $a[31] \le 127$ - Parameters:
- a- $= a[0]+256*a[1]+\dots+256^{31} a[31]$
- Returns:
- the GroupElement
 
 - 
slidestatic byte[] slide(byte[] a) Calculates a sliding-windows base 2 representation for a given value $a$. To learn more about it see [6] page 8.Output: $r$ which satisfies $a = r0 * 2^0 + r1 * 2^1 + \dots + r255 * 2^{255}$ with $ri$ in $\{-15, -13, -11, -9, -7, -5, -3, -1, 0, 1, 3, 5, 7, 9, 11, 13, 15\}$ Method is package private only so that tests run. - Parameters:
- a- $= a[0]+256*a[1]+\dots+256^{31} a[31]$.
- Returns:
- The byte array $r$ in the above described form.
 
 - 
doubleScalarMultiplyVariableTimepublic GroupElement doubleScalarMultiplyVariableTime(GroupElement A, byte[] a, byte[] b) $r = a * A + b * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$, $b = b[0]+256*b[1]+\dots+256^{31} b[31]$ and $B$ is this point.$A$ must have been previously precomputed. - Parameters:
- A- in P3 representation.
- a- $= a[0]+256*a[1]+\dots+256^{31} a[31]$
- b- $= b[0]+256*b[1]+\dots+256^{31} b[31]$
- Returns:
- the GroupElement
 
 - 
isOnCurvepublic boolean isOnCurve() Verify that a point is on its curve.- Returns:
- true if the point lies on its curve.
 
 - 
isOnCurvepublic boolean isOnCurve(Curve curve) Verify that a point is on the curve.- Parameters:
- curve- The curve to check.
- Returns:
- true if the point lies on the curve.
 
 
- 
 
-