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