Client: don't try to generate vanity keys with wrong first letter
This commit is contained in:
parent
7e4a0f3368
commit
89c018f31b
@ -38,62 +38,84 @@ let gen_keys_containing
|
|||||||
~containing ~name (cctxt : #Client_context.io_wallet) =
|
~containing ~name (cctxt : #Client_context.io_wallet) =
|
||||||
let unrepresentable =
|
let unrepresentable =
|
||||||
List.filter (fun s -> not @@ Base58.Alphabet.all_in_alphabet Base58.Alphabet.bitcoin s) containing in
|
List.filter (fun s -> not @@ Base58.Alphabet.all_in_alphabet Base58.Alphabet.bitcoin s) containing in
|
||||||
|
let good_initial_char = "KLMNPQRSTUVWXYZabcdefghi" in
|
||||||
|
let bad_initial_char = "123456789ABCDEFGHJjkmnopqrstuvwxyz" in
|
||||||
match unrepresentable with
|
match unrepresentable with
|
||||||
| _ :: _ ->
|
| _ :: _ ->
|
||||||
cctxt#warning
|
cctxt#error
|
||||||
"The following can't be written in the key alphabet (%a): %a"
|
"@[<v 0>The following words can't be written in the key alphabet: %a.@,\
|
||||||
Base58.Alphabet.pp Base58.Alphabet.bitcoin
|
Valid characters: %a@,\
|
||||||
|
Extra restriction for the first character: %s@]"
|
||||||
(Format.pp_print_list
|
(Format.pp_print_list
|
||||||
~pp_sep:(fun ppf () -> Format.fprintf ppf ", ")
|
~pp_sep:(fun ppf () -> Format.fprintf ppf ", ")
|
||||||
(fun ppf s -> Format.fprintf ppf "'%s'" s))
|
(fun ppf s -> Format.fprintf ppf "'%s'" s))
|
||||||
unrepresentable >>= return
|
unrepresentable
|
||||||
|
Base58.Alphabet.pp Base58.Alphabet.bitcoin
|
||||||
|
good_initial_char
|
||||||
| [] ->
|
| [] ->
|
||||||
Public_key_hash.mem cctxt name >>=? fun name_exists ->
|
let unrepresentable =
|
||||||
if name_exists && not force
|
List.filter (fun s -> prefix &&
|
||||||
then
|
String.contains bad_initial_char s.[0]) containing in
|
||||||
cctxt#warning
|
match unrepresentable with
|
||||||
"Key for name '%s' already exists. Use --force to update." name >>= return
|
| _ :: _ ->
|
||||||
else
|
cctxt#error
|
||||||
begin
|
"@[<v 0>The following words don't respect the first character restriction: %a.@,\
|
||||||
cctxt#warning "This process uses a brute force search and \
|
Valid characters: %a@,\
|
||||||
may take a long time to find a key." >>= fun () ->
|
Extra restriction for the first character: %s@]"
|
||||||
let matches =
|
(Format.pp_print_list
|
||||||
if prefix then
|
~pp_sep:(fun ppf () -> Format.fprintf ppf ", ")
|
||||||
let containing_tz1 = List.map ((^) "tz1") containing in
|
(fun ppf s -> Format.fprintf ppf "'%s'" s))
|
||||||
(fun key -> List.exists
|
unrepresentable
|
||||||
(fun containing ->
|
Base58.Alphabet.pp Base58.Alphabet.bitcoin
|
||||||
String.sub key 0 (String.length containing) = containing)
|
good_initial_char
|
||||||
containing_tz1)
|
| [] ->
|
||||||
else
|
Public_key_hash.mem cctxt name >>=? fun name_exists ->
|
||||||
let re = Re.Str.regexp (String.concat "\\|" containing) in
|
if name_exists && not force
|
||||||
(fun key -> try ignore (Re.Str.search_forward re key 0); true
|
then
|
||||||
with Not_found -> false) in
|
cctxt#warning
|
||||||
let rec loop attempts =
|
"Key for name '%s' already exists. Use --force to update." name >>= return
|
||||||
let public_key_hash, public_key, secret_key =
|
else
|
||||||
Signature.generate_key () in
|
begin
|
||||||
let hash = Signature.Public_key_hash.to_b58check @@
|
cctxt#warning "This process uses a brute force search and \
|
||||||
Signature.Public_key.hash public_key in
|
may take a long time to find a key." >>= fun () ->
|
||||||
if matches hash
|
let matches =
|
||||||
then
|
if prefix then
|
||||||
let pk_uri = Tezos_signer_backends.Unencrypted.make_pk public_key in
|
let containing_tz1 = List.map ((^) "tz1") containing in
|
||||||
begin
|
(fun key -> List.exists
|
||||||
if encrypted then
|
(fun containing ->
|
||||||
Tezos_signer_backends.Encrypted.encrypt cctxt secret_key
|
String.sub key 0 (String.length containing) = containing)
|
||||||
|
containing_tz1)
|
||||||
else
|
else
|
||||||
return (Tezos_signer_backends.Unencrypted.make_sk secret_key)
|
let re = Re.Str.regexp (String.concat "\\|" containing) in
|
||||||
end >>=? fun sk_uri ->
|
(fun key -> try ignore (Re.Str.search_forward re key 0); true
|
||||||
register_key cctxt ~force
|
with Not_found -> false) in
|
||||||
(public_key_hash, pk_uri, sk_uri) name >>=? fun () ->
|
let rec loop attempts =
|
||||||
return hash
|
let public_key_hash, public_key, secret_key =
|
||||||
else begin if attempts mod 25_000 = 0
|
Signature.generate_key () in
|
||||||
then cctxt#message "Tried %d keys without finding a match" attempts
|
let hash = Signature.Public_key_hash.to_b58check @@
|
||||||
else Lwt.return () end >>= fun () ->
|
Signature.Public_key.hash public_key in
|
||||||
loop (attempts + 1) in
|
if matches hash
|
||||||
loop 1 >>=? fun key_hash ->
|
then
|
||||||
cctxt#message
|
let pk_uri = Tezos_signer_backends.Unencrypted.make_pk public_key in
|
||||||
"Generated '%s' under the name '%s'." key_hash name >>= fun () ->
|
begin
|
||||||
return ()
|
if encrypted then
|
||||||
end
|
Tezos_signer_backends.Encrypted.encrypt cctxt secret_key
|
||||||
|
else
|
||||||
|
return (Tezos_signer_backends.Unencrypted.make_sk secret_key)
|
||||||
|
end >>=? fun sk_uri ->
|
||||||
|
register_key cctxt ~force
|
||||||
|
(public_key_hash, pk_uri, sk_uri) name >>=? fun () ->
|
||||||
|
return hash
|
||||||
|
else begin if attempts mod 25_000 = 0
|
||||||
|
then
|
||||||
|
cctxt#message "Tried %d keys without finding a match" attempts
|
||||||
|
else Lwt.return () end >>= fun () ->
|
||||||
|
loop (attempts + 1) in
|
||||||
|
loop 1 >>=? fun key_hash ->
|
||||||
|
cctxt#message
|
||||||
|
"Generated '%s' under the name '%s'." key_hash name >>= fun () ->
|
||||||
|
return ()
|
||||||
|
end
|
||||||
|
|
||||||
let commands () : Client_context.io_wallet Clic.command list =
|
let commands () : Client_context.io_wallet Clic.command list =
|
||||||
let open Clic in
|
let open Clic in
|
||||||
|
Loading…
Reference in New Issue
Block a user