Unify into a single implementation file
This commit is contained in:
154
Ascon.cry
154
Ascon.cry
@@ -48,11 +48,11 @@ type constraint ValidRnd rnd = rnd <= 16
|
||||
|
||||
/// Core permutation function parameterized by a round count.
|
||||
Ascon_p : {rnd} (ValidRnd rnd) => State -> State
|
||||
Ascon_p S = foldl p`{rnd} S (drop`{back=rnd} Const)
|
||||
Ascon_p S = foldl round S (drop`{back=rnd} Const)
|
||||
|
||||
/// Single round of the Ascon-p permutation.
|
||||
p : {rnd} (ValidRnd rnd) => State -> [64] -> State
|
||||
p S ci = pL (pS (pC S ci))
|
||||
round : State -> [64] -> State
|
||||
round S ci = pL (pS (pC S ci))
|
||||
|
||||
// 3.1. Internal State
|
||||
|
||||
@@ -149,3 +149,151 @@ wordsToBits M = join (map reverse M)
|
||||
|
||||
bitsToWords : {w,n} (fin w) => [w*n] -> [n][w]
|
||||
bitsToWords M = map reverse (split M)
|
||||
|
||||
// 4. Authenticated Encryption Schema: Ascon-AEAD128
|
||||
|
||||
/// Encryption using Ascon-AEAD128
|
||||
///
|
||||
/// Parameters:
|
||||
/// - Key
|
||||
/// - Nonce
|
||||
/// - Additional data
|
||||
/// - Plaintext
|
||||
///
|
||||
/// Returns:
|
||||
/// - Authenticated ciphertext
|
||||
AEAD128_encrypt : {a, p} (fin a, fin p) => [128] -> [128] -> [a] -> [p] -> [p + 128]
|
||||
AEAD128_encrypt K N A P = C # T
|
||||
where
|
||||
// key and nonce as two 64-bit integers
|
||||
[K0,K1] = bitsToWords K
|
||||
[N0,N1] = bitsToWords N
|
||||
|
||||
S0 = Ascon_p`{12} [Ascon_AEAD128_IV, K0, K1, N0, N1] ^ [0, 0, 0, K0, K1]
|
||||
SA = AddAD S0 A
|
||||
|
||||
SCs = [XorBlock s p | s <- [SA] # map Ascon_p`{8} SCs | p <- toBlocks P]
|
||||
|
||||
C = take (join (map ExtractC SCs))
|
||||
|
||||
ST = Ascon_p`{12} (last SCs ^ [0, 0, K0, K1, 0])
|
||||
T = ExtractT ST ^ K
|
||||
|
||||
/// Decryption using Ascon-AEAD128
|
||||
///
|
||||
/// Parameters:
|
||||
/// - Key
|
||||
/// - Nonce
|
||||
/// - Additional data
|
||||
/// - Ciphertext
|
||||
///
|
||||
/// Returns:
|
||||
/// - Some plaintext on success
|
||||
/// - None when message authentication fails
|
||||
AEAD128_decrypt : {a, p} (fin a, fin p) => [128] -> [128] -> [a] -> [p + 128] -> Option [p]
|
||||
AEAD128_decrypt K N A (Cs_ # Cl # T) =
|
||||
if T == T' then Some P else trace "P" P None
|
||||
where
|
||||
// key and nonce as two 64-bit integers
|
||||
[K0,K1] = bitsToWords K
|
||||
[N0,N1] = bitsToWords N
|
||||
|
||||
S0 = Ascon_p`{12} [Ascon_AEAD128_IV, K0, K1, N0, N1] ^ [0, 0, 0, K0, K1]
|
||||
SA = AddAD S0 A
|
||||
|
||||
Cs = split`{p/128, 128} Cs_
|
||||
|
||||
SCs # [SCl] = [SA] # [Ascon_p`{8} (AssignC s c) | s <- SCs | c <- Cs]
|
||||
|
||||
Plmask # SCl' = ExtractC SCl
|
||||
Sl' = AssignC SCl (Cl # (0b1#0 ^ SCl'))
|
||||
|
||||
Ps = zipWith (\x y -> ExtractC x ^ y) SCs Cs
|
||||
Pl = Plmask ^ Cl
|
||||
P = join Ps # Pl
|
||||
|
||||
ST = Ascon_p`{12} (Sl' ^ [0, 0, K0, K1, 0])
|
||||
T' = ExtractT ST ^ K
|
||||
|
||||
AEAD128_encrypt_bytes : {a, p} (fin a, fin p) => [16][8] -> [16][8] -> [a][8] -> [p][8] -> [p + 16][8]
|
||||
AEAD128_encrypt_bytes K N A P =
|
||||
bitsToWords (AEAD128_encrypt (wordsToBits K) (wordsToBits N) (wordsToBits A) (wordsToBits P))
|
||||
|
||||
AEAD128_decrypt_bytes : {a, p} (fin a, fin p) => [16][8] -> [16][8] -> [a][8] -> [p + 16][8] -> Option ([p][8])
|
||||
AEAD128_decrypt_bytes K N A C =
|
||||
case AEAD128_decrypt (wordsToBits K) (wordsToBits N) (wordsToBits A) (wordsToBits C) of
|
||||
None -> None
|
||||
Some p -> Some (bitsToWords p)
|
||||
|
||||
AddAD : {a} (fin a) => State -> [a] -> State
|
||||
AddAD S A
|
||||
| a == 0 => DomainSep S
|
||||
| a > 0 => DomainSep (foldl AbsorbBlock128 S (toBlocks A))
|
||||
|
||||
DomainSep : State -> State
|
||||
DomainSep [s0, s1, s2, s3, s4] = [s0, s1, s2, s3, s4 ^ 0b1 # 0]
|
||||
|
||||
AbsorbBlock128 : State -> [128] -> State
|
||||
AbsorbBlock128 S X = Ascon_p`{8} (XorBlock S X)
|
||||
|
||||
XorBlock : State -> [128] -> State
|
||||
XorBlock [s0, s1, s2, s3, s4] (xhi # xlo) = [s0 ^ xlo, s1 ^ xhi, s2, s3, s4]
|
||||
|
||||
ExtractC : State -> [128]
|
||||
ExtractC [s0, s1, _, _, _] = wordsToBits [s0, s1]
|
||||
|
||||
AssignC : State -> [128] -> State
|
||||
AssignC [_, _, s2, s3, s4] C = bitsToWords C # [s2, s3, s4]
|
||||
|
||||
ExtractT : State -> [128]
|
||||
ExtractT [_, _, _, s3, s4] = wordsToBits [s3, s4]
|
||||
|
||||
Ascon_AEAD128_IV : [64]
|
||||
Ascon_AEAD128_IV = 0x00001000808c0001
|
||||
|
||||
// 5. Hash and eXtendable-Output Functions (XOFs)
|
||||
|
||||
hashBlocks : {n} (fin n) => [64] -> [n][64] -> [inf]
|
||||
hashBlocks IV Ms = wordsToBits [head S | S <- iterate Ascon_p`{12} Sn]
|
||||
where
|
||||
S0 = Ascon_p`{12} [IV, 0, 0, 0, 0]
|
||||
Sn = foldl AbsorbBlock64 S0 Ms
|
||||
|
||||
AbsorbBlock64 : State -> [64] -> State
|
||||
AbsorbBlock64 [s0, s1, s2, s3, s4] X = Ascon_p`{12} [X ^ s0, s1, s2, s3, s4]
|
||||
|
||||
/// 5.1. Specification of Ascon-Hash256
|
||||
Hash256 : {n} (fin n) => [n] -> [256]
|
||||
Hash256 M = take (hashBlocks Hash256_IV (toBlocks M))
|
||||
|
||||
Hash256_bytes : {n} (fin n) => [n][8] -> [32][8]
|
||||
Hash256_bytes M = bitsToWords (Hash256 (wordsToBits M))
|
||||
|
||||
Hash256_IV : [64]
|
||||
Hash256_IV = 0x0000080100cc0002
|
||||
|
||||
// 5.2. Specification of Ascon-XOF128
|
||||
|
||||
XOF128 : {r, n} (fin n, fin r) => [n] -> [r]
|
||||
XOF128 M = take (hashBlocks XOF128_IV (toBlocks M))
|
||||
|
||||
XOF128_bytes : {r, n} (fin n, fin r) => [n][8] -> [r][8]
|
||||
XOF128_bytes M = bitsToWords (XOF128 (wordsToBits M))
|
||||
|
||||
XOF128_IV : [64]
|
||||
XOF128_IV = 0x0000080000cc0003
|
||||
|
||||
// 5.3. Specification of Ascon-CXOF128
|
||||
|
||||
CXOF128 : {r, c, n} (fin n, fin r, fin c, 64 >= width c) => [c] -> [n] -> [r]
|
||||
CXOF128 Z M = take (hashBlocks CXOF128_IV Ms)
|
||||
where
|
||||
Ms = [`c]
|
||||
# toBlocks Z
|
||||
# toBlocks M
|
||||
|
||||
CXOF128_bytes : {r, z, n} (fin n, fin r, 61 >= width z) => [z][8] -> [n][8] -> [r][8]
|
||||
CXOF128_bytes Z M = bitsToWords (CXOF128 (wordsToBits Z) (wordsToBits M))
|
||||
|
||||
CXOF128_IV : [64]
|
||||
CXOF128_IV = 0x0000080000cc0004
|
||||
|
@@ -1,51 +0,0 @@
|
||||
module AsconCipher where
|
||||
|
||||
import Ascon
|
||||
|
||||
// 4. Authenticated Encryption Schema: Ascon-AEAD128
|
||||
|
||||
Ascon_AEAD128 : {a, p} (fin a, fin p) => [128] -> [128] -> [a] -> [p] -> [p + 128]
|
||||
Ascon_AEAD128 K N A P = C # T
|
||||
where
|
||||
// key and nonce as two 64-bit integers
|
||||
[K0,K1] = bitsToWords K
|
||||
[N0,N1] = bitsToWords N
|
||||
|
||||
S0 = Ascon_p`{12} [Ascon_AEAD128_IV, K0, K1, N0, N1]
|
||||
^ [0, 0, 0, K0, K1]
|
||||
|
||||
SA = AddAD S0 A
|
||||
|
||||
SCs = zipWith XorBlock (take ([SA] # map Ascon_p`{8} SCs)) (toBlocks P)
|
||||
|
||||
C = take (join (map ExtractC SCs))
|
||||
|
||||
ST = Ascon_p`{12} (last SCs ^ [0, 0, K0, K1, 0])
|
||||
T = ExtractT ST ^ K
|
||||
|
||||
Ascon_AEAD128_bytes : {a, p} (fin a, fin p) => [16][8] -> [16][8] -> [a][8] -> [p][8] -> [p + 16][8]
|
||||
Ascon_AEAD128_bytes K N A P =
|
||||
bitsToWords (Ascon_AEAD128 (wordsToBits K) (wordsToBits N) (wordsToBits A) (wordsToBits P))
|
||||
|
||||
AddAD : {a} (fin a) => State -> [a] -> State
|
||||
AddAD S A
|
||||
| a == 0 => DomainSep S
|
||||
| a > 0 => DomainSep (foldl AbsorbBlock S (toBlocks A))
|
||||
|
||||
XorBlock : State -> [128] -> State
|
||||
XorBlock [s0, s1, s2, s3, s4] (xhi # xlo) = [s0 ^ xlo, s1 ^ xhi, s2, s3, s4]
|
||||
|
||||
AbsorbBlock : State -> [128] -> State
|
||||
AbsorbBlock S X = Ascon_p`{8} (XorBlock S X)
|
||||
|
||||
DomainSep : State -> State
|
||||
DomainSep [s0, s1, s2, s3, s4] = [s0, s1, s2, s3, s4 ^ 0b1 # 0]
|
||||
|
||||
ExtractC : State -> [128]
|
||||
ExtractC [s0, s1, _, _, _] = wordsToBits [s0, s1]
|
||||
|
||||
ExtractT : State -> [128]
|
||||
ExtractT [_, _, _, s3, s4] = wordsToBits [s3, s4]
|
||||
|
||||
Ascon_AEAD128_IV : [64]
|
||||
Ascon_AEAD128_IV = 0x00001000808c0001
|
@@ -1,56 +0,0 @@
|
||||
module AsconHash where
|
||||
|
||||
import Ascon
|
||||
|
||||
// 5. Hash and eXtendable-Output Functions (XOFs)
|
||||
|
||||
Ascon_Digest : {n} (fin n) => [64] -> [n][64] -> [inf]
|
||||
Ascon_Digest IV Ms = wordsToBits [head S | S <- iterate Ascon_p`{12} Sn]
|
||||
where
|
||||
S0 = Ascon_p`{12} [IV, 0, 0, 0, 0]
|
||||
Sn = foldl AbsorbBlock S0 Ms
|
||||
|
||||
AbsorbBlock : State -> [64] -> State
|
||||
AbsorbBlock [s0, s1, s2, s3, s4] X = Ascon_p`{12} [X ^ s0, s1, s2, s3, s4]
|
||||
|
||||
/// 5.1. Specification of Ascon-Hash256
|
||||
Ascon_Hash256 : {n} (fin n) => [n] -> [256]
|
||||
Ascon_Hash256 M = take (Ascon_Digest Ascon_Hash256_IV (toBlocks M))
|
||||
|
||||
Ascon_Hash256_IV : [64]
|
||||
Ascon_Hash256_IV = 0x0000080100cc0002
|
||||
|
||||
Ascon_Hash256_bytes : {n} (fin n) => [n][8] -> [32][8]
|
||||
Ascon_Hash256_bytes M = bitsToWords (Ascon_Hash256 (wordsToBits M))
|
||||
|
||||
property
|
||||
initial_value_works =
|
||||
Ascon_p`{12} ([Ascon_Hash256_IV] # zero)
|
||||
==
|
||||
[0x9b1e5494e934d681, 0x4bc3a01e333751d2, 0xae65396c6b34b81a, 0x3c7fd4a4d56a4db3, 0x1a5c464906c5976d]
|
||||
|
||||
// 5.2. Specification of Ascon-XOF128
|
||||
|
||||
Ascon_XOF128 : {r, n} (fin n, fin r) => [n] -> [r]
|
||||
Ascon_XOF128 M = take (Ascon_Digest Ascon_XOF128_IV (toBlocks M))
|
||||
|
||||
Ascon_XOF128_IV : [64]
|
||||
Ascon_XOF128_IV = 0x0000080000cc0003
|
||||
|
||||
Ascon_XOF128_bytes : {r, n} (fin n, fin r) => [n][8] -> [r][8]
|
||||
Ascon_XOF128_bytes M = bitsToWords (Ascon_XOF128 (wordsToBits M))
|
||||
|
||||
// 5.3. Specification of Ascon-CXOF128
|
||||
|
||||
Ascon_CXOF128 : {r, c, n} (fin n, fin r, fin c, 64 >= width c) => [c] -> [n] -> [r]
|
||||
Ascon_CXOF128 Z M = take (Ascon_Digest Ascon_CXOF128_IV Ms)
|
||||
where
|
||||
Ms = [`c]
|
||||
# toBlocks Z
|
||||
# toBlocks M
|
||||
|
||||
Ascon_CXOF128_bytes : {r, z, n} (fin n, fin r, 61 >= width z) => [z][8] -> [n][8] -> [r][8]
|
||||
Ascon_CXOF128_bytes Z M = bitsToWords (Ascon_CXOF128 (wordsToBits Z) (wordsToBits M))
|
||||
|
||||
Ascon_CXOF128_IV : [64]
|
||||
Ascon_CXOF128_IV = 0x0000080000cc0004
|
@@ -1,11 +1,14 @@
|
||||
module TestAsconAEAD128 where
|
||||
|
||||
import Ascon
|
||||
import AsconCipher
|
||||
|
||||
testcase : {n, m} (fin m, fin n) => [128] -> [128] -> [8 * m] -> [8 * n] -> [8 * (m + 16)] -> Bit
|
||||
testcase K N P A C =
|
||||
Ascon_AEAD128_bytes (split K) (split N) (split A) (split P) == split C
|
||||
AEAD128_encrypt_bytes (split K) (split N) (split A) (split P) == split C
|
||||
/\
|
||||
case AEAD128_decrypt_bytes (split K) (split N) (split A) (split C) of
|
||||
None -> False
|
||||
Some p -> p == split P
|
||||
|
||||
property
|
||||
test1 = testcase 0x000102030405060708090A0B0C0D0E0F 0x101112131415161718191A1B1C1D1E1F [] 0x 0x4F9C278211BEC9316BF68F46EE8B2EC6
|
||||
|
@@ -1,9 +1,9 @@
|
||||
module TestAsconCXOF128 where
|
||||
|
||||
import AsconHash
|
||||
import Ascon
|
||||
|
||||
testcase : {r, z, n} (fin n, fin r, 61 >= width z) => [8*n] -> [8*z] -> [8*r] -> Bool
|
||||
testcase M Z D = Ascon_CXOF128_bytes (split Z) (split M) == split D
|
||||
testcase M Z D = CXOF128_bytes (split Z) (split M) == split D
|
||||
|
||||
property
|
||||
test1 = testcase [] [] 0x4F50159EF70BB3DAD8807E034EAEBD44C4FA2CBBC8CF1F05511AB66CDCC529905CA12083FC186AD899B270B1473DC5F7EC88D1052082DCDFE69FB75D269E7B74
|
||||
|
@@ -1,9 +1,9 @@
|
||||
module TestAsconHash256 where
|
||||
|
||||
import AsconHash
|
||||
import Ascon
|
||||
|
||||
testcase : {n} (fin n) => [8*n] -> [256] -> Bool
|
||||
testcase M D = Ascon_Hash256_bytes (split M) == split D
|
||||
testcase M D = Hash256_bytes (split M) == split D
|
||||
|
||||
property
|
||||
test1 = testcase [] 0x0B3BE5850F2F6B98CAF29F8FDEA89B64A1FA70AA249B8F839BD53BAA304D92B2
|
||||
|
@@ -1,9 +1,9 @@
|
||||
module TestAsconXOF128 where
|
||||
|
||||
import AsconHash
|
||||
import Ascon
|
||||
|
||||
testcase : {r, n} (fin n, fin r) => [8*n] -> [8*r] -> Bool
|
||||
testcase M D = Ascon_XOF128_bytes (split M) == split D
|
||||
testcase M D = XOF128_bytes (split M) == split D
|
||||
|
||||
property
|
||||
test1 = testcase [] 0x473D5E6164F58B39DFD84AACDB8AE42EC2D91FED33388EE0D960D9B3993295C6AD77855A5D3B13FE6AD9E6098988373AF7D0956D05A8F1665D2C67D1A3AD10FF
|
||||
|
Reference in New Issue
Block a user