raw
eucrypt_ch10_oaep...    1 -- Implementation of TMSR's OAEP with Keccak as hash function
eucrypt_ch10_oaep... 2 --
eucrypt_ch10_oaep... 3 -- S.MG, 2018
eucrypt_ch10_oaep... 4
eucrypt_ch10_oaep... 5 with SMG_Keccak; use SMG_Keccak; -- Keccak is used as hash function
eucrypt_ch10_oaep... 6 with Interfaces; use Interfaces; -- for Unsigned_8 type and bit-level ops
eucrypt_ch10_oaep... 7 with Interfaces.C; use Interfaces.C; -- for interop with C
eucrypt_ch10_oaep... 8
eucrypt_ch10_oaep... 9 package SMG_OAEP is
eucrypt_ch10_oaep... 10 pragma Pure( SMG_OAEP ); -- stateless, no side effects -> can cache calls
eucrypt_ch10_oaep... 11
eucrypt_ch10_oaep... 12 -- fixed length of OAEP block in bits and in octets
eucrypt_ch10_oaep... 13 OAEP_LENGTH_BITS : constant := 4096;
eucrypt_ch10_oaep... 14 OAEP_LENGTH_OCTETS : constant := 512;
eucrypt_ch10_oaep... 15 OAEP_HALF_OCTETS : constant := OAEP_LENGTH_OCTETS / 2;
eucrypt_ch10_oaep... 16
eucrypt_ch10_oaep... 17 -- subtypes used by the OAEP encrypt/decrypt
eucrypt_ch10_oaep... 18 subtype OAEP_Block is String( 1 .. OAEP_LENGTH_OCTETS );
eucrypt_ch10_oaep... 19 subtype OAEP_HALF is String( 1 .. OAEP_HALF_OCTETS );
eucrypt_ch10_oaep... 20
eucrypt_ch10_oaep... 21 -- padding & formatting of maximum 1960 bits of the given String
eucrypt_ch10_oaep... 22 -- uses TMSR's OAEP schema:
eucrypt_ch10_oaep... 23 -- 1.format M00 as: [random octet][sz1][sz2]"TMSR-RSA"[random]*Message
eucrypt_ch10_oaep... 24 -- where sz1 and sz2 store the length of the message in bits
eucrypt_ch10_oaep... 25 -- the random octets before message are padding to make OAEP_LENGTH_OCTETS
eucrypt_ch10_oaep... 26 -- 2. R = OAEP_HALF_OCTETS random bits
eucrypt_ch10_oaep... 27 -- 3. X = M00 xor hash(R)
eucrypt_ch10_oaep... 28 -- 4. Y = R xor hash(X)
eucrypt_ch10_oaep... 29 -- 5. Result is X || Y
eucrypt_ch10_oaep... 30 -- NB: the Entropy parameter should be random octets from which this method
eucrypt_ch10_oaep... 31 -- will use as many as required for the OAEP encryption of given Msg
eucrypt_ch10_oaep... 32 -- NB: at MOST OAEP_LENGTH_OCTETS - 11 octets of Msg! (Msg at most 1960 bits)
eucrypt_ch10_oaep... 33 procedure OAEP_Encrypt( Msg : in String;
eucrypt_ch10_oaep... 34 Entropy : in OAEP_Block;
eucrypt_ch10_oaep... 35 Output : out OAEP_Block);
eucrypt_ch10_oaep... 36
eucrypt_ch10_oaep... 37 -- This is the opposite of OAEP_Encrypt above.
eucrypt_ch10_oaep... 38 -- @param Encr - an OAEP block previously obtained from OAEP_Encrypt
eucrypt_ch10_oaep... 39 -- @param Len - this will hold the length of the obtained message (in bits!)
eucrypt_ch10_oaep... 40 -- @param Output - the first Len octets of this are the recovered message
eucrypt_ch10_oaep... 41 -- @param Success - set to TRUE if message was recovered, false otherwise
eucrypt_ch10_oaep... 42 -- NB: when Success is FALSE, both Len and Output have undefined values
eucrypt_ch10_oaep... 43 procedure OAEP_Decrypt( Encr : in OAEP_Block;
eucrypt_ch10_oaep... 44 Len : out Natural;
eucrypt_ch10_oaep... 45 Output : out OAEP_HALF;
eucrypt_ch10_oaep... 46 Success : out Boolean);
eucrypt_ch10_oaep... 47
eucrypt_ch10_oaep... 48 -- helper method, xor on strings
eucrypt_ch10_oaep... 49 -- NB: only Output'Length bits will be considered from S1 and S2
eucrypt_ch10_oaep... 50 -- NB: caller is responsible for S1 and S2 being long enough!
eucrypt_ch10_oaep... 51 procedure XOR_Strings( S1: in String; S2: in String; Output: out String );
eucrypt_ch10_oaep... 52
eucrypt_ch10_oaep... 53 -- gnat-specific methods for bit-level operations
eucrypt_ch10_oaep... 54 function Shift_Right( Value : Unsigned_8;
eucrypt_ch10_oaep... 55 Amount : Natural )
eucrypt_ch10_oaep... 56 return Unsigned_8;
eucrypt_ch10_oaep... 57 pragma Import(Intrinsic, Shift_Right);
eucrypt_ch10_oaep... 58
eucrypt_ch10_oaep... 59 function Shift_Left( Value : Unsigned_8;
eucrypt_ch10_oaep... 60 Amount : Natural )
eucrypt_ch10_oaep... 61 return Unsigned_8;
eucrypt_ch10_oaep... 62 pragma Import(Intrinsic, Shift_Left);
eucrypt_ch10_oaep... 63
eucrypt_ch10_oaep... 64 -- conversions between bitstream and string
eucrypt_ch10_oaep... 65 -- NB: caller has to ensure correct size of output parameter! no checks here.
eucrypt_ch10_oaep... 66 procedure ToString( B: in Bitstream; S: out String );
eucrypt_ch10_oaep... 67 procedure ToBitstream( S: in String; B: out Bitstream );
eucrypt_ch10_oaep... 68
eucrypt_ch10_oaep... 69 -- public wrapper for Sponge to use String for input/output
eucrypt_ch10_oaep... 70 procedure HashKeccak( Input : in String;
eucrypt_ch10_oaep... 71 Output : out String;
eucrypt_ch10_oaep... 72 Block_Len : in Keccak_Rate := Default_Bitrate);
eucrypt_ch10_oaep... 73
eucrypt_ch10_oaep... 74 -- wrapper for calling from C
eucrypt_ch10_oaep... 75 -- @param Input the input string, as array of characters (C style)
eucrypt_ch10_oaep... 76 -- @param LenIn the length of the input string (as number of BITS)
eucrypt_ch10_oaep... 77 -- @param LenOut the desired number of bits to be returned as output
eucrypt_ch10_oaep... 78 -- @param Block_Len the bitrate used by the Keccak sponge (number of BITS)
eucrypt_ch10_oaep... 79 -- @return an array of characters with first LenOut bits set to Keccak output
eucrypt_ch10_oaep... 80
eucrypt_ch10_oaep... 81 -- NB: caller HAS TO provide the length of the Input (parameter LenIn)
eucrypt_ch10_oaep... 82 -- NB: caller HAS TO provide the length of the Output (parameter LenOut)
eucrypt_ch10_oaep... 83 function Hash( Input : Interfaces.C.Char_Array;
eucrypt_ch10_oaep... 84 LenIn : Interfaces.C.size_t;
eucrypt_ch10_oaep... 85 LenOut : Interfaces.C.size_t;
eucrypt_ch10_oaep... 86 Block_Len : Interfaces.C.int := Default_Bitrate)
eucrypt_ch10_oaep... 87 return Interfaces.C.Char_Array;
eucrypt_ch10_oaep... 88 pragma Export( C, Hash, "hash" );
eucrypt_ch10_oaep... 89
eucrypt_ch10_oaep... 90 end SMG_OAEP;