Example #1
0
        public string crypt(string str, PasswordSecure pwd = null)
        {
            if (pwd == null)
            {
                pwd = key;
            }

            var sha = new SHA3(str.Length);

            if (random == null)
            {
                var inits = str + DateTime.Now.ToString("r");
                var t     = new UTF32Encoding().GetBytes(inits);
                var bbi   = new BytesBuilder();
                bbi.add(t);
                bbi.add(sha.CreateInitVector(0, 64, 40));
                var init = bbi.getBytes();

                random = new SHA3.SHA3Random(init);

                bbi.clear();
                BytesBuilder.ClearString(inits);
                BytesBuilder.ToNull(init);
            }

            var bytes = new UTF32Encoding().GetBytes(str);

            var openKey = pwd.getObjectValue();
            var crypted = sha.multiCryptLZMA(bytes, openKey, null, 22, false);

            BytesBuilder.BytesToNull(openKey);
            BytesBuilder.BytesToNull(bytes);
            BytesBuilder.ClearString(str);

            return(Convert.ToBase64String(crypted));
        }
Example #2
0
        // GOST5 = GostRegime - 21
        public unsafe byte[] getGamma(long gammaLength, int GOST5 = 0)
        {
            if (workingKey == null)
            {
                throw new Exception("GOST 28147 mod. gamma not prepared");
            }

            if (gammaLength <= 0)
            {
                throw new ArgumentOutOfRangeException("GOST 28147 mod. gammaLenght is incorrect");
            }

            var bb = new BytesBuilder();
            int SL = snc.Length & 0x7FFFFFF8;
            int BL = SL;

            if (SL > 72)
            {
                BL = 64;
            }
            bool BL72 = false;

            byte[] S     = null;
            byte[] SA    = null;
            int    tmp72 = 0;
            int    kl    = 0;

            byte[] tmpp = null;

            keccak.SHA3 sha = null, shaR = null;

            if (GOST5 > 0)
            {
                BL72 = (SL % 72 > 0) && (SL > 71);
                if (GOST5 < 13)
                {
                    tmp72 = (SL / 72) * (GOST5 == 1 ? 64 : 16);
                }
                else
                {
                    tmp72 = (SL / 72) * 8;     // Хеш возвращает только 8 байтов
                }

                S    = BytesBuilder.CloneBytes(snc, 0, SL);
                SA   = new byte[SL];
                tmpp = new byte[SL + 72];
                sha  = new SHA3(SL);
                shaP = new SHA3.SHA3Random(snc);     // это не лишнее, получает ключ для инициализирующих перестановок
                if (GOST5 >= 13)
                {
                    shaPP = new SHA3.SHA3Random(shaP.nextBytes64());
                    shaR  = new SHA3(SL);
                }

                if (SL < 64)
                {
                    throw new ArgumentException("GOST 28147 mod. sync lenght is incorrect");
                }
            }
            snc = null;

            fixed(byte *S1 = currentSBox, S2 = currentSBox2, S3 = currentSBox3, S4 = currentSBox4, S5 = currentSBox5, S6 = currentSBox6)
            {
                BytesBuilder.CopyTo(N1, _N3);
                BytesBuilder.CopyTo(N2, _N3, 4);

                byte[]   k = { 0, 1, 2, 3, 4 };
                byte *[] b = { S1, S2, S3, S4, S5, S6 };

                if (GOST5 > 0)
                {
                    if (GOST5 <= 2)
                    {
                        processBlocksForGamma(SL, S, SA, k, b);
                        processBlocksForGamma(SL, SA, S, k, b, true);
                        processBlocksForGamma(SL, S, SA, k, b, true);
                        processBlocksForGamma(SL, SA, S, k, b, true);
                    }
                    else
                    {
                        processBlocksForGamma2(SL, S, SA, k, b, false, GOST5);
                        processBlocksForGamma2(SL, SA, S, k, b, true, GOST5);
                        processBlocksForGamma2(SL, S, SA, k, b, true, GOST5);
                        processBlocksForGamma2(SL, SA, S, k, b, true, GOST5);
                    }
                    sha.getDuplex(S, false, -1, false);
                    if (GOST5 >= 13)
                    {
                        shaR.getDuplex(S, false, -1, false);
                    }
                }
                else
                {
                    // Делаем несколько раз шифрование, на всяк пожарный, хотя это и не по ГОСТу
                    ProcessBlock(_N3, 0, _N4, 0, workingKey[0], S2);
                    ProcessBlock(_N4, 0, _N3, 0, workingKey[1], S3);
                    ProcessBlock(_N3, 0, _N4, 0, workingKey[2], S4);
                    ProcessBlock(_N4, 0, _N3, 0, workingKey[3], S1);

                    ProcessBlock(_N3, 0, _N4, 0, workingKey[2], S3);
                    ProcessBlock(_N4, 0, _N3, 0, workingKey[1], S1);
                    ProcessBlock(_N3, 0, _N4, 0, workingKey[3], S2);
                    ProcessBlock(_N4, 0, _N3, 0, workingKey[0], S4);
                }

                BytesBuilder.CopyTo(_N3, N1);
                BytesBuilder.CopyTo(_N3, N2, 0, 4, 4);

                long n1 = bytesToint(N1, 0), n2 = bytesToint(N2, 0);
                int  _n1, _n2;

                int ik = 0;

                do
                {
                    if (GOST5 > 0)
                    {
                        byte[] tmp1, tmp2, tmp3;
                        fixed(byte *s = S, sa = SA, tmpp_ = tmpp)
                        {
                            if (GOST5 <= 2)
                            {
                                processBlocksForGamma(SL, S, SA, k, b);
                            }
                            else
                            {
                                processBlocksForGamma2(SL, S, SA, k, b, false, GOST5);
                            }

                            if (GOST5 < 13)
                            {
                                tmp1 = sha.getDuplex(SA, true);
                            }
                            else
                            {
                                tmp1 = shaR.getDuplex(SA, true);
                            }
                            addConstant(s, S.Length);
                            tmp3 = BytesBuilder.CloneBytes(sa, 0, SA.Length);

                            if (GOST5 <= 2)
                            {
                                processBlocksForGamma(SL, S, SA, k, b);
                            }
                            else
                            {
                                processBlocksForGamma2(SL, S, SA, k, b, false, GOST5);
                            }

                            if (GOST5 < 13)
                                fixed(byte *tmp1_ = tmp1, tmp3_ = tmp3)
                                {
                                    if (GOST5 > 1)
                                    {
                                        MergePermutation.permutationMergeBytes(tmp3_, tmp3.Length, sa, tmpp_, SL, ref kl, true);
                                    }

                                    SHA3.xorBytesWithGamma(SA, tmp1);

                                    MergePermutation.permutationMergeBytes(tmp1_, tmp1.Length, sa, tmpp_, SL, ref kl, true);
                                    BytesBuilder.ToNull(tmp1.Length, tmp1_);
                                    BytesBuilder.ToNull(tmp3.Length, tmp3_);
                                }

                            if (GOST5 < 13)
                            {
                                tmp2 = sha.getDuplex(SA, true, GOST5 == 1 ? 64 : 16);
                            }
                            else
                            {
                                tmp2 = sha.getDuplexMod(SA, tmp1, true, 8, 0);
                                BytesBuilder.ToNull(tmp1);
                                BytesBuilder.ToNull(tmp3);
                            }
                            addConstant(s, S.Length);
                        }

                        if (BL72)
                        {
                            bb.add(BytesBuilder.CloneBytes(tmp2, tmp2.Length - tmp72, tmp72));
                            BytesBuilder.ToNull(tmp2);
                        }
                        else
                        {
                            bb.add(tmp2);
                        }
                    }
                    else
                    {
                        n1 += 0x1010101;
                        n2 += 0x1010104;

                        if (n2 >= 0x100000000L)
                        {
                            n2 -= 0xFFFFFFFFL;
                        }
                        if (n1 >= 0x100000000L)
                        {
                            n1 -= 0x100000000L;
                        }

                        _n1 = (int)n1;
                        _n2 = (int)n2;

                        intTobytes(_n1, _N3, 0);
                        intTobytes(_n2, _N3, 4);

                        // Получаем новые значения N1; опять не по ГОСТу - 4 преобразования вместо одного
                        ProcessBlock(_N3, 0, _N4, 0, workingKey[2], S1);
                        ProcessBlock(_N4, 0, _N3, 0, workingKey[(ik + 1) & 1], S3);
                        ProcessBlock(_N3, 0, _N4, 0, workingKey[ik & 1], S4);
                        ProcessBlock(_N4, 0, _N3, 0, workingKey[3], S2);

                        bb.addCopy(_N3);
                    }

                    ik++;
                }while (bb.Count < gammaLength);

                n1  = 0;
                n2  = 0;
                _n1 = 0;
                _n2 = 0;
            }

            for (int i = 0; i < workingKey.Length; i++)
            {
                for (int j = 0; j < workingKey[i].Length; j++)
                {
                    workingKey[i][j] = 0;
                }
            }
            workingKey = null;
            if (workingKeyA != null)
            {
                BytesBuilder.ToNull(workingKeyA);
                workingKeyA = null;
            }

            BytesBuilder.ToNull(N1);
            BytesBuilder.ToNull(N2);
            BytesBuilder.ToNull(_N3);
            BytesBuilder.ToNull(_N4);

            var result = bb.getBytes(gammaLength);

            bb.clear();
            if (S != null)
            {
                BytesBuilder.ToNull(S);
                BytesBuilder.ToNull(SA);
                BytesBuilder.ToNull(tmpp);
            }

            if (sha != null)
            {
                sha.Clear(true);
                shaP.Clear();
                sha  = null;
                shaP = null;

                if (shaPP != null)
                {
                    shaPP.Clear();
                    shaPP = null;
                }
            }

            return(result);
        }