123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
- {
- /**
- * generate suitable parameters for GOST3410.
- */
- public class Gost3410ParametersGenerator
- {
- private int size;
- private int typeproc;
- private SecureRandom init_random;
- /**
- * initialise the key generator.
- *
- * @param size size of the key
- * @param typeProcedure type procedure A,B = 1; A',B' - else
- * @param random random byte source.
- */
- public void Init(
- int size,
- int typeProcedure,
- SecureRandom random)
- {
- this.size = size;
- this.typeproc = typeProcedure;
- this.init_random = random;
- }
- //Procedure A
- private int procedure_A(int x0, int c, BigInteger[] pq, int size)
- {
- //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd.
- while(x0<0 || x0>65536)
- {
- x0 = init_random.NextInt()/32768;
- }
- while((c<0 || c>65536) || (c/2==0))
- {
- c = init_random.NextInt()/32768 + 1;
- }
- BigInteger C = BigInteger.ValueOf(c);
- BigInteger constA16 = BigInteger.ValueOf(19381);
- //step1
- BigInteger[] y = new BigInteger[1]; // begin length = 1
- y[0] = BigInteger.ValueOf(x0);
- //step 2
- int[] t = new int[1]; // t - orders; begin length = 1
- t[0] = size;
- int s = 0;
- for (int i=0; t[i]>=17; i++)
- {
- // extension array t
- int[] tmp_t = new int[t.Length + 1]; ///////////////
- Array.Copy(t,0,tmp_t,0,t.Length); // extension
- t = new int[tmp_t.Length]; // array t
- Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); ///////////////
- t[i+1] = t[i]/2;
- s = i+1;
- }
- //step3
- BigInteger[] p = new BigInteger[s+1];
- p[s] = new BigInteger("8003",16); //set min prime number length 16 bit
- int m = s-1; //step4
- for (int i=0; i<s; i++)
- {
- int rm = t[m]/16; //step5
- step6: for(;;)
- {
- //step 6
- BigInteger[] tmp_y = new BigInteger[y.Length]; ////////////////
- Array.Copy(y,0,tmp_y,0,y.Length); // extension
- y = new BigInteger[rm+1]; // array y
- Array.Copy(tmp_y,0,y,0,tmp_y.Length); ////////////////
- for (int j=0; j<rm; j++)
- {
- y[j+1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16));
- }
- //step 7
- BigInteger Ym = BigInteger.Zero;
- for (int j=0; j<rm; j++)
- {
- Ym = Ym.Add(y[j].ShiftLeft(16*j));
- }
- y[0] = y[rm]; //step 8
- //step 9
- BigInteger N = BigInteger.One.ShiftLeft(t[m]-1).Divide(p[m+1]).Add(
- Ym.ShiftLeft(t[m]-1).Divide(p[m+1].ShiftLeft(16*rm)));
- if (N.TestBit(0))
- {
- N = N.Add(BigInteger.One);
- }
- //step 10
- for(;;)
- {
- //step 11
- BigInteger NByLastP = N.Multiply(p[m+1]);
- if (NByLastP.BitLength > t[m])
- {
- goto step6; //step 12
- }
- p[m] = NByLastP.Add(BigInteger.One);
- //step13
- if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0
- && BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0)
- {
- break;
- }
- N = N.Add(BigInteger.Two);
- }
- if (--m < 0)
- {
- pq[0] = p[0];
- pq[1] = p[1];
- return y[0].IntValue; //return for procedure B step 2
- }
- break; //step 14
- }
- }
- return y[0].IntValue;
- }
- //Procedure A'
- private long procedure_Aa(long x0, long c, BigInteger[] pq, int size)
- {
- //Verify and perform condition: 0<x<2^32; 0<c<2^32; c - odd.
- while(x0<0 || x0>4294967296L)
- {
- x0 = init_random.NextInt()*2;
- }
- while((c<0 || c>4294967296L) || (c/2==0))
- {
- c = init_random.NextInt()*2+1;
- }
- BigInteger C = BigInteger.ValueOf(c);
- BigInteger constA32 = BigInteger.ValueOf(97781173);
- //step1
- BigInteger[] y = new BigInteger[1]; // begin length = 1
- y[0] = BigInteger.ValueOf(x0);
- //step 2
- int[] t = new int[1]; // t - orders; begin length = 1
- t[0] = size;
- int s = 0;
- for (int i=0; t[i]>=33; i++)
- {
- // extension array t
- int[] tmp_t = new int[t.Length + 1]; ///////////////
- Array.Copy(t,0,tmp_t,0,t.Length); // extension
- t = new int[tmp_t.Length]; // array t
- Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); ///////////////
- t[i+1] = t[i]/2;
- s = i+1;
- }
- //step3
- BigInteger[] p = new BigInteger[s+1];
- p[s] = new BigInteger("8000000B",16); //set min prime number length 32 bit
- int m = s-1; //step4
- for (int i=0; i<s; i++)
- {
- int rm = t[m]/32; //step5
- step6: for(;;)
- {
- //step 6
- BigInteger[] tmp_y = new BigInteger[y.Length]; ////////////////
- Array.Copy(y,0,tmp_y,0,y.Length); // extension
- y = new BigInteger[rm+1]; // array y
- Array.Copy(tmp_y,0,y,0,tmp_y.Length); ////////////////
- for (int j=0; j<rm; j++)
- {
- y[j+1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32));
- }
- //step 7
- BigInteger Ym = BigInteger.Zero;
- for (int j=0; j<rm; j++)
- {
- Ym = Ym.Add(y[j].ShiftLeft(32*j));
- }
- y[0] = y[rm]; //step 8
- //step 9
- BigInteger N = BigInteger.One.ShiftLeft(t[m]-1).Divide(p[m+1]).Add(
- Ym.ShiftLeft(t[m]-1).Divide(p[m+1].ShiftLeft(32*rm)));
- if (N.TestBit(0))
- {
- N = N.Add(BigInteger.One);
- }
- //step 10
- for(;;)
- {
- //step 11
- BigInteger NByLastP = N.Multiply(p[m+1]);
- if (NByLastP.BitLength > t[m])
- {
- goto step6; //step 12
- }
- p[m] = NByLastP.Add(BigInteger.One);
- //step13
- if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0
- && BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0)
- {
- break;
- }
- N = N.Add(BigInteger.Two);
- }
- if (--m < 0)
- {
- pq[0] = p[0];
- pq[1] = p[1];
- return y[0].LongValue; //return for procedure B' step 2
- }
- break; //step 14
- }
- }
- return y[0].LongValue;
- }
- //Procedure B
- private void procedure_B(int x0, int c, BigInteger[] pq)
- {
- //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd.
- while(x0<0 || x0>65536)
- {
- x0 = init_random.NextInt()/32768;
- }
- while((c<0 || c>65536) || (c/2==0))
- {
- c = init_random.NextInt()/32768 + 1;
- }
- BigInteger [] qp = new BigInteger[2];
- BigInteger q = null, Q = null, p = null;
- BigInteger C = BigInteger.ValueOf(c);
- BigInteger constA16 = BigInteger.ValueOf(19381);
- //step1
- x0 = procedure_A(x0, c, qp, 256);
- q = qp[0];
- //step2
- x0 = procedure_A(x0, c, qp, 512);
- Q = qp[0];
- BigInteger[] y = new BigInteger[65];
- y[0] = BigInteger.ValueOf(x0);
- const int tp = 1024;
- BigInteger qQ = q.Multiply(Q);
- step3:
- for(;;)
- {
- //step 3
- for (int j=0; j<64; j++)
- {
- y[j+1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16));
- }
- //step 4
- BigInteger Y = BigInteger.Zero;
- for (int j=0; j<64; j++)
- {
- Y = Y.Add(y[j].ShiftLeft(16*j));
- }
- y[0] = y[64]; //step 5
- //step 6
- BigInteger N = BigInteger.One.ShiftLeft(tp-1).Divide(qQ).Add(
- Y.ShiftLeft(tp-1).Divide(qQ.ShiftLeft(1024)));
- if (N.TestBit(0))
- {
- N = N.Add(BigInteger.One);
- }
- //step 7
- for(;;)
- {
- //step 11
- BigInteger qQN = qQ.Multiply(N);
- if (qQN.BitLength > tp)
- {
- goto step3; //step 9
- }
- p = qQN.Add(BigInteger.One);
- //step10
- if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0
- && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0)
- {
- pq[0] = p;
- pq[1] = q;
- return;
- }
- N = N.Add(BigInteger.Two);
- }
- }
- }
- //Procedure B'
- private void procedure_Bb(long x0, long c, BigInteger[] pq)
- {
- //Verify and perform condition: 0<x<2^32; 0<c<2^32; c - odd.
- while(x0<0 || x0>4294967296L)
- {
- x0 = init_random.NextInt()*2;
- }
- while((c<0 || c>4294967296L) || (c/2==0))
- {
- c = init_random.NextInt()*2+1;
- }
- BigInteger [] qp = new BigInteger[2];
- BigInteger q = null, Q = null, p = null;
- BigInteger C = BigInteger.ValueOf(c);
- BigInteger constA32 = BigInteger.ValueOf(97781173);
- //step1
- x0 = procedure_Aa(x0, c, qp, 256);
- q = qp[0];
- //step2
- x0 = procedure_Aa(x0, c, qp, 512);
- Q = qp[0];
- BigInteger[] y = new BigInteger[33];
- y[0] = BigInteger.ValueOf(x0);
- const int tp = 1024;
- BigInteger qQ = q.Multiply(Q);
- step3:
- for(;;)
- {
- //step 3
- for (int j=0; j<32; j++)
- {
- y[j+1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32));
- }
- //step 4
- BigInteger Y = BigInteger.Zero;
- for (int j=0; j<32; j++)
- {
- Y = Y.Add(y[j].ShiftLeft(32*j));
- }
- y[0] = y[32]; //step 5
- //step 6
- BigInteger N = BigInteger.One.ShiftLeft(tp-1).Divide(qQ).Add(
- Y.ShiftLeft(tp-1).Divide(qQ.ShiftLeft(1024)));
- if (N.TestBit(0))
- {
- N = N.Add(BigInteger.One);
- }
- //step 7
- for(;;)
- {
- //step 11
- BigInteger qQN = qQ.Multiply(N);
- if (qQN.BitLength > tp)
- {
- goto step3; //step 9
- }
- p = qQN.Add(BigInteger.One);
- //step10
- if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0
- && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0)
- {
- pq[0] = p;
- pq[1] = q;
- return;
- }
- N = N.Add(BigInteger.Two);
- }
- }
- }
- /**
- * Procedure C
- * procedure generates the a value from the given p,q,
- * returning the a value.
- */
- private BigInteger procedure_C(BigInteger p, BigInteger q)
- {
- BigInteger pSub1 = p.Subtract(BigInteger.One);
- BigInteger pSub1Divq = pSub1.Divide(q);
- for(;;)
- {
- BigInteger d = new BigInteger(p.BitLength, init_random);
- // 1 < d < p-1
- if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0)
- {
- BigInteger a = d.ModPow(pSub1Divq, p);
- if (a.CompareTo(BigInteger.One) != 0)
- {
- return a;
- }
- }
- }
- }
- /**
- * which generates the p , q and a values from the given parameters,
- * returning the Gost3410Parameters object.
- */
- public Gost3410Parameters GenerateParameters()
- {
- BigInteger [] pq = new BigInteger[2];
- BigInteger q = null, p = null, a = null;
- int x0, c;
- long x0L, cL;
- if (typeproc==1)
- {
- x0 = init_random.NextInt();
- c = init_random.NextInt();
- switch(size)
- {
- case 512:
- procedure_A(x0, c, pq, 512);
- break;
- case 1024:
- procedure_B(x0, c, pq);
- break;
- default:
- throw new ArgumentException("Ooops! key size 512 or 1024 bit.");
- }
- p = pq[0]; q = pq[1];
- a = procedure_C(p, q);
- //System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16));
- //System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a);
- return new Gost3410Parameters(p, q, a, new Gost3410ValidationParameters(x0, c));
- }
- else
- {
- x0L = init_random.NextLong();
- cL = init_random.NextLong();
- switch(size)
- {
- case 512:
- procedure_Aa(x0L, cL, pq, 512);
- break;
- case 1024:
- procedure_Bb(x0L, cL, pq);
- break;
- default:
- throw new InvalidOperationException("Ooops! key size 512 or 1024 bit.");
- }
- p = pq[0]; q = pq[1];
- a = procedure_C(p, q);
- //System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16));
- //System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a);
- return new Gost3410Parameters(p, q, a, new Gost3410ValidationParameters(x0L, cL));
- }
- }
- }
- }
- #pragma warning restore
- #endif
|