github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/flow/address.go (about)

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