Deriving Curve22519 public keys from a secret key with enacl

djb’s nacl is a secure, fast and easy to use crypto library. libsodium is a more packageable fork of it. The enacl project provides Erlang bindings for the basic API functions of the latter one, however, it does not cover libsodium’s crypto_scalarmult_base() function to derive the adequate public key from a Curve22519 secret key.

I may at some point work on a pull request to include this functionality in enacl. I however found a decent workaround: one could use the offered enacl:curve25519_scalarmult(Secret, BasePoint) function. While the Secret variable refers to the secret key, the BasePoint was rather unclear at first. However, after some digging in the code and online I discovered that this is a case

where the constant basepoint is 9 followed by all zeros:

const unsigned char basepoint[32] = {9};

This means that deriving a public key can be done with enacl this way:

#{secret := Secret} = enacl:box_keypair().
Filler = binary:copy(<<0:8>>, 31).
BasePoint = <<9:8, Filler/binary>>.
Public = enacl:curve25519_scalarmult(Secret, BasePoint).
- published on

Mocking IPv6 Addresses With Erlang

I started programming Erlang some time ago. It is a great language and to dive into functional programming is somewhat mindbending. I will from time post some code snippets here in order to remember them myself and as help for others.

In this case I’m building an Erlang module that will handle tuples { Address, Port } of ip addresses and ports of remote peers. While writing unit tests for it, I realized I wanted to mock some random generated addresses. Here is the code:

random_peer() ->
    AllowedChars = [$1,$2,$3,$4,$5,$6,$7,$8,$9,$a,$b,$c,$d,$e,$f],
    Random_char = fun() -> 
      lists:nth(rand:uniform(length(AllowedChars)), AllowedChars) end,
    Random_block = fun() -> 
      lists:map(fun(_) -> Random_char() end, lists:seq(1,4)) end,
    List = lists:join($:, lists:map(fun(_) -> 
      Random_block() end, lists:seq(1,8))),
    AddressString = lists:flatten(List),
    Address = inet:parse_ipv6_address(AddressString),
    Port = rand:uniform(65535),
    {Address, Port}. 

The function does not exclude reserved address spaces and so on, it does however create a string which is accepted by inet:parse_ipv6_address/1. This should be enough to use the mocked-up addresses for testing with EUnit.

- published on

↦ Forward Secrecy in BitTorrent Bleep

Over at the BitTorrent Engineering Blog they posted an article about how authentication works in Bleep. They explain Bleep supports Forward Secrecy, so no old messages can be decrypted by an attacker, even if the private key gets stolen. This is a nice thing to have, but given they recently announced that Bleep will also support offline messaging, it will be interesting to see how they handle this together.

Forward Secrecy relies on temporarily used keys which get discarded after use or regularly. The key negotiation can only happen while both parties are online, so keeping Forward Secrecy while introducing offline messages is normally a challenge. Over at OpenWhisperSystems they handled this problem for the TextSecure app by generating 100 key exchange messages and storing them on the centralized server:

At registration time, the TextSecure client preemptively generates 100 signed key exchange messages and sends them to the server. We call these “prekeys.” A client that wishes to send a secure message to a user for the first time can now:

  1. Connect to the server and request the destination’s next “prekey.”
  2. Generate its own key exchange message half.
  3. Calculate a shared secret with the prekey it received and its own key exchange half.
  4. Use the shared secret to encrypt the message.
  5. Package up the prekey id, the locally generated key exchange message, and the ciphertext.
  6. Send it all in one bundle to the destination client.

The user experience for the sender is ideal: they type a message, hit send, and an encrypted message is immediately sent.

I think this is a solid workaround.

- published on

↦ 'Project Maelstrom' aims to make the Web distributed

BitTorrent wants to make the Web distributed. They announced they’ve been working on a Browser (and included server it seems) which is based on a distributed Peer-to-Peer architecture:

Project Maelstrom begins to answer that question with our first public release of a web browser that can power a new way for web content to be published, accessed and consumed. Truly an Internet powered by people, one that lowers barriers and denies gatekeepers their grip on our future.

This is a great idea! Let’s hope they make this an open platform to build on, and open source so everyone can check what’s going on in the internals!

They are looking for participants in ‘Project Maelstrom’, so if you are interested to have a look at it as an alpha tester, developer, researcher, agency, publisher or artist, sign up for their mailing list.

- published on

↦ Collision on 32bit PGP key ids

Research shows that it takes only 4 seconds to create PGP keys with colliding 32bit key ids. This is presented on evil32.com:

Stop using 32bit key ids

It takes 4 seconds to generate a colliding 32bit key id on a GPU (using scallion). Key servers do little verification of uploaded keys and allow keys with colliding 32bit ids. Further, GPG uses 32bit key ids throughout its interface and does not warn you when an operation might apply to multiple keys.

With this it is relatively easy to fool a target into importing the wrong PGP key and therefore gain his/her trust.

Solution: using the Web of Trust circumvents this. Also, checking fingerprints ensures you got the right key. But still, this seems like one more nail in the coffin of PGP: As its usability and distribution is getting worse and worse, everyone waits for a new solution to replace PGP once and for all. To quote Matt Green:

It’s time for PGP to die.

- published on

older Posts: