/// <summary> /// Multiplies the polynomial by another, taking the indices mod N. /// <para>Does not change this polynomial but returns the result as a new polynomial. /// Both polynomials must have the same number of coefficients. /// This method uses the <a href="http://en.wikipedia.org/wiki/Schönhage–Strassen_algorithm"/> /// Schönhage–Strassen algorithm.</para> /// </summary> /// /// <param name="Factor">Multiplication factor</param> /// /// <returns>Multiplied polynomial</returns> /// /// <exception cref="CryptoAsymmetricException">Thrown if the two polynomials differ in the number of coefficients</exception> public BigDecimalPolynomial Multiply(BigIntPolynomial Factor) { if (Factor.Coeffs.Length != Coeffs.Length) { throw new CryptoAsymmetricException("BigDecimalPolynomial:Multiply", "Number of coefficients must be the same!", new FormatException()); } BigIntPolynomial poly1 = new BigIntPolynomial(Coeffs.Length); for (int i = 0; i < Coeffs.Length; i++) { poly1.Coeffs[i] = Coeffs[i].UnScaledValue; } int scale = Coeffs[0].Scale; BigIntPolynomial cBigInt = poly1.MultBig(Factor); BigDecimalPolynomial c = new BigDecimalPolynomial(cBigInt.Coeffs.Length); for (int i = 0; i < c.Coeffs.Length; i++) { c.Coeffs[i] = new BigDecimal(cBigInt.Coeffs[i], scale); } return(c); }
/// <summary> /// Adds another polynomial which can have a different number of coefficients. /// </summary> /// /// <param name="B">The polynomial to add</param> public void Add(BigDecimalPolynomial B) { if (B.Coeffs.Length > Coeffs.Length) { int N = Coeffs.Length; Coeffs = Coeffs.CopyOf(B.Coeffs.Length); for (int i = N; i < Coeffs.Length; i++) Coeffs[i] = BigDecimal.Zero; } for (int i = 0; i < B.Coeffs.Length; i++) Coeffs[i] = Coeffs[i].Add(B.Coeffs[i]); }
/// <summary> /// Divides each coefficient by a <c>BigDecimal</c> and rounds the result to <c>decimalPlaces</c> places. /// </summary> /// /// <param name="Divisor">The divisor</param> /// <param name="DecimalPlaces">The number of fractional digits to round the result to</param> /// /// <returns>The polynomial product</returns> public BigDecimalPolynomial Divide(BigDecimal Divisor, int DecimalPlaces) { BigInteger max = MaxCoeffAbs(); int coeffLength = (int)(max.BitLength * LOG_10_2) + 1; // factor = 1/divisor BigDecimal factor = BigDecimal.One.Divide(Divisor, coeffLength + DecimalPlaces + 1, RoundingModes.HalfEven); // multiply each coefficient by factor BigDecimalPolynomial p = new BigDecimalPolynomial(Coeffs.Length); for (int i = 0; i < Coeffs.Length; i++) { // multiply, then truncate after decimalPlaces so subsequent operations aren't slowed down p.Coeffs[i] = new BigDecimal(Coeffs[i]).Multiply(factor).SetScale(DecimalPlaces, RoundingModes.HalfEven); } return(p); }
/// <summary> /// Adds another polynomial which can have a different number of coefficients. /// </summary> /// /// <param name="B">The polynomial to add</param> public void Add(BigDecimalPolynomial B) { if (B.Coeffs.Length > Coeffs.Length) { int N = Coeffs.Length; Coeffs = Coeffs.CopyOf(B.Coeffs.Length); for (int i = N; i < Coeffs.Length; i++) { Coeffs[i] = BigDecimal.Zero; } } for (int i = 0; i < B.Coeffs.Length; i++) { Coeffs[i] = Coeffs[i].Add(B.Coeffs[i]); } }
/// <summary> /// Multiplies the polynomial by another, taking the indices mod N. /// <para>Does not change this polynomial but returns the result as a new polynomial. /// Both polynomials must have the same number of coefficients. /// This method uses the <a href="http://en.wikipedia.org/wiki/Schönhage–Strassen_algorithm"/> /// Schönhage–Strassen algorithm.</para> /// </summary> /// /// <param name="Factor">Multiplication factor</param> /// /// <returns>Multiplied polynomial</returns> /// /// <exception cref="NTRUException">Thrown if the two polynomials differ in the number of coefficients</exception> public BigDecimalPolynomial Multiply(BigIntPolynomial Factor) { if (Factor.Coeffs.Length != Coeffs.Length) throw new CryptoAsymmetricException("BigDecimalPolynomial:Multiply", "Number of coefficients must be the same!", new FormatException()); BigIntPolynomial poly1 = new BigIntPolynomial(Coeffs.Length); for (int i = 0; i < Coeffs.Length; i++) poly1.Coeffs[i] = Coeffs[i].UnScaledValue; int scale = Coeffs[0].Scale; BigIntPolynomial cBigInt = poly1.MultBig(Factor); BigDecimalPolynomial c = new BigDecimalPolynomial(cBigInt.Coeffs.Length); for (int i = 0; i < c.Coeffs.Length; i++) c.Coeffs[i] = new BigDecimal(cBigInt.Coeffs[i], scale); return c; }
/// <summary> /// Divides each coefficient by a <c>BigDecimal</c> and rounds the result to <c>decimalPlaces</c> places. /// </summary> /// /// <param name="Divisor">The divisor</param> /// <param name="DecimalPlaces">The number of fractional digits to round the result to</param> /// /// <returns>The polynomial product</returns> public BigDecimalPolynomial Divide(BigDecimal Divisor, int DecimalPlaces) { BigInteger max = MaxCoeffAbs(); int coeffLength = (int)(max.BitLength * LOG_10_2) + 1; // factor = 1/divisor BigDecimal factor = BigDecimal.One.Divide(Divisor, coeffLength + DecimalPlaces + 1, RoundingModes.HalfEven); // multiply each coefficient by factor BigDecimalPolynomial p = new BigDecimalPolynomial(Coeffs.Length); for (int i = 0; i < Coeffs.Length; i++) { // multiply, then truncate after decimalPlaces so subsequent operations aren't slowed down p.Coeffs[i] = new BigDecimal(Coeffs[i]).Multiply(factor).SetScale(DecimalPlaces, RoundingModes.HalfEven); } return p; }
private BigDecimalPolynomial CreateBigDecimalPolynomial(int[] coeffs) { int N = coeffs.Length; BigDecimalPolynomial poly = new BigDecimalPolynomial(N); for (int i = 0; i < N; i++) poly.Coeffs[i] = new BigDecimal(coeffs[i]); return poly; }