github.com/mavryk-network/mvgo@v1.19.9/mavryk/blinded.go (about) 1 // Copyright (c) 2020-2021 Blockwatch Data Inc. 2 // Author: alex@blockwatch.cc 3 4 package mavryk 5 6 import ( 7 "bytes" 8 "fmt" 9 10 "github.com/mavryk-network/mvgo/base58" 11 "golang.org/x/crypto/blake2b" 12 ) 13 14 // blinded pks 15 // def genesis_commitments(wallets, blind): 16 // commitments = [] 17 // for pkh_b58, amount in wallets.iteritems(): 18 // # Public key hash corresponding to this Tezos address. 19 // pkh = bitcoin.b58check_to_bin(pkh_b58)[2:] 20 // # The redemption code is unique to the public key hash and deterministically 21 // # constructed using a secret blinding value. 22 // secret = secret_code(pkh, blind) 23 // # The redemption code is used to blind the pkh 24 // blinded_pkh = blake2b(pkh, 20, key=secret).digest() 25 // commitment = { 26 // 'blinded_pkh': bitcoin.bin_to_b58check(blinded_pkh, magicbyte=16921055), 27 // 'amount': amount 28 // } 29 // commitments.append(commitment) 30 // return commitments 31 32 func BlindHash(hash, secret []byte) ([]byte, error) { 33 h, err := blake2b.New(20, secret) 34 if err != nil { 35 return nil, err 36 } 37 h.Write(hash) 38 return h.Sum(nil), nil 39 } 40 41 func BlindAddress(a Address, secret []byte) (Address, error) { 42 bh, err := BlindHash(a[1:], secret) 43 if err != nil { 44 return Address{}, err 45 } 46 return NewAddress(AddressTypeBlinded, bh), nil 47 } 48 49 // Checks if address a when blinded with secret equals blinded address b. 50 func MatchBlindedAddress(a, b Address, secret []byte) bool { 51 bh, _ := BlindHash(a[1:], secret) 52 return bytes.Equal(bh, b[1:]) 53 } 54 55 func DecodeBlindedAddress(addr string) (a Address, err error) { 56 ibuf := bufPool32.Get() 57 dec, ver, err2 := base58.CheckDecode(addr, 4, ibuf.([]byte)) 58 if err2 != nil { 59 if err == base58.ErrChecksum { 60 err = ErrChecksumMismatch 61 return 62 } 63 err = fmt.Errorf("tezos: decoded address is of unknown format: %w", err2) 64 return 65 } 66 if len(dec) != 20 { 67 err = fmt.Errorf("tezos: decoded address hash has invalid length %d", len(dec)) 68 return 69 } 70 if !bytes.Equal(ver, BLINDED_PUBLIC_KEY_HASH_ID) { 71 err = fmt.Errorf("tezos: decoded address %s is of unknown type %x", addr, ver) 72 return 73 } 74 a[0] = byte(AddressTypeBlinded) 75 copy(a[1:], dec) 76 bufPool32.Put(ibuf) 77 return 78 } 79 80 func EncodeBlindedAddress(hash, secret []byte) (string, error) { 81 bh, err := BlindHash(hash, secret) 82 if err != nil { 83 return "", err 84 } 85 return EncodeAddress(AddressTypeBlinded, bh), nil 86 }