/** * D.3.2 pg 101 * @see org.bouncycastle.math.ec.multiplier.ECMultiplier#multiply(org.bouncycastle.math.ec.ECPoint, java.math.BigInteger) */ public ECPoint Multiply(ECPoint p, IBigInteger k, IPreCompInfo preCompInfo) { // TODO Probably should try to add this // IBigInteger e = k.Mod(n); // n == order of p IBigInteger e = k; IBigInteger h = e.Multiply(BigInteger.Three); ECPoint neg = p.Negate(); ECPoint R = p; for (int i = h.BitLength - 2; i > 0; --i) { R = R.Twice(); bool hBit = h.TestBit(i); bool eBit = e.TestBit(i); if (hBit != eBit) { R = R.Add(hBit ? p : neg); } } return(R); }
/** * D.3.2 pg 101 * @see org.bouncycastle.math.ec.multiplier.ECMultiplier#multiply(org.bouncycastle.math.ec.ECPoint, java.math.BigInteger) */ public ECPoint Multiply(ECPoint p, IBigInteger k, IPreCompInfo preCompInfo) { // TODO Probably should try to add this // IBigInteger e = k.Mod(n); // n == order of p IBigInteger e = k; IBigInteger h = e.Multiply(BigInteger.Three); ECPoint neg = p.Negate(); ECPoint R = p; for (int i = h.BitLength - 2; i > 0; --i) { R = R.Twice(); bool hBit = h.TestBit(i); bool eBit = e.TestBit(i); if (hBit != eBit) { R = R.Add(hBit ? p : neg); } } return R; }
/** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations in * {@link org.bouncycastle.math.ec.ECPoint ECPoint}. * * @param p The point to multiply. * @param k The factor by which to multiply. * @return The result of the point multiplication <code>k * p</code>. */ public ECPoint Multiply(ECPoint p, IBigInteger k, IPreCompInfo preCompInfo) { ECPoint q = p.Curve.Infinity; int t = k.BitLength; for (int i = 0; i < t; i++) { if (k.TestBit(i)) { q = q.Add(p); } p = p.Twice(); } return q; }
/** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations in * {@link org.bouncycastle.math.ec.ECPoint ECPoint}. * * @param p The point to multiply. * @param k The factor by which to multiply. * @return The result of the point multiplication <code>k * p</code>. */ public ECPoint Multiply(ECPoint p, IBigInteger k, IPreCompInfo preCompInfo) { ECPoint q = p.Curve.Infinity; int t = k.BitLength; for (int i = 0; i < t; i++) { if (k.TestBit(i)) { q = q.Add(p); } p = p.Twice(); } return(q); }
/** * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} * by <code>k</code> using the reduced <code>τ</code>-adic NAF (RTNAF) * method. * @param p The F2mPoint to multiply. * @param k The integer by which to multiply <code>k</code>. * @return <code>p</code> multiplied by <code>k</code>. */ public ECPoint Multiply(ECPoint point, IBigInteger k, IPreCompInfo preCompInfo) { if (!(point is F2MPoint)) throw new ArgumentException("Only F2mPoint can be used in WTauNafMultiplier"); F2MPoint p = (F2MPoint)point; F2MCurve curve = (F2MCurve) p.Curve; int m = curve.M; sbyte a = (sbyte) curve.A.ToBigInteger().IntValue; sbyte mu = curve.GetMu(); IBigInteger[] s = curve.GetSi(); ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10); return MultiplyWTnaf(p, rho, preCompInfo, a, mu); }
/** * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} * by <code>k</code> using the reduced <code>τ</code>-adic NAF (RTNAF) * method. * @param p The F2mPoint to multiply. * @param k The integer by which to multiply <code>k</code>. * @return <code>p</code> multiplied by <code>k</code>. */ public ECPoint Multiply(ECPoint point, IBigInteger k, IPreCompInfo preCompInfo) { if (!(point is F2MPoint)) { throw new ArgumentException("Only F2mPoint can be used in WTauNafMultiplier"); } F2MPoint p = (F2MPoint)point; F2MCurve curve = (F2MCurve)p.Curve; int m = curve.M; sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; sbyte mu = curve.GetMu(); IBigInteger[] s = curve.GetSi(); ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10); return(MultiplyWTnaf(p, rho, preCompInfo, a, mu)); }
/** * Multiplies a {@link org.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, IPreCompInfo preCompInfo, sbyte a, sbyte mu) { ZTauElement[] alpha; if (a == 0) { alpha = Tnaf.Alpha0; } else { // a == 1 alpha = Tnaf.Alpha1; } IBigInteger 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)); }
/** * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> * using the window <code>τ</code>-adic NAF (TNAF) method, given the * WTNAF of <code>λ</code>. * @param p The F2mPoint to multiply. * @param u The the WTNAF of <code>λ</code>.. * @return <code>λ * p</code> */ private static F2MPoint MultiplyFromWTnaf(F2MPoint p, sbyte[] u, IPreCompInfo preCompInfo) { F2MCurve curve = (F2MCurve)p.Curve; sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; F2MPoint[] pu; if ((preCompInfo == null) || !(preCompInfo is WTauNafPreCompInfo)) { pu = Tnaf.GetPreComp(p, a); p.PreCompInfo = new WTauNafPreCompInfo(pu); } else { pu = ((WTauNafPreCompInfo)preCompInfo).GetPreComp(); } // q = infinity F2MPoint q = (F2MPoint)p.Curve.Infinity; for (int i = u.Length - 1; i >= 0; i--) { q = Tnaf.Tau(q); if (u[i] != 0) { if (u[i] > 0) { q = q.AddSimple(pu[u[i]]); } else { // u[i] < 0 q = q.SubtractSimple(pu[-u[i]]); } } } return(q); }
/** * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> * using the window <code>τ</code>-adic NAF (TNAF) method, given the * WTNAF of <code>λ</code>. * @param p The F2mPoint to multiply. * @param u The the WTNAF of <code>λ</code>.. * @return <code>λ * p</code> */ private static F2MPoint MultiplyFromWTnaf(F2MPoint p, sbyte[] u, IPreCompInfo preCompInfo) { F2MCurve curve = (F2MCurve)p.Curve; sbyte a = (sbyte) curve.A.ToBigInteger().IntValue; F2MPoint[] pu; if ((preCompInfo == null) || !(preCompInfo is WTauNafPreCompInfo)) { pu = Tnaf.GetPreComp(p, a); p.PreCompInfo = new WTauNafPreCompInfo(pu); } else { pu = ((WTauNafPreCompInfo)preCompInfo).GetPreComp(); } // q = infinity F2MPoint q = (F2MPoint) p.Curve.Infinity; for (int i = u.Length - 1; i >= 0; i--) { q = Tnaf.Tau(q); if (u[i] != 0) { if (u[i] > 0) { q = q.AddSimple(pu[u[i]]); } else { // u[i] < 0 q = q.SubtractSimple(pu[-u[i]]); } } } return q; }
/** * Multiplies <code>this</code> by an integer <code>k</code> using the * Window NAF method. * @param k The integer by which <code>this</code> is multiplied. * @return A new <code>ECPoint</code> which equals <code>this</code> * multiplied by <code>k</code>. */ public ECPoint Multiply(ECPoint p, IBigInteger k, IPreCompInfo preCompInfo) { WNafPreCompInfo wnafPreCompInfo; if ((preCompInfo != null) && (preCompInfo is WNafPreCompInfo)) { wnafPreCompInfo = (WNafPreCompInfo)preCompInfo; } else { // Ignore empty PreCompInfo or PreCompInfo of incorrect type wnafPreCompInfo = new WNafPreCompInfo(); } // floor(log2(k)) int m = k.BitLength; // width of the Window NAF sbyte width; // Required length of precomputation array int reqPreCompLen; // Determine optimal width and corresponding length of precomputation // array based on literature values if (m < 13) { width = 2; reqPreCompLen = 1; } else { if (m < 41) { width = 3; reqPreCompLen = 2; } else { if (m < 121) { width = 4; reqPreCompLen = 4; } else { if (m < 337) { width = 5; reqPreCompLen = 8; } else { if (m < 897) { width = 6; reqPreCompLen = 16; } else { if (m < 2305) { width = 7; reqPreCompLen = 32; } else { width = 8; reqPreCompLen = 127; } } } } } } // The length of the precomputation array int preCompLen = 1; ECPoint[] preComp = wnafPreCompInfo.GetPreComp(); ECPoint twiceP = wnafPreCompInfo.GetTwiceP(); // Check if the precomputed ECPoints already exist if (preComp == null) { // Precomputation must be performed from scratch, create an empty // precomputation array of desired length preComp = new ECPoint[]{ p }; } else { // Take the already precomputed ECPoints to start with preCompLen = preComp.Length; } if (twiceP == null) { // Compute twice(p) twiceP = p.Twice(); } if (preCompLen < reqPreCompLen) { // Precomputation array must be made bigger, copy existing preComp // array into the larger new preComp array ECPoint[] oldPreComp = preComp; preComp = new ECPoint[reqPreCompLen]; Array.Copy(oldPreComp, 0, preComp, 0, preCompLen); for (int i = preCompLen; i < reqPreCompLen; i++) { // Compute the new ECPoints for the precomputation array. // The values 1, 3, 5, ..., 2^(width-1)-1 times p are // computed preComp[i] = twiceP.Add(preComp[i - 1]); } } // Compute the Window NAF of the desired width sbyte[] wnaf = WindowNaf(width, k); int l = wnaf.Length; // Apply the Window NAF to p using the precomputed ECPoint values. ECPoint q = p.Curve.Infinity; for (int i = l - 1; i >= 0; i--) { q = q.Twice(); if (wnaf[i] != 0) { if (wnaf[i] > 0) { q = q.Add(preComp[(wnaf[i] - 1)/2]); } else { // wnaf[i] < 0 q = q.Subtract(preComp[(-wnaf[i] - 1)/2]); } } } // Set PreCompInfo in ECPoint, such that it is available for next // multiplication. wnafPreCompInfo.SetPreComp(preComp); wnafPreCompInfo.SetTwiceP(twiceP); p.PreCompInfo = wnafPreCompInfo; return q; }
/** * Multiplies <code>this</code> by an integer <code>k</code> using the * Window NAF method. * @param k The integer by which <code>this</code> is multiplied. * @return A new <code>ECPoint</code> which equals <code>this</code> * multiplied by <code>k</code>. */ public ECPoint Multiply(ECPoint p, IBigInteger k, IPreCompInfo preCompInfo) { WNafPreCompInfo wnafPreCompInfo; if ((preCompInfo != null) && (preCompInfo is WNafPreCompInfo)) { wnafPreCompInfo = (WNafPreCompInfo)preCompInfo; } else { // Ignore empty PreCompInfo or PreCompInfo of incorrect type wnafPreCompInfo = new WNafPreCompInfo(); } // floor(log2(k)) int m = k.BitLength; // width of the Window NAF sbyte width; // Required length of precomputation array int reqPreCompLen; // Determine optimal width and corresponding length of precomputation // array based on literature values if (m < 13) { width = 2; reqPreCompLen = 1; } else { if (m < 41) { width = 3; reqPreCompLen = 2; } else { if (m < 121) { width = 4; reqPreCompLen = 4; } else { if (m < 337) { width = 5; reqPreCompLen = 8; } else { if (m < 897) { width = 6; reqPreCompLen = 16; } else { if (m < 2305) { width = 7; reqPreCompLen = 32; } else { width = 8; reqPreCompLen = 127; } } } } } } // The length of the precomputation array int preCompLen = 1; ECPoint[] preComp = wnafPreCompInfo.GetPreComp(); ECPoint twiceP = wnafPreCompInfo.GetTwiceP(); // Check if the precomputed ECPoints already exist if (preComp == null) { // Precomputation must be performed from scratch, create an empty // precomputation array of desired length preComp = new ECPoint[] { p }; } else { // Take the already precomputed ECPoints to start with preCompLen = preComp.Length; } if (twiceP == null) { // Compute twice(p) twiceP = p.Twice(); } if (preCompLen < reqPreCompLen) { // Precomputation array must be made bigger, copy existing preComp // array into the larger new preComp array ECPoint[] oldPreComp = preComp; preComp = new ECPoint[reqPreCompLen]; Array.Copy(oldPreComp, 0, preComp, 0, preCompLen); for (int i = preCompLen; i < reqPreCompLen; i++) { // Compute the new ECPoints for the precomputation array. // The values 1, 3, 5, ..., 2^(width-1)-1 times p are // computed preComp[i] = twiceP.Add(preComp[i - 1]); } } // Compute the Window NAF of the desired width sbyte[] wnaf = WindowNaf(width, k); int l = wnaf.Length; // Apply the Window NAF to p using the precomputed ECPoint values. ECPoint q = p.Curve.Infinity; for (int i = l - 1; i >= 0; i--) { q = q.Twice(); if (wnaf[i] != 0) { if (wnaf[i] > 0) { q = q.Add(preComp[(wnaf[i] - 1) / 2]); } else { // wnaf[i] < 0 q = q.Subtract(preComp[(-wnaf[i] - 1) / 2]); } } } // Set PreCompInfo in ECPoint, such that it is available for next // multiplication. wnafPreCompInfo.SetPreComp(preComp); wnafPreCompInfo.SetTwiceP(twiceP); p.PreCompInfo = wnafPreCompInfo; return(q); }
/** * Multiplies a {@link org.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, IPreCompInfo preCompInfo, sbyte a, sbyte mu) { ZTauElement[] alpha; if (a == 0) { alpha = Tnaf.Alpha0; } else { // a == 1 alpha = Tnaf.Alpha1; } IBigInteger 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); }