65 lines
1.8 KiB
Plaintext
65 lines
1.8 KiB
Plaintext
// storage type
|
|
|
|
type counter = nat
|
|
type threshold = nat
|
|
type authorized_keys = key list
|
|
type id = string
|
|
|
|
type storage = {
|
|
id : id;
|
|
counter : counter;
|
|
threshold : threshold;
|
|
auth : authorized_keys
|
|
}
|
|
|
|
// I/O types
|
|
|
|
type message = unit -> operation list
|
|
|
|
type signatures = (key_hash * signature) list
|
|
|
|
type check_message_pt = {
|
|
counter : counter;
|
|
message : message;
|
|
signatures : signatures
|
|
}
|
|
|
|
type return = operation list * storage
|
|
|
|
type parameter = CheckMessage of check_message_pt
|
|
|
|
let check_message (param, s : check_message_pt * storage) : return =
|
|
let message : message = param.message in
|
|
let s =
|
|
if param.counter <> s.counter then
|
|
(failwith "Counters does not match" : storage)
|
|
else
|
|
let packed_payload : bytes =
|
|
Bytes.pack (message, param.counter, s.id, chain_id) in
|
|
let valid : nat = 0n in
|
|
let keys : authorized_keys = s.auth in
|
|
let aux =
|
|
fun (vk, pkh_sig: (nat * authorized_keys)*(key_hash * signature)) ->
|
|
let valid, keys = vk in
|
|
match keys with
|
|
| [] -> vk
|
|
| key::keys ->
|
|
if pkh_sig.0 = Crypto.hash_key key
|
|
then
|
|
let valid =
|
|
if Crypto.check key pkh_sig.1 packed_payload
|
|
then valid + 1n
|
|
else (failwith "Invalid signature" : nat)
|
|
in valid, keys
|
|
else valid, keys in
|
|
let valid, keys =
|
|
List.fold aux param.signatures (valid, keys) in
|
|
if valid < s.threshold then
|
|
(failwith ("Not enough signatures passed the check") : storage)
|
|
else {s with counter = s.counter + 1n}
|
|
in message unit, s
|
|
|
|
let main (action, store : parameter * storage) : return =
|
|
match action with
|
|
CheckMessage (p) -> check_message (p, store)
|