Пример #1
0
        private byte[] signHash(byte[] msgHash, SignatureKeyPair kp)
        {
            int r = 0;
            IntegerPolynomial s;
            IntegerPolynomial i;

            do
            {
                r++;
                if (r > param.signFailTolerance)
                {
                    throw new NtruException("Signing failed: too many retries (max=" + param.signFailTolerance + ")");
                }
                i = createMsgRep(msgHash, r);
                s = sign(i, kp);
            } while (!verify(i, s, kp.pub.h));

            byte[] rawSig = s.ToBinary(param.q);

            MemoryStream sbuf = new MemoryStream(rawSig.Length + 4);
            BinaryWriter bwr  = new BinaryWriter(sbuf);

            bwr.Write(rawSig);
            bwr.Write(r);
            return(sbuf.ToArray());
        }
Пример #2
0
        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);
        }
Пример #3
0
 /**
  * Resets the engine for signing a message.
  * @param kp
  * @throws NtruException if the JRE doesn't implement the specified hash algorithm
  */
 public void initSign(SignatureKeyPair kp)
 {
     this.signingKeyPair = kp;
     try
     {
         hashAlg = new SHA256();// MessageDigest.getInstance(param.hashAlg);
     }
     catch (Exception e)
     {
         throw new NtruException(e.Message);
     }
     hashAlg.Reset();
 }
Пример #4
0
 /**
  * Signs a message.<br/>
  * This is a "one stop" method and does not require <code>initSign</code> to be called. Only the message supplied via
  * the parameter <code>m</code> is signed, regardless of prior calls to {@link #update(byte[])}.
  * @param m the message to sign
  * @param kp a key pair (the public key is needed to ensure there are no signing failures)
  * @return a signature
  * @throws NtruException if the JRE doesn't implement the specified hash algorithm
  */
 public byte[] sign(byte[] m, SignatureKeyPair kp)
 {
     try
     {
         // EESS directly passes the message into the MRGM (message representative
         // generation method). Since that is inefficient for long messages, we work
         // with the hash of the message.
         hashAlg = new SHA256();
         byte[] msgHash = hashAlg.ComputeHash(m);
         return(signHash(msgHash, kp));
     }
     catch (Exception e)
     {
         throw new NtruException(e.Message);
     }
 }
Пример #5
0
        /**
         * Generates a new signature key pair. Uses up to <code>B+1</code> threads
         * if multiple processors are available.
         * @return a key pair
         */
        public SignatureKeyPair generateKeyPair()
        {
            int processors           = Environment.ProcessorCount;
            SignaturePrivateKey priv = new SignaturePrivateKey(param);
            int B = param.B;

            //if (processors == 1)
            // generate all B+1 bases in the current thread
            for (int k = B; k >= 0; k--)
            {
                priv.add(generateBoundedBasis());
            }

            /*else {
             *  List<Future<Basis>> bases = new ArrayList<Future<Basis>>();
             *
             *  // start up to processors-1 new threads and generate B bases
             *  int numThreads = Math.min(B, processors-1);
             *  if (numThreads > 0) {
             *      ExecutorService executor = Executors.newFixedThreadPool(numThreads);
             *      for (int k=B-1; k>=0; k--)
             *          bases.add(executor.submit(new BasisGenerationTask()));
             *      executor.shutdown();
             *  }
             *
             *  // generate the remaining basis in the current thread
             *  Basis basis0 = generateBoundedBasis();
             *
             *  // build the private key
             *  for (Future<Basis> basis: bases)
             *      try {
             *          priv.add(basis.get());
             *      } catch (Exception e) {
             *          throw new NtruException(e);
             *      }
             *  priv.add(basis0);
             * }*/

            int q = param.q;
            SignaturePublicKey pub = new SignaturePublicKey(priv.getBasis(0).h, q);

            priv.getBasis(0).h = null;   // remove the public polynomial h from the private key

            SignatureKeyPair kp = new SignatureKeyPair(priv, pub);

            return(kp);
        }
Пример #6
0
        /**
         * Generates a new signature key pair. Runs in a single thread.
         * @return a key pair
         */
        public SignatureKeyPair generateKeyPairSingleThread()
        {
            SignaturePrivateKey priv = new SignaturePrivateKey(param);
            SignaturePublicKey  pub  = null;

            Basis pubBasis = generateBoundedBasis();

            pub        = new SignaturePublicKey(pubBasis.h, param.q);
            pubBasis.h = null;   // remove the public polynomial h from the private key
            priv.add(pubBasis);

            for (int k = param.B; k > 0; k--)
            {
                Basis basis = generateBoundedBasis();
                priv.add(basis);
            }

            SignatureKeyPair kp = new SignatureKeyPair(priv, pub);

            return(kp);
        }
Пример #7
0
        //@Override
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }
            if (obj == null)
            {
                return(false);
            }
            //if (getClass() != obj.getClass())
            //    return false;
            SignatureKeyPair other = (SignatureKeyPair)obj;

            if (priv == null)
            {
                if (other.priv != null)
                {
                    return(false);
                }
            }
            else if (!priv.Equals(other.priv))
            {
                return(false);
            }
            if (pub == null)
            {
                if (other.pub != null)
                {
                    return(false);
                }
            }
            else if (!pub.Equals(other.pub))
            {
                return(false);
            }
            return(true);
        }
Пример #8
0
        private void Encode(SignatureParameters param)
        {
            NtruSign ntru = new NtruSign(param);
            SignatureKeyPair kp = ntru.generateKeyPair();

            // encode to byte[] and reconstruct
            byte[] pub = kp.pub.getEncoded();
            byte[] priv = kp.priv.getEncoded();
            SignatureKeyPair kp2 = new SignatureKeyPair(new SignaturePrivateKey(priv), new SignaturePublicKey(pub));
            Assert.Equals(kp.pub, kp2.pub);
            Assert.Equals(kp.priv, kp2.priv);

            // encode to OutputStream and reconstruct
            MemoryStream bos1 = new MemoryStream();
            MemoryStream bos2 = new MemoryStream();
            kp.priv.writeTo(bos1);
            kp.pub.writeTo(bos2);
            MemoryStream bis1 = new MemoryStream(bos1.ToArray());
            MemoryStream bis2 = new MemoryStream(bos2.ToArray());
            SignatureKeyPair kp3 = new SignatureKeyPair(new SignaturePrivateKey(bis1), new SignaturePublicKey(bis2));
            Assert.Equals(kp.pub, kp3.pub);
            Assert.Equals(kp.priv, kp3.priv);
           // Assert.assertNull(kp3.priv.getBasis(0).h); ToDo: why?
        }
Пример #9
0
        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);
        }
Пример #10
0
        /**
         * Generates a new signature key pair. Runs in a single thread.
         * @return a key pair
         */
        public SignatureKeyPair generateKeyPairSingleThread()
        {
            SignaturePrivateKey priv = new SignaturePrivateKey(param);
            SignaturePublicKey pub = null;

            Basis pubBasis = generateBoundedBasis();
            pub = new SignaturePublicKey(pubBasis.h, param.q);
            pubBasis.h = null;   // remove the public polynomial h from the private key
            priv.add(pubBasis);

            for (int k = param.B; k > 0; k--)
            {
                Basis basis = generateBoundedBasis();
                priv.add(basis);
            }

            SignatureKeyPair kp = new SignatureKeyPair(priv, pub);
            return kp;
        }
Пример #11
0
        /**
         * Generates a new signature key pair. Uses up to <code>B+1</code> threads
         * if multiple processors are available.
         * @return a key pair
         */
        public SignatureKeyPair generateKeyPair()
        {
            int processors = Environment.ProcessorCount;
            SignaturePrivateKey priv = new SignaturePrivateKey(param);
            int B = param.B;

            //if (processors == 1)
            // generate all B+1 bases in the current thread
            for (int k = B; k >= 0; k--)
                priv.add(generateBoundedBasis());
            /*else {
                List<Future<Basis>> bases = new ArrayList<Future<Basis>>();
            
                // start up to processors-1 new threads and generate B bases
                int numThreads = Math.min(B, processors-1);
                if (numThreads > 0) {
                    ExecutorService executor = Executors.newFixedThreadPool(numThreads);
                    for (int k=B-1; k>=0; k--)
                        bases.add(executor.submit(new BasisGenerationTask()));
                    executor.shutdown();
                }
            
                // generate the remaining basis in the current thread
                Basis basis0 = generateBoundedBasis();
            
                // build the private key
                for (Future<Basis> basis: bases)
                    try {
                        priv.add(basis.get());
                    } catch (Exception e) {
                        throw new NtruException(e);
                    }
                priv.add(basis0);
            }*/

            int q = param.q;
            SignaturePublicKey pub = new SignaturePublicKey(priv.getBasis(0).h, q);
            priv.getBasis(0).h = null;   // remove the public polynomial h from the private key

            SignatureKeyPair kp = new SignatureKeyPair(priv, pub);
            return kp;
        }
Пример #12
0
        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;
        }
Пример #13
0
        private byte[] signHash(byte[] msgHash, SignatureKeyPair kp)
        {
            int r = 0;
            IntegerPolynomial s;
            IntegerPolynomial i;
            do
            {
                r++;
                if (r > param.signFailTolerance)
                    throw new NtruException("Signing failed: too many retries (max=" + param.signFailTolerance + ")");
                i = createMsgRep(msgHash, r);
                s = sign(i, kp);
            } while (!verify(i, s, kp.pub.h));

            byte[] rawSig = s.ToBinary(param.q);

            MemoryStream sbuf = new MemoryStream(rawSig.Length + 4);
            BinaryWriter bwr = new BinaryWriter(sbuf);
            bwr.Write(rawSig);
            bwr.Write(r);
            return sbuf.ToArray();
        }
Пример #14
0
 /**
  * Signs a message.<br/>
  * This is a "one stop" method and does not require <code>initSign</code> to be called. Only the message supplied via
  * the parameter <code>m</code> is signed, regardless of prior calls to {@link #update(byte[])}.
  * @param m the message to sign
  * @param kp a key pair (the public key is needed to ensure there are no signing failures)
  * @return a signature
  * @throws NtruException if the JRE doesn't implement the specified hash algorithm
  */
 public byte[] sign(byte[] m, SignatureKeyPair kp)
 {
     try
     {
         // EESS directly passes the message into the MRGM (message representative
         // generation method). Since that is inefficient for long messages, we work
         // with the hash of the message.
         hashAlg = new SHA256();
         byte[] msgHash = hashAlg.ComputeHash(m);
         return signHash(msgHash, kp);
     }
     catch (Exception e)
     {
         throw new NtruException(e.Message);
     }
 }
Пример #15
0
 /**
  * Resets the engine for signing a message.
  * @param kp
  * @throws NtruException if the JRE doesn't implement the specified hash algorithm
  */
 public void initSign(SignatureKeyPair kp)
 {
     this.signingKeyPair = kp;
     try
     {
         hashAlg = new SHA256();// MessageDigest.getInstance(param.hashAlg);
     }
     catch (Exception e)
     {
         throw new NtruException(e.Message);
     }
     hashAlg.Reset();
 }
Пример #16
0
        private void Encode(SignatureParameters param)
        {
            NtruSign ntru = new NtruSign(param);
            SignatureKeyPair kp = ntru.generateKeyPair();

            // encode to byte[] and reconstruct
            byte[] enc = kp.getEncoded();
            SignatureKeyPair kp2 = new SignatureKeyPair(enc);
            Assert.Equals(kp, kp2);

            // encode to OutputStream and reconstruct
            MemoryStream bos = new MemoryStream();
            kp.writeTo(bos);
            MemoryStream bis = new MemoryStream(bos.ToArray());
            SignatureKeyPair kp3 = new SignatureKeyPair(bis);
            Assert.Equals(kp, kp3);
        }