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 /** 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 protected ECPoint multiplyPositive(ECPoint point, BigInteger k) 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 ECCurve.F2m curve = (ECCurve.F2m)p.getCurve(); 29 int m = curve.getM(); 30 byte a = curve.getA().toBigInteger().byteValue(); 31 byte mu = curve.getMu(); 32 BigInteger[] s = curve.getSi(); 33 34 ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10); 35 36 return multiplyWTnaf(p, rho, curve.getPreCompInfo(p), a, mu); 37 } 38 39 /** 40 * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} 41 * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> using 42 * the <code>τ</code>-adic NAF (TNAF) method. 43 * @param p The ECPoint.F2m to multiply. 44 * @param lambda The element <code>λ</code> of 45 * <code><b>Z</b>[τ]</code> of which to compute the 46 * <code>[τ]</code>-adic NAF. 47 * @return <code>p</code> multiplied by <code>λ</code>. 48 */ 49 private ECPoint.F2m multiplyWTnaf(ECPoint.F2m p, ZTauElement lambda, 50 PreCompInfo preCompInfo, byte a, byte mu) 51 { 52 ZTauElement[] alpha; 53 if (a == 0) 54 { 55 alpha = Tnaf.alpha0; 56 } 57 else 58 { 59 // a == 1 60 alpha = Tnaf.alpha1; 61 } 62 63 BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH); 64 65 byte[]u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH, 66 BigInteger.valueOf(Tnaf.POW_2_WIDTH), tw, alpha); 67 68 return multiplyFromWTnaf(p, u, preCompInfo); 69 } 70 71 /** 72 * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} 73 * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> 74 * using the window <code>τ</code>-adic NAF (TNAF) method, given the 75 * WTNAF of <code>λ</code>. 76 * @param p The ECPoint.F2m to multiply. 77 * @param u The the WTNAF of <code>λ</code>.. 78 * @return <code>λ * p</code> 79 */ 80 private static ECPoint.F2m multiplyFromWTnaf(ECPoint.F2m p, byte[] u, 81 PreCompInfo preCompInfo) 82 { 83 ECCurve.F2m curve = (ECCurve.F2m)p.getCurve(); 84 byte a = curve.getA().toBigInteger().byteValue(); 85 86 ECPoint.F2m[] pu; 87 if ((preCompInfo == null) || !(preCompInfo instanceof WTauNafPreCompInfo)) 88 { 89 pu = Tnaf.getPreComp(p, a); 90 curve.setPreCompInfo(p, new WTauNafPreCompInfo(pu)); 91 } 92 else 93 { 94 pu = ((WTauNafPreCompInfo)preCompInfo).getPreComp(); 95 } 96 97 // q = infinity 98 ECPoint.F2m q = (ECPoint.F2m) p.getCurve().getInfinity(); 99 for (int i = u.length - 1; i >= 0; i--) 100 { 101 q = Tnaf.tau(q); 102 if (u[i] != 0) 103 { 104 if (u[i] > 0) 105 { 106 q = q.addSimple(pu[u[i]]); 107 } 108 else 109 { 110 // u[i] < 0 111 q = q.subtractSimple(pu[-u[i]]); 112 } 113 } 114 } 115 116 return q; 117 } 118} 119