hdwallet

package module
v0.0.0-...-57e7ab3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2022 License: MIT Imports: 4 Imported by: 0

README

Algorand HDWallet

This a Algorand HDWallet implementation trial, complying with bip32 & slip-0010 for ED25519 curve.

Also, basic deterministic key derivation from 25 words mnemomic is implemented too using native go sdks. (Thanks to Yieldly repo here)

Key Notes
  • Only hardened public keys are supported, because normal/public derivations (extended public key to public key) is not possible for ED25519 curve.
  • Algorand coin code is 283 according to slip-0044. So derivation paths may be m/44'/283'/0'/1'/100' or simply m/1'/0'/0' (Not mandating any format...)
  • ed25519 test vectors 1 & 2 defined with SLIP-0010 are implemented.

Usage

package main

import (
        "fmt"
        "github.com/polarbit/hdwallet"
)

func main() {
        mnemonic24 := "segment inhale symptom olive cheese tissue vacuum lazy sketch salt enroll wink oyster hen glory food weasel comic glow legal cute diet fun real"
        path := "m/44'/283'/0'"
        a, _, _ := hdwallet.DeriveAddressFromMnemonic(mnemonic24, path)

        fmt.Printf("Address: %s\n", a)
}

Notes

PublicKey & Algorand Address

slip0010 creates extended public keys padded a zero byte (0x00) from left.
This 33 bytes public key is not compatible with Alogrand address generation (32 bytes required).
So while creating Algorand an address, we ignore the padded zero byte.

PrivateKey

ed25519 key generation produces a 64 byte private key.
Second half of this private key is public key of the curve, pub = priv[32:] .
slip0010 uses the first half (32 byest) of that for key generation
Algorand-Sdk also uses the first half of that private key for mnemonics.

kmd - Deterministic Address Generation

This is the Algorand kmd code that generates deterministec wallets. I expect same derivations from same seed; but did not tested myself.

How transactions are signed by Algorand-SDK

Below are two main/low-level methods that helps to understand low levels of Algorand tx signing.

// rawSignTransaction signs the msgpack-encoded tx (with prepended "TX" prefix), and returns the sig and txid
func rawSignTransaction(sk ed25519.PrivateKey, tx types.Transaction) (s types.Signature, txid string, err error) {
	toBeSigned := rawTransactionBytesToSign(tx)

	// Sign the encoded transaction
	signature := ed25519.Sign(sk, toBeSigned)

	// Copy the resulting signature into a Signature, 
    // and check that it's the expected length
	n := copy(s[:], signature)
	if n != len(s) {
		err = errInvalidSignatureReturned
		return
	}
	// Populate txID
	txid = txIDFromRawTxnBytesToSign(toBeSigned)
	return
}

// rawTransactionBytesToSign returns the byte form of the tx that 
// we actually sign and compute txID from.
func RawTransactionBytesToSign(tx types.Transaction) []byte {
	var txidPrefix = []byte("TX")

	// Encode the transaction as msgpack
	encodedTx := msgpack.Encode(tx)

	// Prepend the hashable prefix
	msgParts := [][]byte{txidPrefix, encodedTx}
	return bytes.Join(msgParts, nil)
}

go-algorand/daemon/kmd/wallet/driver/sqlite_crypto.go


Tests

Run single test: go test ./... -run "MnemonicToSeed" -v

Run integration test: TEST_INT=true go test ./... -run "AlgorandPayment" -v


References

SLIP-0010

BIP-32

BIP-44

Yieldly - Algorand Deterministic Account Derivation

Algorand Developer Docs - Offline Signing

Algorand Go SDK - crypto.go


To Do

  • Refactor: logs, types ([]byte), errors (better messages).
  • Add TX building, signing and broadcasting capability. (We already do this in payment integration test)
  • Import & export xpriv, and generate keys from it.
  • Use environment variables in integration tests for mnemomics.
  • ... support other curves when Algorand is done. (maybe no or just ed25519 coins!)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeriveAddressFromMnemonic

func DeriveAddressFromMnemonic(mnemonic string, derivationPath string) (a string, xkey *slip0010.ExtendedKey, err error)

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL