private void InitUpdateSign(SignatureParameters param)
        {
            NtruSign ntru = new NtruSign(param);

            SignatureKeyPair kp = ntru.generateKeyPair();

            Random rng = new Random();

            byte[] msg = new byte[10 + rng.Next(1000)];
            rng.NextBytes(msg);

            // sign and verify a message in two pieces each
            ntru.initSign(kp);
            int splitIdx = rng.Next(msg.Length);

            ntru.update(ArrayUtils.CopyOf(msg, splitIdx));                           // part 1 of msg
            byte[] s = ntru.sign(ArrayUtils.CopyOfRange(msg, splitIdx, msg.Length)); // part 2 of msg
            ntru.initVerify(kp.pub);
            splitIdx = rng.Next(msg.Length);
            ntru.update(ArrayUtils.CopyOf(msg, splitIdx));                  // part 1 of msg
            ntru.update(ArrayUtils.CopyOfRange(msg, splitIdx, msg.Length)); // part 2 of msg
            bool valid = ntru.verify(s);

            Assert.True(valid);
            // verify the same signature with the one-step method
            valid = ntru.verify(msg, s, kp.pub);
            Assert.True(valid);

            // sign using the one-step method and verify using the multi-step method
            s = ntru.sign(msg, kp);
            ntru.initVerify(kp.pub);
            splitIdx = rng.Next(msg.Length);
            ntru.update(ArrayUtils.CopyOf(msg, splitIdx));                  // part 1 of msg
            ntru.update(ArrayUtils.CopyOfRange(msg, splitIdx, msg.Length)); // part 2 of msg
            valid = ntru.verify(s);
            Assert.True(valid);
        }
        private void SignVerify(SignatureParameters param)
        {
            NtruSign         ntru = new NtruSign(param);
            SignatureKeyPair kp   = ntru.generateKeyPair();

            Assert.Equals(param.B + 1, kp.priv.getNumBases());

            Random rng = new Random();

            byte[] msg = new byte[10 + rng.Next(1000)];
            rng.NextBytes(msg);

            // sign and verify
            byte[] s     = ntru.sign(msg, kp);
            bool   valid = ntru.verify(msg, s, kp.pub);

            Assert.True(valid);

            // altering the signature should make it invalid
            s[rng.Next(param.N)] += 1;
            valid = ntru.verify(msg, s, kp.pub);
            Assert.False(valid);

            // test that a random signature fails
            rng.NextBytes(s);
            valid = ntru.verify(msg, s, kp.pub);
            Assert.False(valid);

            // encode, decode keypair, test
            SignaturePrivateKey priv = new SignaturePrivateKey(kp.priv.getEncoded());
            SignaturePublicKey  pub  = new SignaturePublicKey(kp.pub.getEncoded());

            kp    = new SignatureKeyPair(priv, pub);
            s     = ntru.sign(msg, kp);
            valid = ntru.verify(msg, s, kp.pub);
            Assert.True(valid);

            // altering the signature should make it invalid
            s[rng.Next(s.Length)] += 1;
            valid = ntru.verify(msg, s, kp.pub);
            Assert.False(valid);

            // sparse/dense
            param.sparse = !param.sparse;
            s            = ntru.sign(msg, kp);
            valid        = ntru.verify(msg, s, kp.pub);
            Assert.True(valid);
            s[rng.Next(s.Length)] += 1;
            valid = ntru.verify(msg, s, kp.pub);
            Assert.False(valid);
            param.sparse = !param.sparse;

            // decrease NormBound to force multiple signing attempts
            SignatureParameters params2 = param.Clone();

            params2.normBoundSq      *= (float)4.0 / 9; // works for APR2011_439_PROD but may need to be increased for different params
            params2.signFailTolerance = 10000;
            ntru  = new NtruSign(params2);
            s     = ntru.sign(msg, kp);
            valid = ntru.verify(msg, s, kp.pub);
            Assert.True(valid);

            // test KeyGenAlg.FLOAT (default=RESULTANT)
            params2         = param.Clone();
            param.keyGenAlg = KeyGenAlg.FLOAT;
            ntru            = new NtruSign(param);
            kp    = ntru.generateKeyPair();
            s     = ntru.sign(msg, kp);
            valid = ntru.verify(msg, s, kp.pub);
            Assert.True(valid);
            s[rng.Next(s.Length)] += 1;
            valid = ntru.verify(msg, s, kp.pub);
            Assert.False(valid);
        }