001: package org.bouncycastle.math.ec;
002:
003: import java.math.BigInteger;
004:
005: /**
006: * Class implementing the WTNAF (Window
007: * <code>τ</code>-adic Non-Adjacent Form) algorithm.
008: */
009: class WTauNafMultiplier implements ECMultiplier {
010: /**
011: * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
012: * by <code>k</code> using the reduced <code>τ</code>-adic NAF (RTNAF)
013: * method.
014: * @param p The ECPoint.F2m to multiply.
015: * @param k The integer by which to multiply <code>k</code>.
016: * @return <code>p</code> multiplied by <code>k</code>.
017: */
018: public ECPoint multiply(ECPoint point, BigInteger k,
019: PreCompInfo preCompInfo) {
020: if (!(point instanceof ECPoint.F2m)) {
021: throw new IllegalArgumentException(
022: "Only ECPoint.F2m can be "
023: + "used in WTauNafMultiplier");
024: }
025:
026: ECPoint.F2m p = (ECPoint.F2m) point;
027:
028: ECCurve.F2m curve = (ECCurve.F2m) p.getCurve();
029: int m = curve.getM();
030: byte a = curve.getA().toBigInteger().byteValue();
031: byte mu = curve.getMu();
032: BigInteger[] s = curve.getSi();
033:
034: ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu,
035: (byte) 10);
036:
037: return multiplyWTnaf(p, rho, preCompInfo, a, mu);
038: }
039:
040: /**
041: * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
042: * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> using
043: * the <code>τ</code>-adic NAF (TNAF) method.
044: * @param p The ECPoint.F2m to multiply.
045: * @param lambda The element <code>λ</code> of
046: * <code><b>Z</b>[τ]</code> of which to compute the
047: * <code>[τ]</code>-adic NAF.
048: * @return <code>p</code> multiplied by <code>λ</code>.
049: */
050: private ECPoint.F2m multiplyWTnaf(ECPoint.F2m p,
051: ZTauElement lambda, PreCompInfo preCompInfo, byte a, byte mu) {
052: ZTauElement[] alpha;
053: if (a == 0) {
054: alpha = Tnaf.alpha0;
055: } else {
056: // a == 1
057: alpha = Tnaf.alpha1;
058: }
059:
060: BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH);
061:
062: byte[] u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH, BigInteger
063: .valueOf(Tnaf.POW_2_WIDTH), tw, alpha);
064:
065: return multiplyFromWTnaf(p, u, preCompInfo);
066: }
067:
068: /**
069: * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
070: * by an element <code>λ</code> of <code><b>Z</b>[τ]</code>
071: * using the window <code>τ</code>-adic NAF (TNAF) method, given the
072: * WTNAF of <code>λ</code>.
073: * @param p The ECPoint.F2m to multiply.
074: * @param u The the WTNAF of <code>λ</code>..
075: * @return <code>λ * p</code>
076: */
077: private static ECPoint.F2m multiplyFromWTnaf(ECPoint.F2m p,
078: byte[] u, PreCompInfo preCompInfo) {
079: ECCurve.F2m curve = (ECCurve.F2m) p.getCurve();
080: byte a = curve.getA().toBigInteger().byteValue();
081:
082: ECPoint.F2m[] pu;
083: if ((preCompInfo == null)
084: || !(preCompInfo instanceof WTauNafPreCompInfo)) {
085: pu = Tnaf.getPreComp(p, a);
086: p.setPreCompInfo(new WTauNafPreCompInfo(pu));
087: } else {
088: pu = ((WTauNafPreCompInfo) preCompInfo).getPreComp();
089: }
090:
091: // q = infinity
092: ECPoint.F2m q = (ECPoint.F2m) p.getCurve().getInfinity();
093: for (int i = u.length - 1; i >= 0; i--) {
094: q = Tnaf.tau(q);
095: if (u[i] != 0) {
096: if (u[i] > 0) {
097: q = q.addSimple(pu[u[i]]);
098: } else {
099: // u[i] < 0
100: q = q.subtractSimple(pu[-u[i]]);
101: }
102: }
103: }
104:
105: return q;
106: }
107: }
|