tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
March 2019
- 20 participants
- 3265 discussions

[translation/donatepages-messagespot_completed] Update translations for donatepages-messagespot_completed
by translation@torproject.org 19 Mar '19
by translation@torproject.org 19 Mar '19
19 Mar '19
commit 5a33b36ae01c0a3761a81a8743bdc66f5fc1369d
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 19 13:45:43 2019 +0000
Update translations for donatepages-messagespot_completed
---
locale/pt_BR/LC_MESSAGES/messages.po | 1089 +++++++++++++++++-----------------
1 file changed, 553 insertions(+), 536 deletions(-)
diff --git a/locale/pt_BR/LC_MESSAGES/messages.po b/locale/pt_BR/LC_MESSAGES/messages.po
index efc9240a4..93c47aeec 100644
--- a/locale/pt_BR/LC_MESSAGES/messages.po
+++ b/locale/pt_BR/LC_MESSAGES/messages.po
@@ -8,46 +8,37 @@
# Victor Galdino <altgaldinovictor(a)gmail.com>, 2018
# dark crystal <darc.krystal(a)insicuri.net>, 2018
# Eduardo Bonsi, 2018
-# Communia <ameaneantie(a)riseup.net>, 2018
# erinm, 2018
# nilson t. c., 2018
# André Almeida <andrefalmeida(a)protonmail.com>, 2018
# Emma Peel, 2018
-# son_mars <miguel.augusto.r.silva(a)gmail.com>, 2019
# Chacal Exodius, 2019
# Eduardo Addad de Oliveira <eduardoaddad(a)hotmail.com>, 2019
+# Communia <ameaneantie(a)riseup.net>, 2019
#
msgid ""
msgstr ""
-"Last-Translator: Eduardo Addad de Oliveira <eduardoaddad(a)hotmail.com>, 2019\n"
+"Last-Translator: Communia <ameaneantie(a)riseup.net>, 2019\n"
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/otf/teams/1519/pt_BR/)\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: tmp/cache_locale/e1/e1e12763540d9524f8871157240d5a8fbf2ea77ace1c46527b3031db68943acc.php:34
-msgid "Processing Donation - Tor"
-msgstr "Processando a sua Doação - Tor"
-
-#: tmp/cache_locale/e1/e1e12763540d9524f8871157240d5a8fbf2ea77ace1c46527b3031db68943acc.php:44
-msgid "Processing Donation. Please Wait..."
-msgstr "Processando a sua Doação - Por Favor Aguarde..."
-
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:34
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:34
msgid "Tor Privacy Policy"
msgstr "Regras de Privacidade do Tor"
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:44
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:44
msgid "Donor privacy policy"
msgstr "Regras de privacidade do doador"
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:58
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:58
msgid ""
"The Tor Project respects donor privacy and welcomes anonymous donations."
msgstr ""
"O Projeto Tor respeita a privacidade de seus doadores aceitando o "
"recebimento de doações anônimas."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:60
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:60
msgid ""
"If being anonymous is important to you, the best way to preserve your "
"anonymity is by donating using a method that doesn't disclose your personal "
@@ -57,7 +48,7 @@ msgstr ""
" anonimato é doando usando um método que não divulgue as suas informações "
"pessoais."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:65
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:65
msgid ""
"If you provide personal information as part of the donation process, it may "
"be collected and retained by third-party service providers and/or the Tor "
@@ -67,7 +58,7 @@ msgstr ""
"elas poderão ser coletadas e retidas por provedores de serviços "
"terceirizados e/ou pelo Projeto Tor, conforme descrito abaixo."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:67
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:67
msgid ""
"The Tor Project has very little influence over how third-party service "
"providers, such as PayPal, may collect and use your information."
@@ -76,7 +67,7 @@ msgstr ""
"pagamentos terceirizados, como o PayPal, que podem coletar e usar as suas "
"informações."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:69
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:69
msgid ""
"We recommend you familiarize yourself with their <a class=\"hyperlinks "
"links\" target=\"_blank\" href=\"https://www.paypal.com/webapps/mpp/ua"
@@ -87,7 +78,7 @@ msgstr ""
"full\">regras</a>, especialmente se você tiver preocupações com a sua "
"privacidade."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:74
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:74
msgid ""
"When you donate to the Tor Project, depending what mechanism you use, we may"
" learn your name, the amount you donated, your email address, phone number "
@@ -98,7 +89,7 @@ msgstr ""
"e-mail, o número de telefone e/ou o seu endereço de correspondência, bem "
"como qualquer outra informação que você forneça."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:76
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:76
msgid ""
"We may also learn incidental data such as the date and time of your "
"donation."
@@ -106,7 +97,7 @@ msgstr ""
"Nós também podemos coletar alguns dados incidentais, como a data e a hora da"
" sua doação."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:78
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:78
msgid ""
"The Tor Project will never have access to your financial data, such as your "
"credit card information.We aim to be careful with your information."
@@ -115,7 +106,7 @@ msgstr ""
" do seu cartão de crédito. O nosso objetivo é ter cuidado com as suas "
"informações."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:83
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:83
msgid ""
"If you have provided your email address, we will email you once to thank you"
" and give you a receipt."
@@ -123,14 +114,14 @@ msgstr ""
"Se você forneceu o seu endereço de e-mail, nós lhe enviaremos um e-mail em "
"retorno com os nossos agradecimentos e o recibo da transação."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:85
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:85
msgid ""
"If you opt in during the donation process, we may email you again in future."
msgstr ""
"Se você optar pelo processo de doação, poderemos lhe enviar um e-mail "
"novamente no futuro."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:87
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:87
msgid ""
"If you donate more than $5,000 and we know your name and address, we are "
"required to disclose it to the IRS in <a class=\"hyperlinks links\" "
@@ -142,7 +133,7 @@ msgstr ""
"class=\"hyperlinks links\" target=\"_blank\" href=\"https://www.irs.gov/pub"
"/irs-pdf/f990ezb.pdf\">Schedule B do Formulário 990</a>."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:89
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:89
msgid ""
"But, that information is redacted from the publicly-available version of our"
" Form 990."
@@ -150,20 +141,20 @@ msgstr ""
"E, essa informação será omitida na versão do nosso formulário 990, "
"publicamente disponível online."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:91
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:91
msgid ""
"We will never publicly identify you as a donor without your permission."
msgstr ""
"Nós nunca iremos identificá-lo publicamente como um doador sem a sua "
"permissão."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:96
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:96
msgid "We do not publish, sell, trade, or rent any information about you."
msgstr ""
"Nós não publicamos, vendemos, negociamos ou alugamos qualquer informação "
"sobre você."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:98
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:98
msgid ""
"For our records, we retain your name, the amount of your donation, the date "
"of the donation, and your contact information."
@@ -171,7 +162,7 @@ msgstr ""
"Para os nossos registros, nós mantemos o seu nome, o valor de sua doação, a "
"data da doação e suas informações de contato."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:100
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:100
msgid ""
"Access to that information is restricted inside the Tor Project to people "
"who need it to do their work, for example by thanking you or mailing you a "
@@ -181,7 +172,7 @@ msgstr ""
" precisam delas para fazer o seu trabalho, por exemplo, em agradecimento ou "
"quando enviamos uma camiseta para você."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:105
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:105
msgid ""
"<span class=\"bold\">The Tor Project very much appreciates all its donors. "
"Thank you for supporting Tor</span>."
@@ -189,52 +180,271 @@ msgstr ""
"<span class=\"bold\">O Projeto Tor aprecia muito todos os seus doadores. "
"Muito obrigado por apoiar o Tor</span>."
-#: tmp/cache_locale/ad/ad05838d90eae883761f0bcec6c27d77959c6e2884e8abf6c4aec89d7a741ea9.php:113
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:656
+#: tmp/cache_locale/fa/fadd8d2107638a3de94449a9eddfca4e8f010bb26f3f6a71e2d875cb910cc5f1.php:113
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:656
msgid "Back to Donate Page"
msgstr "Voltar para a Página de Doações"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:35
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:35
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:35
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:35
msgid "Support the Tor Project Today!"
msgstr "Ajude o Projeto Tor Hoje!"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:48
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:71
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:647
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:48
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:71
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:516
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:654
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:48
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:71
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:48
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:71
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:516
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:642
+#: tmp/cache_locale/9f/9f870858aaf6c5a7c94ea6a959618fbe485cbfd16174993d34a8e370a4567526.php:75
msgid "Tor: Strength in Numbers"
msgstr "Tor: Nossa Força em Números"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:52
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:75
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:52
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:75
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:52
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:75
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:52
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:75
msgid "Donate to the Tor Project and protect the privacy of millions."
msgstr "Doe para o Projeto Tor e proteja a privacidade de milhões."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:54
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:77
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:54
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:77
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:54
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:77
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:54
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:77
msgid "Anonymity loves company."
msgstr "Anonimidade adora companhia "
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:63
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:63
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:63
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:63
msgid "summary_large_image"
msgstr "resumo_de_imagem_grande"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:67
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:67
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:67
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:67
msgid "@torproject"
msgstr "@torproject"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:102
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:102
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:101
+msgid "Want to donate by credit card or PayPal?"
+msgstr "Você deseja doar usando cartão de crédito ou Paypal?"
+
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:110
+msgid ""
+"Thanks for your interest in donating cryptocurrency to the Tor Project."
+msgstr "Agradecemos o seu interesse em doar criptomoedas ao Projeto Tor."
+
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:117
+msgid ""
+"Please fill out this form and then send your coins to the appropriate "
+"wallet."
+msgstr ""
+"Por favor, preencha este formulário antes de enviar moedas para a carteira "
+"escolhida."
+
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:119
+msgid ""
+"Filling out the form is not necessary, but doing so will notify us about "
+"your donation quickly, allow us to send you an acknowledgement, and let us "
+"know your communication preferences."
+msgstr ""
+"O preenchimento do formulário não é necessário, mas com isso nós receberemos"
+" uma notificação rapidamente, e assim poderemos enviar-lhe nossos "
+"agradecimentos e saber mais sobre como você prefere que nos comuniquemos."
+
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:125
+msgid ""
+"Below you will find the cryptocurrencies we accept and our wallet addresses."
+msgstr ""
+"Abaixo você verá quais criptomoedas nós aceitamos e os endereços das "
+"carteiras."
+
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:127
+msgid ""
+"The wallet addresses will be displayed again after you complete the form."
+msgstr ""
+"Os endereços das carteiras serão exibidos após o preenchimento do "
+"formulário."
+
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:129
+msgid ""
+"Please make sure to copy the wallet addresses exactly when making your "
+"donation, as we cannot recover funds sent to the wrong wallet."
+msgstr ""
+"Por favor, confira a exatidão dos endereços das carteiras ao copiá-los para "
+"fazer sua doação, pois nós não podemos resgatar fundos enviados para outras "
+"carteiras."
+
+#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:135
+msgid ""
+"If you have any questions, or would like to donate a cryptocurrency not "
+"listed above, please email us at giving(a)torproject.org."
+msgstr ""
+"Se você tiver alguma pergunta ou se quiser doar uma cryptomoeda não listada "
+"acima, por favor, envie-nos um e-mail no giving(a)torproject.org."
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:29
+msgid ""
+"The European shirt fits run a little small so you might want to consider "
+"sizing up."
+msgstr ""
+"Os números do tamanho da camiseta europeia é um pouco pequeno, então você "
+"deveria considerar pedir um tamanho maior."
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:36
+msgid "Fit"
+msgstr "Tamanho"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:40
+msgid "Select Fit"
+msgstr "Selecione o seu Tamanho"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:44
+msgid "Slim"
+msgstr "Esbelto"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:48
+msgid "Classic"
+msgstr "Clássico"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:56
+msgid "European"
+msgstr "Europeu"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:66
+msgid "Size"
+msgstr "Medida"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:70
+msgid "Select Size"
+msgstr "Selecione a sua Medida"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:74
+msgid "S"
+msgstr "P"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:78
+msgid "M"
+msgstr "M"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:82
+msgid "L"
+msgstr "G"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:86
+msgid "XL"
+msgstr "GG"
+
+#: tmp/cache_locale/ce/ce708c1cd991748e8c1c29f932e6ddbd1be5be1b4cc2c5b49b607cae1df80432.php:90
+msgid "XXL"
+msgstr "GGG"
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:34
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:34
+msgid "Tor Thanks You"
+msgstr "O Tor te agradece"
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:44
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:44
+msgid "Thank you!"
+msgstr "Obrigado!"
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:51
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:51
+msgid "Thank you for supporting Tor's Strength in Numbers campaign."
+msgstr "Obrigado por apoiar a campanha Força em números do Tor."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:53
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:53
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:63
+msgid "You should receive an email receipt shortly."
+msgstr "Você deve receber um recibo por e-mail em breve."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:55
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:55
+msgid ""
+"With your support and the generous matching funds from Mozilla, we'll be "
+"able to tackle ambitious projects, such as developing a more secure, "
+"privacy-enhancing browser for mobile devices and making it easier for third-"
+"party developers to integrate Tor into their applications."
+msgstr ""
+"Com o seu apoio e os generosos fundos de contrapartida da Mozilla, poderemos"
+" enfrentar projetos ambiciosos, como o desenvolvimento de um navegador mais "
+"seguro e aprimorador de privacidade para dispositivos móveis e facilitar a "
+"integração de Tor em aplicativos de terceiros a seus aplicativos. ."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:61
+msgid "Thank you for standing up for privacy and freedom online."
+msgstr ""
+"Agradecemos por você ajudar a defender a privacidade e a liberdade na "
+"Internet."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:63
+msgid ""
+"With your gift of cryptocurrency, you're helping the Tor Project give "
+"millions of people private access to the open web."
+msgstr ""
+"Com o seu dom em criptomoedas, você está ajudando o Projeto Tor a oferecer "
+"acesso privado à rede aberta a milhões de pessoas."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:65
+msgid ""
+"Your contribution helps make Tor an even stronger tool against authoritarian"
+" governments and privacy-invading corporations."
+msgstr ""
+"A sua contribuição ajuda a fazer do Tor uma ferramenta ainda mais forte "
+"conta governos autoritários e empresas que invadem a privacidade de seus "
+"usuários. "
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:71
+msgid "For your convenience, our wallet addresses are listed below."
+msgstr ""
+"Para a sua conveniência, os endereços das nossas carteiras estão listados "
+"abaixo."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:73
+msgid ""
+"Please make sure to copy the wallet addresses exactly when making your "
+"donation, as we are unable to recover funds sent to the wrong wallet."
+msgstr ""
+"Por favor, confira a exatidão dos endereços das carteiras ao copiá-los para "
+"fazer sua doação, pois nós não podemos resgatar fundos enviados para outras "
+"carteiras."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:77
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:77
+msgid "SHARE THE TOR PROJECT"
+msgstr "COMPARTILHE O PROJETO TOR"
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:145
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:115
+msgid "Got Skills?"
+msgstr "Tem Habilidades?"
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:151
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:121
+msgid "The Tor network depends on volunteers."
+msgstr "A rede Tor depende de voluntários."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:157
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:127
+msgid ""
+"We need people to run relays, write code, organize the community and spread "
+"the word about our good work."
+msgstr ""
+"Nós precisamos de pessoas que rodem relays, escrevam código, organizem a "
+"comunidade e espalhem a mensagem sobre o nosso trabalho."
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:159
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:129
+msgid "Learn how you can help."
+msgstr " Veja de que maneira você pode ajudar. "
+
+#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:167
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:137
+msgid "I Want To Volunteer"
+msgstr "Eu quero ser um voluntário"
+
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:102
msgid ""
"This page requires Javascript to do PayPal or credit card\n"
" donations, but it appears you have Javascript disabled."
@@ -242,8 +452,7 @@ msgstr ""
"Esta página requer o Javascript para fazer doações com o PayPal ou cartão de crédito,\n"
"mas parece que você está com o JavaScript desativado."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:106
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:106
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:106
msgid ""
"If you wish to donate without enabling Javascript, please take a look at our"
" <a href=\"https://www.torproject.org/donate/donate-options.html.en\">other "
@@ -253,84 +462,67 @@ msgstr ""
"href=\"https://www.torproject.org/donate/donate-options.html.en\">na outra "
"página de opções de doações</a>."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:127
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:127
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:127
msgid "Number of Donations"
msgstr "Número de Doações"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:143
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:143
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:143
msgid "Total Donated"
msgstr "Total doado"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:159
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:159
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:159
msgid "Total Raised with Mozilla's Match"
msgstr "Total arrecadado com o jogo da Mozilla"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:170
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:176
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:170
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:176
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:170
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:176
msgid "donate"
msgstr "doe"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:172
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:172
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:172
msgid "once"
msgstr "uma vez"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:178
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:178
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:178
msgid "monthly"
msgstr "mensalmente"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:185
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:345
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:185
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:339
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:185
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:339
msgid "Want to donate Bitcoin, Stock, or via snail mail?"
msgstr "Você quer doar Bitcoin, Stocks ou através do correio tradicional? "
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:201
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:201
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:201
msgid "invalid amount"
msgstr "quantidade inválida"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:205
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:205
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:205
msgid "$2 minimum donation"
msgstr "doação mínima de $2"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:209
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:209
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:209
msgid "$ other"
msgstr "$ outro"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:216
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:216
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:216
msgid "Choose your gift as a token of our thanks."
msgstr "Escolha um presente como um símbolo da nossa gratidão."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:223
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:223
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:223
msgid "No thanks, I don't want a gift."
msgstr "Não, obrigado, não quero um presente."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:225
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:225
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:225
#, php-format
msgid "I would prefer 100% of my donation to go to the Tor Project's work."
msgstr ""
"Eu preferiria que 100% da minha doação fosse para o trabalho do Projeto Tor."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:236
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:236
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:236
msgid "sticker Pack"
msgstr "Pacote de Adesivos"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:243
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:243
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:243
msgid ""
"A collection of our favorite logo stickers for decorating your stuff and "
"covering your cams."
@@ -338,31 +530,19 @@ msgstr ""
"Temos uma coleção de nossos adesivos favoritos para decorar suas coisas e "
"cobrir suas câmeras."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:253
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:253
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:253
msgid "t-shirt"
msgstr "camiseta"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:259
-msgid "$15"
-msgstr "USD 15"
-
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:261
-msgid "OFF"
-msgstr "FORA"
-
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:267
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:261
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:261
msgid "Get our limited edition Tor: Strength in Numbers shirt."
msgstr "Receba nossa edição limitada Tor: Strength in Numbers shirt."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:278
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:272
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:272
msgid "t-shirt pack"
msgstr "pacote de camisetas"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:288
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:282
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:282
msgid ""
"Our Tor: Strength in Numbers t-shirt, plus one of either our Tor: Powering "
"the Digital Resistance, Open Observatory of Network Interference (OONI), or "
@@ -372,238 +552,193 @@ msgstr ""
"a Resistência Digital, Open Observatory of Network Interference (OONI), ou "
"camisetas do Tor no Coração da Internet Freedom."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:294
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:288
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:288
msgid "Tor at the Heart of Internet Freedom"
msgstr "Tor no coração da liberdade da Internet"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:298
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:292
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:292
msgid "Powering the Digital Resistance"
msgstr "Promovendo a Resistência Digital"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:302
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:296
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:296
msgid "Open Observatory of Network Interference"
msgstr "Observatório Aberto de Interferência de Rede"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:313
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:307
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:307
msgid "sweatshirt"
msgstr "agasalho de moletom"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:320
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:314
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:314
msgid "Your generous support of Tor gets you this high-quality zip hoodie."
msgstr ""
"A sua grande ajuda ao Tor te dá esse agasalho de capuz de alta qualidade."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:330
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:324
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:324
msgid "how do you want to <span class=\"green\">DONATE</span>?"
msgstr "Como você quer <span class=\"green\">DOAR</span>?"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:336
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:330
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:330
msgid "Credit Card"
msgstr "Cartão de Crédito"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:352
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:346
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:346
msgid "Your Info"
msgstr "Sua Informação"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:356
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:350
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:350
msgid "* required fields"
msgstr "* campos obrigatórios"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:361
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:355
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:355
msgid "First Name"
msgstr "Primeiro Nome"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:365
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:359
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:359
msgid "Last Name"
msgstr "Sobrenome"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:371
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:365
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:365
msgid "Street Address"
msgstr "Endereço da Rua"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:375
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:369
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:369
msgid "Apt."
msgstr "Apt."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:385
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:379
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:379
msgid "City"
msgstr "Cidade"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:389
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:383
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:383
msgid "State"
msgstr "Estado"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:394
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:388
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:388
msgid "Zip"
msgstr "CEP"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:400
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:394
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:394
msgid "Enter email"
msgstr "Insira seu e-mail"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:404
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:398
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:398
msgid "We‘ll email you your receipt"
msgstr "Nós‘ll lhe enviaremos o seu recibo por e-mail"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:411
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:405
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:405
msgid "Start sending me email updates about the Tor Project!"
msgstr "Comece a me enviar atualizações por email sobre o Projeto Tor!"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:418
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:412
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:412
msgid "Card Number"
msgstr "Número do cartão"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:425
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:419
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:419
msgid "MM"
msgstr "Mês"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:429
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:423
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:423
msgid "YY"
msgstr "Ano"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:433
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:427
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:427
msgid "CVC"
msgstr "Código de Segurança"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:441
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:493
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:435
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:500
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:435
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:500
msgid "Choose your size and fit."
msgstr "Escolha a sua medida e tamanho."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:446
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:454
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:440
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:448
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:440
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:448
msgid "T-shirt:"
msgstr "Camiseta:"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:464
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:468
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:470
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:458
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:462
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:464
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:458
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:462
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:464
msgid "Comments"
msgstr "Comentários"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:476
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:470
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:470
msgid "Donating:"
msgstr "Doando:"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:483
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:478
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:478
msgid "Donate"
msgstr "Doe"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:497
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:504
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:488
+msgid "Gift Selected"
+msgstr "Presente selecionado"
+
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:492
+msgid "No Gift Selected"
+msgstr "Nenhum presente selecionado"
+
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:496
+msgid "Sticker Pack"
+msgstr "Pacote de autocolantes"
+
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:504
msgid "T-Shirt"
msgstr "Camiseta"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:501
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:508
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:508
msgid "Choose your size and fit for each shirt."
msgstr "Escolha a sua medida e tamanho para cada camiseta."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:505
-msgid ""
-"Tor at the Heart of Internet, Powering Digital Resistance or Open "
-"Observvatory of Network Interference (OONI) T-Shirt"
-msgstr ""
-"Tor no coração do Internet, Powering Digital Resistance ou Camiseta Open "
-"Observvatory of Network Interference (OONI)"
-
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:509
-msgid "Strength in Numbers T-Shirt"
-msgstr "Força nos números camiseta"
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:512
+msgid "T-Shirt Pack"
+msgstr "Pacote de camiseta"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:513
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:520
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:520
msgid "Choose your size."
msgstr "Escolha a sua medida."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:517
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:524
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:524
msgid "Sweatshirt"
msgstr "Agasalho de Moletom"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:521
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:528
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:528
msgid "A required field is missing from the form."
msgstr "Um campo requerido do formulário não está preenchido."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:523
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:530
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:530
msgid "Please reload the page and try again."
msgstr "Por favor, recarregue a página e tente novamente."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:527
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:534
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:534
msgid "There was a problem submitting your request to the server:<br>"
msgstr "Houve um problema ao enviar a sua requisição para o provedor: <br>"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:531
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:538
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:538
msgid "validation failed"
msgstr "a validação falhou"
#. notes: __field_name__ will be replaced with the field name in the
#. javascript.
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:537
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:544
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:544
msgid "__field_name__ must be filled out."
msgstr "__campo_nome__ deve ser preenchido. "
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:542
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:549
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:549
msgid "This field is required"
msgstr "Este campo é requerido"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:546
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:553
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:553
msgid "Invalid email address."
msgstr "Endereço de e-mail inválido."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:550
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:557
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:557
msgid "per month"
msgstr "por mês"
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:564
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:571
-msgid "One moment while we shovel coal into our servers."
-msgstr "Aguarde um momento enquanto abastecemos nosso provedor."
-
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:654
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:662
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:661
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:669
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:649
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:657
+#: tmp/cache_locale/9f/9f870858aaf6c5a7c94ea6a959618fbe485cbfd16174993d34a8e370a4567526.php:82
+#: tmp/cache_locale/9f/9f870858aaf6c5a7c94ea6a959618fbe485cbfd16174993d34a8e370a4567526.php:90
msgid ""
"Stand up for the universal human rights to privacy and freedom and help keep"
" Tor robust and secure."
@@ -611,68 +746,16 @@ msgstr ""
"Defenda os direitos humanos universais à privacidade e liberdade e ajude a "
"manter o Tor robusto e seguro."
-#: tmp/cache_locale/93/936f5ca9f26662b60293a725343573df95cb28c99d7c3f12b1c94ed37a453012.php:656
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:663
+#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:651
+#: tmp/cache_locale/9f/9f870858aaf6c5a7c94ea6a959618fbe485cbfd16174993d34a8e370a4567526.php:84
msgid "Mozilla will match your gift and double your impact."
msgstr "A Mozilla combinará seu presente e dobrará seu impacto."
-#: tmp/cache_locale/6f/6f67db0a5268c67c9254c73517aaaea60c8c65a268f9242703a3299173f14b74.php:22
-msgid "See if your employer offers employee gift matching"
-msgstr ""
-"Veja se o seu empregador oferece um programa de doação em dobro para os seus"
-" funcionários"
-
-#: tmp/cache_locale/6f/6f67db0a5268c67c9254c73517aaaea60c8c65a268f9242703a3299173f14b74.php:52
-msgid "Company"
-msgstr "Empresa"
-
-#: tmp/cache_locale/6f/6f67db0a5268c67c9254c73517aaaea60c8c65a268f9242703a3299173f14b74.php:60
-msgid "Matching Conditions"
-msgstr "Condições do Programa de Doação em Dobro"
-
-#: tmp/cache_locale/6f/6f67db0a5268c67c9254c73517aaaea60c8c65a268f9242703a3299173f14b74.php:68
-msgid "Contact Information"
-msgstr "Informação de Contato"
-
-#: tmp/cache_locale/6f/6f67db0a5268c67c9254c73517aaaea60c8c65a268f9242703a3299173f14b74.php:76
-msgid "Additional Notes"
-msgstr "Explicações Adicionais"
-
-#: tmp/cache_locale/6f/6f67db0a5268c67c9254c73517aaaea60c8c65a268f9242703a3299173f14b74.php:84
-msgid "Procedure"
-msgstr "Procedimento"
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:34
-msgid "Tor Thanks You"
-msgstr "O Tor te agradece"
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:44
-msgid "Thank you!"
-msgstr "Obrigado!"
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:51
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:61
-msgid "Thank you for supporting Tor's Strength in Numbers campaign."
-msgstr "Obrigado por apoiar a campanha Força em números do Tor."
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:53
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:63
-msgid "You should receive an email receipt shortly."
-msgstr "Você deve receber um recibo por e-mail em breve."
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:55
-msgid ""
-"With your support and the generous matching funds from Mozilla, we'll be "
-"able to tackle ambitious projects, such as developing a more secure, "
-"privacy-enhancing browser for mobile devices and making it easier for third-"
-"party developers to integrate Tor into their applications."
-msgstr ""
-"Com o seu apoio e os generosos fundos de contrapartida da Mozilla, poderemos"
-" enfrentar projetos ambiciosos, como o desenvolvimento de um navegador mais "
-"seguro e aprimorador de privacidade para dispositivos móveis e facilitar a "
-"integração de Tor em aplicativos de terceiros a seus aplicativos. ."
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:61
+msgid "Thank you for your support of the Tor Project."
+msgstr "Agradecemos a você pelo seu apoio ao Projeto Tor."
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:65
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:65
msgid ""
"With your support, we'll be able to tackle ambitious projects, such as "
"developing a more secure, privacy-enhancing browser for mobile devices and "
@@ -684,7 +767,7 @@ msgstr ""
"de dispositivos móveis, e facilitar a integração do Tor em seus aplicativos "
"por terceiros."
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:71
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:71
msgid ""
"It's an incredible time to stand up for world-leading security and privacy "
"software."
@@ -692,7 +775,7 @@ msgstr ""
"É um momento incrível para se posicionar em favor do software líder mundial "
"em segurança e privacidade."
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:73
+#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:73
msgid ""
"Tell family, friends, and colleagues that you're supporting privacy and "
"security with Tor!"
@@ -700,35 +783,15 @@ msgstr ""
" Fale para sua família, amigos e colegas que você está apoiando a "
"privacidade e a segurança com o Tor! "
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:77
-msgid "SHARE THE TOR PROJECT"
-msgstr "COMPARTILHE O PROJETO TOR"
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:115
-msgid "Got Skills?"
-msgstr "Tem Habilidades?"
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:121
-msgid "The Tor network depends on volunteers."
-msgstr "A rede Tor depende de voluntários."
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:127
-msgid ""
-"We need people to run relays, write code, organize the community and spread "
-"the word about our good work."
-msgstr ""
-"Nós precisamos de pessoas que rodem relays, escrevam código, organizem a "
-"comunidade e espalhem a mensagem sobre o nosso trabalho."
-
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:129
-msgid "Learn how you can help."
-msgstr " Veja de que maneira você pode ajudar. "
+#: tmp/cache_locale/92/9248b30ecfc0bb3509fc7e1db98f98ec86e72399ad551da3d5abe54c7cd987af.php:34
+msgid "Processing Donation - Tor"
+msgstr "Processando a sua Doação - Tor"
-#: tmp/cache_locale/54/5420828d7720daccac45a05e74a0bdde5ef138020bd4901a7e81ad8817d3f8e8.php:137
-msgid "I Want To Volunteer"
-msgstr "Eu quero ser um voluntário"
+#: tmp/cache_locale/92/9248b30ecfc0bb3509fc7e1db98f98ec86e72399ad551da3d5abe54c7cd987af.php:44
+msgid "Processing Donation. Please Wait..."
+msgstr "Processando a sua Doação - Por Favor Aguarde..."
-#: tmp/cache_locale/50/50777d283fdd4725b4b51b066a1fa065079d875050e04874af7ad8d37f823d3f.php:25
+#: tmp/cache_locale/2d/2d5f07aeb16acd7bb0a8dd355b13f59678a1f0ba6ea2b3d9dec8d2b5dcfbfde5.php:25
msgid ""
"The Tor Project is a US 501(c)(3) non-profit organization advancing human "
"rights and freedoms by creating and deploying free and open source anonymity"
@@ -740,27 +803,27 @@ msgstr ""
"código aberto de privacidade e anonimato, apoiando sua disponibilidade e uso"
" irrestritos e promovendo o seu entendimento científico e popular."
-#: tmp/cache_locale/50/50777d283fdd4725b4b51b066a1fa065079d875050e04874af7ad8d37f823d3f.php:31
+#: tmp/cache_locale/2d/2d5f07aeb16acd7bb0a8dd355b13f59678a1f0ba6ea2b3d9dec8d2b5dcfbfde5.php:31
msgid "Subscribe to Our Newsletter"
msgstr "Inscreva-se em nossa lista de e-mails"
-#: tmp/cache_locale/50/50777d283fdd4725b4b51b066a1fa065079d875050e04874af7ad8d37f823d3f.php:35
+#: tmp/cache_locale/2d/2d5f07aeb16acd7bb0a8dd355b13f59678a1f0ba6ea2b3d9dec8d2b5dcfbfde5.php:35
msgid "Get monthly updates and opportunities from the Tor Project."
msgstr "Receba atualizações mensais e avisos de oportunidades do Projeto Tor"
-#: tmp/cache_locale/50/50777d283fdd4725b4b51b066a1fa065079d875050e04874af7ad8d37f823d3f.php:39
+#: tmp/cache_locale/2d/2d5f07aeb16acd7bb0a8dd355b13f59678a1f0ba6ea2b3d9dec8d2b5dcfbfde5.php:39
msgid "Sign Up"
msgstr "Cadastrar-se"
-#: tmp/cache_locale/50/50777d283fdd4725b4b51b066a1fa065079d875050e04874af7ad8d37f823d3f.php:47
+#: tmp/cache_locale/2d/2d5f07aeb16acd7bb0a8dd355b13f59678a1f0ba6ea2b3d9dec8d2b5dcfbfde5.php:47
msgid "Donate FAQs"
msgstr "FAQs de Doação"
-#: tmp/cache_locale/50/50777d283fdd4725b4b51b066a1fa065079d875050e04874af7ad8d37f823d3f.php:51
+#: tmp/cache_locale/2d/2d5f07aeb16acd7bb0a8dd355b13f59678a1f0ba6ea2b3d9dec8d2b5dcfbfde5.php:51
msgid "Privacy Policy"
msgstr "Política de Privacidade"
-#: tmp/cache_locale/50/50777d283fdd4725b4b51b066a1fa065079d875050e04874af7ad8d37f823d3f.php:67
+#: tmp/cache_locale/2d/2d5f07aeb16acd7bb0a8dd355b13f59678a1f0ba6ea2b3d9dec8d2b5dcfbfde5.php:67
msgid ""
"Designed and built by <span class=\"stamp-bold\"><a "
"href=\"https://www.giantrabbit.com/\" class=\"stamp-bold\" "
@@ -770,15 +833,15 @@ msgstr ""
"href=\"https://www.giantrabbit.com/\" class=\"stamp-bold\" "
"target=\"_blank\">Um Coelho Gigante</a></span>"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:34
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:34
msgid "Tor Donor FAQ"
msgstr "FAQ do Doador Tor "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:44
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:44
msgid "Questions?"
msgstr "Perguntas?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:59
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:59
msgid ""
"If your question isn’t answered below, email <span "
"class=\"email\">frontdesk(at)rt.torproject.org</span> with general Tor "
@@ -791,11 +854,11 @@ msgstr ""
"class=\"email\">giving(at)torproject.org</span>com perguntas específicas "
"sobre doações. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:66
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:66
msgid "What is the Tor Project and what does it do?"
msgstr "O que é o Projeto Tor e o que ele faz?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:70
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:70
msgid ""
"The Tor Project’s mission is to advance human rights and freedoms by "
"creating and deploying free and open anonymity and privacy technologies, "
@@ -807,7 +870,7 @@ msgstr ""
"anonimato e privacidade, apoiando o seu uso e disponibilidade irrestrita, "
"promovendo a sua compreensão científica e popular. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:72
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:72
msgid ""
"The main product of the Tor Project is <a "
"href=\"https://www.torproject.org/download/download-easy.html.en\">Tor "
@@ -817,7 +880,7 @@ msgstr ""
"href=\"https://www.torproject.org/download/download-easy.html.en\">Navegador"
" Tor</a>, que permite que as pessoas naveguem pela internet anonimamente. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:74
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:74
msgid ""
"The Tor Project is a 501(c)3 tax-exempt non-profit organization based in "
"Boston, Massachusetts."
@@ -825,15 +888,15 @@ msgstr ""
"O Projeto Tor é uma organização sem fins lucrativos do tipo 501(c)3, isenta "
"de impostos, baseada em Boston, Massachusetts. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:76
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:76
msgid "It was founded in 2006."
msgstr "Foi fundado em 2006."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:82
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:82
msgid "Who works for the Tor Project, and what do they do?"
msgstr "Quem trabalha para o Projeto Tor e o que eles fazem?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:86
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:86
msgid ""
"Thousands of people around the world actively support the work of the Tor "
"Project, including developers, designers, relay operators, researchers, "
@@ -845,14 +908,14 @@ msgstr ""
"relays, pesquisadores, criptógrafos, cientistas da computação, defensores da"
" privacidade, e a maioria deles não são pagos pelo Projeto Tor. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:88
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:88
msgid ""
"The paid staff of the Tor Project is very small: about 47 people in total."
msgstr ""
"A equipe remunerada do Projeto Tor é muito pequena: cerca de 47 pessoas no "
"total."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:90
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:90
msgid ""
"You can read about the core contributors to the Tor Project on our <a "
"class=\"hyperlinks\" target=\"_blank\" "
@@ -864,11 +927,11 @@ msgstr ""
"href=\"https://www.torproject.org/about/corepeople.html.en\"><span "
"class=\"links\">página de Contribuidores Centrais</span></a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:95
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:95
msgid "Who uses Tor?"
msgstr "Quem usa Tor?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:99
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:99
msgid ""
"The vast majority of Tor users are ordinary people who want control of their"
" privacy online or people whose internet use is censored."
@@ -877,7 +940,7 @@ msgstr ""
"controle de sua privacidade online ou pessoas que tem o acesso a internet "
"censurada. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:101
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:101
msgid ""
"Other Tor users are journalists, human rights defenders, domestic violence "
"survivors, policymakers, diplomats, and academic and research institutions."
@@ -886,15 +949,15 @@ msgstr ""
"sobreviventes de violência doméstica, desenvolvedores de leis, diplomatas, e"
" instituições acadêmicas de pesquisa. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:107
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:107
msgid "Can anyone use Tor?"
msgstr "Será que qualquer um pode usar o Tor?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:111
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:111
msgid "Yes! Tor is free, and anyone can use it."
msgstr "Sim! O Tor é gratuito, e qualquer pessoa pode utilizá-lo. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:113
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:113
msgid ""
"To get started, you will need to <a class=\"hyperlinks\" target=\"_blank\" "
"href=\"https://www.torproject.org/projects/torbrowser.html.en\"><span "
@@ -904,7 +967,7 @@ msgstr ""
"href=\"https://www.torproject.org/projects/torbrowser.html.en\"><span "
"class=\"links\">baixar o Navegador Tor</span></a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:115
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:115
msgid ""
"We offer instructions on how to download for <a class=\"hyperlinks links\" "
"target=\"_blank\" "
@@ -922,15 +985,15 @@ msgstr ""
"OS X</a> e <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.torproject.org/projects/torbrowser.html.en#linux\">Linux</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:121
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:121
msgid "What kinds of people support Tor?"
msgstr "Que tipo de pessoa apoia o Tor?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:125
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:125
msgid "All kinds of people."
msgstr "Todo tipo de pessoa."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:127
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:127
msgid ""
"Thousands of individuals have donated to support the Tor Project, and we "
"have also received funding from a wide range of organizations including "
@@ -948,7 +1011,7 @@ msgstr ""
"Germany, o U.S. Naval Research Laboratory, Omidyar Network, SRI "
"International, a Radio Free Asia."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:129
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:129
msgid ""
"People also support Tor in non-financial ways, for example by running Tor "
"relays to help carry traffic for other users."
@@ -957,7 +1020,7 @@ msgstr ""
"exemplo, rodando transmissores do Tor para ajudar a transportar o tráfego de"
" outros usuários. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:131
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:131
msgid ""
"In addition, everybody who uses Tor is helping to keep other users safe and "
"anonymous, because the more people using Tor, the harder it is to identify "
@@ -967,13 +1030,13 @@ msgstr ""
"usuários seguros e anônimos, porque quanto mais pessoas usam o Tor, mais "
"difícil é para identificar qualquer usuário individual. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:137
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:137
msgid "How does the Tor software work to protect people's anonymity?"
msgstr ""
"De que forma o software do Tor funciona para proteger o anonimato das "
"pessoas?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:141
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:141
msgid ""
"Tor protects you by bouncing your communications around the Tor network, "
"which is a distributed network of relays run by volunteers all around the "
@@ -982,7 +1045,7 @@ msgstr ""
"O Tor protege você, enviando suas comunicações pela rede Tor, que é uma rede"
" distribuída de retransmissões comandada por voluntários em todo o mundo."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:143
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:143
msgid ""
"If someone is watching your internet connection, Tor prevents them from "
"finding out what sites you are visiting."
@@ -990,14 +1053,14 @@ msgstr ""
"Se alguém estiver observando sua conexão com a internet, o Tor irá impedir "
"que eles descubram quais sites que você está visitando. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:145
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:145
msgid ""
"It also prevents sites you visit from finding out where you're located."
msgstr ""
"E também impede que os sites que você visita descubram onde você está "
"localizado."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:147
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:147
msgid ""
"You can read more about how Tor works on our <a class=\"hyperlinks links\" "
"target=\"_blank\" "
@@ -1008,7 +1071,7 @@ msgstr ""
"href=\"https://www.torproject.org/about/overview.html.en\">página de visão "
"geral."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:154
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:154
msgid ""
"I would like to know more about how Tor works, what onion services are, or "
"how to run a relay."
@@ -1016,7 +1079,7 @@ msgstr ""
"Eu gostaria de saber mais sobre como o Tor funciona, o que são serviços de "
"Onion ou como executar um retransmissor."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:158
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:158
msgid ""
"<a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.torproject.org/docs/faq.html.en\">This Tor Project "
@@ -1026,11 +1089,11 @@ msgstr ""
"href=\"https://www.torproject.org/docs/faq.html.en\">Esse FAQ do Projeto "
"Tor</a>tem respostas para todas essas perguntas e mais. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:164
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:164
msgid "Does the Tor software work?"
msgstr "A software do Tor funciona?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:168
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:168
msgid ""
"We believe Tor is the best solution available today, and we know that it "
"does a better job of keeping you safely anonymous than other options such as"
@@ -1041,7 +1104,7 @@ msgstr ""
"relação a outras opções, tais como VPNs, proxychains ou modos de \"navegação"
" privada\" de navegadores."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:170
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:170
msgid ""
"We know that both the Russian government and the NSA have tried in the past "
"to crack Tor, and failed."
@@ -1049,7 +1112,7 @@ msgstr ""
"Nós sabemos que tanto o governo Russo quanto a NSA tentaram no passado achar"
" uma brecha no Tor e falharam. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:172
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:172
msgid ""
"The Electronic Frontier Foundation says that Tor offers <a "
"class=\"hyperlinks links\" target=\"_blank\" "
@@ -1066,12 +1129,12 @@ msgstr ""
"\"A melhor ferramenta atual para proteger o seu anonimato ao navegar na web "
"é o Tor\". "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:178
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:178
msgid "Is what Tor does legal? Can I get in trouble for using it?"
msgstr ""
"O que o Tor faz está dentro da lei? Será que eu vou ter problemas em usá-lo?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:182
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:182
msgid ""
"Downloading Tor Browser or using the Tor network is legal in nearly every "
"country."
@@ -1079,7 +1142,7 @@ msgstr ""
"Fazer o download do Navegador Tor ou usar a rede Tor é legal em quase todos "
"os países. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:184
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:184
msgid ""
"A few web sites occasionally block Tor, but that doesn't mean you're doing "
"anything wrong."
@@ -1087,7 +1150,7 @@ msgstr ""
"Alguns web sites ocasionalmente bloqueiam o Tor, mas isso não significa que "
"você está fazendo algo de errado. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:186
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:186
msgid ""
"Usually it means that site has had difficulties with visitors who've been "
"using Tor in the past, or that they misunderstand what Tor is and how it "
@@ -1097,14 +1160,14 @@ msgstr ""
"que estivam usando o Tor, ou que não compreenderam como o Tor funciona (mas "
"nós estamos trabalhando para mudar isso)."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:188
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:188
msgid ""
"But it is not illegal to use Tor, and you shouldn't get in trouble for doing"
" it."
msgstr ""
"Mas não é ilegal usar o Tor e você não deveria ter problemas por usá-lo. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:190
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:190
msgid ""
"You can find more information about Tor's legal status on the <a "
"class=\"hyperlinks links\" target=\"_blank\" "
@@ -1114,7 +1177,7 @@ msgstr ""
"class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.eff.org/torchallenge/faq.html\">site da EFF</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:196
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:196
msgid ""
"Where can I find out more about the Tor Project, especially financial "
"information?"
@@ -1122,7 +1185,7 @@ msgstr ""
"Onde eu posso saber mais sobre o Projeto Tor, especialmente informações "
"financeiras?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:200
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:200
msgid ""
"Here are the Tor Project's <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.torproject.org/about/financials.html.en\">financial "
@@ -1132,11 +1195,11 @@ msgstr ""
"href=\"https://www.torproject.org/about/financials.html.en\">declarações "
"financeiras e o Formulário 990</a>do Projeto Tor. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:206
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:206
msgid "Where does the Tor Project's money come from?"
msgstr "De onde vem o dinheiro do Projeto Tor?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:210
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:210
msgid ""
"Tor is supported by United States government funding agencies, NGOs, private"
" foundations, research institutions, private companies, and over 20,000 "
@@ -1146,7 +1209,7 @@ msgstr ""
" ONGs, fundações privadas, instituições de pesquisa, empresas privadas, e "
"quase 20,000 doações pessoais de pessoas como você. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:212
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:212
msgid ""
"(See <a class=\"hyperlinks links single-link\" target=\"_blank\" "
"href=\"https://www.torproject.org/about/sponsors.html.en\">https://www.torproject.org/about/sponsors</a>"
@@ -1156,7 +1219,7 @@ msgstr ""
"href=\"https://www.torproject.org/about/sponsors.html.en\">https://www.torproject.org/about/sponsors</a>"
" para mais informações.)"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:214
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:214
msgid ""
"While we are grateful for this funding, we don't want the Tor Project to "
"become too dependent on any single source."
@@ -1164,7 +1227,7 @@ msgstr ""
"Ainda que sejamos gratos por essas doações, não queremos que o Projeto Tor "
"se torne dependente demais de nenhuma fonte específica. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:216
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:216
msgid ""
"Crowdfunding allows us to diversify our donor base and is unrestricted -- it"
" allows us to spend the money on the projects we think are most important "
@@ -1174,7 +1237,7 @@ msgstr ""
"irrestritos - nos permitem gastar o dinheiro nos projetos que pensamos ser "
"mais importantes e ter uma resposta rápida às mudanças de contexto. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:218
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:218
msgid ""
"And so, we are asking you to help financially support us, to increase the "
"Tor Project's independence and ensure the sustainability of the products and"
@@ -1184,16 +1247,16 @@ msgstr ""
"ampliar a independência do Projeto Tor e garantir a sustentabilidade dos "
"produtos e serviços que nós fornecemos. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:224
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:224
msgid ""
"How much money does the Tor Project spend annually, and what is it used for?"
msgstr "Quanto dinheiro o Projeto Tor gasta anualmente e para que é usado?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:228
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:228
msgid "The Tor Project spends about $4 million annually."
msgstr "O Projeto Tor gasta cerca de $4 milhões de dólares anualmente. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:230
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:230
#, php-format
msgid ""
"About 80% of the Tor Project's spending goes to staffing, mostly software "
@@ -1202,7 +1265,7 @@ msgstr ""
"Cerca de 80% das despesas do Projeto Tor são gastos com equipe, "
"principalmente engenheiros de software. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:232
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:232
msgid ""
"About 10% goes towards administrative costs such as accounting and legal "
"costs and bank fees."
@@ -1210,7 +1273,7 @@ msgstr ""
"Cerca de 10% vão para custos administrativos tais como custos legais e com "
"contabilidade e taxas bancárias. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:234
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:234
msgid ""
"The remaining 10% is spent on travel, meetings and conferences, which are "
"important for Tor because the Tor community is global."
@@ -1218,11 +1281,11 @@ msgstr ""
"Os 10% restantes são gastos em viagens, reuniões e conferências, que são "
"importantes para o Tor já que a comunidade Tor é global. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:240
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:240
msgid "Is my donation tax-deductible?"
msgstr "A minha doação é dedutível de impostos?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:244
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:244
msgid ""
"If you pay taxes in the United States, your donation to Tor is tax "
"deductible to the full extent required by law."
@@ -1230,11 +1293,11 @@ msgstr ""
"Se você paga impostos nos Estados Unidos, sua doação para o Tor é dedutível "
"em toda a extensão requerida pela lei. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:246
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:246
msgid "Following is information you may need for reporting purposes:"
msgstr "A seguir estão as informações que você pode precisar para declarar:"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:251
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:251
msgid ""
"<b>Tor Project Tax ID Number (EIN #):</b> 20-8096820<br>\n"
" <b>Address:</b><br>\n"
@@ -1252,15 +1315,15 @@ msgstr ""
" <b>Telefone:</b> 206-420-3136<br>\n"
" <b>Pessoa de contato:</b> Isabela Bagueros, diretora executiva<br>"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:264
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:264
msgid "If I am not in the United States, can I still donate?"
msgstr "Se eu não estiver nos Estados Unidos, ainda assim posso doar?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:268
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:268
msgid "Yes, definitely."
msgstr "Sim, definitivamente. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:270
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:270
msgid ""
"Your donation probably isn't tax-deductible (unless you pay taxes on U.S. "
"income) but we would very much appreciate your support."
@@ -1269,7 +1332,7 @@ msgstr ""
" pague impostos sobre renda nos EUA), mas mesmo assim, gostaríamos muito do "
"seu apoio."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:276
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:276
msgid ""
"Can I donate to a specific project, or restrict my donation to a particular "
"purpose?"
@@ -1277,12 +1340,12 @@ msgstr ""
"Posso doar para um projeto específico, ou restringir minha doação para uma "
"finalidade particular?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:280
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:560
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:280
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:560
msgid "No, sorry."
msgstr "Não, desculpe."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:282
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:282
msgid ""
"If we accept a donation from someone who has specified how they want it "
"used, we're required by the IRS to track and report separately on that "
@@ -1292,7 +1355,7 @@ msgstr ""
"seja usada, nos é exigido pela IRS rastrear e declarar separadamente esse "
"dinheiro. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:284
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:284
msgid ""
"That would be a big administrative burden for a small organization, and we "
"don't think it's a good idea for us."
@@ -1300,7 +1363,7 @@ msgstr ""
"Esse seria um grande fardo para uma organização pequena, e nós não "
"acreditamos que seja uma boa ideia para nós. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:286
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:286
msgid ""
"However, we would be very happy to hear your ideas and feedback about our "
"work."
@@ -1308,7 +1371,7 @@ msgstr ""
"Entretanto, nós ficaríamos muito felizes em ouvir suas ideias e avaliações "
"sobre nosso trabalho. "
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:288
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:288
msgid ""
"If you're donating using a mechanism that allows for comments, feel free to "
"send your thoughts that way."
@@ -1316,15 +1379,15 @@ msgstr ""
"Se você estiver doando usando um mecanismo que permite comentários, sinta-se"
" à vontade para enviar suas ideias dessa maneira."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:294
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:294
msgid "Can I donate while using Tor Browser?"
msgstr "Será que posso doar quando estiver usando o Navegador Tor?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:298
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:298
msgid "Yes! In our testing, donation works via Tor Browser."
msgstr "Sim! Em nossos testes, a doação funciona através do navegador Tor."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:300
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:300
msgid ""
"If you run into problems, please contact <span "
"class=\"email\">giving(at)torproject.org</span>."
@@ -1332,7 +1395,7 @@ msgstr ""
"Se você encontrar problemas, entre em contato com o nosso setor de doação "
"pelo e-mail <span class=\"email\">giving(at)torproject.org</span>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:304
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:304
msgid ""
"For users logging in to Paypal: some people had no problem donating via "
"PayPal while using Tor Browser."
@@ -1340,7 +1403,7 @@ msgstr ""
"Para os usuários que doaram através do Paypal: algumas pessoas não tiveram "
"problemas para doar via PayPal enquanto usavam o Navegador Tor."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:306
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:306
msgid ""
"In past years, some people couldn't complete the donation process, and one "
"person had their PayPal account temporarily frozen."
@@ -1348,16 +1411,16 @@ msgstr ""
"Nos últimos anos, algumas pessoas não conseguiram concluir o processo de "
"doação e uma pessoa teve a sua conta do PayPal temporariamente congelada."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:308
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:308
msgid "If you run into any problems donating via PayPal, please let us know."
msgstr ""
"Se você tiver algum problema ao doar via PayPal, por favor, nos avise."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:314
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:314
msgid "How can I donate via debit or credit card?"
msgstr "Como posso doar via cartão de débito ou crédito?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:318
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:318
msgid ""
"To donate using a major credit card or debit card (VISA, MasterCard, "
"Discover or American Express) or via PayPal, please visit our <a "
@@ -1367,13 +1430,13 @@ msgstr ""
"ou American Express) ou via PayPal, por favor, visite a nossa<a "
"href=\"https://donate.torproject.org\">página de doações</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:324
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:324
msgid "Why do you ask for my address and similar information?"
msgstr ""
"Por que você está perguntando pelo meu endereço e outras informações "
"semelhantes?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:328
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:328
msgid ""
"If you donate by credit card, you will be asked for some information that's "
"required to process your credit card payment, including your billing "
@@ -1383,7 +1446,7 @@ msgstr ""
"necessárias para processar o pagamento por cartão de crédito, incluindo o "
"seu endereço de faturamento."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:330
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:330
msgid ""
"This allows our payment processor to verify your identity, process your "
"payment, and prevent fraudulent charges to your credit card."
@@ -1392,7 +1455,7 @@ msgstr ""
"identidade, processe o seu pagamento e evite cobranças fraudulentas em seu "
"cartão de crédito."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:332
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:332
msgid ""
"We don't ask for information beyond what's required by the payment "
"processor."
@@ -1400,11 +1463,11 @@ msgstr ""
"Nós não pedimos informações além do que é exigido pelo processador de "
"pagamento."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:338
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:338
msgid "Why is there a minimum donation?"
msgstr "Por que existe uma doação mínima?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:342
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:342
msgid ""
"People who have stolen credit card information often donate to nonprofits as"
" a way of testing whether the card works."
@@ -1413,7 +1476,7 @@ msgstr ""
"valor irrisório para organizações sem fins lucrativos como forma de testar "
"se o cartão funciona."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:344
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:344
msgid ""
"These people typically use a very small amount for their testing, and we've "
"found that setting a $1 minimum donation seems to deter them."
@@ -1422,11 +1485,11 @@ msgstr ""
"assim, descobrimos que definir uma doação mínima de US $1 parece dissuadi-"
"las."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:350
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:350
msgid "Is there a maximum donation?"
msgstr "Existe uma doação máxima?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:354
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:354
msgid ""
"No, no, no! More funding from you means we can do more things we are excited"
" to do, like hire a person to monitor the Tor network full time, or "
@@ -1439,11 +1502,11 @@ msgstr ""
"pesquisar, testar e implementar as ideias que temos, para tornar a rede Tor "
"ainda mais forte."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:360
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:360
msgid "Can I donate via bitcoin?"
msgstr "Posso doar via bitcoin?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:364
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:364
msgid ""
"Yes! We accept <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.torproject.org/donate/donate-options.html.en\">bitcoin "
@@ -1453,7 +1516,7 @@ msgstr ""
"href=\"https://www.torproject.org/donate/donate-options.html.en\">bitcoin "
"via BitPay</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:370
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:370
msgid ""
"If I want my donation to be anonymous, what is the best way for me to "
"donate?"
@@ -1461,7 +1524,7 @@ msgstr ""
"Se eu quiser que a minha doação seja anônima, qual é a melhor maneira de "
"doar?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:374
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:374
msgid ""
"You can donate by <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.torproject.org/donate/donate-"
@@ -1471,7 +1534,7 @@ msgstr ""
"href=\"https://www.torproject.org/donate/donate-options.html.en#cash"
"\">enviando-nos um vale postal.</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:376
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:376
msgid ""
"You can donate via bitcoin if you have bitcoin set up in a way that "
"preserves your anonymity."
@@ -1479,11 +1542,11 @@ msgstr ""
"Você pode doar via bitcoin se tiver bitcoin configurado de uma maneira que "
"preserve o seu anonimato."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:378
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:378
msgid "You can buy cash gift cards and mail them to us."
msgstr "Você pode comprar vales-presente em dinheiro e enviá-los para nós."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:380
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:380
msgid ""
"There are probably other ways to donate anonymously that we haven't thought "
"of-- maybe you will :)"
@@ -1491,7 +1554,7 @@ msgstr ""
"Provavelmente existem outras maneiras de doar anonimamente na qual não "
"sabemos - mas talvez você saiba como :)"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:387
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:387
msgid ""
"Is the Tor Project required to identify me as a donor to the United States "
"government, or to any other authority?"
@@ -1499,7 +1562,7 @@ msgstr ""
"É necessário que o Projeto Tor me identifique como um doador para o governo "
"dos Estados Unidos ou para qualquer outra autoridade?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:391
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:391
msgid ""
"If you donate $5,000 or more to the Tor Project in a single year, we are "
"required to report the donation amount and your name and address (if we have"
@@ -1510,7 +1573,7 @@ msgstr ""
"precisarmos) ao IRS, no Anexo B do Formulário 990, que é preenchido "
"anualmente."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:393
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:393
msgid ""
"However, it's normal for nonprofits to redact individual donor information "
"from the copy of the 990 that's made publicly-available, and that's what we "
@@ -1520,7 +1583,7 @@ msgstr ""
"informações de doadores individuais na cópia 990, o que é disponibilizada "
"publicamente, e é isso que fazemos."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:395
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:395
msgid ""
"We are not required to identify donors to any other organization or "
"authority, and we do not."
@@ -1528,7 +1591,7 @@ msgstr ""
"Nós não somos obrigados a identificar os doadores para qualquer outra "
"organização ou autoridade, e nós não fazemos isto."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:397
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:397
msgid ""
"(Also, if you wanted, you could give us $4,999 in late 2018 and $4,999 in "
"early 2019.)"
@@ -1536,7 +1599,7 @@ msgstr ""
"(No entanto, se você quiser, você poderá nos dar US $4.999 no final de 2018 "
"e US $4.999 no início de 2019;)"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:403
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:403
msgid ""
"In your privacy policy, you say you will never publicly identify me as a "
"donor without my permission."
@@ -1544,15 +1607,15 @@ msgstr ""
"Nas suas regras de privacidade, você diz que nunca me identificará "
"publicamente como um doador sem minha permissão."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:405
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:405
msgid "What does that mean?"
msgstr "O que isso significa?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:409
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:409
msgid "Yes, that's right."
msgstr "Sim, você está certo."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:411
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:411
msgid ""
"If you donate to the Tor Project, there will be some people at the Tor "
"Project who know about your donation."
@@ -1560,7 +1623,7 @@ msgstr ""
"Se você doar para o Projeto Tor, haverá algumas pessoas do Projeto Tor que "
"irão saber sobre a sua doação."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:413
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:413
msgid ""
"However, we will never publicly identify you as a donor, unless you have "
"given us permission to do so."
@@ -1568,7 +1631,7 @@ msgstr ""
"No entanto, nunca iremos identificá-lo publicamente como um doador, ao menos"
" que você tenha nos dado a permissão para fazê-lo."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:415
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:415
msgid ""
"That means we won't post your name on our website, thank you on Twitter, or "
"do anything else that would publicly identify you as someone who has "
@@ -1578,7 +1641,7 @@ msgstr ""
"agradece-lo no Twitter ou fazer qualquer outra coisa que o identifique "
"publicamente como alguém que doou."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:417
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:417
msgid ""
"If we decide we would like to publicly name you as a donor, we will ask you "
"first, and will not do it until and unless you say it's okay."
@@ -1587,7 +1650,7 @@ msgstr ""
"perguntaremos a você primeiro e não faremos isso até que você diga que está "
"tudo bem."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:423
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:423
msgid ""
"It's important to me that my donation be tax-deductible, but I don't pay "
"taxes in the United States."
@@ -1595,7 +1658,7 @@ msgstr ""
"É importante para mim que minha doação seja dedutível de impostos, porém eu "
"não pago impostos nos Estados Unidos."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:427
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:427
msgid ""
"Right now, we can only offer tax-deductibility to donors who pay taxes in "
"the United States."
@@ -1603,7 +1666,7 @@ msgstr ""
"No momento, só podemos oferecer dedução de impostos a doadores que pagam "
"impostos nos Estados Unidos."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:429
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:429
msgid ""
"If it's important to you that your donations be tax-deductible in a "
"different country, let us know and we will try to offer tax-deductibility in"
@@ -1613,7 +1676,7 @@ msgstr ""
" em um país diferente, avise-nos e nós tentaremos oferecer deduções de "
"impostos em seu país no futuro."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:431
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:431
msgid ""
"Or, if you are in Germany, France or Sweden, <a class=\"hyperlinks links\" "
"target=\"_blank\" "
@@ -1627,7 +1690,7 @@ msgstr ""
"organizações suportam a rede Tor</a> e podem oferecer dedutibilidade fiscal "
"para sua doação."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:437
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:437
msgid ""
"What if I don't want to use credit card or PayPal? Is there another way I "
"can donate?"
@@ -1635,7 +1698,7 @@ msgstr ""
"E se eu não quiser usar o cartão de crédito ou o PayPal? Existe outra "
"maneira de doar?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:441
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:441
msgid ""
"Yes! Here is a list of <a href=\"https://www.torproject.org/donate/donate-"
"options.html.en\" class=\"hyperlinks links\" target=\"_blank\">other ways "
@@ -1645,11 +1708,11 @@ msgstr ""
"options.html.en\" class=\"hyperlinks links\" target=\"_blank\">e outras "
"maneiras de doar </a>"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:448
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:448
msgid "What is your donor privacy policy?"
msgstr "Qual é a suas regras de privacidade do doador?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:452
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:452
msgid ""
"Here is the Tor Project <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"/%langcode%/privacy-policy\">donor privacy policy</a>."
@@ -1658,11 +1721,11 @@ msgstr ""
"target=\"_blank\" href=\"/%langcode%/privacy-policy\">de privacidade dos "
"doadores</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:458
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:458
msgid "What is your refund policy?"
msgstr "Quais são as suas regras de reembolso?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:462
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:462
msgid ""
"If you want your donation refunded, please tell us by emailing <span "
"class=\"email\">giving(at)torproject.org</span>."
@@ -1670,7 +1733,7 @@ msgstr ""
"Se você quiser que a sua doação seja reembolsada, por favor nos avise por "
"e-mail <span class=\"email\">giving(at)torproject.org</span>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:464
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:464
msgid ""
"To process your refund we'll need to know the date of your donation, the "
"amount you donated, your full name, the payment method you used and your "
@@ -1680,11 +1743,11 @@ msgstr ""
"valor que você doou, o nome completo, o método de pagamento usado e o país "
"de origem."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:466
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:466
msgid "Please also tell us why you're asking for a refund."
msgstr "Por favor, diga-nos por que você está pedindo um reembolso."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:468
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:468
msgid ""
"Please note that some payment methods won't support refunds, or require them"
" to be made in a specific way, so we may need additional information from "
@@ -1694,16 +1757,16 @@ msgstr ""
"que sejam feitos de uma forma específica, pelo que poderemos necessitar de "
"mais informações para processar o seu."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:474
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:474
msgid "Can I donate by mail?"
msgstr "Posso doar pelo correio?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:478
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:584
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:478
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:584
msgid "Yes."
msgstr "Sim."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:480
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:480
msgid ""
"Our mailing address is The Tor Project, 217 First Avenue South #4903, "
"Seattle WA 98194, USA"
@@ -1711,19 +1774,19 @@ msgstr ""
"O nosso endereço para correspondência é, Projeto Tor, 217 First Avenue South"
" #4903, Seattle WA 98194, USA"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:486
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:486
msgid "Do you accept cash donations?"
msgstr "Você aceita doações em dinheiro?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:490
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:490
msgid "Yes"
msgstr "Sim"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:496
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:496
msgid "Does Tor Project accept matching donations?"
msgstr "O Projeto Tor aceita doações correspondentes?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:500
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:500
msgid ""
"Yes! Many companies --such as Google, Microsoft, eBay, PayPal, Apple, "
"Verizon, Red Hat, many universities, and others-- will match donations made "
@@ -1733,7 +1796,7 @@ msgstr ""
"Verizon, Red Hat, universidades e outros - corresponderão às doações feitas "
"por seus funcionários."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:502
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:502
msgid ""
"The fastest way to find out if your company matches donations is usually by "
"checking with your HR department, or you can search for your company name at"
@@ -1745,7 +1808,7 @@ msgstr ""
"empresa em, <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.matchinggifts.com/rit/\">https://www.matchinggifts.com/rit/</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:504
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:504
msgid ""
"If your company isn't currently set up to match donations to the Tor "
"Project, we would be happy to help with the paperwork."
@@ -1753,7 +1816,7 @@ msgstr ""
"Se a sua empresa não está atualmente configurada para corresponder as "
"doações ao Projeto Tor, ficaremos felizes em ajudar com a sua papelada."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:506
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:506
msgid ""
"If you want help figuring out the process, write us at <span "
"class=\"email\">giving(at)torproject.org</a>."
@@ -1761,11 +1824,11 @@ msgstr ""
"Se você quiser ajuda para resolver o processo, escreva-nos para <span "
"class=\"email\">giving(at)torproject.org</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:512
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:512
msgid "Can I become a Tor Project member?"
msgstr "Posso me tornar um membro do Projeto Tor?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:516
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:516
msgid ""
"Right now, we don't have a membership program, but we may set one up in the "
"future."
@@ -1773,7 +1836,7 @@ msgstr ""
"No momento, nós não temos um programa de associação, mas podemos criar uma "
"no futuro."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:518
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:518
msgid ""
"If you want to get involved with the Tor Project, <a class=\"hyperlinks "
"links\" target=\"_blank\" "
@@ -1785,11 +1848,11 @@ msgstr ""
"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">este é um "
"bom lugar para começar</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:524
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:524
msgid "How can I get a Tor t-shirt or stickers?"
msgstr "Como posso obter uma camiseta ou adesivos do Tor?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:528
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:528
msgid ""
"A variety of thank-you gifts for donors, including t-shirts, hoodies and "
"stickers, are presented on our main <a "
@@ -1799,7 +1862,7 @@ msgstr ""
"camisetas, casacos de capuz e adesivos, são apresentados na nossa página "
"principal de <a href=\"https://donate.torproject.org\">doações</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:534
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:534
msgid ""
"If I want to stay in touch with the Tor Project, what's the best way for me "
"to do that?"
@@ -1807,7 +1870,7 @@ msgstr ""
"Se eu quiser ficar em contato com o Projeto Tor, qual é a melhor maneira de "
"fazê-lo?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:538
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:538
msgid ""
"You can sign up to receive <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://newsletter.torproject.org/\">Tor News</a>, read the <a "
@@ -1823,17 +1886,17 @@ msgstr ""
"class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://twitter.com/torproject\">nos seguir no Twitter</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:544
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:544
msgid ""
"Does the Tor Project participate in the Combined Federal Campaign program?"
msgstr ""
"Será que o Projeto Tor participa do programa de Campanha Federal Combinada?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:548
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:548
msgid "No, Tor doesn't currently participate in the CFC program."
msgstr "Não, o Tor não participa atualmente do programa CFC."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:550
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:550
msgid ""
"If you'd like to get Tor added to the CFC program in your location, that "
"would be great: please let us know if you need any help."
@@ -1841,11 +1904,11 @@ msgstr ""
"Se você quiser adicionar o Tor ao programa CFC em sua localidade, isso seria"
" ótimo: informe-nos se precisar de ajuda."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:556
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:556
msgid "Can I donate my airline miles, flight vouchers, or hotel points?"
msgstr "Posso doar milhas aéreas, vales de voo ou pontos de hotel?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:562
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:562
msgid ""
"We would like to accept your miles, vouchers and hotel points, and in the "
"future we may be able to."
@@ -1853,15 +1916,15 @@ msgstr ""
"Nós gostaríamos de aceitar as suas milhas, vouchers e pontos de hotel, e no "
"futuro talvez poderemos fazê-lo."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:568
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:568
msgid "Can I donate hardware?"
msgstr "Posso doar hardware?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:572
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:572
msgid "Typically no, we don't encourage people to donate hardware."
msgstr "Normalmente, nós não encorajamos as pessoas a doarem hardware."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:574
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:574
msgid ""
"But if you want to make a hardware donation that you think might be "
"especially useful for us, please mail <span "
@@ -1871,11 +1934,11 @@ msgstr ""
"poderá ser especialmente útil para nós, por favor, enviem-nos um email para "
"<span class=\"email\">giving(at)torproject.org</span>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:580
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:580
msgid "Can I donate my time?"
msgstr "Posso doar o meu tempo?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:586
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:586
msgid ""
"Here's a <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">list of "
@@ -1885,15 +1948,15 @@ msgstr ""
"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">uma lista "
"das áreas em que gostaríamos da sua ajuda.</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:592
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:592
msgid "I would like my company to support Tor."
msgstr "Eu gostaria que minha empresa apoiasse o Tor."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:594
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:594
msgid "What can we do to help?"
msgstr "O que nós podemos fazer para ajudar?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:598
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:598
msgid ""
"Your company could match donations made by its employees to the Tor Project"
"--that would be wonderful."
@@ -1901,7 +1964,7 @@ msgstr ""
"Sua empresa poderia igualar as doações feitas por seus funcionários ao "
"Projeto Tor - isso seria maravilhoso."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:600
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:600
msgid ""
"Your company may operate a corporate foundation that gives out grants, and "
"if so, you should encourage it to fund us."
@@ -1909,7 +1972,7 @@ msgstr ""
"A sua empresa pode operar uma fundação corporativa que conceda doações, em "
"caso afirmativo, você deve incentivá-la a nos financiar."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:602
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:602
msgid ""
"Maybe your company would be willing to <a class=\"hyperlinks links\" "
"target=\"_blank\" "
@@ -1921,7 +1984,7 @@ msgstr ""
"href=\"https://www.torproject.org/docs/faq.html.en#HowDoIDecide\">a operar "
"um relé do Tor.</a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:604
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:604
msgid ""
"If your company sells cloud services, perhaps it could donate these to Tor: "
"We use them in some anti-censorship projects."
@@ -1929,25 +1992,25 @@ msgstr ""
"Se a sua empresa vende serviços de nuvem, talvez vocês possam doá-los para o"
" Projeto Tor: Nós os usamos em alguns projetos anti-censura."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:610
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:610
msgid "You don't support my preferred way to donate."
msgstr "Você não suporta meu jeito preferido de doar."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:612
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:612
msgid "Can I recommend a new donation method to you?"
msgstr "Posso recomendar um novo método de doação para você?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:616
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:616
msgid "Sure."
msgstr "Certamente que sim."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:618
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:618
msgid "Just mail us at <span class=\"email\">giving(at)torproject.org</span></a>."
msgstr ""
"Envie-nos um e-mail para <span "
"class=\"email\">giving(at)torproject.org</span></a>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:624
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:624
msgid ""
"Will the Tor Project accept donations from anybody, or do you reserve the "
"right to reject support from specific organizations or individuals?"
@@ -1956,29 +2019,29 @@ msgstr ""
"reserva no direito de rejeitar o apoio de organizações ou indivíduos "
"específicos?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:628
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:628
msgid "We do reserve the right to reject a donation."
msgstr "Nós reservamos o direito de rejeitar uma doação."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:630
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:630
msgid "To date though, we haven't exercised that right."
msgstr ""
"Porém, até hoje, nós não tivemos a necessidade de exercer esse direito."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:632
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:632
msgid "We are happy that a broad range of people use and support Tor."
msgstr ""
"Nós estamos felizes que uma ampla gama de pessoas usa e suporta o Tor."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:638
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:638
msgid "I have more questions."
msgstr "Eu tenho mais perguntas."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:640
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:640
msgid "How can I get answers?"
msgstr "Como posso obter as respostas?"
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:644
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:644
msgid ""
"Feel free to send questions to <span "
"class=\"email\">frontdesk(at)rt.torproject.org</span>."
@@ -1986,7 +2049,7 @@ msgstr ""
"Sinta-se à vontade para enviar-nos as suas perguntas para o nosso escritório"
" pelo e-mail, <span class=\"email\">frontdesk(at)rt.torproject.org</span>."
-#: tmp/cache_locale/4a/4ab2d928dab25aeb8c96bb2d1c2ad651173d6c029f40a442edf6925bfd038cd2.php:646
+#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:646
msgid ""
"We will try to answer you, and we'll also post your question (and the "
"answer) here."
@@ -1994,74 +2057,28 @@ msgstr ""
"Vamos tentar responder-lhe, e também vamos postar a sua pergunta (e a "
"resposta) aqui."
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:29
-msgid ""
-"The European shirt fits run a little small so you might want to consider "
-"sizing up."
+#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:22
+msgid "See if your employer offers employee gift matching"
msgstr ""
-"Os números do tamanho da camiseta europeia é um pouco pequeno, então você "
-"deveria considerar pedir um tamanho maior."
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:36
-msgid "Fit"
-msgstr "Tamanho"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:40
-msgid "Select Fit"
-msgstr "Selecione o seu Tamanho"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:44
-msgid "Slim"
-msgstr "Esbelto"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:48
-msgid "Classic"
-msgstr "Clássico"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:56
-msgid "European"
-msgstr "Europeu"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:66
-msgid "Size"
-msgstr "Medida"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:70
-msgid "Select Size"
-msgstr "Selecione a sua Medida"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:74
-msgid "S"
-msgstr "P"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:78
-msgid "M"
-msgstr "M"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:82
-msgid "L"
-msgstr "G"
-
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:86
-msgid "XL"
-msgstr "GG"
+"Veja se o seu empregador oferece um programa de doação em dobro para os seus"
+" funcionários"
-#: tmp/cache_locale/36/36a88fcfb8a236c24db42d5e39602cd43f2ed8bec6f6b807fb97f8e091541f37.php:90
-msgid "XXL"
-msgstr "GGG"
+#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:52
+msgid "Company"
+msgstr "Empresa"
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:488
-msgid "Gift Selected"
-msgstr "Presente selecionado"
+#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:60
+msgid "Matching Conditions"
+msgstr "Condições do Programa de Doação em Dobro"
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:492
-msgid "No Gift Selected"
-msgstr "Nenhum presente selecionado"
+#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:68
+msgid "Contact Information"
+msgstr "Informação de Contato"
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:496
-msgid "Sticker Pack"
-msgstr "Pacote de autocolantes"
+#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:76
+msgid "Additional Notes"
+msgstr "Explicações Adicionais"
-#: tmp/cache_locale/04/0421bb9119a5b92b0e2e4a49c25d718283ccfa1495534b2a08ff967a0f4fd06a.php:512
-msgid "T-Shirt Pack"
-msgstr "Pacote de camiseta"
+#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:84
+msgid "Procedure"
+msgstr "Procedimento"
1
0

[translation/donatepages-messagespot] Update translations for donatepages-messagespot
by translation@torproject.org 19 Mar '19
by translation@torproject.org 19 Mar '19
19 Mar '19
commit 549d924f6524dc81b86318ab33572e7c9133a0bc
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 19 13:45:36 2019 +0000
Update translations for donatepages-messagespot
---
locale/pt_BR/LC_MESSAGES/messages.po | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/locale/pt_BR/LC_MESSAGES/messages.po b/locale/pt_BR/LC_MESSAGES/messages.po
index 1da1ebba9..93c47aeec 100644
--- a/locale/pt_BR/LC_MESSAGES/messages.po
+++ b/locale/pt_BR/LC_MESSAGES/messages.po
@@ -231,7 +231,7 @@ msgstr "Você deseja doar usando cartão de crédito ou Paypal?"
#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:110
msgid ""
"Thanks for your interest in donating cryptocurrency to the Tor Project."
-msgstr "Agradecemos o seu interesse em doar cryptomoedas ao Projeto Tor."
+msgstr "Agradecemos o seu interesse em doar criptomoedas ao Projeto Tor."
#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:117
msgid ""
@@ -255,7 +255,7 @@ msgstr ""
msgid ""
"Below you will find the cryptocurrencies we accept and our wallet addresses."
msgstr ""
-"Abaixo você verá quais cryptomoedas nós aceitamos e os endereços das "
+"Abaixo você verá quais criptomoedas nós aceitamos e os endereços das "
"carteiras."
#: tmp/cache_locale/ef/ef5649de7f8cead2eb5ba30c5d2afbe4e1ea84df12773fd2513ca8f8823e3fbc.php:127
@@ -398,6 +398,8 @@ msgstr ""
#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:71
msgid "For your convenience, our wallet addresses are listed below."
msgstr ""
+"Para a sua conveniência, os endereços das nossas carteiras estão listados "
+"abaixo."
#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:73
msgid ""
1
0

[translation/abouttor-homepage] Update translations for abouttor-homepage
by translation@torproject.org 19 Mar '19
by translation@torproject.org 19 Mar '19
19 Mar '19
commit a8574c4e53eb22a1ed23be4802fce69237379f5d
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 19 13:45:04 2019 +0000
Update translations for abouttor-homepage
---
zh_TW/aboutTor.dtd | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zh_TW/aboutTor.dtd b/zh_TW/aboutTor.dtd
index 42636547b..0ba39e22e 100644
--- a/zh_TW/aboutTor.dtd
+++ b/zh_TW/aboutTor.dtd
@@ -6,7 +6,7 @@
<!ENTITY aboutTor.title "關於 Tor">
-<!ENTITY aboutTor.viewChangelog.label "View Changelog">
+<!ENTITY aboutTor.viewChangelog.label "檢視變更記錄">
<!ENTITY aboutTor.ready.label "探索。隱密。">
<!ENTITY aboutTor.ready2.label "您已準備好使用全世界最私密的瀏覽體驗。">
1
0

[tor/maint-0.4.0] Merge branch 'bug29706_029_minimal' into bug29706_034_minimal_merge
by nickm@torproject.org 19 Mar '19
by nickm@torproject.org 19 Mar '19
19 Mar '19
commit 1d0146e2a23180d6c3764fd51a29f84a4127d58e
Merge: e021f89f3 c44ad396f
Author: teor <teor(a)torproject.org>
Date: Mon Mar 18 11:27:59 2019 +1000
Merge branch 'bug29706_029_minimal' into bug29706_034_minimal_merge
changes/bug29706_minimal | 4 ++++
src/or/dirauth/shared_random_state.c | 4 ++--
src/or/dirauth/shared_random_state.h | 2 ++
src/test/test_shared_random.c | 17 ++++++++++++++---
4 files changed, 22 insertions(+), 5 deletions(-)
diff --cc src/or/dirauth/shared_random_state.h
index 60a326f86,cf027f2d3..d31983d18
--- a/src/or/dirauth/shared_random_state.h
+++ b/src/or/dirauth/shared_random_state.h
@@@ -140,8 -140,10 +140,10 @@@ STATIC int is_phase_transition(sr_phase
STATIC void set_sr_phase(sr_phase_t phase);
STATIC sr_state_t *get_sr_state(void);
+ STATIC void state_del_previous_srv(void);
+ STATIC void state_del_current_srv(void);
-#endif /* TOR_UNIT_TESTS */
+#endif /* defined(TOR_UNIT_TESTS) */
-#endif /* TOR_SHARED_RANDOM_STATE_H */
+#endif /* !defined(TOR_SHARED_RANDOM_STATE_H) */
1
0

[tor/maint-0.4.0] Merge branch 'bug29706_034_minimal_merge' into bug29706_035_minimal_merge
by nickm@torproject.org 19 Mar '19
by nickm@torproject.org 19 Mar '19
19 Mar '19
commit 55865a2c9c9929b690a4f5a969afd5d4415c40bd
Merge: 5d41e2223 aec6ee201
Author: teor <teor(a)torproject.org>
Date: Mon Mar 18 11:29:20 2019 +1000
Merge branch 'bug29706_034_minimal_merge' into bug29706_035_minimal_merge
changes/bug29706_minimal | 4 ++++
src/feature/dirauth/shared_random_state.c | 4 ++--
src/feature/dirauth/shared_random_state.h | 2 ++
src/test/test_shared_random.c | 17 ++++++++++++++---
4 files changed, 22 insertions(+), 5 deletions(-)
diff --cc src/feature/dirauth/shared_random_state.c
index 2bc030f4a,000000000..b3e4a4ef9
mode 100644,000000..100644
--- a/src/feature/dirauth/shared_random_state.c
+++ b/src/feature/dirauth/shared_random_state.c
@@@ -1,1340 -1,0 +1,1340 @@@
+/* Copyright (c) 2016-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file shared_random_state.c
+ *
+ * \brief Functions and data structures for the state of the random protocol
+ * as defined in proposal #250.
+ **/
+
+#define SHARED_RANDOM_STATE_PRIVATE
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "lib/crypt_ops/crypto_util.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/relay/router.h"
+#include "feature/dirauth/shared_random.h"
+#include "feature/hs_common/shared_random_client.h"
+#include "feature/dirauth/shared_random_state.h"
+#include "feature/dircommon/voting_schedule.h"
+#include "lib/encoding/confline.h"
+
+#include "app/config/or_state_st.h"
+
+/* Default filename of the shared random state on disk. */
+static const char default_fname[] = "sr-state";
+
+/* String representation of a protocol phase. */
+static const char *phase_str[] = { "unknown", "commit", "reveal" };
+
+/* Our shared random protocol state. There is only one possible state per
+ * protocol run so this is the global state which is reset at every run once
+ * the shared random value has been computed. */
+static sr_state_t *sr_state = NULL;
+
+/* Representation of our persistent state on disk. The sr_state above
+ * contains the data parsed from this state. When we save to disk, we
+ * translate the sr_state to this sr_disk_state. */
+static sr_disk_state_t *sr_disk_state = NULL;
+
+/* Disk state file keys. */
+static const char dstate_commit_key[] = "Commit";
+static const char dstate_prev_srv_key[] = "SharedRandPreviousValue";
+static const char dstate_cur_srv_key[] = "SharedRandCurrentValue";
+
+/** dummy instance of sr_disk_state_t, used for type-checking its
+ * members with CONF_CHECK_VAR_TYPE. */
+DUMMY_TYPECHECK_INSTANCE(sr_disk_state_t);
+
+/* These next two are duplicates or near-duplicates from config.c */
+#define VAR(name, conftype, member, initvalue) \
+ { name, CONFIG_TYPE_ ## conftype, offsetof(sr_disk_state_t, member), \
+ initvalue CONF_TEST_MEMBERS(sr_disk_state_t, conftype, member) }
+/* As VAR, but the option name and member name are the same. */
+#define V(member, conftype, initvalue) \
+ VAR(#member, conftype, member, initvalue)
+/* Our persistent state magic number. */
+#define SR_DISK_STATE_MAGIC 0x98AB1254
+
+static int
+disk_state_validate_cb(void *old_state, void *state, void *default_state,
+ int from_setconf, char **msg);
+static void disk_state_free_cb(void *);
+
+/* Array of variables that are saved to disk as a persistent state. */
+static config_var_t state_vars[] = {
+ V(Version, UINT, "0"),
+ V(TorVersion, STRING, NULL),
+ V(ValidAfter, ISOTIME, NULL),
+ V(ValidUntil, ISOTIME, NULL),
+
+ V(Commit, LINELIST, NULL),
+
+ V(SharedRandValues, LINELIST_V, NULL),
+ VAR("SharedRandPreviousValue",LINELIST_S, SharedRandValues, NULL),
+ VAR("SharedRandCurrentValue", LINELIST_S, SharedRandValues, NULL),
+ END_OF_CONFIG_VARS
+};
+
+/* "Extra" variable in the state that receives lines we can't parse. This
+ * lets us preserve options from versions of Tor newer than us. */
+static config_var_t state_extra_var = {
+ "__extra", CONFIG_TYPE_LINELIST,
+ offsetof(sr_disk_state_t, ExtraLines), NULL
+ CONF_TEST_MEMBERS(sr_disk_state_t, LINELIST, ExtraLines)
+};
+
+/* Configuration format of sr_disk_state_t. */
+static const config_format_t state_format = {
+ sizeof(sr_disk_state_t),
+ SR_DISK_STATE_MAGIC,
+ offsetof(sr_disk_state_t, magic_),
+ NULL,
+ NULL,
+ state_vars,
+ disk_state_validate_cb,
+ disk_state_free_cb,
+ &state_extra_var,
+};
+
+/* Return a string representation of a protocol phase. */
+STATIC const char *
+get_phase_str(sr_phase_t phase)
+{
+ const char *the_string = NULL;
+
+ switch (phase) {
+ case SR_PHASE_COMMIT:
+ case SR_PHASE_REVEAL:
+ the_string = phase_str[phase];
+ break;
+ default:
+ /* Unknown phase shouldn't be possible. */
+ tor_assert(0);
+ }
+
+ return the_string;
+}
+/* Return the time we should expire the state file created at <b>now</b>.
+ * We expire the state file in the beginning of the next protocol run. */
+STATIC time_t
+get_state_valid_until_time(time_t now)
+{
+ int total_rounds = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
+ int current_round, voting_interval, rounds_left;
+ time_t valid_until, beginning_of_current_round;
+
+ voting_interval = get_voting_interval();
+ /* Find the time the current round started. */
+ beginning_of_current_round = get_start_time_of_current_round();
+
+ /* Find how many rounds are left till the end of the protocol run */
+ current_round = (now / voting_interval) % total_rounds;
+ rounds_left = total_rounds - current_round;
+
+ /* To find the valid-until time now, take the start time of the current
+ * round and add to it the time it takes for the leftover rounds to
+ * complete. */
+ valid_until = beginning_of_current_round + (rounds_left * voting_interval);
+
+ { /* Logging */
+ char tbuf[ISO_TIME_LEN + 1];
+ format_iso_time(tbuf, valid_until);
+ log_debug(LD_DIR, "SR: Valid until time for state set to %s.", tbuf);
+ }
+
+ return valid_until;
+}
+
+/* Given the consensus 'valid-after' time, return the protocol phase we should
+ * be in. */
+STATIC sr_phase_t
+get_sr_protocol_phase(time_t valid_after)
+{
+ /* Shared random protocol has two phases, commit and reveal. */
+ int total_periods = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
+ int current_slot;
+
+ /* Split time into slots of size 'voting_interval'. See which slot we are
+ * currently into, and find which phase it corresponds to. */
+ current_slot = (valid_after / get_voting_interval()) % total_periods;
+
+ if (current_slot < SHARED_RANDOM_N_ROUNDS) {
+ return SR_PHASE_COMMIT;
+ } else {
+ return SR_PHASE_REVEAL;
+ }
+}
+
+/* Add the given <b>commit</b> to <b>state</b>. It MUST be a valid commit
+ * and there shouldn't be a commit from the same authority in the state
+ * already else verification hasn't been done prior. This takes ownership of
+ * the commit once in our state. */
+static void
+commit_add_to_state(sr_commit_t *commit, sr_state_t *state)
+{
+ sr_commit_t *saved_commit;
+
+ tor_assert(commit);
+ tor_assert(state);
+
+ saved_commit = digestmap_set(state->commits, commit->rsa_identity,
+ commit);
+ if (saved_commit != NULL) {
+ /* This means we already have that commit in our state so adding twice
+ * the same commit is either a code flow error, a corrupted disk state
+ * or some new unknown issue. */
+ log_warn(LD_DIR, "SR: Commit from %s exists in our state while "
+ "adding it: '%s'", sr_commit_get_rsa_fpr(commit),
+ commit->encoded_commit);
+ sr_commit_free(saved_commit);
+ }
+}
+
+/* Helper: deallocate a commit object. (Used with digestmap_free(), which
+ * requires a function pointer whose argument is void *). */
+static void
+commit_free_(void *p)
+{
+ sr_commit_free_(p);
+}
+
+#define state_free(val) \
+ FREE_AND_NULL(sr_state_t, state_free_, (val))
+
+/* Free a state that was allocated with state_new(). */
+static void
+state_free_(sr_state_t *state)
+{
+ if (state == NULL) {
+ return;
+ }
+ tor_free(state->fname);
+ digestmap_free(state->commits, commit_free_);
+ tor_free(state->current_srv);
+ tor_free(state->previous_srv);
+ tor_free(state);
+}
+
+/* Allocate an sr_state_t object and returns it. If no <b>fname</b>, the
+ * default file name is used. This function does NOT initialize the state
+ * timestamp, phase or shared random value. NULL is never returned. */
+static sr_state_t *
+state_new(const char *fname, time_t now)
+{
+ sr_state_t *new_state = tor_malloc_zero(sizeof(*new_state));
+ /* If file name is not provided, use default. */
+ if (fname == NULL) {
+ fname = default_fname;
+ }
+ new_state->fname = tor_strdup(fname);
+ new_state->version = SR_PROTO_VERSION;
+ new_state->commits = digestmap_new();
+ new_state->phase = get_sr_protocol_phase(now);
+ new_state->valid_until = get_state_valid_until_time(now);
+ return new_state;
+}
+
+/* Set our global state pointer with the one given. */
+static void
+state_set(sr_state_t *state)
+{
+ tor_assert(state);
+ if (sr_state != NULL) {
+ state_free(sr_state);
+ }
+ sr_state = state;
+}
+
+#define disk_state_free(val) \
+ FREE_AND_NULL(sr_disk_state_t, disk_state_free_, (val))
+
+/* Free an allocated disk state. */
+static void
+disk_state_free_(sr_disk_state_t *state)
+{
+ if (state == NULL) {
+ return;
+ }
+ config_free(&state_format, state);
+}
+
+/* Allocate a new disk state, initialize it and return it. */
+static sr_disk_state_t *
+disk_state_new(time_t now)
+{
+ sr_disk_state_t *new_state = tor_malloc_zero(sizeof(*new_state));
+
+ new_state->magic_ = SR_DISK_STATE_MAGIC;
+ new_state->Version = SR_PROTO_VERSION;
+ new_state->TorVersion = tor_strdup(get_version());
+ new_state->ValidUntil = get_state_valid_until_time(now);
+ new_state->ValidAfter = now;
+
+ /* Init config format. */
+ config_init(&state_format, new_state);
+ return new_state;
+}
+
+/* Set our global disk state with the given state. */
+static void
+disk_state_set(sr_disk_state_t *state)
+{
+ tor_assert(state);
+ if (sr_disk_state != NULL) {
+ disk_state_free(sr_disk_state);
+ }
+ sr_disk_state = state;
+}
+
+/* Return -1 if the disk state is invalid (something in there that we can't or
+ * shouldn't use). Return 0 if everything checks out. */
+static int
+disk_state_validate(const sr_disk_state_t *state)
+{
+ time_t now;
+
+ tor_assert(state);
+
+ /* Do we support the protocol version in the state or is it 0 meaning
+ * Version wasn't found in the state file or bad anyway ? */
+ if (state->Version == 0 || state->Version > SR_PROTO_VERSION) {
+ goto invalid;
+ }
+
+ /* If the valid until time is before now, we shouldn't use that state. */
+ now = time(NULL);
+ if (state->ValidUntil < now) {
+ log_info(LD_DIR, "SR: Disk state has expired. Ignoring it.");
+ goto invalid;
+ }
+
+ /* Make sure we don't have a valid after time that is earlier than a valid
+ * until time which would make things not work well. */
+ if (state->ValidAfter >= state->ValidUntil) {
+ log_info(LD_DIR, "SR: Disk state valid after/until times are invalid.");
+ goto invalid;
+ }
+
+ return 0;
+
+ invalid:
+ return -1;
+}
+
+/* Validate the disk state (NOP for now). */
+static int
+disk_state_validate_cb(void *old_state, void *state, void *default_state,
+ int from_setconf, char **msg)
+{
+ /* We don't use these; only options do. */
+ (void) from_setconf;
+ (void) default_state;
+ (void) old_state;
+
+ /* This is called by config_dump which is just before we are about to
+ * write it to disk. At that point, our global memory state has been
+ * copied to the disk state so it's fair to assume it's trustable. */
+ (void) state;
+ (void) msg;
+ return 0;
+}
+
+static void
+disk_state_free_cb(void *state)
+{
+ disk_state_free_(state);
+}
+
+/* Parse the Commit line(s) in the disk state and translate them to the
+ * the memory state. Return 0 on success else -1 on error. */
+static int
+disk_state_parse_commits(sr_state_t *state,
+ const sr_disk_state_t *disk_state)
+{
+ config_line_t *line;
+ smartlist_t *args = NULL;
+
+ tor_assert(state);
+ tor_assert(disk_state);
+
+ for (line = disk_state->Commit; line; line = line->next) {
+ sr_commit_t *commit = NULL;
+
+ /* Extra safety. */
+ if (strcasecmp(line->key, dstate_commit_key) ||
+ line->value == NULL) {
+ /* Ignore any lines that are not commits. */
+ tor_fragile_assert();
+ continue;
+ }
+ args = smartlist_new();
+ smartlist_split_string(args, line->value, " ",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ if (smartlist_len(args) < 3) {
+ log_warn(LD_BUG, "SR: Too few arguments in Commit Line: %s",
+ escaped(line->value));
+ goto error;
+ }
+ commit = sr_parse_commit(args);
+ if (commit == NULL) {
+ /* Ignore badly formed commit. It could also be a authority
+ * fingerprint that we don't know about so it shouldn't be used. */
+ smartlist_free(args);
+ continue;
+ }
+ /* We consider parseable commit from our disk state to be valid because
+ * they need to be in the first place to get in there. */
+ commit->valid = 1;
+ /* Add commit to our state pointer. */
+ commit_add_to_state(commit, state);
+
+ SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+ smartlist_free(args);
+ }
+
+ return 0;
+
+ error:
+ SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+ smartlist_free(args);
+ return -1;
+}
+
+/* Parse a share random value line from the disk state and save it to dst
+ * which is an allocated srv object. Return 0 on success else -1. */
+static int
+disk_state_parse_srv(const char *value, sr_srv_t *dst)
+{
+ int ret = -1;
+ smartlist_t *args;
+ sr_srv_t *srv;
+
+ tor_assert(value);
+ tor_assert(dst);
+
+ args = smartlist_new();
+ smartlist_split_string(args, value, " ",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ if (smartlist_len(args) < 2) {
+ log_warn(LD_BUG, "SR: Too few arguments in shared random value. "
+ "Line: %s", escaped(value));
+ goto error;
+ }
+ srv = sr_parse_srv(args);
+ if (srv == NULL) {
+ goto error;
+ }
+ dst->num_reveals = srv->num_reveals;
+ memcpy(dst->value, srv->value, sizeof(dst->value));
+ tor_free(srv);
+ ret = 0;
+
+ error:
+ SMARTLIST_FOREACH(args, char *, s, tor_free(s));
+ smartlist_free(args);
+ return ret;
+}
+
+/* Parse both SharedRandCurrentValue and SharedRandPreviousValue line from
+ * the state. Return 0 on success else -1. */
+static int
+disk_state_parse_sr_values(sr_state_t *state,
+ const sr_disk_state_t *disk_state)
+{
+ /* Only one value per type (current or previous) is allowed so we keep
+ * track of it with these flag. */
+ unsigned int seen_previous = 0, seen_current = 0;
+ config_line_t *line;
+ sr_srv_t *srv = NULL;
+
+ tor_assert(state);
+ tor_assert(disk_state);
+
+ for (line = disk_state->SharedRandValues; line; line = line->next) {
+ if (line->value == NULL) {
+ continue;
+ }
+ srv = tor_malloc_zero(sizeof(*srv));
+ if (disk_state_parse_srv(line->value, srv) < 0) {
+ log_warn(LD_BUG, "SR: Broken current SRV line in state %s",
+ escaped(line->value));
+ goto bad;
+ }
+ if (!strcasecmp(line->key, dstate_prev_srv_key)) {
+ if (seen_previous) {
+ log_warn(LD_DIR, "SR: Second previous SRV value seen. Bad state");
+ goto bad;
+ }
+ state->previous_srv = srv;
+ seen_previous = 1;
+ } else if (!strcasecmp(line->key, dstate_cur_srv_key)) {
+ if (seen_current) {
+ log_warn(LD_DIR, "SR: Second current SRV value seen. Bad state");
+ goto bad;
+ }
+ state->current_srv = srv;
+ seen_current = 1;
+ } else {
+ /* Unknown key. Ignoring. */
+ tor_free(srv);
+ }
+ }
+
+ return 0;
+ bad:
+ tor_free(srv);
+ return -1;
+}
+
+/* Parse the given disk state and set a newly allocated state. On success,
+ * return that state else NULL. */
+static sr_state_t *
+disk_state_parse(const sr_disk_state_t *new_disk_state)
+{
+ sr_state_t *new_state = state_new(default_fname, time(NULL));
+
+ tor_assert(new_disk_state);
+
+ new_state->version = new_disk_state->Version;
+ new_state->valid_until = new_disk_state->ValidUntil;
+ new_state->valid_after = new_disk_state->ValidAfter;
+
+ /* Set our current phase according to the valid-after time in our disk
+ * state. The disk state we are parsing contains everything for the phase
+ * starting at valid_after so make sure our phase reflects that. */
+ new_state->phase = get_sr_protocol_phase(new_state->valid_after);
+
+ /* Parse the shared random values. */
+ if (disk_state_parse_sr_values(new_state, new_disk_state) < 0) {
+ goto error;
+ }
+ /* Parse the commits. */
+ if (disk_state_parse_commits(new_state, new_disk_state) < 0) {
+ goto error;
+ }
+ /* Great! This new state contains everything we had on disk. */
+ return new_state;
+
+ error:
+ state_free(new_state);
+ return NULL;
+}
+
+/* From a valid commit object and an allocated config line, set the line's
+ * value to the state string representation of a commit. */
+static void
+disk_state_put_commit_line(const sr_commit_t *commit, config_line_t *line)
+{
+ char *reveal_str = NULL;
+
+ tor_assert(commit);
+ tor_assert(line);
+
+ if (!tor_mem_is_zero(commit->encoded_reveal,
+ sizeof(commit->encoded_reveal))) {
+ /* Add extra whitespace so we can format the line correctly. */
+ tor_asprintf(&reveal_str, " %s", commit->encoded_reveal);
+ }
+ tor_asprintf(&line->value, "%u %s %s %s%s",
+ SR_PROTO_VERSION,
+ crypto_digest_algorithm_get_name(commit->alg),
+ sr_commit_get_rsa_fpr(commit),
+ commit->encoded_commit,
+ reveal_str != NULL ? reveal_str : "");
+ if (reveal_str != NULL) {
+ memwipe(reveal_str, 0, strlen(reveal_str));
+ tor_free(reveal_str);
+ }
+}
+
+/* From a valid srv object and an allocated config line, set the line's
+ * value to the state string representation of a shared random value. */
+static void
+disk_state_put_srv_line(const sr_srv_t *srv, config_line_t *line)
+{
+ char encoded[SR_SRV_VALUE_BASE64_LEN + 1];
+
+ tor_assert(line);
+
+ /* No SRV value thus don't add the line. This is possible since we might
+ * not have a current or previous SRV value in our state. */
+ if (srv == NULL) {
+ return;
+ }
+ sr_srv_encode(encoded, sizeof(encoded), srv);
+ tor_asprintf(&line->value, "%" PRIu64 " %s", srv->num_reveals, encoded);
+}
+
+/* Reset disk state that is free allocated memory and zeroed the object. */
+static void
+disk_state_reset(void)
+{
+ /* Free allocated memory */
+ config_free_lines(sr_disk_state->Commit);
+ config_free_lines(sr_disk_state->SharedRandValues);
+ config_free_lines(sr_disk_state->ExtraLines);
+ tor_free(sr_disk_state->TorVersion);
+
+ /* Clean up the struct */
+ memset(sr_disk_state, 0, sizeof(*sr_disk_state));
+
+ /* Reset it with useful data */
+ sr_disk_state->magic_ = SR_DISK_STATE_MAGIC;
+ sr_disk_state->TorVersion = tor_strdup(get_version());
+}
+
+/* Update our disk state based on our global SR state. */
+static void
+disk_state_update(void)
+{
+ config_line_t **next, *line;
+
+ if (BUG(!sr_disk_state))
+ return;
+ if (BUG(!sr_state))
+ return;
+
+ /* Reset current disk state. */
+ disk_state_reset();
+
+ /* First, update elements that we don't need to do a construction. */
+ sr_disk_state->Version = sr_state->version;
+ sr_disk_state->ValidUntil = sr_state->valid_until;
+ sr_disk_state->ValidAfter = sr_state->valid_after;
+
+ /* Shared random values. */
+ next = &sr_disk_state->SharedRandValues;
+ if (sr_state->previous_srv != NULL) {
+ *next = line = tor_malloc_zero(sizeof(config_line_t));
+ line->key = tor_strdup(dstate_prev_srv_key);
+ disk_state_put_srv_line(sr_state->previous_srv, line);
+ /* Go to the next shared random value. */
+ next = &(line->next);
+ }
+ if (sr_state->current_srv != NULL) {
+ *next = line = tor_malloc_zero(sizeof(*line));
+ line->key = tor_strdup(dstate_cur_srv_key);
+ disk_state_put_srv_line(sr_state->current_srv, line);
+ }
+
+ /* Parse the commits and construct config line(s). */
+ next = &sr_disk_state->Commit;
+ DIGESTMAP_FOREACH(sr_state->commits, key, sr_commit_t *, commit) {
+ *next = line = tor_malloc_zero(sizeof(*line));
+ line->key = tor_strdup(dstate_commit_key);
+ disk_state_put_commit_line(commit, line);
+ next = &(line->next);
+ } DIGESTMAP_FOREACH_END;
+}
+
+/* Load state from disk and put it into our disk state. If the state passes
+ * validation, our global state will be updated with it. Return 0 on
+ * success. On error, -EINVAL is returned if the state on disk did contained
+ * something malformed or is unreadable. -ENOENT is returned indicating that
+ * the state file is either empty of non existing. */
+static int
+disk_state_load_from_disk(void)
+{
+ int ret;
+ char *fname;
+
+ fname = get_datadir_fname(default_fname);
+ ret = disk_state_load_from_disk_impl(fname);
+ tor_free(fname);
+
+ return ret;
+}
+
+/* Helper for disk_state_load_from_disk(). */
+STATIC int
+disk_state_load_from_disk_impl(const char *fname)
+{
+ int ret;
+ char *content = NULL;
+ sr_state_t *parsed_state = NULL;
+ sr_disk_state_t *disk_state = NULL;
+
+ /* Read content of file so we can parse it. */
+ if ((content = read_file_to_str(fname, 0, NULL)) == NULL) {
+ log_warn(LD_FS, "SR: Unable to read SR state file %s",
+ escaped(fname));
+ ret = -errno;
+ goto error;
+ }
+
+ {
+ config_line_t *lines = NULL;
+ char *errmsg = NULL;
+
+ /* Every error in this code path will return EINVAL. */
+ ret = -EINVAL;
+ if (config_get_lines(content, &lines, 0) < 0) {
+ config_free_lines(lines);
+ goto error;
+ }
+
+ disk_state = disk_state_new(time(NULL));
+ config_assign(&state_format, disk_state, lines, 0, &errmsg);
+ config_free_lines(lines);
+ if (errmsg) {
+ log_warn(LD_DIR, "SR: Reading state error: %s", errmsg);
+ tor_free(errmsg);
+ goto error;
+ }
+ }
+
+ /* So far so good, we've loaded our state file into our disk state. Let's
+ * validate it and then parse it. */
+ if (disk_state_validate(disk_state) < 0) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ parsed_state = disk_state_parse(disk_state);
+ if (parsed_state == NULL) {
+ ret = -EINVAL;
+ goto error;
+ }
+ state_set(parsed_state);
+ disk_state_set(disk_state);
+ tor_free(content);
+ log_info(LD_DIR, "SR: State loaded successfully from file %s", fname);
+ return 0;
+
+ error:
+ disk_state_free(disk_state);
+ tor_free(content);
+ return ret;
+}
+
+/* Save the disk state to disk but before that update it from the current
+ * state so we always have the latest. Return 0 on success else -1. */
+static int
+disk_state_save_to_disk(void)
+{
+ int ret;
+ char *state, *content = NULL, *fname = NULL;
+ char tbuf[ISO_TIME_LEN + 1];
+ time_t now = time(NULL);
+
+ /* If we didn't have the opportunity to setup an internal disk state,
+ * don't bother saving something to disk. */
+ if (sr_disk_state == NULL) {
+ ret = 0;
+ goto done;
+ }
+
+ /* Make sure that our disk state is up to date with our memory state
+ * before saving it to disk. */
+ disk_state_update();
+ state = config_dump(&state_format, NULL, sr_disk_state, 0, 0);
+ format_local_iso_time(tbuf, now);
+ tor_asprintf(&content,
+ "# Tor shared random state file last generated on %s "
+ "local time\n"
+ "# Other times below are in UTC\n"
+ "# Please *do not* edit this file.\n\n%s",
+ tbuf, state);
+ tor_free(state);
+ fname = get_datadir_fname(default_fname);
+ if (write_str_to_file(fname, content, 0) < 0) {
+ log_warn(LD_FS, "SR: Unable to write SR state to file %s", fname);
+ ret = -1;
+ goto done;
+ }
+ ret = 0;
+ log_debug(LD_DIR, "SR: Saved state to file %s", fname);
+
+ done:
+ tor_free(fname);
+ tor_free(content);
+ return ret;
+}
+
+/* Reset our state to prepare for a new protocol run. Once this returns, all
+ * commits in the state will be removed and freed. */
+STATIC void
+reset_state_for_new_protocol_run(time_t valid_after)
+{
+ if (BUG(!sr_state))
+ return;
+
+ /* Keep counters in track */
+ sr_state->n_reveal_rounds = 0;
+ sr_state->n_commit_rounds = 0;
+ sr_state->n_protocol_runs++;
+
+ /* Reset valid-until */
+ sr_state->valid_until = get_state_valid_until_time(valid_after);
+ sr_state->valid_after = valid_after;
+
+ /* We are in a new protocol run so cleanup commits. */
+ sr_state_delete_commits();
+}
+
+/* This is the first round of the new protocol run starting at
+ * <b>valid_after</b>. Do the necessary housekeeping. */
+STATIC void
+new_protocol_run(time_t valid_after)
+{
+ sr_commit_t *our_commitment = NULL;
+
+ /* Only compute the srv at the end of the reveal phase. */
+ if (sr_state->phase == SR_PHASE_REVEAL) {
+ /* We are about to compute a new shared random value that will be set in
+ * our state as the current value so rotate values. */
+ state_rotate_srv();
+ /* Compute the shared randomness value of the day. */
+ sr_compute_srv();
+ }
+
+ /* Prepare for the new protocol run by reseting the state */
+ reset_state_for_new_protocol_run(valid_after);
+
+ /* Do some logging */
+ log_info(LD_DIR, "SR: Protocol run #%" PRIu64 " starting!",
+ sr_state->n_protocol_runs);
+
+ /* Generate fresh commitments for this protocol run */
+ our_commitment = sr_generate_our_commit(valid_after,
+ get_my_v3_authority_cert());
+ if (our_commitment) {
+ /* Add our commitment to our state. In case we are unable to create one
+ * (highly unlikely), we won't vote for this protocol run since our
+ * commitment won't be in our state. */
+ sr_state_add_commit(our_commitment);
+ }
+}
+
+/* Return 1 iff the <b>next_phase</b> is a phase transition from the current
+ * phase that is it's different. */
+STATIC int
+is_phase_transition(sr_phase_t next_phase)
+{
+ return sr_state->phase != next_phase;
+}
+
+/* Helper function: return a commit using the RSA fingerprint of the
+ * authority or NULL if no such commit is known. */
+static sr_commit_t *
+state_query_get_commit(const char *rsa_fpr)
+{
+ tor_assert(rsa_fpr);
+ return digestmap_get(sr_state->commits, rsa_fpr);
+}
+
+/* Helper function: This handles the GET state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void *
+state_query_get_(sr_state_object_t obj_type, const void *data)
+{
+ void *obj = NULL;
+
+ switch (obj_type) {
+ case SR_STATE_OBJ_COMMIT:
+ {
+ obj = state_query_get_commit(data);
+ break;
+ }
+ case SR_STATE_OBJ_COMMITS:
+ obj = sr_state->commits;
+ break;
+ case SR_STATE_OBJ_CURSRV:
+ obj = sr_state->current_srv;
+ break;
+ case SR_STATE_OBJ_PREVSRV:
+ obj = sr_state->previous_srv;
+ break;
+ case SR_STATE_OBJ_PHASE:
+ obj = &sr_state->phase;
+ break;
+ case SR_STATE_OBJ_VALID_AFTER:
+ default:
+ tor_assert(0);
+ }
+ return obj;
+}
+
+/* Helper function: This handles the PUT state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void
+state_query_put_(sr_state_object_t obj_type, void *data)
+{
+ switch (obj_type) {
+ case SR_STATE_OBJ_COMMIT:
+ {
+ sr_commit_t *commit = data;
+ tor_assert(commit);
+ commit_add_to_state(commit, sr_state);
+ break;
+ }
+ case SR_STATE_OBJ_CURSRV:
+ sr_state->current_srv = (sr_srv_t *) data;
+ break;
+ case SR_STATE_OBJ_PREVSRV:
+ sr_state->previous_srv = (sr_srv_t *) data;
+ break;
+ case SR_STATE_OBJ_VALID_AFTER:
+ sr_state->valid_after = *((time_t *) data);
+ break;
+ /* It's not allowed to change the phase nor the full commitments map from
+ * the state. The phase is decided during a strict process post voting and
+ * the commits should be put individually. */
+ case SR_STATE_OBJ_PHASE:
+ case SR_STATE_OBJ_COMMITS:
+ default:
+ tor_assert(0);
+ }
+}
+
+/* Helper function: This handles the DEL_ALL state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void
+state_query_del_all_(sr_state_object_t obj_type)
+{
+ switch (obj_type) {
+ case SR_STATE_OBJ_COMMIT:
+ {
+ /* We are in a new protocol run so cleanup commitments. */
+ DIGESTMAP_FOREACH_MODIFY(sr_state->commits, key, sr_commit_t *, c) {
+ sr_commit_free(c);
+ MAP_DEL_CURRENT(key);
+ } DIGESTMAP_FOREACH_END;
+ break;
+ }
+ /* The following object are _NOT_ suppose to be removed. */
+ case SR_STATE_OBJ_CURSRV:
+ case SR_STATE_OBJ_PREVSRV:
+ case SR_STATE_OBJ_PHASE:
+ case SR_STATE_OBJ_COMMITS:
+ case SR_STATE_OBJ_VALID_AFTER:
+ default:
+ tor_assert(0);
+ }
+}
+
+/* Helper function: This handles the DEL state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void
+state_query_del_(sr_state_object_t obj_type, void *data)
+{
+ (void) data;
+
+ switch (obj_type) {
+ case SR_STATE_OBJ_PREVSRV:
+ tor_free(sr_state->previous_srv);
+ break;
+ case SR_STATE_OBJ_CURSRV:
+ tor_free(sr_state->current_srv);
+ break;
+ case SR_STATE_OBJ_COMMIT:
+ case SR_STATE_OBJ_COMMITS:
+ case SR_STATE_OBJ_PHASE:
+ case SR_STATE_OBJ_VALID_AFTER:
+ default:
+ tor_assert(0);
+ }
+}
+
+/* Query state using an <b>action</b> for an object type <b>obj_type</b>.
+ * The <b>data</b> pointer needs to point to an object that the action needs
+ * to use and if anything is required to be returned, it is stored in
+ * <b>out</b>.
+ *
+ * This mechanism exists so we have one single point where we synchronized
+ * our memory state with our disk state for every actions that changes it.
+ * We then trigger a write on disk immediately.
+ *
+ * This should be the only entry point to our memory state. It's used by all
+ * our state accessors and should be in the future. */
+static void
+state_query(sr_state_action_t action, sr_state_object_t obj_type,
+ void *data, void **out)
+{
+ switch (action) {
+ case SR_STATE_ACTION_GET:
+ *out = state_query_get_(obj_type, data);
+ break;
+ case SR_STATE_ACTION_PUT:
+ state_query_put_(obj_type, data);
+ break;
+ case SR_STATE_ACTION_DEL:
+ state_query_del_(obj_type, data);
+ break;
+ case SR_STATE_ACTION_DEL_ALL:
+ state_query_del_all_(obj_type);
+ break;
+ case SR_STATE_ACTION_SAVE:
+ /* Only trigger a disk state save. */
+ break;
+ default:
+ tor_assert(0);
+ }
+
+ /* If the action actually changes the state, immediately save it to disk.
+ * The following will sync the state -> disk state and then save it. */
+ if (action != SR_STATE_ACTION_GET) {
+ disk_state_save_to_disk();
+ }
+}
+
+/* Delete the current SRV value from the state freeing it and the value is set
+ * to NULL meaning empty. */
- static void
++STATIC void
+state_del_current_srv(void)
+{
+ state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_CURSRV, NULL, NULL);
+}
+
+/* Delete the previous SRV value from the state freeing it and the value is
+ * set to NULL meaning empty. */
- static void
++STATIC void
+state_del_previous_srv(void)
+{
+ state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_PREVSRV, NULL, NULL);
+}
+
+/* Rotate SRV value by freeing the previous value, assigning the current
+ * value to the previous one and nullifying the current one. */
+STATIC void
+state_rotate_srv(void)
+{
+ /* First delete previous SRV from the state. Object will be freed. */
+ state_del_previous_srv();
+ /* Set previous SRV with the current one. */
+ sr_state_set_previous_srv(sr_state_get_current_srv());
+ /* Nullify the current srv. */
+ sr_state_set_current_srv(NULL);
+}
+
+/* Set valid after time in the our state. */
+void
+sr_state_set_valid_after(time_t valid_after)
+{
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_VALID_AFTER,
+ (void *) &valid_after, NULL);
+}
+
+/* Return the phase we are currently in according to our state. */
+sr_phase_t
+sr_state_get_phase(void)
+{
+ void *ptr;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_PHASE, NULL, &ptr);
+ return *(sr_phase_t *) ptr;
+}
+
+/* Return the previous SRV value from our state. Value CAN be NULL. */
+const sr_srv_t *
+sr_state_get_previous_srv(void)
+{
+ const sr_srv_t *srv;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_PREVSRV, NULL,
+ (void *) &srv);
+ return srv;
+}
+
+/* Set the current SRV value from our state. Value CAN be NULL. The srv
+ * object ownership is transferred to the state object. */
+void
+sr_state_set_previous_srv(const sr_srv_t *srv)
+{
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_PREVSRV, (void *) srv,
+ NULL);
+}
+
+/* Return the current SRV value from our state. Value CAN be NULL. */
+const sr_srv_t *
+sr_state_get_current_srv(void)
+{
+ const sr_srv_t *srv;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_CURSRV, NULL,
+ (void *) &srv);
+ return srv;
+}
+
+/* Set the current SRV value from our state. Value CAN be NULL. The srv
+ * object ownership is transferred to the state object. */
+void
+sr_state_set_current_srv(const sr_srv_t *srv)
+{
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_CURSRV, (void *) srv,
+ NULL);
+}
+
+/* Clean all the SRVs in our state. */
+void
+sr_state_clean_srvs(void)
+{
+ /* Remove SRVs from state. They will be set to NULL as "empty". */
+ state_del_previous_srv();
+ state_del_current_srv();
+}
+
+/* Return a pointer to the commits map from our state. CANNOT be NULL. */
+digestmap_t *
+sr_state_get_commits(void)
+{
+ digestmap_t *commits;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_COMMITS,
+ NULL, (void *) &commits);
+ tor_assert(commits);
+ return commits;
+}
+
+/* Update the current SR state as needed for the upcoming voting round at
+ * <b>valid_after</b>. */
+void
+sr_state_update(time_t valid_after)
+{
+ sr_phase_t next_phase;
+
+ if (BUG(!sr_state))
+ return;
+
+ /* Don't call this function twice in the same voting period. */
+ if (valid_after <= sr_state->valid_after) {
+ log_info(LD_DIR, "SR: Asked to update state twice. Ignoring.");
+ return;
+ }
+
+ /* Get phase of upcoming round. */
+ next_phase = get_sr_protocol_phase(valid_after);
+
+ /* If we are transitioning to a new protocol phase, prepare the stage. */
+ if (is_phase_transition(next_phase)) {
+ if (next_phase == SR_PHASE_COMMIT) {
+ /* Going into commit phase means we are starting a new protocol run. */
+ new_protocol_run(valid_after);
+ }
+ /* Set the new phase for this round */
+ sr_state->phase = next_phase;
+ } else if (sr_state->phase == SR_PHASE_COMMIT &&
+ digestmap_size(sr_state->commits) == 0) {
+ /* We are _NOT_ in a transition phase so if we are in the commit phase
+ * and have no commit, generate one. Chances are that we are booting up
+ * so let's have a commit in our state for the next voting period. */
+ sr_commit_t *our_commit =
+ sr_generate_our_commit(valid_after, get_my_v3_authority_cert());
+ if (our_commit) {
+ /* Add our commitment to our state. In case we are unable to create one
+ * (highly unlikely), we won't vote for this protocol run since our
+ * commitment won't be in our state. */
+ sr_state_add_commit(our_commit);
+ }
+ }
+
+ sr_state_set_valid_after(valid_after);
+
+ /* Count the current round */
+ if (sr_state->phase == SR_PHASE_COMMIT) {
+ /* invariant check: we've not entered reveal phase yet */
+ if (BUG(sr_state->n_reveal_rounds != 0))
+ return;
+ sr_state->n_commit_rounds++;
+ } else {
+ sr_state->n_reveal_rounds++;
+ }
+
+ { /* Debugging. */
+ char tbuf[ISO_TIME_LEN + 1];
+ format_iso_time(tbuf, valid_after);
+ log_info(LD_DIR, "SR: State prepared for upcoming voting period (%s). "
+ "Upcoming phase is %s (counters: %d commit & %d reveal rounds).",
+ tbuf, get_phase_str(sr_state->phase),
+ sr_state->n_commit_rounds, sr_state->n_reveal_rounds);
+ }
+}
+
+/* Return commit object from the given authority digest <b>rsa_identity</b>.
+ * Return NULL if not found. */
+sr_commit_t *
+sr_state_get_commit(const char *rsa_identity)
+{
+ sr_commit_t *commit;
+
+ tor_assert(rsa_identity);
+
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_COMMIT,
+ (void *) rsa_identity, (void *) &commit);
+ return commit;
+}
+
+/* Add <b>commit</b> to the permanent state. The commit object ownership is
+ * transferred to the state so the caller MUST not free it. */
+void
+sr_state_add_commit(sr_commit_t *commit)
+{
+ tor_assert(commit);
+
+ /* Put the commit to the global state. */
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_COMMIT,
+ (void *) commit, NULL);
+
+ log_debug(LD_DIR, "SR: Commit from %s has been added to our state.",
+ sr_commit_get_rsa_fpr(commit));
+}
+
+/* Remove all commits from our state. */
+void
+sr_state_delete_commits(void)
+{
+ state_query(SR_STATE_ACTION_DEL_ALL, SR_STATE_OBJ_COMMIT, NULL, NULL);
+}
+
+/* Copy the reveal information from <b>commit</b> into <b>saved_commit</b>.
+ * This <b>saved_commit</b> MUST come from our current SR state. Once modified,
+ * the disk state is updated. */
+void
+sr_state_copy_reveal_info(sr_commit_t *saved_commit, const sr_commit_t *commit)
+{
+ tor_assert(saved_commit);
+ tor_assert(commit);
+
+ saved_commit->reveal_ts = commit->reveal_ts;
+ memcpy(saved_commit->random_number, commit->random_number,
+ sizeof(saved_commit->random_number));
+
+ strlcpy(saved_commit->encoded_reveal, commit->encoded_reveal,
+ sizeof(saved_commit->encoded_reveal));
+ state_query(SR_STATE_ACTION_SAVE, 0, NULL, NULL);
+ log_debug(LD_DIR, "SR: Reveal value learned %s (for commit %s) from %s",
+ saved_commit->encoded_reveal, saved_commit->encoded_commit,
+ sr_commit_get_rsa_fpr(saved_commit));
+}
+
+/* Set the fresh SRV flag from our state. This doesn't need to trigger a
+ * disk state synchronization so we directly change the state. */
+void
+sr_state_set_fresh_srv(void)
+{
+ sr_state->is_srv_fresh = 1;
+}
+
+/* Unset the fresh SRV flag from our state. This doesn't need to trigger a
+ * disk state synchronization so we directly change the state. */
+void
+sr_state_unset_fresh_srv(void)
+{
+ sr_state->is_srv_fresh = 0;
+}
+
+/* Return the value of the fresh SRV flag. */
+unsigned int
+sr_state_srv_is_fresh(void)
+{
+ return sr_state->is_srv_fresh;
+}
+
+/* Cleanup and free our disk and memory state. */
+void
+sr_state_free_all(void)
+{
+ state_free(sr_state);
+ disk_state_free(sr_disk_state);
+ /* Nullify our global state. */
+ sr_state = NULL;
+ sr_disk_state = NULL;
+}
+
+/* Save our current state in memory to disk. */
+void
+sr_state_save(void)
+{
+ /* Query a SAVE action on our current state so it's synced and saved. */
+ state_query(SR_STATE_ACTION_SAVE, 0, NULL, NULL);
+}
+
+/* Return 1 iff the state has been initialized that is it exists in memory.
+ * Return 0 otherwise. */
+int
+sr_state_is_initialized(void)
+{
+ return sr_state == NULL ? 0 : 1;
+}
+
+/* Initialize the disk and memory state.
+ *
+ * If save_to_disk is set to 1, the state is immediately saved to disk after
+ * creation else it's not thus only kept in memory.
+ * If read_from_disk is set to 1, we try to load the state from the disk and
+ * if not found, a new state is created.
+ *
+ * Return 0 on success else a negative value on error. */
+int
+sr_state_init(int save_to_disk, int read_from_disk)
+{
+ int ret = -ENOENT;
+ time_t now = time(NULL);
+
+ /* We shouldn't have those assigned. */
+ tor_assert(sr_disk_state == NULL);
+ tor_assert(sr_state == NULL);
+
+ /* First, try to load the state from disk. */
+ if (read_from_disk) {
+ ret = disk_state_load_from_disk();
+ }
+
+ if (ret < 0) {
+ switch (-ret) {
+ case EINVAL:
+ /* We have a state on disk but it contains something we couldn't parse
+ * or an invalid entry in the state file. Let's remove it since it's
+ * obviously unusable and replace it by an new fresh state below. */
+ case ENOENT:
+ {
+ /* No state on disk so allocate our states for the first time. */
+ sr_state_t *new_state = state_new(default_fname, now);
+ sr_disk_state_t *new_disk_state = disk_state_new(now);
+ state_set(new_state);
+ /* It's important to set our disk state pointer since the save call
+ * below uses it to synchronized it with our memory state. */
+ disk_state_set(new_disk_state);
+ /* No entry, let's save our new state to disk. */
+ if (save_to_disk && disk_state_save_to_disk() < 0) {
+ goto error;
+ }
+ break;
+ }
+ default:
+ /* Big problem. Not possible. */
+ tor_assert(0);
+ }
+ }
+ /* We have a state in memory, let's make sure it's updated for the current
+ * and next voting round. */
+ {
+ time_t valid_after = voting_schedule_get_next_valid_after_time();
+ sr_state_update(valid_after);
+ }
+ return 0;
+
+ error:
+ return -1;
+}
+
+#ifdef TOR_UNIT_TESTS
+
+/* Set the current phase of the protocol. Used only by unit tests. */
+void
+set_sr_phase(sr_phase_t phase)
+{
+ if (BUG(!sr_state))
+ return;
+ sr_state->phase = phase;
+}
+
+/* Get the SR state. Used only by unit tests */
+sr_state_t *
+get_sr_state(void)
+{
+ return sr_state;
+}
+
+#endif /* defined(TOR_UNIT_TESTS) */
diff --cc src/feature/dirauth/shared_random_state.h
index 35626be3f,000000000..08f999f9d
mode 100644,000000..100644
--- a/src/feature/dirauth/shared_random_state.h
+++ b/src/feature/dirauth/shared_random_state.h
@@@ -1,146 -1,0 +1,148 @@@
+/* Copyright (c) 2016-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_SHARED_RANDOM_STATE_H
+#define TOR_SHARED_RANDOM_STATE_H
+
+#include "feature/dirauth/shared_random.h"
+
+/* Action that can be performed on the state for any objects. */
+typedef enum {
+ SR_STATE_ACTION_GET = 1,
+ SR_STATE_ACTION_PUT = 2,
+ SR_STATE_ACTION_DEL = 3,
+ SR_STATE_ACTION_DEL_ALL = 4,
+ SR_STATE_ACTION_SAVE = 5,
+} sr_state_action_t;
+
+/* Object in the state that can be queried through the state API. */
+typedef enum {
+ /* Will return a single commit using an authority identity key. */
+ SR_STATE_OBJ_COMMIT,
+ /* Returns the entire list of commits from the state. */
+ SR_STATE_OBJ_COMMITS,
+ /* Return the current SRV object pointer. */
+ SR_STATE_OBJ_CURSRV,
+ /* Return the previous SRV object pointer. */
+ SR_STATE_OBJ_PREVSRV,
+ /* Return the phase. */
+ SR_STATE_OBJ_PHASE,
+ /* Get or Put the valid after time. */
+ SR_STATE_OBJ_VALID_AFTER,
+} sr_state_object_t;
+
+/* State of the protocol. It's also saved on disk in fname. This data
+ * structure MUST be synchronized at all time with the one on disk. */
+typedef struct sr_state_t {
+ /* Filename of the state file on disk. */
+ char *fname;
+ /* Version of the protocol. */
+ uint32_t version;
+ /* The valid-after of the voting period we have prepared the state for. */
+ time_t valid_after;
+ /* Until when is this state valid? */
+ time_t valid_until;
+ /* Protocol phase. */
+ sr_phase_t phase;
+
+ /* Number of runs completed. */
+ uint64_t n_protocol_runs;
+ /* The number of commitment rounds we've performed in this protocol run. */
+ unsigned int n_commit_rounds;
+ /* The number of reveal rounds we've performed in this protocol run. */
+ unsigned int n_reveal_rounds;
+
+ /* A map of all the received commitments for this protocol run. This is
+ * indexed by authority RSA identity digest. */
+ digestmap_t *commits;
+
+ /* Current and previous shared random value. */
+ sr_srv_t *previous_srv;
+ sr_srv_t *current_srv;
+
+ /* Indicate if the state contains an SRV that was _just_ generated. This is
+ * used during voting so that we know whether to use the super majority rule
+ * or not when deciding on keeping it for the consensus. It is _always_ set
+ * to 0 post consensus.
+ *
+ * EDGE CASE: if an authority computes a new SRV then immediately reboots
+ * and, once back up, votes for the current round, it won't know if the
+ * SRV is fresh or not ultimately making it _NOT_ use the super majority
+ * when deciding to put or not the SRV in the consensus. This is for now
+ * an acceptable very rare edge case. */
+ unsigned int is_srv_fresh:1;
+} sr_state_t;
+
+/* Persistent state of the protocol, as saved to disk. */
+typedef struct sr_disk_state_t {
+ uint32_t magic_;
+ /* Version of the protocol. */
+ int Version;
+ /* Version of our running tor. */
+ char *TorVersion;
+ /* Creation time of this state */
+ time_t ValidAfter;
+ /* State valid until? */
+ time_t ValidUntil;
+ /* All commits seen that are valid. */
+ struct config_line_t *Commit;
+ /* Previous and current shared random value. */
+ struct config_line_t *SharedRandValues;
+ /* Extra Lines for configuration we might not know. */
+ struct config_line_t *ExtraLines;
+} sr_disk_state_t;
+
+/* API */
+
+/* Public methods: */
+
+void sr_state_update(time_t valid_after);
+
+/* Private methods (only used by shared-random.c): */
+
+void sr_state_set_valid_after(time_t valid_after);
+sr_phase_t sr_state_get_phase(void);
+const sr_srv_t *sr_state_get_previous_srv(void);
+const sr_srv_t *sr_state_get_current_srv(void);
+void sr_state_set_previous_srv(const sr_srv_t *srv);
+void sr_state_set_current_srv(const sr_srv_t *srv);
+void sr_state_clean_srvs(void);
+digestmap_t *sr_state_get_commits(void);
+sr_commit_t *sr_state_get_commit(const char *rsa_fpr);
+void sr_state_add_commit(sr_commit_t *commit);
+void sr_state_delete_commits(void);
+void sr_state_copy_reveal_info(sr_commit_t *saved_commit,
+ const sr_commit_t *commit);
+unsigned int sr_state_srv_is_fresh(void);
+void sr_state_set_fresh_srv(void);
+void sr_state_unset_fresh_srv(void);
+int sr_state_init(int save_to_disk, int read_from_disk);
+int sr_state_is_initialized(void);
+void sr_state_save(void);
+void sr_state_free_all(void);
+
+#ifdef SHARED_RANDOM_STATE_PRIVATE
+
+STATIC int disk_state_load_from_disk_impl(const char *fname);
+
+STATIC sr_phase_t get_sr_protocol_phase(time_t valid_after);
+
+STATIC time_t get_state_valid_until_time(time_t now);
+STATIC const char *get_phase_str(sr_phase_t phase);
+STATIC void reset_state_for_new_protocol_run(time_t valid_after);
+STATIC void new_protocol_run(time_t valid_after);
+STATIC void state_rotate_srv(void);
+STATIC int is_phase_transition(sr_phase_t next_phase);
+
+#endif /* defined(SHARED_RANDOM_STATE_PRIVATE) */
+
+#ifdef TOR_UNIT_TESTS
+
+STATIC void set_sr_phase(sr_phase_t phase);
+STATIC sr_state_t *get_sr_state(void);
++STATIC void state_del_previous_srv(void);
++STATIC void state_del_current_srv(void);
+
+#endif /* defined(TOR_UNIT_TESTS) */
+
+#endif /* !defined(TOR_SHARED_RANDOM_STATE_H) */
1
0

[tor/maint-0.4.0] test/sr: Clear SRVs after init, and before setup
by nickm@torproject.org 19 Mar '19
by nickm@torproject.org 19 Mar '19
19 Mar '19
commit c44ad396f89e755f5a639b382e0a55ed1cbcc177
Author: teor <teor(a)torproject.org>
Date: Mon Mar 18 11:12:25 2019 +1000
test/sr: Clear SRVs after init, and before setup
Already merged to 0.4.0 and later in tor-github/pr/776.
Backported to 0.2.9 and later with minor comment changes.
Part of 29706.
---
src/test/test_shared_random.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c
index 0a3c2e119..526fb09b6 100644
--- a/src/test/test_shared_random.c
+++ b/src/test/test_shared_random.c
@@ -54,6 +54,9 @@ init_authority_state(void)
* the phase we are currently in which uses "now" as the starting
* timestamp. Delete it before we do any testing below. */
sr_state_delete_commits();
+ /* It's also possible that a current SRV has been generated, if we are at
+ * state transition time. But let's just forget about that SRV. */
+ sr_state_clean_srvs();
done:
UNMOCK(get_my_v3_authority_cert);
@@ -449,20 +452,26 @@ test_encoding(void *arg)
;
}
-/** Setup some SRVs in our SR state. If <b>also_current</b> is set, then set
- * both current and previous SRVs.
- * Helper of test_vote() and test_sr_compute_srv(). */
+/** Setup some SRVs in our SR state.
+ * If <b>also_current</b> is set, then set both current and previous SRVs.
+ * Otherwise, just set the previous SRV. (And clear the current SRV.)
+ *
+ * You must call sr_state_free() to free the state at the end of each test
+ * function (on pass or fail). */
static void
test_sr_setup_srv(int also_current)
{
+ /* Clear both SRVs before starting.
+ * In 0.3.5 and earlier, sr_state_set_previous_srv() and
+ * sr_state_set_current_srv() do not free() the old srvs. */
+ sr_state_clean_srvs();
+
sr_srv_t *srv = tor_malloc_zero(sizeof(sr_srv_t));
srv->num_reveals = 42;
memcpy(srv->value,
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
sizeof(srv->value));
- /* sr_state_set_previous_srv() does not free() the old previous srv. */
- state_del_previous_srv();
sr_state_set_previous_srv(srv);
if (also_current) {
@@ -472,8 +481,6 @@ test_sr_setup_srv(int also_current)
"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
sizeof(srv->value));
- /* sr_state_set_previous_srv() does not free() the old current srv. */
- state_del_current_srv();
sr_state_set_current_srv(srv);
}
}
1
0

[tor/maint-0.4.0] Merge branch 'bug29706_035_minimal_merge' into bug29706_040_minimal_merge
by nickm@torproject.org 19 Mar '19
by nickm@torproject.org 19 Mar '19
19 Mar '19
commit af21d126e6b138c6f986f02c33c8c38d9bcd537f
Merge: 1547fd99a 55865a2c9
Author: teor <teor(a)torproject.org>
Date: Mon Mar 18 11:30:37 2019 +1000
Merge branch 'bug29706_035_minimal_merge' into bug29706_040_minimal_merge
Comment merge.
src/test/test_shared_random.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
1
0

[tor/maint-0.4.0] test/sr: update sr_state_free() to sr_state_free_all() in a comment
by nickm@torproject.org 19 Mar '19
by nickm@torproject.org 19 Mar '19
19 Mar '19
commit aec6ee201bbf63f54bcf879de10addf00779504c
Author: teor <teor(a)torproject.org>
Date: Mon Mar 18 11:28:34 2019 +1000
test/sr: update sr_state_free() to sr_state_free_all() in a comment
---
src/test/test_shared_random.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c
index 2d07eb219..630883e1f 100644
--- a/src/test/test_shared_random.c
+++ b/src/test/test_shared_random.c
@@ -551,7 +551,7 @@ test_encoding(void *arg)
* If <b>also_current</b> is set, then set both current and previous SRVs.
* Otherwise, just set the previous SRV. (And clear the current SRV.)
*
- * You must call sr_state_free() to free the state at the end of each test
+ * You must call sr_state_free_all() to free the state at the end of each test
* function (on pass or fail). */
static void
test_sr_setup_srv(int also_current)
1
0

[tor/maint-0.4.0] Merge remote-tracking branch 'tor-github/pr/802' into maint-0.4.0
by nickm@torproject.org 19 Mar '19
by nickm@torproject.org 19 Mar '19
19 Mar '19
commit de5ab1ef49559ed24b639bbf052ea584db2f2b77
Merge: b4483edce af21d126e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Mar 19 09:32:05 2019 -0400
Merge remote-tracking branch 'tor-github/pr/802' into maint-0.4.0
src/test/test_shared_random.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
1
0

[tor/master] Merge branch 'bug29706_034_minimal_merge' into bug29706_035_minimal_merge
by nickm@torproject.org 19 Mar '19
by nickm@torproject.org 19 Mar '19
19 Mar '19
commit 55865a2c9c9929b690a4f5a969afd5d4415c40bd
Merge: 5d41e2223 aec6ee201
Author: teor <teor(a)torproject.org>
Date: Mon Mar 18 11:29:20 2019 +1000
Merge branch 'bug29706_034_minimal_merge' into bug29706_035_minimal_merge
changes/bug29706_minimal | 4 ++++
src/feature/dirauth/shared_random_state.c | 4 ++--
src/feature/dirauth/shared_random_state.h | 2 ++
src/test/test_shared_random.c | 17 ++++++++++++++---
4 files changed, 22 insertions(+), 5 deletions(-)
diff --cc src/feature/dirauth/shared_random_state.c
index 2bc030f4a,000000000..b3e4a4ef9
mode 100644,000000..100644
--- a/src/feature/dirauth/shared_random_state.c
+++ b/src/feature/dirauth/shared_random_state.c
@@@ -1,1340 -1,0 +1,1340 @@@
+/* Copyright (c) 2016-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file shared_random_state.c
+ *
+ * \brief Functions and data structures for the state of the random protocol
+ * as defined in proposal #250.
+ **/
+
+#define SHARED_RANDOM_STATE_PRIVATE
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "lib/crypt_ops/crypto_util.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/relay/router.h"
+#include "feature/dirauth/shared_random.h"
+#include "feature/hs_common/shared_random_client.h"
+#include "feature/dirauth/shared_random_state.h"
+#include "feature/dircommon/voting_schedule.h"
+#include "lib/encoding/confline.h"
+
+#include "app/config/or_state_st.h"
+
+/* Default filename of the shared random state on disk. */
+static const char default_fname[] = "sr-state";
+
+/* String representation of a protocol phase. */
+static const char *phase_str[] = { "unknown", "commit", "reveal" };
+
+/* Our shared random protocol state. There is only one possible state per
+ * protocol run so this is the global state which is reset at every run once
+ * the shared random value has been computed. */
+static sr_state_t *sr_state = NULL;
+
+/* Representation of our persistent state on disk. The sr_state above
+ * contains the data parsed from this state. When we save to disk, we
+ * translate the sr_state to this sr_disk_state. */
+static sr_disk_state_t *sr_disk_state = NULL;
+
+/* Disk state file keys. */
+static const char dstate_commit_key[] = "Commit";
+static const char dstate_prev_srv_key[] = "SharedRandPreviousValue";
+static const char dstate_cur_srv_key[] = "SharedRandCurrentValue";
+
+/** dummy instance of sr_disk_state_t, used for type-checking its
+ * members with CONF_CHECK_VAR_TYPE. */
+DUMMY_TYPECHECK_INSTANCE(sr_disk_state_t);
+
+/* These next two are duplicates or near-duplicates from config.c */
+#define VAR(name, conftype, member, initvalue) \
+ { name, CONFIG_TYPE_ ## conftype, offsetof(sr_disk_state_t, member), \
+ initvalue CONF_TEST_MEMBERS(sr_disk_state_t, conftype, member) }
+/* As VAR, but the option name and member name are the same. */
+#define V(member, conftype, initvalue) \
+ VAR(#member, conftype, member, initvalue)
+/* Our persistent state magic number. */
+#define SR_DISK_STATE_MAGIC 0x98AB1254
+
+static int
+disk_state_validate_cb(void *old_state, void *state, void *default_state,
+ int from_setconf, char **msg);
+static void disk_state_free_cb(void *);
+
+/* Array of variables that are saved to disk as a persistent state. */
+static config_var_t state_vars[] = {
+ V(Version, UINT, "0"),
+ V(TorVersion, STRING, NULL),
+ V(ValidAfter, ISOTIME, NULL),
+ V(ValidUntil, ISOTIME, NULL),
+
+ V(Commit, LINELIST, NULL),
+
+ V(SharedRandValues, LINELIST_V, NULL),
+ VAR("SharedRandPreviousValue",LINELIST_S, SharedRandValues, NULL),
+ VAR("SharedRandCurrentValue", LINELIST_S, SharedRandValues, NULL),
+ END_OF_CONFIG_VARS
+};
+
+/* "Extra" variable in the state that receives lines we can't parse. This
+ * lets us preserve options from versions of Tor newer than us. */
+static config_var_t state_extra_var = {
+ "__extra", CONFIG_TYPE_LINELIST,
+ offsetof(sr_disk_state_t, ExtraLines), NULL
+ CONF_TEST_MEMBERS(sr_disk_state_t, LINELIST, ExtraLines)
+};
+
+/* Configuration format of sr_disk_state_t. */
+static const config_format_t state_format = {
+ sizeof(sr_disk_state_t),
+ SR_DISK_STATE_MAGIC,
+ offsetof(sr_disk_state_t, magic_),
+ NULL,
+ NULL,
+ state_vars,
+ disk_state_validate_cb,
+ disk_state_free_cb,
+ &state_extra_var,
+};
+
+/* Return a string representation of a protocol phase. */
+STATIC const char *
+get_phase_str(sr_phase_t phase)
+{
+ const char *the_string = NULL;
+
+ switch (phase) {
+ case SR_PHASE_COMMIT:
+ case SR_PHASE_REVEAL:
+ the_string = phase_str[phase];
+ break;
+ default:
+ /* Unknown phase shouldn't be possible. */
+ tor_assert(0);
+ }
+
+ return the_string;
+}
+/* Return the time we should expire the state file created at <b>now</b>.
+ * We expire the state file in the beginning of the next protocol run. */
+STATIC time_t
+get_state_valid_until_time(time_t now)
+{
+ int total_rounds = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
+ int current_round, voting_interval, rounds_left;
+ time_t valid_until, beginning_of_current_round;
+
+ voting_interval = get_voting_interval();
+ /* Find the time the current round started. */
+ beginning_of_current_round = get_start_time_of_current_round();
+
+ /* Find how many rounds are left till the end of the protocol run */
+ current_round = (now / voting_interval) % total_rounds;
+ rounds_left = total_rounds - current_round;
+
+ /* To find the valid-until time now, take the start time of the current
+ * round and add to it the time it takes for the leftover rounds to
+ * complete. */
+ valid_until = beginning_of_current_round + (rounds_left * voting_interval);
+
+ { /* Logging */
+ char tbuf[ISO_TIME_LEN + 1];
+ format_iso_time(tbuf, valid_until);
+ log_debug(LD_DIR, "SR: Valid until time for state set to %s.", tbuf);
+ }
+
+ return valid_until;
+}
+
+/* Given the consensus 'valid-after' time, return the protocol phase we should
+ * be in. */
+STATIC sr_phase_t
+get_sr_protocol_phase(time_t valid_after)
+{
+ /* Shared random protocol has two phases, commit and reveal. */
+ int total_periods = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
+ int current_slot;
+
+ /* Split time into slots of size 'voting_interval'. See which slot we are
+ * currently into, and find which phase it corresponds to. */
+ current_slot = (valid_after / get_voting_interval()) % total_periods;
+
+ if (current_slot < SHARED_RANDOM_N_ROUNDS) {
+ return SR_PHASE_COMMIT;
+ } else {
+ return SR_PHASE_REVEAL;
+ }
+}
+
+/* Add the given <b>commit</b> to <b>state</b>. It MUST be a valid commit
+ * and there shouldn't be a commit from the same authority in the state
+ * already else verification hasn't been done prior. This takes ownership of
+ * the commit once in our state. */
+static void
+commit_add_to_state(sr_commit_t *commit, sr_state_t *state)
+{
+ sr_commit_t *saved_commit;
+
+ tor_assert(commit);
+ tor_assert(state);
+
+ saved_commit = digestmap_set(state->commits, commit->rsa_identity,
+ commit);
+ if (saved_commit != NULL) {
+ /* This means we already have that commit in our state so adding twice
+ * the same commit is either a code flow error, a corrupted disk state
+ * or some new unknown issue. */
+ log_warn(LD_DIR, "SR: Commit from %s exists in our state while "
+ "adding it: '%s'", sr_commit_get_rsa_fpr(commit),
+ commit->encoded_commit);
+ sr_commit_free(saved_commit);
+ }
+}
+
+/* Helper: deallocate a commit object. (Used with digestmap_free(), which
+ * requires a function pointer whose argument is void *). */
+static void
+commit_free_(void *p)
+{
+ sr_commit_free_(p);
+}
+
+#define state_free(val) \
+ FREE_AND_NULL(sr_state_t, state_free_, (val))
+
+/* Free a state that was allocated with state_new(). */
+static void
+state_free_(sr_state_t *state)
+{
+ if (state == NULL) {
+ return;
+ }
+ tor_free(state->fname);
+ digestmap_free(state->commits, commit_free_);
+ tor_free(state->current_srv);
+ tor_free(state->previous_srv);
+ tor_free(state);
+}
+
+/* Allocate an sr_state_t object and returns it. If no <b>fname</b>, the
+ * default file name is used. This function does NOT initialize the state
+ * timestamp, phase or shared random value. NULL is never returned. */
+static sr_state_t *
+state_new(const char *fname, time_t now)
+{
+ sr_state_t *new_state = tor_malloc_zero(sizeof(*new_state));
+ /* If file name is not provided, use default. */
+ if (fname == NULL) {
+ fname = default_fname;
+ }
+ new_state->fname = tor_strdup(fname);
+ new_state->version = SR_PROTO_VERSION;
+ new_state->commits = digestmap_new();
+ new_state->phase = get_sr_protocol_phase(now);
+ new_state->valid_until = get_state_valid_until_time(now);
+ return new_state;
+}
+
+/* Set our global state pointer with the one given. */
+static void
+state_set(sr_state_t *state)
+{
+ tor_assert(state);
+ if (sr_state != NULL) {
+ state_free(sr_state);
+ }
+ sr_state = state;
+}
+
+#define disk_state_free(val) \
+ FREE_AND_NULL(sr_disk_state_t, disk_state_free_, (val))
+
+/* Free an allocated disk state. */
+static void
+disk_state_free_(sr_disk_state_t *state)
+{
+ if (state == NULL) {
+ return;
+ }
+ config_free(&state_format, state);
+}
+
+/* Allocate a new disk state, initialize it and return it. */
+static sr_disk_state_t *
+disk_state_new(time_t now)
+{
+ sr_disk_state_t *new_state = tor_malloc_zero(sizeof(*new_state));
+
+ new_state->magic_ = SR_DISK_STATE_MAGIC;
+ new_state->Version = SR_PROTO_VERSION;
+ new_state->TorVersion = tor_strdup(get_version());
+ new_state->ValidUntil = get_state_valid_until_time(now);
+ new_state->ValidAfter = now;
+
+ /* Init config format. */
+ config_init(&state_format, new_state);
+ return new_state;
+}
+
+/* Set our global disk state with the given state. */
+static void
+disk_state_set(sr_disk_state_t *state)
+{
+ tor_assert(state);
+ if (sr_disk_state != NULL) {
+ disk_state_free(sr_disk_state);
+ }
+ sr_disk_state = state;
+}
+
+/* Return -1 if the disk state is invalid (something in there that we can't or
+ * shouldn't use). Return 0 if everything checks out. */
+static int
+disk_state_validate(const sr_disk_state_t *state)
+{
+ time_t now;
+
+ tor_assert(state);
+
+ /* Do we support the protocol version in the state or is it 0 meaning
+ * Version wasn't found in the state file or bad anyway ? */
+ if (state->Version == 0 || state->Version > SR_PROTO_VERSION) {
+ goto invalid;
+ }
+
+ /* If the valid until time is before now, we shouldn't use that state. */
+ now = time(NULL);
+ if (state->ValidUntil < now) {
+ log_info(LD_DIR, "SR: Disk state has expired. Ignoring it.");
+ goto invalid;
+ }
+
+ /* Make sure we don't have a valid after time that is earlier than a valid
+ * until time which would make things not work well. */
+ if (state->ValidAfter >= state->ValidUntil) {
+ log_info(LD_DIR, "SR: Disk state valid after/until times are invalid.");
+ goto invalid;
+ }
+
+ return 0;
+
+ invalid:
+ return -1;
+}
+
+/* Validate the disk state (NOP for now). */
+static int
+disk_state_validate_cb(void *old_state, void *state, void *default_state,
+ int from_setconf, char **msg)
+{
+ /* We don't use these; only options do. */
+ (void) from_setconf;
+ (void) default_state;
+ (void) old_state;
+
+ /* This is called by config_dump which is just before we are about to
+ * write it to disk. At that point, our global memory state has been
+ * copied to the disk state so it's fair to assume it's trustable. */
+ (void) state;
+ (void) msg;
+ return 0;
+}
+
+static void
+disk_state_free_cb(void *state)
+{
+ disk_state_free_(state);
+}
+
+/* Parse the Commit line(s) in the disk state and translate them to the
+ * the memory state. Return 0 on success else -1 on error. */
+static int
+disk_state_parse_commits(sr_state_t *state,
+ const sr_disk_state_t *disk_state)
+{
+ config_line_t *line;
+ smartlist_t *args = NULL;
+
+ tor_assert(state);
+ tor_assert(disk_state);
+
+ for (line = disk_state->Commit; line; line = line->next) {
+ sr_commit_t *commit = NULL;
+
+ /* Extra safety. */
+ if (strcasecmp(line->key, dstate_commit_key) ||
+ line->value == NULL) {
+ /* Ignore any lines that are not commits. */
+ tor_fragile_assert();
+ continue;
+ }
+ args = smartlist_new();
+ smartlist_split_string(args, line->value, " ",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ if (smartlist_len(args) < 3) {
+ log_warn(LD_BUG, "SR: Too few arguments in Commit Line: %s",
+ escaped(line->value));
+ goto error;
+ }
+ commit = sr_parse_commit(args);
+ if (commit == NULL) {
+ /* Ignore badly formed commit. It could also be a authority
+ * fingerprint that we don't know about so it shouldn't be used. */
+ smartlist_free(args);
+ continue;
+ }
+ /* We consider parseable commit from our disk state to be valid because
+ * they need to be in the first place to get in there. */
+ commit->valid = 1;
+ /* Add commit to our state pointer. */
+ commit_add_to_state(commit, state);
+
+ SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+ smartlist_free(args);
+ }
+
+ return 0;
+
+ error:
+ SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+ smartlist_free(args);
+ return -1;
+}
+
+/* Parse a share random value line from the disk state and save it to dst
+ * which is an allocated srv object. Return 0 on success else -1. */
+static int
+disk_state_parse_srv(const char *value, sr_srv_t *dst)
+{
+ int ret = -1;
+ smartlist_t *args;
+ sr_srv_t *srv;
+
+ tor_assert(value);
+ tor_assert(dst);
+
+ args = smartlist_new();
+ smartlist_split_string(args, value, " ",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ if (smartlist_len(args) < 2) {
+ log_warn(LD_BUG, "SR: Too few arguments in shared random value. "
+ "Line: %s", escaped(value));
+ goto error;
+ }
+ srv = sr_parse_srv(args);
+ if (srv == NULL) {
+ goto error;
+ }
+ dst->num_reveals = srv->num_reveals;
+ memcpy(dst->value, srv->value, sizeof(dst->value));
+ tor_free(srv);
+ ret = 0;
+
+ error:
+ SMARTLIST_FOREACH(args, char *, s, tor_free(s));
+ smartlist_free(args);
+ return ret;
+}
+
+/* Parse both SharedRandCurrentValue and SharedRandPreviousValue line from
+ * the state. Return 0 on success else -1. */
+static int
+disk_state_parse_sr_values(sr_state_t *state,
+ const sr_disk_state_t *disk_state)
+{
+ /* Only one value per type (current or previous) is allowed so we keep
+ * track of it with these flag. */
+ unsigned int seen_previous = 0, seen_current = 0;
+ config_line_t *line;
+ sr_srv_t *srv = NULL;
+
+ tor_assert(state);
+ tor_assert(disk_state);
+
+ for (line = disk_state->SharedRandValues; line; line = line->next) {
+ if (line->value == NULL) {
+ continue;
+ }
+ srv = tor_malloc_zero(sizeof(*srv));
+ if (disk_state_parse_srv(line->value, srv) < 0) {
+ log_warn(LD_BUG, "SR: Broken current SRV line in state %s",
+ escaped(line->value));
+ goto bad;
+ }
+ if (!strcasecmp(line->key, dstate_prev_srv_key)) {
+ if (seen_previous) {
+ log_warn(LD_DIR, "SR: Second previous SRV value seen. Bad state");
+ goto bad;
+ }
+ state->previous_srv = srv;
+ seen_previous = 1;
+ } else if (!strcasecmp(line->key, dstate_cur_srv_key)) {
+ if (seen_current) {
+ log_warn(LD_DIR, "SR: Second current SRV value seen. Bad state");
+ goto bad;
+ }
+ state->current_srv = srv;
+ seen_current = 1;
+ } else {
+ /* Unknown key. Ignoring. */
+ tor_free(srv);
+ }
+ }
+
+ return 0;
+ bad:
+ tor_free(srv);
+ return -1;
+}
+
+/* Parse the given disk state and set a newly allocated state. On success,
+ * return that state else NULL. */
+static sr_state_t *
+disk_state_parse(const sr_disk_state_t *new_disk_state)
+{
+ sr_state_t *new_state = state_new(default_fname, time(NULL));
+
+ tor_assert(new_disk_state);
+
+ new_state->version = new_disk_state->Version;
+ new_state->valid_until = new_disk_state->ValidUntil;
+ new_state->valid_after = new_disk_state->ValidAfter;
+
+ /* Set our current phase according to the valid-after time in our disk
+ * state. The disk state we are parsing contains everything for the phase
+ * starting at valid_after so make sure our phase reflects that. */
+ new_state->phase = get_sr_protocol_phase(new_state->valid_after);
+
+ /* Parse the shared random values. */
+ if (disk_state_parse_sr_values(new_state, new_disk_state) < 0) {
+ goto error;
+ }
+ /* Parse the commits. */
+ if (disk_state_parse_commits(new_state, new_disk_state) < 0) {
+ goto error;
+ }
+ /* Great! This new state contains everything we had on disk. */
+ return new_state;
+
+ error:
+ state_free(new_state);
+ return NULL;
+}
+
+/* From a valid commit object and an allocated config line, set the line's
+ * value to the state string representation of a commit. */
+static void
+disk_state_put_commit_line(const sr_commit_t *commit, config_line_t *line)
+{
+ char *reveal_str = NULL;
+
+ tor_assert(commit);
+ tor_assert(line);
+
+ if (!tor_mem_is_zero(commit->encoded_reveal,
+ sizeof(commit->encoded_reveal))) {
+ /* Add extra whitespace so we can format the line correctly. */
+ tor_asprintf(&reveal_str, " %s", commit->encoded_reveal);
+ }
+ tor_asprintf(&line->value, "%u %s %s %s%s",
+ SR_PROTO_VERSION,
+ crypto_digest_algorithm_get_name(commit->alg),
+ sr_commit_get_rsa_fpr(commit),
+ commit->encoded_commit,
+ reveal_str != NULL ? reveal_str : "");
+ if (reveal_str != NULL) {
+ memwipe(reveal_str, 0, strlen(reveal_str));
+ tor_free(reveal_str);
+ }
+}
+
+/* From a valid srv object and an allocated config line, set the line's
+ * value to the state string representation of a shared random value. */
+static void
+disk_state_put_srv_line(const sr_srv_t *srv, config_line_t *line)
+{
+ char encoded[SR_SRV_VALUE_BASE64_LEN + 1];
+
+ tor_assert(line);
+
+ /* No SRV value thus don't add the line. This is possible since we might
+ * not have a current or previous SRV value in our state. */
+ if (srv == NULL) {
+ return;
+ }
+ sr_srv_encode(encoded, sizeof(encoded), srv);
+ tor_asprintf(&line->value, "%" PRIu64 " %s", srv->num_reveals, encoded);
+}
+
+/* Reset disk state that is free allocated memory and zeroed the object. */
+static void
+disk_state_reset(void)
+{
+ /* Free allocated memory */
+ config_free_lines(sr_disk_state->Commit);
+ config_free_lines(sr_disk_state->SharedRandValues);
+ config_free_lines(sr_disk_state->ExtraLines);
+ tor_free(sr_disk_state->TorVersion);
+
+ /* Clean up the struct */
+ memset(sr_disk_state, 0, sizeof(*sr_disk_state));
+
+ /* Reset it with useful data */
+ sr_disk_state->magic_ = SR_DISK_STATE_MAGIC;
+ sr_disk_state->TorVersion = tor_strdup(get_version());
+}
+
+/* Update our disk state based on our global SR state. */
+static void
+disk_state_update(void)
+{
+ config_line_t **next, *line;
+
+ if (BUG(!sr_disk_state))
+ return;
+ if (BUG(!sr_state))
+ return;
+
+ /* Reset current disk state. */
+ disk_state_reset();
+
+ /* First, update elements that we don't need to do a construction. */
+ sr_disk_state->Version = sr_state->version;
+ sr_disk_state->ValidUntil = sr_state->valid_until;
+ sr_disk_state->ValidAfter = sr_state->valid_after;
+
+ /* Shared random values. */
+ next = &sr_disk_state->SharedRandValues;
+ if (sr_state->previous_srv != NULL) {
+ *next = line = tor_malloc_zero(sizeof(config_line_t));
+ line->key = tor_strdup(dstate_prev_srv_key);
+ disk_state_put_srv_line(sr_state->previous_srv, line);
+ /* Go to the next shared random value. */
+ next = &(line->next);
+ }
+ if (sr_state->current_srv != NULL) {
+ *next = line = tor_malloc_zero(sizeof(*line));
+ line->key = tor_strdup(dstate_cur_srv_key);
+ disk_state_put_srv_line(sr_state->current_srv, line);
+ }
+
+ /* Parse the commits and construct config line(s). */
+ next = &sr_disk_state->Commit;
+ DIGESTMAP_FOREACH(sr_state->commits, key, sr_commit_t *, commit) {
+ *next = line = tor_malloc_zero(sizeof(*line));
+ line->key = tor_strdup(dstate_commit_key);
+ disk_state_put_commit_line(commit, line);
+ next = &(line->next);
+ } DIGESTMAP_FOREACH_END;
+}
+
+/* Load state from disk and put it into our disk state. If the state passes
+ * validation, our global state will be updated with it. Return 0 on
+ * success. On error, -EINVAL is returned if the state on disk did contained
+ * something malformed or is unreadable. -ENOENT is returned indicating that
+ * the state file is either empty of non existing. */
+static int
+disk_state_load_from_disk(void)
+{
+ int ret;
+ char *fname;
+
+ fname = get_datadir_fname(default_fname);
+ ret = disk_state_load_from_disk_impl(fname);
+ tor_free(fname);
+
+ return ret;
+}
+
+/* Helper for disk_state_load_from_disk(). */
+STATIC int
+disk_state_load_from_disk_impl(const char *fname)
+{
+ int ret;
+ char *content = NULL;
+ sr_state_t *parsed_state = NULL;
+ sr_disk_state_t *disk_state = NULL;
+
+ /* Read content of file so we can parse it. */
+ if ((content = read_file_to_str(fname, 0, NULL)) == NULL) {
+ log_warn(LD_FS, "SR: Unable to read SR state file %s",
+ escaped(fname));
+ ret = -errno;
+ goto error;
+ }
+
+ {
+ config_line_t *lines = NULL;
+ char *errmsg = NULL;
+
+ /* Every error in this code path will return EINVAL. */
+ ret = -EINVAL;
+ if (config_get_lines(content, &lines, 0) < 0) {
+ config_free_lines(lines);
+ goto error;
+ }
+
+ disk_state = disk_state_new(time(NULL));
+ config_assign(&state_format, disk_state, lines, 0, &errmsg);
+ config_free_lines(lines);
+ if (errmsg) {
+ log_warn(LD_DIR, "SR: Reading state error: %s", errmsg);
+ tor_free(errmsg);
+ goto error;
+ }
+ }
+
+ /* So far so good, we've loaded our state file into our disk state. Let's
+ * validate it and then parse it. */
+ if (disk_state_validate(disk_state) < 0) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ parsed_state = disk_state_parse(disk_state);
+ if (parsed_state == NULL) {
+ ret = -EINVAL;
+ goto error;
+ }
+ state_set(parsed_state);
+ disk_state_set(disk_state);
+ tor_free(content);
+ log_info(LD_DIR, "SR: State loaded successfully from file %s", fname);
+ return 0;
+
+ error:
+ disk_state_free(disk_state);
+ tor_free(content);
+ return ret;
+}
+
+/* Save the disk state to disk but before that update it from the current
+ * state so we always have the latest. Return 0 on success else -1. */
+static int
+disk_state_save_to_disk(void)
+{
+ int ret;
+ char *state, *content = NULL, *fname = NULL;
+ char tbuf[ISO_TIME_LEN + 1];
+ time_t now = time(NULL);
+
+ /* If we didn't have the opportunity to setup an internal disk state,
+ * don't bother saving something to disk. */
+ if (sr_disk_state == NULL) {
+ ret = 0;
+ goto done;
+ }
+
+ /* Make sure that our disk state is up to date with our memory state
+ * before saving it to disk. */
+ disk_state_update();
+ state = config_dump(&state_format, NULL, sr_disk_state, 0, 0);
+ format_local_iso_time(tbuf, now);
+ tor_asprintf(&content,
+ "# Tor shared random state file last generated on %s "
+ "local time\n"
+ "# Other times below are in UTC\n"
+ "# Please *do not* edit this file.\n\n%s",
+ tbuf, state);
+ tor_free(state);
+ fname = get_datadir_fname(default_fname);
+ if (write_str_to_file(fname, content, 0) < 0) {
+ log_warn(LD_FS, "SR: Unable to write SR state to file %s", fname);
+ ret = -1;
+ goto done;
+ }
+ ret = 0;
+ log_debug(LD_DIR, "SR: Saved state to file %s", fname);
+
+ done:
+ tor_free(fname);
+ tor_free(content);
+ return ret;
+}
+
+/* Reset our state to prepare for a new protocol run. Once this returns, all
+ * commits in the state will be removed and freed. */
+STATIC void
+reset_state_for_new_protocol_run(time_t valid_after)
+{
+ if (BUG(!sr_state))
+ return;
+
+ /* Keep counters in track */
+ sr_state->n_reveal_rounds = 0;
+ sr_state->n_commit_rounds = 0;
+ sr_state->n_protocol_runs++;
+
+ /* Reset valid-until */
+ sr_state->valid_until = get_state_valid_until_time(valid_after);
+ sr_state->valid_after = valid_after;
+
+ /* We are in a new protocol run so cleanup commits. */
+ sr_state_delete_commits();
+}
+
+/* This is the first round of the new protocol run starting at
+ * <b>valid_after</b>. Do the necessary housekeeping. */
+STATIC void
+new_protocol_run(time_t valid_after)
+{
+ sr_commit_t *our_commitment = NULL;
+
+ /* Only compute the srv at the end of the reveal phase. */
+ if (sr_state->phase == SR_PHASE_REVEAL) {
+ /* We are about to compute a new shared random value that will be set in
+ * our state as the current value so rotate values. */
+ state_rotate_srv();
+ /* Compute the shared randomness value of the day. */
+ sr_compute_srv();
+ }
+
+ /* Prepare for the new protocol run by reseting the state */
+ reset_state_for_new_protocol_run(valid_after);
+
+ /* Do some logging */
+ log_info(LD_DIR, "SR: Protocol run #%" PRIu64 " starting!",
+ sr_state->n_protocol_runs);
+
+ /* Generate fresh commitments for this protocol run */
+ our_commitment = sr_generate_our_commit(valid_after,
+ get_my_v3_authority_cert());
+ if (our_commitment) {
+ /* Add our commitment to our state. In case we are unable to create one
+ * (highly unlikely), we won't vote for this protocol run since our
+ * commitment won't be in our state. */
+ sr_state_add_commit(our_commitment);
+ }
+}
+
+/* Return 1 iff the <b>next_phase</b> is a phase transition from the current
+ * phase that is it's different. */
+STATIC int
+is_phase_transition(sr_phase_t next_phase)
+{
+ return sr_state->phase != next_phase;
+}
+
+/* Helper function: return a commit using the RSA fingerprint of the
+ * authority or NULL if no such commit is known. */
+static sr_commit_t *
+state_query_get_commit(const char *rsa_fpr)
+{
+ tor_assert(rsa_fpr);
+ return digestmap_get(sr_state->commits, rsa_fpr);
+}
+
+/* Helper function: This handles the GET state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void *
+state_query_get_(sr_state_object_t obj_type, const void *data)
+{
+ void *obj = NULL;
+
+ switch (obj_type) {
+ case SR_STATE_OBJ_COMMIT:
+ {
+ obj = state_query_get_commit(data);
+ break;
+ }
+ case SR_STATE_OBJ_COMMITS:
+ obj = sr_state->commits;
+ break;
+ case SR_STATE_OBJ_CURSRV:
+ obj = sr_state->current_srv;
+ break;
+ case SR_STATE_OBJ_PREVSRV:
+ obj = sr_state->previous_srv;
+ break;
+ case SR_STATE_OBJ_PHASE:
+ obj = &sr_state->phase;
+ break;
+ case SR_STATE_OBJ_VALID_AFTER:
+ default:
+ tor_assert(0);
+ }
+ return obj;
+}
+
+/* Helper function: This handles the PUT state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void
+state_query_put_(sr_state_object_t obj_type, void *data)
+{
+ switch (obj_type) {
+ case SR_STATE_OBJ_COMMIT:
+ {
+ sr_commit_t *commit = data;
+ tor_assert(commit);
+ commit_add_to_state(commit, sr_state);
+ break;
+ }
+ case SR_STATE_OBJ_CURSRV:
+ sr_state->current_srv = (sr_srv_t *) data;
+ break;
+ case SR_STATE_OBJ_PREVSRV:
+ sr_state->previous_srv = (sr_srv_t *) data;
+ break;
+ case SR_STATE_OBJ_VALID_AFTER:
+ sr_state->valid_after = *((time_t *) data);
+ break;
+ /* It's not allowed to change the phase nor the full commitments map from
+ * the state. The phase is decided during a strict process post voting and
+ * the commits should be put individually. */
+ case SR_STATE_OBJ_PHASE:
+ case SR_STATE_OBJ_COMMITS:
+ default:
+ tor_assert(0);
+ }
+}
+
+/* Helper function: This handles the DEL_ALL state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void
+state_query_del_all_(sr_state_object_t obj_type)
+{
+ switch (obj_type) {
+ case SR_STATE_OBJ_COMMIT:
+ {
+ /* We are in a new protocol run so cleanup commitments. */
+ DIGESTMAP_FOREACH_MODIFY(sr_state->commits, key, sr_commit_t *, c) {
+ sr_commit_free(c);
+ MAP_DEL_CURRENT(key);
+ } DIGESTMAP_FOREACH_END;
+ break;
+ }
+ /* The following object are _NOT_ suppose to be removed. */
+ case SR_STATE_OBJ_CURSRV:
+ case SR_STATE_OBJ_PREVSRV:
+ case SR_STATE_OBJ_PHASE:
+ case SR_STATE_OBJ_COMMITS:
+ case SR_STATE_OBJ_VALID_AFTER:
+ default:
+ tor_assert(0);
+ }
+}
+
+/* Helper function: This handles the DEL state action using an
+ * <b>obj_type</b> and <b>data</b> needed for the action. */
+static void
+state_query_del_(sr_state_object_t obj_type, void *data)
+{
+ (void) data;
+
+ switch (obj_type) {
+ case SR_STATE_OBJ_PREVSRV:
+ tor_free(sr_state->previous_srv);
+ break;
+ case SR_STATE_OBJ_CURSRV:
+ tor_free(sr_state->current_srv);
+ break;
+ case SR_STATE_OBJ_COMMIT:
+ case SR_STATE_OBJ_COMMITS:
+ case SR_STATE_OBJ_PHASE:
+ case SR_STATE_OBJ_VALID_AFTER:
+ default:
+ tor_assert(0);
+ }
+}
+
+/* Query state using an <b>action</b> for an object type <b>obj_type</b>.
+ * The <b>data</b> pointer needs to point to an object that the action needs
+ * to use and if anything is required to be returned, it is stored in
+ * <b>out</b>.
+ *
+ * This mechanism exists so we have one single point where we synchronized
+ * our memory state with our disk state for every actions that changes it.
+ * We then trigger a write on disk immediately.
+ *
+ * This should be the only entry point to our memory state. It's used by all
+ * our state accessors and should be in the future. */
+static void
+state_query(sr_state_action_t action, sr_state_object_t obj_type,
+ void *data, void **out)
+{
+ switch (action) {
+ case SR_STATE_ACTION_GET:
+ *out = state_query_get_(obj_type, data);
+ break;
+ case SR_STATE_ACTION_PUT:
+ state_query_put_(obj_type, data);
+ break;
+ case SR_STATE_ACTION_DEL:
+ state_query_del_(obj_type, data);
+ break;
+ case SR_STATE_ACTION_DEL_ALL:
+ state_query_del_all_(obj_type);
+ break;
+ case SR_STATE_ACTION_SAVE:
+ /* Only trigger a disk state save. */
+ break;
+ default:
+ tor_assert(0);
+ }
+
+ /* If the action actually changes the state, immediately save it to disk.
+ * The following will sync the state -> disk state and then save it. */
+ if (action != SR_STATE_ACTION_GET) {
+ disk_state_save_to_disk();
+ }
+}
+
+/* Delete the current SRV value from the state freeing it and the value is set
+ * to NULL meaning empty. */
- static void
++STATIC void
+state_del_current_srv(void)
+{
+ state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_CURSRV, NULL, NULL);
+}
+
+/* Delete the previous SRV value from the state freeing it and the value is
+ * set to NULL meaning empty. */
- static void
++STATIC void
+state_del_previous_srv(void)
+{
+ state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_PREVSRV, NULL, NULL);
+}
+
+/* Rotate SRV value by freeing the previous value, assigning the current
+ * value to the previous one and nullifying the current one. */
+STATIC void
+state_rotate_srv(void)
+{
+ /* First delete previous SRV from the state. Object will be freed. */
+ state_del_previous_srv();
+ /* Set previous SRV with the current one. */
+ sr_state_set_previous_srv(sr_state_get_current_srv());
+ /* Nullify the current srv. */
+ sr_state_set_current_srv(NULL);
+}
+
+/* Set valid after time in the our state. */
+void
+sr_state_set_valid_after(time_t valid_after)
+{
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_VALID_AFTER,
+ (void *) &valid_after, NULL);
+}
+
+/* Return the phase we are currently in according to our state. */
+sr_phase_t
+sr_state_get_phase(void)
+{
+ void *ptr;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_PHASE, NULL, &ptr);
+ return *(sr_phase_t *) ptr;
+}
+
+/* Return the previous SRV value from our state. Value CAN be NULL. */
+const sr_srv_t *
+sr_state_get_previous_srv(void)
+{
+ const sr_srv_t *srv;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_PREVSRV, NULL,
+ (void *) &srv);
+ return srv;
+}
+
+/* Set the current SRV value from our state. Value CAN be NULL. The srv
+ * object ownership is transferred to the state object. */
+void
+sr_state_set_previous_srv(const sr_srv_t *srv)
+{
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_PREVSRV, (void *) srv,
+ NULL);
+}
+
+/* Return the current SRV value from our state. Value CAN be NULL. */
+const sr_srv_t *
+sr_state_get_current_srv(void)
+{
+ const sr_srv_t *srv;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_CURSRV, NULL,
+ (void *) &srv);
+ return srv;
+}
+
+/* Set the current SRV value from our state. Value CAN be NULL. The srv
+ * object ownership is transferred to the state object. */
+void
+sr_state_set_current_srv(const sr_srv_t *srv)
+{
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_CURSRV, (void *) srv,
+ NULL);
+}
+
+/* Clean all the SRVs in our state. */
+void
+sr_state_clean_srvs(void)
+{
+ /* Remove SRVs from state. They will be set to NULL as "empty". */
+ state_del_previous_srv();
+ state_del_current_srv();
+}
+
+/* Return a pointer to the commits map from our state. CANNOT be NULL. */
+digestmap_t *
+sr_state_get_commits(void)
+{
+ digestmap_t *commits;
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_COMMITS,
+ NULL, (void *) &commits);
+ tor_assert(commits);
+ return commits;
+}
+
+/* Update the current SR state as needed for the upcoming voting round at
+ * <b>valid_after</b>. */
+void
+sr_state_update(time_t valid_after)
+{
+ sr_phase_t next_phase;
+
+ if (BUG(!sr_state))
+ return;
+
+ /* Don't call this function twice in the same voting period. */
+ if (valid_after <= sr_state->valid_after) {
+ log_info(LD_DIR, "SR: Asked to update state twice. Ignoring.");
+ return;
+ }
+
+ /* Get phase of upcoming round. */
+ next_phase = get_sr_protocol_phase(valid_after);
+
+ /* If we are transitioning to a new protocol phase, prepare the stage. */
+ if (is_phase_transition(next_phase)) {
+ if (next_phase == SR_PHASE_COMMIT) {
+ /* Going into commit phase means we are starting a new protocol run. */
+ new_protocol_run(valid_after);
+ }
+ /* Set the new phase for this round */
+ sr_state->phase = next_phase;
+ } else if (sr_state->phase == SR_PHASE_COMMIT &&
+ digestmap_size(sr_state->commits) == 0) {
+ /* We are _NOT_ in a transition phase so if we are in the commit phase
+ * and have no commit, generate one. Chances are that we are booting up
+ * so let's have a commit in our state for the next voting period. */
+ sr_commit_t *our_commit =
+ sr_generate_our_commit(valid_after, get_my_v3_authority_cert());
+ if (our_commit) {
+ /* Add our commitment to our state. In case we are unable to create one
+ * (highly unlikely), we won't vote for this protocol run since our
+ * commitment won't be in our state. */
+ sr_state_add_commit(our_commit);
+ }
+ }
+
+ sr_state_set_valid_after(valid_after);
+
+ /* Count the current round */
+ if (sr_state->phase == SR_PHASE_COMMIT) {
+ /* invariant check: we've not entered reveal phase yet */
+ if (BUG(sr_state->n_reveal_rounds != 0))
+ return;
+ sr_state->n_commit_rounds++;
+ } else {
+ sr_state->n_reveal_rounds++;
+ }
+
+ { /* Debugging. */
+ char tbuf[ISO_TIME_LEN + 1];
+ format_iso_time(tbuf, valid_after);
+ log_info(LD_DIR, "SR: State prepared for upcoming voting period (%s). "
+ "Upcoming phase is %s (counters: %d commit & %d reveal rounds).",
+ tbuf, get_phase_str(sr_state->phase),
+ sr_state->n_commit_rounds, sr_state->n_reveal_rounds);
+ }
+}
+
+/* Return commit object from the given authority digest <b>rsa_identity</b>.
+ * Return NULL if not found. */
+sr_commit_t *
+sr_state_get_commit(const char *rsa_identity)
+{
+ sr_commit_t *commit;
+
+ tor_assert(rsa_identity);
+
+ state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_COMMIT,
+ (void *) rsa_identity, (void *) &commit);
+ return commit;
+}
+
+/* Add <b>commit</b> to the permanent state. The commit object ownership is
+ * transferred to the state so the caller MUST not free it. */
+void
+sr_state_add_commit(sr_commit_t *commit)
+{
+ tor_assert(commit);
+
+ /* Put the commit to the global state. */
+ state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_COMMIT,
+ (void *) commit, NULL);
+
+ log_debug(LD_DIR, "SR: Commit from %s has been added to our state.",
+ sr_commit_get_rsa_fpr(commit));
+}
+
+/* Remove all commits from our state. */
+void
+sr_state_delete_commits(void)
+{
+ state_query(SR_STATE_ACTION_DEL_ALL, SR_STATE_OBJ_COMMIT, NULL, NULL);
+}
+
+/* Copy the reveal information from <b>commit</b> into <b>saved_commit</b>.
+ * This <b>saved_commit</b> MUST come from our current SR state. Once modified,
+ * the disk state is updated. */
+void
+sr_state_copy_reveal_info(sr_commit_t *saved_commit, const sr_commit_t *commit)
+{
+ tor_assert(saved_commit);
+ tor_assert(commit);
+
+ saved_commit->reveal_ts = commit->reveal_ts;
+ memcpy(saved_commit->random_number, commit->random_number,
+ sizeof(saved_commit->random_number));
+
+ strlcpy(saved_commit->encoded_reveal, commit->encoded_reveal,
+ sizeof(saved_commit->encoded_reveal));
+ state_query(SR_STATE_ACTION_SAVE, 0, NULL, NULL);
+ log_debug(LD_DIR, "SR: Reveal value learned %s (for commit %s) from %s",
+ saved_commit->encoded_reveal, saved_commit->encoded_commit,
+ sr_commit_get_rsa_fpr(saved_commit));
+}
+
+/* Set the fresh SRV flag from our state. This doesn't need to trigger a
+ * disk state synchronization so we directly change the state. */
+void
+sr_state_set_fresh_srv(void)
+{
+ sr_state->is_srv_fresh = 1;
+}
+
+/* Unset the fresh SRV flag from our state. This doesn't need to trigger a
+ * disk state synchronization so we directly change the state. */
+void
+sr_state_unset_fresh_srv(void)
+{
+ sr_state->is_srv_fresh = 0;
+}
+
+/* Return the value of the fresh SRV flag. */
+unsigned int
+sr_state_srv_is_fresh(void)
+{
+ return sr_state->is_srv_fresh;
+}
+
+/* Cleanup and free our disk and memory state. */
+void
+sr_state_free_all(void)
+{
+ state_free(sr_state);
+ disk_state_free(sr_disk_state);
+ /* Nullify our global state. */
+ sr_state = NULL;
+ sr_disk_state = NULL;
+}
+
+/* Save our current state in memory to disk. */
+void
+sr_state_save(void)
+{
+ /* Query a SAVE action on our current state so it's synced and saved. */
+ state_query(SR_STATE_ACTION_SAVE, 0, NULL, NULL);
+}
+
+/* Return 1 iff the state has been initialized that is it exists in memory.
+ * Return 0 otherwise. */
+int
+sr_state_is_initialized(void)
+{
+ return sr_state == NULL ? 0 : 1;
+}
+
+/* Initialize the disk and memory state.
+ *
+ * If save_to_disk is set to 1, the state is immediately saved to disk after
+ * creation else it's not thus only kept in memory.
+ * If read_from_disk is set to 1, we try to load the state from the disk and
+ * if not found, a new state is created.
+ *
+ * Return 0 on success else a negative value on error. */
+int
+sr_state_init(int save_to_disk, int read_from_disk)
+{
+ int ret = -ENOENT;
+ time_t now = time(NULL);
+
+ /* We shouldn't have those assigned. */
+ tor_assert(sr_disk_state == NULL);
+ tor_assert(sr_state == NULL);
+
+ /* First, try to load the state from disk. */
+ if (read_from_disk) {
+ ret = disk_state_load_from_disk();
+ }
+
+ if (ret < 0) {
+ switch (-ret) {
+ case EINVAL:
+ /* We have a state on disk but it contains something we couldn't parse
+ * or an invalid entry in the state file. Let's remove it since it's
+ * obviously unusable and replace it by an new fresh state below. */
+ case ENOENT:
+ {
+ /* No state on disk so allocate our states for the first time. */
+ sr_state_t *new_state = state_new(default_fname, now);
+ sr_disk_state_t *new_disk_state = disk_state_new(now);
+ state_set(new_state);
+ /* It's important to set our disk state pointer since the save call
+ * below uses it to synchronized it with our memory state. */
+ disk_state_set(new_disk_state);
+ /* No entry, let's save our new state to disk. */
+ if (save_to_disk && disk_state_save_to_disk() < 0) {
+ goto error;
+ }
+ break;
+ }
+ default:
+ /* Big problem. Not possible. */
+ tor_assert(0);
+ }
+ }
+ /* We have a state in memory, let's make sure it's updated for the current
+ * and next voting round. */
+ {
+ time_t valid_after = voting_schedule_get_next_valid_after_time();
+ sr_state_update(valid_after);
+ }
+ return 0;
+
+ error:
+ return -1;
+}
+
+#ifdef TOR_UNIT_TESTS
+
+/* Set the current phase of the protocol. Used only by unit tests. */
+void
+set_sr_phase(sr_phase_t phase)
+{
+ if (BUG(!sr_state))
+ return;
+ sr_state->phase = phase;
+}
+
+/* Get the SR state. Used only by unit tests */
+sr_state_t *
+get_sr_state(void)
+{
+ return sr_state;
+}
+
+#endif /* defined(TOR_UNIT_TESTS) */
diff --cc src/feature/dirauth/shared_random_state.h
index 35626be3f,000000000..08f999f9d
mode 100644,000000..100644
--- a/src/feature/dirauth/shared_random_state.h
+++ b/src/feature/dirauth/shared_random_state.h
@@@ -1,146 -1,0 +1,148 @@@
+/* Copyright (c) 2016-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_SHARED_RANDOM_STATE_H
+#define TOR_SHARED_RANDOM_STATE_H
+
+#include "feature/dirauth/shared_random.h"
+
+/* Action that can be performed on the state for any objects. */
+typedef enum {
+ SR_STATE_ACTION_GET = 1,
+ SR_STATE_ACTION_PUT = 2,
+ SR_STATE_ACTION_DEL = 3,
+ SR_STATE_ACTION_DEL_ALL = 4,
+ SR_STATE_ACTION_SAVE = 5,
+} sr_state_action_t;
+
+/* Object in the state that can be queried through the state API. */
+typedef enum {
+ /* Will return a single commit using an authority identity key. */
+ SR_STATE_OBJ_COMMIT,
+ /* Returns the entire list of commits from the state. */
+ SR_STATE_OBJ_COMMITS,
+ /* Return the current SRV object pointer. */
+ SR_STATE_OBJ_CURSRV,
+ /* Return the previous SRV object pointer. */
+ SR_STATE_OBJ_PREVSRV,
+ /* Return the phase. */
+ SR_STATE_OBJ_PHASE,
+ /* Get or Put the valid after time. */
+ SR_STATE_OBJ_VALID_AFTER,
+} sr_state_object_t;
+
+/* State of the protocol. It's also saved on disk in fname. This data
+ * structure MUST be synchronized at all time with the one on disk. */
+typedef struct sr_state_t {
+ /* Filename of the state file on disk. */
+ char *fname;
+ /* Version of the protocol. */
+ uint32_t version;
+ /* The valid-after of the voting period we have prepared the state for. */
+ time_t valid_after;
+ /* Until when is this state valid? */
+ time_t valid_until;
+ /* Protocol phase. */
+ sr_phase_t phase;
+
+ /* Number of runs completed. */
+ uint64_t n_protocol_runs;
+ /* The number of commitment rounds we've performed in this protocol run. */
+ unsigned int n_commit_rounds;
+ /* The number of reveal rounds we've performed in this protocol run. */
+ unsigned int n_reveal_rounds;
+
+ /* A map of all the received commitments for this protocol run. This is
+ * indexed by authority RSA identity digest. */
+ digestmap_t *commits;
+
+ /* Current and previous shared random value. */
+ sr_srv_t *previous_srv;
+ sr_srv_t *current_srv;
+
+ /* Indicate if the state contains an SRV that was _just_ generated. This is
+ * used during voting so that we know whether to use the super majority rule
+ * or not when deciding on keeping it for the consensus. It is _always_ set
+ * to 0 post consensus.
+ *
+ * EDGE CASE: if an authority computes a new SRV then immediately reboots
+ * and, once back up, votes for the current round, it won't know if the
+ * SRV is fresh or not ultimately making it _NOT_ use the super majority
+ * when deciding to put or not the SRV in the consensus. This is for now
+ * an acceptable very rare edge case. */
+ unsigned int is_srv_fresh:1;
+} sr_state_t;
+
+/* Persistent state of the protocol, as saved to disk. */
+typedef struct sr_disk_state_t {
+ uint32_t magic_;
+ /* Version of the protocol. */
+ int Version;
+ /* Version of our running tor. */
+ char *TorVersion;
+ /* Creation time of this state */
+ time_t ValidAfter;
+ /* State valid until? */
+ time_t ValidUntil;
+ /* All commits seen that are valid. */
+ struct config_line_t *Commit;
+ /* Previous and current shared random value. */
+ struct config_line_t *SharedRandValues;
+ /* Extra Lines for configuration we might not know. */
+ struct config_line_t *ExtraLines;
+} sr_disk_state_t;
+
+/* API */
+
+/* Public methods: */
+
+void sr_state_update(time_t valid_after);
+
+/* Private methods (only used by shared-random.c): */
+
+void sr_state_set_valid_after(time_t valid_after);
+sr_phase_t sr_state_get_phase(void);
+const sr_srv_t *sr_state_get_previous_srv(void);
+const sr_srv_t *sr_state_get_current_srv(void);
+void sr_state_set_previous_srv(const sr_srv_t *srv);
+void sr_state_set_current_srv(const sr_srv_t *srv);
+void sr_state_clean_srvs(void);
+digestmap_t *sr_state_get_commits(void);
+sr_commit_t *sr_state_get_commit(const char *rsa_fpr);
+void sr_state_add_commit(sr_commit_t *commit);
+void sr_state_delete_commits(void);
+void sr_state_copy_reveal_info(sr_commit_t *saved_commit,
+ const sr_commit_t *commit);
+unsigned int sr_state_srv_is_fresh(void);
+void sr_state_set_fresh_srv(void);
+void sr_state_unset_fresh_srv(void);
+int sr_state_init(int save_to_disk, int read_from_disk);
+int sr_state_is_initialized(void);
+void sr_state_save(void);
+void sr_state_free_all(void);
+
+#ifdef SHARED_RANDOM_STATE_PRIVATE
+
+STATIC int disk_state_load_from_disk_impl(const char *fname);
+
+STATIC sr_phase_t get_sr_protocol_phase(time_t valid_after);
+
+STATIC time_t get_state_valid_until_time(time_t now);
+STATIC const char *get_phase_str(sr_phase_t phase);
+STATIC void reset_state_for_new_protocol_run(time_t valid_after);
+STATIC void new_protocol_run(time_t valid_after);
+STATIC void state_rotate_srv(void);
+STATIC int is_phase_transition(sr_phase_t next_phase);
+
+#endif /* defined(SHARED_RANDOM_STATE_PRIVATE) */
+
+#ifdef TOR_UNIT_TESTS
+
+STATIC void set_sr_phase(sr_phase_t phase);
+STATIC sr_state_t *get_sr_state(void);
++STATIC void state_del_previous_srv(void);
++STATIC void state_del_current_srv(void);
+
+#endif /* defined(TOR_UNIT_TESTS) */
+
+#endif /* !defined(TOR_SHARED_RANDOM_STATE_H) */
1
0