-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ADR 028: Public Key Addresses #7086
Conversation
Codecov Report
@@ Coverage Diff @@
## master #7086 +/- ##
==========================================
+ Coverage 54.21% 54.60% +0.39%
==========================================
Files 611 547 -64
Lines 38464 37121 -1343
==========================================
- Hits 20852 20270 -582
+ Misses 15503 15192 -311
+ Partials 2109 1659 -450 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good
The proposal here looks good to me, in terms of the specification for new addresses. However, I'm a bit confused how this actually relates to existing address formats, and I think the wording around that could be clarified. If i understand correctly, this means that legacy account addresses would be unchanged and remain in their bech32 prefixed form, but accounts generated with non How does one distinguish between a "legacy" or "new" multisig? Is this about addresses that exist onchain on a current zone, vs ones that do not? Or about what pubkey type the multisig address is comprised of (where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the comments in this ADR and in the linked issues, the feeling I get is that everyone here is aligned to say "it should be okay" (incl. me).
Would it make sense to run this by a cryptographer, to get validation "yes, this is okay". I'd trust the word of a cryptographer over my gut feeling any day of the week.
key type prefix when creating addresses. | ||
|
||
We define the canonical address format for new (non-legacy) public keys as | ||
`Sha256(fmt.Sprintf("%s/%x, proto.MessageName(key), key.Bytes())[:20]`. This takes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current secp256k1 uses ripemd160 instead of [:20]. The latter is faster to compute, but are there other trade-offs (in particular, security-wise)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is needed for bitcoin compatibility. There were other designs, but the 2017 fundraiser addresses were generated with a bitcoin secp256k1 address derivation and the go code had to be compatible.
But I cannot tell you if 20 bytes prefix is just as safe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ripemd160 is an odd and basically pointless cryptographic choice and there is no reason to retain it.
It's a slow hash function and doesn't improve security in a meaningful way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are changing this, how about using blake2b
? Which is faster, and many believe that it's more secure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not blake3 @robert-zaremba ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So hypothetically it would be easier to find a pre-image for a SHA256 address than a Blake2 address?
Not worse, and it's more random.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blake3 reduced the number of rounds from Blake2 to get a speed up
It uses a different mechanism, so I can't say if the reduction of number of rounds impacts the security vs Blake2 or not. Probably asking one of the authors (Zooko?) would be the best approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we err on the side of caution and go with Blake2
This seams to be the balanced solution. Although it would be still good to check out with zcash about their view. I will try to reach out to some of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new draft uses blake2b
. Both because it has better library support and has been around longer and vetted more thoroughly (as I understand it).
I'm assuming blake2b
is preferable to blake2s
for our use case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BLAKE2b is designed and optimized for 64-bit CPUs. BLAKE2s is designed and optimized for 8, 16, 32-bit CPUs.
BLAKE2 has indeed excellent Golang and Rust libraries support. Today there are very few BLAKE3 supported implementations. The speed boost observed with BLAKE3 is not really a selling point regarding ADR 028.
@clevinson I can try to answer your questions, given my understanding of this ADR:
There's public key (
Given a random 20-byte address, I believe there's no way to distinguish if it's a "legacy" or "new" multisig, or any other single public key type. This ADR describes the other direction, given 1/ threshold and 2/ an array of public keys (each being potentially of a different key type), how to construct "legacy" and "new" multisig addresses. Also, I don't think secp256k1 is deemed "legacy"; it just has a different address generation algorithm. |
For new account They have one of the best cryptographers form the world so they know best what / how to use. Additional advantage is that it has a checksum, which protects against a wrong copy paste! |
The proposal looks good, though I'm interested in understanding better what are the consequences for multisig keys (see Cory's questioin: |
if len(contents) != 0 { | ||
preImage = append(preImage, 0) | ||
preImage = append(preImage, contents...) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When implementing this we should use use make([]byte, correctSize)
and copy they content using for
or copy
(into slice starting from index 2
).
Yes, but we will still need to rethink how to handle dynamic accounts (more about it below).
Maybe. This will go into the category of a complex / multisig account with a native address. I think we will need to go back to the ADR28 once we will put all accounts together and before we will implement it. So for the moment I would like to mark it only. |
In general I would use a pseudo code for explaining the algorithm. The reason is that we should discuss implementation details separately, which will involve things like integration and optimization, and language specific things. |
We use a 256-bit `blake2b` hash instead of `sha256` because it is generally considered more secure. Blake hashes | ||
are considered "random oracle indifferentiable", a stronger property which `sha256` does not have. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Random oracle indifferentiability is cryptographically irrelevant for constructing addresses.
https://blog.cryptographyengineering.com/2012/07/17/indifferentiability/
Cause see the prefix of an address always specifies the length of suffix. Ie. sr25519 key is always 32bytes. In the context of this protocol, a MD hash like sha256 is "random oracle indeffentiable"
I'm just saying this because I'm always going to strongly advocate for a really high bar for adding a new hash function to the Cosmos trusted computing base.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zmanian I agree with your general approach. But we don't propose a any exotic algorithm. Blake2 is a part of at least Go and Python3 stdlib and it's an improvement. Some cryptographers claim that sha256 is easier to break than blake2 because we already know how to break other hash functions from the MD family.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some cryptographers claim that sha256 is easier to break than blake2.
Some references would be appreciated 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just saying this because I'm always going to strongly advocate for a really high bar for adding a new hash function to the Cosmos trusted computing base.
So I want to summarize what I heard from @zmanian on our last call about this. Basically:
- there is no consensus on the replacement for SHA256 yet in the crypto community and there's a widespread sense that it won't be broken anytime soon
- we want to minimize what is needed for someone to implement "cosmos" on a broad array of devices including hardware wallets and embedded devices
Thus for now it's probably preferable to stick with SHA256. Is that accurate @zmanian ?
@alessio any progress on getting the cryptographer at AiB to take a look at this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
W3F Research / Polkadot is using blake2b and avoiding sha2.
…ronc/adr-028-pub-key-addresses
I have reverted to change to In the interest of progress and the points raised in #7498 can we merge this ADR with status proposed and address remaining issues as follow-up issues and or PRs? I still would like to get a cryptographer's opinion on the hashing if we can, but I think I have addressed what I can for now. So basically I would like to get people's opinion as to whether this is a good enough starting point that we can move forward with it at least preliminarily. We need something to work off of within the SDK. Our plan is to include this in the v0.41 release so we can open a few follow-up issues tagged as v0.41 and make sure we address them before release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add notes around the parts which:
- Require opinion of qualified person
- Are still under consideration
And then merge
@robert-zaremba could you open an issue documenting those things? |
ref: #5694
This ADR proposes a canonical extensible address format for new public key types, and addresses the multisig pubkey address issue.
Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.
docs/
) or specification (x/<module>/spec/
)godoc
comments.Unreleased
section inCHANGELOG.md
Files changed
in the Github PR explorerCodecov Report
in the comment section below once CI passes