1
$\begingroup$

Just for the sake of learning, I'm attempting to write an ECDSA implementation in Java.

I have what I believe is a correct implementation for point addition and doubling, but I'm not sure how to implement point multiplication - Every online description I've found says to use an algorithm like this:

public static Point pointMultiply(BigInteger kin, Point a, Curve curve) {
        Point r = new Point(BigInteger.ZERO, BigInteger.ONE);

        BigInteger k = kin.mod(curve.getN());
        int length = k.bitLength();

        byte[] binarray = new byte[length];

        for(int i = 0; i < length; i++) {
            binarray[i] = k.mod(BigInteger.TWO).byteValue();
            k = k.divide(BigInteger.TWO);
        }

        for(int i = length - 1; i >= 0; i--) {
            r = pointAdd(r, r, curve);

            if(binarray[i] == 1) {
                r = pointAdd(r, a, curve);
            }
        }

        return r;
    }

Except all of those descriptions define r as the point at infinity. That's great, except my point doubling/adding code requires actual values in order to operate on the point. How do I find an actual value for that point so I can manipulate it, and if there is no defined value, how would I implement point multiplication?

Most of the descriptions of the point at infinity I've found say that it either isn't a real point and is some sort of abstract thing (in which case I don't understand how one can manipulate it) or that it has coordinates of (0,1), which does not give me a correct pubkey when I test it against BouncyCastle.

$\endgroup$
  • $\begingroup$ I am not answering your question here, but I want to comment that the presented code is not side channel safe, and is vulnerable to very simply timing attacks. This is because the number of operations depends on the secret value. Thus, this is a very unsafe implementation. I suggest reading more about this; one place to start is the paper Remote Timing Attacks are Still Practical. In general, it is very hard to write side-channel proof code, and this is just one issue. $\endgroup$ – Yehuda Lindell Jun 21 '18 at 10:46
  • $\begingroup$ This is, for the moment, intentional - I wanted a simplistic implementation before attempting to move on to make it side channel resistant. $\endgroup$ – Lev Knoblock Jun 21 '18 at 12:33
2
$\begingroup$

It is unfortunate that the code for point addition does not support a representation for the point at infinity; but one can get away with it by using the left-to-right binary exponentiation (as the question's code does), skipping the leftmost bit set and starting from a rather than from the point at infinity.

For example, that computes $13\times A=1101_b\times A$ as

  • $R\gets A$ (handling the leftmost bit in a most simple way)
  • $R\gets R+R=2\times A$ and $R\gets A+R=3\times A$ (second bit from the left which is 1)
  • $R\gets R+R=6\times A$ (third bit which is 0)
  • $R\gets R+R=12\times A$ and $R\gets A+R=13\times A$ (fourth/last bit which is 1).

The code becomes as follows (I made basic simplifications, but did not even try to compile).

public static Point pointMultiply(BigInteger kin, Point a, Curve curve) {

    BigInteger k = kin.mod(curve.getN());
    int length = k.bitLength();
    if (length != 0) { // kin reduced modulo the curve's order is not zero
        Point r = a;
        for(int i = length-2; i >= 0; --i) { // skip the high-order bit!
            r = pointAdd(r, r, curve);
            if (k.testBit(i)) { // test bit i of k
                r = pointAdd(r, a, curve);
            }
        }
        return r; // that's our result
    }
    // result is the point at infinity, act as appropriate
}

As long as you do not hit the point at infinity in one of the computations, that will do. In particular that will always do if kin is positive and less than the order of a, and in cryptographic applications absent errors and attacks. Otherwise, pointAdd can face a situation where it receives opposite inputs and must produce the point at infinity, or throw an exception.

Speed left aside, the code is adequate for some cryptographic operations, such as ECDSA signature verification. It is not adequate for signature generation, Diffie-Hellman key exchange, or more generally when secrets are handled, because it is sensitive to various side channels (including timing, SPA..) and perhaps injection of values triggering appearance of the point at infinity.

$\endgroup$
4
$\begingroup$

How do I find an actual value for that point so I can manipulate it

You don't, because the articles you read are right, there is no affine representation for the point at infinity. The usual approach is then to have a flag or something in your point class that indicates whether it currently holds the point at infinity and trigger special behavior on the additon and doubling routines when this flag is set.

that it has coordinates of (0,1)

This is true for curves in so-called Edwards form with $c=1$ (which is quite usual).

how would I implement point multiplication?

In serious implementations projective coordinates or jacobian coordinates are used for these calculations and the point at infinity does have a representation using these coordinates with which you can work more easily.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.