Skip to content

CryptAda.Pragmatics

Antonio edited this page May 30, 2017 · 11 revisions

Overview

This package defines a set of types and operations on those types that are widely used along the library. Next sections describe the types used and the operations on those types.

Types

Basic modular types

The package provides basic modular type definitions for 8, 16, 32 and 64-bit values based on those provided in the Interfaces package.

type Byte is new Interfaces.Unsigned_8;
type Two_Bytes is new Interfaces.Unsigned_16;
type Four_Bytes is new Interfaces.Unsigned_32;
type Eight_Bytes is new Interfaces.Unsigned_64;

Unconstrained array types

The package includes definitions of unconstrained, Positive indexed array types for the basic modular types:

type Byte_Array is array(Positive range <>) of Byte;
type Two_Bytes_Array is array(Positive range <>) of Two_Bytes;
type Four_Bytes_Array is array(Positive range <>) of Four_Bytes;
type Eight_Bytes_Array is array(Positive range <>) of Eight_Bytes;

Constrained array subtypes

Next subtypes provide support for extracting (unpacking) the bytes that conform the basic modular types and to build basic modular types from byte arrays (packing):

subtype Unpacked_Two_Bytes is Byte_Array(1 .. 2);
subtype Unpacked_Four_Bytes is Byte_Array(1 .. 4);
subtype Unpacked_Eight_Bytes is Byte_Array(1 .. 8);

Access to modular array values

The package also include a set of access types to basic modular array values.

type Byte_Array_Ptr is access all Byte_Array;
type Two_Bytes_Array_Ptr is access all Two_Bytes_Array;
type Four_Bytes_Array_Ptr is access all Four_Bytes_Array;
type Eight_Bytes_Array_Ptr is access all Eight_Bytes_Array;

Byte_Order

Finally, the package provides an enumeration type, Byte_Order, that identifies the order of bytes in Byte_Array values that will be converted to basic modular values or that are obtained from unpacking basic modular values. Byte_Order values are:

  • Little_Endian. Significance of bytes in the byte array increases as the index of the array increases. The lower the index the less significance of the byte.
  • Big_Endian. Significance of bytes in the byte array decreases as the index of the array increases. The lower the index the greater the significance of bytes.
type Byte_Order is (Little_Endian, Big_Endian);

Subprograms

Obtaining parts of modular values

There are a number of subprograms that allow to obtain parts of modular values. These subprograms are inlined for performance reasons and do not raise any exceptions. Since their definition is clear and straightforward no further description is provided.

   function    Lo_Nibble(
                  B              : in     Byte)
      return   Byte;

   function    Hi_Nibble(
                  B              : in     Byte)
      return   Byte;

   function    Lo_Byte(
                  T              : in     Two_Bytes)
      return   Byte;

   function    Hi_Byte(
                  T              : in     Two_Bytes)
      return   Byte;

   function    Lo_Two_Bytes(
                  F              : in     Four_Bytes)
      return   Two_Bytes;

   function    Hi_Two_Bytes(
                  F              : in     Four_Bytes)
      return   Two_Bytes;

   function    Lo_Four_Bytes(
                  E              : in     Eight_Bytes)
      return   Four_Bytes;

   function    Hi_Four_Bytes(
                  E              : in     Eight_Bytes)
      return   Four_Bytes;

Making modular values

Next subprograms allow to build modular values out of other modular values. These subprograms do not raise any exceptions. Since their definition is clear and straightforward no further description is provided.

Argument names indicate the significance of the part (L => Low, H => High).

   function    Make_Two_Bytes(
                  L              : in     Byte;
                  H              : in     Byte)
      return   Two_Bytes;

   function    Make_Four_Bytes(
                  LL             : in     Byte;
                  LH             : in     Byte;
                  HL             : in     Byte;
                  HH             : in     Byte)
      return   Four_Bytes;

   function    Make_Four_Bytes(
                  L              : in     Two_Bytes;
                  H              : in     Two_Bytes)
      return   Four_Bytes;

   function    Make_Eight_Bytes(
                  LLL            : in     Byte;
                  LLH            : in     Byte;
                  LHL            : in     Byte;
                  LHH            : in     Byte;
                  HLL            : in     Byte;
                  HLH            : in     Byte;
                  HHL            : in     Byte;
                  HHH            : in     Byte)
      return   Eight_Bytes;

   function    Make_Eight_Bytes(
                  LL             : in     Two_Bytes;
                  LH             : in     Two_Bytes;
                  HL             : in     Two_Bytes;
                  HH             : in     Two_Bytes)
      return   Eight_Bytes;

   function    Make_Eight_Bytes(
                  L              : in     Four_Bytes;
                  H              : in     Four_Bytes)
      return   Eight_Bytes;

Packing byte arrays

Next subprograms allow to 'pack' byte arrays' bytes into modular values. The subprograms provide an argument (Order) that allow to specify the significance of the bytes into the resulting modular value.

   function    Pack(
                  Unpacked       : in     Unpacked_Two_Bytes;
                  Order          : in     Byte_Order := Little_Endian)
      return   Two_Bytes;

   function    Pack(
                  Unpacked       : in     Unpacked_Four_Bytes;
                  Order          : in     Byte_Order := Little_Endian)
      return   Four_Bytes;

   function    Pack(
                  Unpacked       : in     Unpacked_Eight_Bytes;
                  Order          : in     Byte_Order := Little_Endian)
      return   Eight_Bytes;

Example:

declare
   BA          : constant Byte_Array(1 .. 4) := (16#01#, 16#02#, 16#03#, 16#04#);
   FB_LE       : constant Four_Bytes := Pack(BA, Little_Endian);
   FB_BE       : constant Four_Bytes := Pack(BA, Big_Endian);
begin
   -- The values of FB_LE and FB_BE are:
   -- FB_LE => 16#04030201#
   -- FB_BE => 16#01020304#
end;

Unpacking modular values

Next subprograms allow to 'unpack' modular values into byte arrays. The subprograms provide an argument (Order) that allow to specify the order of the modular value's bytes into the array.

   function    Unpack(
                  Packed         : in     Two_Bytes;
                  Order          : in     Byte_Order := Little_Endian)
      return   Unpacked_Two_Bytes;

   function    Unpack(
                  Packed         : in     Four_Bytes;
                  Order          : in     Byte_Order := Little_Endian)
      return   Unpacked_Four_Bytes;

   function    Unpack(
                  Packed         : in     Eight_Bytes;
                  Order          : in     Byte_Order := Little_Endian)
      return   Unpacked_Eight_Bytes;

Example:

declare
   FB          : constant Four_Bytes := 16#01020304#;
   BA_LE       : constant Byte_Array(1 .. 4) := Unpack(FB, Little_Endian);
   BA_BE       : constant Byte_Array(1 .. 4) := Unpack(FB, Big_Endian);
begin
   -- The values of BA_LE and BA_BE are:
   -- BA_LE => (16#04#, 16#03#, 16#02#, 16#01#)
   -- BA_BE => (16#01#, 16#02#, 16#03#, 16#04#)
end;
Clone this wiki locally