Update 09 December, 2021

We hate to disappoint, but unfortuntely the cusp turned out to be slightly less cuspy than anticipated, so any testnet is still a some days away. We’ll let you know as soon as it’s ready – it really could be any day now, but we won’t tempt fate by predicting.

Last week David Rusu gave a demo of ring confidential transactions (Ring CT) to the team. It was fascinating stuff, but pretty heavy on the maths, so this week we’ve got a stripped down version with the bare minimum of algebra in an attempt to give a bit of backgound and explain the direction we’re taking with private DBC transactions.

General progress

David Rusu, @danda and @Anselme have all been getting stuck into various aspects of ring signature implementation including proofs of payment.

@ChrisO has been struggling manfully with GitHub Actions to try to get the testnet release-worthy, but it hasn’t been playing ball over the last couple of days.

@bochaco has been working alongside @chrisO aiming to tighten up the remaining failing CLI tests, and we’ve been squashing ever more edge cases around section splits

The entire team has been looking at membership DKG – what’s the most efficient way to ensure Elders can keep track of the adults in their sections, and how can we protect against key-selling attacks, where an adversary successfully buys control of a section?

Ring signatures and Safe

We want to spend a DBC. To do this we must prove we’re the owner. But to increase privacy of our DBC transactions we don’t want the mint to know precisely who we are - which it would if we were to use a standard key. Furthermore, the mint also needs to know this DBC has not already been spent.

To achieve these aims we’re looking to use ring signatures, building on the Ring CT work done by Monero, and adding a Safe twist of multi sig and proof-of-payment.

What is a ring signature?

Ring signatures are a probabilistic security method rather than a cryptographically hard one, but as Monero has demonstrated, still a very effective one for anonymising transactions.

A ring signature is a way of hiding a public key (such as our DBC owner key) among many other decoy keys. A ring is just a word for a group, so on Safe our key is in the ring with a bunch of decoys chosen randomly from a pool of keys the mint knows about.

A signature made by any key in the ring is valid, but the mint can’t tell which key in the ring actually signed a transaction, only that one of them did. The larger the pool of decoy keys the harder it will be for an observer of the system to guess the actual key that signed a transaction.

We use the ring signature to sign a message, such as a request for a mint to reissue a DBC so we can spend it. From this signature the mint can tell the message is valid, but not who we are. It can also check that our key has not been used before to prevent doublespend.

The ring signature itself contains (among other things) a blinding value (random number) for each of the decoy and one for our key, plus a ‘key image’ for our key. A key image is a representation of our key which hides its true identity.

A few things to note:

  • The decoy keys have all been seen by the mint before. They could be ownership keys of other unspent DBCs or some other valid public keys.

  • Each ring sig can only be used once.

  • The key image is stored in the spentbook, so the mint can tell it’s already been spent.

  • Creation of our key image requires our secret key.

So what is our secret key? To explain this we have to go into elliptic curve cryptography (ECC).

Elliptic curve cryptography

ECC is a type of asymmetric cryptography that’s used by many cryptocurrencies, including bitcoin. Like all asymmetric cryptosystems it depends on calculations being easy in one direction and very difficult in the other, i.e. one-way functions.

In ECC the calculation is how to get from one point of a curve to another. Here’s how it works

Let’s say we have a curve of the form: y2= x3 + ax + b.

We are using the BLS12-381 curve (specifically blstrs) which has this sort of shape:

elliptic curve

The curve is huge, covering a finite field Fq where q is a very large prime number, which means there are an enormous (but finite) number of possible points on the curve. All arithmetic operations on points on the curve are modulo q . In modular arithmetic, once a value is larger than q it loops around to the start again, as with a clock: 3 + 10 modulo 12 = 1.

When we multiply one point on the curve ( A ) with another point on the curve s , we will arrive, seemingly at random, at another point ( B ) that’s also on the curve. Doing that multiplication is very quick and easy but reversing it - working out what s we multiplied point A by to arrive at point B - will typically take thousands of years, as you basically have to iterate through every possible option til you hit on the right one. There is no obvious pattern to where successive points turn up on the curve, and no easy way to reverse-engineer the process.

There are some special points on this curve called generators. A generator ( G ) has the property that if you keep adding it to itself ( G, G+G, G+G+G ..) eventually it will define every possible point on the curve. We create a key pair by picking a G and multiplying it by s , another point on the curve known only to us.

  • sG is our public key, s is our secret key.

OK, so we’ve got our public key sG (which in our example is our DBC owner key) and our secret key. Now we have to make a key image I. The formula for doing this is:

  • I = sHp(sG)

Our key image is our secret key s multiplied by a hash of our public key sG. Our key image I is another point on the curve.

Note that since our secret key s is required to create I, only we can create it. I is stored in the spentbook.

So now we can prove our identity is valid with I even though our public key is hashed and multiplied by our secret key, and our public key is blinded and mixed in with all the other blinded decoy keys. The mint only knows that one of those keys is the correct one and if our key image is used again it will be found in the spentbook and blocked.

Next steps

David Rusu is integrating Ring CT into the DBC code. The next step will be to get it working with BLS, and then looking at proof of payment. @danda and @Anselme have laid the groundwork here. The idea is to have invoices that have ‘pay-to’ public keys and Pedersen Commitments in them. The payment DBC will be reissued to have the exact same Pedersen Commitment as that in the invoice. In this way we can prove that we’ve issued the correct amount and to the correct payee. We can post both the invoice and the payment DBC publicly for all to see, providing proof that we have payed this invoice. This is very much a work in progress.

Useful Links

Feel free to reply below with links to translations of this dev update and moderators will add them here:

:russia: Russian ; :germany: German ; :spain: Spanish ; :france: French; :bulgaria: Bulgarian

As an open source project, we’re always looking for feedback, comments and community contributions - so don’t be shy, join in and let’s create the Safe Network together!


First? Wow. That’s a first. :grinning:


second this time around


Third wow not as good as first but better than nothing!

Great work team


This is a GREAT explanation of some of the cryptographic functions involved in the whole crypto field–very accessible even to the uninitiated (or “simpletons”, as it were.

Thanks so much to the team.


Thanks so much to the entire Maidsafe team for all of your hard work! :racehorse:


Always thanks for your hardwork.

God bless team.


As a relentless spy on GitHub I have seen @joshuef making a lot of commits recently, but there is no mention of his work on the update. Why is that? I’m curious to know what he has been tinkering…


:tada: :tada:

Just in time for the holidays.


He is omnipresent, all over the codebase :smiley: To be fair many are, @lionel.faber @yogesh @qi_ma @bochaco @chriso and the rest. Many are more focussed on DBC/Registers and more, but many are debugging and all over the codebase.


Thank you to all the team for their efforts this week. Thank you for the explanation of RingCT. I have convinced myself (at least temporarily) that I now know what is going on here.


We hate to disappoint, but unfortuntely the cusp turned out to be slightly less cuspy than anticipated, so any testnet is still a some days away.

For someone that had no idea that a new testnet was this close this was all but a disappointment. The perseverance you guys show is remarkable, you’re all amazing.


A few of questions.

Proof of payment is more a tool for the sender, correct?
Useful in any kind of e-commerce transaction where something is expected in return

The recipient also has a copy?

Proof of payment is optional or required?

Just trying to clarify that
Proof of payment is more a cryptographic way of proving you paid an agreed amount to the proper recipient in an anonymous digital cash system but that it doesn’t reveal much or any other information besides proof that you did pay an agreed amount.

Edit: Also am going to be curious (once everything is implemented) what the settlement or tps ends up being! Sounded like RingCT was much lighter than other options. Batching of ops like chunk storage payment also help that along.

Thanks for the explanations so far. Excited to hear there is a test net in the not too distant future.


I didn’t know we were that close … encouraging! :smiley:

Nice rock in the pic… reverse pic suggest it has a nice name Arête, which is apt as a narrow ridge of rock which separates two places. Over the next ridge… almost there! :+1:


This is the Pirin Mountain! :dragon: The older name of that mountain was Perun, the Slavic god of Thunder. :vulcano:

Privacy. Security. Freedom


Thanks for making it happen.


I am smelling a double Xmas dinner cooking here!!


(a great (stable) testnet + ERC20 launch)


Yeah! This happened to me, as well. What’s 1-5 days compared to 1-5 months? Nothing, that’s what!


@danda ever hear of this?? Apparently fastest zk roll ups around. Not sure if this is interesting or applicable at all tbh but it is built in Rust.