67 lines
1.8 KiB
Plaintext
67 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
|
||
|
let coco = failwith ("Counters does not match") in s
|
||
|
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
|
||
|
| [] -> (valid,keys)
|
||
|
| key::tl -> (
|
||
|
let keys = tl in
|
||
|
if (pkh_sig.0 = Crypto.hash_key (key)) then
|
||
|
let valid =
|
||
|
if (Crypto.check key pkh_sig.1 packed_payload) then valid + 1n
|
||
|
else let coco = failwith ("Invalid signature") in valid
|
||
|
in
|
||
|
(valid,keys)
|
||
|
else (valid,keys)
|
||
|
)
|
||
|
in
|
||
|
let (valid,keys) = List.fold aux param.signatures (valid,keys) in
|
||
|
if (valid < s.threshold) then
|
||
|
let coco = failwith ("Not enough signatures passed the check") in
|
||
|
s
|
||
|
else
|
||
|
{s with counter = s.counter + 1n}
|
||
|
)
|
||
|
in
|
||
|
(message(unit),s)
|
||
|
|
||
|
let main (param, s: parameter * storage) : return =
|
||
|
match (param) with
|
||
|
| CheckMessage (p) -> check_message (p,s)
|