1package org.bouncycastle.math.ec; 2 3import java.math.BigInteger; 4 5/** 6 * Class implementing the WTNAF (Window 7 * <code>τ</code>-adic Non-Adjacent Form) algorithm. 8 */ 9class WTauNafMultiplier implements ECMultiplier 10{ 11 /** 12 * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} 13 * by <code>k</code> using the reduced <code>τ</code>-adic NAF (RTNAF) 14 * method. 15 * @param p The ECPoint.F2m to multiply. 16 * @param k The integer by which to multiply <code>k</code>. 17 * @return <code>p</code> multiplied by <code>k</code>. 18 */ 19 public ECPoint multiply(ECPoint point, BigInteger k, PreCompInfo preCompInfo) 20 { 21 if (!(point instanceof ECPoint.F2m)) 22 { 23 throw new IllegalArgumentException("Only ECPoint.F2m can be " + 24 "used in WTauNafMultiplier"); 25 } 26 27 ECPoint.F2m p = (ECPoint.F2m)point; 28 29 ECCurve.F2m curve = (ECCurve.F2m) p.getCurve(); 30 int m = curve.getM(); 31 byte a = curve.getA().toBigInteger().byteValue(); 32 byte mu = curve.getMu(); 33 BigInteger[] s = curve.getSi(); 34 35 ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10); 36 37 return multiplyWTnaf(p, rho, preCompInfo, a, mu); 38 } 39 40 /** 41 * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} 42 * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> using 43 * the <code>τ</code>-adic NAF (TNAF) method. 44 * @param p The ECPoint.F2m to multiply. 45 * @param lambda The element <code>λ</code> of 46 * <code><b>Z</b>[τ]</code> of which to compute the 47 * <code>[τ]</code>-adic NAF. 48 * @return <code>p</code> multiplied by <code>λ</code>. 49 */ 50 private ECPoint.F2m multiplyWTnaf(ECPoint.F2m p, ZTauElement lambda, 51 PreCompInfo preCompInfo, byte a, byte mu) 52 { 53 ZTauElement[] alpha; 54 if (a == 0) 55 { 56 alpha = Tnaf.alpha0; 57 } 58 else 59 { 60 // a == 1 61 alpha = Tnaf.alpha1; 62 } 63 64 BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH); 65 66 byte[]u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH, 67 BigInteger.valueOf(Tnaf.POW_2_WIDTH), tw, alpha); 68 69 return multiplyFromWTnaf(p, u, preCompInfo); 70 } 71 72 /** 73 * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} 74 * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> 75 * using the window <code>τ</code>-adic NAF (TNAF) method, given the 76 * WTNAF of <code>λ</code>. 77 * @param p The ECPoint.F2m to multiply. 78 * @param u The the WTNAF of <code>λ</code>.. 79 * @return <code>λ * p</code> 80 */ 81 private static ECPoint.F2m multiplyFromWTnaf(ECPoint.F2m p, byte[] u, 82 PreCompInfo preCompInfo) 83 { 84 ECCurve.F2m curve = (ECCurve.F2m)p.getCurve(); 85 byte a = curve.getA().toBigInteger().byteValue(); 86 87 ECPoint.F2m[] pu; 88 if ((preCompInfo == null) || !(preCompInfo instanceof WTauNafPreCompInfo)) 89 { 90 pu = Tnaf.getPreComp(p, a); 91 p.setPreCompInfo(new WTauNafPreCompInfo(pu)); 92 } 93 else 94 { 95 pu = ((WTauNafPreCompInfo)preCompInfo).getPreComp(); 96 } 97 98 // q = infinity 99 ECPoint.F2m q = (ECPoint.F2m) p.getCurve().getInfinity(); 100 for (int i = u.length - 1; i >= 0; i--) 101 { 102 q = Tnaf.tau(q); 103 if (u[i] != 0) 104 { 105 if (u[i] > 0) 106 { 107 q = q.addSimple(pu[u[i]]); 108 } 109 else 110 { 111 // u[i] < 0 112 q = q.subtractSimple(pu[-u[i]]); 113 } 114 } 115 } 116 117 return q; 118 } 119} 120