// 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!"); } }
public IntegerPolynomial createMsgRep(byte[] msgHash, int r) { int N = param.N; int q = param.q; int c = 31 - IntUtils.numberOfLeadingZeros(q); int B = (c + 7) / 8; IntegerPolynomial i = new IntegerPolynomial(N); MemoryStream cbuf = new MemoryStream(msgHash.Length + 4); BinaryWriter bwr = new BinaryWriter(cbuf); bwr.Write(msgHash); bwr.Write(r); Prng prng = new Prng(cbuf.ToArray(), param.hashAlg); for (int t = 0; t < N; t++) { byte[] o = prng.nextBytes(B); int hi = o[o.Length - 1]; hi >>= 8 * B - c; hi <<= 8 * B - c; o[o.Length - 1] = (byte)hi; MemoryStream obuf = new MemoryStream(4); BinaryWriter bwr2 = new BinaryWriter(obuf); bwr2.Write(o); obuf.Position = 0; // reverse byte order so it matches the endianness of java ints i.Coeffs[t] = ArrayUtils.ReverseBytes(obuf.ToArray()); } return(i); }
private void DivTest() { Random rng = new Random(); for (int i = 0; i < 10; i++) { IntegerPolynomial poly = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(439, 10000); // test special case: division by 2048 IntegerPolynomial a = poly.Clone(); a.Divide(2048); for (int j = 0; j < poly.Coeffs.Length; j++) { if (!Compare.Equals((int)Math.Floor((((double)poly.Coeffs[j]) / 2048) + 0.5), a.Coeffs[j])) { throw new Exception("IntegerPolynomialTest division test failed!"); } } // test the general case a = poly.Clone(); int k = rng.Next(2047) + 1; a.Divide(k); for (int j = 0; j < poly.Coeffs.Length; j++) { if (!Compare.Equals((int)Math.Floor(((double)poly.Coeffs[j] / k) + 0.5), a.Coeffs[j])) { throw new Exception("IntegerPolynomialTest division test failed!"); } } } }
private void InvertFq() { // Verify an example from the NTRU tutorial IntegerPolynomial a = new IntegerPolynomial(new int[] { -1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1 }); IntegerPolynomial b = a.InvertFq(32); AssertEqualsMod(new int[] { 5, 9, 6, 16, 4, 15, 16, 22, 20, 18, 30 }, b.Coeffs, 32); VerifyInverse(a, b, 32); // test 3 random polynomials int numInvertible = 0; while (numInvertible < 3) { a = (IntegerPolynomial)PolynomialGeneratorForTesting.generateRandom(853); b = a.InvertFq(2048); if (b != null) { numInvertible++; VerifyInverse(a, b, 2048); } } // test a non-invertible polynomial a = new IntegerPolynomial(new int[] { -1, 0, 1, 1, 0, 0, -1, 0, -1, 0, 1 }); b = a.InvertFq(32); if (b != null) { throw new Exception("IntegerPolynomialTest InvertFq test failed!"); } }
private void MultTest() { IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 }); IntegerPolynomial i2 = new IntegerPolynomial(new int[] { 1729, 1924, 806, 179, 1530, 1381, 1695, 60 }); LongPolynomial2 a = new LongPolynomial2(i1); LongPolynomial2 b = new LongPolynomial2(i2); IntegerPolynomial c1 = i1.Multiply(i2, 2048); IntegerPolynomial c2 = a.Multiply(b).ToIntegerPolynomial(); if (!Compare.AreEqual(c1.Coeffs, c2.Coeffs)) { throw new Exception("LongPolynomial2 multiply test failed!"); } // test 10 random polynomials Random rng = new Random(); for (int i = 0; i < 10; i++) { int N = 2 + rng.Next(2000); i1 = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(N, 2048); i2 = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(N, 2048); a = new LongPolynomial2(i1); b = new LongPolynomial2(i2); c1 = i1.Multiply(i2); c1.ModPositive(2048); c2 = a.Multiply(b).ToIntegerPolynomial(); if (!Compare.AreEqual(c1.Coeffs, c2.Coeffs)) { throw new Exception("LongPolynomial2 multiply test failed!"); } } }
/** * Reads a basis from an input stream and constructs a new basis. * @param is an input stream * @param params NtruSign parameters * @param include_h whether to read the polynomial <code>h</code> (<code>true</code>) or only <code>f</code> and <code>f'</code> (<code>false</code>) * @throws IOException */ public Basis(MemoryStream ins, int N, int q, bool sparse, TernaryPolynomialType polyType, BasisType basisType, double keyNormBoundSq, bool include_h) { this.N = N; this.q = q; this.polyType = polyType; this.basisType = basisType; this.keyNormBoundSq = keyNormBoundSq; if (polyType == TernaryPolynomialType.PRODUCT) f = ProductFormPolynomial.FromBinary(ins, N); else { IntegerPolynomial fInt = IntegerPolynomial.FromBinary3Tight(ins, N); if (sparse) f = new SparseTernaryPolynomial(fInt); else f = new DenseTernaryPolynomial(fInt); } if (basisType == BasisType.STANDARD) { IntegerPolynomial fPrimeInt = IntegerPolynomial.FromBinary(ins, N, q); for (int i = 0; i < fPrimeInt.Coeffs.Length; i++) fPrimeInt.Coeffs[i] -= q / 2; fPrime = fPrimeInt; } else if (polyType == TernaryPolynomialType.PRODUCT) fPrime = ProductFormPolynomial.FromBinary(ins, N); else fPrime = IntegerPolynomial.FromBinary3Tight(ins, N); if (include_h) h = IntegerPolynomial.FromBinary(ins, N, q); }
public void testMult() { IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 }); IntegerPolynomial i2 = new IntegerPolynomial(new int[] { 1729, 1924, 806, 179, 1530, 1381, 1695, 60 }); LongPolynomial2 a = new LongPolynomial2(i1); LongPolynomial2 b = new LongPolynomial2(i2); IntegerPolynomial c1 = i1.Multiply(i2, 2048); IntegerPolynomial c2 = a.Multiply(b).ToIntegerPolynomial(); Assert.True(c1.coeffs.SequenceEqual(c2.coeffs)); SecureRandom rng = new SecureRandom(); for (int i = 0; i < 10; i++) { int N = 2 + rng.NextInt(2000); i1 = PolynomialGenerator.GenerateRandom(N, 2048); i2 = PolynomialGenerator.GenerateRandom(N, 2048); a = new LongPolynomial2(i1); b = new LongPolynomial2(i2); c1 = i1.Multiply(i2); c1.ModPositive(2048); c2 = a.Multiply(b).ToIntegerPolynomial(); Assert.True(c1.coeffs.SequenceEqual(c2.coeffs)); } }
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()); }
private void IsValid() { // test valid key pairs NtruSign ntru = null; SignatureKeyPair kp = null; SignatureParameters[] paramSets = new SignatureParameters[] { SignatureParameters.TEST157, SignatureParameters.TEST157_PROD }; foreach (SignatureParameters param in paramSets) { ntru = new NtruSign(param); kp = ntru.generateKeyPair(); Assert.True(kp.isValid()); } // test an invalid key pair int q = kp.pub.q; kp.pub.h.Multiply(101); // make h invalid kp.pub.h.ModPositive(q); Assert.False(kp.isValid()); int inv101 = IntEuclidean.Calculate(101, q).X; kp.pub.h.Multiply(inv101); // restore h kp.pub.h.ModPositive(q); IntegerPolynomial f = kp.priv.getBasis(0).f.ToIntegerPolynomial(); f.Multiply(3); // make f invalid kp.priv.getBasis(0).f = f; Assert.False(kp.isValid()); }
public void testMult() { // multiplication modulo q IntegerPolynomial a = new IntegerPolynomial(new int[] { -1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1 }); IntegerPolynomial b = new IntegerPolynomial(new int[] { 14, 11, 26, 24, 14, 16, 30, 7, 25, 6, 19 }); IntegerPolynomial c = a.Multiply(b, 32); assertEqualsMod(new int[] { 3, -7, -10, -11, 10, 7, 6, 7, 5, -3, -7 }, c.coeffs, 32); a = new IntegerPolynomial(new int[] { 15, 27, 18, 16, 12, 13, 16, 2, 28, 22, 26 }); b = new IntegerPolynomial(new int[] { -1, 0, 1, 1, 0, 1, 0, 0, -1, 0, -1 }); c = a.Multiply(b, 32); assertEqualsMod(new int[] { 8, 25, 22, 20, 12, 24, 15, 19, 12, 19, 16 }, c.coeffs, 32); // multiplication without a modulus a = new IntegerPolynomial(new int[] { 1, 1, 0, 0, -1, -1, 0, 0, -1, 0, 1 }); b = new IntegerPolynomial(new int[] { 704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); c = a.Multiply(b); // mult(p, modulus) should give the same result as mult(p) followed by modulus a = new IntegerPolynomial(new int[] { 1, 0, -1, 1, 0, 1, 1, 1, -1, 1, -1 }); b = new IntegerPolynomial(new int[] { 0, 1, 1, 0, 0, -1, -1, 1, 1, -1, 1 }); c = a.Multiply(b); c.ModPositive(20); IntegerPolynomial d = a.Multiply(b, 20); d.ModPositive(20); Assert.True(c.coeffs.SequenceEqual(d.coeffs)); }
public void testInvertFq() { SecureRandom random = new SecureRandom(); // Verify an example from the NTRU tutorial IntegerPolynomial a = new IntegerPolynomial(new int[] { -1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1 }); IntegerPolynomial b = a.InvertFq(32); assertEqualsMod(new int[] { 5, 9, 6, 16, 4, 15, 16, 22, 20, 18, 30 }, b.coeffs, 32); verifyInverse(a, b, 32); // test 3 random polynomials int numInvertible = 0; while (numInvertible < 3) { a = DenseTernaryPolynomial.GenerateRandom(853, random); b = a.InvertFq(2048); if (b != null) { numInvertible++; verifyInverse(a, b, 2048); } } // test a non-invertible polynomial a = new IntegerPolynomial(new int[] { -1, 0, 1, 1, 0, 0, -1, 0, -1, 0, 1 }); b = a.InvertFq(32); Assert.IsNull(b); }
public void testResultant() { SecureRandom random = new SecureRandom(); NTRUSigningKeyGenerationParameters parameters = NTRUSigningKeyGenerationParameters.APR2011_439; IntegerPolynomial a = DenseTernaryPolynomial.GenerateRandom(parameters.N, parameters.d, parameters.d, random); Resultant r = a.Resultant(); if (r.Rho.GetCoeffs().Length > parameters.N) { BigInteger[] trimmedArray = new BigInteger[parameters.N]; Array.Copy(r.Rho.GetCoeffs(), trimmedArray, parameters.N); r.Rho.coeffs = trimmedArray; } verifyResultant(a, r); a = new IntegerPolynomial(new int[] { 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, -1, -1, 0, -1, 1, -1, 0, -1, 0, -1, -1, -1, 0, 0, 0, 1, 1, -1, -1, -1, 0, -1, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 1, 1, -1, 0, 1, -1, 0, 1, 0, 1, 0, -1, -1, 0, 1, 0, -1, 1, 1, 1, 1, 0, 0, -1, -1, 1, 0, 0, -1, -1, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, -1, 0, 0, 1, 1, 1, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0, -1, -1, 0, -1, -1, -1, 0, -1, -1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 1, 1, 0, 0, -1, 1, 0, 0, 0, -1, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 1, 1, 0, 0, -1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, 0, -1, -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, -1, 1, -1, -1, 1, -1, 0, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, -1, 0, 1, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, -1, 0, -1, 1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 1, -1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, -1, -1, 0, 0, -1, 0, 1, 1, -1, 1, -1, 0, 0, 0, 1 }); r = a.Resultant(); if (r.Rho.GetCoeffs().Length > a.coeffs.Length) { BigInteger[] trimmedArray = new BigInteger[a.coeffs.Length]; Array.Copy(r.Rho.GetCoeffs(), trimmedArray, a.coeffs.Length); r.Rho.coeffs = trimmedArray; } verifyResultant(a, r); }
public void testFromToBinary3Tight() { int[] c = new int[] { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 1, 0, 1, 0, -1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0 }; IntegerPolynomial poly1 = new IntegerPolynomial(c); IntegerPolynomial poly2 = IntegerPolynomial.FromBinary3Tight(poly1.ToBinary3Tight(), c.Length); Assert.True(poly1.coeffs.SequenceEqual(poly2.coeffs)); IntegerPolynomial poly3 = new IntegerPolynomial(new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }); byte[] arr = poly3.ToBinary3Tight(); IntegerPolynomial poly4 = IntegerPolynomial.FromBinary3Tight(arr, 1499); Assert.True(poly3.coeffs.SequenceEqual(poly4.coeffs)); IntegerPolynomial poly5 = new IntegerPolynomial(new int[] { 0, 0, 0, 1, -1, -1, -1 }); arr = poly5.ToBinary3Tight(); IntegerPolynomial poly6 = IntegerPolynomial.FromBinary3Tight(arr, 7); Assert.True(poly5.coeffs.SequenceEqual(poly6.coeffs)); SecureRandom random = new SecureRandom(); for (int i = 0; i < 100; i++) { IntegerPolynomial poly7 = DenseTernaryPolynomial.GenerateRandom(157, random); arr = poly7.ToBinary3Tight(); IntegerPolynomial poly8 = IntegerPolynomial.FromBinary3Tight(arr, 157); Assert.True(poly7.coeffs.SequenceEqual(poly8.coeffs)); } }
/// <summary> /// Multiplies the polynomial by an <c>IntegerPolynomial</c>, /// taking the coefficient values mod <c>modulus</c> and the indices mod <c>N</c>. /// </summary> /// /// <param name="Factor">A polynomial factor</param> /// <param name="Modulus">The modulus to apply</param> /// /// <returns>The product of the two polynomials</returns> public IntegerPolynomial Multiply(IntegerPolynomial Factor, int Modulus) { IntegerPolynomial c = Multiply(Factor); c.Mod(Modulus); return(c); }
/// <summary> /// Returns a polynomial that is equal to this polynomial (in the sense that mult(IntegerPolynomial, int) /// returns equal <c>IntegerPolynomial</c>s). The new polynomial is guaranteed to be independent of the original. /// </summary> /// /// <returns>The polynomial product</returns> public IntegerPolynomial ToIntegerPolynomial() { IntegerPolynomial i = m_f1.Multiply(m_f2.ToIntegerPolynomial()); i.Add(m_f3); return(i); }
/// <summary> /// Constructs a <c>BigIntPolynomial</c> from a <c>IntegerPolynomial</c>. The two polynomials are /// independent of each other. /// </summary> /// /// <param name="P">The original polynomial</param> public BigIntPolynomial(IntegerPolynomial P) { Coeffs = new BigInteger[P.Coeffs.Length]; for (int i = 0; i < Coeffs.Length; i++) { Coeffs[i] = BigInteger.ValueOf(P.Coeffs[i]); } }
private IntegerPolynomial sign(IntegerPolynomial i, SignatureKeyPair kp) { int N = param.N; int q = param.q; int perturbationBases = param.B; IntegerPolynomial s = new IntegerPolynomial(N); int iLoop = perturbationBases; while (iLoop >= 1) { IPolynomial f = kp.priv.getBasis(iLoop).f; IPolynomial fPrime = kp.priv.getBasis(iLoop).fPrime; IntegerPolynomial y = f.Multiply(i); y.Divide(q); y = fPrime.Multiply(y); IntegerPolynomial x = fPrime.Multiply(i); x.Divide(q); x = f.Multiply(x); IntegerPolynomial si = y; si.Subtract(x); s.Add(si); IntegerPolynomial hi = kp.priv.getBasis(iLoop).h.Clone(); if (iLoop > 1) { hi.Subtract(kp.priv.getBasis(iLoop - 1).h); } else { hi.Subtract(kp.pub.h); } i = si.Multiply(hi, q); iLoop--; } IPolynomial f2 = kp.priv.getBasis(0).f; IPolynomial fPrime2 = kp.priv.getBasis(0).fPrime; IntegerPolynomial y2 = f2.Multiply(i); y2.Divide(q); y2 = fPrime2.Multiply(y2); IntegerPolynomial x2 = fPrime2.Multiply(i); x2.Divide(q); x2 = f2.Multiply(x2); y2.Subtract(x2); s.Add(y2); s.ModPositive(q); return(s); }
/// <summary> /// Multiplies the polynomial by an <c>IntegerPolynomial</c>, /// taking the indices mod <c>N</c>. /// </summary> /// /// <param name="Factor">A polynomial factor</param> /// /// <returns>The product of the two polynomials</returns> public IntegerPolynomial Multiply(IntegerPolynomial Factor) { IntegerPolynomial c = m_f1.Multiply(Factor); c = m_f2.Multiply(c); c.Add(m_f3.Multiply(Factor)); return(c); }
public void testFromToBinary3Sves() { sbyte[] signed = new sbyte[] { -112, -78, 19, 15, 99, -65, -56, -90, 44, -93, -109, 104, 40, 90, -84, -21, -124, 51, -33, 4, -51, -106, 33, 86, -76, 42, 41, -17, 47, 79, 81, -29, 15, 116, 101, 120, 116, 32, 116, 111, 32, 101, 110, 99, 114, 121, 112, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; byte[] a = (byte[])(Array)signed; IntegerPolynomial poly = IntegerPolynomial.FromBinary3Sves(a, 1499); byte[] b = poly.ToBinary3Sves(); Assert.True(a.SequenceEqual(b)); }
private void ToBinary4() { IntegerPolynomial a = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(743, 2048); if (!Compare.AreEqual(a.ToBinary(4), a.ToBinary4())) { throw new Exception("IntegerPolynomialTest ToBinary4 test failed!"); } }
public FGBasis(IPolynomial f, IPolynomial fPrime, IntegerPolynomial h, IntegerPolynomial F, IntegerPolynomial G, int q, TernaryPolynomialType polyType, BasisType basisType, double keyNormBoundSq) : base(f, fPrime, h, q, polyType, basisType, keyNormBoundSq) { ; this.F = F; this.G = G; this.q = q; this.keyNormBoundSq = keyNormBoundSq; }
public void testMult() { ProductFormPolynomial p1 = ProductFormPolynomial.GenerateRandom(N, df1, df2, df3, df3 - 1, new SecureRandom()); IntegerPolynomial p2 = PolynomialGenerator.GenerateRandom(N, q); IntegerPolynomial p3 = p1.Multiply(p2); IntegerPolynomial p4 = p1.ToIntegerPolynomial().Multiply(p2); Assert.AreEqual(p3.ToIntegerPolynomial().coeffs, p4.ToIntegerPolynomial().coeffs); }
/// <summary> /// Constructs a new private key from a polynomial /// </summary> /// /// <param name="T">The polynomial which determines the key: if <c>FastFp=true</c>, <c>f=1+3T</c>; otherwise, <c>f=T</c></param> /// <param name="FP">Fp the inverse of <c>f</c></param> /// <param name="N">The number of polynomial coefficients</param> /// <param name="Q">The big q modulus</param> /// <param name="Sparse">Sparse whether the polynomial <c>T</c> is sparsely or densely populated</param> /// <param name="FastFp">FastFp whether <c>FP=1</c></param> /// <param name="PolyType">PolyType type of the polynomial <c>T</c></param> internal NTRUPrivateKey(IPolynomial T, IntegerPolynomial FP, int N, int Q, bool Sparse, bool FastFp, TernaryPolynomialType PolyType) { m_T = T; m_FP = FP; m_N = N; m_Q = Q; m_sparse = Sparse; m_fastFp = FastFp; m_polyType = PolyType; }
public void testMult2And() { IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 }); LongPolynomial2 i2 = new LongPolynomial2(i1); i2.mult2And(2047); i1.Multiply(2); i1.ModPositive(2048); Assert.True(i1.coeffs.SequenceEqual(i2.ToIntegerPolynomial().coeffs)); }
/// <summary> /// Read a Private key from a stream /// </summary> /// /// <param name="KeyStream">The stream containing the key</param> /// /// <returns>An initialized NTRUPrivateKey class</returns> /// /// <exception cref="NTRUException">Thrown if the stream can not be read</exception> public static NTRUPrivateKey From(MemoryStream KeyStream) { BinaryReader dataStream = new BinaryReader(KeyStream); try { // ins.Position = 0; wrong here, ins pos is wrong int n = IntUtils.ReadShort(KeyStream); int q = IntUtils.ReadShort(KeyStream); byte flags = dataStream.ReadByte(); bool sparse = (flags & 1) != 0; bool fastFp = (flags & 2) != 0; IPolynomial t; TernaryPolynomialType polyType = (flags & 4) == 0 ? TernaryPolynomialType.SIMPLE : TernaryPolynomialType.PRODUCT; if (polyType == TernaryPolynomialType.PRODUCT) { t = ProductFormPolynomial.FromBinary(KeyStream, n); } else { IntegerPolynomial fInt = IntegerPolynomial.FromBinary3Tight(KeyStream, n); if (sparse) { t = new SparseTernaryPolynomial(fInt); } else { t = new DenseTernaryPolynomial(fInt); } } // Initializes fp from t IntegerPolynomial fp; if (fastFp) { fp = new IntegerPolynomial(n); fp.Coeffs[0] = 1; } else { fp = t.ToIntegerPolynomial().InvertF3(); } return(new NTRUPrivateKey(t, fp, n, q, sparse, fastFp, polyType)); } catch (IOException ex) { throw new NTRUException("NTRUPrivateKey:From", ex.Message, ex); } }
/** * Constructs a new basis from polynomials <code>f, f', h</code>. * @param f * @param fPrime * @param h * @param params NtruSign parameters */ public Basis(IPolynomial f, IPolynomial fPrime, IntegerPolynomial h, int q, TernaryPolynomialType polyType, BasisType basisType, double keyNormBoundSq) { this.f = f; this.fPrime = fPrime; this.h = h; this.N = h.Coeffs.Length; this.q = q; this.polyType = polyType; this.basisType = basisType; this.keyNormBoundSq = keyNormBoundSq; }
// tests if a*b=1 (mod modulus) private void verifyInverse(IntegerPolynomial a, IntegerPolynomial b, int modulus) { IntegerPolynomial c = a.Multiply(b, modulus); for (int i = 1; i < c.coeffs.Length; i++) { c.coeffs[i] %= modulus; } c.EnsurePositive(modulus); Assert.True(c.EqualsOne()); }
private void testMult(int[] coeffs1, int[] coeffs2) { IntegerPolynomial i1 = new IntegerPolynomial(coeffs1); IntegerPolynomial i2 = new IntegerPolynomial(coeffs2); LongPolynomial5 a = new LongPolynomial5(i1); DenseTernaryPolynomial b = new DenseTernaryPolynomial(i2); IntegerPolynomial c1 = i1.Multiply(i2, 2048); IntegerPolynomial c2 = a.Multiply(b).ToIntegerPolynomial(); assertEqualsMod(c1.coeffs, c2.coeffs, 2048); }
private bool verifyHash(byte[] msgHash, byte[] sig, SignaturePublicKey pub) { MemoryStream sbuf = new MemoryStream(sig); BinaryReader brr = new BinaryReader(sbuf); byte[] rawSig = new byte[sig.Length - 4]; rawSig = brr.ReadBytes(rawSig.Length); IntegerPolynomial s = IntegerPolynomial.FromBinary(rawSig, param.N, param.q); int r = brr.ReadInt32(); return(verify(createMsgRep(msgHash, r), s, pub.h)); }
/** * Implementation of the optional steps 20 through 26 in EESS1v2.pdf, section 3.5.1.1. * This doesn't seem to have much of an effect and sometimes actually increases the * norm of F, but on average it slightly reduces the norm.<br/> * This method changes <code>F</code> and <code>G</code> but leaves <code>f</code> and * <code>g</code> unchanged. * @param f * @param g * @param F * @param G * @param N */ private void minimizeFG(IntegerPolynomial f, IntegerPolynomial g, IntegerPolynomial F, IntegerPolynomial G, int N) { int E = 0; for (int j = 0; j < N; j++) { E += 2 * N * (f.Coeffs[j] * f.Coeffs[j] + g.Coeffs[j] * g.Coeffs[j]); } // [f(1)+g(1)]^2 = 4 E -= 4; IntegerPolynomial u = f.Clone(); IntegerPolynomial v = g.Clone(); int j2 = 0; int k = 0; int maxAdjustment = N; while (k < maxAdjustment && j2 < N) { int D = 0; int i = 0; while (i < N) { int D1 = F.Coeffs[i] * f.Coeffs[i]; int D2 = G.Coeffs[i] * g.Coeffs[i]; int D3 = 4 * N * (D1 + D2); D += D3; i++; } // f(1)+g(1) = 2 int D4 = 4 * (F.SumCoeffs() + G.SumCoeffs()); D -= D4; if (D > E) { F.Subtract(u); G.Subtract(v); k++; j2 = 0; } else if (D < -E) { F.Add(u); G.Add(v); k++; j2 = 0; } j2++; u.Rotate1(); v.Rotate1(); } }
public void testSubAnd() { IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 }); IntegerPolynomial i2 = new IntegerPolynomial(new int[] { 1729, 1924, 806, 179, 1530, 1381, 1695, 60 }); LongPolynomial2 a = new LongPolynomial2(i1); LongPolynomial2 b = new LongPolynomial2(i2); a.SubAnd(b, 2047); i1.Sub(i2); i1.ModPositive(2048); Assert.True(a.ToIntegerPolynomial().coeffs.SequenceEqual(i1.coeffs)); }
/** * Reconstructs a public key from its <code>byte</code> array representation. * @param is an input stream containing an encoded key * @throws NtruException if an {@link IOException} occurs * @see #writeTo(OutputStream) */ public SignaturePublicKey(MemoryStream ins) { BinaryReader dataStream = new BinaryReader(ins); try { int N = dataStream.ReadInt16(); q = dataStream.ReadInt16(); h = IntegerPolynomial.FromBinary(ins, N, q); } catch (IOException e) { throw new NtruException(e.Message); } }
/** * Constructs a new public key from a polynomial * @param h the polynomial <code>h</code> which determines the key * @param q the modulus */ public SignaturePublicKey(IntegerPolynomial h, int q) { this.h = h; this.q = q; }
/** * Tests if the basis is valid. * @param h the polynomial h (either from the public key or from this basis) * @return <code>true</code> if the basis is valid, <code>false</code> otherwise */ public bool isValid(IntegerPolynomial h) { if (f.ToIntegerPolynomial().Coeffs.Length != N) return false; if (fPrime.ToIntegerPolynomial().Coeffs.Length != N) return false; if (h.Coeffs.Length != N || !h.IsReduced(q)) return false; // determine F, G, g from f, fPrime, h using the eqn. fG-Fg=q IPolynomial FPoly = basisType == BasisType.STANDARD ? fPrime : f.Multiply(h, q); IntegerPolynomial F = FPoly.ToIntegerPolynomial(); IntegerPolynomial fq = f.ToIntegerPolynomial().InvertFq(q); IPolynomial g; if (basisType == BasisType.STANDARD) g = f.Multiply(h, q); else g = fPrime; IntegerPolynomial G = g.Multiply(F); G.Coeffs[0] -= q; G = G.Multiply(fq, q); G.ModCenter(q); // check norms of F and G if (!new FGBasis(f, fPrime, h, F, G, q, polyType, basisType, keyNormBoundSq).isNormOk()) return false; // check norms of f and g int factor = N / 24; if (f.ToIntegerPolynomial().CenteredNormSq(q) * factor >= F.CenteredNormSq(q)) return false; if (g.ToIntegerPolynomial().CenteredNormSq(q) * factor >= G.CenteredNormSq(q)) return false; // check ternarity if (polyType == TernaryPolynomialType.SIMPLE) { if (!f.ToIntegerPolynomial().IsTernary()) return false; if (!g.ToIntegerPolynomial().IsTernary()) return false; } else { if (!(f.GetType().IsAssignableFrom(typeof(ProductFormPolynomial)))) return false; if (!(g.GetType().IsAssignableFrom(typeof(ProductFormPolynomial)))) return false; } return true; }
private IntegerPolynomial sign(IntegerPolynomial i, SignatureKeyPair kp) { int N = param.N; int q = param.q; int perturbationBases = param.B; IntegerPolynomial s = new IntegerPolynomial(N); int iLoop = perturbationBases; while (iLoop >= 1) { IPolynomial f = kp.priv.getBasis(iLoop).f; IPolynomial fPrime = kp.priv.getBasis(iLoop).fPrime; IntegerPolynomial y = f.Multiply(i); y.Divide(q); y = fPrime.Multiply(y); IntegerPolynomial x = fPrime.Multiply(i); x.Divide(q); x = f.Multiply(x); IntegerPolynomial si = y; si.Subtract(x); s.Add(si); IntegerPolynomial hi = kp.priv.getBasis(iLoop).h.Clone(); if (iLoop > 1) hi.Subtract(kp.priv.getBasis(iLoop - 1).h); else hi.Subtract(kp.pub.h); i = si.Multiply(hi, q); iLoop--; } IPolynomial f2 = kp.priv.getBasis(0).f; IPolynomial fPrime2 = kp.priv.getBasis(0).fPrime; IntegerPolynomial y2 = f2.Multiply(i); y2.Divide(q); y2 = fPrime2.Multiply(y2); IntegerPolynomial x2 = fPrime2.Multiply(i); x2.Divide(q); x2 = f2.Multiply(x2); y2.Subtract(x2); s.Add(y2); s.ModPositive(q); return s; }
private bool verify(IntegerPolynomial i, IntegerPolynomial s, IntegerPolynomial h) { int q = param.q; double normBoundSq = param.normBoundSq; double betaSq = param.betaSq; IntegerPolynomial t = h.Multiply(s, q); t.Subtract(i); long centeredNormSq = (long)(s.CenteredNormSq(q) + betaSq * t.CenteredNormSq(q)); return centeredNormSq <= normBoundSq; }
public IntegerPolynomial createMsgRep(byte[] msgHash, int r) { int N = param.N; int q = param.q; int c = 31 - IntUtils.numberOfLeadingZeros(q); int B = (c + 7) / 8; IntegerPolynomial i = new IntegerPolynomial(N); MemoryStream cbuf = new MemoryStream(msgHash.Length + 4); BinaryWriter bwr = new BinaryWriter(cbuf); bwr.Write(msgHash); bwr.Write(r); Prng prng = new Prng(cbuf.ToArray(), param.hashAlg); for (int t = 0; t < N; t++) { byte[] o = prng.nextBytes(B); int hi = o[o.Length - 1]; hi >>= 8 * B - c; hi <<= 8 * B - c; o[o.Length - 1] = (byte)hi; MemoryStream obuf = new MemoryStream(4); BinaryWriter bwr2 = new BinaryWriter(obuf); bwr2.Write(o); obuf.Position = 0; // reverse byte order so it matches the endianness of java ints i.Coeffs[t] = ArrayUtils.ReverseBytes(obuf.ToArray()); } return i; }
// verifies that f*G-g*F=q private bool EqualsQ(NTRU.Polynomial.IPolynomial f, NTRU.Polynomial.IPolynomial g, IntegerPolynomial F, IntegerPolynomial G, int q, int N) { IntegerPolynomial x = f.Multiply(G); x.Subtract(g.Multiply(F)); bool equalsQ = true; for (int i = 1; i < x.Coeffs.Length; i++) equalsQ &= x.Coeffs[i] == 0; equalsQ &= x.Coeffs[0] == q; return equalsQ; }
/** * 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); }
/** * Implementation of the optional steps 20 through 26 in EESS1v2.pdf, section 3.5.1.1. * This doesn't seem to have much of an effect and sometimes actually increases the * norm of F, but on average it slightly reduces the norm.<br/> * This method changes <code>F</code> and <code>G</code> but leaves <code>f</code> and * <code>g</code> unchanged. * @param f * @param g * @param F * @param G * @param N */ private void minimizeFG(IntegerPolynomial f, IntegerPolynomial g, IntegerPolynomial F, IntegerPolynomial G, int N) { int E = 0; for (int j = 0; j < N; j++) E += 2 * N * (f.Coeffs[j] * f.Coeffs[j] + g.Coeffs[j] * g.Coeffs[j]); // [f(1)+g(1)]^2 = 4 E -= 4; IntegerPolynomial u = f.Clone(); IntegerPolynomial v = g.Clone(); int j2 = 0; int k = 0; int maxAdjustment = N; while (k < maxAdjustment && j2 < N) { int D = 0; int i = 0; while (i < N) { int D1 = F.Coeffs[i] * f.Coeffs[i]; int D2 = G.Coeffs[i] * g.Coeffs[i]; int D3 = 4 * N * (D1 + D2); D += D3; i++; } // f(1)+g(1) = 2 int D4 = 4 * (F.SumCoeffs() + G.SumCoeffs()); D -= D4; if (D > E) { F.Subtract(u); G.Subtract(v); k++; j2 = 0; } else if (D < -E) { F.Add(u); G.Add(v); k++; j2 = 0; } j2++; u.Rotate1(); v.Rotate1(); } }