1 module crypto.utils;
2 
3 import std.bigint;
4 import std.array;
5 import std.algorithm;
6 import std.traits : Unqual;
7 import std.conv;
8 import std.random;
9 
10 struct BigIntHelper
11 {
12     static ubyte[] bigIntToUByteArray(BigInt v)
13     {
14         Appender!(ubyte[]) app;
15 
16         while (v > 0)
17         {
18             app.put((v - ((v >> 8) << 8)).to!ubyte);
19             v >>= 8;
20         }
21 
22         reverse(app.data);
23         return app.data;
24     }
25 
26     static BigInt bigIntFromUByteArray(in ubyte[] buffer)
27     {
28         BigInt ret = BigInt("0");
29 
30         for (uint i; i < buffer.length; i++)
31         {
32             ret <<= 8;
33             ret += buffer[i];
34         }
35 
36         return ret;
37     }
38 
39 //    static BigInt powMod(BigInt base, BigInt modulus, BigInt exponent)
40 //    {
41 //        assert(base >= 1 && exponent >= 0 && modulus >= 1);
42 //
43 //        BigInt result = BigInt("1");
44 //
45 //        while (exponent > 0)
46 //        {
47 //            if (exponent & 1)
48 //            {
49 //                result = (result * base) % modulus;
50 //                base = (base * base) % modulus;
51 //                exponent >>= 1;
52 //            }
53 //        }
54 //
55 //        return result;
56 //    }
57 
58     static BigInt powMod(BigInt base, BigInt modulus, BigInt exponent)
59     {
60         assert(base >= 1 && exponent >= 0 && modulus >= 1);
61 
62         if (exponent == 0)
63         {
64             return BigInt(1) % modulus;
65         }
66 
67         if (exponent == 1)
68         {
69             return base % modulus;
70         }
71 
72         if (exponent % 2 != 0)
73         {
74             BigInt temp = powMod(base, modulus, exponent / 2);
75 
76             return (temp * temp * base) % modulus;
77         }
78         else
79         {
80             BigInt temp = powMod(base, modulus, exponent / 2);
81 
82             return (temp * temp) % modulus;
83         }
84     }
85 }
86 
87 /++ Fast but cryptographically insecure source of random numbers. +/
88 struct InsecureRandomGenerator
89 {
90     private static Mt19937 generator;
91 
92     static this()
93     {
94         generator.seed(unpredictableSeed);
95     }
96 
97     T next(T = uint)(T min = T.min, T max = T.max) if (is(Unqual!T == uint) || is(Unqual!T == int) || is(Unqual!T == ubyte) || is(Unqual!T == byte))
98     {
99         return uniform!("[]", T, T, typeof(generator))(min, max, generator);
100     }
101 }