Bouncy Castle Cryptography Library 1.87

org.bouncycastle.math.ec.sm9
Class SM9G2Point

java.lang.Object
  extended byorg.bouncycastle.math.ec.sm9.SM9G2Point

public class SM9G2Point
extends java.lang.Object

Affine point of the group G2 for SM9, the order-N subgroup of the sextic twist E'(F_p2): y^2 = x^3 + 5u (GM/T 0044.5-2016). Immutable. G1 by contrast is an ordinary prime-field curve, handled by the custom constant-time SM9P256V1Curve (see SM9Curve.G1).


Method Summary
 SM9G2Point add(SM9G2Point o)
           
static SM9G2Point decode(byte[] enc)
           
 boolean equals(java.lang.Object other)
           
 byte[] getEncoded()
          Uncompressed encoding 0x04 || x || y, each F_p2 coordinate written high dimension first (u-coefficient then constant), 32 bytes per F_p component; 129 bytes total.
 int hashCode()
           
 boolean isInfinity()
           
 boolean isInSubgroup()
          Whether this point lies in G2, the order-N subgroup of the twist curve - that is, whether [N]P is the point at infinity.
 SM9G2Point multiply(java.math.BigInteger k)
          Scalar multiplication, returning [k]this.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

isInfinity

public boolean isInfinity()

add

public SM9G2Point add(SM9G2Point o)

multiply

public SM9G2Point multiply(java.math.BigInteger k)
Scalar multiplication, returning [k]this. This point must be in G2, as every point decode() returns is.

The KGC runs it on its secrets - [ks]P2 for a signature master key and [t2]P2 for each encryption user key it derives - so four things are done for it: The scalar is blinded with a random multiple of N, which leaves [k]this unchanged for a point of G2, into a value of exactly 320 bits, the first of them set (see SM9Curve#blind): the multiplication runs the same steps from the same leading bit whatever k is, where a ladder over k itself stayed at the point at infinity, on cheaper arithmetic, through k's leading zero bits. It works in Jacobian coordinates, (X, Y, Z) standing for (X/Z^2, Y/Z^3), on values that carry a random factor drawn for the call, as the Miller loop starts from a random representative of its G2 argument: every value it works on carries a factor no two calls share. It inverts once, at the end, where the affine arithmetic inverted at every addition and doubling. It does not branch on the scalar's bits, nor choose by them the memory it reads, and its additions take the cases their formulas do not, an operand at infinity among them, by the same steps as any other. The F_p2 arithmetic underneath runs in constant time.

P2 itself, the instance SM9Curve.P2 - the base of both - runs Lim and Lee's comb, over a table of thirty-two multiples of P2 and their doubles that its first call makes and P2 keeps, 8 KB of points anyone can compute. The blinded scalar's bits fall into sixty-four columns of five, column c holding bits c, c + 64, c + 128, c + 192 and c + 256, and entry d of the table, for d = d0 + 2d1 + 4d2 + 8d3 + 16d4, is [1 + d0 + d1 2^64 + d2 2^128 + d3 2^192 + d4 2^256]P2. From the top column down, each column doubles the running point and adds the entry its bits pick out, read out of the table in full, through #lookup. The 1 in each entry's multiple makes entry 0 P2 rather than the point at infinity, which has no affine coordinates to hold; the entries the columns add then carry [2^64 - 1]P2 as well, so the comb is run over the blinded scalar less 2^64 - 1, which the blinding leaves positive. A call takes sixty-three doublings and sixty-three additions, where the ladder takes 320 doublings and 319 additions; the first also makes the table.

The entries are fixed points, whose coordinates would tell apart each column's entry as it is read and added. So each call draws a random non-zero lambda of F_p2 and carries the entries from (x, y) to (lambda^2 x, lambda^3 y), points of the twist y^2 = x^3 + lambda^6 5u, which that map takes this one to, and runs the comb there: the doubling and the addition do not involve the curve's constant, and a result (X, Y, Z) there is (X, Y, lambda Z) here. The copy of the table the factor is applied to is erased when the call ends; the table itself holds only multiples of P2. Each column's scan of the table starts at an entry drawn at random for it, one byte each of a sixty-four-byte draw the call makes, and wraps round, and the value it reads into is cleared first, so that the step of the scan that moves the column's entry into place does not give the column's bits away - see #lookup. And the running point may be at infinity, equal to the entry it adds, or its negation - for a small k such as 1 or 2 the blinding makes one of the first two happen in about one call in thirty-two - so the table holds each entry's double beside it, and the addition takes the double or the entry in place of the sum under masks (see #addEntry), with no doubling but the column's.

Any other point runs a Montgomery ladder, maintaining the invariant r1 = r0 + this: one addition and one doubling per bit, from (x Z^2, y Z^3, Z) for a random non-zero Z drawn for the call, its two running points exchanged at each bit, or not, by a masked swap that reads and writes both either way, and updated in the same steps whichever it did.


getEncoded

public byte[] getEncoded()
Uncompressed encoding 0x04 || x || y, each F_p2 coordinate written high dimension first (u-coefficient then constant), 32 bytes per F_p component; 129 bytes total.


decode

public static SM9G2Point decode(byte[] enc)

isInSubgroup

public boolean isInSubgroup()
Whether this point lies in G2, the order-N subgroup of the twist curve - that is, whether [N]P is the point at infinity.

Being on the twist curve is not enough. E'(F_p2) has order N*h2 with h2 = 2q - N, a 256-bit composite (13 divides it), so unlike G1 - whose cofactor is 1, which is what lets on-curve-and-not-infinity settle membership there - the twist carries points of other orders, and the pairing has no bilinear meaning on them: e(P1, A + B) does not equal e(P1, A) * e(P1, B) for an A outside G2, and the Miller loop can reach a degenerate division and raise ArithmeticException. Every encoded G2 point that arrives from outside the process is therefore checked here, and a caller that builds one through add(org.bouncycastle.math.ec.sm9.SM9G2Point) or multiply(java.math.BigInteger) can check it the same way.

The test is [t + 1]P + pi([t]P) + pi^2([t]P) = pi^3([2t]P), for the BN parameter t and pi(x, y) = (x^q gamma^-2, y^q gamma^-3), the q-power Frobenius carried to the twist and back, which gives the pairing its point Q1 (see SM9Pairing): whether f(pi)P = O for f(x) = (t + 1) + t x + t x^2 - 2t x^3. pi takes each point of G2 to its q-th multiple, and q = N + 6t^2, so on G2 f(pi) is [f(6t^2)], and N divides f(6t^2): every point of G2 passes. And pi satisfies pi^2 - tr pi + q = 0 on the whole twist, tr = 6t^2 + 1 being the trace of the Frobenius of E, so f(pi) is a0 + a1 pi there, a0 + a1 x being the remainder of f on division by x^2 - tr x + q, and a point that passes has, applying a0 + a1 (tr - pi) as well, [a0^2 + a0 a1 tr + a1^2 q]P = O. That multiplier is a multiple of N prime to h2, so the point's order divides N; N does not divide h2, so the points of E'(F_p2) whose order divides N are those of G2.

[t]P is formed by a chain of doublings and additions over the non-adjacent form of t, whose sixty-four digits have eleven that are not 0: sixty-three doublings and ten additions, where the ladder multiply(java.math.BigInteger) runs would take sixty-three doublings and sixty-two additions over the 63 bits of t (and [N]P a ladder over 256 bits). t being public, a ladder's regularity gains nothing here. [t + 1]P is one addition more. None of the chain's additions meets two equal operands (see add(org.bouncycastle.math.ec.sm9.SM9G2Point)), so none forms the double that #addAny forms each time to take that case; the rest is two additions through addAny, a doubling and three applications of pi, and the two sides are compared in Jacobian coordinates, so nothing is inverted. For no point of the twist other than infinity do those two additions meet an operand at infinity or two equal or opposite operands, or the comparison a side at infinity: each would need [t]P, [t + 1]P, [2t]P, or (t + 1) -+ t pi or (t + 1) + t pi -+ t pi^2 applied to P, to be O, and the point's order, which divides N h2, h2 = 2q - N, the order of the twist being N h2, would then divide the multiplier's norm, a0^2 + a0 a1 tr + a1^2 q for its remainder a0 + a1 pi, each of which is prime to N h2. The additions take them through addAny all the same. The cost, under a sixth of a pairing, is paid when a key is decoded, not per operation.


equals

public boolean equals(java.lang.Object other)

hashCode

public int hashCode()

Bouncy Castle Cryptography Library 1.87