├── historical ├── v1 │ ├── py │ │ ├── dust │ │ │ ├── __init__.py │ │ │ ├── core │ │ │ │ ├── __init__.py │ │ │ │ ├── data_packet.py │ │ │ │ ├── data_packet2.py │ │ │ │ └── dust_packet2.py │ │ │ ├── crypto │ │ │ │ ├── __init__.py │ │ │ │ ├── curve25519.so │ │ │ │ ├── curve25519-donna.dll │ │ │ │ ├── curve25519-donna-c64.so │ │ │ │ ├── pyskein.py │ │ │ │ └── dustUtil.py │ │ │ ├── intro │ │ │ │ ├── __init__.py │ │ │ │ ├── intro.py │ │ │ │ ├── intro_socket.py │ │ │ │ └── intro_packet.py │ │ │ ├── invite │ │ │ │ ├── __init__.py │ │ │ │ └── inviteShell.py │ │ │ ├── server │ │ │ │ ├── __init__.py │ │ │ │ ├── activeServices.py │ │ │ │ └── lite_router.py │ │ │ ├── util │ │ │ │ ├── __init__.py │ │ │ │ ├── jsonrpc │ │ │ │ │ └── __init__.py │ │ │ │ ├── ymap.py │ │ │ │ └── safethread.py │ │ │ ├── extensions │ │ │ │ ├── __init__.py │ │ │ │ ├── lite │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── lite_socket.py │ │ │ │ │ └── lite_socket2.py │ │ │ │ ├── onion │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── onion_packet.py │ │ │ │ ├── utp │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── demo.py │ │ │ │ │ └── inetd-test.py │ │ │ │ ├── multiplex │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── multiplex_socket.py │ │ │ │ └── stego │ │ │ │ │ ├── gen.sh │ │ │ │ │ ├── words.txt │ │ │ │ │ ├── slashdot.txt │ │ │ │ │ ├── unrandom │ │ │ │ │ ├── PNRP-trafficdump │ │ │ │ │ ├── encode.py │ │ │ │ │ └── stats.py │ │ │ │ │ ├── test.py │ │ │ │ │ ├── encode.py │ │ │ │ │ └── gen.py │ │ │ ├── services │ │ │ │ ├── __init__.py │ │ │ │ ├── chat │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── chatService.py │ │ │ │ ├── file │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── file_socket.py │ │ │ │ │ └── file_packet.py │ │ │ │ ├── http │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── proxy_packet.py │ │ │ │ │ └── proxyback_packet.py │ │ │ │ ├── mail │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── mailService.py │ │ │ │ ├── socks │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── socks.txt │ │ │ │ │ ├── proxy_packet.py │ │ │ │ │ └── proxyback_packet.py │ │ │ │ ├── tracker │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── trackbackClient.py │ │ │ │ │ ├── trackerClient.py │ │ │ │ │ ├── trackerService.py │ │ │ │ │ ├── trackbackService.py │ │ │ │ │ ├── trackbackHandler.py │ │ │ │ │ └── trackerHandler.py │ │ │ │ ├── dustmail │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── dustmailbackClient.py │ │ │ │ │ ├── dustmailClient.py │ │ │ │ │ ├── dustmailbackHandler.py │ │ │ │ │ ├── dustmailbackService.py │ │ │ │ │ ├── dustmailService.py │ │ │ │ │ ├── notify.py │ │ │ │ │ ├── dustmail_packet.py │ │ │ │ │ └── add.py │ │ │ │ ├── socks2 │ │ │ │ │ ├── echo_server.py │ │ │ │ │ ├── tcp_proxy.py │ │ │ │ │ ├── socks.py │ │ │ │ │ ├── client_server.py │ │ │ │ │ ├── shared.py │ │ │ │ │ ├── dustSocksServer.py │ │ │ │ │ ├── loopback.py │ │ │ │ │ └── socksDustProxy.py │ │ │ │ └── socks3 │ │ │ │ │ ├── socks.py │ │ │ │ │ ├── socksDustProxy.py │ │ │ │ │ ├── shared.py │ │ │ │ │ ├── loopback.py │ │ │ │ │ └── dustSocksServer.py │ │ │ ├── test │ │ │ │ ├── pbkdf_setup.py │ │ │ │ ├── printIP.py │ │ │ │ ├── sample.txt │ │ │ │ ├── print-random.py │ │ │ │ ├── test-pbkdf.py │ │ │ │ ├── test-curve.py │ │ │ │ ├── multiplex-recv.py │ │ │ │ ├── print-invites.py │ │ │ │ ├── test-cskein.py │ │ │ │ ├── test-pyskein.py │ │ │ │ ├── multiplex-send.py │ │ │ │ ├── TestSkein.py │ │ │ │ ├── create-data-packet.py │ │ │ │ ├── lite-chat-send.py │ │ │ │ ├── multiplex-router.py │ │ │ │ ├── intro-send.py │ │ │ │ ├── create-chained-data-packet.py │ │ │ │ ├── mail-send.py │ │ │ │ ├── mmail-send.py │ │ │ │ ├── chat-send.py │ │ │ │ ├── file-getmeta.py │ │ │ │ ├── file-get.py │ │ │ │ ├── TestPureSkein.py │ │ │ │ ├── intro-mmail-send.py │ │ │ │ ├── mail-recv.py │ │ │ │ ├── test-tracker.py │ │ │ │ └── file-fetch.py │ │ │ └── commands │ │ │ │ ├── send.sh │ │ │ │ ├── tracker.sh │ │ │ │ ├── go.sh │ │ │ │ ├── lite-serve.py │ │ │ │ ├── gen.py │ │ │ │ ├── gen-endpoint.py │ │ │ │ ├── process-invite.py │ │ │ │ ├── tracker-serve.py │ │ │ │ ├── make-invite.py │ │ │ │ └── serve.py │ │ ├── .gitignore │ │ ├── config │ │ │ ├── fileService.yaml │ │ │ ├── id.yaml │ │ │ └── emailServer.yaml │ │ ├── bin │ │ │ ├── update.sh │ │ │ └── build.sh │ │ ├── deps │ │ │ ├── PyYAML-3.09.tar.gz │ │ │ ├── bitstring-1.2.0.zip │ │ │ └── pyskein-0.6.tar.gz │ │ ├── docs │ │ │ ├── DustMail-Howto.txt │ │ │ └── howto.txt │ │ └── setup.py │ ├── java │ │ ├── lib │ │ │ ├── dust.jar │ │ │ ├── skein.jar │ │ │ └── curve25519.jar │ │ ├── src │ │ │ └── dust │ │ │ │ ├── crypto │ │ │ │ ├── DustPRNG.java │ │ │ │ ├── Key.java │ │ │ │ ├── Curve.java │ │ │ │ ├── DustConstants.java │ │ │ │ ├── Keypair.java │ │ │ │ ├── DustUtil.java │ │ │ │ ├── DustCipher.java │ │ │ │ └── SkeinPRNG.java │ │ │ │ ├── test │ │ │ │ ├── sample.txt │ │ │ │ ├── TestUtil.java │ │ │ │ ├── TestCurve.java │ │ │ │ ├── TestDustPacket.java │ │ │ │ └── TestDustCrypto.java │ │ │ │ └── core │ │ │ │ └── DataPacket.java │ │ └── build.xml │ └── skein-java │ │ ├── lib │ │ └── skein.jar │ │ ├── src │ │ ├── skein.jar │ │ └── nl │ │ │ └── warper │ │ │ ├── skein │ │ │ ├── Skein.class │ │ │ ├── UBI64.class │ │ │ ├── Util.class │ │ │ ├── SkeinMain.class │ │ │ ├── SkeinTest.class │ │ │ ├── Skein$Tweak.class │ │ │ ├── SkeinMain$1.class │ │ │ └── Skein$Configuration.class │ │ │ └── threefish │ │ │ ├── ThreefishImpl.class │ │ │ └── ThreefishSecretKey.class │ │ └── build.xml └── haskell2014 │ ├── Dust-command │ ├── Setup.hs │ ├── INSTALL │ ├── Dust-command.cabal │ └── Dust │ │ └── Control │ │ ├── State.hs │ │ └── Lazy.hs │ ├── Dust │ ├── Setup.hs │ ├── Dust │ │ ├── Model │ │ │ ├── Stats.hs │ │ │ ├── Port.hs │ │ │ └── PacketLength.hs │ │ ├── Core │ │ │ └── Invite.hs │ │ └── Network │ │ │ ├── UdpServer.hs │ │ │ ├── TcpClient.hs │ │ │ ├── Util.hs │ │ │ ├── TcpServer.hs │ │ │ ├── DustClient.hs │ │ │ └── DustServer.hs │ ├── INSTALL │ └── tests │ │ ├── TestModel.hs │ │ └── TestCore.hs │ ├── Dust-crypto │ ├── Setup.hs │ ├── Dust │ │ └── Crypto │ │ │ ├── Hash.hs │ │ │ ├── ECDH.hs │ │ │ └── ECDSA.hs │ ├── INSTALL │ └── Dust-crypto.cabal │ └── INSTALL ├── go ├── .dir-locals.el ├── model1 │ ├── math.go │ ├── decoder.go │ ├── model.go │ └── encoder.go ├── v2 │ ├── Dust2_proxy │ │ └── optional_privmodels.go │ ├── Dust2_tool │ │ └── optional_privmodels.go │ ├── interface │ │ ├── go.mod │ │ ├── errors.go │ │ ├── go.sum │ │ ├── address.go │ │ └── mode_rawstream.go │ ├── crypting │ │ ├── params.go │ │ ├── identity.go │ │ └── errors.go │ └── shaping │ │ ├── timer.go │ │ ├── shaper.go │ │ └── codec.go ├── prim1 │ ├── value.go │ ├── derivation.go │ ├── sym_cipher.go │ ├── value_repr.go │ ├── asym_repr.go │ ├── asym_dh.go │ └── ntor.go ├── dist │ ├── exponential.go │ ├── uniform.go │ ├── laplace.go │ ├── poisson.go │ ├── multinomial.go │ ├── norm.go │ └── constants.go ├── NOTES └── proc │ ├── event.go │ └── request_reply.go ├── .DS_Store ├── modelgen ├── scripts │ ├── run-client.sh │ ├── run-only-server.sh │ ├── run-server.sh │ ├── run.sh │ ├── build-js.sh │ ├── run-only-client.sh │ ├── build.sh │ ├── build-go.sh │ ├── prep.sh │ └── run-base.sh ├── templates │ ├── models.go.airspeed │ ├── models.js.airspeed │ ├── models_test.js.airspeed │ ├── test.js.airspeed │ ├── test.go.airspeed │ └── model.go.airspeed ├── src │ ├── convert-sequences.py │ ├── convert.py │ └── convert-huffman.py ├── INSTALL ├── README ├── examples │ └── dustexample │ │ └── dustexample.go └── lib │ └── jshintrc ├── .idea ├── misc.xml ├── vcs.xml ├── modules.xml ├── Dust.iml └── .gitignore ├── docs └── v2 │ ├── shaping.md │ └── overview.md └── .gitignore /historical/v1/py/dust/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /go/.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((go-mode 2 | (fill-column . 110))) 3 | -------------------------------------------------------------------------------- /historical/v1/py/dust/core/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/intro/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/invite/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/server/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/util/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/.DS_Store -------------------------------------------------------------------------------- /historical/v1/py/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.ip 3 | *.yaml 4 | spool 5 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/lite/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/onion/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/utp/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/chat/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/file/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/http/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/mail/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/tracker/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/util/jsonrpc/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/multiplex/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/__init__.py: -------------------------------------------------------------------------------- 1 | # python is stupid 2 | -------------------------------------------------------------------------------- /historical/v1/py/config/fileService.yaml: -------------------------------------------------------------------------------- 1 | root: public_files 2 | incoming: incoming -------------------------------------------------------------------------------- /historical/haskell2014/Dust-command/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | 4 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-crypto/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | 4 | -------------------------------------------------------------------------------- /historical/v1/java/lib/dust.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/java/lib/dust.jar -------------------------------------------------------------------------------- /historical/v1/java/lib/skein.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/java/lib/skein.jar -------------------------------------------------------------------------------- /historical/v1/py/bin/update.sh: -------------------------------------------------------------------------------- 1 | python3.1 setup.py bdist_egg upload 2 | rm -rf build 3 | rm -rf Dust.egg-info 4 | -------------------------------------------------------------------------------- /historical/v1/java/lib/curve25519.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/java/lib/curve25519.jar -------------------------------------------------------------------------------- /historical/v1/skein-java/lib/skein.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/lib/skein.jar -------------------------------------------------------------------------------- /historical/v1/skein-java/src/skein.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/skein.jar -------------------------------------------------------------------------------- /modelgen/scripts/run-client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . scripts/run-base.sh 3 | scripts/run-only-client.sh $1 $2 $PROTOCOL 4 | -------------------------------------------------------------------------------- /historical/v1/py/deps/PyYAML-3.09.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/deps/PyYAML-3.09.tar.gz -------------------------------------------------------------------------------- /historical/v1/py/deps/bitstring-1.2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/deps/bitstring-1.2.0.zip -------------------------------------------------------------------------------- /historical/v1/py/deps/pyskein-0.6.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/deps/pyskein-0.6.tar.gz -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/gen.sh: -------------------------------------------------------------------------------- 1 | wget -O words.html "$1" 2 | html2text words.html >words.txt 3 | python3.0 gen.py -------------------------------------------------------------------------------- /modelgen/scripts/run-only-server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ~/go/bin/DustProxy -d --incomplete -c $DESTINATION in ~/DustProxy.invite 3 | -------------------------------------------------------------------------------- /historical/v1/py/bin/build.sh: -------------------------------------------------------------------------------- 1 | rm `find . -iname "*.pyc"` 2 | python3.1 setup.py bdist_egg 3 | rm -rf build 4 | rm -rf Dust.egg-info -------------------------------------------------------------------------------- /historical/v1/py/dust/crypto/curve25519.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/dust/crypto/curve25519.so -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/words.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/dust/extensions/stego/words.txt -------------------------------------------------------------------------------- /historical/v1/py/dust/crypto/curve25519-donna.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/dust/crypto/curve25519-donna.dll -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/slashdot.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/dust/extensions/stego/slashdot.txt -------------------------------------------------------------------------------- /modelgen/scripts/run-server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . scripts/run-base.sh 3 | echo "Launching $DUSTIP $DUSTPROXYID" 4 | scripts/run-only-server.sh 5 | -------------------------------------------------------------------------------- /historical/v1/py/dust/crypto/curve25519-donna-c64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/dust/crypto/curve25519-donna-c64.so -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/Skein.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/Skein.class -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/UBI64.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/UBI64.class -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/Util.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/Util.class -------------------------------------------------------------------------------- /modelgen/templates/models.go.airspeed: -------------------------------------------------------------------------------- 1 | package $packageBase 2 | 3 | import ( 4 | #foreach($model in $models) 5 | _ "$packageName/$model" 6 | #end 7 | ) 8 | -------------------------------------------------------------------------------- /modelgen/templates/models.js.airspeed: -------------------------------------------------------------------------------- 1 | package $packageBase 2 | 3 | import ( 4 | #foreach($model in $models) 5 | _ "$packageName/$model" 6 | #end 7 | ) 8 | -------------------------------------------------------------------------------- /historical/v1/py/config/id.yaml: -------------------------------------------------------------------------------- 1 | [43aafb64bc96460f3928f6068b2a01aa87bac16da6dc034b4525d1837e9cb85e, 48ef7b8c0c6343b332a02862335c11e0cd2b38f0d7d6a3647a7f8f2661d1c946] 2 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/pbkdf_setup.py: -------------------------------------------------------------------------------- 1 | from dust.crypto import dust 2 | 3 | passwd="testpw" 4 | prng=dust.DustPRNG() 5 | salt=prng.getBytes(32) 6 | pbkdf=dust.pbkdf -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/SkeinMain.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/SkeinMain.class -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/SkeinTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/SkeinTest.class -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/Skein$Tweak.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/Skein$Tweak.class -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/SkeinMain$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/SkeinMain$1.class -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/unrandom/PNRP-trafficdump: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/py/dust/extensions/stego/unrandom/PNRP-trafficdump -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/threefish/ThreefishImpl.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/threefish/ThreefishImpl.class -------------------------------------------------------------------------------- /modelgen/scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . scripts/run-base.sh 3 | scripts/run-only-server.sh & 4 | scripts/run-only-client.sh $DUSTIP $DUSTPROXYID $PROTOCOL 5 | killall DustProxy 6 | -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/skein/Skein$Configuration.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/skein/Skein$Configuration.class -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/send.sh: -------------------------------------------------------------------------------- 1 | python3.1 dust/services/dustmail/send.py test 7002 [2001:470:1f0e:63a::2]:7040 7d0aeb009a71496de7be1753cfcd8797f33ee81c3d8908416588755542355829 "$1" 2 | -------------------------------------------------------------------------------- /historical/v1/skein-java/src/nl/warper/threefish/ThreefishSecretKey.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/Dust/HEAD/historical/v1/skein-java/src/nl/warper/threefish/ThreefishSecretKey.class -------------------------------------------------------------------------------- /modelgen/scripts/build-js.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | # compile-go.py [language] [modelDir] [packageName] [packageDir] 4 | python src/compile.py js ../go/models DustTestModels ~/js/DustTestModels 5 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /modelgen/scripts/run-only-client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Connecting to $1 $2 $3" 3 | echo "Listening on localhost:16680" 4 | ~/go/bin/DustProxy -d --incomplete -r 127.0.0.1 -l 127.0.0.1:16680 out $1:16667 $2 m=$3 5 | -------------------------------------------------------------------------------- /modelgen/scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | # compile-go.py [language] [modelDir] [packageName] [packageDir] 4 | python src/compile.py "$1" "$2" "$3" "$4" 5 | pushd "$4" 6 | go install 7 | #go test 8 | popd 9 | -------------------------------------------------------------------------------- /historical/v1/py/config/emailServer.yaml: -------------------------------------------------------------------------------- 1 | smtpHost: blanu.net 2 | senders: { 3 | "[2001:0:53aa:64c:1cb8:53c2:527c:2edb]:8001": {to: ['blanu.net'], from: ['blanu.net']}, 4 | "*": {to: ['blanu.net'], from: ['blanu.net']} 5 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/tracker.sh: -------------------------------------------------------------------------------- 1 | python3.1 dust/commands/make-invite.py test 7040 6 2 | rm config/outgoing_invites.ip 3 | python3.1 dust/commands/process-invite.py test test 4 | python3.1 dust/commands/tracker-serve.py 7040 6 test -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/dustmailbackClient.py: -------------------------------------------------------------------------------- 1 | from dust.util.jsonrpc.proxy import ServiceProxy 2 | 3 | class DustmailbackClient(ServiceProxy): 4 | def __init__(self, router): 5 | ServiceProxy.__init__(self, router, serviceName="dustmailback") 6 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/dustmailClient.py: -------------------------------------------------------------------------------- 1 | from dust.util.jsonrpc.proxy import ServiceProxy 2 | 3 | class DustmailClient(ServiceProxy): 4 | def __init__(self, router, addr): 5 | ServiceProxy.__init__(self, router, addr=addr, serviceName="dustmail") 6 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/tracker/trackbackClient.py: -------------------------------------------------------------------------------- 1 | from dust.util.jsonrpc.proxy import ServiceProxy 2 | 3 | class TrackbackClient(ServiceProxy): 4 | def __init__(self, router, addr): 5 | ServiceProxy.__init__(self, router, addr=addr, serviceName="trackback") 6 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/tracker/trackerClient.py: -------------------------------------------------------------------------------- 1 | from dust.util.jsonrpc.proxy import ServiceProxy 2 | 3 | class TrackerClient(ServiceProxy): 4 | def __init__(self, router, addr=None): 5 | ServiceProxy.__init__(self, router, addr=addr, serviceName="tracker") 6 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/printIP.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dust.core.util import getPublicIP 4 | 5 | ipv=sys.argv[1] 6 | 7 | if ipv=='6': 8 | print(getPublicIP(True)) 9 | elif ipv=='4': 10 | print(getPublicIP(False)) 11 | else: 12 | print('Unknown ip version:', ipv) -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/go.sh: -------------------------------------------------------------------------------- 1 | export PYTHONPATH=. 2 | python3.1 dust/commands/make-invite.py test 7000 6 3 | #rm config/outgoing_invites.ip 4 | python3.1 dust/commands/process-invite.py test test 5 | python3.1 dust/commands/serve.py 7000 6 test [2001:0:53aa:64c:306f:460a:baa2:c211]:7040 -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/DustPRNG.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | import dust.crypto.SkeinPRNG; 4 | import dust.crypto.DustConstants; 5 | 6 | public class DustPRNG extends SkeinPRNG 7 | { 8 | public DustPRNG() 9 | { 10 | super(DustConstants.PRNG_PERS); 11 | } 12 | } -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/lite-serve.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dust.server.lite_router import LitePacketRouter 4 | from dust.crypto.keys import KeyManager 5 | 6 | inport=int(sys.argv[1]) 7 | v6=sys.argv[2] 8 | 9 | keys=KeyManager() 10 | 11 | LitePacketRouter(v6, inport, keys) 12 | 13 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/sample.txt: -------------------------------------------------------------------------------- 1 | ectester@blanu.net 2 | ectest@blanu.net 3 | EC Test Message 4 | This is a test of the elliptical curve encryption delivery of a RFC2822 test 5 | message. Hopefully it will not be filtered and will be delivered successfully, 6 | proving that the mail daemon works properly. 7 | . 8 | -------------------------------------------------------------------------------- /modelgen/scripts/build-go.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | # compile.py [language] [modelDir] [packageName] [packageDir] 4 | python src/compile.py go ../go/models "git.torproject.org/pluggable-transports/obfs4.git/transports/Dust2/models" ~/go/src/git.torproject.org/pluggable-transports/obfs4.git/transports/Dust2/models 5 | -------------------------------------------------------------------------------- /modelgen/templates/models_test.js.airspeed: -------------------------------------------------------------------------------- 1 | #foreach($model in $models) 2 | var $model=require("$packageName/${model}.js") 3 | #end 4 | 5 | #foreach($model in $models) 6 | var ${model}Instance=${model}() 7 | var ${model}Result=${model}Instance.WholeStreamDuration() 8 | console.log(${model}Result); 9 | #end 10 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/test/sample.txt: -------------------------------------------------------------------------------- 1 | ectester@blanu.net 2 | ectest@blanu.net 3 | EC Test Message 4 | This is a test of the elliptical curve encryption delivery of a RFC2822 test 5 | message. Hopefully it will not be filtered and will be delivered successfully, 6 | proving that the mail daemon works properly. 7 | . 8 | -------------------------------------------------------------------------------- /go/model1/math.go: -------------------------------------------------------------------------------- 1 | package model1 2 | 3 | func clampUint16(n float64) uint16 { 4 | // Use positive test for in-range to handle NaN properly, just in case. 5 | switch { 6 | case 0.0 <= n && n <= 65535.0: 7 | return uint16(n) 8 | case 65535.0 < n: 9 | return 65535 10 | default: 11 | return 0 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /go/v2/Dust2_proxy/optional_privmodels.go: -------------------------------------------------------------------------------- 1 | // +build privmodels 2 | 3 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 4 | // the MIT-style license in the file ../../LICENSE.md. 5 | 6 | package main 7 | 8 | import _ "caolta3iaejox3z4madc5wmp4z.uuid/Dust_privmodels" 9 | -------------------------------------------------------------------------------- /go/v2/Dust2_tool/optional_privmodels.go: -------------------------------------------------------------------------------- 1 | // +build privmodels 2 | 3 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 4 | // the MIT-style license in the file ../../LICENSE.md. 5 | 6 | package main 7 | 8 | import _ "caolta3iaejox3z4madc5wmp4z.uuid/Dust_privmodels" 9 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/test.py: -------------------------------------------------------------------------------- 1 | from encode import WordsEncoding 2 | 3 | bs=b'\x00\x01\xFF' 4 | 5 | w=WordsEncoding() 6 | words=w.encode(bs) 7 | text=' '.join(words) 8 | words2=text.split(' ') 9 | bs2=w.decode(words2) 10 | 11 | print(bs) 12 | print(words) 13 | print(text) 14 | print(words2) 15 | print(bs2) -------------------------------------------------------------------------------- /historical/v1/py/dust/services/chat/chatService.py: -------------------------------------------------------------------------------- 1 | from dust.core.util import encodeAddress 2 | 3 | class ChatHandler: 4 | def __init__(self): 5 | pass 6 | 7 | def handle(self, msock, msg, addr): 8 | print('Message from '+encodeAddress(addr)+':') 9 | print(msg.decode('ascii')) 10 | print('-----------------') 11 | -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3.1 2 | import os 3 | import sys 4 | # python sucks 5 | sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))) 6 | 7 | from dust.crypto.keys import KeyManager 8 | 9 | keys=KeyManager() 10 | keys.createKeypair() 11 | keys.saveKeypair('config/id.yaml') 12 | -------------------------------------------------------------------------------- /.idea/Dust.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /modelgen/scripts/prep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo apt-get install mercurial 3 | pushd ~/go 4 | export GOPATH=~/go 5 | go get code.google.com/p/go.crypto/curve25519 6 | go get git.torproject.org/pluggable-transports/obfs4.git/common/csrand 7 | go get github.com/dchest/skein 8 | go get github.com/agl/ed25519/extra25519 9 | go get github.com/op/go-logging 10 | popd 11 | -------------------------------------------------------------------------------- /go/v2/interface/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/blanu/Dust/go/v2/interface 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/OperatorFoundation/ed25519 v0.0.0-20200225224545-b22b4bd3ddef // indirect 7 | github.com/blanu/Dust v1.0.1 8 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 9 | golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/print-random.py: -------------------------------------------------------------------------------- 1 | from dust.crypto.dust import DustPRNG 2 | 3 | r=DustPRNG() 4 | print(r.getBytes(10)) 5 | print(r.getBytes(20)) 6 | print(r.getBytes(1)) 7 | 8 | print(r.getInt()) 9 | print(r.getInt()) 10 | print(r.getInt()) 11 | print(r.getInt()) 12 | 13 | print(r.getInt(255)) 14 | print(r.getInt(255)) 15 | print(r.getInt(255)) 16 | print(r.getInt(255)) 17 | -------------------------------------------------------------------------------- /modelgen/templates/test.js.airspeed: -------------------------------------------------------------------------------- 1 | var $packagename=require("./${packagename}.js"); 2 | var instance=new ${packagename}.${packagename}Codec(); 3 | console.log(instance); 4 | 5 | var duration=instance.WholeStreamDuration(); 6 | console.log(duration); 7 | 8 | var ita=instance.NextPacketSleep(); 9 | console.log(ita); 10 | 11 | var len=instance.NextPacketLength(); 12 | console.log(len); 13 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/Key.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | import nl.warper.skein.Util; 4 | 5 | public class Key 6 | { 7 | byte[] bytes; 8 | 9 | public Key(byte[] b) 10 | { 11 | bytes=b; 12 | } 13 | 14 | public byte[] getBytes() 15 | { 16 | return bytes; 17 | } 18 | 19 | public String toString() 20 | { 21 | return Util.tohex(bytes); 22 | } 23 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/unrandom/encode.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from encoder import Encoder 4 | 5 | f=open('stats.out') 6 | lines=f.readlines() 7 | f.close() 8 | 9 | dist=[] 10 | for x in range(len(lines)): 11 | p=float(lines[x].strip()) 12 | dist.append((p, x)) 13 | 14 | enc=Encoder(dist) 15 | enc.encode(sys.argv[1], sys.argv[2]) 16 | enc.decode(sys.argv[2], sys.argv[3]) 17 | 18 | 19 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/dustmailbackHandler.py: -------------------------------------------------------------------------------- 1 | from dust.util.ymap import YamlMap 2 | 3 | class TrackbackHandler: 4 | def __init__(self, router): 5 | self.state=YamlMap('config/trackback.yaml') 6 | 7 | def putPeerForEndpoint(self, key, value): 8 | try: 9 | map=self.state['endpoints'] 10 | map[key]=value 11 | self.state.save() 12 | except: 13 | pass 14 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Model/Stats.hs: -------------------------------------------------------------------------------- 1 | module Dust.Model.Stats 2 | ( 3 | histogram 4 | ) 5 | where 6 | 7 | import qualified Data.Map as M 8 | import Data.List (foldl') 9 | 10 | -- count the number of instances each symbol occurs in a list 11 | histogram :: Ord a => [a] -> [(a,Int)] 12 | histogram xs = 13 | M.toList . foldl' insert M.empty $ xs 14 | where 15 | insert a k = M.insertWith' (+) k 1 a 16 | 17 | -------------------------------------------------------------------------------- /modelgen/src/convert-sequences.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import json 3 | 4 | f=open(sys.argv[1]) 5 | s=f.read() 6 | f.close() 7 | 8 | seqs=json.loads(s) 9 | 10 | f=open(sys.argv[2]) 11 | s=f.read() 12 | f.close() 13 | 14 | data=json.loads(s) 15 | data['incomingModel']['sequence']=seqs['incoming'] 16 | data['outgoingModel']['sequence']=seqs['outgoing'] 17 | 18 | f=open(sys.argv[2], 'w') 19 | f.write(json.dumps(data)) 20 | f.close() 21 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/test-pbkdf.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | 3 | from dust.crypto.dust import DustPRNG 4 | 5 | passwd="testpw" 6 | 7 | prng=DustPRNG() 8 | salt=prng.getBytes(32) 9 | 10 | setup="import pbkdf_setup" 11 | 12 | stmt=""" 13 | print(pbkdf_setup.pbkdf(pbkdf_setup.passwd, pbkdf_setup.salt)) 14 | """ 15 | 16 | r=10 17 | 18 | t=timeit.Timer(stmt, setup) 19 | try: 20 | print(t.timeit(number=r)/r) 21 | except: 22 | t.print_exc() -------------------------------------------------------------------------------- /historical/v1/py/dust/server/activeServices.py: -------------------------------------------------------------------------------- 1 | from dust.util.ymap import YamlMap 2 | 3 | activeServices={} 4 | 5 | paths=YamlMap('config/activeServices.yaml') 6 | for serviceName in paths.keys(): 7 | modName, clsName=paths[serviceName] 8 | path=modName.split('.') 9 | mod=__import__(modName) 10 | for name in path[1:]: 11 | mod=getattr(mod, name) 12 | cls=getattr(mod, clsName) 13 | obj=cls() 14 | activeServices[serviceName]=obj 15 | -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/gen-endpoint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | import sys 4 | # python sucks 5 | sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))) 6 | 7 | from dust.crypto.keys import KeyManager 8 | 9 | keys=KeyManager() 10 | keys.createKeypair() 11 | 12 | dustdir=os.path.expanduser("~/.dust") 13 | if not os.path.exists(dustdir): 14 | os.mkdir(dustdir) 15 | keys.saveKeypair(dustdir+'/endpoint.yaml') 16 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/echo_server.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | import monocle 4 | from monocle import _o 5 | monocle.init(sys.argv[1]) 6 | 7 | from monocle.stack import eventloop 8 | from monocle.stack.network import add_service, Service 9 | 10 | @_o 11 | def echo(conn): 12 | their_message = yield conn.readline() 13 | yield conn.write("you said: %s\r\n" % their_message.strip()) 14 | 15 | add_service(Service(echo, 7050)) 16 | eventloop.run() 17 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/test-curve.py: -------------------------------------------------------------------------------- 1 | from dust.crypto.curve import Keypair, Key 2 | from dust.core.util import encode, decode 3 | 4 | keypair=Keypair(Key(decode('48ef7b8c0c6343b332a02862335c11e0cd2b38f0d7d6a3647a7f8f2661d1c946'), False), Key(decode('43aafb64bc96460f3928f6068b2a01aa87bac16da6dc034b4525d1837e9cb85e'), False)) 5 | session=keypair.createSessionBytes(decode('77516be967ad1a68632a3c8b08c9e032d23ff5b764a7fe49461b9c12b2da0c32')) 6 | print(encode(session)) 7 | 8 | -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/process-invite.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dust.crypto.keys import KeyManager 4 | 5 | passwd=sys.argv[1] 6 | mypasswd=sys.argv[2] 7 | 8 | keys=KeyManager() 9 | keys.setInvitePassword(mypasswd) 10 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 11 | 12 | keys.loadIncomingInvites('config/incoming_invites.ip', passwd) 13 | keys.outgoingInvites.merge(keys.incomingInvites) 14 | 15 | keys.saveOutgoingInvites('config/outgoing_invites.ip', mypasswd) -------------------------------------------------------------------------------- /historical/v1/py/dust/test/multiplex-recv.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from dust.extensions.multiplex_socket import * 4 | from dust.crypto.curve import loadKeypair 5 | 6 | buffsize=102400 7 | host = '::1' 8 | inport=7000 9 | outport=7001 10 | nodeName='A' 11 | 12 | keypair=loadKeypair(nodeName+'-priv.txt', nodeName+'-pub.txt') 13 | 14 | msock=multiplex_socket(keypair) 15 | msock.bind(('', inport)) 16 | msock.connect((host, outport)) 17 | print('result:', msock.mrecvfrom(1024)) 18 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/print-invites.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dust.crypto.keys import KeyManager 4 | 5 | mypasswd=sys.argv[1] 6 | 7 | keys=KeyManager() 8 | keys.setInvitePassword(mypasswd) 9 | 10 | print('Outgoing:') 11 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 12 | print(keys.outgoingInvites) 13 | 14 | print("\n------------------\n") 15 | 16 | print('Incoming:') 17 | keys.loadIncomingInvites('config/incoming_invites.ip') 18 | print(keys.incomingInvites) 19 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-crypto/Dust/Crypto/Hash.hs: -------------------------------------------------------------------------------- 1 | module Dust.Crypto.Hash 2 | ( 3 | digest 4 | ) 5 | where 6 | 7 | import Data.ByteString 8 | import Data.Serialize 9 | import Crypto.Classes 10 | 11 | import Crypto.Skein 12 | 13 | digest :: ByteString -> ByteString 14 | digest bs = 15 | let h = hash' bs :: Skein_256_256 16 | in encode h 17 | 18 | mac :: ByteString -> Key -> ByteString 19 | mac bs key = 20 | let m = skeinMAC' key bs :: Skein_256_256 21 | in encode m 22 | 23 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/unrandom/stats.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | f=open(sys.argv[1], 'rb') 4 | bs=f.read() 5 | f.close() 6 | 7 | counts=[] 8 | for x in range(256): 9 | counts.append(0) 10 | 11 | for b in bs: 12 | i=ord(b) 13 | counts[i]=counts[i]+1 14 | 15 | print(counts) 16 | 17 | for x in range(len(counts)): 18 | counts[x]=float(counts[x])/len(bs) 19 | 20 | print(counts) 21 | 22 | f=open(sys.argv[2], 'w') 23 | for count in counts: 24 | f.write(str(count)+"\n") 25 | f.close() 26 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/INSTALL: -------------------------------------------------------------------------------- 1 | That is only been testing using Haskell platform 2014.2.0.0 64-bit for OS X. It may work with other versions of Haskell. 2 | For best results, follow the instructions on stackage.org to configure your system to use the Stackage packages for your version of Haskell. 3 | Attempts to install Dust using Hackage packages have generally been met with frustration. 4 | 5 | Install Dust: 6 | cabal install --only-dependencies 7 | cabal configure 8 | cabal build 9 | cabal install 10 | -------------------------------------------------------------------------------- /docs/v2/shaping.md: -------------------------------------------------------------------------------- 1 | # Shaping layer for Dust 2.5 2 | 3 | ## Overview 4 | 5 | The shaping layer mediates between a raw stream connection which is expected to transmit statistically uniform 6 | bytes in both directions and a shaped stream connection conforming to the properties of a model. In the Dust 7 | stack, it mediates between uniform streams and visible streams. 8 | 9 | Properties modeled include packet inter-arrival times, fixed byte strings, and probability distributions of 10 | transmitted bytes. 11 | 12 | [XXX] -------------------------------------------------------------------------------- /historical/haskell2014/Dust-command/INSTALL: -------------------------------------------------------------------------------- 1 | That is only been testing using Haskell platform 2014.2.0.0 64-bit for OS X. It may work with other versions of Haskell. 2 | For best results, follow the instructions on stackage.org to configure your system to use the Stackage packages for your version of Haskell. 3 | Attempts to install Dust using Hackage packages have generally been met with frustration. 4 | 5 | Install Dust-command: 6 | cabal install --only-dependencies 7 | cabal configure 8 | cabal build 9 | cabal install 10 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/encode.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | 3 | class WordsEncoding: 4 | def __init__(self, filename='words.yaml'): 5 | f=open(filename, 'r') 6 | self.words=yaml.load(f.read()) 7 | f.close() 8 | 9 | def encode(self, bs): 10 | results=[] 11 | for b in bs: 12 | results.append(self.words[b]) 13 | return results 14 | 15 | def decode(self, ws): 16 | results=bytearray() 17 | for w in ws: 18 | b=self.words.index(w) 19 | results.append(b) 20 | return bytes(results) 21 | -------------------------------------------------------------------------------- /modelgen/INSTALL: -------------------------------------------------------------------------------- 1 | Requirements: Go 1.4, Python 2.7.6, PyYAML 2 | 3 | Put your model files in a dedicated directory. 4 | You cannot build without model files. 5 | You must provide your own model files! 6 | 7 | Run ./build.sh [language] [model-directory] [go-package-path] [corresponding-code-directory] 8 | 9 | Example: ./build.sh go ~/foo-models/ foo.example/our_models ~/go/src/foo.example/our_models 10 | 11 | For testing with DustProxy with the privmodels option, use the following package path: 12 | caolta3iaejox3z4madc5wmp4z.uuid/Dust_privmodels 13 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Core/Invite.hs: -------------------------------------------------------------------------------- 1 | module Dust.Core.Invite 2 | ( 3 | ) 4 | where 5 | 6 | import Network 7 | import Data.ByteString 8 | 9 | import Dust.Crypto.Keys 10 | import Dust.Crypto.Cipher 11 | import Dust.Model.TrafficModel 12 | 13 | data Invite = Invite { 14 | address :: Address, 15 | encryptionKey :: PublicKey, 16 | signingKey :: PublicKey, 17 | model :: TrafficModel, 18 | nonce :: ByteString 19 | } 20 | 21 | data Address = Address { 22 | v6 :: Bool, 23 | host :: String, 24 | port :: PortNumber 25 | } 26 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Network/UdpServer.hs: -------------------------------------------------------------------------------- 1 | module Dust.Network.UdpServer 2 | ( 3 | server 4 | ) where 5 | 6 | import Network (PortID(PortNumber)) 7 | import Network.Socket 8 | import Control.Monad (forever) 9 | 10 | server :: String -> PortNumber -> (Socket -> IO()) -> IO() 11 | server host port@(PortNum iport) handleRequest = withSocketsDo $ do 12 | sock <- socket AF_INET Datagram defaultProtocol 13 | putStrLn $ "Binding to " ++ (show iport) 14 | bindSocket sock (SockAddrInet port iNADDR_ANY) 15 | handleRequest sock 16 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/test-cskein.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from skein import skein512 3 | from dust.core.util import encode 4 | 5 | v3=(sys.version[0]=='3') 6 | 7 | ### Print hash of MSG if called directly ### 8 | if __name__ == "__main__": 9 | if v3: 10 | MSG = bytes("Nobody inspects the spammish repetition", 'ascii') 11 | else: 12 | MSG = "Nobody inspects the spammish repetition" 13 | 14 | hash = skein512(MSG, digest_bits=256).digest() 15 | print(encode(hash)) 16 | 17 | hash = skein512(MSG, digest_bits=512).digest() 18 | print(encode(hash)) 19 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/test-pyskein.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from dust.crypto.pyskein import skein512 3 | from dust.core.util import encode 4 | 5 | v3=(sys.version[0]=='3') 6 | 7 | ### Print hash of MSG if called directly ### 8 | if __name__ == "__main__": 9 | if v3: 10 | MSG = bytes("Nobody inspects the spammish repetition", 'ascii') 11 | else: 12 | MSG = "Nobody inspects the spammish repetition" 13 | 14 | hash = skein512(msg=MSG, digest_bits=256) 15 | print(encode(hash)) 16 | 17 | hash = skein512(msg=MSG, digest_bits=512) 18 | print(encode(hash)) 19 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/dustmailbackService.py: -------------------------------------------------------------------------------- 1 | from dust.core.util import encodeAddress 2 | from dust.util.jsonrpc.serviceHandler import ServiceHandler 3 | from dust.services.tracker.trackbackHandler import TrackbackHandler 4 | 5 | class TrackbackService: 6 | def __init__(self): 7 | self.router=None 8 | 9 | def setRouter(self, r): 10 | self.router=r; 11 | 12 | def handle(self, msock, msg, addr): 13 | print('Tracker message from '+encodeAddress(addr)+':') 14 | trackback=ServiceHandler(TrackbackHandler(self.router)) 15 | trackback.handleRequest(msg.decode('utf-8')) 16 | -------------------------------------------------------------------------------- /modelgen/src/convert.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | 3 | def parse(item): 4 | if item=='': 5 | return None 6 | a=[] 7 | for x in item: 8 | if x=="0": 9 | a.append(False) 10 | elif x=="1": 11 | a.append(True) 12 | return a 13 | 14 | f=open('huffman.export') 15 | s=f.read() 16 | f.close() 17 | 18 | l=s.split("\n") 19 | l=map(parse, l) 20 | l=filter(lambda x: x!=None, l) 21 | 22 | f=open('src/Dust/models/test.yaml') 23 | s=f.read() 24 | f.close() 25 | 26 | data=yaml.load(s) 27 | data['huffman']=l 28 | 29 | f=open('src/Dust/models/test.yaml', 'w') 30 | f.write(yaml.dump(data)) 31 | f.close() 32 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/dustmailService.py: -------------------------------------------------------------------------------- 1 | from dust.core.util import encodeAddress 2 | from dust.util.jsonrpc.serviceHandler import ServiceHandler 3 | from dust.services.dustmail.dustmailHandler import DustmailHandler 4 | 5 | class DustmailService: 6 | def __init__(self): 7 | self.router=None 8 | 9 | def setRouter(self, r): 10 | self.router=r; 11 | 12 | def handle(self, msock, msg, addr): 13 | print('Dustmail message from '+encodeAddress(addr)+': '+msg.decode('ascii')) 14 | dustmail=ServiceHandler(DustmailHandler(self.router)) 15 | dustmail.handleRequest(msg.decode('ascii')) 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/go 3 | # Edit at https://www.gitignore.io/?templates=go 4 | 5 | ### Go ### 6 | # Binaries for programs and plugins 7 | *.exe 8 | *.exe~ 9 | *.dll 10 | *.so 11 | *.dylib 12 | 13 | # Test binary, built with `go test -c` 14 | *.test 15 | 16 | # Output of the go coverage tool, specifically when used with LiteIDE 17 | *.out 18 | 19 | # Dependency directories (remove the comment below to include it) 20 | # vendor/ 21 | 22 | ### Go Patch ### 23 | /vendor/ 24 | /Godeps/ 25 | 26 | # End of https://www.gitignore.io/api/go 27 | 28 | 29 | # Default ignored files 30 | /workspace.xml 31 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-crypto/INSTALL: -------------------------------------------------------------------------------- 1 | That is only been testing using Haskell platform 2014.2.0.0 64-bit for OS X. It may work with other versions of Haskell. 2 | For best results, follow the instructions on stackage.org to configure your system to use the Stackage packages for your version of Haskell. 3 | Attempts to install Dust using Hackage packages have generally been met with frustration. 4 | 5 | Install Dust-crypto: 6 | First install hs-nacl: Get hs-nacl here and follow the instructions to install it: https://github.com/thoughtpolice/hs-nacl 7 | cabal install --only-dependencies 8 | cabal configure 9 | cabal build 10 | cabal install 11 | -------------------------------------------------------------------------------- /historical/v1/py/dust/core/data_packet.py: -------------------------------------------------------------------------------- 1 | from dust.core.dust_packet import DustPacket 2 | 3 | class DataPacket(DustPacket): 4 | def __init__(self): 5 | DustPacket.__init__(self) 6 | 7 | def createDataPacket(self, key, data, entropy): 8 | self.createDustPacket(key, data, entropy) 9 | 10 | def decodeDataPacket(self, key, packet): 11 | self.decodeDustPacket(key, packet) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /historical/v1/py/dust/core/data_packet2.py: -------------------------------------------------------------------------------- 1 | from dust.core.dust_packet2 import DustPacket 2 | 3 | class DataPacket(DustPacket): 4 | def __init__(self): 5 | DustPacket.__init__(self) 6 | 7 | def createDataPacket(self, key, data, entropy): 8 | self.createDustPacket(key, data, entropy) 9 | 10 | def decodeDataPacket(self, key, packet): 11 | self.decodeDustPacket(key, packet) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/tracker/trackerService.py: -------------------------------------------------------------------------------- 1 | from dust.core.util import encodeAddress 2 | from dust.util.jsonrpc.serviceHandler import ServiceHandler 3 | from dust.services.tracker.trackerHandler import TrackerHandler 4 | 5 | class TrackerService: 6 | def __init__(self): 7 | self.router=None 8 | 9 | def setRouter(self, r): 10 | self.router=r; 11 | 12 | def handle(self, msock, msg, addr): 13 | print('Tracker message from '+encodeAddress(addr)+': '+msg.decode('ascii')) 14 | tracker=ServiceHandler(TrackerHandler(self.router, addr)) 15 | print('tracker: '+str(tracker)) 16 | tracker.handleRequest(msg.decode('ascii')) 17 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/test/TestUtil.java: -------------------------------------------------------------------------------- 1 | package dust.test; 2 | 3 | import java.util.Random; 4 | import java.util.Arrays; 5 | 6 | import dust.core.Util; 7 | 8 | public class TestUtil 9 | { 10 | static public void main(String[] args) throws Exception 11 | { 12 | Random random=new Random(); 13 | 14 | byte[] key=new byte[32]; 15 | random.nextBytes(key); 16 | 17 | String s=Util.encode(key); 18 | byte[] b=Util.decode(s); 19 | 20 | System.out.println(Arrays.equals(key, b)); 21 | 22 | int i1=7; 23 | b=Util.intToByteArray(i1, 4); 24 | int i2=Util.byteArrayToInt(b); 25 | System.out.println(i1+" "+i2); 26 | } 27 | } -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Network/TcpClient.hs: -------------------------------------------------------------------------------- 1 | module Dust.Network.TcpClient 2 | ( 3 | client 4 | ) where 5 | 6 | import Network.Socket 7 | import qualified Data.ByteString as B 8 | import qualified Data.ByteString.Lazy as BL 9 | 10 | import Dust.Network.Util 11 | import Dust.Crypto.Cipher 12 | 13 | client :: String -> PortNumber -> (Socket -> IO(Plaintext)) -> IO(Plaintext) 14 | client host port handleRequest = withSocketsDo $ do 15 | sock <- socket AF_INET Stream defaultProtocol 16 | addr <- inet_addr host 17 | connect sock (SockAddrInet port addr) 18 | setSocketOption sock NoDelay 1 19 | 20 | handleRequest sock 21 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/multiplex-send.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from dust.extensions.multiplex.multiplex_socket import * 4 | from dust.crypto.curve import loadKeypair 5 | 6 | buffsize=102400 7 | host = '::1' 8 | outport=7000 9 | inport=7001 10 | nodeName='A' 11 | 12 | keypair=loadKeypair(nodeName+'-priv.txt', nodeName+'-pub.txt') 13 | 14 | msock=multiplex_socket(keypair) 15 | msock.bind((host, inport)) 16 | msock.connect((host, outport)) 17 | msock.msend(b'testA', service='test1') 18 | msock.msendto(b'testB', (host, outport), service='test2') 19 | 20 | msock.connectToService('test3') 21 | 22 | msock.msend(b'testC') 23 | msock.msendto(b'testD', (host, outport)) -------------------------------------------------------------------------------- /historical/v1/py/dust/test/TestSkein.py: -------------------------------------------------------------------------------- 1 | #from dust.crypto.dust import DustPRNG, encrypt, decrypt 2 | from dust.core.util import encode, decode 3 | from dust.crypto.skeinUtil import encrypt, decrypt, hash 4 | 5 | #r=DustPRNG() 6 | #iv=r.getBytes(16) 7 | #key=r.getBytes(32) 8 | key=decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013") 9 | iv=decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013") 10 | 11 | text=b'test data' 12 | 13 | print("hash: "+encode(hash(text))) 14 | print("hash pers: "+encode(hash(text, pers=b"a"))) 15 | 16 | #data=encrypt(key, iv, text) 17 | #print(text) 18 | #print(encode(data)) 19 | #print(decrypt(key, iv, data)) 20 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Model/Port.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric, DefaultSignatures #-} -- For automatic generation of cereal put and get 2 | 3 | module Dust.Model.Port 4 | ( 5 | PortModel(..), 6 | nextPort 7 | ) 8 | where 9 | 10 | import GHC.Generics 11 | import Data.Serialize 12 | import Data.Random 13 | import Data.Random.RVar 14 | import Data.Random.Extras 15 | import Data.Random.Source.IO 16 | import Data.Random.Source.Std 17 | 18 | data PortModel = PortModel [Int] deriving (Eq, Show, Generic) 19 | instance Serialize PortModel 20 | 21 | nextPort :: [Int] -> IO Int 22 | nextPort ports = 23 | let dist = choice ports 24 | in runRVar dist StdRandom :: IO Int 25 | 26 | -------------------------------------------------------------------------------- /historical/v1/py/docs/DustMail-Howto.txt: -------------------------------------------------------------------------------- 1 | Setup 2 | 3 | You need an invite to use DustMail. The first time you run the reader (dust/services/dustmail/reader.py), it will prompt 4 | you for an invite, either pasted in or loaded from a file. 5 | 6 | The reader will configure your dust client to be capable of receiving DustMail packets. 7 | 8 | Commands 9 | 10 | a: add invite - Paste in an invite code, or load one from a file. It will be added to your address book. 11 | i: make invite - Display an invite code to be copied, save it to a file, or send it via email. 12 | s: send message - Send a message to someone in your address book. 13 | 14 | l: list messages 15 | num: read message num 16 | x: quit 17 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/Curve.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | import djb.Curve25519; 4 | import dust.crypto.Keypair; 5 | 6 | public class Curve 7 | { 8 | static public Keypair createKeypair(byte[] entropy) 9 | { 10 | byte[] pub=new byte[32]; 11 | byte[] secret=new byte[32]; 12 | 13 | System.arraycopy(entropy, 0, secret, 0, 32); 14 | 15 | Curve25519.keygen(pub, null, secret); 16 | 17 | return new Keypair(new Key(secret), new Key(pub)); 18 | } 19 | 20 | static public byte[] createShared(byte[] secret, byte[] pubkey2) 21 | { 22 | byte[] shared=new byte[32]; 23 | 24 | Curve25519.curve(shared, secret, pubkey2); 25 | 26 | return shared; 27 | } 28 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/crypto/pyskein.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | v3=(sys.version[0]=='3') 4 | 5 | try: 6 | from skein import skein512 as cskein512 7 | 8 | def skein512(msg=None, mac=None, pers=None, nonce=None, tree=None, digest_bits=512): 9 | if msg==None: 10 | msg=bytes('', 'ascii') 11 | if mac==None: 12 | mac=bytes('', 'ascii') 13 | if pers==None: 14 | pers=bytes('', 'ascii') 15 | if nonce==None: 16 | nonce=bytes('', 'ascii') 17 | return cskein512(msg, mac=mac, pers=pers, nonce=nonce, tree=tree, digest_bits=digest_bits).digest() 18 | # raise(Exception()) 19 | except: 20 | #print('Using pure python skein') 21 | from dust.crypto.skein512 import skein512 22 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/create-data-packet.py: -------------------------------------------------------------------------------- 1 | from dust.crypto.keys import KeyManager 2 | from dust.core.data_packet import DataPacket 3 | from dust.core.util import encode, decode 4 | 5 | keys=KeyManager() 6 | #psk=keys.entropy.getBytes(32) 7 | 8 | psk=decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013") 9 | 10 | packet=DataPacket() 11 | packet.createDataPacket(psk, b"test #3", keys.entropy) 12 | print('packet:', packet) 13 | print('packetData:', encode(packet.packet)) 14 | 15 | print('------------------------') 16 | 17 | p2=DataPacket() 18 | p2.decodeDataPacket(psk, packet.packet) 19 | print(p2) 20 | print('checkMac:', p2.checkMac()) 21 | print('checkTimestamp:', p2.checkTimestamp()) -------------------------------------------------------------------------------- /historical/v1/py/dust/test/lite-chat-send.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from dust.extensions.multiplex.lite_multiplex_socket import * 3 | from dust.core.util import getPublicIP 4 | from dust.crypto.keys import KeyManager 5 | 6 | ipv=sys.argv[1] 7 | if ipv=='4': 8 | v6=False 9 | else: 10 | v6=True 11 | inport=int(sys.argv[2]) 12 | outport=int(sys.argv[3]) 13 | 14 | host=getPublicIP(v6) 15 | dest=host 16 | 17 | keys=KeyManager() 18 | 19 | msock=lite_multiplex_socket(keys) 20 | msock.bind((host, inport)) 21 | msock.connect((dest, outport)) 22 | msock.connectToService('chat') 23 | 24 | msg='' 25 | while msg!='.': 26 | print('>> ', end='') 27 | msg=sys.stdin.readline().strip() 28 | msock.msend(msg.encode('ascii')) 29 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/http/proxy_packet.py: -------------------------------------------------------------------------------- 1 | from dust.core.util import splitFields, encode 2 | 3 | REQID_LENGTH=4 4 | 5 | class ProxyMessage: 6 | def __init__(self): 7 | self.reqid=None 8 | self.data=None 9 | self.msg=None 10 | 11 | def createProxyMessage(self, reqid, data): 12 | self.reqid=reqid 13 | self.data=data 14 | 15 | self.msg=reqid+data 16 | 17 | def decodeProxyMessage(self, msg): 18 | self.msg=msg 19 | self.reqid, self.data=splitFields(msg, [REQID_LENGTH]) 20 | 21 | def __str__(self): 22 | s="ProxyMessage\n" 23 | s=s+"[\n" 24 | s=s+" reqid: "+str(self.reqid) 25 | s=s+" data: "+str(self.data) 26 | s=s+"]\n\n" 27 | return s 28 | 29 | -------------------------------------------------------------------------------- /modelgen/templates/test.go.airspeed: -------------------------------------------------------------------------------- 1 | package $packagename 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/blanu/Dust/go/model1/testing" 7 | ) 8 | 9 | func TestC2S(t *testing.T) { 10 | enc, _, errc := theModel.MakeClientPair() 11 | _, dec, errs := theModel.MakeServerPair() 12 | if errc != nil || errs != nil { 13 | t.Fatalf("making codec pairs: %v, %v", errc, errs) 14 | } 15 | testing1.TestOneDirection(t, enc, dec) 16 | } 17 | 18 | func TestS2C(t *testing.T) { 19 | _, dec, errc := theModel.MakeClientPair() 20 | enc, _, errs := theModel.MakeServerPair() 21 | if errc != nil || errs != nil { 22 | t.Fatalf("making codec pairs: %v, %v", errc, errs) 23 | } 24 | testing1.TestOneDirection(t, enc, dec) 25 | } 26 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/multiplex-router.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import yaml 4 | import email 5 | import smtplib 6 | 7 | from dust.extensions.multiplex_socket import * 8 | from dust.crypto.curve import loadKeypair 9 | 10 | from dust.services import services 11 | print("services:", services) 12 | 13 | buffsize=102400 14 | host = '::1' 15 | inport=7000 16 | outport=7001 17 | nodeName='A' 18 | 19 | keypair=loadKeypair(nodeName+'-priv.txt', nodeName+'-pub.txt') 20 | 21 | msock=multiplex_socket(keypair) 22 | msock.bind(('', inport)) 23 | #ecsock.connect((host, outport)) 24 | 25 | msg, addr, service=msock.mrecvfrom(1024) 26 | handler=services[service] 27 | print('Routing to', handler, '...') 28 | handler(msg, addr) -------------------------------------------------------------------------------- /go/prim1/value.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package prim 5 | 6 | import ( 7 | cryptoRand "crypto/rand" 8 | ) 9 | 10 | const ( 11 | CValueLen = 32 12 | ) 13 | 14 | type CValue [CValueLen]byte 15 | 16 | var zeroCValue CValue 17 | 18 | const personPrefix = "tag:blanu.net,2015:Dust2015/" 19 | 20 | func ZeroCValue() CValue { 21 | return zeroCValue 22 | } 23 | 24 | func RandomCValue() CValue { 25 | var result [CValueLen]byte 26 | _, err := cryptoRand.Read(result[:]) 27 | if err != nil { 28 | panic("Dust/prim: somehow out of entropy") 29 | } 30 | 31 | return result 32 | } 33 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Network/Util.hs: -------------------------------------------------------------------------------- 1 | module Dust.Network.Util 2 | ( 3 | recvAll 4 | ) 5 | where 6 | 7 | import Data.ByteString 8 | import qualified Data.ByteString as B 9 | import qualified Data.ByteString.Lazy as BL 10 | import Network.Socket hiding (recv, send) 11 | import Network.Socket.ByteString (recv, send) 12 | 13 | recvAll :: Socket -> IO(BL.ByteString) 14 | recvAll sock = do 15 | list <- recvList sock 16 | return (BL.fromChunks list) 17 | 18 | recvList :: Socket -> IO([B.ByteString]) 19 | recvList sock = do 20 | input <- recv sock 4096 21 | if B.null input 22 | then return ([input]) 23 | else do 24 | next <- recvList sock 25 | return (input:next) 26 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/lite/lite_socket.py: -------------------------------------------------------------------------------- 1 | from dust.crypto.dustUtil import hash 2 | from dust.core.dust_socket import dust_socket 3 | from dust.core.util import encodeAddress, xor, encode 4 | 5 | class lite_socket(dust_socket): 6 | def makeSession(self, address, tryInvite): 7 | # addressKey=encodeAddress(address) 8 | addressKey=address[0] 9 | if addressKey in self.sessionKeys: 10 | return self.sessionKeys[addressKey] 11 | 12 | h1=hash(addressKey.encode('ascii')) 13 | h2=hash(self.myAddress[0].encode('ascii')) 14 | 15 | sessionKey=xor(h1, h2) 16 | 17 | self.sessionKeys[addressKey]=sessionKey 18 | print('SessionKey:', len(self.sessionKeys[addressKey])) 19 | return sessionKey 20 | -------------------------------------------------------------------------------- /historical/v1/py/dust/server/lite_router.py: -------------------------------------------------------------------------------- 1 | from dust.extensions.multiplex.lite_multiplex_socket import * 2 | from dust.crypto.keys import KeyManager 3 | from dust.core.util import getPublicIP 4 | 5 | from dust.server.services import services 6 | print("services:", services) 7 | 8 | class LitePacketRouter: 9 | def __init__(self, v6, port, keys): 10 | self.host = getPublicIP(v6) 11 | self.port=port 12 | 13 | msock=lite_multiplex_socket(keys) 14 | msock.bind((self.host, self.port)) 15 | 16 | while True: 17 | msg, addr, service=msock.mrecvfrom(1024) 18 | if msg and addr and service: 19 | handler=services[service] 20 | # print('Routing to', handler, '...') 21 | handler(msg, addr) -------------------------------------------------------------------------------- /go/dist/exponential.go: -------------------------------------------------------------------------------- 1 | // Copyright ©2014 The gonum Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dist 6 | 7 | import ( 8 | "math/rand" 9 | ) 10 | 11 | // Exponential represents the exponential distribution (https://en.wikipedia.org/wiki/Exponential_distribution). 12 | type Exponential struct { 13 | Rate float64 14 | Source *rand.Rand 15 | } 16 | 17 | // Rand returns a random sample drawn from the distribution. 18 | func (e Exponential) Rand() float64 { 19 | var rnd float64 20 | if e.Source == nil { 21 | rnd = rand.ExpFloat64() 22 | } else { 23 | rnd = e.Source.ExpFloat64() 24 | } 25 | return rnd / e.Rate 26 | } 27 | -------------------------------------------------------------------------------- /go/v2/crypting/params.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | package crypting 5 | 6 | import ( 7 | "errors" 8 | ) 9 | 10 | type Params struct { 11 | // Maximum datagram size. 12 | MTU int 13 | 14 | // Whether to allow propagating backpressure by buffering unsent datagrams. 15 | HoldIncoming bool 16 | } 17 | 18 | const ( 19 | MinMTU = 1280 20 | MaxMTU = 32000 21 | ) 22 | 23 | var ( 24 | ErrBadMTU = errors.New("Dust/crypting: bad MTU") 25 | ) 26 | 27 | func (params *Params) Validate() error { 28 | if !(MinMTU <= params.MTU && params.MTU <= MaxMTU) { 29 | return ErrBadMTU 30 | } 31 | 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/stego/gen.py: -------------------------------------------------------------------------------- 1 | import re 2 | import yaml 3 | 4 | wordlist=[] 5 | f=open('words.txt', 'r') 6 | while True: 7 | try: 8 | line=f.readline() 9 | #print('line:', line) 10 | except: 11 | print('Error reading line:', line) 12 | continue 13 | if line=='': 14 | break 15 | line=line.strip() 16 | #print('line:', line) 17 | words=re.findall('([A-Za-z]+)', line) 18 | #print('words:', words) 19 | for word in words: 20 | if len(word)>2 and not word in wordlist: 21 | wordlist.append(word) 22 | f.close() 23 | 24 | print(len(wordlist)) 25 | wordlist=wordlist[0:256] 26 | print(len(wordlist)) 27 | print(wordlist) 28 | 29 | f=open('words.yaml', 'w') 30 | f.write(yaml.dump(wordlist)) 31 | f.close() 32 | -------------------------------------------------------------------------------- /go/dist/uniform.go: -------------------------------------------------------------------------------- 1 | // Copyright ©2014 The gonum Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dist 6 | 7 | import ( 8 | "math/rand" 9 | ) 10 | 11 | // Uniform represents a continuous uniform distribution (https://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29). 12 | type Uniform struct { 13 | Min float64 14 | Max float64 15 | Source *rand.Rand 16 | } 17 | 18 | // Rand returns a random sample drawn from the distribution. 19 | func (u Uniform) Rand() float64 { 20 | var rnd float64 21 | if u.Source == nil { 22 | rnd = rand.Float64() 23 | } else { 24 | rnd = u.Source.Float64() 25 | } 26 | return rnd*(u.Max-u.Min) + u.Min 27 | } 28 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-command/Dust-command.cabal: -------------------------------------------------------------------------------- 1 | name: Dust-command 2 | version: 0.1.0.0 3 | synopsis: Executable providing access to the Dust engine from a separate process 4 | homepage: https://github.com/blanu/Dust 5 | license: GPL-2 6 | license-file: LICENSE 7 | author: Brandon Wiley 8 | maintainer: brandon@blanu.net 9 | category: Network 10 | build-type: Simple 11 | cabal-version: >=1.10 12 | 13 | executable Dust-command 14 | main-is: Dust/Control/Main.hs 15 | build-depends: 16 | base >=4.7 && <4.8, 17 | Dust, 18 | Dust-crypto, 19 | bytestring, 20 | binary, 21 | mtl, 22 | lens 23 | default-language: Haskell2010 24 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-crypto/Dust/Crypto/ECDH.hs: -------------------------------------------------------------------------------- 1 | module Dust.Crypto.ECDH 2 | ( 3 | createKeypair, 4 | createShared 5 | ) where 6 | 7 | import Data.ByteString as B 8 | import qualified Crypto.DH.Curve25519 as Curve25519 9 | import qualified Crypto.Key as CK 10 | 11 | import Dust.Crypto.Keys 12 | import Dust.Crypto.Cipher 13 | import Dust.Crypto.PRNG 14 | 15 | createKeypair :: IO Keypair 16 | createKeypair = do 17 | ((CK.PublicKey public), (CK.SecretKey private)) <- Curve25519.createKeypair 18 | return $ Keypair (PublicKey public) (PrivateKey private) 19 | 20 | createShared :: PrivateKey -> PublicKey -> EncryptionKey 21 | createShared (PrivateKey private) (PublicKey public) = EncryptionKey $ Curve25519.curve25519 (CK.SecretKey private) (CK.PublicKey public) 22 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/DustConstants.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | public class DustConstants 4 | { 5 | static public final int SEED_SIZE=16; 6 | static public final int IV_SIZE=16; 7 | static public final int BLOCK_SIZE=32; 8 | 9 | // static public final int PBKDF_ITERATIONS=13000; 10 | static public final int PBKDF_ITERATIONS=10; 11 | 12 | static public final String MAC_PERS="1978-10-26 dust@blanu.net Dust/MAC"; 13 | static public final String PRNG_PERS="1978-10-26 dust@blanu.net Dust/PRNG"; 14 | static public final String HASH_PERS="1978-10-26 dust@blanu.net Dust/hash"; 15 | static public final String PBKDF_PERS="1978-10-26 dust@blanu.net Dust/PBKDF"; 16 | static public final String CIPHER_PERS="1978-10-26 dust@blanu.net Dust/cipher"; 17 | } 18 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/Keypair.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | import dust.crypto.Curve; 4 | 5 | public class Keypair 6 | { 7 | Key secret; 8 | Key pub; 9 | 10 | static public Keypair create(byte[] entropy) 11 | { 12 | return Curve.createKeypair(entropy); 13 | } 14 | 15 | public Keypair(Key s, Key p) 16 | { 17 | secret=s; 18 | pub=p; 19 | } 20 | 21 | public Key getSecret() 22 | { 23 | return secret; 24 | } 25 | 26 | public Key getPublic() 27 | { 28 | return pub; 29 | } 30 | 31 | public Key session(Key pub2) 32 | { 33 | return new Key(Curve.createShared(secret.getBytes(), pub2.getBytes())); 34 | } 35 | 36 | public String toString() 37 | { 38 | return ""; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks/socks.txt: -------------------------------------------------------------------------------- 1 | c -> s # handshake 2 | 0x05 - version 3 | 0x01 - number of auth methods, just one 4 | 0x00 - "no auth" auth method 5 | 6 | s -> c # handshake 7 | 0x05 - version 8 | 0x00 - choose "no auth" auth method 9 | 10 | c -> s # connection request 11 | 0x05 - version 12 | 0x01 - request TCP connection 13 | 0x00 - reserved, must be 0 14 | 0x01 - IPv4 address # just for testing, add domain name and IPv6 later 15 | 4 bytes - IPv4 IP address 16 | 2 bytes - network byte order port 17 | 18 | s -> c # connection response 19 | 0x05 - version 20 | 0x00 - request granted, just for testing, add other error codes later 21 | 0x00 - reserved, must be 0 22 | 0x01 - IPv4 IP address 23 | 4 bytes - IPv4 IP address 24 | 2 bytes - network byte order port 25 | 26 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/tcp_proxy.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | import monocle 5 | from monocle import _o 6 | monocle.init('tornado') 7 | 8 | from monocle.stack import eventloop 9 | from monocle.stack.network import add_service, Service, Client, ConnectionLost 10 | 11 | @_o 12 | def pump(input, output): 13 | while True: 14 | try: 15 | message = yield input.read(1) 16 | yield output.write(message) 17 | except ConnectionLost: 18 | output.close() 19 | break 20 | 21 | @_o 22 | def handle_socks(conn): 23 | client = Client() 24 | yield client.connect('localhost', 8050) 25 | monocle.launch(pump, conn, client) 26 | yield pump(client, conn) 27 | 28 | add_service(Service(handle_socks, port=7050)) 29 | eventloop.run_multicore(1) 30 | -------------------------------------------------------------------------------- /go/NOTES: -------------------------------------------------------------------------------- 1 | #+TITLE: Working notes on Dust Go implementation 2 | Updated: [2015-04-13 Mon] 3 | 4 | * Tasks 5 | ** Dust2 juggling 6 | *** Reimplement close/interrupt support for newly juggled crypting layer API 7 | ** General 8 | *** Adjust Huffman coder to be able to use restricted symbol set 9 | *** Implementation documentation pass started [2015-04-11 Sat] 10 | - [ ] buf 11 | - [ ] huffman 12 | - [ ] prim1 13 | - [ ] proc 14 | - [ ] skein 15 | - [ ] v2/crypting 16 | - [ ] v2/shaping 17 | - [ ] v2/engine 18 | *** Use 'byte' terminology consistently 19 | *** Use consistent error terminology 20 | *** Pull license for 'dist' package 21 | ** Mostly optional 22 | *** Refactor CLI parts 23 | 24 | * (metadata) 25 | 26 | Local variables: 27 | mode: org 28 | mode: auto-fill 29 | fill-column: 110 30 | End: 31 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/DustUtil.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import dust.crypto.DustConstants; 6 | import dust.crypto.SkeinUtil; 7 | 8 | public class DustUtil 9 | { 10 | static public byte[] hash(byte[] data) 11 | { 12 | return SkeinUtil.hash(data, DustConstants.HASH_PERS); 13 | } 14 | 15 | static public byte[] mac(byte[] key, ByteBuffer data) 16 | { 17 | return DustUtil.mac(key, data.array()); 18 | } 19 | 20 | static public byte[] mac(byte[] key, byte[] data) 21 | { 22 | return SkeinUtil.mac(data, key, DustConstants.MAC_PERS); 23 | } 24 | 25 | static public byte[] pbkdf(byte[] pb, byte[] salt) 26 | { 27 | return SkeinUtil.pbkdf(pb, salt, DustConstants.PBKDF_ITERATIONS, DustConstants.PBKDF_PERS); 28 | } 29 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/tracker-serve.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | from dust.server.router import PacketRouter 5 | from dust.crypto.keys import KeyManager 6 | from dust.core.util import getPublicIP, encodeAddress, decodeAddress, encode 7 | 8 | inport=int(sys.argv[1]) 9 | v6=sys.argv[2]=='6' 10 | passwd=sys.argv[3] 11 | 12 | host=getPublicIP(v6) 13 | 14 | keys=KeyManager() 15 | keys.setInvitePassword(passwd) 16 | keys.loadKeypair('config/id.yaml') 17 | keys.loadKnownHosts('config/knownhosts.yaml') 18 | keys.loadIncomingInvites('config/incoming_invites.ip') 19 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 20 | 21 | router=PacketRouter(v6, inport, keys, passwd) 22 | router.start() 23 | 24 | while True: 25 | try: 26 | time.sleep(1) 27 | except: 28 | sys.exit(0) 29 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/intro-send.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from dust.intro.intro_socket import * 3 | from dust.crypto.keys import KeyManager 4 | from dust.core.util import getPublicIP 5 | 6 | passwd=sys.argv[1] 7 | ipv=sys.argv[2] 8 | if ipv=='4': 9 | v6=False 10 | else: 11 | v6=True 12 | 13 | host=getPublicIP(v6) 14 | dest=getPublicIP(v6) 15 | 16 | buffsize=102400 17 | inport=8001 18 | outport=7000 19 | nodeName='A' 20 | 21 | keys=KeyManager() 22 | keys.loadKeypair('config/id.yaml') 23 | keypair=keys.getKeypair() 24 | 25 | keys.setInvitePassword(passwd) 26 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 27 | invite=keys.outgoingInvites.getInviteForHost(False, (dest, outport)) 28 | 29 | isock=intro_socket(keys) 30 | isock.bind((host, inport)) 31 | isock.iconnect(invite) 32 | isock.isend() -------------------------------------------------------------------------------- /go/proc/event.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package proc 5 | 6 | import ( 7 | "sync/atomic" 8 | ) 9 | 10 | type Event struct { 11 | Val interface{} 12 | trig chan<- struct{} 13 | once uint32 14 | } 15 | 16 | func NewEvent() (*Event, <-chan struct{}) { 17 | ch := make(chan struct{}, 0) 18 | return &Event{trig: ch}, ch 19 | } 20 | 21 | func (ev *Event) Trip(val interface{}) bool { 22 | if !atomic.CompareAndSwapUint32(&ev.once, 0, 1) { 23 | return false 24 | } 25 | 26 | ev.Val = val 27 | close(ev.trig) 28 | return true 29 | } 30 | 31 | func propagateEvent(fromChan <-chan struct{}, from, to *Event) { 32 | _ = <-fromChan 33 | to.Trip(from.Val) 34 | } 35 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/core/DataPacket.java: -------------------------------------------------------------------------------- 1 | package dust.core; 2 | 3 | import dust.core.DustPacket; 4 | import dust.crypto.DustPRNG; 5 | 6 | public class DataPacket extends DustPacket 7 | { 8 | static public DataPacket create(byte[] key, byte[] data, DustPRNG entropy) 9 | { 10 | return new DataPacket(key, data, entropy); 11 | } 12 | 13 | static public DataPacket decode(byte[] key, byte[] packet) 14 | { 15 | return new DataPacket(key, packet); 16 | } 17 | 18 | public DataPacket(byte[] key, byte[] data) 19 | { 20 | super(key, data); 21 | } 22 | 23 | public DataPacket(byte[] key, byte[] data, DustPRNG entropy) 24 | { 25 | super(key, data, entropy); 26 | } 27 | } 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/create-chained-data-packet.py: -------------------------------------------------------------------------------- 1 | from dust.crypto.keys import KeyManager 2 | from dust.core.data_packet import DataPacket 3 | 4 | keys=KeyManager() 5 | psk=keys.entropy.getBytes(32) 6 | 7 | packet=DataPacket() 8 | packet.createDataPacket(psk, b"Hello", keys.entropy) 9 | print(packet) 10 | print('l:', len(packet.packet)) 11 | 12 | print('------------------------') 13 | 14 | pc=DataPacket() 15 | pc.createDataPacket(psk, b"Chained!", keys.entropy) 16 | print('l:', len(pc.packet)) 17 | 18 | print(pc) 19 | 20 | chain=packet.packet+pc.packet 21 | 22 | print('l:', len(chain)) 23 | 24 | print('------------------------') 25 | 26 | p2=DataPacket() 27 | p2.decodeDataPacket(psk, chain) 28 | print(p2) 29 | 30 | print('------------------------') 31 | 32 | pc2=DataPacket() 33 | pc2.decodeDataPacket(psk, p2.remaining) 34 | print(pc2) 35 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/mail-send.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from dust.core.dust_socket import * 4 | from dust.crypto.curve import loadKeypair 5 | 6 | from email.mime.text import MIMEText 7 | 8 | buffsize=102400 9 | host = '::1' 10 | outport=7000 11 | inport=7001 12 | nodeName='A' 13 | 14 | keypair=loadKeypair(nodeName+'-priv.txt', nodeName+'-pub.txt') 15 | 16 | ecsock=dust_socket(keypair) 17 | ecsock.bind((host, inport)) 18 | ecsock.connect((host, outport)) 19 | 20 | frm=input('From: ') 21 | to=input('To: ') 22 | subject=input('Subject: ') 23 | 24 | line=None 25 | body='' 26 | while True: 27 | line=sys.stdin.readline() 28 | if line.strip()=='.': 29 | break 30 | body=body+line 31 | 32 | msg=MIMEText(body) 33 | msg['From']=frm 34 | msg['To']=to 35 | msg['Subject']=subject 36 | 37 | ecsock.send(msg.as_string().encode('ascii')) 38 | -------------------------------------------------------------------------------- /modelgen/scripts/run-base.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export PROTOCOL=http 3 | export DUSTIP=`ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'` 4 | export DESTINATION=google.com:80 5 | 6 | if [ ! -d "~/go/src/caolta3iaejox3z4madc5wmp4z.uuid" ]; then 7 | mkdir ~/go/src/caolta3iaejox3z4madc5wmp4z.uuid 8 | fi 9 | 10 | scripts/build.sh go ../go/models caolta3iaejox3z4madc5wmp4z.uuid/Dust_privmodels ~/go/src/caolta3iaejox3z4madc5wmp4z.uuid/Dust_privmodels 11 | 12 | pushd ~/go/src/github.com/blanu/Dust/go/cmd/DustTool 13 | go build 14 | go install 15 | rm ~/DustProxy.invite 16 | ~/go/bin/DustTool newid -o ~/DustProxy.invite test $DUSTIP:16667 m=$PROTOCOL >~/DustProxy.bridge 17 | export DUSTPROXYID=`cat ~/DustProxy.bridge | awk '{print $4}'` 18 | popd 19 | 20 | pushd ~/go/src/github.com/blanu/Dust/go/cmd/DustProxy 21 | go install -tags privmodels 22 | popd 23 | -------------------------------------------------------------------------------- /go/v2/shaping/timer.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | package shaping 5 | 6 | import ( 7 | "time" 8 | 9 | "github.com/blanu/Dust/go/proc" 10 | ) 11 | 12 | type timer struct { 13 | proc.Ctl 14 | } 15 | 16 | func (t *timer) Init(parent *proc.Env) { 17 | proc.InitDriver(parent, &t.Ctl, t.runTimer, nil) 18 | } 19 | 20 | func (t *timer) runTimer(env *proc.Env) (err error) { 21 | for req, any := env.GetRequest(); any; req, any = env.GetRequest() { 22 | dur := req.(time.Duration) 23 | log.Debug(" .. sleep %v ..", dur) 24 | time.Sleep(dur) 25 | afterSleep := time.Now() 26 | env.PutReply(afterSleep) 27 | } 28 | 29 | return nil 30 | } 31 | 32 | func (t *timer) cycle(dur time.Duration) { 33 | t.PutRequest(dur) 34 | } 35 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/notify.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | import email 3 | import smtplib 4 | 5 | from email.mime.text import MIMEText 6 | 7 | class Notifier: 8 | def __init__(self, frm): 9 | self.frm=frm 10 | 11 | f=open('config/emailServer.yaml', 'r') 12 | self.config=yaml.load(f.read()) 13 | f.close() 14 | 15 | def notify(self, to, subject, body): 16 | print('Notifying '+str(to)+'...') 17 | msg=MIMEText(body) 18 | msg['From']=self.frm 19 | msg['To']=to 20 | msg['Subject']=subject 21 | 22 | smtp = smtplib.SMTP(self.config['smtpHost']) 23 | smtp.set_debuglevel(1) 24 | smtp.sendmail(self.frm, to, msg.as_string()) 25 | smtp.quit() 26 | 27 | if __name__=='__main__': 28 | notifier=Notifier('brandon@blanu.net') 29 | notifier.notify('brandon@blanu.net', 'Test Message', 'This is a test of the DustMail notifier system.') 30 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/tests/TestModel.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -fno-warn-missing-signatures #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | 4 | module Main where 5 | 6 | import Test.Framework.Providers.HUnit 7 | import Test.Framework.TH 8 | import Test.Framework 9 | import Test.HUnit hiding (test) 10 | 11 | import qualified Data.ByteString as B 12 | import Data.ByteString.Char8 (pack) 13 | 14 | import Dust.Model.Content 15 | 16 | case_encode_decode = do 17 | (ContentModel tree) <- loadContentModel "/usr/share/dict/american-english" 18 | let msg1 = pack "qwerty" 19 | let len = B.length msg1 20 | putStrLn (show msg1) 21 | let enc = encodeContent tree msg1 22 | putStrLn (show enc) 23 | let msg2 = B.take len $ decodeContent tree enc 24 | putStrLn (show msg2) 25 | 26 | msg1 @=? msg2 27 | 28 | main :: IO () 29 | main = defaultMain [$(testGroupGenerator)] 30 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/mmail-send.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from dust.extensions.multiplex_socket import * 4 | from dust.crypto.curve import loadKeypair 5 | 6 | from email.mime.text import MIMEText 7 | 8 | buffsize=102400 9 | host = '::1' 10 | outport=7000 11 | inport=7001 12 | nodeName='A' 13 | 14 | keypair=loadKeypair(nodeName+'-priv.txt', nodeName+'-pub.txt') 15 | 16 | msock=multiplex_socket(keypair) 17 | msock.bind((host, inport)) 18 | msock.connect((host, outport)) 19 | msock.connectToService('mail') 20 | 21 | frm=input('From: ') 22 | to=input('To: ') 23 | subject=input('Subject: ') 24 | 25 | line=None 26 | body='' 27 | while True: 28 | line=sys.stdin.readline() 29 | if line.strip()=='.': 30 | break 31 | body=body+line 32 | 33 | msg=MIMEText(body) 34 | msg['From']=frm 35 | msg['To']=to 36 | msg['Subject']=subject 37 | 38 | msock.msend(msg.as_string().encode('ascii')) 39 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-command/Dust/Control/State.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | 3 | module Dust.Control.State 4 | ( 5 | ControlState, 6 | newControlState, 7 | trafficGenerator, 8 | packetCountRandom, 9 | lengthRandom, 10 | portRandom 11 | ) 12 | where 13 | 14 | import qualified Data.ByteString as B 15 | import qualified Data.ByteString.Lazy as BL 16 | import Control.Lens.TH (makeLenses) 17 | 18 | import Dust.Crypto.PRNG 19 | import Dust.Model.TrafficModel 20 | 21 | data ControlState = ControlState { 22 | _trafficGenerator :: TrafficGenerator, 23 | _packetCountRandom :: PRNG, 24 | _lengthRandom :: PRNG, 25 | _portRandom :: PRNG 26 | } 27 | 28 | makeLenses ''ControlState 29 | 30 | newControlState :: TrafficGenerator -> IO ControlState 31 | newControlState gen = do 32 | r1 <- newPRNG 33 | r2 <- newPRNG 34 | r3 <- newPRNG 35 | return $ ControlState gen r1 r2 r3 36 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/test/TestCurve.java: -------------------------------------------------------------------------------- 1 | package dust.test; 2 | 3 | import java.util.Random; 4 | 5 | import dust.crypto.Curve; 6 | import dust.crypto.Keypair; 7 | import dust.crypto.Key; 8 | import dust.core.Util; 9 | 10 | public class TestCurve 11 | { 12 | static public void main(String[] args) throws Exception 13 | { 14 | byte[] entropy=new byte[32]; 15 | Random random=new Random(); 16 | 17 | random.nextBytes(entropy); 18 | Keypair pair1=Curve.createKeypair(entropy); 19 | System.out.println("pair1: "+pair1); 20 | 21 | random.nextBytes(entropy); 22 | Keypair pair2=Curve.createKeypair(entropy); 23 | System.out.println("pair2: "+pair2); 24 | 25 | Key session1=pair1.session(pair2.getPublic()); 26 | System.out.println("session1: "+session1); 27 | 28 | Key session2=pair2.session(pair1.getPublic()); 29 | System.out.println("session1: "+session2); 30 | } 31 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/util/ymap.py: -------------------------------------------------------------------------------- 1 | import os 2 | import yaml 3 | 4 | # This is not thread safe 5 | class YamlMap: 6 | def __init__(self, filename): 7 | self.filename=filename 8 | if os.path.exists(filename): 9 | f=open(self.filename, 'r') 10 | self.map=yaml.load(f) 11 | f.close() 12 | else: 13 | self.map={} 14 | 15 | def getWithDefault(self, key, default): 16 | if key in self.map.keys(): 17 | return self.map[key] 18 | else: 19 | return default 20 | 21 | def __getitem__(self, key): 22 | return self.map[key] 23 | 24 | def __setitem__(self, key, value): 25 | self.map[key]=value 26 | self.save() 27 | 28 | def keys(self): 29 | return self.map.keys() 30 | 31 | def values(self): 32 | return self.map.values() 33 | 34 | def save(self): 35 | f=open(self.filename, 'w') 36 | yaml.dump(self.map, f) 37 | f.close() 38 | 39 | -------------------------------------------------------------------------------- /go/dist/laplace.go: -------------------------------------------------------------------------------- 1 | // Copyright ©2014 The gonum Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dist 6 | 7 | import ( 8 | "math" 9 | "math/rand" 10 | ) 11 | 12 | // Laplace represents the Laplace distribution (https://en.wikipedia.org/wiki/Laplace_distribution). 13 | type Laplace struct { 14 | Mu float64 // Mean of the Laplace distribution 15 | Scale float64 // Scale of the Laplace distribution 16 | Source *rand.Rand 17 | } 18 | 19 | // Rand returns a random sample drawn from the distribution. 20 | func (l Laplace) Rand() float64 { 21 | var rnd float64 22 | if l.Source == nil { 23 | rnd = rand.Float64() 24 | } else { 25 | rnd = l.Source.Float64() 26 | } 27 | u := rnd - 0.5 28 | if u < 0 { 29 | return l.Mu + l.Scale*math.Log(1+2*u) 30 | } 31 | return l.Mu - l.Scale*math.Log(1-2*u) 32 | } 33 | -------------------------------------------------------------------------------- /go/model1/decoder.go: -------------------------------------------------------------------------------- 1 | package model1 2 | 3 | import ( 4 | "github.com/blanu/Dust/go/huffman" 5 | ) 6 | 7 | type Decoder struct { 8 | Prefix []byte 9 | Enhuffer *huffman.Encoder 10 | 11 | position uint64 12 | } 13 | 14 | func (half *HalfModel) NewDecoderIsh() *Decoder { 15 | return &Decoder{ 16 | Prefix: half.Prefix, 17 | Enhuffer: huffman.NewEncoder(half.HuffCoding), 18 | } 19 | } 20 | 21 | func (dec *Decoder) UnshapeBytes(dst, src []byte) (dn, sn int) { 22 | if dec.position < uint64(len(dec.Prefix)) { 23 | skip := int(uint64(len(dec.Prefix)) - dec.position) 24 | if len(src) < skip { 25 | skip = len(src) 26 | } 27 | 28 | // NOTE: this doesn't do any comparison with the expected content. 29 | src = src[skip:] 30 | sn += skip 31 | dec.position += uint64(skip) 32 | } 33 | 34 | hdn, hsn := dec.Enhuffer.Encode(dst, src) 35 | dec.position += uint64(hsn) 36 | dn += hdn 37 | sn += hsn 38 | return 39 | } 40 | -------------------------------------------------------------------------------- /historical/v1/skein-java/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 29 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/chat-send.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from dust.crypto.keys import KeyManager 4 | from dust.extensions.multiplex.multiplex_socket import * 5 | from dust.core.util import getPublicIP, decodeAddress 6 | 7 | passwd=sys.argv[1] 8 | inport=int(sys.argv[2]) 9 | addr=sys.argv[3] 10 | 11 | dest, outport, ipv=decodeAddress(addr) 12 | 13 | host=getPublicIP(ipv) 14 | 15 | keys=KeyManager() 16 | keys.setInvitePassword(passwd) 17 | keys.loadKnownHosts('config/knownhosts.yaml') 18 | keys.loadKeypair('config/id.yaml') 19 | keys.loadIncomingInvites('config/incoming_invites.ip') 20 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 21 | 22 | msock=multiplex_socket(keys) 23 | msock.bind((host, inport)) 24 | msock.connect((dest, outport)) 25 | msock.connectToService('chat') 26 | 27 | msg='' 28 | while msg!='.': 29 | print('>> ', end='') 30 | msg=sys.stdin.readline().strip() 31 | msock.msend(msg.encode('ascii')) 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/dist 2 | **/id.pub 3 | **/id.priv 4 | Dust-crypto/dist 5 | **/*.pyc 6 | **/*.so 7 | **/*.dylib 8 | Dust-command/*.model 9 | Dust-command/*.json 10 | Dust-command/*.commands 11 | Dust-command/*.commands2 12 | Dust-command/*.py 13 | modelgen/models/generated 14 | modelgen/models/data/http.json 15 | modelgen/models/data/https.json 16 | modelgen/node_modules 17 | .idea/workspace.xml 18 | 19 | # Created by https://www.gitignore.io/api/go 20 | # Edit at https://www.gitignore.io/?templates=go 21 | 22 | ### Go ### 23 | # Binaries for programs and plugins 24 | *.exe 25 | *.exe~ 26 | *.dll 27 | *.so 28 | *.dylib 29 | 30 | # Test binary, built with `go test -c` 31 | *.test 32 | 33 | # Output of the go coverage tool, specifically when used with LiteIDE 34 | *.out 35 | 36 | # Dependency directories (remove the comment below to include it) 37 | # vendor/ 38 | 39 | ### Go Patch ### 40 | /vendor/ 41 | /Godeps/ 42 | 43 | # End of https://www.gitignore.io/api/go 44 | -------------------------------------------------------------------------------- /go/dist/poisson.go: -------------------------------------------------------------------------------- 1 | // Copyright ©2014 The gonum Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dist 6 | 7 | import ( 8 | "math" 9 | "math/rand" 10 | ) 11 | 12 | // Poisson represents the Poisson distribution (https://en.wikipedia.org/wiki/Poisson_distribution). 13 | type Poisson struct { 14 | Expected float64 15 | Source *rand.Rand 16 | } 17 | 18 | // Rand returns a random sample drawn from the distribution. 19 | /* Poisson sampling according to Knuth 20 | init: 21 | Let L ← e−λ, k ← 0 and p ← 1. 22 | do: 23 | k ← k + 1. 24 | Generate uniform random number u in [0,1] and let p ← p × u. 25 | while p > L. 26 | return k − 1. 27 | */ 28 | func (self Poisson) Rand() uint16 { 29 | var l float64 = math.E - self.Expected 30 | var k uint16 = 0 31 | 32 | for p := rand.Float64(); p > l; p = p * rand.Float64() { 33 | k = k + 1 34 | } 35 | 36 | return k 37 | } 38 | -------------------------------------------------------------------------------- /go/dist/multinomial.go: -------------------------------------------------------------------------------- 1 | // Copyright ©2014 The gonum Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dist 6 | 7 | import ( 8 | "math/rand" 9 | ) 10 | 11 | // Poisson represents the Poisson distribution (https://en.wikipedia.org/wiki/Poisson_distribution). 12 | type Multinomial struct { 13 | Weights []float64 14 | Source *rand.Rand 15 | } 16 | 17 | // Rand returns a random sample drawn from the distribution. 18 | func (e Multinomial) Rand() float64 { 19 | var rnd float64 20 | if e.Source == nil { 21 | rnd = rand.Float64() 22 | } else { 23 | rnd = e.Source.Float64() 24 | } 25 | 26 | var last float64 = 0 27 | var next float64 = 0 28 | 29 | for index, weight := range e.Weights { 30 | next = next + weight 31 | if rnd > last && rnd < next { 32 | return float64(uint64(index)) 33 | } 34 | last = next 35 | } 36 | 37 | return float64(uint64(len(e.Weights))) 38 | } 39 | -------------------------------------------------------------------------------- /historical/haskell2014/INSTALL: -------------------------------------------------------------------------------- 1 | That is only been testing using Haskell platform 2014.2.0.0 64-bit for OS X. It may work with other versions of Haskell. 2 | For best results, follow the instructions on stackage.org to configure your system to use the Stackage packages for your version of Haskell. 3 | Attempts to install Dust using Hackage packages have generally been met with frustration. 4 | 5 | Install Dust-crypto: 6 | Install hs-ncal: Get hs-nacl here and follow the instructions to install it: https://github.com/thoughtpolice/hs-nacl 7 | cd Dust-crypto 8 | cabal install --only-dependencies 9 | cabal configure 10 | cabal build 11 | cabal install 12 | cd .. 13 | 14 | Install Dust: 15 | cd Dust 16 | cabal install --only-dependencies 17 | cabal configure 18 | cabal build 19 | cabal install 20 | cd .. 21 | 22 | Install Dust-command: 23 | cd Dust-command 24 | cabal install --only-dependencies 25 | cabal configure 26 | cabal build 27 | cabal install 28 | cd .. 29 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/tracker/trackbackService.py: -------------------------------------------------------------------------------- 1 | from dust.core.util import encodeAddress 2 | from dust.util.jsonrpc.serviceHandler import ServiceHandler 3 | from dust.services.tracker.trackbackHandler import TrackbackHandler 4 | 5 | class TrackbackService: 6 | def __init__(self): 7 | self.router=None 8 | 9 | def setRouter(self, r): 10 | self.router=r; 11 | self.handler=TrackbackHandler(self.router.keys) 12 | self.trackback=ServiceHandler(self.handler) 13 | 14 | def setPutPeerForEndpointCallback(self, key, callback): 15 | self.handler.setPutPeerForEndpointCallback(key, callback) 16 | 17 | def setPutInviteForPeerCallback(self, key, callback): 18 | self.handler.setPutInviteForPeer(key, callback) 19 | 20 | def setPutTrackerInviteCallback(self, callback): 21 | self.handler.setPutTrackerInvite(callback) 22 | 23 | def handle(self, msock, msg, addr): 24 | print('Trackback message from '+encodeAddress(addr)+':') 25 | self.trackback.handleRequest(msg.decode('utf-8')) 26 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/file-getmeta.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dust.services.file.file_socket import file_socket 4 | from dust.crypto.keys import KeyManager 5 | 6 | from dust.server.services import services 7 | print("services:", services) 8 | 9 | host = '2002:ad82:39e1:7:250:8dff:fe5f:6e33' 10 | inport=7001 11 | outport=7000 12 | passwd='test' 13 | 14 | keys=KeyManager() 15 | keys.setInvitePassword(passwd) 16 | keys.loadKeypair('config/id.yaml') 17 | keys.loadKnownHosts('config/knownhosts.yaml') 18 | keys.loadIncomingInvites('config/incoming_invites.ip') 19 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 20 | 21 | fsock=file_socket(keys) 22 | fsock.bind((host, inport)) 23 | fsock.connect((host, outport)) 24 | 25 | headers={'command': 'getMeta', 'file': 'test.txt'} 26 | data=None 27 | fsock.fsend(headers, data) 28 | 29 | headers, data, addr=fsock.frecvfrom() 30 | 31 | print('got:', headers, data, addr) 32 | 33 | #handler=services[service] 34 | #print('Routing to', handler, '...') 35 | #handler(msg, addr) -------------------------------------------------------------------------------- /historical/v1/py/dust/test/file-get.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dust.services.file.file_socket import file_socket 4 | from dust.crypto.keys import KeyManager 5 | 6 | from dust.server.services import services 7 | print("services:", services) 8 | 9 | host = '2002:ad82:39e1:7:250:8dff:fe5f:6e33' 10 | inport=7001 11 | outport=7000 12 | passwd='test' 13 | 14 | keys=KeyManager() 15 | keys.setInvitePassword(passwd) 16 | keys.loadKeypair('config/id.yaml') 17 | keys.loadKnownHosts('config/knownhosts.yaml') 18 | keys.loadIncomingInvites('config/incoming_invites.ip') 19 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 20 | 21 | fsock=file_socket(keys) 22 | fsock.bind((host, inport)) 23 | fsock.connect((host, outport)) 24 | 25 | headers={'command': 'get', 'file': 'test.txt', 'offset': 0} 26 | data=None 27 | fsock.fsend(headers, data) 28 | 29 | headers, data, addr=fsock.frecvfrom() 30 | 31 | print('got:', headers, data, addr) 32 | 33 | #handler=services[service] 34 | #print('Routing to', handler, '...') 35 | #handler(msg, addr) -------------------------------------------------------------------------------- /modelgen/README: -------------------------------------------------------------------------------- 1 | Dust/go contains a compiler for the Dust statistical model specification to Go 2 | Though the output is a Go library, the compiler is written in Python. 3 | You therefore need both Go 1.4 and Python 2.7.6 in order to run the compiler. 4 | 5 | An important thing to understand is that there is no one single Dust library 6 | for Go. You use the Dust compiler to generate a custom Dust library for your 7 | specific models. 8 | 9 | Therefore in order to use Dust you must provide your own models. 10 | Once you have compiled your models you will have a custom Dust library. 11 | No executable binaries are produced, only a library. 12 | In order to use this library you will need to integrate it into an application. 13 | 14 | This is not proxy software. It is not suitable for use by end users. 15 | It is a tool for developers to use to create new filtering circumvention tools. 16 | 17 | If you would like to use your custom Dust library in an application, please do 18 | so. If you would like advice on doing this, feel free to contact us. 19 | -------------------------------------------------------------------------------- /go/model1/model.go: -------------------------------------------------------------------------------- 1 | package model1 2 | 3 | import ( 4 | "github.com/blanu/Dust/go/huffman" 5 | ) 6 | 7 | type Rand interface { 8 | Rand() float64 9 | } 10 | 11 | type HalfStatic struct { 12 | Prefix []byte 13 | HuffTable []huffman.BitString 14 | } 15 | 16 | type HalfModel struct { 17 | Prefix []byte 18 | HuffCoding *huffman.Coding 19 | } 20 | 21 | func CompileHalf(static *HalfStatic) (compiled *HalfModel, err error) { 22 | compiled = &HalfModel{} 23 | compiled.Prefix = static.Prefix 24 | compiled.HuffCoding, err = huffman.NewCoding(static.HuffTable) 25 | return 26 | } 27 | 28 | func CompileTwoHalves(a, b *HalfStatic) (ax, bx *HalfModel, err error) { 29 | ax, err = CompileHalf(a) 30 | if err != nil { 31 | return 32 | } 33 | bx, err = CompileHalf(b) 34 | return 35 | } 36 | 37 | func CompileTwoHalvesOrPanic(a, b *HalfStatic, panicPrefix string) (ax, bx *HalfModel) { 38 | var err error 39 | ax, bx, err = CompileTwoHalves(a, b) 40 | if err != nil { 41 | panic(panicPrefix + err.Error()) 42 | } 43 | return ax, bx 44 | } 45 | -------------------------------------------------------------------------------- /go/prim1/derivation.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package prim 5 | 6 | import ( 7 | "github.com/blanu/Dust/go/skein" 8 | ) 9 | 10 | const ( 11 | personKDF = personPrefix + "kdf.skein" 12 | 13 | SecretLen = 32 14 | ) 15 | 16 | type Secret CValue 17 | 18 | func (s Secret) deriveRaw(n uint64, id string) (result CValue) { 19 | args := skein.Args{ 20 | Key: s[:], 21 | Person: []byte(personKDF), 22 | KeyId: []byte(id), 23 | } 24 | 25 | var hash skein.Hash 26 | hash.Init(n, &args) 27 | _, _ = hash.Read(result[:n]) 28 | return 29 | } 30 | 31 | const ( 32 | kdfCipherPrefix = "clk." 33 | kdfAuthPrefix = "mac." 34 | ) 35 | 36 | func (s Secret) DeriveCipherKey(id string) CipherKey { 37 | return CipherKey(s.deriveRaw(CipherKeyLen, kdfCipherPrefix + id)) 38 | } 39 | 40 | func (s Secret) DeriveAuthKey(id string) AuthKey { 41 | return AuthKey(s.deriveRaw(AuthKeyLen, kdfAuthPrefix + id)) 42 | } 43 | -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/make-invite.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | # python sucks 4 | sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))) 5 | 6 | from dust.invite.invite import InvitePackage 7 | from dust.crypto.keys import KeyManager 8 | from dust.core.util import getAddress, getPublicIP 9 | 10 | password=sys.argv[1] 11 | 12 | port=int(sys.argv[2]) 13 | 14 | v6=True # defaults to IPv6 15 | if sys.argv[3]=='6': 16 | v6=True 17 | elif sys.argv[3]=='4': 18 | v6=False 19 | else: 20 | print('Unknown IP version:', sys.argv[2]) 21 | print('v6: '+sys.argv[3]+' '+str(v6)) 22 | 23 | if v6: 24 | print('Generating invites for udp://'+getAddress(port)) 25 | else: 26 | print('Generating invites for udp://'+getPublicIP(False)+':'+str(port)) 27 | 28 | keys=KeyManager() 29 | keys.loadKeypair('config/id.yaml') 30 | keypair=keys.getKeypair() 31 | pubkey=keypair.public 32 | 33 | ip=InvitePackage() 34 | ip.generate(pubkey, v6, False, port, 5, keys.entropy) 35 | ip.save('config/incoming_invites.ip', password, keys.entropy) 36 | -------------------------------------------------------------------------------- /go/prim1/sym_cipher.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package prim 5 | 6 | import ( 7 | "crypto/cipher" 8 | 9 | "github.com/blanu/Dust/go/skein" 10 | ) 11 | 12 | const ( 13 | personCipher = personPrefix + "stream.skein" 14 | 15 | CipherKeyLen = 32 16 | ) 17 | 18 | type ( 19 | CipherKey CValue 20 | ) 21 | 22 | func ZeroCipherKey() CipherKey { 23 | return CipherKey(zeroCValue) 24 | } 25 | 26 | type Cipher struct { 27 | skein.Hash 28 | } 29 | 30 | var _ cipher.Stream = (*Cipher)(nil) 31 | 32 | func (c *Cipher) SetKey(key CipherKey) { 33 | args := skein.Args{ 34 | Key: key[:], 35 | Person: []byte(personCipher), 36 | Nonce: nil, 37 | } 38 | 39 | c.Hash.Init(^uint64(0), &args) 40 | c.Hash.CloseWrite() 41 | } 42 | 43 | func (c *Cipher) SetRandomKey() { 44 | c.SetKey(CipherKey(RandomCValue())) 45 | } 46 | 47 | func (c *Cipher) XORKeyStream(dst, src []byte) { 48 | c.Hash.XORKeyStream(dst, src) 49 | } 50 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/DustCipher.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import dust.crypto.DustConstants; 6 | 7 | public class DustCipher extends SkeinCipherOFB 8 | { 9 | static public byte[] encrypt(byte[] k, byte[] iv, byte[] data) 10 | { 11 | DustCipher cipher=new DustCipher(k, iv); 12 | return cipher.encrypt(data); 13 | } 14 | 15 | static public byte[] decrypt(byte[] k, byte[] iv, byte[] data) 16 | { 17 | DustCipher cipher=new DustCipher(k, iv); 18 | return cipher.decrypt(data); 19 | } 20 | 21 | static public ByteBuffer encrypt(byte[] k, byte[] iv, ByteBuffer data) 22 | { 23 | DustCipher cipher=new DustCipher(k, iv); 24 | return cipher.encrypt(data); 25 | } 26 | 27 | static public ByteBuffer decrypt(byte[] k, byte[] iv, ByteBuffer data) 28 | { 29 | DustCipher cipher=new DustCipher(k, iv); 30 | return cipher.decrypt(data); 31 | } 32 | 33 | public DustCipher(byte[] key, byte[] iv) 34 | { 35 | super(key, iv, DustConstants.CIPHER_PERS); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /go/dist/norm.go: -------------------------------------------------------------------------------- 1 | // Copyright ©2014 The gonum Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dist 6 | 7 | import ( 8 | "math/rand" 9 | ) 10 | 11 | // UnitNormal is an instantiation of the standard normal distribution 12 | var UnitNormal = Normal{Mu: 0, Sigma: 1} 13 | 14 | // Normal respresents a normal (Gaussian) distribution (https://en.wikipedia.org/wiki/Normal_distribution). 15 | type Normal struct { 16 | Mu float64 // Mean of the normal distribution 17 | Sigma float64 // Standard deviation of the normal distribution 18 | Source *rand.Rand 19 | 20 | // Needs to be Mu and Sigma and not Mean and StdDev because Normal has functions 21 | // Mean and StdDev 22 | } 23 | 24 | // Rand returns a random sample drawn from the distribution. 25 | func (n Normal) Rand() float64 { 26 | var rnd float64 27 | if n.Source == nil { 28 | rnd = rand.NormFloat64() 29 | } else { 30 | rnd = n.Source.NormFloat64() 31 | } 32 | return rnd*n.Sigma + n.Mu 33 | } 34 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/socks.py: -------------------------------------------------------------------------------- 1 | from struct import unpack 2 | from socket import inet_ntoa 3 | 4 | import monocle 5 | from monocle import _o, Return 6 | 7 | from dust.core.util import encode 8 | 9 | def uncompact(x): 10 | ip, port = unpack("!4sH", x) 11 | return inet_ntoa(ip), port 12 | 13 | @_o 14 | def readHandshake(input): 15 | version=yield input.read(1) 16 | print('version: '+encode(str(version))) 17 | nauth=yield input.read(1) 18 | nauth=unpack('B', nauth)[0] 19 | auths=[] 20 | for x in range(nauth): 21 | auth=yield input.read(1) 22 | auth=unpack('B', auth)[0] 23 | auths.append(auth) 24 | 25 | @_o 26 | def sendHandshake(output): 27 | yield output.write(b"\x05\x00") 28 | 29 | @_o 30 | def readRequest(input): 31 | version=yield input.read(1) 32 | command=yield input.read(1) 33 | reserved=yield input.read(1) 34 | addrtype=yield input.read(1) 35 | dest=yield input.read(6) 36 | 37 | yield Return(dest) 38 | 39 | @_o 40 | def sendResponse(dest, output): 41 | yield output.write(b"\x05\x00\x00\x01"+dest) 42 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks3/socks.py: -------------------------------------------------------------------------------- 1 | from struct import unpack 2 | from socket import inet_ntoa 3 | 4 | import monocle 5 | from monocle import _o, Return 6 | 7 | from dust.core.util import encode 8 | 9 | def uncompact(x): 10 | ip, port = unpack("!4sH", x) 11 | return inet_ntoa(ip), port 12 | 13 | @_o 14 | def readHandshake(input): 15 | version=yield input.read(1) 16 | print('version: '+encode(str(version))) 17 | nauth=yield input.read(1) 18 | nauth=unpack('B', nauth)[0] 19 | auths=[] 20 | for x in range(nauth): 21 | auth=yield input.read(1) 22 | auth=unpack('B', auth)[0] 23 | auths.append(auth) 24 | 25 | @_o 26 | def sendHandshake(output): 27 | yield output.write(b"\x05\x00") 28 | 29 | @_o 30 | def readRequest(input): 31 | version=yield input.read(1) 32 | command=yield input.read(1) 33 | reserved=yield input.read(1) 34 | addrtype=yield input.read(1) 35 | dest=yield input.read(6) 36 | 37 | yield Return(dest) 38 | 39 | @_o 40 | def sendResponse(dest, output): 41 | yield output.write(b"\x05\x00\x00\x01"+dest) 42 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/TestPureSkein.py: -------------------------------------------------------------------------------- 1 | #from dust.crypto.dust import DustPRNG, encrypt, decrypt 2 | from dust.core.util import encode, decode 3 | from dust.crypto.pureskein512 import skein512 as pure 4 | from skein import skein512 5 | 6 | #r=DustPRNG() 7 | #iv=r.getBytes(16) 8 | #key=r.getBytes(32) 9 | key=decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013") 10 | iv=decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013") 11 | 12 | text=b'test data' 13 | 14 | def purehash(data, pers=None): 15 | if pers: 16 | return pure(data, pers=pers) 17 | else: 18 | return pure(data) 19 | 20 | def chash(data, pers=None): 21 | if pers: 22 | return skein512(data, pers=pers).digest() 23 | else: 24 | return skein512(data).digest() 25 | 26 | print("hash: "+encode(purehash(text))) 27 | print("hash pers: "+encode(purehash(text, pers=b"a"))) 28 | print("hash: "+encode(chash(text))) 29 | print("hash pers: "+encode(chash(text, pers=b"a"))) 30 | 31 | #data=encrypt(key, iv, text) 32 | #print(text) 33 | #print(encode(data)) 34 | #print(decrypt(key, iv, data)) 35 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/tests/TestCore.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -fno-warn-missing-signatures #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | 4 | module Main where 5 | 6 | import Data.Monoid 7 | import qualified Data.ByteString.Lazy as LZ 8 | 9 | import Test.QuickCheck 10 | import Test.Framework.Providers.QuickCheck2 11 | import Test.Framework 12 | 13 | import Dust.Model.Huffman (bitpack, bitunpack, padToEight) 14 | 15 | -- | Bits of the sort that can be bitpack'd and then bitunpack'd 16 | newtype Bits = Bits [Bool] deriving (Show) 17 | 18 | instance Arbitrary Bits where 19 | arbitrary = fmap (Bits . padToEight) $ arbitrary `suchThat` startsWithTrue 20 | where 21 | startsWithTrue (True:_) = True 22 | startsWithTrue _ = False 23 | 24 | prop_bitpack_unpack_loop :: Bits -> Bool 25 | prop_bitpack_unpack_loop (Bits bits) = bitunpack packed == bits 26 | where 27 | packed = mconcat $ LZ.toChunks $ bitpack bits 28 | {-# NOINLINE packed #-} 29 | 30 | main :: IO () 31 | main = defaultMain [ 32 | testGroup "Huffman" [ 33 | testProperty "bit pack/unpack loop" prop_bitpack_unpack_loop 34 | ] 35 | ] 36 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/dustmail_packet.py: -------------------------------------------------------------------------------- 1 | from dust.core.dust_packet import DustPacket 2 | from dust.core.util import getAddress, encode, splitField 3 | from dust.crypto.dustUtil import pbkdf 4 | 5 | SALT_LENGTH=32 6 | PUBKEY_LENGTH=32 7 | 8 | class DustmailInvitePacket(DustPacket): 9 | def __init__(self): 10 | DustPacket.__init__(self) 11 | 12 | self.salt=None 13 | self.pubkey=None 14 | self.invite=None 15 | 16 | def makeSalt(self, entropy): 17 | return entropy.getBytes(SALT_LENGTH) 18 | 19 | def createDustmailInvitePacket(self, password, pubkey, invite, entropy): 20 | self.pubkey=pubkey 21 | self.invite=invite 22 | self.salt=self.makeSalt(entropy) 23 | sk=pbkdf(password, self.salt) 24 | message=self.pubkey+self.invite 25 | self.createDustPacket(sk, message, entropy) 26 | self.packet=self.salt+self.packet 27 | 28 | def decodeDustmailInvitePacket(self, password, packet): 29 | self.salt, packet=splitField(packet, SALT_LENGTH) 30 | sk=pbkdf(password, self.salt) 31 | self.decodeDustPacket(sk, packet) 32 | self.pubkey, self.invite=splitField(self.data, PUBKEY_LENGTH) 33 | -------------------------------------------------------------------------------- /historical/v1/java/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/onion/onion_packet.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from dust.core.data_packet import DataPacket 3 | from dust.core.util import splitFields, encode 4 | 5 | SENDER_LENGTH=32 6 | RECEIVER_LENGTH=32 7 | 8 | class OnionPacket(DataPacket): 9 | def __init__(self): 10 | DataPacket.__init__(self) 11 | 12 | self.sender=None 13 | self.receiver=None 14 | 15 | def createOnionPacket(self, keypair, receiver, data, entropy): 16 | self.sender=keypair.public.bytes 17 | self.receiver=receiver 18 | skb=keypair.createSessionBytes(self.receiver) 19 | self.createDataPacket(skb, data, entropy) 20 | self.packet=self.sender+self.receiver+self.packet 21 | 22 | def decodeOnionPacket(self, keypair, packet): 23 | self.sender, self.receiver, packet=splitFields(packet, [SENDER_LENGTH, RECEIVER_LENGTH]) 24 | if keypair.public.bytes!=self.receiver: 25 | print('Error! Onion packet meant for a different receiver. Keypair does not match: '+encode(self.sender)+' '+encode(self.receiver)+' '+encode(keypair.public.bytes)) 26 | return 27 | else: 28 | skb=keypair.createSessionBytes(self.sender) 29 | self.decodeDataPacket(skb, packet) 30 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/client_server.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | import monocle 5 | from monocle import _o 6 | monocle.init(sys.argv[1]) 7 | 8 | from monocle.stack import eventloop 9 | from monocle.stack.network import add_service, Service, Client, ConnectionLost 10 | 11 | @_o 12 | def handle_echo(conn): 13 | while True: 14 | try: 15 | message = yield conn.read_until('\r\n') 16 | except ConnectionLost: 17 | break 18 | yield conn.write("you said: %s\r\n" % message.strip()) 19 | 20 | @_o 21 | def do_echos(): 22 | try: 23 | client = Client() 24 | yield client.connect('localhost', 8000) 25 | t = time.time() 26 | for x in xrange(10000): 27 | msg = "hello, world #%s!" % x 28 | yield client.write(msg + '\r\n') 29 | echo_result = yield client.read_until("\r\n") 30 | assert echo_result.strip() == "you said: %s" % msg 31 | print '10000 loops in %.2fs' % (time.time() - t) 32 | finally: 33 | client.close() 34 | eventloop.halt() 35 | 36 | add_service(Service(handle_echo, port=8000)) 37 | monocle.launch(do_echos) 38 | eventloop.run() 39 | -------------------------------------------------------------------------------- /go/dist/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright ©2014 The gonum Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dist 6 | 7 | const ( 8 | // oneOverRoot2Pi is the value of 1/(2Pi)^(1/2) 9 | // http://www.wolframalpha.com/input/?i=1%2F%282+*+pi%29%5E%281%2F2%29 10 | oneOverRoot2Pi = 0.39894228040143267793994605993438186847585863116493465766592582967065792589930183850125233390730693643030255886263518268 11 | 12 | //LogRoot2Pi is the value of log(sqrt(2*Pi)) 13 | logRoot2Pi = 0.91893853320467274178032973640561763986139747363778341281715154048276569592726039769474329863595419762200564662463433744 14 | negLogRoot2Pi = -logRoot2Pi 15 | log2Pi = 1.8378770664093454835606594728112352797227949472755668 16 | ln2 = 0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057068573368552023 17 | 18 | // Euler–Mascheroni constant. 19 | eulerGamma = 0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495146314472498070824809605 20 | ) 21 | 22 | const ( 23 | panicNameMismatch = "parameter name mismatch" 24 | ) 25 | -------------------------------------------------------------------------------- /go/prim1/value_repr.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package prim 5 | 6 | import ( 7 | "encoding/base32" 8 | "errors" 9 | "strings" 10 | ) 11 | 12 | var ( 13 | ErrInvalidCValue = errors.New("Dust/prim: not a CValue representation") 14 | ) 15 | 16 | func decodeText(out *[32]byte, in string, actualError error) error { 17 | if len(in) != 52 { 18 | return actualError 19 | } 20 | b, err := base32.StdEncoding.DecodeString(in + `====`) 21 | if err != nil { 22 | return actualError 23 | } 24 | copy(out[:], b) 25 | return nil 26 | } 27 | 28 | func encodeText(in *[32]byte) (result string) { 29 | result = strings.TrimRight(base32.StdEncoding.EncodeToString(in[:]), `=`) 30 | if len(result) != 52 { 31 | panic("Dust/prim: weird Base32 consistency error") 32 | } 33 | return 34 | } 35 | 36 | func (cval CValue) Text() string { 37 | array := [32]byte(cval) 38 | return encodeText(&array) 39 | } 40 | 41 | func CValueFromText(text string) (out CValue, err error) { 42 | var array [32]byte 43 | err = decodeText(&array, text, ErrInvalidCValue) 44 | out = CValue(array) 45 | return 46 | } 47 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Network/TcpServer.hs: -------------------------------------------------------------------------------- 1 | module Dust.Network.TcpServer 2 | ( 3 | server 4 | ) where 5 | 6 | import Network (listenOn, PortID(PortNumber)) 7 | import Network.Socket 8 | import qualified Network.Socket.ByteString as NSB 9 | import qualified Network.Socket.ByteString.Lazy as NSBL 10 | import Network.Socket.ByteString (sendAll) 11 | import Data.ByteString.Lazy (ByteString, fromChunks) 12 | import Control.Monad (forever) 13 | 14 | import Dust.Network.Util 15 | 16 | type Host = SockAddr 17 | 18 | server :: String -> PortNumber -> (Socket -> IO()) -> IO() 19 | server host port handleRequest = withSocketsDo $ do 20 | sock <- initSocket host port 21 | forever $ acceptAndProcess sock handleRequest 22 | sClose sock 23 | 24 | initSocket :: String -> PortNumber -> IO(Socket) 25 | initSocket host port = listenOn $ PortNumber port 26 | 27 | acceptAndProcess :: Socket -> (Socket-> IO()) -> IO() 28 | acceptAndProcess sock handleRequest = do 29 | (s, _) <- accept sock 30 | setSocketOption s NoDelay 1 31 | process handleRequest s 32 | 33 | process :: (Socket -> IO()) -> Socket -> IO() 34 | process handleRequest sock = do 35 | handleRequest sock 36 | sClose sock 37 | return () 38 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/intro-mmail-send.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from dust.crypto.keys import KeyManager 4 | from dust.extensions.multiplex.multiplex_socket import * 5 | from dust.core.util import getPublicIP 6 | 7 | from email.mime.text import MIMEText 8 | 9 | inport=int(sys.argv[1]) 10 | outport=int(sys.argv[2]) 11 | ipv=sys.argv[3] 12 | if ipv=='4': 13 | v6=False 14 | else: 15 | v6=True 16 | passwd=sys.argv[4] 17 | 18 | host=getPublicIP(v6) 19 | dest=host 20 | 21 | keys=KeyManager() 22 | keys.setInvitePassword(passwd) 23 | keys.loadKnownHosts('config/knownhosts.yaml') 24 | keys.loadKeypair('config/id.yaml') 25 | keys.loadIncomingInvites('config/incoming_invites.ip') 26 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 27 | 28 | msock=multiplex_socket(keys) 29 | msock.bind((host, inport)) 30 | msock.connect((dest, outport)) 31 | msock.connectToService('mail') 32 | 33 | frm=input('From: ') 34 | to=input('To: ') 35 | subject=input('Subject: ') 36 | 37 | line=None 38 | body='' 39 | while True: 40 | line=sys.stdin.readline() 41 | if line.strip()=='.': 42 | break 43 | body=body+line 44 | 45 | msg=MIMEText(body) 46 | msg['From']=frm 47 | msg['To']=to 48 | msg['Subject']=subject 49 | 50 | msock.msend(msg.as_string().encode('ascii')) 51 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks3/socksDustProxy.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | from struct import unpack 5 | from socket import inet_ntoa 6 | 7 | import monocle 8 | from monocle import _o, Return 9 | monocle.init('tornado') 10 | 11 | from monocle.stack import eventloop 12 | from monocle.stack.network import add_service, Service, Client 13 | 14 | from dust.core.util import getPublicIP 15 | 16 | from shared import pump 17 | 18 | from dust.extensions.lite.lite_socket2 import lite_socket, makeSession, makeEphemeralSession, createEphemeralKeypair 19 | from dust.core.dust_packet import IV_SIZE, KEY_SIZE 20 | 21 | @_o 22 | def handle_socksDust(conn): 23 | print('connection') 24 | client = Client() 25 | yield client.connect('blanu.net', 7051) 26 | 27 | coder=yield handshake(client) 28 | 29 | monocle.launch(pump, conn, client, coder.encrypt) 30 | yield pump(client, conn, coder.decrypt) 31 | 32 | @_o 33 | def handshake(conn): 34 | ekeypair=createEphemeralKeypair() 35 | 36 | yield conn.write(ekeypair.public.bytes) 37 | epub=yield conn.read(KEY_SIZE) 38 | 39 | esession=makeEphemeralSession(ekeypair, epub) 40 | 41 | coder=lite_socket(esession) 42 | 43 | yield Return(coder) 44 | 45 | add_service(Service(handle_socksDust, port=7050)) 46 | eventloop.run() 47 | -------------------------------------------------------------------------------- /historical/v1/py/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup, find_packages 4 | 5 | setup( 6 | name='Dust', 7 | version='0.1a17', 8 | description='Blocking-resistant network protocol', 9 | author='Brandon Wiley', 10 | author_email='dust@blanu.net', 11 | url='http://github.com/blanu/Dust', 12 | # packages=['Dust'], 13 | packages=find_packages(), 14 | package_data={ 15 | '':['*.so', '*.dll'], 16 | }, 17 | long_description="""\ 18 | Dust is an Internet protocol designed to resist a number of attacks currently in active use to censor Internet communication. 19 | """, 20 | classifiers=[ 21 | "Development Status :: 3 - Alpha", 22 | "Environment :: No Input/Output (Daemon)", 23 | "License :: OSI Approved :: BSD License", 24 | "Programming Language :: Python", 25 | "Intended Audience :: Developers", 26 | "Operating System :: OS Independent", 27 | "Topic :: Internet", 28 | "Topic :: Security :: Cryptography", 29 | "Topic :: Software Development :: Libraries :: Python Modules", 30 | ], 31 | keywords='cryptography privacy internet', 32 | license='BSD', 33 | install_requires=[ 34 | 'pyskein>=0.6', 35 | 'bitstring', 36 | 'PyYAML>=3.09', 37 | ], 38 | # console_scripts=[ 39 | # ], 40 | zip_safe=True, 41 | ) -------------------------------------------------------------------------------- /go/v2/crypting/identity.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | /* 5 | Package crypting implements the cryptographic and framing layer of the Dust protocol suite. 6 | */ 7 | package crypting 8 | 9 | import ( 10 | "errors" 11 | 12 | "github.com/blanu/Dust/go/prim1" 13 | ) 14 | 15 | var ( 16 | ErrBadOpaqueId = errors.New("Dust/crypting: bad opaque ID") 17 | ) 18 | 19 | type OpaqueId prim.CValue 20 | 21 | // Public holds the longterm public key and shared identifier for a server. 22 | type Public struct { 23 | Id OpaqueId 24 | Key prim.Public 25 | } 26 | 27 | // Private holds the longterm private key and shared identifier for a server. 28 | type Private struct { 29 | Id OpaqueId 30 | Key prim.Private 31 | } 32 | 33 | func NewOpaqueId() *OpaqueId { 34 | opaque := OpaqueId(prim.RandomCValue()) 35 | return &opaque 36 | } 37 | 38 | func (opaque OpaqueId) Text() string { 39 | return prim.CValue(opaque).Text() 40 | } 41 | 42 | func LoadOpaqueIdText(text string) (*OpaqueId, error) { 43 | if cvalue, err := prim.CValueFromText(text); err == nil { 44 | opaque := OpaqueId(cvalue) 45 | return &opaque, nil 46 | } else { 47 | return nil, ErrBadOpaqueId 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/utp/demo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | from threading import Thread, Event 5 | from queue import Queue, Empty 6 | 7 | from dust.extensions.utp.dustUtpSocket import DustUtpSocket 8 | 9 | class LineReader: 10 | def __init__(self, outq): 11 | self.outq=outq 12 | 13 | def start(self): 14 | t=Thread(target=self.run) 15 | t.setDaemon(True) 16 | t.start() 17 | 18 | def run(self): 19 | while True: 20 | try: 21 | line=sys.stdin.readline() 22 | except: 23 | self.outq.put(None) 24 | return 25 | self.outq.put(line.encode('ascii')) 26 | 27 | class LinePrinter: 28 | def __init__(self, inq): 29 | self.inq=inq 30 | 31 | def start(self): 32 | t=Thread(target=self.run) 33 | t.setDaemon(True) 34 | t.start() 35 | 36 | def run(self): 37 | while True: 38 | line=self.inq.get() 39 | sys.stderr.write(line.decode('ascii')+"\n") 40 | sys.stderr.flush() 41 | 42 | if __name__=='__main__': 43 | if sys.argv[1]=='-s': 44 | server=True 45 | else: 46 | server=False 47 | 48 | inq=Queue() 49 | outq=Queue() 50 | 51 | lr=LineReader(inq) 52 | lp=LinePrinter(outq) 53 | dus=DustUtpSocket(server, inq, outq) 54 | 55 | lr.start() 56 | lp.start() 57 | dus.start() 58 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-crypto/Dust/Crypto/ECDSA.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric, DefaultSignatures #-} -- For automatic generation of cereal put and get 2 | 3 | module Dust.Crypto.ECDSA 4 | ( 5 | Signature, 6 | createSigningKeypair, 7 | sign, 8 | verify 9 | ) where 10 | 11 | import GHC.Generics (Generic) 12 | import Data.Serialize (Serialize) 13 | import Data.ByteString (ByteString) 14 | import qualified Data.ByteString as B 15 | 16 | import Dust.Crypto.Keys 17 | import qualified Crypto.Key as CK 18 | import qualified Crypto.Sign.Ed25519 as Ed 19 | 20 | newtype Signature = Signature { signatureBytes :: ByteString } deriving (Show, Eq, Generic) 21 | instance Serialize Signature 22 | 23 | -- FIXME - uses system entropy, but it would be better to pass in the PRNG 24 | createSigningKeypair :: IO Keypair 25 | createSigningKeypair = do 26 | (CK.PublicKey pub, CK.SecretKey priv) <- Ed.createKeypair 27 | return $ Keypair (PublicKey pub) (PrivateKey priv) 28 | 29 | sign :: ByteString -> PrivateKey -> Signature 30 | sign bs (PrivateKey private) = 31 | let (Ed.Signature sig) = Ed.sign' (CK.SecretKey private) bs 32 | in Signature sig 33 | 34 | verify :: ByteString -> Signature -> PublicKey -> Bool 35 | verify bs (Signature sig) (PublicKey public) = Ed.verify' (CK.PublicKey public) bs (Ed.Signature sig) 36 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/shared.py: -------------------------------------------------------------------------------- 1 | import monocle 2 | from monocle import _o, Return 3 | 4 | from monocle.stack.network import ConnectionLost 5 | 6 | from dust.core.util import encode 7 | 8 | @_o 9 | def pump(input, output, transform, debug=False): 10 | while True: 11 | try: 12 | message = yield input.read_some() 13 | # message=yield input.read(1) 14 | if not message or len(message)==0: 15 | print('0 from '+str(input)+' '+str(type(message))) 16 | raise(Exception()) 17 | # message=yield input.read(1) 18 | if debug: 19 | print('receive '+str(len(message))) 20 | except ConnectionLost: 21 | print('Client connection closed') 22 | output.close() 23 | break 24 | except IOError: 25 | output.close() 26 | break 27 | 28 | if transform: 29 | message=transform(message) 30 | 31 | if debug: 32 | print('sending '+str(len(message))) 33 | try: 34 | yield output.write(message) 35 | except ConnectionLost: 36 | print('Connection lost') 37 | input.close() 38 | return 39 | except IOError: 40 | print('IOError') 41 | input.close() 42 | return 43 | except Exception, e: 44 | print('Exception') 45 | print(e) 46 | input.close() 47 | return 48 | -------------------------------------------------------------------------------- /modelgen/src/convert-huffman.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import json 3 | import subprocess 4 | 5 | def huffman(content): 6 | print(content) 7 | print('Writing frequencies...') 8 | f=open('tmp.freqs', 'w') 9 | for x in range(len(content)): 10 | count=int(content[x]*1000000) 11 | f.write(str(count)) 12 | f.write("\n") 13 | print(str(x)+"/"+str(len(content))+' '+str(content[x])+' '+str(count)) 14 | f.close() 15 | print('Generating code table...') 16 | subprocess.call(['/Users/brandon/Dust-tools/dist/build/huffman/huffman', 'tmp.freqs', 'tmp.huffman']) 17 | 18 | f=open('tmp.huffman') 19 | s=f.read() 20 | f.close() 21 | 22 | l=s.split("\n") 23 | l=map(parse, l) 24 | l=filter(lambda x: x!=None, l) 25 | 26 | print(l) 27 | 28 | return l 29 | 30 | def parse(item): 31 | if item=='': 32 | return None 33 | a=[] 34 | for x in item: 35 | if x=="0": 36 | a.append(False) 37 | elif x=="1": 38 | a.append(True) 39 | return a 40 | 41 | f=open(sys.argv[1]) 42 | s=f.read() 43 | f.close() 44 | data=json.loads(s) 45 | 46 | data['incomingModel']['huffman']=huffman(data['incomingModel']['content']['params']) 47 | data['outgoingModel']['huffman']=huffman(data['outgoingModel']['content']['params']) 48 | 49 | f=open(sys.argv[1], 'w') 50 | f.write(json.dumps(data)) 51 | f.close() 52 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks3/shared.py: -------------------------------------------------------------------------------- 1 | import monocle 2 | from monocle import _o, Return 3 | 4 | from monocle.stack.network import ConnectionLost 5 | 6 | from dust.core.util import encode 7 | 8 | @_o 9 | def pump(input, output, transform, debug=False): 10 | while True: 11 | try: 12 | message = yield input.read_some() 13 | # message=yield input.read(1) 14 | if not message or len(message)==0: 15 | print('0 from '+str(input)+' '+str(type(message))) 16 | raise(Exception()) 17 | # message=yield input.read(1) 18 | if debug: 19 | print('receive '+str(len(message))) 20 | except ConnectionLost: 21 | print('Client connection closed') 22 | output.close() 23 | break 24 | except IOError: 25 | output.close() 26 | break 27 | 28 | if transform: 29 | message=yield transform(message) 30 | 31 | if debug: 32 | print('sending '+str(len(message))) 33 | try: 34 | yield output.write(message) 35 | except ConnectionLost: 36 | print('Connection lost') 37 | input.close() 38 | return 39 | except IOError: 40 | print('IOError') 41 | input.close() 42 | return 43 | except Exception, e: 44 | print('Exception') 45 | print(e) 46 | input.close() 47 | return 48 | -------------------------------------------------------------------------------- /historical/v1/py/dust/intro/intro.py: -------------------------------------------------------------------------------- 1 | from dust.invite.invite import loadInvitePackage 2 | from dust.intro.intro_packet import IntroPacket 3 | from dust.intro.intro_socket import intro_socket 4 | from dust.core.util import getAddress, getPublicIP 5 | from dust.crypto.curve import Key 6 | 7 | class Introducer: 8 | def __init__(self, keys, myaddr): 9 | self.keys=keys 10 | self.myaddr=myaddr 11 | 12 | def acceptIntroduction(self, data, addr): 13 | print('Introducing', addr) 14 | 15 | intro=IntroPacket() 16 | intro.decodeIntroPacket(self.keys.incomingInvites, data) 17 | if intro.intro: 18 | self.keys.addHost(addr, intro.intro.pubkey) 19 | return intro 20 | else: 21 | print('Could not read intro packet') 22 | return None 23 | 24 | def makeIntroduction(self, addr, sock): 25 | print('Introducing', addr) 26 | invite=self.keys.outgoingInvites.getInviteForHost(False, addr) 27 | if not invite: 28 | print('Can\'t find invite for', addr, ', invite failed.') 29 | return None 30 | 31 | print('invite:', invite) 32 | 33 | isock=intro_socket(self.keys, socket=sock) 34 | isock.iconnect(invite) 35 | isock.isend() 36 | 37 | self.keys.addHost((invite.ip, invite.port), invite.pubkey) 38 | 39 | return self.keys.getSessionKeyForHost(addr) 40 | -------------------------------------------------------------------------------- /go/v2/interface/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | package Dust 5 | 6 | // ParameterErrorHow describes whether the data element referenced in a ParameterError is missing, unexpected 7 | // (present but without a known interpretation), or invalid (present when expected but with an uninterpretable 8 | // value). 9 | type ParameterErrorHow int 10 | 11 | const ( 12 | ParameterErrorUnknown ParameterErrorHow = iota 13 | ParameterMissing 14 | ParameterUnexpected 15 | ParameterInvalid 16 | ) 17 | 18 | // ParameterError describes a problem relating to a specific data element. Specific may be the empty string 19 | // to refer to the single element of a kind. 20 | type ParameterError struct { 21 | How ParameterErrorHow 22 | Kind string 23 | Specific string 24 | } 25 | 26 | func (pe *ParameterError) Error() string { 27 | var str string 28 | switch pe.How { 29 | case ParameterErrorUnknown: 30 | str = "??? " 31 | case ParameterMissing: 32 | str = "missing " 33 | case ParameterUnexpected: 34 | str = "unexpected " 35 | case ParameterInvalid: 36 | str = "invalid " 37 | } 38 | 39 | str += pe.Kind 40 | if pe.Specific != "" { 41 | str += " '" + pe.Specific + "'" 42 | } 43 | return str 44 | } 45 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/test/TestDustPacket.java: -------------------------------------------------------------------------------- 1 | package dust.test; 2 | 3 | import java.util.Random; 4 | 5 | import dust.core.DustPacket; 6 | import dust.core.Util; 7 | import dust.crypto.DustPRNG; 8 | 9 | public class TestDustPacket 10 | { 11 | static public void main(String[] args) throws Exception 12 | { 13 | Random random=new Random(); 14 | 15 | byte[] key=Util.decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013"); 16 | // byte[] key=new byte[32]; 17 | // random.nextBytes(key); 18 | byte[] data="test #3".getBytes(); 19 | DustPRNG entropy=new DustPRNG(); 20 | 21 | DustPacket p1=DustPacket.create(key, data, entropy); 22 | byte[] bytes=p1.getBytes(); 23 | 24 | System.out.println("key: "+Util.encode(key)); 25 | System.out.println("p1: "+Util.encode(bytes)); 26 | System.out.println("mac: "+p1.checkMac()+" timestamp: "+p1.checkTimestamp()); 27 | 28 | DustPacket p2=DustPacket.decode(key, bytes); 29 | System.out.println("p2: "+new String(p2.getData())); 30 | System.out.println("mac: "+p2.checkMac()+" timestamp: "+p2.checkTimestamp()); 31 | 32 | DustPacket p3=DustPacket.decode(key, Util.decode(Util.encode(bytes))); 33 | System.out.println("p3: "+new String(p3.getData())); 34 | System.out.println("mac: "+p3.checkMac()+" timestamp: "+p3.checkTimestamp()); 35 | } 36 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/lite/lite_socket2.py: -------------------------------------------------------------------------------- 1 | from dust.crypto.dustUtil import hash 2 | from dust.core.dust_socket2 import dust_socket 3 | from dust.core.util import encodeAddress, xor, encode 4 | from dust.core.dust_packet2 import makeIV 5 | from dust.crypto.keys import KeyManager 6 | from dust.crypto.curve import Key 7 | from dust.crypto.dustUtil import DustCipher 8 | 9 | import monocle 10 | from monocle import _o, Return 11 | 12 | def makeSession(myAddress, address): 13 | addressKey=address[0] 14 | 15 | h1=hash(addressKey.encode('ascii')) 16 | h2=hash(myAddress[0].encode('ascii')) 17 | 18 | sessionKey=xor(h1, h2) 19 | return sessionKey 20 | 21 | def makeEphemeralSession(keypair, pub): 22 | pub=Key(pub, False) 23 | return keypair.createSession(pub) 24 | 25 | def createEphemeralKeypair(): 26 | return KeyManager().createKeypair() 27 | 28 | class lite_socket(object): 29 | def __init__(self, key): 30 | self.keys=KeyManager() 31 | self.key=key 32 | self.cipherIn=DustCipher(key, "\x00") 33 | self.cipherOut=DustCipher(key, "\x00") 34 | 35 | @_o 36 | def encrypt(self, data): 37 | data=self.cipherOut.encrypt(data) 38 | yield Return(data) 39 | 40 | @_o 41 | def decrypt(self, data): 42 | data=self.cipherIn.decrypt(data) 43 | yield Return(data) 44 | 45 | def createEphemeralKeypair(self): 46 | return self.keys.createKeypair() 47 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/dustSocksServer.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import time 4 | 5 | from struct import unpack 6 | from socket import inet_ntoa 7 | 8 | import monocle 9 | from monocle import _o, Return 10 | monocle.init('tornado') 11 | 12 | from monocle.stack import eventloop 13 | from monocle.stack.network import add_service, Service, Client, ConnectionLost 14 | from loopback import FakeSocket 15 | 16 | from dust.core.dust_packet import IV_SIZE, KEY_SIZE 17 | 18 | from dust.extensions.lite.lite_socket2 import lite_socket, makeSession, makeEphemeralSession, createEphemeralKeypair 19 | from dust.core.util import encode 20 | 21 | from shared import * 22 | from socks import * 23 | 24 | @_o 25 | def handle_dust(conn): 26 | print('handle_dust') 27 | coder=yield handshake(conn) 28 | 29 | client = Client() 30 | yield client.connect('localhost', 9050) 31 | 32 | monocle.launch(pump, conn, client, coder.decrypt) 33 | yield pump(client, conn, coder.encrypt) 34 | 35 | @_o 36 | def handshake(conn): 37 | ekeypair=createEphemeralKeypair() 38 | 39 | epub=yield conn.read(KEY_SIZE) 40 | esession=makeEphemeralSession(ekeypair, epub).bytes 41 | print('esssion: '+encode(esession)) 42 | coder=lite_socket(esession.bytes) 43 | yield conn.write(ekeypair.public.bytes) 44 | 45 | yield Return(coder) 46 | 47 | add_service(Service(handle_dust, port=7051)) 48 | eventloop.run() 49 | -------------------------------------------------------------------------------- /go/v2/interface/go.sum: -------------------------------------------------------------------------------- 1 | github.com/OperatorFoundation/ed25519 v0.0.0-20200225224545-b22b4bd3ddef h1:1xEtDEuNE9/yybZaHS94OIjx5FUo4e8M3UwcK9bFC9s= 2 | github.com/OperatorFoundation/ed25519 v0.0.0-20200225224545-b22b4bd3ddef/go.mod h1:gQNGvsyT4Zmps9H/yzCqdc+RQzt8ZxCndRNtGTYnBzQ= 3 | github.com/blanu/Dust v1.0.1 h1:C1IiRXr9YP1A4iiuhhpQOCgl8785LoVq78lbDrVRVqc= 4 | github.com/blanu/Dust v1.0.1/go.mod h1:jLFQI2Ufz4kBnGiTzh8O9+/p4U/9MLbouXkaympnTI0= 5 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= 6 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= 7 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 8 | golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw= 9 | golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 10 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 11 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 12 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 13 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 14 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/file/file_socket.py: -------------------------------------------------------------------------------- 1 | from dust.services.file.file_packet import FileMessage 2 | from dust.extensions.multiplex.multiplex_socket import multiplex_socket 3 | 4 | class file_socket(multiplex_socket): 5 | def __init__(self, keys): 6 | multiplex_socket.__init__(self, keys) 7 | self.connectToService('file') 8 | 9 | def fsend(self, headers, data): 10 | fmsg=FileMessage() 11 | fmsg.createFileMessage(headers, data) 12 | self.msend(fmsg.message, service='file') 13 | 14 | def fsendto(self, headers, data, addr): 15 | file=FileMessage() 16 | file.createFileMessage(headers, data) 17 | self.msendto(file.message, addr) 18 | 19 | def frecv(self): 20 | data, serviceName=self.mrecv(1024) 21 | if not data: 22 | return None, None 23 | file=FileMessage() 24 | file.decodeFileMessage(data) 25 | if serviceName!='file': 26 | print('Bad file service name', file.serviceName) 27 | return None, None 28 | return file.headers, file.data 29 | 30 | def frecvfrom(self): 31 | data, addr, serviceName=self.mrecvfrom(1024) 32 | if not data: 33 | print('File: No data') 34 | return None, None, None 35 | file=FileMessage() 36 | file.decodeFileMessage(data) 37 | if serviceName!='file': 38 | print('Bad file service name', file.serviceName) 39 | return None, None, None 40 | return file.headers, file.data, addr 41 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/mail-recv.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import yaml 4 | import email 5 | import smtplib 6 | 7 | from dust.core.dust_socket import * 8 | from dust.crypto.curve import loadKeypair 9 | 10 | f=open('emailServer.yaml', 'r') 11 | config=yaml.load(f.read()) 12 | f.close() 13 | 14 | buffsize=102400 15 | host = '::1' 16 | inport=7000 17 | outport=7001 18 | nodeName='A' 19 | 20 | keypair=loadKeypair(nodeName+'-priv.txt', nodeName+'-pub.txt') 21 | 22 | ecsock=dust_socket(keypair) 23 | ecsock.bind(('', inport)) 24 | #ecsock.connect((host, outport)) 25 | 26 | msg, addr=ecsock.recvfrom(1024) 27 | 28 | print('-----------------') 29 | print(msg.decode('ascii')) 30 | 31 | msg=msg.decode('ascii') 32 | mail=email.message_from_string(msg) 33 | to=mail['To'] 34 | frm=mail['From'] 35 | 36 | print('To:', to, 'From:', frm) 37 | 38 | tod=to.split('@')[1] 39 | frmd=frm.split('@')[1] 40 | 41 | addressKey=addr[0]+'-'+str(addr[1]) 42 | 43 | sender=config['senders'][addressKey] 44 | if not sender: 45 | print('Unknown sender', addr) 46 | else: 47 | if not tod in sender['to']: 48 | print('Illegal to address', tod, sender['to']) 49 | elif not frmd in sender['from']: 50 | print('Illegal from address', frmd, sender['from']) 51 | else: 52 | print('Sending...') 53 | # smtp = smtplib.SMTP(config['smtpHost']) 54 | # smtp.set_debuglevel(1) 55 | # smtp.sendmail(frm, to, msg) 56 | # smtp.quit() 57 | 58 | -------------------------------------------------------------------------------- /modelgen/examples/dustexample/dustexample.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "Dust" 6 | ) 7 | 8 | func main() { 9 | 10 | fmt.Println("Testing test...") 11 | 12 | var instance = &Dust.Test{} 13 | var result uint16 = 0 14 | 15 | fmt.Println("Testing duration...") 16 | 17 | for x := 0; x<10; x++ { 18 | result = instance.Duration() 19 | fmt.Printf("Duration: %d\n", result) 20 | } 21 | 22 | fmt.Println("Testing length...") 23 | 24 | for x := 0; x<10; x++ { 25 | result = instance.PacketLength() 26 | fmt.Printf("Length: %d\n", result) 27 | } 28 | 29 | fmt.Println("Testing count...") 30 | 31 | for x := 0; x<10; x++ { 32 | result = instance.PacketLength() 33 | fmt.Printf("Length: %d\n", result) 34 | } 35 | 36 | fmt.Println("Testing padding...") 37 | 38 | for x := 0; x<10; x++ { 39 | var bytes []byte = instance.RandomBytes(10) 40 | for index := range bytes { 41 | fmt.Printf("Random byte: %d\n", bytes[index]) 42 | } 43 | } 44 | 45 | fmt.Println("Testing encoding...") 46 | 47 | var testBytes = []byte {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 48 | var resultBytes []byte = instance.Encode(testBytes) 49 | var decoded []byte = instance.Decode(resultBytes) 50 | for index := range resultBytes { 51 | fmt.Printf("Encoded byte: %d -> %d <- %d\n", testBytes[index], resultBytes[index], decoded[index]) 52 | } 53 | 54 | fmt.Println("Done.") 55 | } 56 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/mail/mailService.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | import email 3 | import smtplib 4 | 5 | from dust.core.util import encodeAddress 6 | 7 | class MailHandler: 8 | def __init__(self): 9 | f=open('config/emailServer.yaml', 'r') 10 | self.config=yaml.load(f.read()) 11 | f.close() 12 | 13 | def handle(self, msock, msg, addr): 14 | print('-----------------') 15 | print(msg.decode('ascii')) 16 | 17 | msg=msg.decode('ascii') 18 | mail=email.message_from_string(msg) 19 | to=mail['To'] 20 | frm=mail['From'] 21 | 22 | print('To:', to, 'From:', frm) 23 | 24 | tod=to.split('@')[1] 25 | frmd=frm.split('@')[1] 26 | 27 | addressKey=encodeAddress(addr) 28 | 29 | try: 30 | sender=self.config['senders'][addressKey] 31 | except: 32 | print('Unknown sender', addr, 'trying generic...') 33 | try: 34 | sender=self.config['senders']['*'] 35 | except: 36 | print('No generic sender rules, rejecting.') 37 | return 38 | 39 | if not tod in sender['to']: 40 | print('Illegal to address', tod, sender['to']) 41 | elif not frmd in sender['from']: 42 | print('Illegal from address', frmd, sender['from']) 43 | else: 44 | print('Sending...') 45 | # smtp = smtplib.SMTP(self.config['smtpHost']) 46 | # smtp.set_debuglevel(1) 47 | # smtp.sendmail(frm, to, msg) 48 | # smtp.quit() 49 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-crypto/Dust-crypto.cabal: -------------------------------------------------------------------------------- 1 | Name: Dust-crypto 2 | Version: 0.3 3 | Description: Cryptographic operations used by the Dust polymorphic protocol engine 4 | Synopsis: Cryptographic operations 5 | Category: Cryptography 6 | License: GPL 7 | License-file: LICENSE 8 | Author: Brandon Wiley 9 | Maintainer: brandon@blanu.net 10 | Build-Type: Simple 11 | Cabal-Version: >=1.8 12 | 13 | Library 14 | Build-Depends: 15 | base >= 3 && < 5, 16 | bytestring, 17 | cereal, 18 | ghc-prim, 19 | nacl, 20 | skein, 21 | crypto-api, 22 | entropy, 23 | mtl, 24 | cereal, 25 | random 26 | 27 | Exposed-modules: 28 | Dust.Crypto.Keys, 29 | Dust.Crypto.ECDSA, 30 | Dust.Crypto.ECDH, 31 | Dust.Crypto.Cipher 32 | Dust.Crypto.PRNG 33 | Dust.Crypto.Hash 34 | 35 | test-suite crypto 36 | type: exitcode-stdio-1.0 37 | main-is: TestCrypto.hs 38 | ghc-options: -w -threaded -rtsopts -with-rtsopts=-N 39 | hs-source-dirs: tests 40 | 41 | build-depends: 42 | base, 43 | Dust, 44 | HUnit >= 1.2, 45 | test-framework >= 0.6, 46 | test-framework-hunit >= 0.2, 47 | test-framework-quickcheck2, 48 | -- test-framework-th, 49 | bytestring, 50 | threefish, 51 | cereal, 52 | ghc-prim, 53 | QuickCheck, 54 | mtl, 55 | binary 56 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks/proxy_packet.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import logging 3 | from dust.core.data_packet import DataPacket 4 | from dust.core.util import splitFields, encode, encodeFlags, decodeFlags 5 | 6 | REQID_LENGTH=4 7 | SEQ_LENGTH=4 8 | FLAGS_LENGTH=1 9 | 10 | def encodeSeq(seq): 11 | return struct.pack('I', seq) 12 | 13 | def decodeSeq(bs): 14 | return struct.unpack('I', bs)[0] 15 | 16 | class ProxyMessage: 17 | def __init__(self): 18 | self.reqid=None 19 | self.seq=None 20 | self.data=None 21 | self.msg=None 22 | 23 | def createProxyMessage(self, reqid, seq, fin, data): 24 | self.reqid=reqid 25 | self.seq=seq 26 | self.fin=fin 27 | self.data=data 28 | 29 | self.flags=[self.fin, False, False, False, False, False, False, False] 30 | 31 | self.msg=self.reqid+encodeSeq(seq)+encodeFlags(self.flags)+data 32 | 33 | def decodeProxyMessage(self, msg): 34 | self.msg=msg 35 | self.reqid, seqByte, flagBytes, self.data=splitFields(msg, [REQID_LENGTH, SEQ_LENGTH, FLAGS_LENGTH], True) 36 | self.seq=decodeSeq(seqByte) 37 | self.flags=decodeFlags(flagBytes) 38 | self.fin=self.flags[0] 39 | 40 | def __str__(self): 41 | s="ProxyMessage\n" 42 | s=s+"[\n" 43 | s=s+" reqid: "+str(encode(self.reqid)) 44 | s=s+" seq: "+str(self.seq) 45 | s=s+" flags: "+str(self.flags) 46 | s=s+" fin: "+str(self.fin) 47 | s=s+" data: "+str(self.data) 48 | s=s+"]\n\n" 49 | return s 50 | -------------------------------------------------------------------------------- /go/model1/encoder.go: -------------------------------------------------------------------------------- 1 | package model1 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/blanu/Dust/go/huffman" 7 | ) 8 | 9 | type Encoder struct { 10 | SleepDist Rand 11 | LengthDist Rand 12 | MaxSleep time.Duration 13 | Prefix []byte 14 | Unhuffer *huffman.Decoder 15 | 16 | position uint64 17 | } 18 | 19 | func (half *HalfModel) NewEncoderIsh() *Encoder { 20 | return &Encoder{ 21 | Prefix: half.Prefix, 22 | Unhuffer: huffman.NewDecoder(half.HuffCoding), 23 | position: 0, 24 | } 25 | } 26 | 27 | func (enc *Encoder) MaxPacketLength() uint16 { 28 | return 1440 29 | } 30 | 31 | func (enc *Encoder) NextPacketLength() uint16 { 32 | var result = clampUint16(enc.LengthDist.Rand()) 33 | for result <= 0 || result > 1440 { 34 | result = clampUint16(enc.LengthDist.Rand()) 35 | } 36 | return result 37 | // return 1440 38 | } 39 | 40 | func (enc *Encoder) NextPacketSleep() time.Duration { 41 | var r = enc.SleepDist.Rand() 42 | for r <= 0 || r > 5000 { 43 | r = enc.SleepDist.Rand() 44 | } 45 | return time.Duration(r * float64(time.Millisecond)) 46 | } 47 | 48 | func (enc *Encoder) ShapeBytes(dst, src []byte) (dn, sn int) { 49 | if enc.position < uint64(len(enc.Prefix)) { 50 | fixedn := copy(dst, enc.Prefix[enc.position:]) 51 | dst = dst[fixedn:] 52 | dn += fixedn 53 | enc.position += uint64(fixedn) 54 | } 55 | 56 | hdn, hsn := enc.Unhuffer.Decode(dst, src) 57 | enc.position += uint64(hdn) 58 | dn += hdn 59 | sn += hsn 60 | return 61 | } 62 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/http/proxyback_packet.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import logging 3 | from dust.core.data_packet import DataPacket 4 | from dust.core.util import splitFields, encode, encodeFlags, decodeFlags 5 | 6 | REQID_LENGTH=4 7 | SEQ_LENGTH=4 8 | FLAGS_LENGTH=1 9 | 10 | def encodeSeq(seq): 11 | return struct.pack('I', seq) 12 | 13 | def decodeSeq(bs): 14 | return struct.unpack('I', bs)[0] 15 | 16 | class ProxybackMessage: 17 | def __init__(self): 18 | self.reqid=None 19 | self.seq=None 20 | self.data=None 21 | self.msg=None 22 | 23 | def createProxybackMessage(self, reqid, seq, fin, data): 24 | self.reqid=reqid 25 | self.seq=seq 26 | self.fin=fin 27 | self.data=data 28 | 29 | self.flags=[self.fin, False, False, False, False, False, False, False] 30 | 31 | self.msg=self.reqid+encodeSeq(seq)+encodeFlags(self.flags)+data 32 | 33 | def decodeProxybackMessage(self, msg): 34 | self.msg=msg 35 | self.reqid, seqByte, flagBytes, self.data=splitFields(msg, [REQID_LENGTH, SEQ_LENGTH, FLAGS_LENGTH]) 36 | self.seq=decodeSeq(seqByte) 37 | self.flags=decodeFlags(flagBytes) 38 | self.fin=self.flags[0] 39 | 40 | def __str__(self): 41 | s="ProxybackMessage\n" 42 | s=s+"[\n" 43 | s=s+" reqid: "+str(encode(self.reqid)) 44 | s=s+" seq: "+str(self.seq) 45 | s=s+" flags: "+str(self.flags) 46 | s=s+" fin: "+str(self.fin) 47 | s=s+" data: "+str(self.data) 48 | s=s+"]\n\n" 49 | return s 50 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks/proxyback_packet.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import logging 3 | from dust.core.data_packet import DataPacket 4 | from dust.core.util import splitFields, encode, encodeFlags, decodeFlags 5 | 6 | REQID_LENGTH=4 7 | SEQ_LENGTH=4 8 | FLAGS_LENGTH=1 9 | 10 | def encodeSeq(seq): 11 | return struct.pack('I', seq) 12 | 13 | def decodeSeq(bs): 14 | return struct.unpack('I', bs)[0] 15 | 16 | class ProxybackMessage: 17 | def __init__(self): 18 | self.reqid=None 19 | self.seq=None 20 | self.data=None 21 | self.msg=None 22 | 23 | def createProxybackMessage(self, reqid, seq, fin, data): 24 | self.reqid=reqid 25 | self.seq=seq 26 | self.fin=fin 27 | self.data=data 28 | 29 | self.flags=[self.fin, False, False, False, False, False, False, False] 30 | 31 | self.msg=self.reqid+encodeSeq(seq)+encodeFlags(self.flags)+data 32 | 33 | def decodeProxybackMessage(self, msg): 34 | self.msg=msg 35 | self.reqid, seqByte, flagBytes, self.data=splitFields(msg, [REQID_LENGTH, SEQ_LENGTH, FLAGS_LENGTH], True) 36 | self.seq=decodeSeq(seqByte) 37 | self.flags=decodeFlags(flagBytes) 38 | self.fin=self.flags[0] 39 | 40 | def __str__(self): 41 | s="ProxybackMessage\n" 42 | s=s+"[\n" 43 | s=s+" reqid: "+str(encode(self.reqid)) 44 | s=s+" seq: "+str(self.seq) 45 | s=s+" flags: "+str(self.flags) 46 | s=s+" fin: "+str(self.fin) 47 | s=s+" data: "+str(self.data) 48 | s=s+"]\n\n" 49 | return s 50 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/utp/inetd-test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | from threading import Thread, Event 5 | from queue import Queue, Empty 6 | from subprocess import Popen, PIPE 7 | 8 | from dust.extensions.utp.dustUtpSocket import DustUtpSocket 9 | 10 | class Inetd: 11 | def __init__(self, inq, outq): 12 | self.inq=inq 13 | self.outq=outq 14 | 15 | def start(self): 16 | self.proc=Popen(['fossil', 'http', '/home/blanu/fossil/'], stdin=PIPE, stdout=PIPE) 17 | # self.proc=Popen(['fossil', 'help'], stdin=PIPE, stdout=PIPE) 18 | 19 | t=Thread(target=self.processIn) 20 | t.setDaemon(True) 21 | t.start() 22 | 23 | t2=Thread(target=self.processOut) 24 | # t2.setDaemon(True) 25 | t2.start() 26 | 27 | def processIn(self): 28 | self.proc.poll() 29 | while not self.proc.returncode: 30 | data=self.inq.get() 31 | print('inetd -> '+str(data)) 32 | self.proc.stdin.write(data) 33 | self.proc.stdin.flush() 34 | self.proc.poll() 35 | 36 | def processOut(self): 37 | print('waiting to finish') 38 | # self.proc.wait() 39 | print('finished') 40 | print('waiting to read from inetd') 41 | data=self.proc.stdout.read() 42 | print('inetd <- '+str(data)) 43 | self.outq.put(data) 44 | 45 | if __name__=='__main__': 46 | inq=Queue() 47 | outq=Queue() 48 | 49 | outq.put("GET / HTTP/1.0\n".encode('ascii')) 50 | outq.put("\n".encode('ascii')) 51 | inetd=Inetd(outq, inq) 52 | 53 | inetd.start() 54 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust-command/Dust/Control/Lazy.hs: -------------------------------------------------------------------------------- 1 | module Dust.Control.Lazy 2 | ( 3 | byteSource, 4 | packetize, 5 | depacketize, 6 | getRequests 7 | ) 8 | where 9 | 10 | import Data.ByteString.Char8 (pack, unpack) 11 | import System.IO (stdin, stdout) 12 | import System.IO.Error 13 | import Data.Binary.Get (runGet, runGetState) 14 | import Data.Binary.Put (runPut) 15 | import qualified Data.ByteString as B 16 | import qualified Data.ByteString.Lazy as BL 17 | import Data.Word 18 | 19 | import Dust.Control.Protocol 20 | import Dust.Control.State 21 | 22 | byteSource :: IO BL.ByteString 23 | byteSource = BL.getContents 24 | 25 | -------- 26 | 27 | packetize :: BL.ByteString -> [BL.ByteString] 28 | packetize stream = do 29 | if BL.null stream 30 | then [] 31 | else do 32 | let (lenbs, stream') = BL.splitAt 2 stream 33 | let len = fromIntegral $ runGet getPacketLength lenbs 34 | let (bs, stream'') = BL.splitAt len stream' 35 | bs : packetize stream'' 36 | 37 | depacketize :: [BL.ByteString] -> BL.ByteString 38 | depacketize [] = BL.empty 39 | depacketize (packet:packets) = do 40 | let len = BL.length packet 41 | let lenbs = runPut (putPacketLength (fromIntegral len)) 42 | let chunk = BL.append lenbs packet 43 | BL.append chunk (depacketize packets) 44 | 45 | -------- 46 | 47 | getRequests :: [BL.ByteString] -> [Maybe ControlRequest] 48 | getRequests [] = [] 49 | getRequests (packet:packets) = do 50 | let request = runGet getControlRequest packet 51 | request : getRequests packets 52 | -------------------------------------------------------------------------------- /docs/v2/overview.md: -------------------------------------------------------------------------------- 1 | # Overview of Dust 2.5 2 | 3 | ## Terminology 4 | 5 | [XXX] 6 | 7 | ## The protocol stack 8 | 9 | The Dust 2.5 stack consists of the following context assumptions and resultant layers: 10 | 11 | - A client and server (the communicating parties) wish to transceive datagrams. The client has been introduced 12 | to the server out of band, but not necessarily the other way around. The client is already capable of 13 | establishing “visible stream” connections with the server, where visible streams must conform to certain 14 | static and statistical properties to avoid being blocked by a censoring adversary. 15 | - The [crypting.md](crypting layer) converts the datagrams into uniform streams to prevent adversaries from 16 | reading or tampering with them and to eliminate any predictable patterns within the content that adversaries 17 | might use to detect the presence of a Dust stream. 18 | - The [shaping.md](shaping layer) converts the uniform streams into visible streams that satisfy the desired 19 | properties so that the censoring adversary, who can see the contents and timing of the visible streams, will 20 | allow them through. 21 | 22 | ## The pluggable transport for Tor 23 | 24 | The Dust2 pluggable transport for Tor additionally has the following provisions: 25 | 26 | - Visible connections are transceived over TCP/IP. 27 | - One Tor bridge connection is transceived per visible connection. The only transformation made to 28 | content in each direction is reblocking the byte stream into datagrams of at most the Dust MTU. 29 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/loopback.py: -------------------------------------------------------------------------------- 1 | import monocle 2 | from monocle import _o 3 | monocle.init('tornado') 4 | 5 | from monocle.core import Callback, Return 6 | from monocle.stack import eventloop 7 | 8 | from monocle.stack.network import Connection, ConnectionLost 9 | from monocle.experimental import Channel 10 | 11 | buffsize=1024 12 | 13 | class FakeSocket(object): 14 | def __init__(self, a=None, b=None): 15 | if a==None: 16 | self.a=Channel(buffsize) 17 | else: 18 | self.a=a 19 | if b==None: 20 | self.b=Channel(buffsize) 21 | else: 22 | self.b=b 23 | 24 | self.inBuff=b'' 25 | self.outBuff=b'' 26 | 27 | def invert(self): 28 | return FakeSocket(a=self.b, b=self.a) 29 | 30 | @_o 31 | def read(self, x): 32 | while len(self.inBuff)0: 47 | data=self.inBuff 48 | self.inBuff=b'' 49 | yield Return(data) 50 | else: 51 | data=b'' 52 | while len(data)==0: 53 | data=yield self.a.recv() 54 | if data: 55 | yield Return(data) 56 | else: 57 | yield ConnectionLost() 58 | 59 | @_o 60 | def write(self, bs): 61 | yield self.b.send(bs) 62 | 63 | def close(self): 64 | yield self.b.send(None) 65 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks3/loopback.py: -------------------------------------------------------------------------------- 1 | import monocle 2 | from monocle import _o 3 | monocle.init('tornado') 4 | 5 | from monocle.core import Callback, Return 6 | from monocle.stack import eventloop 7 | 8 | from monocle.stack.network import Connection, ConnectionLost 9 | from monocle.experimental import Channel 10 | 11 | buffsize=1024 12 | 13 | class FakeSocket(object): 14 | def __init__(self, a=None, b=None): 15 | if a==None: 16 | self.a=Channel(buffsize) 17 | else: 18 | self.a=a 19 | if b==None: 20 | self.b=Channel(buffsize) 21 | else: 22 | self.b=b 23 | 24 | self.inBuff=b'' 25 | self.outBuff=b'' 26 | 27 | def invert(self): 28 | return FakeSocket(a=self.b, b=self.a) 29 | 30 | @_o 31 | def read(self, x): 32 | while len(self.inBuff)0: 47 | data=self.inBuff 48 | self.inBuff=b'' 49 | yield Return(data) 50 | else: 51 | data=b'' 52 | while len(data)==0: 53 | data=yield self.a.recv() 54 | if data: 55 | yield Return(data) 56 | else: 57 | yield ConnectionLost() 58 | 59 | @_o 60 | def write(self, bs): 61 | yield self.b.send(bs) 62 | 63 | def close(self): 64 | yield self.b.send(None) 65 | -------------------------------------------------------------------------------- /historical/v1/py/dust/intro/intro_socket.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import struct 4 | from socket import * 5 | 6 | import yaml 7 | 8 | from dust.crypto.curve import * 9 | from dust.intro.intro_packet import IntroPacket 10 | from dust.core.util import encodeAddress 11 | 12 | class intro_socket: 13 | def __init__(self, keys, socket=None): 14 | self.keys=keys 15 | self.pubkey=keys.getKeypair().public 16 | if socket: 17 | self.sock=socket 18 | else: 19 | self.sock=None 20 | self.address=None 21 | 22 | def bind(self, address): 23 | print('binding', address) 24 | self.address=address 25 | 26 | def iconnect(self, invite): 27 | self.invite=invite 28 | 29 | def isend(self): 30 | if not self.invite: 31 | print('No invite') 32 | return 33 | 34 | if not self.sock: 35 | if self.invite.v6: 36 | self.sock=socket(AF_INET6, SOCK_DGRAM) 37 | else: 38 | self.sock=socket(AF_INET, SOCK_DGRAM) 39 | 40 | if self.address: 41 | try: 42 | self.sock.bind(self.address) 43 | except: 44 | if self.invite.v6: 45 | self.sock.bind(('::',self.address[1])) 46 | else: 47 | self.sock.bind(('',self.address[1])) 48 | 49 | packet=IntroPacket() 50 | packet.createIntroPacket(self.invite.secret, self.invite.id, self.pubkey, self.keys.entropy) 51 | addr=(self.invite.ip, self.invite.port) 52 | self.sock.sendto(packet.packet, 0, addr) 53 | self.invite=None # Invites are single use only 54 | -------------------------------------------------------------------------------- /go/v2/crypting/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | package crypting 5 | 6 | import ( 7 | "errors" 8 | "net" 9 | ) 10 | 11 | var ( 12 | ErrBadHandshake = errors.New("Dust/crypting: bad handshake") 13 | ErrBadDecode = errors.New("Dust/crypting: bad decode") 14 | ErrNotSupported = errors.New("Dust/crypting: operation not supported") 15 | ) 16 | 17 | type errTimeout struct{} 18 | var ErrTimeout net.Error = (*errTimeout)(nil) 19 | 20 | func (_ *errTimeout) Error() string { 21 | return "Dust/crypting: I/O timeout" 22 | } 23 | 24 | func (_ *errTimeout) Timeout() bool { 25 | return true 26 | } 27 | 28 | func (_ *errTimeout) Temporary() bool { 29 | return false 30 | } 31 | 32 | type errInterrupted struct{} 33 | var ErrInterrupted net.Error = (*errInterrupted)(nil) 34 | 35 | func (_ *errInterrupted) Error() string { 36 | return "Dust/crypting: I/O interrupted" 37 | } 38 | 39 | func (_ *errInterrupted) Timeout() bool { 40 | return false 41 | } 42 | 43 | func (_ *errInterrupted) Temporary() bool { 44 | return true 45 | } 46 | 47 | type errCrashInterrupted struct{} 48 | var ErrCrashInterrupted net.Error = (*errCrashInterrupted)(nil) 49 | 50 | func (_ *errCrashInterrupted) Error() string { 51 | return "Dust/crypting: I/O interrupted (irreversibly)" 52 | } 53 | 54 | func (_ *errCrashInterrupted) Timeout() bool { 55 | return false 56 | } 57 | 58 | func (_ *errCrashInterrupted) Temporary() bool { 59 | return true 60 | } 61 | -------------------------------------------------------------------------------- /go/v2/shaping/shaper.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | package shaping 5 | 6 | import ( 7 | "io" 8 | 9 | "github.com/op/go-logging" 10 | 11 | "github.com/blanu/Dust/go/v2/crypting" 12 | "github.com/blanu/Dust/go/proc" 13 | ) 14 | 15 | var log = logging.MustGetLogger("Dust/shaping") 16 | 17 | // Shaper represents a process mediating between a shaped channel and a Dust crypting session. It can be 18 | // managed through its proc.Link structure. 19 | type Shaper struct { 20 | proc.Ctl 21 | 22 | incoming incoming 23 | outgoing outgoing 24 | } 25 | 26 | func (sh *Shaper) runShaper(env *proc.Env) (err error) { 27 | select { 28 | case _ = <-env.Cancel: 29 | return env.ExitCanceled() 30 | } 31 | } 32 | 33 | // NewShaper initializes a new shaper process object for the outward-facing side of crypter, using in/out for 34 | // receiving and sending shaped data and decoder/encoder as the model for this side of the Dust connection. 35 | // The shaper will not be running. Call Start() on the shaper afterwards to start it in the background. 36 | func NewShaper( 37 | parent *proc.Env, 38 | crypter *crypting.Session, 39 | in io.Reader, 40 | decoder Decoder, 41 | out io.Writer, 42 | encoder Encoder, 43 | ) (*Shaper, error) { 44 | sh := &Shaper{} 45 | env := proc.InitChild(parent, &sh.Ctl, sh.runShaper) 46 | sh.incoming.Init(env, crypter.Back, in, decoder) 47 | sh.outgoing.Init(env, out, crypter.Back, encoder) 48 | return sh, nil 49 | } 50 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Model/PacketLength.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric, DefaultSignatures #-} -- For automatic generation of cereal put and get 2 | 3 | module Dust.Model.PacketLength 4 | ( 5 | PacketLengthModel(..), 6 | nextLength 7 | ) 8 | where 9 | 10 | import GHC.Generics (Generic) 11 | import qualified Data.ByteString as B 12 | import Data.Serialize (Serialize, decode) 13 | import Control.Monad.State.Lazy (State(..), get, put) 14 | import Data.Word (Word16) 15 | import Debug.Trace 16 | 17 | import Dust.Crypto.PRNG (PRNG, randomDouble) 18 | 19 | data PacketLengthModel = PacketLengthModel [Double] deriving (Eq, Show, Generic) 20 | 21 | instance Serialize PacketLengthModel 22 | 23 | nextLength :: [Double] -> State PRNG Word16 24 | nextLength weights = do 25 | prng <- get 26 | let (r, prng') = randomDouble prng 27 | traceShow r $ put prng' 28 | let result = weightedSample weights r 29 | return result 30 | -- let dist = weightedSampleCDF 1 cdf 31 | -- arr <- runRVar dist StdRandom :: IO [Int] 32 | -- return (head arr) 33 | 34 | weightedSample :: [Double] -> Double -> Word16 35 | weightedSample weights r = traceShow weights $ weightedSampleWithIndex 0 weights r 36 | 37 | weightedSampleWithIndex :: Word16 -> [Double] -> Double -> Word16 38 | weightedSampleWithIndex index [] r = index 39 | weightedSampleWithIndex index (weight:weights) r = do 40 | let r' = traceShow (r,weight,r-weight) $ r - weight 41 | if r < 0 42 | then traceShow (r,index) $ index 43 | else traceShow (r,index) $ weightedSampleWithIndex (index+1) weights r' 44 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Network/DustClient.hs: -------------------------------------------------------------------------------- 1 | module Dust.Network.DustClient 2 | ( 3 | dustClient 4 | ) 5 | where 6 | 7 | import qualified Data.ByteString as B 8 | import qualified Data.ByteString.Lazy as BL 9 | import Data.ByteString.Char8 (pack) 10 | import Data.Binary.Put 11 | import System.Environment (getArgs) 12 | import System.IO.Error 13 | import Network.Socket 14 | import Crypto.Threefish.Random 15 | 16 | import Dust.Crypto.Keys 17 | import Dust.Crypto.ECDH 18 | import Dust.Core.Protocol 19 | import Dust.Crypto.Cipher 20 | import Dust.Core.DustPacket 21 | import Dust.Network.TcpClient 22 | import Dust.Model.TrafficModel 23 | 24 | dustClient :: TrafficGenerator -> FilePath -> Plaintext -> IO(Plaintext) 25 | dustClient gen idpath payload = do 26 | -- let host = "166.78.129.122" 27 | let host = "127.0.0.1" 28 | let port = 6885 29 | 30 | rand <- newSkeinGen 31 | let (iv, rand') = createIV rand 32 | 33 | keypair <- createKeypair 34 | public <- loadPublic idpath 35 | let session = makeSession keypair public iv 36 | 37 | client host port (handleRequest gen session payload) 38 | 39 | handleRequest :: TrafficGenerator -> Session -> Plaintext -> Socket -> IO(Plaintext) 40 | handleRequest gen session@(Session keypair _ _) payload sock = do 41 | putStrLn $ "Request:" ++ (show payload) 42 | 43 | putSessionPacket gen session payload sock 44 | 45 | otherSession <- getSession gen keypair sock 46 | plaintext <- getPacket gen otherSession sock 47 | 48 | putStrLn $ "Response:" ++ (show plaintext) 49 | 50 | return plaintext 51 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/test-tracker.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from dust.crypto.keys import KeyManager 4 | from dust.core.util import getPublicIP, encodeAddress 5 | from dust.server.router import PacketRouter 6 | 7 | from dust.services.tracker.trackerClient import TrackerClient 8 | 9 | def foundPeer(pubkey, peer): 10 | print('foundPeer '+str(pubkey)+' '+str(peer)) 11 | pubkey=peer[0] 12 | addr=peer[1] 13 | 14 | passwd=sys.argv[1] 15 | inport=int(sys.argv[2]) 16 | dest=sys.argv[3] 17 | outport=int(sys.argv[4]) 18 | ipv=int(sys.argv[5]) 19 | if ipv==6: 20 | v6=True 21 | else: 22 | v6=False 23 | 24 | host=getPublicIP(v6) 25 | print('Host: '+str(host)) 26 | 27 | keys=KeyManager() 28 | keys.setInvitePassword(passwd) 29 | keys.loadKnownHosts('config/knownhosts.yaml') 30 | keys.loadKeypair('config/id.yaml') 31 | keys.loadIncomingInvites('config/incoming_invites.ip') 32 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 33 | 34 | router=PacketRouter(v6, inport, keys, passwd) 35 | router.connect(dest, outport) 36 | 37 | tracker=TrackerClient(router) 38 | trackback=router.getService('trackback') 39 | 40 | router.start() 41 | 42 | tracker.putPeerForEndpoint('43aafb64bc96460f3928f6068b2a01aa87bac16da6dc034b4525d1837e9cb85e', ['43aafb64bc96460f3928f6068b2a01aa87bac16da6dc034b4525d1837e9cb85e', encodeAddress((host, inport))]) 43 | trackback.setPutPeerForEndpointCallback('43aafb64bc96460f3928f6068b2a01aa87bac16da6dc034b4525d1837e9cb85e', foundPeer) 44 | tracker.getPeerForEndpoint('43aafb64bc96460f3928f6068b2a01aa87bac16da6dc034b4525d1837e9cb85e') 45 | 46 | while True: 47 | time.sleep(1) 48 | -------------------------------------------------------------------------------- /historical/v1/py/dust/util/safethread.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import traceback 3 | from threading import Thread, Event 4 | 5 | # If you don't do it this way, ctrl-c doesn't work anymore. 6 | def waitForEvent(event): 7 | done=False 8 | while not event.isSet() and not done: 9 | try: 10 | event.wait(1000) 11 | except KeyboardInterrupt: 12 | done=True 13 | 14 | def waitFor(delay): 15 | # Event().wait(delay) 16 | import time 17 | time.sleep(delay) 18 | 19 | def wait(): 20 | # Event().wait() 21 | import time 22 | done=False 23 | while not done: 24 | try: 25 | time.sleep(1000) 26 | except KeyboardInterrupt: 27 | print('Ctrl-C') 28 | done=True 29 | 30 | def waitForThreads(threads): 31 | while len(threads) > 0: 32 | try: 33 | print('Threads before: '+str(threads)) 34 | threads = [t.join(1) for t in threads if t is not None and t.isAlive()] 35 | print('Threads after: '+str(threads)) 36 | except KeyboardInterrupt: 37 | print("Ctrl-c received! Sending kill to threads...") 38 | for t in threads: 39 | t.done = True 40 | 41 | class SafeThread(Thread): 42 | def __init__(self, target=None, args=None): 43 | Thread.__init__(self, target=self.safeCall) 44 | self.method=target 45 | self.args=args 46 | self.done=False 47 | 48 | def safeCall(self): 49 | if self.method==None: 50 | return 51 | try: 52 | if self.args==None: 53 | self.method() 54 | else: 55 | self.method(*self.args) 56 | except Exception: 57 | print('Internal crash') 58 | traceback.print_exc() 59 | -------------------------------------------------------------------------------- /historical/v1/py/dust/invite/inviteShell.py: -------------------------------------------------------------------------------- 1 | from dust.crypto.keys import KeyManager 2 | 3 | class InviteShell: 4 | def __init__(self, keys): 5 | self.keys=keys 6 | 7 | def run(self): 8 | self.printHelp() 9 | command=self.getCommand() 10 | while command!='q': 11 | self.executeCommand(command) 12 | command=self.getCommand() 13 | 14 | def printHelp(self): 15 | print('h: help') 16 | print('a: add invite') 17 | print('d: delete invite') 18 | print('l: list invites') 19 | print('li: list incoming invites') 20 | print('lo: list outgoing invites') 21 | 22 | def getCommand(self): 23 | return input('> ').strip() 24 | 25 | def executeCommand(self, command): 26 | if command=='h': 27 | self.printHelp() 28 | elif command=='a': 29 | pass 30 | elif command=='d': 31 | pass 32 | elif command=='l': 33 | print('Incoming:') 34 | print(keys.incomingInvites) 35 | print() 36 | print('Outgoing:') 37 | print(keys.outgoingInvites) 38 | elif command=='li': 39 | print('Incoming:') 40 | print(keys.incomingInvites) 41 | elif command=='lo': 42 | print('Outgoing:') 43 | print(keys.outgoingInvites) 44 | 45 | if __name__=='__main__': 46 | passwd=input('Password: ') 47 | keys=KeyManager() 48 | keys.setInvitePassword(passwd) 49 | keys.loadKnownHosts('config/knownhosts.yaml') 50 | keys.loadKeypair('config/id.yaml') 51 | keys.loadIncomingInvites('config/incoming_invites.ip') 52 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 53 | 54 | shell=InviteShell(keys) 55 | shell.run() 56 | -------------------------------------------------------------------------------- /go/prim1/asym_repr.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package prim 5 | 6 | const ( 7 | PublicBinaryLen = 32 8 | PrivateBinaryLen = 32 9 | PublicTextLen = 52 10 | PrivateTextLen = 52 11 | ) 12 | 13 | func LoadPublicBinary(b []byte) (result Public, err error) { 14 | if len(b) != 32 { 15 | return Public{}, ErrBadPublicKey 16 | } 17 | copy(result.uniform[:], b) 18 | err = result.recompute() 19 | return 20 | } 21 | 22 | func LoadPublicText(s string) (result Public, err error) { 23 | err = decodeText((*[32]byte)(&result.uniform), s, ErrBadPublicKey) 24 | if err != nil { 25 | return 26 | } 27 | err = result.recompute() 28 | return 29 | } 30 | 31 | func LoadPrivateBinary(b []byte) (result Private, err error) { 32 | if len(b) != 32 { 33 | return Private{}, ErrBadPrivateKey 34 | } 35 | copy(result.private[:], b) 36 | err = result.recompute() 37 | return 38 | } 39 | 40 | func LoadPrivateText(s string) (result Private, err error) { 41 | err = decodeText((*[32]byte)(&result.private), s, ErrBadPrivateKey) 42 | if err != nil { 43 | return 44 | } 45 | err = result.recompute() 46 | return 47 | } 48 | 49 | func (public Public) Binary() []byte { 50 | return public.uniform[:] 51 | } 52 | 53 | func (public Public) Text() string { 54 | return encodeText((*[32]byte)(&public.uniform)) 55 | } 56 | 57 | func (private Private) PrivateBinary() []byte { 58 | return private.private[:] 59 | } 60 | 61 | func (private Private) PrivateText() string { 62 | return encodeText((*[32]byte)(&private.private)) 63 | } 64 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks2/socksDustProxy.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | from struct import unpack 5 | from socket import inet_ntoa 6 | 7 | import monocle 8 | from monocle import _o, Return 9 | monocle.init('tornado') 10 | 11 | from monocle.stack import eventloop 12 | from monocle.stack.network import add_service, Service, Client 13 | 14 | from dust.core.util import getPublicIP, encode 15 | 16 | from shared import pump 17 | 18 | from dust.extensions.lite.lite_socket2 import lite_socket, makeSession, makeEphemeralSession, createEphemeralKeypair 19 | from dust.core.dust_packet import IV_SIZE, KEY_SIZE 20 | 21 | from socks import * 22 | 23 | @_o 24 | def handle_socks(conn): 25 | yield readHandshake(conn) 26 | yield sendHandshake(conn) 27 | dest=yield readRequest(conn) 28 | yield sendResponse(dest, conn) 29 | 30 | addr, port=uncompact(dest) 31 | print(addr) 32 | print(port) 33 | 34 | client = Client() 35 | yield client.connect(addr, port) 36 | 37 | yield handle_socksDust(conn, client) 38 | 39 | @_o 40 | def handle_socksDust(conn, client): 41 | print('handle socks dust') 42 | coder=yield handshake(client) 43 | 44 | monocle.launch(pump, conn, client, coder.encrypt) 45 | yield pump(client, conn, coder.decrypt) 46 | 47 | @_o 48 | def handshake(client): 49 | ekeypair=createEphemeralKeypair() 50 | 51 | yield client.write(ekeypair.public.bytes) 52 | epub=yield client.read(KEY_SIZE) 53 | 54 | esession=makeEphemeralSession(ekeypair, epub) 55 | print('esession: '+encode(esession.bytes)) 56 | coder=lite_socket(esession) 57 | 58 | yield Return(coder) 59 | 60 | add_service(Service(handle_socks, port=7050)) 61 | eventloop.run() 62 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/dustmail/add.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3.1 2 | import os 3 | import sys 4 | from dust.crypto.keys import KeyManager 5 | from dust.crypto.curve import Key 6 | from dust.core.util import getPublicIP, encode, decode, encodeAddress, decodeAddress 7 | from dust.util.ymap import YamlMap 8 | 9 | from dust.invite.invite_packet import InviteMessage 10 | from dust.services.dustmail.dustmail_packet import DustmailInvitePacket 11 | 12 | passwd=sys.argv[1] 13 | 14 | keys=KeyManager() 15 | keys.setInvitePassword(passwd) 16 | keys.loadKnownHosts('config/knownhosts.yaml') 17 | keys.loadKeypair('config/id.yaml') 18 | keys.loadIncomingInvites('config/incoming_invites.ip') 19 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 20 | endpoint=keys.loadEndpoint(os.path.expanduser('~/.dust/endpoint.yaml')) 21 | 22 | pf=input("Load invite from Paste or File [P/f]? ") 23 | if pf=='f': 24 | filename=input("Load invite from filename: ").strip() 25 | f=open(filename, 'rb') 26 | data=f.read() 27 | f.close() 28 | else: 29 | data=decode(input("Past invite: ")) 30 | 31 | passwd=input("Decrypt invite with password: ") 32 | packet=DustmailInvitePacket() 33 | packet.decodeDustmailInvitePacket(passwd, data) 34 | print("pubkey: "+encode(packet.pubkey)) 35 | print("invite: "+encode(packet.invite)) 36 | invite=InviteMessage() 37 | invite.decodeInviteMessage(packet.invite) 38 | keys.addInvite(invite) 39 | 40 | name=input("Name for this endpoint: ") 41 | book=YamlMap('config/dustmail-addressbook.yaml') 42 | try: 43 | entry=book[name] 44 | except: 45 | entry={} 46 | entry['pubkey']=encode(packet.pubkey) 47 | entry['tracker']=encodeAddress((invite.ip, invite.port)) 48 | book[name]=entry 49 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/test/TestDustCrypto.java: -------------------------------------------------------------------------------- 1 | package dust.test; 2 | 3 | import java.util.Random; 4 | 5 | import dust.crypto.DustUtil; 6 | import dust.crypto.DustPRNG; 7 | import dust.crypto.DustCipher; 8 | import dust.core.Util; 9 | 10 | public class TestDustCrypto 11 | { 12 | static public void main(String[] args) throws Exception 13 | { 14 | byte[] entropy=new byte[32]; 15 | Random random=new Random(); 16 | random.nextBytes(entropy); 17 | 18 | byte[] pass="test".getBytes(); 19 | byte[] pbkdf=DustUtil.pbkdf(pass, entropy); 20 | 21 | System.out.println("pbkdf: "+Util.encode(pbkdf)); 22 | 23 | byte[] data="test data".getBytes(); 24 | byte[] hash=DustUtil.hash(data); 25 | System.out.println("hash: "+Util.encode(hash)); 26 | 27 | DustPRNG prng=new DustPRNG(); 28 | byte[] rb=prng.getBytes(1); 29 | System.out.println("prng: "+Util.encode(rb)); 30 | rb=prng.getBytes(1); 31 | System.out.println("prng: "+Util.encode(rb)); 32 | rb=prng.getBytes(10); 33 | System.out.println("prng: "+Util.encode(rb)); 34 | rb=prng.getBytes(32); 35 | System.out.println("prng: "+Util.encode(rb)); 36 | 37 | // byte[] key=new byte[32]; 38 | // random.nextBytes(key); 39 | // byte[] iv=new byte[32]; 40 | // random.nextBytes(iv); 41 | byte[] key=Util.decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013"); 42 | byte[] iv=Util.decode("5475e69147a1463ef65116ccd8b3d732ead5ce8b5c9b0e61eb4c218fe6165013"); 43 | byte[] enc=DustCipher.encrypt(key, iv, data); 44 | byte[] dec=DustCipher.decrypt(key, iv, enc); 45 | System.out.println("cipher: "+new String(data)+" "+Util.encode(enc)+" "+new String(dec)); 46 | } 47 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/commands/serve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3.1 2 | import os 3 | import sys 4 | 5 | # python sucks 6 | sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))) 7 | 8 | from dust.crypto.keys import KeyManager 9 | 10 | from dust.server.router import PacketRouter 11 | from dust.crypto.keys import KeyManager 12 | from dust.core.util import getPublicIP, encodeAddress, decodeAddress, encode 13 | from dust.util.ymap import YamlMap 14 | from dust.util.safethread import wait 15 | 16 | from dust.services.tracker.trackerClient import TrackerClient 17 | 18 | inport=int(sys.argv[1]) 19 | v6=sys.argv[2] 20 | passwd=sys.argv[3] 21 | trackerAddr=decodeAddress(sys.argv[4]) 22 | 23 | host=getPublicIP(v6) 24 | 25 | keys=KeyManager() 26 | keys.setInvitePassword(passwd) 27 | 28 | try: 29 | keys.loadKeypair('config/id.yaml') 30 | except: 31 | print('Generating server keypair...') 32 | keys.createKeypair() 33 | keys.saveKeypair('config/id.yaml') 34 | 35 | keys.loadKnownHosts('config/knownhosts.yaml') 36 | keys.loadIncomingInvites('config/incoming_invites.ip') 37 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 38 | 39 | router=PacketRouter(v6, inport, keys, passwd) 40 | router.connect(trackerAddr[0], trackerAddr[1]) 41 | 42 | tracker=TrackerClient(router) 43 | 44 | router.start() 45 | 46 | keypair=keys.getKeypair() 47 | pubkey=keypair.public 48 | 49 | invite=keys.generateInvite(inport, v6=v6) 50 | tracker.putInviteForPeer(encodeAddress((host, inport)), encode(invite.message)) 51 | 52 | endpoints=YamlMap('config/endpoints.yaml') 53 | for key in endpoints.values(): 54 | tracker.putPeerForEndpoint(key, [encode(pubkey.bytes), encodeAddress((host,inport))]) 55 | 56 | wait() 57 | -------------------------------------------------------------------------------- /historical/v1/java/src/dust/crypto/SkeinPRNG.java: -------------------------------------------------------------------------------- 1 | package dust.crypto; 2 | 3 | import java.util.Random; 4 | import java.nio.ByteBuffer; 5 | 6 | import nl.warper.skein.SkeinMain; 7 | import dust.core.Util; 8 | 9 | public class SkeinPRNG 10 | { 11 | static final int SEED_SIZE=16; 12 | static final int BLOCK_SIZE_BYTES=32; 13 | static final int BLOCK_SIZE_BITS=BLOCK_SIZE_BYTES*8; 14 | 15 | Random random; 16 | byte[] seed; 17 | String pers; 18 | 19 | public SkeinPRNG() 20 | { 21 | this(null); 22 | } 23 | 24 | public SkeinPRNG(String p) 25 | { 26 | pers=p; 27 | random=new Random(); 28 | seed=generateSeed(); 29 | } 30 | 31 | public byte[] generateSeed() 32 | { 33 | byte[] rb=new byte[SEED_SIZE]; 34 | random.nextBytes(rb); 35 | return rb; 36 | } 37 | 38 | public byte[] getBytes(int n) 39 | { 40 | ByteBuffer result=ByteBuffer.allocate(n); 41 | byte[] b=null; 42 | 43 | while(result.remaining()>0) 44 | { 45 | if(pers!=null) 46 | { 47 | b=SkeinMain.fullSkein(BLOCK_SIZE_BITS, null, pers.getBytes(), null, null, null, seed, BLOCK_SIZE_BITS); 48 | } 49 | else 50 | { 51 | b=SkeinMain.fullSkein(BLOCK_SIZE_BITS, null, null, null, null, null, seed, BLOCK_SIZE_BITS); 52 | } 53 | 54 | System.arraycopy(b, 0, seed, 0, SEED_SIZE); 55 | result.put(b, SEED_SIZE, Math.min(BLOCK_SIZE_BYTES-SEED_SIZE, result.remaining())); 56 | } 57 | 58 | return result.array(); 59 | } 60 | 61 | public int getInt(int max) 62 | { 63 | byte[] b=getBytes(4); 64 | int l=Math.abs(Util.byteArrayToInt(b)); 65 | if(max!=0) 66 | { 67 | l=l%max; 68 | } 69 | 70 | return l; 71 | } 72 | } -------------------------------------------------------------------------------- /historical/v1/py/dust/services/tracker/trackbackHandler.py: -------------------------------------------------------------------------------- 1 | from dust.util.ymap import YamlMap 2 | from dust.invite.invite_packet import InviteMessage 3 | from dust.core.util import decode 4 | 5 | class TrackbackHandler: 6 | def __init__(self, keys): 7 | self.keys=keys 8 | self.state=YamlMap('config/trackback.yaml') 9 | self.callbacks={} 10 | 11 | def setPutPeerForEndpointCallback(self, key, callback): 12 | self.callbacks[key]=callback 13 | 14 | def putPeerForEndpoint(self, key, value): 15 | print('putPeerForEndpoint!!! '+str(key)+' '+str(value)) 16 | try: 17 | map=self.state['endpoints'] 18 | map[key]=value 19 | self.state.save() 20 | except: 21 | map={key: value} 22 | self.state['endpoints']=map 23 | print('callbacks: '+str(self.callbacks)) 24 | callback=self.callbacks[key] 25 | callback(key, value) 26 | 27 | def setPutInviteForPeer(self, key, callback): 28 | self.callbacks[key]=callback 29 | 30 | def putInviteForPeer(self, addr, invite): 31 | print('putInviteForPeer!!! '+str(addr)+' '+str(invite)) 32 | i=InviteMessage() 33 | i.decodeInviteMessage(decode(invite)) 34 | self.keys.outgoingInvites.addInvite(i) 35 | if self.keys.outgoingFilename: 36 | self.keys.saveOutgoingInvites(self.keys.outgoingFilename, self.keys.invitePassword) 37 | 38 | callback=self.callbacks[addr] 39 | callback(addr, i) 40 | 41 | def setPutTrackerInvite(self, callback): 42 | self.callbacks['tracker']=callback 43 | 44 | def putTrackerInvite(self, invite): 45 | print('putTrackerInvite: '+str(invite)) 46 | 47 | callback=self.callbacks['tracker'] 48 | print('callback: '+str(callback)) 49 | callback(decode(invite)) 50 | -------------------------------------------------------------------------------- /go/prim1/asym_dh.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package prim 5 | 6 | import ( 7 | "errors" 8 | 9 | "github.com/OperatorFoundation/ed25519/extra25519" 10 | "golang.org/x/crypto/curve25519" 11 | ) 12 | 13 | var ( 14 | ErrBadPrivateKey = errors.New("Dust/prim: bad private key") 15 | ErrBadPublicKey = errors.New("Dust/prim: bad public key") 16 | ) 17 | 18 | type Public struct { 19 | public [32]byte 20 | uniform [32]byte 21 | } 22 | 23 | func (public *Public) recompute() (err error) { 24 | extra25519.RepresentativeToPublicKey(&public.public, &public.uniform) 25 | return 26 | } 27 | 28 | type Private struct { 29 | Public 30 | private CValue 31 | } 32 | 33 | func (private *Private) recompute() (err error) { 34 | acceptable := extra25519.ScalarBaseMult(&private.public, &private.uniform, (*[32]byte)(&private.private)) 35 | if !acceptable { 36 | err = ErrBadPrivateKey 37 | } 38 | return 39 | } 40 | 41 | func maskPrivate(c *CValue) { 42 | c[0] &= 248 43 | c[31] &= 127 44 | c[31] |= 64 45 | } 46 | 47 | func NewPrivate() (result Private) { 48 | acceptable := false 49 | for tries := 0; !acceptable && tries < 256; { 50 | result.private = RandomCValue() 51 | maskPrivate(&result.private) 52 | acceptable = result.recompute() == nil 53 | } 54 | 55 | if !acceptable { 56 | panic("Dust/prim: too many failures generating private key") 57 | } 58 | return 59 | } 60 | 61 | func (private Private) SharedSecret(public Public) Secret { 62 | var raw CValue 63 | curve25519.ScalarMult((*[32]byte)(&raw), (*[32]byte)(&private.private), &public.public) 64 | return Secret(raw) 65 | } 66 | -------------------------------------------------------------------------------- /historical/v1/py/dust/intro/intro_packet.py: -------------------------------------------------------------------------------- 1 | from dust.core.dust_packet import DustPacket 2 | from dust.invite.invite import InvitePackage 3 | from dust.core.util import getAddress, encode 4 | from dust.crypto.curve import Key, Keypair 5 | 6 | ID_LENGTH=16 7 | PUBKEY_LENGTH=32 8 | PRIVKEY_LENGTH=32 9 | 10 | # 1 byte 11 | def makeByteLength(data): 12 | b=bytearray(1) 13 | b[0]=len(data) 14 | print('mbl#@#@#:', b) 15 | return b 16 | 17 | class IntroMessage: 18 | def __init__(self): 19 | self.keypair=None 20 | 21 | def createIntroMessage(self, pubkey): 22 | self.pubkey=pubkey 23 | publicKey=self.pubkey.bytes 24 | self.message=publicKey 25 | 26 | def decodeIntroMessage(self, message): 27 | self.message=message 28 | publicKey=self.message 29 | self.pubkey=Key(publicKey, False) 30 | 31 | class IntroPacket(DustPacket): 32 | def __init__(self): 33 | DustPacket.__init__(self) 34 | 35 | self.identifier=None 36 | self.intro=None 37 | 38 | def createIntroPacket(self, sk, id, pubkey, entropy): 39 | self.identifier=id 40 | self.intro=IntroMessage() 41 | self.intro.createIntroMessage(pubkey) 42 | 43 | self.createDustPacket(sk, self.intro.message, entropy) 44 | self.packet=self.identifier+self.packet 45 | 46 | def decodeIntroPacket(self, invites, packet): 47 | self.identifier=packet[:ID_LENGTH] 48 | packet=packet[ID_LENGTH:] 49 | invite=invites.getInviteWithId(self.identifier) 50 | if not invite: 51 | print('Unknown invite id', encode(self.identifier)) 52 | print(invites) 53 | return 54 | sk=invite.secret 55 | 56 | self.decodeDustPacket(sk, packet) 57 | self.intro=IntroMessage() 58 | self.intro.decodeIntroMessage(self.data) 59 | -------------------------------------------------------------------------------- /go/proc/request_reply.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package proc 5 | 6 | // PutRequest sends req to the controlled process's request channel. It returns true if the request was 7 | // delivered to the channel, or false if the process exited before it could be delivered. 8 | func (ctl *Ctl) PutRequest(req interface{}) bool { 9 | select { 10 | case _ = <-ctl.Exit: 11 | return false 12 | case ctl.req <- req: 13 | return true 14 | } 15 | } 16 | 17 | // GetReply receives a reply from the controlled process's reply channel. It returns the reply, and true 18 | // if a reply was available, or false if the process exited or closed its reply channel. 19 | func (ctl *Ctl) GetReply() (interface{}, bool) { 20 | select { 21 | case _ = <-ctl.Exit: 22 | return nil, false 23 | case rep, any := <-ctl.Rep: 24 | return rep, any 25 | } 26 | } 27 | 28 | // GetRequest receives a request for this process. It returns the request, and true if a request was 29 | // available, or false if the request channel was closed. If a cancellation request is pending for this 30 | // process, the process exits instead and GetRequest never returns. 31 | func (env *Env) GetRequest() (interface{}, bool) { 32 | select { 33 | case _ = <-env.Cancel: 34 | env.ExitCanceled() 35 | return nil, false 36 | case req, any := <-env.Req: 37 | return req, any 38 | } 39 | } 40 | 41 | // PutReply sends a reply from this process. If a cancellation request is pending for this process, 42 | // the process exits instead and PutReply never returns. 43 | func (env *Env) PutReply(rep interface{}) { 44 | select { 45 | case _ = <-env.Cancel: 46 | env.ExitCanceled() 47 | case env.rep <- rep: 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /historical/v1/py/dust/test/file-fetch.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dust.services.file.file_socket import file_socket 4 | from dust.crypto.keys import KeyManager 5 | from dust.services.file.fileService import FileHandler 6 | 7 | host = '2002:ae94:84fa:4:250:8dff:fe5f:6e33' 8 | inport=7001 9 | outport=7000 10 | passwd='test' 11 | 12 | keys=KeyManager() 13 | keys.setInvitePassword(passwd) 14 | keys.loadKeypair('config/id.yaml') 15 | keys.loadKnownHosts('config/knownhosts.yaml') 16 | keys.loadIncomingInvites('config/incoming_invites.ip') 17 | keys.loadOutgoingInvites('config/outgoing_invites.ip') 18 | 19 | fsock=file_socket(keys) 20 | fsock.bind((host, inport)) 21 | fsock.connect((host, outport)) 22 | 23 | headers={'command': 'getMeta', 'file': 'test.txt'} 24 | fsock.fsend(headers, None) 25 | headers, data, addr=fsock.frecvfrom() 26 | command=headers['command'] 27 | 28 | if command=='putMeta': 29 | l=headers['length'] 30 | else: 31 | print('Expecting putMeta, got', command) 32 | 33 | print('downloading', l, 'bytes') 34 | 35 | file='test.txt' 36 | f=open('incoming/'+file, 'wb') 37 | written=0 38 | while written>48), uint16(n>>32), uint16(n>>16), uint16(n) 44 | if w == 0 && x == 0 { 45 | return fmt.Sprintf("%x.%x", y, z) 46 | } else { 47 | return fmt.Sprintf("%x.%x.%x.%x", w, x, y, z) 48 | } 49 | } 50 | 51 | const ( 52 | linkNetwork = "Dust_link" 53 | ) 54 | 55 | type LinkAddr addrToken 56 | 57 | func (addr LinkAddr) Network() string { 58 | return linkNetwork 59 | } 60 | 61 | func (addr LinkAddr) String() string { 62 | return fmt.Sprintf("%s:%s", linkNetwork, addrToken(addr).String()) 63 | } 64 | 65 | func (addr LinkAddr) IsZero() bool { 66 | return addrToken(addr).ptr == nil 67 | } 68 | 69 | func LinkAddrEqual(a, b LinkAddr) bool { 70 | return a.ptr == b.ptr 71 | } 72 | 73 | func genLinkAddr() LinkAddr { 74 | return LinkAddr(nextAddrToken()) 75 | } 76 | -------------------------------------------------------------------------------- /modelgen/lib/jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise" : true, 3 | "curly" : true, 4 | "eqeqeq" : true, 5 | "forin" : true, 6 | "immed" : true, 7 | "latedef" : true, 8 | "newcap" : true, 9 | "noarg" : true, 10 | "noempty" : true, 11 | "nonew" : true, 12 | "plusplus" : false, 13 | "regexp" : true, 14 | "undef" : true, 15 | "strict" : true, 16 | "trailing" : true, 17 | 18 | "asi" : false, 19 | "boss" : false, 20 | "debug" : false, 21 | "eqnull" : false, 22 | "es5" : false, 23 | "esnext" : false, 24 | "evil" : false, 25 | "expr" : false, 26 | "funcscope" : false, 27 | "globalstrict" : false, 28 | "iterator" : false, 29 | "lastsemic" : false, 30 | "laxbreak" : false, 31 | "laxcomma" : false, 32 | "loopfunc" : false, 33 | "multistr" : false, 34 | "onecase" : false, 35 | "proto" : false, 36 | "regexdash" : false, 37 | "scripturl" : false, 38 | "smarttabs" : false, 39 | "shadow" : false, 40 | "sub" : false, 41 | "supernew" : false, 42 | "validthis" : false, 43 | 44 | "browser" : true, 45 | "couch" : false, 46 | "devel" : false, 47 | "dojo" : false, 48 | "jquery" : false, 49 | "mootools" : false, 50 | "node" : false, 51 | "nonstandard" : false, 52 | "prototypejs" : false, 53 | "rhino" : false, 54 | "wsh" : false, 55 | 56 | "maxerr" : 100, 57 | "predef" : [ 58 | ], 59 | "indent" : 2 60 | } 61 | -------------------------------------------------------------------------------- /historical/v1/py/dust/extensions/multiplex/multiplex_socket.py: -------------------------------------------------------------------------------- 1 | from dust.extensions.multiplex.multiplex_packet import MultiplexMessage 2 | from dust.core.dust_socket import dust_socket 3 | 4 | class multiplex_socket(dust_socket): 5 | def __init__(self, keys): 6 | dust_socket.__init__(self, keys) 7 | 8 | self.connectService=None 9 | 10 | def connectToService(self, serviceName): 11 | self.connectService=serviceName 12 | 13 | def msend(self, data, service=None): 14 | if not service: 15 | service=self.connectService 16 | multiplex=MultiplexMessage() 17 | multiplex.createMultiplexMessage(service, data) 18 | dust_socket.send(self, multiplex.message) 19 | 20 | def msendto(self, data, addr, service=None): 21 | if not service: 22 | service=self.connectService 23 | multiplex=MultiplexMessage() 24 | multiplex.createMultiplexMessage(service, data) 25 | dust_socket.sendto(self, multiplex.message, addr) 26 | 27 | def mrecv(self, bufsize, service=None): 28 | if not service: 29 | service=self.connectService 30 | data=dust_socket.recv(self, bufsize) 31 | if not data: 32 | return None 33 | multiplex=MultiplexMessage() 34 | multiplex.decodeMultiplexMessage(data) 35 | if service and multiplex.serviceName!=service: 36 | print('Bad multiplex service name', multiplex.serviceName, 'should be ', self.connectService) 37 | return None 38 | return multiplex.data 39 | 40 | def mrecvfrom(self, bufsize, service=None): 41 | if not service: 42 | service=self.connectService 43 | data, addr=dust_socket.recvfrom(self, bufsize) 44 | if not data: 45 | print('Multiplex: No data') 46 | return None, None, None 47 | multiplex=MultiplexMessage() 48 | multiplex.decodeMultiplexMessage(data) 49 | return multiplex.data, addr, multiplex.serviceName 50 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/file/file_packet.py: -------------------------------------------------------------------------------- 1 | import json 2 | import time 3 | import struct 4 | import random 5 | 6 | from dust.core.dust_packet import makeLength 7 | from dust.core.util import encode 8 | from dust.extensions.multiplex.multiplex_packet import MultiplexPacket 9 | 10 | class FileMessage: 11 | def __init__(self): 12 | self.headersLength=None 13 | self.headersLengthValue=None 14 | self.headers=None 15 | self.data=None 16 | self.message=None 17 | 18 | def createFileMessage(self, headers, data): 19 | self.headers=json.dumps(headers).encode('ascii') 20 | self.headersLengthValue=len(self.headers) 21 | self.headersLength=makeLength(self.headersLengthValue, 4) 22 | self.data=data 23 | if self.data: 24 | self.message=self.headersLength+self.headers+self.data 25 | else: 26 | self.message=self.headersLength+self.headers 27 | 28 | def decodeFileMessage(self, message): 29 | self.message=message 30 | self.headersLength=self.message[:4] 31 | self.headersLengthValue=struct.unpack("I", self.headersLength)[0] 32 | self.headers=json.loads(self.message[4:self.headersLengthValue+4].decode('ascii')) 33 | if self.headersLengthValue+4==len(self.message): 34 | self.data=None 35 | else: 36 | self.data=self.message[self.headersLengthValue+4:] 37 | 38 | class FilePacket(MultiplexPacket): 39 | def __init__(self): 40 | MultiplexPacket.__init__(self) 41 | 42 | self.file=None 43 | 44 | def createFilePacket(self, sk, headers, data): 45 | self.file=FileMessage() 46 | self.file.createFileMessage(headers, data) 47 | self.createMultiplexPacket(sk, 'file', self.file.message) 48 | 49 | def decodeMultiplexPacket(self, sk, packet): 50 | self.decodeMultiplexPacket(sk, packet) 51 | self.file=FileMessage() 52 | self.file.decodeFileMessage(self.multiplex.data) 53 | -------------------------------------------------------------------------------- /historical/v1/py/dust/crypto/dustUtil.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import random 3 | import struct 4 | 5 | import dust.crypto.skeinUtil as skeinUtil 6 | from dust.core.util import encode 7 | 8 | v3=(sys.version[0]=='3') 9 | 10 | SEED_SIZE=16 11 | IV_SIZE=16 12 | BLOCK_SIZE=32 13 | 14 | PBKDF_ITERATIONS=13000 15 | 16 | if v3: 17 | MAC_PERS=bytes('1978-10-26 dust@blanu.net Dust/MAC', 'ascii') 18 | PRNG_PERS=bytes('1978-10-26 dust@blanu.net Dust/PRNG', 'ascii') 19 | HASH_PERS=bytes('1978-10-26 dust@blanu.net Dust/hash', 'ascii') 20 | PBKDF_PERS=bytes('1978-10-26 dust@blanu.net Dust/PBKDF', 'ascii') 21 | CIPHER_PERS=bytes('1978-10-26 dust@blanu.net Dust/cipher', 'ascii') 22 | else: 23 | MAC_PERS='1978-10-26 dust@blanu.net Dust/MAC' 24 | PRNG_PERS='1978-10-26 dust@blanu.net Dust/PRNG' 25 | HASH_PERS='1978-10-26 dust@blanu.net Dust/hash' 26 | PBKDF_PERS='1978-10-26 dust@blanu.net Dust/PBKDF' 27 | CIPHER_PERS='1978-10-26 dust@blanu.net Dust/cipher' 28 | 29 | def hash(data): 30 | return skeinUtil.hash(data, digest_bits=256, pers=HASH_PERS) 31 | 32 | def mac(key, data): 33 | return skeinUtil.hash(data, digest_bits=256, mac=key, pers=MAC_PERS) 34 | 35 | def pbkdf(pb, salt): 36 | return skeinUtil.pbkdf(pb, salt, PBKDF_ITERATIONS, pers=PBKDF_PERS) 37 | 38 | class DustPRNG(skeinUtil.SkeinPRNG): 39 | def __init__(self): 40 | skeinUtil.SkeinPRNG.__init__(self, pers=PRNG_PERS) 41 | 42 | def encrypt(k, iv, data): 43 | cipher=DustCipher(k, iv) 44 | return cipher.encrypt(data) 45 | 46 | def decrypt(k, iv, data): 47 | cipher=DustCipher(k, iv) 48 | return cipher.decrypt(data) 49 | 50 | class DustCipher(skeinUtil.SkeinCipherOFB): 51 | def __init__(self, key, iv): 52 | if type(key)!=str: 53 | key=key.bytes 54 | skeinUtil.SkeinCipherOFB.__init__(self, key, iv, pers=CIPHER_PERS) 55 | 56 | def __str__(self): 57 | return 'DustCipher('+encode(self.key)+','+encode(self.iv)+','+str(self.count)+')' 58 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/socks3/dustSocksServer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | from struct import unpack 5 | from socket import inet_ntoa 6 | 7 | import monocle 8 | from monocle import _o, Return 9 | monocle.init('tornado') 10 | 11 | from monocle.stack import eventloop 12 | from monocle.stack.network import add_service, Service, Client, ConnectionLost 13 | from loopback import FakeSocket 14 | 15 | from dust.core.dust_packet import IV_SIZE, KEY_SIZE 16 | 17 | from dust.extensions.lite.lite_socket2 import makeEphemeralSession, createEphemeralKeypair 18 | 19 | from shared import * 20 | from socks import * 21 | 22 | @_o 23 | def handle_dust(conn): 24 | print('handle_dust') 25 | coder=yield handshake(conn) 26 | 27 | buffer=FakeSocket() 28 | 29 | monocle.launch(pump, conn, buffer, coder.decrypt) 30 | monocle.launch(handle_socks, buffer.invert()) 31 | yield pump(buffer, conn, coder.encrypt, True) 32 | 33 | print('done handling dust') 34 | 35 | @_o 36 | def handshake(conn): 37 | ekeypair=createEphemeralKeypair() 38 | 39 | yield conn.write(ekeypair.public.bytes) 40 | epub=yield conn.read(KEY_SIZE) 41 | 42 | esession=makeEphemeralSession(ekeypair, epub) 43 | 44 | coder=lite_socket(esession) 45 | 46 | yield Return(coder) 47 | 48 | @_o 49 | def handle_socks(conn): 50 | print('handle_socks') 51 | yield readHandshake(conn) 52 | print('read handshake') 53 | yield sendHandshake(conn) 54 | print('send handshake') 55 | dest=yield readRequest(conn) 56 | print('read request: '+str(dest)) 57 | yield sendResponse(dest, conn) 58 | print('sent response') 59 | 60 | addr, port=uncompact(dest) 61 | print(addr) 62 | print(port) 63 | 64 | client = Client() 65 | yield client.connect(addr, port) 66 | print('connected '+str(addr)+', '+str(port)) 67 | monocle.launch(pump, conn, client, None) 68 | yield pump(client, conn, None) 69 | 70 | add_service(Service(handle_dust, port=7051)) 71 | eventloop.run() 72 | -------------------------------------------------------------------------------- /go/v2/shaping/codec.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | /* 5 | Package shaping implements the shaping layer of the Dust protocol suite. 6 | */ 7 | package shaping 8 | 9 | import ( 10 | "time" 11 | ) 12 | 13 | // Encoder applies to the sending side of a Dust half-connection. It outputs timing and length parameters for 14 | // outgoing packets, as well as stateful shaping of the byte stream. 15 | type Encoder interface { 16 | // MaxPacketLength returns any uint16 greater than or equal to any length that will ever be returned 17 | // by NextPacketLength from this encoder. 18 | MaxPacketLength() uint16 19 | 20 | // NextPacketLength returns the length of the next packet that should be sent. It and NextPacketSleep 21 | // may be called in either order. 22 | NextPacketLength() uint16 23 | 24 | // NextPacketSleep returns a duration to wait before sending the next packet. It and NextPacketLength 25 | // may be called in either order. 26 | NextPacketSleep() time.Duration 27 | 28 | // ShapeBytes continues transforming a uniform byte stream into a shaped byte stream. Upon return, it 29 | // has consumed sn bytes of src and overwritten dn bytes of dst, and len(src) == sn or len(dst) == dn. 30 | ShapeBytes(dst, src []byte) (dn, sn int) 31 | } 32 | 33 | // Decoder applies to the receiving side of a Dust half-connection. Incoming "soft" characteristics such as 34 | // timing and length are discarded, but the decoder still provides the stateful inverse of the content shaping 35 | // for the byte stream. 36 | type Decoder interface { 37 | // UnshapeBytes continues transforming a shaped byte stream into an expected-to-be-uniform byte stream. 38 | // Upon return, it has consumed sn bytes of src and overwritten dn bytes of dst, and len(src) == sn or 39 | // len(dst) == dn. 40 | UnshapeBytes(dst, src []byte) (dn, sn int) 41 | } 42 | -------------------------------------------------------------------------------- /historical/v1/py/dust/services/tracker/trackerHandler.py: -------------------------------------------------------------------------------- 1 | from dust.util.ymap import YamlMap 2 | from dust.core.util import encode 3 | from dust.services.tracker.trackbackClient import TrackbackClient 4 | 5 | class TrackerHandler: 6 | def __init__(self, router, addr): 7 | print('new TrackerHandler '+str(addr)) 8 | self.router=router 9 | self.addr=addr 10 | self.state=YamlMap('config/tracker.yaml') 11 | 12 | def getPeerForEndpoint(self, key): 13 | print('getPeerForEndpoint('+str(key)+')') 14 | try: 15 | map=self.state['endpoints'] 16 | value=map[key] 17 | trackback=TrackbackClient(self.router, self.addr) 18 | trackback.putPeerForEndpoint(key, value) 19 | except Exception as e: 20 | print('exception: '+str(e)) 21 | pass 22 | 23 | def putPeerForEndpoint(self, key, value): 24 | print('putPeerForEndpoint('+str(key)+','+str(value)+')') 25 | try: 26 | map=self.state['endpoints'] 27 | map[key]=value 28 | self.state.save() 29 | except Exception as e: 30 | map={key: value} 31 | self.state['endpoints']=map 32 | 33 | def getInviteForPeer(self, key): 34 | print('getInviteForPeer('+str(key)+')') 35 | try: 36 | map=self.state['invites'] 37 | value=map[key] 38 | trackback=TrackbackClient(self.router, self.addr) 39 | trackback.putInviteForPeer(key, value) 40 | except Exception as e: 41 | print('exception: '+str(e)) 42 | pass 43 | 44 | def putInviteForPeer(self, key, value): 45 | print('putInviteForPeer('+str(key)+','+str(value)+')') 46 | try: 47 | map=self.state['invites'] 48 | map[key]=value 49 | self.state.save() 50 | except Exception as e: 51 | map={key: value} 52 | self.state['invites']=map 53 | 54 | def getTrackerInvite(self): 55 | invite=self.router.generateInvite() 56 | trackback=TrackbackClient(self.router, self.addr) 57 | trackback.putTrackerInvite(encode(invite.message)) 58 | -------------------------------------------------------------------------------- /historical/haskell2014/Dust/Dust/Network/DustServer.hs: -------------------------------------------------------------------------------- 1 | module Dust.Network.DustServer 2 | ( 3 | dustServer 4 | ) 5 | where 6 | 7 | import Data.ByteString.Lazy (ByteString) 8 | import Data.ByteString.Char8 (pack, unpack) 9 | import System.IO.Error (tryIOError) 10 | import Data.Binary.Get (runGetState) 11 | import Data.Binary.Put (runPut) 12 | import qualified Data.ByteString as B 13 | import qualified Data.ByteString.Lazy as BL 14 | import Network.Socket 15 | 16 | import Dust.Crypto.Keys 17 | import Dust.Crypto.ECDH 18 | import Dust.Core.WireProtocolHandler 19 | import Dust.Network.TcpServer 20 | import Dust.Crypto.Cipher 21 | import Dust.Model.TrafficModel 22 | import Dust.Network.ProtocolSocket 23 | import Dust.Core.CryptoProtocol 24 | import Dust.Crypto.PRNG 25 | import Dust.Crypto.Cipher 26 | 27 | dustServer :: TrafficGenerator -> (Plaintext -> IO(Plaintext)) -> IO() 28 | dustServer gen proxyAction = do 29 | putStrLn "Loading keys..." 30 | (keypair, newKeys) <- ensureKeys "." createKeypair 31 | 32 | if newKeys 33 | then putStrLn "Generating new keys..." 34 | else putStrLn "Loaded keys." 35 | 36 | let host = "0.0.0.0" 37 | let port = 6885 38 | 39 | rand <- newPRNG 40 | let (iv, rand') = createIV rand 41 | 42 | server host port (reencode keypair iv gen proxyAction) 43 | 44 | reencode :: Keypair -> IV -> TrafficGenerator -> (Plaintext -> IO(Plaintext)) -> Socket -> IO() 45 | reencode keypair iv gen proxyAction sock = do 46 | (session, rest) <- getSession B.empty keypair sock 47 | let (Session _ otherPublic _ _) = session 48 | (plaintext, rest') <- getPacket rest session sock 49 | 50 | putStrLn $ "Request:" ++ (show plaintext) 51 | 52 | result <- proxyAction plaintext 53 | let Plaintext resultBytes = result 54 | 55 | putStrLn $ "Response:" ++ (show (B.length resultBytes)) 56 | 57 | let otherSession = makeSession keypair otherPublic iv 58 | encode otherSession result sock 59 | 60 | return () 61 | -------------------------------------------------------------------------------- /historical/v1/py/docs/howto.txt: -------------------------------------------------------------------------------- 1 | What do I need to run this? 2 | 3 | Python3.0 (required for PySkein) 4 | PySkein 0.6 (skein bindings for python) 5 | PyYAML (YAML implementation for python) 6 | python-bitstring (make sure to get the Python 3.x version) 7 | curve25519 module (included for athlon and Win32, you'll need to recompile otherwise) 8 | 9 | How do I run a proxy? 10 | 11 | Generate your keypair: commands/gen.py 12 | Generate some invites: commands/make-invite.py password 13 | 14 | Send out invites (out of band) 15 | 16 | Configure server/services.py to enable desired services (for example, the mail relay) 17 | Edit config/emailServer.py or other relevant config files to configure enabled services 18 | Run commands/serve.py port 6/4 password, example: commands/serve.py 8000 6 testpassword 19 | 20 | How do I use the network to proxy information? 21 | 22 | Generate your keypair: commands/gen.py 23 | Obtain an invite 24 | Obtain the password for the invite 25 | Merge the invite file into your personal invite database: commands/process-invite.py invitePassword passwordForYourInviteDb 26 | 27 | Send a mail message: test/intro-mmail-send.py inport outport 6/4 password (it will prompt for headers and email body) 28 | Example: test/intro-mmail-send.py 7001 8000 6 testpassword 29 | 30 | How do I use Dust Lite services? 31 | 32 | Dust Lite works just like normal Dust, only there is no need to use invites. Consequently, it lacks the security of normal Dust. 33 | 34 | To run a Dust Lite server, run commands/lite-serv.py port 6/4 35 | To send mail with a Dust Lite server, run command/lite-mmail-send.py inport outport 6/4 36 | 37 | What Dust services are available? 38 | 39 | By default, mail and chat are included. The mail service acts as a proxy which let's you send normal mail messages to a list of allowed destination hosts. 40 | Chat is a simple service for debugging which prints received messages on the server's console. 41 | New services can be added easily by editting server/services.py. 42 | -------------------------------------------------------------------------------- /historical/v1/py/dust/core/dust_packet2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import struct 4 | 5 | from dust.crypto.dustUtil import encrypt, decrypt, mac 6 | from dust.core.util import splitField, splitFields, encode 7 | 8 | v3=(sys.version[0]=='3') 9 | 10 | IV_SIZE = 16 11 | KEY_SIZE = 32 12 | 13 | # 16 bytes 14 | def makeIV(entropy): 15 | return entropy.getBytes(IV_SIZE) 16 | 17 | class DustPacket: 18 | def __init__(self): 19 | self.key=None 20 | 21 | self.ciphertext=None 22 | self.iv=None 23 | self.encrypted=None 24 | self.payload=None 25 | 26 | self.data=None 27 | 28 | self.packet=None 29 | 30 | self.remaining=None 31 | 32 | def __str__(self): 33 | s="[\n" 34 | 35 | if self.key: 36 | s=s+" key: "+encode(self.key)+"\n" 37 | else: 38 | s=s+" key: None\n" 39 | 40 | s=s+' IV: '+encode(self.iv)+"\n" 41 | 42 | s=s+" payload: "+encode(self.payload)+"\n" 43 | 44 | s=s+' dataLength: '+str(self.dataLength)+"\n" 45 | s=s+' data: '+str(encode(self.data))+"\n" 46 | if self.remaining: 47 | s=s+' remaining: '+encode(self.remaining)+"\n" 48 | else: 49 | s=s+" remaining: None\n" 50 | s=s+"]\n" 51 | return s 52 | 53 | def createDustPacket(self, key, data, entropy): 54 | self.key=key 55 | if v3 and type(data)!=bytes: 56 | self.data=bytes(data, 'ascii') 57 | else: 58 | self.data=data 59 | 60 | payloadLength=len(self.data) 61 | 62 | self.dataLength=len(self.data) 63 | self.payload=self.data 64 | 65 | self.encrypted=encrypt(self.key, self.iv, self.payload) 66 | 67 | self.ciphertext=self.encrypted 68 | 69 | self.packet=self.ciphertext 70 | 71 | def decodeDustPacket(self, key, packet): 72 | self.key=key 73 | self.packet=packet 74 | 75 | self.ciphertext=self.payload 76 | self.encrypted=self.ciphertext 77 | self.payload=decrypt(self.key, self.iv, self.encrypted) 78 | 79 | self.data=self.payload 80 | 81 | self.ciphertext=self.data 82 | 83 | -------------------------------------------------------------------------------- /go/v2/interface/mode_rawstream.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../../LICENSE.md. 3 | 4 | package Dust 5 | 6 | import ( 7 | "errors" 8 | "net" 9 | "time" 10 | ) 11 | 12 | var ( 13 | // TODO: support deadlines, of course. 14 | ErrDeadlineNotSupported = errors.New("Dust: I/O deadline not supported") 15 | ) 16 | 17 | type RawStreamConn struct { 18 | connection 19 | } 20 | 21 | var _ net.Conn = (*RawStreamConn)(nil) 22 | 23 | func (rconn *RawStreamConn) LocalAddr() net.Addr { 24 | return &rconn.local 25 | } 26 | 27 | func (rconn *RawStreamConn) RemoteAddr() net.Addr { 28 | return &rconn.remote 29 | } 30 | 31 | func (rconn *RawStreamConn) Read(p []byte) (n int, err error) { 32 | return rconn.crypter.Front.Read(p) 33 | } 34 | 35 | func (rconn *RawStreamConn) Write(p []byte) (n int, err error) { 36 | return rconn.crypter.Front.Write(p) 37 | } 38 | 39 | func (rconn *RawStreamConn) Close() error { 40 | return rconn.connection.Close() 41 | } 42 | 43 | func (rconn *RawStreamConn) SetDeadline(t time.Time) error { 44 | return rconn.crypter.Front.SetDeadline(t) 45 | } 46 | 47 | func (rconn *RawStreamConn) SetReadDeadline(t time.Time) error { 48 | return rconn.crypter.Front.SetReadDeadline(t) 49 | } 50 | 51 | func (rconn *RawStreamConn) SetWriteDeadline(t time.Time) error { 52 | return rconn.crypter.Front.SetWriteDeadline(t) 53 | } 54 | 55 | func BeginRawStreamClient(socket Socket, spub *ServerPublic) (rconn *RawStreamConn, err error) { 56 | rconn = &RawStreamConn{} 57 | if err = rconn.initClient(spub); err != nil { 58 | return 59 | } 60 | if err = rconn.spawn(socket); err != nil { 61 | return 62 | } 63 | return 64 | } 65 | 66 | func BeginRawStreamServer(socket Socket, spriv *ServerPrivate) (rconn *RawStreamConn, err error) { 67 | rconn = &RawStreamConn{} 68 | if err = rconn.initServer(spriv); err != nil { 69 | return 70 | } 71 | if err = rconn.spawn(socket); err != nil { 72 | return 73 | } 74 | return 75 | } 76 | -------------------------------------------------------------------------------- /go/prim1/ntor.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2015 Drake Wilson. Copying, distribution, and modification of this software is governed by 2 | // the MIT-style license in the file ../LICENSE.md. 3 | 4 | package prim 5 | 6 | import ( 7 | "bytes" 8 | 9 | "github.com/blanu/Dust/go/skein" 10 | ) 11 | 12 | const ( 13 | personNtorH = personPrefix + "ntor-H.skein" 14 | personNtorHmac = personPrefix + "ntor-Hmac.skein" 15 | 16 | ntorSquawk = `ntor(Dust2015)` 17 | ntorServer = `server` 18 | ntorClient = `client` 19 | ) 20 | 21 | type NtorHandshake struct { 22 | h skein.Hash 23 | 24 | x, y []byte 25 | bHat []byte 26 | } 27 | 28 | func makeInitial(osize uint64, args *skein.Args) (out skein.Initial) { 29 | out.Init(osize, args) 30 | return 31 | } 32 | 33 | var ( 34 | ntorInitialH = makeInitial(CValueLen + SecretLen, &skein.Args{Person: []byte(personNtorH)}) 35 | ntorInitialHmac = makeInitial(AuthLen, &skein.Args{Person: []byte(personNtorHmac)}) 36 | ) 37 | 38 | func (ntor *NtorHandshake) Init(bHat []byte, x, y *Public) { 39 | ntor.h.InitFrom(&ntorInitialH) 40 | ntor.x = x.Binary() 41 | ntor.y = y.Binary() 42 | ntor.bHat = bHat 43 | } 44 | 45 | func (ntor *NtorHandshake) WriteDHPart(secret Secret) { 46 | ntor.h.Write(secret[:]) 47 | } 48 | 49 | func (ntor *NtorHandshake) Finish(inTail, outTail string) (shared Secret, tIn, tOut AuthValue) { 50 | // The DH parts have already been written into ntor.h. 51 | hTail := bytes.Join([][]byte{ntor.bHat, ntor.x, ntor.y, []byte(ntorSquawk)}, nil) 52 | ntor.h.Write(hTail) 53 | 54 | var confSeed CValue 55 | _, _ = ntor.h.Read(confSeed[:]) 56 | _, _ = ntor.h.Read(shared[:]) 57 | 58 | hMacMedial := bytes.Join([][]byte{ntor.bHat, ntor.y, ntor.x, []byte(ntorSquawk)}, nil) 59 | var hMac skein.Hash 60 | hMac.InitFrom(&ntorInitialHmac) 61 | hMac.Write(confSeed[:]) 62 | hMac.Write(hMacMedial) 63 | 64 | hMacIn := hMac.Copy() 65 | hMacIn.Write([]byte(inTail)) 66 | _, _ = hMacIn.Read(tIn[:]) 67 | hMacOut := hMac.Copy() 68 | hMacOut.Write([]byte(outTail)) 69 | _, _ = hMacOut.Read(tOut[:]) 70 | 71 | return 72 | } 73 | 74 | --------------------------------------------------------------------------------