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 }