github.com/koko1123/flow-go-1@v0.29.6/model/flow/address.go (about) 1 // (c) 2019 Dapper Labs - ALL RIGHTS RESERVED 2 3 package flow 4 5 import ( 6 "encoding/binary" 7 "encoding/hex" 8 "fmt" 9 "strings" 10 ) 11 12 // Address represents the 8 byte address of an account. 13 type Address [AddressLength]byte 14 15 type AddressGenerator interface { 16 NextAddress() (Address, error) 17 CurrentAddress() Address 18 Bytes() []byte 19 AddressCount() uint64 // returns the total number of addresses that have been generated so far 20 } 21 22 type MonotonicAddressGenerator struct { 23 index uint64 24 } 25 26 // linearCodeAddressGenerator represents the internal index of the linear code address generation mechanism 27 type linearCodeAddressGenerator struct { 28 chainCodeWord uint64 29 index uint64 30 } 31 32 const ( 33 // AddressLength is the size of an account address in bytes. 34 // (n) is the size of an account address in bits. 35 AddressLength = (linearCodeN + 7) >> 3 36 // addressIndexLength is the size of an account address state in bytes. 37 // (k) is the size of an account address in bits. 38 addressIndexLength = (linearCodeK + 7) >> 3 39 ) 40 41 // EmptyAddress is the default value of a variable of type Address 42 var EmptyAddress = Address{} 43 44 // HexToAddress converts a hex string to an Address. 45 func HexToAddress(h string) Address { 46 trimmed := strings.TrimPrefix(h, "0x") 47 if len(trimmed)%2 == 1 { 48 trimmed = "0" + trimmed 49 } 50 b, _ := hex.DecodeString(trimmed) 51 return BytesToAddress(b) 52 } 53 54 // BytesToAddress returns Address with value b. 55 // 56 // If b is larger than 8, b will be cropped from the left. 57 // If b is smaller than 8, b will be appended by zeroes at the front. 58 func BytesToAddress(b []byte) Address { 59 var a Address 60 if len(b) > AddressLength { 61 b = b[len(b)-AddressLength:] 62 } 63 copy(a[AddressLength-len(b):], b) 64 return a 65 } 66 67 // Bytes returns the byte representation of the address. 68 func (a Address) Bytes() []byte { 69 return a[:] 70 } 71 72 // Hex returns the hex string representation of the address. 73 func (a Address) Hex() string { 74 return hex.EncodeToString(a.Bytes()) 75 } 76 77 // HexWithPrefix returns the hex string representation of the address, 78 // including the 0x prefix. 79 func (a Address) HexWithPrefix() string { 80 return "0x" + a.Hex() 81 } 82 83 // String returns the string representation of the address. 84 func (a Address) String() string { 85 return a.Hex() 86 } 87 88 // Short returns the string representation of the address with leading zeros 89 // removed. 90 func (a Address) Short() string { 91 hex := a.String() 92 trimmed := strings.TrimLeft(hex, "0") 93 if len(trimmed)%2 != 0 { 94 trimmed = "0" + trimmed 95 } 96 return trimmed 97 } 98 99 func (a Address) MarshalJSON() ([]byte, error) { 100 return []byte(fmt.Sprintf("\"%s\"", a.Hex())), nil 101 } 102 103 func (a *Address) UnmarshalJSON(data []byte) error { 104 *a = HexToAddress(strings.Trim(string(data), "\"")) 105 return nil 106 } 107 108 // modified from binary.bigEndian.uint64 109 func uint48(b []byte) uint64 { 110 _ = b[5] // bounds check hint to compiler; 111 return uint64(b[5]) | uint64(b[4])<<8 | 112 uint64(b[3])<<16 | uint64(b[2])<<24 | uint64(b[1])<<32 | uint64(b[0])<<40 113 } 114 115 // modified from binary.bigEndian.PutUint64 116 func putUint48(b []byte, v uint64) { 117 _ = b[5] // early bounds check to guarantee safety of writes below 118 b[0] = byte(v >> 40) 119 b[1] = byte(v >> 32) 120 b[2] = byte(v >> 24) 121 b[3] = byte(v >> 16) 122 b[4] = byte(v >> 8) 123 b[5] = byte(v) 124 } 125 126 func indexToBytes(index uint64) []byte { 127 indexBytes := make([]byte, addressIndexLength) 128 putUint48(indexBytes, index) 129 return indexBytes 130 } 131 132 // Bytes converts an address index into a slice of bytes 133 func (gen *MonotonicAddressGenerator) Bytes() []byte { 134 return indexToBytes(gen.index) 135 } 136 137 // Bytes converts an address index into a slice of bytes 138 func (gen *linearCodeAddressGenerator) Bytes() []byte { 139 return indexToBytes(gen.index) 140 } 141 142 // NextAddress increments the internal index and generates the new address 143 // corresponding to the new index. 144 func (gen *MonotonicAddressGenerator) NextAddress() (Address, error) { 145 gen.index++ 146 if uint64(gen.index) > maxIndex { 147 return EmptyAddress, fmt.Errorf("the new index value is not valid, it must be less or equal to %x", maxIndex) 148 } 149 return gen.CurrentAddress(), nil 150 } 151 152 // CurrentAddress returns the address corresponding to the internal index. 153 func (gen *MonotonicAddressGenerator) CurrentAddress() Address { 154 return uint64ToAddress(gen.index) 155 } 156 157 // AddressCount returns the total number of addresses generated so far 158 func (gen *MonotonicAddressGenerator) AddressCount() uint64 { 159 return gen.index 160 } 161 162 // NextAddress generates an account address from the addressing index. 163 // 164 // The address is generated for a specific network (Flow mainnet, testnet..) 165 // The second returned value is the new updated addressing index. The new 166 // addressing index should replace the old index to keep generating account 167 // addresses in a sequential way. 168 // Each index is mapped to exactly one address. There are as many addresses 169 // as indices. 170 // zeroAddress() corresponds to the index "0" while ServiceAddress() corresponds to the 171 // index "1". 172 func (gen *linearCodeAddressGenerator) NextAddress() (Address, error) { 173 err := gen.nextIndex() 174 if err != nil { 175 return EmptyAddress, err 176 } 177 index := gen.index 178 address := encodeWord(index) 179 // customize the code word for a specific network 180 address ^= gen.chainCodeWord 181 return uint64ToAddress(address), nil 182 } 183 184 // CurrentAddress returns the current account address. 185 // 186 // The returned address is the address of the latest created account. 187 func (gen *linearCodeAddressGenerator) CurrentAddress() Address { 188 index := gen.index 189 address := encodeWord(index) 190 // customize the code word for a specific network 191 address ^= gen.chainCodeWord 192 return uint64ToAddress(address) 193 } 194 195 // AddressCount returns the total number of addresses generated so far 196 func (gen *linearCodeAddressGenerator) AddressCount() uint64 { 197 return gen.index 198 } 199 200 // increments the internal index of the generator. 201 // 202 // In this implemntation, the index values are simply 203 // incremented from 0 to 2^k-1. 204 func (gen *linearCodeAddressGenerator) nextIndex() error { 205 gen.index++ 206 if uint64(gen.index) > maxIndex { 207 return fmt.Errorf("the new index value is not valid, it must be less or equal to %x", maxIndex) 208 } 209 return nil 210 } 211 212 // uint64ToAddress returns an address with value v. 213 // 214 // The value v fits into the address as the address size is 8 215 func uint64ToAddress(v uint64) Address { 216 var b [AddressLength]byte 217 binary.BigEndian.PutUint64(b[:], v) 218 return Address(b) 219 } 220 221 // uint64 converts an address into a uint64 222 func (a *Address) uint64() uint64 { 223 v := binary.BigEndian.Uint64(a[:]) 224 return v 225 } 226 227 const ( 228 // [n,k,d]-Linear code parameters 229 // The linear code used in the account addressing is a [64,45,7] 230 // It generates a [64,45]-code, which is the space of Flow account addresses. 231 // 232 // n is the size of the code words in bits, 233 // which is also the size of the account addresses in bits. 234 linearCodeN = 64 235 // k is size of the words in bits. 236 // 2^k is the total number of possible account addresses. 237 linearCodeK = 45 238 // p is the number of code parity bits. 239 // p = n - k 240 // 241 // d is the distance of the linear code. 242 // It is the minimum hamming distance between any two Flow account addresses. 243 // This means any pair of Flow addresses have at least 7 different bits, which 244 // minimizes the mistakes of typing wrong addresses. 245 // d is also the minimum hamming weight of all account addresses (the zero address is not an account address). 246 linearCodeD = 7 247 248 // the maximum value of the internal state, 2^k - 1. 249 maxIndex = (1 << linearCodeK) - 1 250 ) 251 252 // The following are invalid code-words in the [64,45] code. 253 // These constants are used to generate non-Flow-Mainnet addresses 254 255 // invalidCodeTestNetwork is the invalid codeword used for long-lived test networks. 256 const invalidCodeTestNetwork = uint64(0x6834ba37b3980209) 257 258 // invalidCodeTransientNetwork is the invalid codeword used for transient test networks. 259 const invalidCodeTransientNetwork = uint64(0x1cb159857af02018) 260 261 // invalidCodeSandboxNetwork is the invalid codeword used for Sandbox network. 262 const invalidCodeSandboxNetwork = uint64(0x1035ce4eff92ae01) 263 264 // encodeWord encodes a word into a code word. 265 // In Flow, the word is the account index while the code word 266 // is the corresponding address. 267 // 268 // The function assumes the word is valid (<2^k) 269 func encodeWord(word uint64) uint64 { 270 // Multiply the index GF(2) vector by the code generator matrix 271 codeWord := uint64(0) 272 for i := 0; i < linearCodeK; i++ { 273 if word&1 == 1 { 274 codeWord ^= generatorMatrixRows[i] 275 } 276 word >>= 1 277 } 278 return codeWord 279 } 280 281 // checks if the input is a valid code word of the linear code 282 func isValidCodeWord(codeWord uint64) bool { 283 // Multiply the code word GF(2)-vector by the parity-check matrix 284 parity := uint(0) 285 for i := 0; i < linearCodeN; i++ { 286 if codeWord&1 == 1 { 287 parity ^= parityCheckMatrixColumns[i] 288 } 289 codeWord >>= 1 290 } 291 return parity == 0 292 } 293 294 // reverse the linear code assuming the input is a valid 295 // codeWord. 296 func decodeCodeWord(codeWord uint64) uint64 { 297 // truncate the address GF(2) vector (last K bits) and multiply it by the inverse matrix of 298 // the partial code generator. 299 word := uint64(0) 300 codeWord >>= (linearCodeN - linearCodeK) 301 for i := 0; i < linearCodeK; i++ { 302 if codeWord&1 == 1 { 303 word ^= inverseMatrixRows[i] 304 } 305 codeWord >>= 1 306 } 307 return word 308 } 309 310 // Rows of the generator matrix G of the [64,45]-code used for Flow addresses. 311 // G is a (k x n) matrix with coefficients in GF(2), each row is converted into 312 // a big endian integer representation of the GF(2) raw vector. 313 // G is used to generate the account addresses 314 var generatorMatrixRows = [linearCodeK]uint64{ 315 0xe467b9dd11fa00df, 0xf233dcee88fe0abe, 0xf919ee77447b7497, 0xfc8cf73ba23a260d, 316 0xfe467b9dd11ee2a1, 0xff233dcee888d807, 0xff919ee774476ce6, 0x7fc8cf73ba231d10, 317 0x3fe467b9dd11b183, 0x1ff233dcee8f96d6, 0x8ff919ee774757ba, 0x47fc8cf73ba2b331, 318 0x23fe467b9dd27f6c, 0x11ff233dceee8e82, 0x88ff919ee775dd8f, 0x447fc8cf73b905e4, 319 0xa23fe467b9de0d83, 0xd11ff233dce8d5a7, 0xe88ff919ee73c38a, 0x7447fc8cf73f171f, 320 0xba23fe467b9dcb2b, 0xdd11ff233dcb0cb4, 0xee88ff919ee26c5d, 0x77447fc8cf775dd3, 321 0x3ba23fe467b9b5a1, 0x9dd11ff233d9117a, 0xcee88ff919efa640, 0xe77447fc8cf3e297, 322 0x73ba23fe467fabd2, 0xb9dd11ff233fb16c, 0xdcee88ff919adde7, 0xee77447fc8ceb196, 323 0xf73ba23fe4621cd0, 0x7b9dd11ff2379ac3, 0x3dcee88ff91df46c, 0x9ee77447fc88e702, 324 0xcf73ba23fe4131b6, 0x67b9dd11ff240f9a, 0x33dcee88ff90f9e0, 0x19ee77447fcff4e3, 325 0x8cf73ba23fe64091, 0x467b9dd11ff115c7, 0x233dcee88ffdb735, 0x919ee77447fe2309, 326 0xc8cf73ba23fdc736} 327 328 // Columns of the parity-check matrix H of the [64,45]-code used for Flow addresses. 329 // H is a (n x p) matrix with coefficients in GF(2), each column is converted into 330 // a big endian integer representation of the GF(2) column vector. 331 // H is used to verify a code word is a valid account address. 332 var parityCheckMatrixColumns = [linearCodeN]uint{ 333 0x00001, 0x00002, 0x00004, 0x00008, 334 0x00010, 0x00020, 0x00040, 0x00080, 335 0x00100, 0x00200, 0x00400, 0x00800, 336 0x01000, 0x02000, 0x04000, 0x08000, 337 0x10000, 0x20000, 0x40000, 0x7328d, 338 0x6689a, 0x6112f, 0x6084b, 0x433fd, 339 0x42aab, 0x41951, 0x233ce, 0x22a81, 340 0x21948, 0x1ef60, 0x1deca, 0x1c639, 341 0x1bdd8, 0x1a535, 0x194ac, 0x18c46, 342 0x1632b, 0x1529b, 0x14a43, 0x13184, 343 0x12942, 0x118c1, 0x0f812, 0x0e027, 344 0x0d00e, 0x0c83c, 0x0b01d, 0x0a831, 345 0x0982b, 0x07034, 0x0682a, 0x05819, 346 0x03807, 0x007d2, 0x00727, 0x0068e, 347 0x0067c, 0x0059d, 0x004eb, 0x003b4, 348 0x0036a, 0x002d9, 0x001c7, 0x0003f, 349 } 350 351 // Rows of the inverse I of the generator matrix I = sub(G)^(-1). 352 // sub(G) is a square sub-matrix of G formed by the first (k) columns. This makes sub(G) 353 // an inversible (k x k) matrix. 354 // I is a (k x k) matrix with coefficients in GF(2), each row is converted into 355 // a big endian integer representation of the GF(2) raw vector. 356 // I is used to retrieve indices from account addresses. 357 var inverseMatrixRows = [linearCodeK]uint64{ 358 0x14b4ae9336c9, 0x1a5a57499b64, 0x0d2d2ba4cdb2, 0x069695d266d9, 359 0x134b4ae9336c, 0x09a5a57499b6, 0x04d2d2ba4cdb, 0x1269695d266d, 360 0x1934b4ae9336, 0x0c9a5a57499b, 0x164d2d2ba4cd, 0x1b269695d266, 361 0x0d934b4ae933, 0x16c9a5a57499, 0x1b64d2d2ba4c, 0x0db269695d26, 362 0x06d934b4ae93, 0x136c9a5a5749, 0x19b64d2d2ba4, 0x0cdb269695d2, 363 0x066d934b4ae9, 0x1336c9a5a574, 0x099b64d2d2ba, 0x04cdb269695d, 364 0x1266d934b4ae, 0x09336c9a5a57, 0x1499b64d2d2b, 0x1a4cdb269695, 365 0x1d266d934b4a, 0x0e9336c9a5a5, 0x17499b64d2d2, 0x0ba4cdb26969, 366 0x15d266d934b4, 0x0ae9336c9a5a, 0x057499b64d2d, 0x12ba4cdb2696, 367 0x095d266d934b, 0x14ae9336c9a5, 0x1a57499b64d2, 0x0d2ba4cdb269, 368 0x1695d266d934, 0x0b4ae9336c9a, 0x05a57499b64d, 0x12d2ba4cdb26, 369 0x09695d266d93, 370 }