Browse Source

spec: add Address spec. notes about Query

pull/1500/head
Ethan Buchman 7 years ago
parent
commit
0e1414ef9d
3 changed files with 76 additions and 17 deletions
  1. +20
    -2
      docs/specification/new-spec/abci.md
  2. +35
    -11
      docs/specification/new-spec/encoding.md
  3. +21
    -4
      docs/specification/new-spec/scripts/crypto.go

+ 20
- 2
docs/specification/new-spec/abci.md View File

@ -28,7 +28,7 @@ message Validator {
The `pub_key` is the Amino encoded public key for the validator. For details on The `pub_key` is the Amino encoded public key for the validator. For details on
Amino encoded public keys, see the [section of the encoding spec](./encoding.md#public-key-cryptography). Amino encoded public keys, see the [section of the encoding spec](./encoding.md#public-key-cryptography).
For example, the 32-byte Ed25519 pubkey
For Ed25519 pubkeys, the Amino prefix is always "1624DE6220". For example, the 32-byte Ed25519 pubkey
`76852933A4686A721442E931A8415F62F5F1AEDF4910F1F252FB393F74C40C85` would be `76852933A4686A721442E931A8415F62F5F1AEDF4910F1F252FB393F74C40C85` would be
Amino encoded as Amino encoded as
`1624DE622076852933A4686A721442E931A8415F62F5F1AEDF4910F1F252FB393F74C40C85` `1624DE622076852933A4686A721442E931A8415F62F5F1AEDF4910F1F252FB393F74C40C85`
@ -44,5 +44,23 @@ following rules:
set with the given power set with the given power
- if the validator does already exist, its power will be adjusted to the given power - if the validator does already exist, its power will be adjusted to the given power
## Query ## Query
Query is a generic message type with lots of flexibility to enable diverse sets
of queries from applications. Tendermint has no requirements from the Query
message for normal operation - that is, the ABCI app developer need not implement Query functionality if they do not wish too.
That said, Tendermint makes a number of queries to support some optional
features. These are:
### Peer Filtering
When Tendermint connects to a peer, it sends two queries to the ABCI application
using the following paths, with no additional data:
- `/p2p/filter/addr/<IP:PORT>`, where `<IP:PORT>` denote the IP address and
the port of the connection
- `p2p/filter/pubkey/<ID>`, where `<ID>` is the peer node ID (ie. the
pubkey.Address() for the peer's PubKey)
If either of these queries return a non-zero ABCI code, Tendermint will refuse
to connect to the peer.

+ 35
- 11
docs/specification/new-spec/encoding.md View File

@ -15,6 +15,9 @@ Notably, every object that satisfies an interface (eg. a particular kind of p2p
or a particular kind of pubkey) is registered with a global name, the hash of or a particular kind of pubkey) is registered with a global name, the hash of
which is included in the object's encoding as the so-called "prefix bytes". which is included in the object's encoding as the so-called "prefix bytes".
We define the `func AminoEncode(obj interface{}) []byte` function to take an
arbitrary object and return the Amino encoded bytes.
## Byte Arrays ## Byte Arrays
The encoding of a byte array is simply the raw-bytes prefixed with the length of The encoding of a byte array is simply the raw-bytes prefixed with the length of
@ -48,6 +51,9 @@ Notice that when encoding byte-arrays, the length of the byte-array is appended
to the PrefixBytes. Thus the encoding of a byte array becomes `<PrefixBytes> to the PrefixBytes. Thus the encoding of a byte array becomes `<PrefixBytes>
<Length> <ByteArray>` <Length> <ByteArray>`
(NOTE: the remainder of this section on Public Key Cryptography can be generated
from [this script](./scripts/crypto.go))
### PubKeyEd25519 ### PubKeyEd25519
``` ```
@ -56,12 +62,21 @@ to the PrefixBytes. Thus the encoding of a byte array becomes `<PrefixBytes>
// Length: 0x20 // Length: 0x20
// Notes: raw 32-byte Ed25519 pubkey // Notes: raw 32-byte Ed25519 pubkey
type PubKeyEd25519 [32]byte type PubKeyEd25519 [32]byte
func (pubkey PubKeyEd25519) Address() []byte {
// NOTE: hash of the Amino encoded bytes!
return RIPEMD160(AminoEncode(pubkey))
}
``` ```
For example, the 32-byte Ed25519 pubkey For example, the 32-byte Ed25519 pubkey
`76852933A4686A721442E931A8415F62F5F1AEDF4910F1F252FB393F74C40C85` would be
`CCACD52F9B29D04393F01CD9AF6535455668115641F3D8BAEFD2295F24BAF60E` would be
encoded as encoded as
`1624DE622076852933A4686A721442E931A8415F62F5F1AEDF4910F1F252FB393F74C40C85`
`1624DE6220CCACD52F9B29D04393F01CD9AF6535455668115641F3D8BAEFD2295F24BAF60E`.
The address would then be
`RIPEMD160(0x1624DE6220CCACD52F9B29D04393F01CD9AF6535455668115641F3D8BAEFD2295F24BAF60E)`
or `430FF75BAF1EC4B0D51BB3EEC2955479D0071605`
### SignatureEd25519 ### SignatureEd25519
@ -74,9 +89,9 @@ type SignatureEd25519 [64]byte
``` ```
For example, the 64-byte Ed25519 signature For example, the 64-byte Ed25519 signature
`005E76B3B0D790959B03F862A9EF8F6236457032B5F522C4CAB5AAD7C44A00A12669E1A2761798E70A0A923DA0CF981839558123CF6466553BCBFF25DADD630F`
`1B6034A8ED149D3C94FDA13EC03B26CC0FB264D9B0E47D3FA3DEF9FCDE658E49C80B35F9BE74949356401B15B18FB817D6E54495AD1C4A8401B248466CB0DB0B`
would be encoded as would be encoded as
`3DA1DB2A40005E76B3B0D790959B03F862A9EF8F6236457032B5F522C4CAB5AAD7C44A00A12669E1A2761798E70A0A923DA0CF981839558123CF6466553BCBFF25DADD630F`
`3DA1DB2A401B6034A8ED149D3C94FDA13EC03B26CC0FB264D9B0E47D3FA3DEF9FCDE658E49C80B35F9BE74949356401B15B18FB817D6E54495AD1C4A8401B248466CB0DB0B`
### PrivKeyEd25519 ### PrivKeyEd25519
@ -85,6 +100,7 @@ would be encoded as
// Notes: raw 32-byte priv key concatenated to raw 32-byte pub key // Notes: raw 32-byte priv key concatenated to raw 32-byte pub key
type PrivKeyEd25519 [64]byte type PrivKeyEd25519 [64]byte
``` ```
### PubKeySecp256k1 ### PubKeySecp256k1
``` ```
@ -93,12 +109,22 @@ type PrivKeyEd25519 [64]byte
// Length: 0x21 // Length: 0x21
// Notes: OpenSSL compressed pubkey prefixed with 0x02 or 0x03 // Notes: OpenSSL compressed pubkey prefixed with 0x02 or 0x03
type PubKeySecp256k1 [33]byte type PubKeySecp256k1 [33]byte
func (pubkey PubKeySecp256k1) Address() []byte {
// NOTE: hash of the raw pubkey bytes (not Amino encoded!).
// Compatible with Bitcoin addresses.
return RIPEMD160(SHA256(pubkey[:]))
}
``` ```
For example, the 33-byte Secp256k1 pubkey For example, the 33-byte Secp256k1 pubkey
`03573E0EC1F989DECC3913AC7D44D0509C1A992ECE700845594A1078DAF19A3380` would be
`020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9` would be
encoded as encoded as
`EB5AE9822103573E0EC1F989DECC3913AC7D44D0509C1A992ECE700845594A1078DAF19A3380`
`EB5AE98221020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9`
The address would then be
`RIPEMD160(SHA256(0x020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9))`
or `0AE5BEE929ABE51BAD345DB925EEA652680783FC`
### SignatureSecp256k1 ### SignatureSecp256k1
@ -112,9 +138,9 @@ type SignatureSecp256k1 []byte
``` ```
For example, the Secp256k1 signature For example, the Secp256k1 signature
`304402207447640A5C12A72BAA052D110B666FB6DF717A7B863361C092E751D016C6C08802205C20F9DEBF8915DED310B98BFA890105F43925FDB2B67B78510FE18EDA2B30DA` would
be encoded as
`16E1FEEA46304402202C10C874E413AF538D97EBEF2B01024719F8B7CC559CEEBDC7C380F9DCC4A6E002200EDE9B62F8531933F88DB2A62E73BA3D43ACEB1CBD23070C2F792AAA18717A4A`
`304402201CD4B8C764D2FD8AF23ECFE6666CA8A53886D47754D951295D2D311E1FEA33BF02201E0F906BB1CF2C30EAACFFB032A7129358AFF96B9F79B06ACFFB18AC90C2ADD7`
would be encoded as
`16E1FEEA46304402201CD4B8C764D2FD8AF23ECFE6666CA8A53886D47754D951295D2D311E1FEA33BF02201E0F906BB1CF2C30EAACFFB032A7129358AFF96B9F79B06ACFFB18AC90C2ADD7`
### PrivKeySecp256k1 ### PrivKeySecp256k1
@ -124,8 +150,6 @@ be encoded as
type PrivKeySecp256k1 [32]byte type PrivKeySecp256k1 [32]byte
``` ```
## Other Common Types ## Other Common Types
### BitArray ### BitArray


+ 21
- 4
docs/specification/new-spec/scripts/crypto.go View File

@ -6,8 +6,11 @@ import (
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
) )
// SECRET
var SECRET = []byte("some secret")
func printEd() { func printEd() {
priv := crypto.GenPrivKeyEd25519()
priv := crypto.GenPrivKeyEd25519FromSecret(SECRET)
pub := priv.PubKey().(crypto.PubKeyEd25519) pub := priv.PubKey().(crypto.PubKeyEd25519)
sig := priv.Sign([]byte("hello")).(crypto.SignatureEd25519) sig := priv.Sign([]byte("hello")).(crypto.SignatureEd25519)
@ -22,9 +25,15 @@ func printEd() {
fmt.Printf("// Length: 0x%X \n", length) fmt.Printf("// Length: 0x%X \n", length)
fmt.Println("// Notes: raw 32-byte Ed25519 pubkey") fmt.Println("// Notes: raw 32-byte Ed25519 pubkey")
fmt.Println("type PubKeyEd25519 [32]byte") fmt.Println("type PubKeyEd25519 [32]byte")
fmt.Println("")
fmt.Println(`func (pubkey PubKeyEd25519) Address() []byte {
// NOTE: hash of the Amino encoded bytes!
return RIPEMD160(AminoEncode(pubkey))
}`)
fmt.Println("```") fmt.Println("```")
fmt.Println("") fmt.Println("")
fmt.Printf("For example, the 32-byte Ed25519 pubkey `%X` would be encoded as `%X`\n", pub[:], pub.Bytes())
fmt.Printf("For example, the 32-byte Ed25519 pubkey `%X` would be encoded as `%X`.\n\n", pub[:], pub.Bytes())
fmt.Printf("The address would then be `RIPEMD160(0x%X)` or `%X`\n", pub.Bytes(), pub.Address())
fmt.Println("") fmt.Println("")
name = "tendermint/SignatureKeyEd25519" name = "tendermint/SignatureKeyEd25519"
@ -55,7 +64,7 @@ func printEd() {
} }
func printSecp() { func printSecp() {
priv := crypto.GenPrivKeySecp256k1()
priv := crypto.GenPrivKeySecp256k1FromSecret(SECRET)
pub := priv.PubKey().(crypto.PubKeySecp256k1) pub := priv.PubKey().(crypto.PubKeySecp256k1)
sig := priv.Sign([]byte("hello")).(crypto.SignatureSecp256k1) sig := priv.Sign([]byte("hello")).(crypto.SignatureSecp256k1)
@ -70,9 +79,16 @@ func printSecp() {
fmt.Printf("// Length: 0x%X \n", length) fmt.Printf("// Length: 0x%X \n", length)
fmt.Println("// Notes: OpenSSL compressed pubkey prefixed with 0x02 or 0x03") fmt.Println("// Notes: OpenSSL compressed pubkey prefixed with 0x02 or 0x03")
fmt.Println("type PubKeySecp256k1 [33]byte") fmt.Println("type PubKeySecp256k1 [33]byte")
fmt.Println("")
fmt.Println(`func (pubkey PubKeySecp256k1) Address() []byte {
// NOTE: hash of the raw pubkey bytes (not Amino encoded!).
// Compatible with Bitcoin addresses.
return RIPEMD160(SHA256(pubkey[:]))
}`)
fmt.Println("```") fmt.Println("```")
fmt.Println("") fmt.Println("")
fmt.Printf("For example, the 33-byte Secp256k1 pubkey `%X` would be encoded as `%X`\n", pub[:], pub.Bytes())
fmt.Printf("For example, the 33-byte Secp256k1 pubkey `%X` would be encoded as `%X`\n\n", pub[:], pub.Bytes())
fmt.Printf("The address would then be `RIPEMD160(SHA256(0x%X))` or `%X`\n", pub[:], pub.Address())
fmt.Println("") fmt.Println("")
name = "tendermint/SignatureKeySecp256k1" name = "tendermint/SignatureKeySecp256k1"
@ -104,5 +120,6 @@ func printSecp() {
func main() { func main() {
printEd() printEd()
fmt.Println("")
printSecp() printSecp()
} }

Loading…
Cancel
Save