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