1 import Base 2 import ../../../../src/crypto/blake/blake2b/types.bend as T 3 import ../../../../src/crypto/blake/blake2b/compress.bend as F 4 import ../../../../src/crypto/blake/blake2b/blake2b.bend as I 5 import ../../../../spec/crypto/blake/blake2b.bend as S 6 7 # The public BLAKE2b-512 API equals the RFC 7693 specification of spec/crypto/blake/blake2b.bend for 8 # every packed input array and every byte length: the same digest, or None for 9 # both when byte_length exceeds 4 * the array's capacity. 10 law blake2b_correct: 11 for words: Array 12 for +byte_length: Nat 13 {I.blake2b(words,byte_length) == S.blake2b(words,byte_length) : Maybe<&1,Array>} 14 15 # The compression function F on a block that is not the last, for every chaining value h, 16 # counter t and message block. 17 law compress_correct: 18 for +h: T.Chain 19 for +t: T.Counter 20 for +w0: U32 21 for +w1: U32 22 for +w2: U32 23 for +w3: U32 24 for +w4: U32 25 for +w5: U32 26 for +w6: U32 27 for +w7: U32 28 for +w8: U32 29 for +w9: U32 30 for +w10: U32 31 for +w11: U32 32 for +w12: U32 33 for +w13: U32 34 for +w14: U32 35 for +w15: U32 36 for +w16: U32 37 for +w17: U32 38 for +w18: U32 39 for +w19: U32 40 for +w20: U32 41 for +w21: U32 42 for +w22: U32 43 for +w23: U32 44 for +w24: U32 45 for +w25: U32 46 for +w26: U32 47 for +w27: U32 48 for +w28: U32 49 for +w29: U32 50 for +w30: U32 51 for +w31: U32 52 {F.compress(h,t,w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29,w30,w31) == S.compress(h,[T.W{w0,w1},T.W{w2,w3},T.W{w4,w5},T.W{w6,w7},T.W{w8,w9},T.W{w10,w11},T.W{w12,w13},T.W{w14,w15},T.W{w16,w17},T.W{w18,w19},T.W{w20,w21},T.W{w22,w23},T.W{w24,w25},T.W{w26,w27},T.W{w28,w29},T.W{w30,w31}],t,False{}) : T.Chain} 53 54 # The compression function F on the last block, for every chaining value h, 55 # counter t and message block. 56 law compress_last_correct: 57 for +h: T.Chain 58 for +t: T.Counter 59 for +w0: U32 60 for +w1: U32 61 for +w2: U32 62 for +w3: U32 63 for +w4: U32 64 for +w5: U32 65 for +w6: U32 66 for +w7: U32 67 for +w8: U32 68 for +w9: U32 69 for +w10: U32 70 for +w11: U32 71 for +w12: U32 72 for +w13: U32 73 for +w14: U32 74 for +w15: U32 75 for +w16: U32 76 for +w17: U32 77 for +w18: U32 78 for +w19: U32 79 for +w20: U32 80 for +w21: U32 81 for +w22: U32 82 for +w23: U32 83 for +w24: U32 84 for +w25: U32 85 for +w26: U32 86 for +w27: U32 87 for +w28: U32 88 for +w29: U32 89 for +w30: U32 90 for +w31: U32 91 {F.compress_last(h,t,w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29,w30,w31) == S.compress(h,[T.W{w0,w1},T.W{w2,w3},T.W{w4,w5},T.W{w6,w7},T.W{w8,w9},T.W{w10,w11},T.W{w12,w13},T.W{w14,w15},T.W{w16,w17},T.W{w18,w19},T.W{w20,w21},T.W{w22,w23},T.W{w24,w25},T.W{w26,w27},T.W{w28,w29},T.W{w30,w31}],t,True{}) : T.Chain} 92 93 # Every digest is sixteen words (64 bytes). 94 law digest_size: 95 for h: T.Chain 96 {Pair.snd(Array,U32,Array.size(U32,I.digest(h))) == 16 : U32} 97 98 # Lengths past the array's capacity are rejected. 99 law capacity_rejection: 100 for a: Array 101 for +n: Nat 102 for +capacity: U32 103 for invalid: {Nat.is_le(n,Nat.mul(4n,U32.to_nat(capacity))) == False{} : Bool} 104 {I.sized(n,(a,capacity)) == None{} : Maybe<&1,Array>}