I have the following parent package which defines several types
aes.ads
package AES is
type Byte is range 0..2**8 - 1;
type Input_Buffer is array(Natural range <>) of Byte;
type Output_Buffer is array(Natural range <>) of Byte;
type Key is array(Natural range <>) of Byte;
subtype AES_128_Key is Key(0..127);
subtype AES_192_Key is Key(0..191);
subtype AES_256_Key is Key(0..255);
type Operation is (Encrypt, Decrypt);
function AES_CBC_128(Input: Input_Buffer; Key: AES_128_Key; Op: Operation) return Output_Buffer;
function AES_CBC_192(Input: Input_Buffer; Key: AES_192_Key; Op: Operation) return Output_Buffer;
function AES_CBC_256(Input: Input_Buffer; Key: AES_256_Key; Op: Operation) return Output_Buffer;
private
type Word is range 0..2**32 - 1;
type State is array(0..3, 0..3) of Byte;
type States is array(Natural range <>) of State;
type Round_Key is array(0..16) of Byte;
type Key_Schedule is array(Natural range <>) of Round_Key;
end AES;
aes.adb
with AES.AES_Cipher; use AES.AES_Cipher;
with AES.AES_Inv_Cipher; use AES.AES_Inv_Cipher;
package body AES is
-- other definitions
function AES_Common(St: State; K: Key; Op: Operation) return State is
Schedule: Key_Schedule := Key_Expansion(K);
begin
return (case Op is
when Encrypt => Cipher(St, Schedule),
when Decrypt => Inv_Cipher(St, Schedule)
);
end AES_Common;
-- more definitions
end AES;
and then two child packages (aes-aes_inv_cipher
is very similar to aes-aes_cipher
so has been omitted)
aes-aes_cipher.ads
package AES.AES_Cipher is
function Cipher(St: State; Schedule: Key_Schedule) return State;
end AES.AES_Cipher;
aes-aes_cipher.adb
package body AES.AES_Cipher is
function Cipher(St: State; Schedule: Key_Schedule) return State is
begin
return St;
end Cipher;
end AES.AES_Cipher;
These are called from main.adb
with AES; use AES;
procedure Main is
Input: Input_Buffer(0..35) := (others => Byte(44));
K: AES_128_Key := (others => Byte(55));
Output: Output_Buffer(0..35);
begin
Output := AES_CBC_128(Input, K, Encrypt);
end Main;
This does not compile with the following error
aes-aes_cipher.ads:2:25: error: "State" is not visible (more references follow)
aes-aes_cipher.ads:2:25: error: non-visible (private) declaration at aes.ads:17
aes-aes_cipher.ads:2:42: error: "Key_Schedule" is not visible (more references follow)
aes-aes_cipher.ads:2:42: error: non-visible (private) declaration at aes.ads:20
I thought because aes-aes_cipher
is a child package of aes
it could access the private definitions in aes.ads
but the error suggests otherwise. If this is not possible, how can I restructure the program so it works as expected? Removing private
fixes it but those types should be private outside the package. I am using gnatmake version 13.2.0 on Windows.
This can be done by making the child package a private package.
private package AES.AES_Cipher is
function Cipher(St: State; Schedule: Key_Schedule) return State;
end AES.AES_Cipher;
This allows the child package to use the private parent types without exposing them publicly and still allows the parent package to use the child functions.
Thank you to Jim Rogers for pointing me in the right direction and this answer for explaining how to do it.