Java tutorial
//package com.java2s; import java.math.BigInteger; public class Main { /** * Computes the Window NAF (non-adjacent Form) of an integer. * @param width The width <code>w</code> of the Window NAF. The width is * defined as the minimal number <code>w</code>, such that for any * <code>w</code> consecutive digits in the resulting representation, at * most one is non-zero. * @param k The integer of which the Window NAF is computed. * @return The Window NAF of the given width, such that the following holds: * <code>k = ∑<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup> * </code>, where the <code>k<sub>i</sub></code> denote the elements of the * returned <code>byte[]</code>. */ public static byte[] generateWindowNaf(int width, BigInteger k) { if (width == 2) { return generateNaf(k); } if (width < 2 || width > 8) { throw new IllegalArgumentException("'width' must be in the range [2, 8]"); } byte[] wnaf = new byte[k.bitLength() + 1]; // 2^width and a mask and sign bit set accordingly int pow2 = 1 << width; int mask = pow2 - 1; int sign = pow2 >>> 1; boolean carry = false; int length = 0, pos = 0; while (pos <= k.bitLength()) { if (k.testBit(pos) == carry) { ++pos; continue; } k = k.shiftRight(pos); int digit = k.intValue() & mask; if (carry) { ++digit; } carry = (digit & sign) != 0; if (carry) { digit -= pow2; } length += (length > 0) ? pos - 1 : pos; wnaf[length++] = (byte) digit; pos = width; } // Reduce the WNAF array to its actual length if (wnaf.length > length) { wnaf = trim(wnaf, length); } return wnaf; } public static byte[] generateNaf(BigInteger k) { BigInteger _3k = k.shiftLeft(1).add(k); int digits = _3k.bitLength() - 1; byte[] naf = new byte[digits]; for (int i = 1; i <= digits; ++i) { boolean _3kBit = _3k.testBit(i); boolean kBit = k.testBit(i); naf[i - 1] = (byte) (_3kBit == kBit ? 0 : kBit ? -1 : 1); } return naf; } private static byte[] trim(byte[] a, int length) { byte[] result = new byte[length]; System.arraycopy(a, 0, result, 0, result.length); return result; } private static int[] trim(int[] a, int length) { int[] result = new int[length]; System.arraycopy(a, 0, result, 0, result.length); return result; } }