1with Crypto.Types;
2with Crypto.Types.Random;
3
4package body Crypto.Types.Nonces.Nonces_Mixed_1 is
5
6   package CT renames Crypto.Types;
7
8   -------------------------------------------------------------------------------
9
10   function Inc(B: in Block) return Block is
11      Result   : CT.Bytes := To_Bytes(B);
12      Counter  : CT.Bytes := Result(CS..End_of_Block);
13      use CT;
14   begin
15      Counter := Counter + 1;
16      Result(CS..End_of_Block) := Counter;
17
18      return To_Block_Type(Result);
19   end Inc;
20
21   -------------------------------------------------------------------------------
22
23   function Update(This : in out Nonce_Mixed_1) return N.Block is
24
25      Rand_Array    : Crypto.Types.Bytes(0..CS-1);
26      Counter_Array : Crypto.Types.Bytes(0..End_of_Block);
27      Result_Array  : Crypto.Types.Bytes(0..End_of_Block);
28
29      Counter: Block;
30   begin
31      This.Mutex.Seize;
32
33      -- increment counter and store in byte array
34      Counter := Inc(This.Value);
35      Counter_Array := To_Bytes(Counter);
36
37      -- get random numbers
38      Crypto.Types.Random.Read(Rand_Array);
39
40      -- fill result array (half counter and half random is default)
41      Result_Array (0..CS-1)           := Rand_Array;
42      Result_Array (CS..End_of_Block)  := Counter_Array(CS..End_of_Block);
43
44      This.Value := To_Block_Type(Result_Array);
45      Counter := This.Value;
46      This.Mutex.Release;
47
48      return Counter;
49   end Update;
50
51   -------------------------------------------------------------------------------
52
53   procedure Initialize(This  : in out Nonce_Mixed_1;
54                        IV    : in     N.Block) is
55   begin
56      This.Value := IV;
57   end Initialize;
58
59end Crypto.Types.Nonces.Nonces_Mixed_1;
60