1 /// Implementation of Circe digester.
2 module tern.digest.circe;
3 
4 import tern.digest;
5 import tern.algorithm;
6 import tern.serialization;
7 
8 /** 
9  * Implementation of Circe digester.
10  *
11  * Circe is a very fast and efficient key derivation algorithm designed for 256 bit keys.
12  *
13  * ```d
14  * import tern.digest.circe
15  *
16  * string key = "...";
17  * ulong seed = 0xFF3CA9FF;
18  * auto keyHash = Circe.hash(cast(ubyte)key, seed);
19  */
20 public static @digester class Circe
21 {
22 public:
23 static:
24 pure:
25     /** 
26      * Derives a 256 bit key from `data`.
27      *
28      * Params:
29      *   data = Data to hash and derive from.
30      *   seed = Seed of the hash. (IV)
31      *
32      * Returns: 
33      *  The new key derived from `data`.
34      *
35      * Remarks:
36      *  Does not validate the length of `data`.
37      */
38     pragma(inline)
39     ubyte[] hash(ubyte[] data, ulong seed = 0)
40     {
41         if (data.length != 32)
42             throw new Throwable("Circe only operates on 32 bytes of data (256 bits!)");
43             
44         ubyte[32] dst;
45         foreach (k; 0..32)
46         {
47             foreach (v; 0..32)
48             {
49                 dst[v] -= data[k] ^= seed;
50                 dst[31 - k] *= data[31 - v];
51                 dst[31 - k] -= dst[k] &= data[k];
52             }
53         }
54         return dst.dup;
55     }
56 }