29

We have seen evidence that users can sign messages using the SR25519 and ED25519 public key with all zeros.

Why or how is the private key to this public key known?

Are there any other things users should be aware of when using SR25519 or ED25519?

2 Answers 2

25

Yes, it's a consequence of the Edwards curve models used, but secp256k1 is a short Weierstrass curve.

Ed25519 has the identity (0,1) in Affine coordinates, meaning (0,1) + (0,1) = (0,1) in Ed25519. It little endian encodes as [1u8, 0u8, ..., 0u8], not all zeros.

In fact [0u8; 32] decodes as (1,0) because -1 is a square in F_q with q = 2^255-19, since q is divisible by 4. It follows (1,0) lies on the curve. It's not in the distinguished prime order subgroup, but (1,0) + (1,0) = (0,1) in Ed25519, so (1,0) still acts like the identity in sane Ed25519 protocols. See page 6 of Ed25519 paper.

Ristretto decompresses [0u8; 32] as the identity. It's arguably somewhat by chance, except Mike Hamberg avoided crazy constants in the Jacobi quartic encoding, so zero stuck around from Ed25519.

If you want unspendable funds then choose a point via hash-to-curve, which also lets you encode an undependable reason, and control who knows they're unspendable.

let mut hash = sha2::Shake256::default();
hash.input(input);
let unspendable_address = RistrettoPoint::from_hash(hash).compress()

Appears dalek never released a hash-to-curve for ed25519, but they've one in master that's usable for this: https://github.com/dalek-cryptography/curve25519-dalek/blob/main/src/edwards.rs#L532

5
  • Can you elaborate on your last sentence, I didn't understand. Are there some specific public keys which should be chosen as ones that we know no one can have the private key for? Or is it only probabilistic?
    – Shawn Tabrizi
    Mar 23, 2022 at 1:48
  • 3
    I think Jeff means that you can hash arbitrary statements to points on the curve (you usually need special algorithms for hash-to-curve as opposed to hash-to-bytes for security reasons). By doing so, you create public keys, which are valid accounts that anybody can verify but nobody knows the private key for. For burning, you could just hash "burn" to a point in the group instead of burning to the 0 address.
    – rob
    Mar 23, 2022 at 4:35
  • Although Ristretto and sr25519 are stable, curve25519-dalek is deprecating its non-standard hash-to-curve interface for ed25519 in github.com/dalek-cryptography/curve25519-dalek/pull/438 so maybe use curve25519-dalek-ng for this, or better yet adopt the standard, maybe send a PR to cruve25519-dalek or wait for them to do it. Nov 30, 2022 at 13:30
  • 1
    Importantly, a burn-to-zero like BTC and ETH do could be insecure, also like we support with CheckNonZeroSender. It's too easy to set up multiple burns in parallel in multiple applications, which could then all be fulfilled with one single burn, and this might break all or some of those applications. The solution is to always burn to a hash-to-curve point. Nov 30, 2022 at 13:39
  • An amusing trick, you could give each user their own burn point if input = "reason_for_burn" ++ user_id so then the user can claim some benefits from their burn later using chain state instead of blocks. After Beefy this gives less benefit though I guess since you can relocatably prove the block contents from the beefy proof. Mar 6 at 22:06
12

SR25519 is a Schnorr Signature protocol on top of the Ristretto compressed point format of the Ed25519 curve.

Bitcoin and Ethereum both use the Secp256k1 elliptic curve.

In elliptic-curve cryptography, public keys are points. In the Ristretto group, 0 is a member of the group, while in Secp256k1 it is not.

The secret key (a scalar value) corresponding to this member of the Ristretto group is, itself, 0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.