1
|
Bitcoin / Armory / libbitcoin vulnerability and armory
|
on: August 18, 2023, 09:13:45 AM
|
Are wallets created with Armory after 2016 actually affected by libbitcoin vulnerability ? sounds like I ought to check if Armory's use of libbitcoin could be affected. I didn't create any new Armory wallets since the date (late 2016) of the libbitcoin-system pull request, but possibly others did. Armory previously used Crypto++, which I guess was subject to a little more scrutiny (guessing isn't good enough however, I feel compelled now to check)
|
|
|
2
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: March 25, 2023, 10:20:35 PM
|
...
Tornando al discorso di esposizione temporale e contemporaneità degli eventi una compagnia si basa sul fatto che non tutti gli anni, non in tutto un arco temporale, a TUTTI accade TUTTO.
È possibile, ed è accaduto più volte che la raccolta dei premi sia inferiore al pagamento di sinistri, per una serie di eventi. È successo con gli eventi grandine, anni disastrosi dove moltissimi assicurati sono stati colpiti. Certo da quel punto in poi i premi saranno più cari.
Magari però nei decenni precedenti si sono accumulati enormi profitti moltiplicati da ulteriori guadagni della gestione delle riserve, che hanno compensato ampiamente la perdita totale di una o più annate altamente sinistro se dove si è dovuto pagare fior di indennizzi. ...
Il punto quindi, affinchè il sistema regga, è che ci siano delle imprese/persone/banche che pagano per coprirsi da un rischio senza mai incappare nell'incidente, ovvero si cerca di spalmare su una base più ampia il costo dell'intervento di sostegno in caso di evento avverso. Più precisamente: si spalma tale costo su molti attori e su molto tempo (su diverse generazioni di attori). In teoria sul lunghissimo periodo in media ciascuna impresa dovrebbe versare un ammontare di premi almeno uguale (se non superiore) a ciò che riceve quando avviene l' evento avverso, altrimenti l'assicurazione non ci guadagna. Ma la possibilità di diluire nel tempo la spesa, acquisendo la copertura assicurativa dal giorno 1 può fare la differenza. Inoltre sul lunghissimo periodo molte imprese non ci sono più, quindi effettivamente ci saranno tanti che avranno pagato senza ricevere nulla in cambio. D'altra parte l'impresa, invece di accantonare della liquidità per un evento negativo che magari mai accadrà, 'risparmia' pagando una certa quota annuale. Se invece l'evento avverso colpisse troppe persone, allora la copertura assicurativa non sarebbe garantita. A me sembra ragionevole che non sia possibile assicurarsi da un evento avverso esageratamente oneroso, come ad esempio qualcosa che colpisse nello stesso anno metà della popolazione, in tal caso non sarebbe fattibile raccogliere e accantonare/investire tale somma.
|
|
|
3
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: March 25, 2023, 06:08:54 PM
|
che un'assicurazione e' un'azienda privata che deve trarre degli utili nell'assicurare eventi.
quindi per ricavare il valore della polizza da farti pagare deve calcolare le probabilita' dell'evento che assicuri P e trasformarlo in valore: VP applicarci un delta di guadagno D per loro e farti pagare VP+D.
Ora poniamo che P sia il rischio di un'attivita' imprenditoriale (banca nel nostro caso) e che sia davvero calcolabile (o approssimabile con sufficente confidenza)
Praticamente ogni impresa (banca) potrebbe annullare rischio imprenditoriale P: perfetto uno potrebbe dire.
Ma e' evidente che il valore del rischio imprenditoriale della banca VP dovrebbe essere un valore proporzionale al valore della banca stessa, + il famoso D che e' il guadagno (utile) dell'assicurazione.
E quindi, a questo punto... l'impresa (banca) non avrebbe piu' spazio per conseguire i propri utili! avrebbe si annullato i rischi, ma anche gli utili, perche' li avrebbe trasferiti all'impresa assicuratrice (compresa una parte del proprio valore)
Non sono sicuro di aver seguito bene il tuo ragionamento. Che collegamento c'è tra gli utili della banca e il guadagno utile dell'assicurazione? Si presuppone che la banca sappia trarre dalla sua attività degli utili maggiori di quanto gli costi l'assicurazione, assicurazione che da parte sua dovrebbe essere in grado di sostenere la copertura del rischio dell'attività della banca a costi minori di quanto potrebbe fare la banca stessa, in pratica ciascuna parte dovrebbe trarre vantaggio dalla cooperazione (teoria dei vantaggi comparati).
|
|
|
4
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: March 25, 2023, 03:07:21 PM
|
Di base e' stupido pensare che qualsiasi tipo di evento sia assicurabile, in quanto vol dire che si rietene che si possa calcolare il rischio esatto di qualsiasi evento.
Quanto mi costerebbe assicurarmi contro la caduta di un meteorite? O contro un'invasione di alieni cattivi? O contro una improvvisa singolarita' spazio-temporale che inghiottisse la terra, o il sistema solare, o la galassia, o magari l'intero universo?
Non dico che si può calcolare il rischio esatto, ma trattare un sistema interconnesso come quello delle banche come fosse un insieme di situazioni indipendenti l'una dall'altra è agire in malafede. Una crisi bancaria generalizzata ogni tot anni non è un cigno nero. Non c'è bisogno di tirare in ballo singolarità o cose di questo tipo. La probabilità di una seria crisi bancaria è molto più alta della probabilità che cada un meteorite.
|
|
|
5
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: March 25, 2023, 03:01:46 PM
|
Gli incidenti automobilistici hanno una distribuzione statistica ben calcolabile, e quindi il rischio per un'assicurazione e' gestibile in modo scientifico.
Ci sono certi tipi di eventi invece, che sono delle singolarita' (come appunto potrebbe essere un crack bancario) e quindi il rischio effettivo non e' calcolabile.
Le assicurazioni fondamentalmente vendono calcolo delle probablita', e ci sono certi eventi dei quali semplicemente non si possono determinare le probablita', in quanto sono o caotici, o la base statistica e' troppo limitata, o sono singolarita' discontinue....
Mi sembra tanto un problema di probabilità condizionata mal posto: l'ipotesi alla base del funzionamento del sistema di assicurazione delle banche è l'indipendenza stocastica di certi eventi negativi, mentre in realtà certi eventi sono molto più legati di quanto non si voglia far credere.
Da qui la questione annosa del contenimento del contagio, del salvataggio a tutti i costi (salvare uno per salvare l'intero sistema). 1 banca dovrebbe valere sempre 1 banca, ma sembra qui invece che 1 banca valga 1000 banche (l'intero sistema).
La probabilità di certi eventi andrebbe calcolata in qualche modo, altrimenti un sistema che basa la sua sicurezza sul calcolo delle probabilità ma non misura certi rischi è per definizione un sistema non "assicurato". E' un problema di impostazione, by design (per cui forse non c'è soluzione). La riserva frazionaria è una conseguenza.
|
|
|
6
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: March 25, 2023, 02:48:22 PM
|
La solita favoletta "si ma i depositi bancari sono assicurati" ha dimostrato in queste ultime settimane tutta la sua limitatezza.
non e' difficile arrivarci con un banale ragionamento: una entita' X (l'assicuratore/gli assicuratori) dovrebbe farsi pagare dalle banche per coprire cio' che loro non possono coprire quindi X dovrebbe tenere i depositi pronti per coprire i depositi che le banche non hanno, e invece X si. Non c'e' nessuna logica in questo schema, in quanto X praticamente quindi tenere "congelati" capitali sufficenti per coprire i capitali della banca assicurata (facendo fondamentalmente la funzione della banca stessa) E non si spiega neppure con una eventuale riassicurazione di X da parte di una ulteriore assicurazione Y: per quanto si passino la palla da uno all'altro, alla fine alla fine qualcuno i capitali per coprire le perdite deve averli. La logica dovrebbe essere che X si limita a raccogliere i soldi da tante banche per coprire i depositi di cui una banca in difficoltà potrebbe avere bisogno in un particolare momento. Certo che X non può coprire contemporaneamente tutti i depositi di tutte le banche. Un po' come le assicurazioni auto, che assicurano tutti (e quindi a livello teorico coprono il rischio di tutti), ma poi pagano a livello pratico solo una piccola percentuale di assicurati l'anno. Se metà degli automobilisti facesse un incidente nello stesso anno non ci sarebbero i soldi per tutti. Il problema con le banche è che sembra che quando 5 banche vanno in difficoltà, allora la probabilità che anche le altre abbiano bisogno di aiuto aumenti a dismisura. Con gli incidenti automobilistici per fortuna non è così. Mi sembra tanto un problema di probabilità condizionata mal posto: l'ipotesi alla base del funzionamento del sistema di assicurazione delle banche è l'indipendenza stocastica di certi eventi negativi, mentre in realtà certi eventi sono molto più legati di quanto non si voglia far credere. Da qui la questione annosa del contenimento del contagio, del salvataggio a tutti i costi (salvare uno per salvare l'intero sistema). 1 banca dovrebbe valere sempre 1 banca, ma sembra qui invece che 1 banca valga 1000 banche (l'intero sistema).
|
|
|
7
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: January 27, 2023, 02:09:42 PM
|
Ma il punto della mia obiezione, che evidentemente non sembra essere stato colto, è che non accetto che la responsabilità di questa malagestione venga fatta ricadere sul singolo, non accetto l'atteggiamento paternalistico di chi, soprattutto se parte delle istituzioni o di una classe politica che non ha mai fatto nulla per affrontare seriamente la questione negli ultimi 30 anni, si permetta di stigmatizzare comportamenti individuali, facendo pressioni per condizionare delle scelte che afferiscono alla sfera privata e più intima della persona, in nome di qualche presunto interesse superiore. Io da cittadino sono tenuto a fare la mia parte, versando regolarmente i contributi previdenziali, non a sopperire alla negligenza e all'incapacità altrui con azioni che riguardano la mia vita privata.
Su questo sono totalmente d'accordo.
|
|
|
8
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: January 27, 2023, 11:28:34 AM
|
il punto è che la 30enne che non vuole avere figli ha tutto il diritto di non farne, senza che gli altri le scassino attributi che in quanto donna non possiede, magari scaricando su di lei le colpe più assurde, dalla gestione dissennata delle casse previdenziali e relativi buchi (finché si paga regolarmente i suoi contributi per 40 anni e oltre, avrà tutto il diritto di maturare una pensione a suo tempo), o peggio ancora sollevando argomenti moralistici e bigotti, riportando indietro le lancette della storia ai peggiori stereotipi sul ruolo della donna come fattrice. Alla faccia dell'emancipazione.
Eh no caro mio. Il sistema previdenziale non funziona così! I contributi che lei sta pagando adesso servono a pagare le pensioni che lo Stato paga adesso ad altre persone. I contributi che lei ha pagato per 40 anni, quando andrà in pensione saranno già stati spesi da un bel po'. L'Inps è uno schema Ponzi, anche se viene considerato una cassa previdenziale. Se lei non fa figli semplicemente non ci sarà qualcuno che lavorerà per pagare la pensione quando andrà lei in pensione. Ed è esattamente quello che sta accadendo all'Inps. Anche io sono d'accordo che si sono sperperati soldi in passato (e anche adesso) nelle pensioni d'oro, ma in passato potevamo permettercelo perchè facevamo figli, ora non più. E non c'entrano assolutamente nulla i discorsi bigotti o moralistici o sensi di colpa vari. Precisiamo meglio: il concetto di "diritto ad ottenere qualcosa" è spesso confuso con "la disponibilità effettiva della cosa stessa". Se io ho diritto ad una pensione, ma non c'è più chi me la deve finanziare, cosa me ne faccio di questo diritto? Durante il covid: i pensionati avevano 'diritto' a mantenere una certa pensione, mentre chi lavorava e doveva effettivamente pagare le loro pensioni non era più in grado di produrre come prima: come era sostenibile effettivamente questo diritto? Facendo altri debiti, cioè caricando il costo di questo 'diritto' sui sempre meno numerosi italiani delle prossime generazioni. Se nei prossimi anni la popolazione italiana diminuirà del 20% https://www.ilsole24ore.com/art/l-italia-si-spopola-e-invecchia-50-anni-12-milioni-meno-AEi1xXze se la produttività continuerà a non crescere, quante ore dovrebbe lavorare in media un italiano del 2070 per: 1) mantenere un livello di spesa comparabile a quello odierno (non dico migliore, e parliamo di 50 anni nel futuro) 2) pagare le pensioni ai pensionati del 2070 3) pagare interessi altissimi su un debito pubblico in crescita con un PIL in diminuzione (meno persone, meno PIL)?
|
|
|
9
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: January 27, 2023, 06:45:28 AM
|
Altro esempio: chi oggi compra un bitcoin, perchè è un risparmiatore? Perchè ha una mentalità migliore o perchè ha visto un'opportunità (rara di questi tempi) di miglioramento per il futuro? La mia tesi è che il concentrarsi sul presente (godere e consumare) anzichè sul futuro (programmazione e risparmio) nasca semplicemente dal fatto che oggi in Italia c'è abbondanza di materia prima da spendere nel presente (leggi denaro e oggetti) da una parte e mancanza di futuro, inteso come prospettiva di miglioramento, dall'altra (vedi i primi 28 secondi di https://www.youtube.com/watch?v=4N3uZGF_mCw ) Avere l'impressione di aver già raggiunto tutto quello che c'era da raggiungere e che non ci sia più nulla da fare facilmente ti porta a concentrarti sul presente, anzichè sul futuro. E direi che sono almeno 30-40 anni che l'Italia non va avanti sotto molti punti di vista (a partire dall'economia, ma non solo). Il fatto di comprare bitcoin è un evidente sintomo di un abbassamento delle preferenze temporali. Rinunciare a consumo oggi "scambiandolo" per consumo domani. Direi che è un atto di fiducia intrinseco nel futuro. La questione è se questo atto di fiducia è più merito di bitcoin (in quanto prospettiva di miglioramento nel futuro creata da qualcuno 15 anni fa) o delle persone che l'hanno acquistato. Io sostengo che è più facile abbassare le preferenze temporali se prima vedi un motivo per farlo. E qui si passa dalla sfera economica a quella sociale: il messaggio, più o meno subliminale, che trasuda da ogni poro della nostra società è quello di incentivare il più possibile la spesa in ognuno di noi.
Ma questo messaggio subliminale è partorito deliberatamente da qualcuno? Se non hai una visione per il futuro (non ce l'hanno i politici, nè la classe dirigente in generale, nè gli intellettuali), cioè se non hai una direzione lungo la quale dirigerti, l'alternativa è "muoversi" a caso il più possibile nel presente; il consumismo mi sembra più il risultato di uno stato ansioso contro la mancanza di senso e di visione per il futuro che il progetto deliberato da qualcuno per spremere le masse.
|
|
|
10
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: January 26, 2023, 06:10:52 PM
|
... La distruzione di ricchezza si ha quando il surplus di consumo (rispetto al reddito) è intergenerazionale: come nel ns Paese dove stiamo distruggendo la ricchezza messa da parte dalle generazioni precedenti.
E' vero che "distruggere" è una parola non corretta: la ricchezza non si distrugge, si trasferisce: nel caso italiano si accentra nelle mani di pochi, sempre più stranieri.
Credo anche che il “lavoratore puro” non esista più da almeno un secolo: i proletari esistevano forse nell'800. Già negli anni 50-60 nonostante gli italiani fossero mediamente molto più poveri di quelli di ora la capacità di risparmiare esisteva eccome.
So di fare un discorso antipatico e poco popolare, ma il crollo della capacità di risparmio nell'Italia attuale è figlio di scelte ben precise e non di una oggettiva impossibilità a mettere da parte a causa dei bassi redditi.
E qui si passa dalla sfera economica a quella sociale: il messaggio, più o meno subliminale, che trasuda da ogni poro della nostra società è quello di incentivare il più possibile la spesa in ognuno di noi.
Tempo fa ero con amici ad una cena. Gente che non vedevo da un pò. Entriamo nell'argomento figli. Una ragazza, single, sui 30 anni se ne esce con queste parole: "A me i figli non interessano, nella mia vita non ho intenzione di farli". Silenzio, sguardi gelidi. La ragazza ha appena toccato un tasto proibito. Qualcosa che nella società di oggi non si può dire e nemmeno pensare. Fossimo in 1984 sarebbe uno psicoreato
Però è un pensiero legittimo o vogliamo fare come in Cina dove lo Stato decide il numero di figli? ....
Come al solito fai considerazioni molto molto interessanti. Il mio punto però era un altro: negli anni 50-60 non è che gli italiani fossero intrinsecamente 'migliori' degli italiani odierni, semplicemente avevano meno di tutto (soldi, tempo, ricchezza in senso lato) ma erano ricchi di un'altra cosa: di 'futuro'. La loro mentalità volta al risparmio (che io non condanno in principio) era più che altro dettata da 2 fattori: 1) dalla necessità (poco da spendere, non potevi viaggiare, comprare libri, smartphone, ... ) 2) da una situazione in cui non spendere era un EVIDENTE vantaggio, visto che il mondo attorno migliorava a vista d'occhio e il futuro appariva senz'altro migliore del presente: risparmiare vuol dire guardare al futuro, e oggi in Italia non hai l'impressione che il futuro sarà migliore, anzi (non cerco scuse, mi limito a descrivere quello che vedo). Se vuoi un confronto: i cinesi negli ultimi decenni per alcuni aspetti si sono trovati in una situazione simile a quella dei nostri nonni: forte crescita economica (facile se parti da molto in basso) e ottime prospettive di crescita, quindi tendenza al risparmio; non è un caso che da quelle parti la capacità di sacrificio dell'oggi per il domani sia molto alta (pensa solo a quanto studia in media un ragazzo cinese contro un ragazzo italiano oggi) Altro esempio: chi oggi compra un bitcoin, perchè è un risparmiatore? Perchè ha una mentalità migliore o perchè ha visto un'opportunità (rara di questi tempi) di miglioramento per il futuro? La mia tesi è che il concentrarsi sul presente (godere e consumare) anzichè sul futuro (programmazione e risparmio) nasca semplicemente dal fatto che oggi in Italia c'è abbondanza di materia prima da spendere nel presente (leggi denaro e oggetti) da una parte e mancanza di futuro, inteso come prospettiva di miglioramento, dall'altra (vedi i primi 28 secondi di https://www.youtube.com/watch?v=4N3uZGF_mCw ) Avere l'impressione di aver già raggiunto tutto quello che c'era da raggiungere e che non ci sia più nulla da fare facilmente ti porta a concentrarti sul presente, anzichè sul futuro. E direi che sono almeno 30-40 anni che l'Italia non va avanti sotto molti punti di vista (a partire dall'economia, ma non solo).
|
|
|
11
|
Local / Italiano (Italian) / Re: BITCOIN PUMP!
|
on: January 22, 2023, 05:29:43 PM
|
Il problema è che le persone non capiscono che c'è una "spesa sana" e una "spesa malata". Quando si parla di consumismo, ci si riferisce a quest'ultima.
....
Nessuno che voglia spendere per creare qualcosa, per lasciare qualcosa. Un'impresa, un sogno nel cassetto grande o piccolo, un' idea, un progetto.
Io ho un sogno nella vita: arrivare in punto di morte sapendo che ho creato più ricchezza di quanta ne ho consumata. Che passo un testimone di maggior valore a quelli che verranno dopo. Non importa chi sono quelli che vengono dopo: i figli, la moglie, il cane, il WWF, la ganza moldava.
L'importante è CREARE qualcosa, è GENERARE VALORE CHE DURI, altrimenti cosa si vive a fare? Che gusto c'è a passare un'intera esistenza solo a nutrirsi, dormire, consumare, produrre rifiuti? Distruggendo ricchezza creata da quelli prima?
...
Altrimenti una società che pensa solo al godimento presente è destinata alla rovina. Che poi la cosa che mi fa incazzare di più è che il godimento deve pure essere senza fatica.
La funzione del consumatore 'puro' non è distruggere ricchezza, è consumare ricchezza più velocemente fornendo così un senso alla produzione e al lavoro di altri. Pensate a un consumatore come a un bambino: per definizione un bambino consuma solo, non è in grado di produrre: la presenza di bambini in una casa è un grande incentivo affinchè i genitori producano/lavorino di più, fornisce un senso al loro lavoro. Il consumatore 'puro' è l'altra faccia della medaglia di chi pensa solo a lavorare (lavoratore 'puro'). Io, che per natura spendo pochissimo, sono affascinato da alcuni personaggi su Youtube che passano il loro tempo per esempio a comprare e provare pc o altri oggetti: anche nel loro caso è consumismo? Entrambe le figure (consumatore e lavoratore 'puro') sono forzature, ma secondo me se nel passato c'erano più lavoratori 'puri', oggi per forza di cosa ci si sta muovendo nell'altra direzione. I miei nonni hanno lavorato sempre finchè hanno potuto, una volta c'erano tantissimi lavoratori a tempo pieno (per necessità, anche se dalla produttività bassa, magari uno faceva il contadino e veniva aiutato dalla moglie e anche dai figli, e passavano un'intera esistenza solo a coltivare, nutrirsi, dormire, consumare quello che producevano). Nella società attuale (almeno in Occidente) la produzione invece supera ormai abbondantemente le necessità di consumo delle persone. E' anche per questo che si stanno moltiplicando le settimane corte al lavoro e che molti giovani danno sempre più peso all'orario di lavoro e agli spostamenti: il tempo delle persone ha un valore. Il problema è che non siamo abituati a gestire questo valore, il tempo libero (nè siamo abituati a gestire denaro in abbondanza rispetto alle pure necessità di base): è un fatto relativamente recente avere tempo libero a disposizione (una volta era una prerogativa di nicchia, non di massa). Non sto difendendo il consumismo sfrenato, dico solo che: 1) chi pone l'accento 'sul godere la vita' ha almeno intuito che c'era un problema nella vita dei nostri nonni (solo lavoro e poco o nulla piacere) 2) se da una parte certi consumatori non si pongono affatto il problema di creare qualcosa che duri nel tempo, dall'altra parte anche molte attività cosiddette 'produttive' producono ben poco di significativo (si potrebbe dire che producano direttamente rifiuti). 3) molti lavori non ti danno la sensazione di produrre qualcosa di valore, che duri nel tempo (esempio: il corriere Amazon, ma ce ne sono tanti altri), dove impari a produrre qualcosa che duri nel tempo allora? Se molte persone passano 8 ore al giorno producendo cose effimere? E' molto difficile distinguere non solo tra spesa sana e spesa malata, tra tempo libero speso bene e speso male, ma anche tra produzione sana e produzione malata. Per esempio, molti accusano la rete Bitcoin di essere una produzione 'malata' (bruciare energia per produrre numeri). Il senso del mio intervento è: non mi stupisco che la società attuale attraversi un periodo difficile, non è questione che siamo uomini deboli mentre una volta c'erano uomini forti, semplicemente le sfide del nostro tempo sono altre (e il passato non ci ha consegnato molte indicazioni utili al riguardo). Un uomo forte di 200 anni fa trapiantato ai giorni nostri incontrerebbe le stesse nostre difficoltà (se non peggio).
|
|
|
12
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: January 07, 2023, 10:27:16 PM
|
randbelow(n-1)+1
how to replace this line private_keys = list(map(secrets.randbelow,n)) Try this code: #!/usr/bin/env python3 # 2023/Jan/01, citb0in_multicore_secrets.py import concurrent.futures import os import secrets import secp256k1 as ice
# how many cores to use num_cores = 10 #num_cores = os.cpu_count()
# Set the number of addresses to generate num_addresses = 10000000
# Define a worker function that generates a batch of addresses and returns them def worker(start, end, i): # Generate a list of random private keys using "secrets" library n = [0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141] * (end - start) #n one = [1] * (end - start) my_secure_rng = secrets.SystemRandom() private_keys = list(map(my_secure_rng.randrange,one,n)) #from 1 to n-1
# Use secp256k1 to convert the private keys to addresses addr_type = [2] * (end - start) is_compressed = [True] * (end - start) thread_addresses = list(map(ice.privatekey_to_address, addr_type, is_compressed, private_keys)) # Write the addresses in the thread file f = open("addresses_1M_multicore_secrets" + str(i) + ".txt", "w") list(map(lambda x:f.write(x+"\n"),thread_addresses)) #####or, if you want to store the private keys, along with the addresses############### #list(map(lambda x,y: f.write(hex(x)[2:].rjust(64,'0') + ' -> ' + y + '\n'),private_keys,thread_addresses) f.close() return
# Use a ProcessPoolExecutor to generate the addresses in parallel with concurrent.futures.ProcessPoolExecutor() as executor: # Divide the addresses evenly among the available CPU cores addresses_per_core = num_addresses // num_cores # Submit a task for each batch of addresses to the executor tasks = [] for i in range(num_cores): start = i * addresses_per_core end = (i+1) * addresses_per_core tasks.append(executor.submit(worker, start, end, i))
|
|
|
13
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: January 04, 2023, 04:08:38 PM
|
With last code, you should save at least 2.5 - 3s on your hardware, I guess from 25,8s to < 23s to compute 10 million keys. Did you try? I'm curious. Absolutely correct arulbero. Thanks for pointing out. I used 2**256 as a quick'n'dirty solution and forgot about the edge of the finite field 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 Good catch.
To be more precise, randbelow(n-1)+1 otherwise with randbelow(n) could occur '0' (extremely unlikely). ...
==> I have generated 1,007,862 addresses (about 1 million keys) in about 15 seconds using one single core with your program. ==> I have generated exactly 1 millions addresses in 10 seconds using one single core with my program.
Conclusion: The originally enormous speed advantage is therefore, according to these tests, not really to be found in the code difference but in the fact that randomly generated keys are simply more computationally intensive and cost more time than simple sequential key generation. So just as you originally said arulbero.
It always depends on the purpose of use, of course, but I have my doubts that the sequential generation of private keys is not the best way. I therefore think, also in terms of security for other applications, that random private keys are always preferable to sequential ones despite the fact they are more time-intensive.
If you try to substitute randbelow(n) with randbelow(10000000) (or another small number), you'll see how much time it requires to sum up many keys to get a high key. I think you may get almost 1 Million keys per sec.
|
|
|
14
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: January 03, 2023, 02:04:46 PM
|
I have modified to create 10 million addresses to make the difference more clear. $ time python3 citb0in_multicore_secrets.py
real 0m38,349s user 5m47,453s sys 0m16,060s
$ time python3 citb0in_multicore_secrets_splitsave.py
real 0m25,835s user 5m57,795s sys 0m14,681s
10 million addresses generated in less than 26 seconds. Rate = 387.071 (Python). ==> this is a performance boost of additional + 32.7 % on my computer. Crazy! thank you for pointing out @arulbero. Great! You don't use any specific function from numpy, then I suggest you to eliminate numpy besides you have to generate a random key k with k < n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 not k < 2**256 you can comment the check at this line: https://github.com/iceland2k14/secp256k1/blob/main/secp256k1.py#L290This is your code optimized: #!/usr/bin/env python3 # 2023/Jan/01, citb0in_multicore_secrets.py import concurrent.futures import os import secrets import secp256k1 as ice
# how many cores to use num_cores = 10 #num_cores = os.cpu_count()
# Set the number of addresses to generate num_addresses = 10000000
# Define a worker function that generates a batch of addresses and returns them def worker(start, end, i): addr_type = [2] * (end - start) is_compressed = [True] * (end - start) n = [0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141] * (end - start) f = open("addresses_1M_multicore_secrets" + str(i) + ".txt", "w") # Generate a list of random private keys using "secrets" library private_keys = list(map(secrets.randbelow,n))
# Use secp256k1 to convert the private keys to addresses thread_addresses = list(map(ice.privatekey_to_address, addr_type, is_compressed, private_keys)) # Write the addresses in the thread file list(map(lambda x:f.write(x+"\n"),thread_addresses))
f.close() return
# Use a ProcessPoolExecutor to generate the addresses in parallel with concurrent.futures.ProcessPoolExecutor() as executor: # Divide the addresses evenly among the available CPU cores addresses_per_core = num_addresses // num_cores # Submit a task for each batch of addresses to the executor tasks = [] for i in range(num_cores): start = i * addresses_per_core end = (i+1) * addresses_per_core tasks.append(executor.submit(worker, start, end, i))
|
|
|
15
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: January 02, 2023, 07:12:14 PM
|
To speed up slightly this code (with multi core), you can write on different files: [...] np.savetxt('addresses_1M_multicore_secrets'+ str(i) +'.txt', thread_addresses, fmt='%s') return [...]
This will finish faster, yes. But it will create only one single output file which contains only 62,500 addresses. My example have all 1 million addresses listed. I'm kinda puzzled  what exactly you mean, can you explain, please? If num_cores = 10, this code saves 100k addresses x 10 files. It doesn't create only 1 file, but 1 file for each thread. On my computer works.
|
|
|
16
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: January 02, 2023, 04:44:47 PM
|
here's the updated complete code variant with using multicore functionality and the secrets library for enhanded speed: #!/usr/bin/env python3 # 2023/Jan/01, citb0in_multicore_secrets.py import concurrent.futures import os import numpy as np import secrets import secp256k1 as ice
# how many cores to use #num_cores = 1 num_cores = os.cpu_count()
# Set the number of addresses to generate num_addresses = 1000000
# Define a worker function that generates a batch of addresses and returns them def worker(start, end): # Generate a NumPy array of random private keys using "secrets" library private_keys = np.array([secrets.randbelow(2**256) for _ in range(start, end)])
# Use secp256k1 to convert the private keys to addresses thread_addresses = np.array([ice.privatekey_to_address(2, True, dec) for dec in private_keys])
return thread_addresses
# Use a ProcessPoolExecutor to generate the addresses in parallel with concurrent.futures.ProcessPoolExecutor() as executor: # Divide the addresses evenly among the available CPU cores addresses_per_core = num_addresses // num_cores
# Submit a task for each batch of addresses to the executor tasks = [] for i in range(num_cores): start = i * addresses_per_core end = (i+1) * addresses_per_core tasks.append(executor.submit(worker, start, end))
# Wait for the tasks to complete and retrieve the results addresses = [] for task in concurrent.futures.as_completed(tasks): addresses.extend(task.result())
# Write the addresses to a file np.savetxt('addresses_1M_multicore_secrets.txt', addresses, fmt='%s')
To speed up slightly this code (with multi core), you can write on different files: #!/usr/bin/env python3 # 2023/Jan/01, citb0in_multicore_secrets.py import concurrent.futures import os import numpy as np import secrets import secp256k1 as ice
# how many cores to use #num_cores = 1 num_cores = os.cpu_count()
# Set the number of addresses to generate num_addresses = 1000000
# Define a worker function that generates a batch of addresses and returns them def worker(start, end, i): # Generate a NumPy array of random private keys using "secrets" library private_keys = np.array([secrets.randbelow(2**256) for _ in range(start, end)])
# Use secp256k1 to convert the private keys to addresses thread_addresses = np.array([ice.privatekey_to_address(2, True, dec) for dec in private_keys]) np.savetxt('addresses_1M_multicore_secrets'+ str(i) +'.txt', thread_addresses, fmt='%s') return
# Use a ProcessPoolExecutor to generate the addresses in parallel with concurrent.futures.ProcessPoolExecutor() as executor: # Divide the addresses evenly among the available CPU cores addresses_per_core = num_addresses // num_cores # Submit a task for each batch of addresses to the executor tasks = [] for i in range(num_cores): start = i * addresses_per_core end = (i+1) * addresses_per_core tasks.append(executor.submit(worker, start, end, i))
Your code doesn't store private keys, are you sure you want to have only a list of addresses without their private keys?
|
|
|
17
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: December 31, 2022, 12:17:18 PM
|
==> I have generated 1,007,862 addresses (about 1 million keys) in about 15 seconds using one single core with your program. ==> I have generated exactly 1 millions addresses in 10 seconds using one single core with my program.
Conclusion: The originally enormous speed advantage is therefore, according to these tests, not really to be found in the code difference but in the fact that randomly generated keys are simply more computationally intensive and cost more time than simple sequential key generation. So just as you originally said arulbero.
You said : "compare apples with apples" but now you are comparing a library written in C against pure python, it seems not fair  For the record: I wrote a library in C with a single function: from public keys to address (without b58 encoding) Private key : 0000000000000000000000000000000000000000000000000000000000000001 Public key : x: 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 y: 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
PrKey WIF c.: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn Address before b58 encode : 751e76e8199196d454941c45d1b3a323f1433bd6 Address with b58 encode : 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
I imported this function as file .so in my python script, result: 1 core, 1M of addresses time python3 gen_batches.py > addresses.out
real 0m3,961s user 0m3,910s sys 0m0,055s
16 cores, 1M of addresses time python3 gen_batches.py > addresses.out
real 0m0,527s user 0m7,404s sys 0m0,151s
1 core, 16.4M of addresses time python3 gen_batches.py > addresses.out
real 1m1,757s user 1m1,382s sys 0m0,348s
16 cores, 16.4M of addresses time python3 gen_batches.py > addresses.out
real 0m6,672s user 2m2,989s sys 0m0,698s
less addresses.out
c71c6741ae4862dadaf2d9c9295d47410a27e194 1d9a3ef1efeec75b05f0ece73ad9402cac767843 44abfeb8701c716380ed2a40aeb72370ef61d7aa d6a2aa6799f42078faa889dcda92b29c6005d84d f3a0e804269feeba68d8c1facf68206b73b2a987 7a795a7b4500f80101e489e9ad5d7bc1855edf13 d8e619b13be4c2d6182aa10c0e7237a35ba0ab05 be801790f2cefb432bdf5dce2946fd22364b36b0 531a9c231f3e42d4bdb02d44bf01104e6eccd83d 7c8391a816b578f0d6e0a56595b67e12a314f945 6d0b359ba6f3d382eb99a346f99f0d27c29e2963 aa4116886a8631699f5077d78f47e6013a1af05f 2574970ffa9d5b26d52d89a76eef9c3c1bfbe798 ...
then the speed is now about 2.4 MKeys/s. I'm pretty sure that more c functions you introduce in your python script, more fast it becomes.
|
|
|
18
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: December 30, 2022, 06:34:55 PM
|
The example I originally showed using iceland2k14/libsecp256k1 was about half the speed. With it I can generate 1 million addresses using all cores (in my case 16 cores) and write to the file in 4.8 seconds, this is a rate of about 208,300 keys/sec. I have modified my initial program so that you can now also configure the cores under which the program is executed. So one can select specifically "1" as value, so that we also compare apples with apples. #!/usr/bin/env python3 # 2022/Dec/30, citb0in import concurrent.futures import os import numpy as np import fastecdsa.keys as fkeys import fastecdsa.curve as fcurve import secp256k1 as ice
# how many cores to use num_cores = 1 #num_cores = os.cpu_count()
# Set the number of addresses to generate num_addresses = 1000000
# Define a worker function that generates a batch of addresses and returns them def worker(start, end): # Generate a NumPy array of random private keys using fastecdsa private_keys = np.array([fkeys.gen_private_key(fcurve.P256) for _ in range(start, end)])
# Use secp256k1 to convert the private keys to addresses thread_addresses = np.array([ice.privatekey_to_address(2, True, dec) for dec in private_keys])
return thread_addresses
# Use a ProcessPoolExecutor to generate the addresses in parallel with concurrent.futures.ProcessPoolExecutor() as executor: # Divide the addresses evenly among the available CPU cores addresses_per_core = num_addresses // num_cores
# Submit a task for each batch of addresses to the executor tasks = [] for i in range(num_cores): start = i * addresses_per_core end = (i+1) * addresses_per_core tasks.append(executor.submit(worker, start, end))
# Wait for the tasks to complete and retrieve the results addresses = [] for task in concurrent.futures.as_completed(tasks): addresses.extend(task.result())
# Write the addresses to a file np.savetxt('addresses_1M_with_singleCore.txt', addresses, fmt='%s')
Running this under one single core, now I get 26.5 sec for 1 million generated addresses. This is a rate of 37,735 keys/second. I am curious to see your program using all available cores. Ok, finally I managed to use your multithread program with my script. Results: 30s to generate 16.4 M of addresses, about 540k addresses / s, and store them in a file. time python3 gen_batches.py > addresses.out
real 0m29,810s user 8m22,402s sys 0m6,273s
wc addresses.out
16474040 16474040 575934502
less addresses.out
18GW1MFwpYZgmRSy8R4wgjUtBnscJtXeUZ 1FXUP9HViWxrtgAvqbpgVrd69yarx6Njdp 1MuxV99fRFnhoNopdxV7kkQB4u14chCtqA 17AzXPYExdE8nxkiV6zJGLuJq32WkAZ134 12DUcGmFMkmXV8tYihM2jLQ36pc4zLBDP6 1AqwPisfi9hDHoF95SEoSEVN89fX8NSGjo 17qRbvdShkoCDw3XJGhEqxaFkQHaK36Yk1 187x8hPiVpRLGDRsvy4nreeMNW7aW9zuFv 1EGSDnc2j7p3qsPJsPakKgavCTz4szYU3w 1F4KjKLNqQSbmw9xsJurRVQ3RciL7Kox7g 1AKaHBfhMEedrtnjGgmFFsdG3SzyN3hpcZ 1GaWuuPPM747Na3CTwaR3DcewoBHc9VVSv 12VeWT4jZCep17HJswMtfCEqh14oDcRr3L 16MBC6WLWMvNeexYYX853Ucf2ZsPoYLRoS 1JVrhzEKTcgzGtSc9u9LpFjksFZiQveFT6 17kz2Wpry3vnLM6RMjB3KXoG6kRxjeDQcj 1TBh3q7vQoTmgX6pY75ADHDSkcaWkmCvd 13QVDFeeWkErhTAFqX3SP2YzrzWt3Bh7iu 1GPyzJC8Ey8PasHn2Qa8aFanjrXuE1aNK5 17QE8iNrtLnju5pinG1vdoCVZpn8zbrM7S 17nKRy1XdKdroWXPsnsd4RvxWKVySZxath 1KWaY8K824oEFk5q4tZioCZ86viLJuKNgS 141m3BUZNjMxbs4a9Cb6SbCmEzx4nPJKCL 12ueqsLkT1XCVheGM34uQWW2fpnhVvtwmE 14eH2SFvCq3fxmrK9NgKTxfMCeKixNwQ6c 1G9CaAqoKJSfTRyGcvPhVFewLRXKWzkwh7 15RthH7DBuDSmYcFCYanUhBsrdEYzBahNw 13BTmQ2gCaZ8x4T7Sba9k2MRBSDRrZLy6u 1NpbKVze4pPVCghjaa2CV7LfRkotCNu76Y 1HfQ42v7DEDHEuQMhH5caPzX2RgtSmoYWw ...
Only 1.3 s to generate 16.4 M public keys (without writing) 30s to generate 16.4 M addresses and store them in a file (24s if each thread writes on the file without waiting for the others)
|
|
|
20
|
Bitcoin / Development & Technical Discussion / Re: the fastest possible way to mass-generate addresses in Python
|
on: December 30, 2022, 06:05:25 PM
|
what is third and fourth element representing?
54338240394213138931889225770364196918256374885639854771044914499200701239376 91288621757068410199936994202114003372515557459679014336095768812037691308008
As I recognize, they seem not to be the public keys of the consequent keys 36028797808045094, 36028797808045095, 36028797808045096
The keys are generated in this way: P (P + 1*G , P - 1*G) -> 4 coordinates, x and y * 2 points (P + 2*G , P - 2*G) (P + 3*G , P - 3*G) (P + 4*G , P - 4*G) (P + 5*G , P - 5*G) (P + 6*G , P - 6*G) ..... ..... (P + 2048*G, P - 2048*G) each batch has all the consecutive keys from P - 2048*G to P+2048*G (4097 public keys), but they are not in order batch=[(0,0,0,0)]*2048 #the element number 0 of the list will be the middle point kG=(kx,ky), you can see it as the couple ((k+0)G, (k-0)G) #the element number 1 will be the couple (k+1)G, (k-1)G #the element number 2 will be the couple (k+2)G, (k-2)G #... #the element number 2048 will be the couple (k+2048)G, (k-2048)G #each element of this list is a couple of points -> 4 scalars: x_(k+m)G,y_(k+m)G,x_(k-m)G,y_(k-m)G, #but the first element is only a fake couple batch = [(kx,ky,kx,ky)]+batch #the element number 0 of the list is now the middle point kG=(kx,ky), you can see it as the fake couple (k+0)G, (k-0)G
|
|
|
|