博客第一篇文章--简单的NTRU 加密算法的编程实现

来源:互联网 发布:淘宝金牌淘拍档 编辑:程序博客网 时间:2024/06/05 06:26

       前段时间选修信息安全实验课,为了完成课程目标,对NTRU加密算法进行了简单的编程实现。使用c#编程语言,完成了一个加解密winform应用程序。

       首先对NTRU加解密算法简答的介绍一下。基于寻找格中最短向量问题的快速的加密算法。在很多领域内有着很广泛的应用。NTRU算法的加解密过程如下:

       秘钥生成:

                                                

       加密过程:

                                                

      解密过程:

                                                  

编程的主要思想就是将环中的多项式用简单的数组表示,加解密过程中所用到的多项式乘法和多项式加法都在数组中进行。特殊的,多项式的逆用单独的函数进行求解。编程过程中用到的主要算法有:扩展的欧几里得算法(数求模与其互素的数逆);牛顿迭代算法(多项式求模多项式的逆);卷积算法(截断环内的多项式乘法)。

       下面就贴上我写的源代码和大家讨论一下,c#编程都是自学,有错误的地方,希望大家可以指出。

        先贴一张成形后的图片吧!


布局也是很简单,这里就不做其他赘述了。

下面是主要算法的实现:

       /// <summary>
        /// 求多项式的逆
        /// </summary>
        /// <param name="a">多项式</param>
        /// <param name="N">多项式最高次</param>
        /// <param name="p">模p</param>
        /// <returns></returns>
        public  int[] InversePoly(int[] a, int N, int q)
        {
            int k = 0;
            int[] b = new int[N];
            int[] c = new int[N];
            int[] f = new int[N];
            int[] g = new int[N + 1];




            f = a;
            g[N] = 1; g[0] = -1; b[0] = 1;
            while (true)
            {




                while (f[0] == 0)
                {
                    for (int i = 1; i <= f.Length - 1; i++)
                    {
                        f[i - 1] = f[i];
                    }
                    for (int i = c.Length - 1; i > 0; i--)
                    {
                        c[i] = c[i - 1];


                    }
                    f[f.Length - 1] = 0;
                    c[0] = 0;
                    k++;


                }




                if (deg(f) == 0)
                {
                    for (int i = 0; i < N; i++)
                    {
                        b[i] = Ix(f[0], q) * b[i];
                        b[i] = b[i] % q;


                    }
                    int[] b1 = new int[N];
                    for (int i = 0; i < N; i++)
                    {
                        b1[i] = b[i];
                        if (b1[i] < 0)
                        {
                            b1[i] = b1[i] + q;
                        }
                    }
                    if (k > N)
                    {


                        for (int i = 0; i < N; i++)
                        {


                            b[i] = b1[(k - N + i) % N];
                            // b[(i + k - N) % N] = (b1[(2 * k - 3*N + i) % N]);


                        }


                    }
                    else
                    {
                        for (int i = 0; i <= k - 1; i++)
                        {
                            b[N - k + i] = b[i] % q;


                        }
                        for (int i = k; i <= N - 1; i++)
                        {
                            b[i - k] = b[i] % q;


                        }
                    }
                    return b;
                }




                if (deg(f) < deg(g))
                {
                    int[] t = new int[N];
                    t = f;
                    f = g;
                    g = t;
                    t = b;
                    b = c;
                    c = t;
                }
                int u = 0;
                if (g[0] < 0)
                {
                    int t = 0;
                    t = g[0];
                    t = (t + q) % q;
                    int Inx = Ix(t, q);
                    u = (f[0] * Inx) % q;


                }
                else
                {
                    int Inx = Ix(g[0], q);
                    u = (f[0] * Inx) % q;


                }
                for (int i = 0; i < N; i++)
                {
                    f[i] = (f[i] - u * g[i]) % q;
                    b[i] = (b[i] - u * c[i]) % q;
                }


            }
            // return b;
        }




      /// <summary>
        /// x模m的逆
        /// </summary>
        /// <param name="x"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        public  int Ix(int m, int n)//扩展的欧几里得算法
        {
            int a, b, c, d, t;
            int ap, bp;
            int q, r;
            ap = b = 1;
            a = bp = 0;
            c = m;
            d = n;
            while (d != 0)
            {
                q = c / d;
                r = c % d;


                c = d;
                d = r;
                t = ap;
                ap = a;
                a = t - q * a;
                t = bp;
                bp = b;
                b = t - q * b;
            }
            if (ap < 0)
            {
                ap = ap + n;
            }
            return ap;
        }


   /// <summary>
        /// 多项式的乘积
        /// </summary>
        /// <param name="a">多项式a</param>
        /// <param name="b">多项式b</param>
        /// <param name="N">标准参数</param>
        /// <param name="m">模m</param>
        /// <returns></returns>
        public  int[] MultiPloy(int[] a, int[] b, int N, int m)
        {
            int[] c = new int[N];
            // int[] c = new int[N];


            for (int i = (N - 1); i >= 0; i--)
            {
                c[i] = 0;
            }
            for (int i = (N - 1); i >= 0; i--)
            {
                int K = 0;
                for (int j = 0; j <= i; j++)
                {
                    c[i] += a[j] * b[i - j];
                    c[i] = c[i] % m;
                }
                for (int j = 1; j <= N - 1 - i; j++)
                {
                    K += a[i + j] * b[N - j];
                    K = K % m;
                }
                c[i] = c[i] += K;
                c[i] = c[i] % m;
            }


            return c;
        }

以上是加解密过程中所用到的算法。算法中要求的输入为01串,但是在实际的加解密的过程中输入的为要加密的明文,解密过程也是一样的。所以就需要在加密过程中将明文转化为01串,而在解密过程中,将01串转化为明文输出。

我主要采用的是将明文转化为ASCII码的方式实现转化。下面是具体的实现代码

 /// <summary>
        /// 将8bit0,1 串转化成字母串
        /// </summary>
         /// <param name="bitString">将8bit0,1 串</param>
         /// <returns>字母串</returns>
         private static string bit01ToWord(string bitString)
         {
             //将8位的二进制串转化为ASCII
             //string teststring = WordTo8bit01("I have a dog.");
             string[] sub = new string[bitString.Length / 8];
             int[] count = new int[bitString.Length / 8];
             for (int i = 0; i < bitString.Length / 8; i++)
             {
                 sub[i] = bitString.Substring(i * 8, 8);
                 try 
                 {  count[i] = Convert.ToInt32(sub[i], 2);
                 }
                catch( Exception e)
                 {
                     MessageBox.Show("输入参数异常");
                 }
                
                 //Console.WriteLine("{0}ahifahisdfiasdhfasdfasdfasd", count[i]);
             }
             //将ASSII转化为字母\
             string strCharacter = null;
             for (int i = 0; i < count.Length; i++)
             {
                 if (count[i] >= 0 && count[i] <= 255)
                 {
                     ASCIIEncoding asciiEncoding = new ASCIIEncoding();
                     byte[] byteArray = new byte[] { (byte)count[i] };
                     strCharacter += asciiEncoding.GetString(byteArray);


                 }
             }
             return strCharacter;
         }


        /// <summary>
         /// 将字母串转化成8bit0,1 串
        /// </summary>
         /// <param name="str">字母串</param>
         /// <returns>8bit0,1 串</returns>
         public static string WordTo8bit01(string str)
         {
             //将字母转化成ASCII
             //str = "I have a dog AB  Cabc*+/.";
             ASCIIEncoding ae = new ASCIIEncoding();
             byte[] ByteArray = ae.GetBytes(str);
             //for (int i = 0; i < ByteArray.Length; i++)
             //{
             //    Console.Write("{0} ", ByteArray[i]);


             //} Console.WriteLine("");
             //将ASCII转化成8位的二进制串
             string s = null;
             for (int i = 0; i < ByteArray.Length; i++)
             {
                 s += Convert.ToString(ByteArray[i], 2).PadLeft(8, '0');
                 //Console.Write(s);
             }
             return s;

         }


以上就是我的编程过程中的主要代码实现。希望可以帮到有需要的人,同时有什么问题,希望大家可以指出,帮助我进步。。第一次发,很多地方不是很熟悉,希望大家见谅。

0 0