package wallet import ( "math/bits" "github.com/phamminh0811/private-grpc/crypto" "github.com/phamminh0811/private-grpc/nockchain" ) var InitialBits = []bool{true, false, false, true, true, false, true, false, false, false, false, false, false, false, true, true, true, true, false, false, false, false, false, true, true, true, false, true, true, false, true, false, true, true, false, false, false, false, true, false, true, true, true, false} func NumBitsUint64(v uint64) int { if v == 0 { return 0 } return 64 - bits.LeadingZeros64(v) } func Uint64ToBitsLSB0(x uint64) []bool { bits := make([]bool, 64) for i := 0; i < 64; i++ { bits[i] = ((x >> i) & 1) == 1 } return bits } func BoolsToBytesLSB0(bits []bool) []byte { if len(bits) == 0 { return nil } n := (len(bits) + 7) / 8 // ceil division bytes := make([]byte, n) for i, bit := range bits { if bit { byteIdx := i / 8 bitIdx := i % 8 bytes[byteIdx] |= 1 << bitIdx // LSB0: least-significant bit first } } return bytes } func EncodeNoteData(noteData *nockchain.NockchainLock) []byte { bits := InitialBits numPubkeys := noteData.KeysRequired numPubkeysSz := NumBitsUint64(uint64(numPubkeys)) numPubkeysSzSz := NumBitsUint64(uint64(numPubkeysSz)) bits = append(bits, false) for i := 0; i < numPubkeysSzSz; i++ { bits = append(bits, false) } bits = append(bits, true) if numPubkeysSzSz > 1 { numPubkeysSzBits := Uint64ToBitsLSB0(uint64(numPubkeysSz)) bits = append(bits, numPubkeysSzBits[0:numPubkeysSzSz-1]...) } numPubkeysBits := Uint64ToBitsLSB0(uint64(numPubkeys)) bits = append(bits, numPubkeysBits[0:numPubkeysSz]...) bits = append(bits, []bool{true, false}...) for _, pkStr := range noteData.Pubkeys { pkHash := crypto.Base58ToTip5Hash(pkStr) for i, hash := range pkHash { if i != 4 { bits = append(bits, []bool{true, false}...) } hashSz := NumBitsUint64(hash) hashSzSz := NumBitsUint64(uint64(hashSz)) bits = append(bits, false) for i := 0; i < hashSzSz; i++ { bits = append(bits, false) } bits = append(bits, true) if hashSzSz > 1 { hashSzBits := Uint64ToBitsLSB0(uint64(hashSz)) bits = append(bits, hashSzBits[0:hashSzSz-1]...) } hashBits := Uint64ToBitsLSB0(hash) bits = append(bits, hashBits[0:hashSz]...) } } bits = append(bits, []bool{true, false, false, true, false, true, false, true}...) return BoolsToBytesLSB0(bits) }