summary refs log tree commit diff
path: root/crypto/src/math/ec/abc/Tnaf.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/math/ec/abc/Tnaf.cs')
-rw-r--r--crypto/src/math/ec/abc/Tnaf.cs834
1 files changed, 834 insertions, 0 deletions
diff --git a/crypto/src/math/ec/abc/Tnaf.cs b/crypto/src/math/ec/abc/Tnaf.cs
new file mode 100644
index 000000000..225fc3075
--- /dev/null
+++ b/crypto/src/math/ec/abc/Tnaf.cs
@@ -0,0 +1,834 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC.Abc
+{
+	/**
+	* Class holding methods for point multiplication based on the window
+	* τ-adic nonadjacent form (WTNAF). The algorithms are based on the
+	* paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves"
+	* by Jerome A. Solinas. The paper first appeared in the Proceedings of
+	* Crypto 1997.
+	*/
+	internal class Tnaf
+	{
+		private static readonly BigInteger MinusOne = BigInteger.One.Negate();
+		private static readonly BigInteger MinusTwo = BigInteger.Two.Negate();
+		private static readonly BigInteger MinusThree = BigInteger.Three.Negate();
+		private static readonly BigInteger Four = BigInteger.ValueOf(4);
+
+		/**
+		* The window width of WTNAF. The standard value of 4 is slightly less
+		* than optimal for running time, but keeps space requirements for
+		* precomputation low. For typical curves, a value of 5 or 6 results in
+		* a better running time. When changing this value, the
+		* <code>&#945;<sub>u</sub></code>'s must be computed differently, see
+		* e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson,
+		* Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004,
+		* p. 121-122
+		*/
+		public const sbyte Width = 4;
+
+		/**
+		* 2<sup>4</sup>
+		*/
+		public const sbyte Pow2Width = 16;
+
+		/**
+		* The <code>&#945;<sub>u</sub></code>'s for <code>a=0</code> as an array
+		* of <code>ZTauElement</code>s.
+		*/
+		public static readonly ZTauElement[] Alpha0 =
+		{
+			null,
+			new ZTauElement(BigInteger.One, BigInteger.Zero), null,
+			new ZTauElement(MinusThree, MinusOne), null,
+			new ZTauElement(MinusOne, MinusOne), null,
+			new ZTauElement(BigInteger.One, MinusOne), null
+		};
+
+		/**
+		* The <code>&#945;<sub>u</sub></code>'s for <code>a=0</code> as an array
+		* of TNAFs.
+		*/
+		public static readonly sbyte[][] Alpha0Tnaf =
+		{
+			null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, 1}
+		};
+
+		/**
+		* The <code>&#945;<sub>u</sub></code>'s for <code>a=1</code> as an array
+		* of <code>ZTauElement</code>s.
+		*/
+		public static readonly ZTauElement[] Alpha1 =
+		{
+			null,
+			new ZTauElement(BigInteger.One, BigInteger.Zero), null,
+			new ZTauElement(MinusThree, BigInteger.One), null,
+			new ZTauElement(MinusOne, BigInteger.One), null,
+			new ZTauElement(BigInteger.One, BigInteger.One), null
+		};
+
+		/**
+		* The <code>&#945;<sub>u</sub></code>'s for <code>a=1</code> as an array
+		* of TNAFs.
+		*/
+		public static readonly sbyte[][] Alpha1Tnaf =
+		{
+			null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, -1}
+		};
+
+		/**
+		* Computes the norm of an element <code>&#955;</code> of
+		* <code><b>Z</b>[&#964;]</code>.
+		* @param mu The parameter <code>&#956;</code> of the elliptic curve.
+		* @param lambda The element <code>&#955;</code> of
+		* <code><b>Z</b>[&#964;]</code>.
+		* @return The norm of <code>&#955;</code>.
+		*/
+		public static BigInteger Norm(sbyte mu, ZTauElement lambda)
+		{
+			BigInteger norm;
+
+			// s1 = u^2
+			BigInteger s1 = lambda.u.Multiply(lambda.u);
+
+			// s2 = u * v
+			BigInteger s2 = lambda.u.Multiply(lambda.v);
+
+			// s3 = 2 * v^2
+			BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1);
+
+			if (mu == 1)
+			{
+				norm = s1.Add(s2).Add(s3);
+			}
+			else if (mu == -1)
+			{
+				norm = s1.Subtract(s2).Add(s3);
+			}
+			else
+			{
+				throw new ArgumentException("mu must be 1 or -1");
+			}
+
+			return norm;
+		}
+
+		/**
+		* Computes the norm of an element <code>&#955;</code> of
+		* <code><b>R</b>[&#964;]</code>, where <code>&#955; = u + v&#964;</code>
+		* and <code>u</code> and <code>u</code> are real numbers (elements of
+		* <code><b>R</b></code>). 
+		* @param mu The parameter <code>&#956;</code> of the elliptic curve.
+		* @param u The real part of the element <code>&#955;</code> of
+		* <code><b>R</b>[&#964;]</code>.
+		* @param v The <code>&#964;</code>-adic part of the element
+		* <code>&#955;</code> of <code><b>R</b>[&#964;]</code>.
+		* @return The norm of <code>&#955;</code>.
+		*/
+		public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v)
+		{
+			SimpleBigDecimal norm;
+
+			// s1 = u^2
+			SimpleBigDecimal s1 = u.Multiply(u);
+
+			// s2 = u * v
+			SimpleBigDecimal s2 = u.Multiply(v);
+
+			// s3 = 2 * v^2
+			SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1);
+
+			if (mu == 1)
+			{
+				norm = s1.Add(s2).Add(s3);
+			}
+			else if (mu == -1)
+			{
+				norm = s1.Subtract(s2).Add(s3);
+			}
+			else
+			{
+				throw new ArgumentException("mu must be 1 or -1");
+			}
+
+			return norm;
+		}
+
+		/**
+		* Rounds an element <code>&#955;</code> of <code><b>R</b>[&#964;]</code>
+		* to an element of <code><b>Z</b>[&#964;]</code>, such that their difference
+		* has minimal norm. <code>&#955;</code> is given as
+		* <code>&#955; = &#955;<sub>0</sub> + &#955;<sub>1</sub>&#964;</code>.
+		* @param lambda0 The component <code>&#955;<sub>0</sub></code>.
+		* @param lambda1 The component <code>&#955;<sub>1</sub></code>.
+		* @param mu The parameter <code>&#956;</code> of the elliptic curve. Must
+		* equal 1 or -1.
+		* @return The rounded element of <code><b>Z</b>[&#964;]</code>.
+		* @throws ArgumentException if <code>lambda0</code> and
+		* <code>lambda1</code> do not have same scale.
+		*/
+		public static ZTauElement Round(SimpleBigDecimal lambda0,
+			SimpleBigDecimal lambda1, sbyte mu)
+		{
+			int scale = lambda0.Scale;
+			if (lambda1.Scale != scale)
+				throw new ArgumentException("lambda0 and lambda1 do not have same scale");
+
+			if (!((mu == 1) || (mu == -1)))
+				throw new ArgumentException("mu must be 1 or -1");
+
+			BigInteger f0 = lambda0.Round();
+			BigInteger f1 = lambda1.Round();
+
+			SimpleBigDecimal eta0 = lambda0.Subtract(f0);
+			SimpleBigDecimal eta1 = lambda1.Subtract(f1);
+
+			// eta = 2*eta0 + mu*eta1
+			SimpleBigDecimal eta = eta0.Add(eta0);
+			if (mu == 1)
+			{
+				eta = eta.Add(eta1);
+			}
+			else
+			{
+				// mu == -1
+				eta = eta.Subtract(eta1);
+			}
+
+			// check1 = eta0 - 3*mu*eta1
+			// check2 = eta0 + 4*mu*eta1
+			SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1);
+			SimpleBigDecimal fourEta1 = threeEta1.Add(eta1);
+			SimpleBigDecimal check1;
+			SimpleBigDecimal check2;
+			if (mu == 1)
+			{
+				check1 = eta0.Subtract(threeEta1);
+				check2 = eta0.Add(fourEta1);
+			}
+			else
+			{
+				// mu == -1
+				check1 = eta0.Add(threeEta1);
+				check2 = eta0.Subtract(fourEta1);
+			}
+
+			sbyte h0 = 0;
+			sbyte h1 = 0;
+
+			// if eta >= 1
+			if (eta.CompareTo(BigInteger.One) >= 0)
+			{
+				if (check1.CompareTo(MinusOne) < 0)
+				{
+					h1 = mu;
+				}
+				else
+				{
+					h0 = 1;
+				}
+			}
+			else
+			{
+				// eta < 1
+				if (check2.CompareTo(BigInteger.Two) >= 0)
+				{
+					h1 = mu;
+				}
+			}
+
+			// if eta < -1
+			if (eta.CompareTo(MinusOne) < 0)
+			{
+				if (check1.CompareTo(BigInteger.One) >= 0)
+				{
+					h1 = (sbyte)-mu;
+				}
+				else
+				{
+					h0 = -1;
+				}
+			}
+			else
+			{
+				// eta >= -1
+				if (check2.CompareTo(MinusTwo) < 0)
+				{
+					h1 = (sbyte)-mu;
+				}
+			}
+
+			BigInteger q0 = f0.Add(BigInteger.ValueOf(h0));
+			BigInteger q1 = f1.Add(BigInteger.ValueOf(h1));
+			return new ZTauElement(q0, q1);
+		}
+
+		/**
+		* Approximate division by <code>n</code>. For an integer
+		* <code>k</code>, the value <code>&#955; = s k / n</code> is
+		* computed to <code>c</code> bits of accuracy.
+		* @param k The parameter <code>k</code>.
+		* @param s The curve parameter <code>s<sub>0</sub></code> or
+		* <code>s<sub>1</sub></code>.
+		* @param vm The Lucas Sequence element <code>V<sub>m</sub></code>.
+		* @param a The parameter <code>a</code> of the elliptic curve.
+		* @param m The bit length of the finite field
+		* <code><b>F</b><sub>m</sub></code>.
+		* @param c The number of bits of accuracy, i.e. the scale of the returned
+		* <code>SimpleBigDecimal</code>.
+		* @return The value <code>&#955; = s k / n</code> computed to
+		* <code>c</code> bits of accuracy.
+		*/
+		public static SimpleBigDecimal ApproximateDivisionByN(BigInteger k,
+			BigInteger s, BigInteger vm, sbyte a, int m, int c)
+		{
+			int _k = (m + 5)/2 + c;
+			BigInteger ns = k.ShiftRight(m - _k - 2 + a);
+
+			BigInteger gs = s.Multiply(ns);
+
+			BigInteger hs = gs.ShiftRight(m);
+
+			BigInteger js = vm.Multiply(hs);
+
+			BigInteger gsPlusJs = gs.Add(js);
+			BigInteger ls = gsPlusJs.ShiftRight(_k-c);
+			if (gsPlusJs.TestBit(_k-c-1))
+			{
+				// round up
+				ls = ls.Add(BigInteger.One);
+			}
+
+			return new SimpleBigDecimal(ls, c);
+		}
+
+		/**
+		* Computes the <code>&#964;</code>-adic NAF (non-adjacent form) of an
+		* element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
+		* @param mu The parameter <code>&#956;</code> of the elliptic curve.
+		* @param lambda The element <code>&#955;</code> of
+		* <code><b>Z</b>[&#964;]</code>.
+		* @return The <code>&#964;</code>-adic NAF of <code>&#955;</code>.
+		*/
+		public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda)
+		{
+			if (!((mu == 1) || (mu == -1))) 
+				throw new ArgumentException("mu must be 1 or -1");
+
+			BigInteger norm = Norm(mu, lambda);
+
+			// Ceiling of log2 of the norm 
+			int log2Norm = norm.BitLength;
+
+			// If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
+			int maxLength = log2Norm > 30 ? log2Norm + 4 : 34;
+
+			// The array holding the TNAF
+			sbyte[] u = new sbyte[maxLength];
+			int i = 0;
+
+			// The actual length of the TNAF
+			int length = 0;
+
+			BigInteger r0 = lambda.u;
+			BigInteger r1 = lambda.v;
+
+			while(!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
+			{
+				// If r0 is odd
+				if (r0.TestBit(0)) 
+				{
+					u[i] = (sbyte) BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue;
+
+					// r0 = r0 - u[i]
+					if (u[i] == 1)
+					{
+						r0 = r0.ClearBit(0);
+					}
+					else
+					{
+						// u[i] == -1
+						r0 = r0.Add(BigInteger.One);
+					}
+					length = i;
+				}
+				else
+				{
+					u[i] = 0;
+				}
+
+				BigInteger t = r0;
+				BigInteger s = r0.ShiftRight(1);
+				if (mu == 1) 
+				{
+					r0 = r1.Add(s);
+				}
+				else
+				{
+					// mu == -1
+					r0 = r1.Subtract(s);
+				}
+
+				r1 = t.ShiftRight(1).Negate();
+				i++;
+			}
+
+			length++;
+
+			// Reduce the TNAF array to its actual length
+			sbyte[] tnaf = new sbyte[length];
+			Array.Copy(u, 0, tnaf, 0, length);
+			return tnaf;
+		}
+
+		/**
+		* Applies the operation <code>&#964;()</code> to an
+		* <code>F2mPoint</code>. 
+		* @param p The F2mPoint to which <code>&#964;()</code> is applied.
+		* @return <code>&#964;(p)</code>
+		*/
+		public static F2mPoint Tau(F2mPoint p)
+		{
+			if (p.IsInfinity)
+				return p;
+
+			ECFieldElement x = p.X;
+			ECFieldElement y = p.Y;
+
+			return new F2mPoint(p.Curve, x.Square(), y.Square(), p.IsCompressed);
+		}
+
+		/**
+		* Returns the parameter <code>&#956;</code> of the elliptic curve.
+		* @param curve The elliptic curve from which to obtain <code>&#956;</code>.
+		* The curve must be a Koblitz curve, i.e. <code>a</code> Equals
+		* <code>0</code> or <code>1</code> and <code>b</code> Equals
+		* <code>1</code>. 
+		* @return <code>&#956;</code> of the elliptic curve.
+		* @throws ArgumentException if the given ECCurve is not a Koblitz
+		* curve.
+		*/
+		public static sbyte GetMu(F2mCurve curve)
+		{
+			BigInteger a = curve.A.ToBigInteger();
+
+			sbyte mu;
+			if (a.SignValue == 0)
+			{
+				mu = -1;
+			}
+			else if (a.Equals(BigInteger.One))
+			{
+				mu = 1;
+			}
+			else
+			{
+				throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible");
+			}
+			return mu;
+		}
+
+		/**
+		* Calculates the Lucas Sequence elements <code>U<sub>k-1</sub></code> and
+		* <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code> and
+		* <code>V<sub>k</sub></code>.
+		* @param mu The parameter <code>&#956;</code> of the elliptic curve.
+		* @param k The index of the second element of the Lucas Sequence to be
+		* returned.
+		* @param doV If set to true, computes <code>V<sub>k-1</sub></code> and
+		* <code>V<sub>k</sub></code>, otherwise <code>U<sub>k-1</sub></code> and
+		* <code>U<sub>k</sub></code>.
+		* @return An array with 2 elements, containing <code>U<sub>k-1</sub></code>
+		* and <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code>
+		* and <code>V<sub>k</sub></code>.
+		*/
+		public static BigInteger[] GetLucas(sbyte mu, int k, bool doV)
+		{
+			if (!(mu == 1 || mu == -1)) 
+				throw new ArgumentException("mu must be 1 or -1");
+
+			BigInteger u0;
+			BigInteger u1;
+			BigInteger u2;
+
+			if (doV)
+			{
+				u0 = BigInteger.Two;
+				u1 = BigInteger.ValueOf(mu);
+			}
+			else
+			{
+				u0 = BigInteger.Zero;
+				u1 = BigInteger.One;
+			}
+
+			for (int i = 1; i < k; i++)
+			{
+				// u2 = mu*u1 - 2*u0;
+				BigInteger s = null;
+				if (mu == 1)
+				{
+					s = u1;
+				}
+				else
+				{
+					// mu == -1
+					s = u1.Negate();
+				}
+	            
+				u2 = s.Subtract(u0.ShiftLeft(1));
+				u0 = u1;
+				u1 = u2;
+				//            System.out.println(i + ": " + u2);
+				//            System.out.println();
+			}
+
+			BigInteger[] retVal = {u0, u1};
+			return retVal;
+		}
+
+		/**
+		* Computes the auxiliary value <code>t<sub>w</sub></code>. If the width is
+		* 4, then for <code>mu = 1</code>, <code>t<sub>w</sub> = 6</code> and for
+		* <code>mu = -1</code>, <code>t<sub>w</sub> = 10</code> 
+		* @param mu The parameter <code>&#956;</code> of the elliptic curve.
+		* @param w The window width of the WTNAF.
+		* @return the auxiliary value <code>t<sub>w</sub></code>
+		*/
+		public static BigInteger GetTw(sbyte mu, int w) 
+		{
+			if (w == 4)
+			{
+				if (mu == 1)
+				{
+					return BigInteger.ValueOf(6);
+				}
+				else
+				{
+					// mu == -1
+					return BigInteger.ValueOf(10);
+				}
+			}
+			else
+			{
+				// For w <> 4, the values must be computed
+				BigInteger[] us = GetLucas(mu, w, false);
+				BigInteger twoToW = BigInteger.Zero.SetBit(w);
+				BigInteger u1invert = us[1].ModInverse(twoToW);
+				BigInteger tw;
+				tw = BigInteger.Two.Multiply(us[0]).Multiply(u1invert).Mod(twoToW);
+				//System.out.println("mu = " + mu);
+				//System.out.println("tw = " + tw);
+				return tw;
+			}
+		}
+
+		/**
+		* Computes the auxiliary values <code>s<sub>0</sub></code> and
+		* <code>s<sub>1</sub></code> used for partial modular reduction. 
+		* @param curve The elliptic curve for which to compute
+		* <code>s<sub>0</sub></code> and <code>s<sub>1</sub></code>.
+		* @throws ArgumentException if <code>curve</code> is not a
+		* Koblitz curve (Anomalous Binary Curve, ABC).
+		*/
+		public static BigInteger[] GetSi(F2mCurve curve)
+		{
+			if (!curve.IsKoblitz)
+				throw new ArgumentException("si is defined for Koblitz curves only");
+
+			int m = curve.M;
+			int a = curve.A.ToBigInteger().IntValue;
+			sbyte mu = curve.GetMu();
+			int h = curve.H.IntValue;
+			int index = m + 3 - a;
+			BigInteger[] ui = GetLucas(mu, index, false);
+
+			BigInteger dividend0;
+			BigInteger dividend1;
+			if (mu == 1)
+			{
+				dividend0 = BigInteger.One.Subtract(ui[1]);
+				dividend1 = BigInteger.One.Subtract(ui[0]);
+			}
+			else if (mu == -1)
+			{
+				dividend0 = BigInteger.One.Add(ui[1]);
+				dividend1 = BigInteger.One.Add(ui[0]);
+			}
+			else
+			{
+				throw new ArgumentException("mu must be 1 or -1");
+			}
+
+			BigInteger[] si = new BigInteger[2];
+
+			if (h == 2)
+			{
+				si[0] = dividend0.ShiftRight(1);
+				si[1] = dividend1.ShiftRight(1).Negate();
+			}
+			else if (h == 4)
+			{
+				si[0] = dividend0.ShiftRight(2);
+				si[1] = dividend1.ShiftRight(2).Negate();
+			}
+			else
+			{
+				throw new ArgumentException("h (Cofactor) must be 2 or 4");
+			}
+
+			return si;
+		}
+
+		/**
+		* Partial modular reduction modulo
+		* <code>(&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>.
+		* @param k The integer to be reduced.
+		* @param m The bitlength of the underlying finite field.
+		* @param a The parameter <code>a</code> of the elliptic curve.
+		* @param s The auxiliary values <code>s<sub>0</sub></code> and
+		* <code>s<sub>1</sub></code>.
+		* @param mu The parameter &#956; of the elliptic curve.
+		* @param c The precision (number of bits of accuracy) of the partial
+		* modular reduction.
+		* @return <code>&#961; := k partmod (&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>
+		*/
+		public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a,
+			BigInteger[] s, sbyte mu, sbyte c)
+		{
+			// d0 = s[0] + mu*s[1]; mu is either 1 or -1
+			BigInteger d0;
+			if (mu == 1)
+			{
+				d0 = s[0].Add(s[1]);
+			}
+			else
+			{
+				d0 = s[0].Subtract(s[1]);
+			}
+
+			BigInteger[] v = GetLucas(mu, m, true);
+			BigInteger vm = v[1];
+
+			SimpleBigDecimal lambda0 = ApproximateDivisionByN(
+				k, s[0], vm, a, m, c);
+	        
+			SimpleBigDecimal lambda1 = ApproximateDivisionByN(
+				k, s[1], vm, a, m, c);
+
+			ZTauElement q = Round(lambda0, lambda1, mu);
+
+			// r0 = n - d0*q0 - 2*s1*q1
+			BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract(
+				BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v));
+
+			// r1 = s1*q0 - s0*q1
+			BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v));
+	        
+			return new ZTauElement(r0, r1);
+		}
+
+		/**
+		* Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+		* by a <code>BigInteger</code> using the reduced <code>&#964;</code>-adic
+		* NAF (RTNAF) method.
+		* @param p The F2mPoint to Multiply.
+		* @param k The <code>BigInteger</code> by which to Multiply <code>p</code>.
+		* @return <code>k * p</code>
+		*/
+		public static F2mPoint MultiplyRTnaf(F2mPoint p, BigInteger k)
+		{
+			F2mCurve curve = (F2mCurve) p.Curve;
+			int m = curve.M;
+			sbyte a = (sbyte) curve.A.ToBigInteger().IntValue;
+			sbyte mu = curve.GetMu();
+			BigInteger[] s = curve.GetSi();
+			ZTauElement rho = PartModReduction(k, m, a, s, mu, (sbyte)10);
+
+			return MultiplyTnaf(p, rho);
+		}
+
+		/**
+		* Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+		* by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
+		* using the <code>&#964;</code>-adic NAF (TNAF) method.
+		* @param p The F2mPoint to Multiply.
+		* @param lambda The element <code>&#955;</code> of
+		* <code><b>Z</b>[&#964;]</code>.
+		* @return <code>&#955; * p</code>
+		*/
+		public static F2mPoint MultiplyTnaf(F2mPoint p, ZTauElement lambda)
+		{
+			F2mCurve curve = (F2mCurve)p.Curve;
+			sbyte mu = curve.GetMu();
+			sbyte[] u = TauAdicNaf(mu, lambda);
+
+			F2mPoint q = MultiplyFromTnaf(p, u);
+
+			return q;
+		}
+
+		/**
+		* Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+		* by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
+		* using the <code>&#964;</code>-adic NAF (TNAF) method, given the TNAF
+		* of <code>&#955;</code>.
+		* @param p The F2mPoint to Multiply.
+		* @param u The the TNAF of <code>&#955;</code>..
+		* @return <code>&#955; * p</code>
+		*/
+		public static F2mPoint MultiplyFromTnaf(F2mPoint p, sbyte[] u)
+		{
+			F2mCurve curve = (F2mCurve)p.Curve;
+			F2mPoint q = (F2mPoint) curve.Infinity;
+			for (int i = u.Length - 1; i >= 0; i--)
+			{
+				q = Tau(q);
+				if (u[i] == 1)
+				{
+					q = (F2mPoint)q.AddSimple(p);
+				}
+				else if (u[i] == -1)
+				{
+					q = (F2mPoint)q.SubtractSimple(p);
+				}
+			}
+			return q;
+		}
+
+		/**
+		* Computes the <code>[&#964;]</code>-adic window NAF of an element
+		* <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
+		* @param mu The parameter &#956; of the elliptic curve.
+		* @param lambda The element <code>&#955;</code> of
+		* <code><b>Z</b>[&#964;]</code> of which to compute the
+		* <code>[&#964;]</code>-adic NAF.
+		* @param width The window width of the resulting WNAF.
+		* @param pow2w 2<sup>width</sup>.
+		* @param tw The auxiliary value <code>t<sub>w</sub></code>.
+		* @param alpha The <code>&#945;<sub>u</sub></code>'s for the window width.
+		* @return The <code>[&#964;]</code>-adic window NAF of
+		* <code>&#955;</code>.
+		*/
+		public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda,
+			sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
+		{
+			if (!((mu == 1) || (mu == -1))) 
+				throw new ArgumentException("mu must be 1 or -1");
+
+			BigInteger norm = Norm(mu, lambda);
+
+			// Ceiling of log2 of the norm 
+			int log2Norm = norm.BitLength;
+
+			// If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
+			int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width;
+
+			// The array holding the TNAF
+			sbyte[] u = new sbyte[maxLength];
+
+			// 2^(width - 1)
+			BigInteger pow2wMin1 = pow2w.ShiftRight(1);
+
+			// Split lambda into two BigIntegers to simplify calculations
+			BigInteger r0 = lambda.u;
+			BigInteger r1 = lambda.v;
+			int i = 0;
+
+			// while lambda <> (0, 0)
+			while (!((r0.Equals(BigInteger.Zero))&&(r1.Equals(BigInteger.Zero))))
+			{
+				// if r0 is odd
+				if (r0.TestBit(0)) 
+				{
+					// uUnMod = r0 + r1*tw Mod 2^width
+					BigInteger uUnMod
+						= r0.Add(r1.Multiply(tw)).Mod(pow2w);
+	                
+					sbyte uLocal;
+					// if uUnMod >= 2^(width - 1)
+					if (uUnMod.CompareTo(pow2wMin1) >= 0)
+					{
+						uLocal = (sbyte) uUnMod.Subtract(pow2w).IntValue;
+					}
+					else
+					{
+						uLocal = (sbyte) uUnMod.IntValue;
+					}
+					// uLocal is now in [-2^(width-1), 2^(width-1)-1]
+
+					u[i] = uLocal;
+					bool s = true;
+					if (uLocal < 0) 
+					{
+						s = false;
+						uLocal = (sbyte)-uLocal;
+					}
+					// uLocal is now >= 0
+
+					if (s) 
+					{
+						r0 = r0.Subtract(alpha[uLocal].u);
+						r1 = r1.Subtract(alpha[uLocal].v);
+					}
+					else
+					{
+						r0 = r0.Add(alpha[uLocal].u);
+						r1 = r1.Add(alpha[uLocal].v);
+					}
+				}
+				else
+				{
+					u[i] = 0;
+				}
+
+				BigInteger t = r0;
+
+				if (mu == 1)
+				{
+					r0 = r1.Add(r0.ShiftRight(1));
+				}
+				else
+				{
+					// mu == -1
+					r0 = r1.Subtract(r0.ShiftRight(1));
+				}
+				r1 = t.ShiftRight(1).Negate();
+				i++;
+			}
+			return u;
+		}
+
+		/**
+		* Does the precomputation for WTNAF multiplication.
+		* @param p The <code>ECPoint</code> for which to do the precomputation.
+		* @param a The parameter <code>a</code> of the elliptic curve.
+		* @return The precomputation array for <code>p</code>. 
+		*/
+		public static F2mPoint[] GetPreComp(F2mPoint p, sbyte a)
+		{
+			F2mPoint[] pu;
+			pu = new F2mPoint[16];
+			pu[1] = p;
+			sbyte[][] alphaTnaf;
+			if (a == 0)
+			{
+				alphaTnaf = Tnaf.Alpha0Tnaf;
+			}
+			else
+			{
+				// a == 1
+				alphaTnaf = Tnaf.Alpha1Tnaf;
+			}
+
+			int precompLen = alphaTnaf.Length;
+			for (int i = 3; i < precompLen; i = i + 2)
+			{
+				pu[i] = Tnaf.MultiplyFromTnaf(p, alphaTnaf[i]);
+			}
+	        
+			return pu;
+		}
+	}
+}