Multisig made robust to replay attack

This commit is contained in:
Lesenechal Remi 2019-11-20 18:17:35 +01:00
parent 1185b8abda
commit 87d0064113
3 changed files with 28 additions and 15 deletions

View File

@ -83,13 +83,11 @@ let evaluate_michelson ?options program =
let%bind etv = evaluate ?options program in let%bind etv = evaluate ?options program in
ex_value_ty_to_michelson etv ex_value_ty_to_michelson etv
let pack_message_lambda (lambda:Michelson.t) = let pack_payload (payload:Michelson.t) ty =
let open Memory_proto_alpha.Protocol.Script_typed_ir in let%bind payload =
let input_ty = Lambda_t (Unit_t None , List_t ((Operation_t None),None,false) , None) in
let%bind lambda =
Trace.trace_tzresult_lwt (simple_error "error parsing message") @@ Trace.trace_tzresult_lwt (simple_error "error parsing message") @@
Memory_proto_alpha.parse_michelson_data lambda input_ty in Memory_proto_alpha.parse_michelson_data payload ty in
let%bind data = let%bind data =
Trace.trace_tzresult_lwt (simple_error "error packing message") @@ Trace.trace_tzresult_lwt (simple_error "error packing message") @@
Memory_proto_alpha.pack input_ty lambda in Memory_proto_alpha.pack ty payload in
ok @@ data ok @@ data

View File

@ -2,8 +2,10 @@
type counter_t is nat type counter_t is nat
type threshold_t is nat type threshold_t is nat
type authorized_keys_t is list(key) type authorized_keys_t is list(key)
type id_t is string
type storage_t is record type storage_t is record
id : id_t ;
counter : counter_t ; counter : counter_t ;
threshold : threshold_t ; threshold : threshold_t ;
auth : authorized_keys_t ; auth : authorized_keys_t ;
@ -28,14 +30,15 @@ function check_message (const param : check_message_pt;
if param.counter =/= s.counter then if param.counter =/= s.counter then
failwith ("Counters does not match") failwith ("Counters does not match")
else block { else block {
var packed_msg : bytes := bytes_pack(message) ; const packed_payload : bytes =
bytes_pack((message , param.counter , s.id , get_chain_id));
var valid : nat := 0n ; var valid : nat := 0n ;
for sig in list param.signatures block { for sig in list param.signatures block {
var is_valid : bool := False ; var is_valid : bool := False ;
for pk in list s.auth block { for pk in list s.auth block {
if crypto_check(pk,sig,packed_msg) then is_valid := True if crypto_check(pk,sig,packed_payload) then is_valid := True
else skip; else skip;
}; };

View File

@ -33,22 +33,26 @@ let str_keys (raw_pk, raw_sk) =
let (sk_str:string) = Base58.simple_encode (Ed25519.Secret_key.b58check_encoding) raw_sk in let (sk_str:string) = Base58.simple_encode (Ed25519.Secret_key.b58check_encoding) raw_sk in
(pk_str,sk_str) (pk_str,sk_str)
let sign_message (msg : expression) raw_sk : string result = let sign_message (payload : expression) raw_sk : string result =
let open Tezos_crypto in let open Tezos_crypto in
let (sk : Signature.secret_key) = Signature.Ed25519 raw_sk in let (sk : Signature.secret_key) = Signature.Ed25519 raw_sk in
let%bind program,_ = get_program () in let%bind program,_ = get_program () in
let%bind (msg : Tezos_utils.Michelson.michelson) = let%bind code =
let env = Ast_typed.program_environment program in let env = Ast_typed.program_environment program in
Ligo.Run.Of_simplified.compile_expression ~env ~state:(Typer.Solver.initial_state) msg Compile.Of_simplified.compile_expression_as_function
in ~env ~state:(Typer.Solver.initial_state) payload in
let%bind msg' = Ligo.Run.Of_michelson.pack_message_lambda msg in let Compiler.Program.{input=_;output=(Ex_ty payload_ty);body=_} = code in
let (signed_data:Signature.t) = Signature.sign sk msg' in let%bind (payload: Tezos_utils.Michelson.michelson) =
Ligo.Run.Of_michelson.evaluate_michelson code in
let%bind packed_payload = Ligo.Run.Of_michelson.pack_payload payload payload_ty in
let (signed_data:Signature.t) = Signature.sign sk packed_payload in
let signature_str = Signature.to_b58check signed_data in let signature_str = Signature.to_b58check signed_data in
ok signature_str ok signature_str
let init_storage threshold counter pkeys = let init_storage threshold counter pkeys =
let keys = List.map (fun el -> e_key @@ fst @@ str_keys el) pkeys in let keys = List.map (fun el -> e_key @@ fst @@ str_keys el) pkeys in
ez_e_record [ ez_e_record [
("id" , e_string "MULTISIG" ) ;
("counter" , e_nat counter ) ; ("counter" , e_nat counter ) ;
("threshold" , e_nat threshold) ; ("threshold" , e_nat threshold) ;
("auth" , e_typed_list keys t_key ) ; ("auth" , e_typed_list keys t_key ) ;
@ -59,11 +63,19 @@ let empty_op_list =
let empty_message = e_lambda "arguments" let empty_message = e_lambda "arguments"
(Some t_unit) (Some (t_list t_operation)) (Some t_unit) (Some (t_list t_operation))
empty_op_list empty_op_list
let chain_id_zero = e_chain_id @@ Tezos_crypto.Base58.simple_encode
Tezos_base__TzPervasives.Chain_id.b58check_encoding
Tezos_base__TzPervasives.Chain_id.zero
(* sign the same message 'msg' with the secret keys of 'keys' *) (* sign the same message 'msg' with the secret keys of 'keys' *)
let params counter msg keys = let params counter msg keys =
let aux = fun acc sk -> let aux = fun acc sk ->
let%bind signature = sign_message msg (snd sk) in let payload = e_tuple
[ msg ;
e_nat counter ;
e_string "MULTISIG" ;
chain_id_zero ] in
let%bind signature = sign_message payload (snd sk) in
ok @@ (e_signature signature)::acc in ok @@ (e_signature signature)::acc in
let%bind signed_msgs = Trace.bind_fold_list aux [] keys in let%bind signed_msgs = Trace.bind_fold_list aux [] keys in
ok @@ e_constructor ok @@ e_constructor