3

I need a short addition chain for a number $n>2^{100}$ in order to implement a fast exponentiation. The memory footprint is not important.

Finding an optimal chain for a large number $n$ is difficult (and considered by some to be an NP-complete problem). However, many heuristics to find good but suboptimal chains have been proposed in literature.

Is there any library to search for short chains, or do I have to implement something by myself? (All the tools I found so far only seem to work for small numbers.)

Many thanks!


Update:

  • I implemented the binary approach, but the resulting chain was rather long.

  • I then implemented the algorithm based on continued fractions described on pages 161-162 in the "Handbook of Elliptic and Hyperelliptic Curve Cryptography" by Cohen et al., and the resulting chain was already 40% shorter. I will just use this chain for my implementation. Here is the corresponding source code:


from math import *

def add(v,j):
    return v+[v[len(v)-1]+j]

def cross(v,w):
    r=v
    vs=v[len(v)-1]
    for y in w[1:]:
        r=r+[y*vs]
    return r


def is2l(x):
    l=log2(x)
    if 2**l==x:
        return l
    return -1

def log2(x):
    l=0
    while 2**(l+1)<=x:
        l=l+1
    return l

def minchain(n):
    l=is2l(n)
    if l!=-1:
        a=[]
        for i in range(l+1):
            a+=[2**i]
        return a
    if n==3:
        return [1,2,3]
    return chain(n,n/int(2**ceil(log2(n)/2.0)))

def chain(n,k):
#    print "chain(",n,",",k,")"
    q=n/k
    r=n%k
    if r==0:
        return cross(minchain(k),minchain(q))
    else:
        return add(cross(chain(k,r),minchain(q)),r)

def sequence(c):
    for i in range(len(c)):
        a=c[i]
        if a==1:
            print "a["+str(i)+"]=x"
        else:
            for j in range(i*i):
                if (j%i)<(j/i) and c[j%i]+c[j/i]==a:
                    print "a["+str(i)+"]=a["+str(j%i)+"]*a["+str(j/i)+"]"
                if (j%i)==(j/i) and c[j%i]+c[j/i]==a:
                    print "a["+str(i)+"]=square(a["+str(j%i)+"])"


sequence(minchain(2**127-1))

  • Probably the more complex (e.g. backtracking or genetic) algorithms described in the literature will find even shorter chains. However, I will not implement these myself.
Chris
  • 989
  • 6
  • 15
  • 1
    what do you mean by "addition chain"? Also, what is the relationship to cryptography? – mikeazo Jul 27 '15 at 16:58
  • What do you mean by 'good'? The simple-minded binary method gives a decent one (within 50% of optimal for random inputs), and is completely trivial to compute. If that's not good enough, how close to optimal are you demanding? – poncho Jul 27 '15 at 18:39
  • @mikeazo: I added a link and some explanation to clarify the question. I hope it is better now. – Chris Jul 27 '15 at 19:13
  • @Chris, I suggest another edit. Questions asking for tools are generally not well received on this site. Also, you still haven't explained the relationship to cryptography. – mikeazo Jul 27 '15 at 19:19
  • @poncho: Lets say, I can invest a few hours (or days) of computing time into the search and I want the chain to be as good as possible. – Chris Jul 27 '15 at 19:29
  • @mikeazo: I added 'in order to implement a fast exponentiation' to explain the relationship to cryptography. – Chris Jul 27 '15 at 19:33
  • What is "good" : shortest, fastest, constant time , least memory footprint, bignum-library-independent, windowing-like ? The least memory footprint is probably the binary addition chain, and probably is the shortest code too. – Pierre Jul 27 '15 at 20:48
  • @Pierre: Ok, thanks! Actually I want a short chain to implement a fast exponentiation. The memory footprint is not important. I was hoping to find something better than the binary method. But maybe the differences are negligible - I don't know yet. – Chris Jul 27 '15 at 21:38
  • As mentioned in introduction of http://cr.yp.to/papers/pippenger.pdf , minimizing exponentiation time is not exactly the same problem as minimizing the chain length. – Pierre Jul 28 '15 at 00:33
  • The reason tools only work for small numbers is explained in https://en.wikipedia.org/wiki/Addition-chain_exponentiation : "shortest addition-chain exponentiation is primarily used for small fixed exponents for which a shortest chain can be precomputed and is not too large". If your exponent is extremely large, and random, search the optimal addition chain might exceed the modular exponentiation computing time ... The memory footprint could reach the one required by Yao algorithm https://en.wikipedia.org/wiki/Exponentiation_by_squaring#Yao.27s_method , without the NP time at all. – Pierre Jul 28 '15 at 00:50
  • 2
    @Pierre: When the multiplication time is constant, minimizing exponentiation time is exactly the same problem as minimizing the chain length. – Chris Jul 28 '15 at 01:43
  • There is an element of response there : http://stackoverflow.com/questions/10140052/how-can-you-compute-a-shortest-addition-chain-for-an-arbitrary-n-600-within-o – Pierre Jul 28 '15 at 01:55
  • @Pierre: The problem is about precomputing a chain for a large and fixed exponent. Obviously one cannot find the shortest chain for a large exponent (NP-completeness). This is done in order to compute the inverse of an element. – Chris Jul 28 '15 at 02:02
  • @Chris Do you happen to have a reference at hand for that problem being NP-complete? – yyyyyyy Jul 28 '15 at 05:12
  • 1
    I just want to add an important comment for everyone reading this. I assume that this chain is for exponentiation with a PRIVATE EXPONENT. It seems to me to be very likely that using such a chain may leak timing information about the exponent. So, I would be very wary of this. – Yehuda Lindell Jul 28 '15 at 05:52
  • A reference to some of the best solutions known to the problem of addition chains (without subtraction) is Daniel Bernstein's Pippenger's exponentiation algorithm – fgrieu Jul 28 '15 at 06:06
  • @yyyyyyy: I don't think anybody has proven NP-completeness; however many people seem to consider it is. In Bernstein's paper "Pippenger's exponentiation algorithm" there is a paragraph on this. – Chris Jul 28 '15 at 07:27
  • 2
    @Yehuda Lindell: Indeed, using this technique with a private exponent would be dangerous. One can however use it to compute the inverse of an element in $F_p$, using the public exponent $p-2$. – Chris Jul 28 '15 at 07:48
  • @Chris, now that you've implemented it, are you going to open source it? If you do, add a link in the question. While the question was put on hold, since it has an upvote, it won't be deleted. Could be useful to someone in the future. – mikeazo Jul 28 '15 at 13:32
  • 1
    @mikeazo: I pasted the source code directly into the question. – Chris Jul 28 '15 at 23:41

0 Answers0