/** * Computes the <code>[τ]</code>-adic window NAF of an element * <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter μ of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code> of which to compute the * <code>[τ]</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>α<sub>u</sub></code>'s for the window width. * @return The <code>[τ]</code>-adic window NAF of * <code>λ</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; }
/** * Computes the <code>τ</code>-adic NAF (non-adjacent form) of an * element <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return The <code>τ</code>-adic NAF of <code>λ</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; }
/** * Multiplies a {@link BitcoinKit.BouncyCastle.math.ec.F2mPoint F2mPoint} * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> * using the <code>τ</code>-adic NAF (TNAF) method. * @param p The F2mPoint to Multiply. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return <code>λ * 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; }
/** * Computes the norm of an element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return The norm of <code>λ</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; }
/** * Multiplies a {@link BitcoinKit.BouncyCastle.math.ec.F2mPoint F2mPoint} * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> using * the <code>τ</code>-adic NAF (TNAF) method. * @param p The F2mPoint to multiply. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code> of which to compute the * <code>[τ]</code>-adic NAF. * @return <code>p</code> multiplied by <code>λ</code>. */ private F2mPoint MultiplyWTnaf(F2mPoint p, ZTauElement lambda, PreCompInfo preCompInfo, sbyte a, sbyte mu) { ZTauElement[] alpha = (a == 0) ? Tnaf.Alpha0 : Tnaf.Alpha1; BigInteger tw = Tnaf.GetTw(mu, Tnaf.Width); sbyte[]u = Tnaf.TauAdicWNaf(mu, lambda, Tnaf.Width, BigInteger.ValueOf(Tnaf.Pow2Width), tw, alpha); return MultiplyFromWTnaf(p, u, preCompInfo); }