public void testMult() { BigDecimalPolynomial a = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[] { 4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5 }))); BigDecimalPolynomial b = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[] { -6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1 }))); BigDecimalPolynomial c = a.Multiply(b); decimal[] expectedCoeffs = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 }))).getCoeffs(); decimal[] cCoeffs = c.getCoeffs(); Assert.AreEqual(expectedCoeffs.Length, cCoeffs.Length); for (int i = 0; i != cCoeffs.Length; i++) { Assert.AreEqual(expectedCoeffs[i], cCoeffs[i]); } // multiply a polynomial by its inverse modulo 2048 and check that the result is 1 SecureRandom random = new SecureRandom(); IntegerPolynomial d, dInv; do { d = DenseTernaryPolynomial.GenerateRandom(1001, 333, 334, random); dInv = d.InvertFq(2048); }while (dInv == null); d.Mod(2048); BigDecimalPolynomial e = new BigDecimalPolynomial(new BigIntPolynomial(d)); BigIntPolynomial f = new BigIntPolynomial(dInv); IntegerPolynomial g = new IntegerPolynomial(e.Multiply(f).round()); g.ModPositive(2048); Assert.True(g.EqualsOne()); }
// verifies that res=rho*a mod x^n-1 mod p private void VerifyResultant(IntegerPolynomial a, Resultant r, int p) { BigIntPolynomial b = new BigIntPolynomial(a).MultSmall(r.Rho); b.Mod(BigInteger.ValueOf(p)); for (int j = 1; j < b.Coeffs.Length - 1; j++) { if (!Compare.Equals(BigInteger.Zero, b.Coeffs[j])) { throw new Exception("IntegerPolynomialTest VerifyResultant test failed!"); } } if (r.Res.Equals(BigInteger.Zero)) { if (!Compare.Equals(BigInteger.Zero, b.Coeffs[0].Subtract(b.Coeffs[b.Coeffs.Length - 1]))) { throw new Exception("IntegerPolynomialTest VerifyResultant test failed!"); } } else { if (!Compare.Equals(BigInteger.Zero, (b.Coeffs[0].Subtract(b.Coeffs[b.Coeffs.Length - 1]).Subtract(r.Res).Mod(BigInteger.ValueOf(p))))) { throw new Exception("IntegerPolynomialTest VerifyResultant test failed!"); } } if (!Compare.Equals(BigInteger.Zero, b.Coeffs[0].Subtract(r.Res).Subtract(b.Coeffs[b.Coeffs.Length - 1].Negate()).Mod(BigInteger.ValueOf(p)))) { throw new Exception("IntegerPolynomialTest VerifyResultant test failed!"); } }
/// <summary> /// Test the validity of the BigIntPolynomial implementation /// </summary> /// /// <returns>State</returns> public string Test() { try { BigIntPolynomial a = new BigIntPolynomial(new IntegerPolynomial(new int[] { 4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5 })); BigIntPolynomial b = new BigIntPolynomial(new IntegerPolynomial(new int[] { -6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1 })); BigIntPolynomial expected = new BigIntPolynomial(new IntegerPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 })); if (!Compare.AreEqual(expected.Coeffs, a.MultSmall(b).Coeffs)) { throw new Exception("BigIntPolynomial known value test failed!"); } OnProgress(new TestEventArgs("Passed round 1 BigIntPolynomial known value")); if (!Compare.AreEqual(expected.Coeffs, a.MultBig(b).Coeffs)) { throw new Exception("BigIntPolynomial known value test failed!"); } OnProgress(new TestEventArgs("Passed round 2 BigIntPolynomial known value")); Random rng = new Random(); BigInteger[] aCoeffs = new BigInteger[10 + rng.Next(50)]; BigInteger[] bCoeffs = new BigInteger[aCoeffs.Length]; for (int i = 0; i < 3; i++) { for (int j = 0; j < aCoeffs.Length; j++) { byte[] aArr = new byte[600 + rng.Next(100)]; rng.NextBytes(aArr); aCoeffs[j] = new BigInteger(aArr); byte[] bArr = new byte[600 + rng.Next(100)]; rng.NextBytes(bArr); bCoeffs[j] = new BigInteger(bArr); } a = new BigIntPolynomial(aCoeffs); b = new BigIntPolynomial(bCoeffs); if (!Compare.AreEqual(a.MultSmall(b).Coeffs, a.MultBig(b).Coeffs)) { throw new Exception("BigIntPolynomial coefficient comparison test failed!"); } } OnProgress(new TestEventArgs("Passed BigIntPolynomial coefficient comparison")); return(SUCCESS); } catch (Exception Ex) { string message = Ex.Message == null ? "" : Ex.Message; throw new Exception(FAILURE + message); } }
public void testMult() { BigIntPolynomial a = new BigIntPolynomial(new IntegerPolynomial(new int[] { 4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5 })); BigIntPolynomial b = new BigIntPolynomial(new IntegerPolynomial(new int[] { -6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1 })); BigIntPolynomial c = a.Multiply(b); BigInteger[] expectedCoeffs = new BigIntPolynomial(new IntegerPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 })).GetCoeffs(); BigInteger[] cCoeffs = c.GetCoeffs(); Assert.AreEqual(expectedCoeffs.Length, cCoeffs.Length); for (int i = 0; i != cCoeffs.Length; i++) { Assert.AreEqual(expectedCoeffs[i], cCoeffs[i]); } }
/** * tests mult(IntegerPolynomial) and mult(BigIntPolynomial) */ public void testMult() { SecureRandom random = new SecureRandom(); SparseTernaryPolynomial p1 = SparseTernaryPolynomial.GenerateRandom(1000, 500, 500, random); IntegerPolynomial p2 = DenseTernaryPolynomial.GenerateRandom(1000, random); IntegerPolynomial prod1 = p1.Multiply(p2); IntegerPolynomial prod2 = p1.Multiply(p2); Assert.AreEqual(prod1.coeffs, prod2.coeffs); BigIntPolynomial p3 = new BigIntPolynomial(p2); BigIntPolynomial prod3 = p1.Multiply(p3); Assert.AreEqual((new BigIntPolynomial(prod1)).coeffs, prod3.coeffs); }
// verifies that res=rho*a mod x^n-1 private void verifyResultant(IntegerPolynomial a, Resultant r) { BigIntPolynomial b = new BigIntPolynomial(a).Multiply(r.Rho); BigInteger[] bCoeffs = b.GetCoeffs(); for (int j = 1; j < bCoeffs.Length - 1; j++) { Assert.AreEqual(BigInteger.Zero, bCoeffs[j]); } if (r.Res.Equals(BigInteger.Zero)) { Assert.AreEqual(BigInteger.Zero, bCoeffs[0].Subtract(bCoeffs[bCoeffs.Length - 1])); } else { Assert.AreEqual(BigInteger.Zero, (bCoeffs[0].Subtract(bCoeffs[bCoeffs.Length - 1]).Mod(r.Res))); } Assert.AreEqual(bCoeffs[0].Subtract(r.Res), bCoeffs[bCoeffs.Length - 1].Negate()); }
/// <summary> /// Test the validity of the BigDecimalPolynomial implementation /// </summary> /// /// <returns>State</returns> public string Test() { try { BigDecimalPolynomial a = CreateBigDecimalPolynomial(new int[] { 4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5 }); BigIntPolynomial b = new BigIntPolynomial(new IntegerPolynomial(new int[] { -6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1 })); BigDecimalPolynomial c = a.Multiply(b); if (!Compare.AreEqual(c.Coeffs, CreateBigDecimalPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 }).Coeffs)) { throw new Exception("The BigDecimalPolynomial test failed!"); } // multiply a polynomial by its inverse modulo 2048 and check that the result is 1 IntegerPolynomial d, dInv; CSPRng rng = new CSPRng(); do { d = DenseTernaryPolynomial.GenerateRandom(1001, 333, 334, rng); dInv = d.InvertFq(2048); } while (dInv == null); d.Mod(2048); BigDecimalPolynomial e = CreateBigDecimalPolynomial(d.Coeffs); BigIntPolynomial f = new BigIntPolynomial(dInv); IntegerPolynomial g = new IntegerPolynomial(e.Multiply(f).Round()); g.ModPositive(2048); if (!g.EqualsOne()) { throw new Exception("The BigDecimalPolynomial test failed!"); } OnProgress(new TestEventArgs("Passed BigDecimalPolynomial tests")); return(SUCCESS); } catch (Exception Ex) { string message = Ex.Message == null ? "" : Ex.Message; throw new Exception(FAILURE + message); } }
/** tests mult(IntegerPolynomial) and mult(BigIntPolynomial) */ private void MultTest() { CSPRng rng = new CSPRng(); SparseTernaryPolynomial p1 = SparseTernaryPolynomial.GenerateRandom(1000, 500, 500, rng); IntegerPolynomial p2 = PolynomialGeneratorForTesting.generateRandom(1000); IntegerPolynomial prod1 = p1.Multiply(p2); prod1 = p1.Multiply(p2); IntegerPolynomial prod2 = p1.Multiply(p2); if (!Compare.Equals(prod1, prod2)) { throw new Exception("SparseTernaryPolynomial multiplication test failed!"); } BigIntPolynomial p3 = new BigIntPolynomial(p2); BigIntPolynomial prod3 = p1.Multiply(p3); if (!Compare.Equals(new BigIntPolynomial(prod1), prod3)) { throw new Exception("SparseTernaryPolynomial multiplication test failed!"); } }
/** * Creates a NtruSign basis consisting of polynomials <code>f, g, F, G, h</code>.<br/> * If <code>KeyGenAlg=FLOAT</code>, the basis may not be valid and this method must be rerun if that is the case.<br/> * @see #generateBoundedBasis() */ private FGBasis generateBasis() { int N = param.N; int q = param.q; int d = param.d; int d1 = param.d1; int d2 = param.d2; int d3 = param.d3; BasisType basisType = param.basisType; IPolynomial f; IntegerPolynomial fInt; IPolynomial g; IntegerPolynomial gInt; IntegerPolynomial fq; Resultant rf; Resultant rg; BigIntEuclidean r; int _2n1 = 2 * N + 1; bool primeCheck = param.primeCheck; Random rng = new Random(); do { do { if (param.polyType == TernaryPolynomialType.SIMPLE) { f = DenseTernaryPolynomial.GenerateRandom(N, d + 1, d); } else { f = ProductFormPolynomial.GenerateRandom(N, d1, d2, d3 + 1, d3); } fInt = f.ToIntegerPolynomial(); } while (primeCheck && fInt.Resultant(_2n1).Res.Equals(BigInteger.Zero)); fq = fInt.InvertFq(q); } while (fq == null); rf = fInt.Resultant(); do { do { do { if (param.polyType == TernaryPolynomialType.SIMPLE) { g = DenseTernaryPolynomial.GenerateRandom(N, d + 1, d); } else { g = ProductFormPolynomial.GenerateRandom(N, d1, d2, d3 + 1, d3); } gInt = g.ToIntegerPolynomial(); } while (primeCheck && gInt.Resultant(_2n1).Res.Equals(BigInteger.Zero)); } while (!gInt.IsInvertiblePow2()); rg = gInt.Resultant(); r = BigIntEuclidean.Calculate(rf.Res, rg.Res); } while (!r.GCD.Equals(BigInteger.One)); BigIntPolynomial A = rf.Rho.Clone(); A.Multiply(r.X.Multiply(BigInteger.ValueOf(q))); BigIntPolynomial B = rg.Rho.Clone(); B.Multiply(r.Y.Multiply(BigInteger.ValueOf(-q))); BigIntPolynomial C; if (param.keyGenAlg == KeyGenAlg.RESULTANT) { int[] fRevCoeffs = new int[N]; int[] gRevCoeffs = new int[N]; fRevCoeffs[0] = fInt.Coeffs[0]; gRevCoeffs[0] = gInt.Coeffs[0]; for (int i = 1; i < N; i++) { fRevCoeffs[i] = fInt.Coeffs[N - i]; gRevCoeffs[i] = gInt.Coeffs[N - i]; } IntegerPolynomial fRev = new IntegerPolynomial(fRevCoeffs); IntegerPolynomial gRev = new IntegerPolynomial(gRevCoeffs); IntegerPolynomial t = f.Multiply(fRev); t.Add(g.Multiply(gRev)); Resultant rt = t.Resultant(); C = fRev.Multiply(B); // fRev.mult(B) is actually faster than new SparseTernaryPolynomial(fRev).mult(B), possibly due to cache locality? C.Add(gRev.Multiply(A)); C = C.MultBig(rt.Rho); C.Divide(rt.Res); } else // KeyGenAlg.FLOAT // calculate ceil(log10(N)) { int log10N = 0; for (int i = 1; i < N; i *= 10) { log10N++; } // * Cdec needs to be accurate to 1 decimal place so it can be correctly rounded; // * fInv loses up to (#digits of longest coeff of B) places in fInv.mult(B); // * multiplying fInv by B also multiplies the rounding error by a factor of N; // so make #decimal places of fInv the sum of the above. BigDecimalPolynomial fInv = rf.Rho.Divide(new BigDecimal(rf.Res), B.GetMaxCoeffLength() + 1 + log10N); BigDecimalPolynomial gInv = rg.Rho.Divide(new BigDecimal(rg.Res), A.GetMaxCoeffLength() + 1 + log10N); BigDecimalPolynomial Cdec = fInv.Multiply(B); Cdec.Add(gInv.Multiply(A)); Cdec.Halve(); C = Cdec.Round(); } BigIntPolynomial F = B.Clone(); F.Subtract(f.Multiply(C)); BigIntPolynomial G = A.Clone(); G.Subtract(g.Multiply(C)); IntegerPolynomial FInt = new IntegerPolynomial(F); IntegerPolynomial GInt = new IntegerPolynomial(G); minimizeFG(fInt, gInt, FInt, GInt, N); IPolynomial fPrime; IntegerPolynomial h; if (basisType == BasisType.STANDARD) { fPrime = FInt; h = g.Multiply(fq, q); } else { fPrime = g; h = FInt.Multiply(fq, q); } h.ModPositive(q); return(new FGBasis(f, fPrime, h, FInt, GInt, param.q, param.polyType, param.basisType, param.keyNormBoundSq)); }