Skip to content

Commit

Permalink
feat: Adding 12 word mnemonic
Browse files Browse the repository at this point in the history
  • Loading branch information
andrix10 authored and janaakhterov committed Nov 23, 2020
1 parent 773ac07 commit 0cd5896
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 25 deletions.
10 changes: 5 additions & 5 deletions contract_create_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ func (transaction *ContractCreateTransaction) GetBytecodeFileID() FileID {
}

/**
* Sets the state of the instance and its fields can be modified arbitrarily if this key signs a transaction
* to modify it. If this is null, then such modifications are not possible, and there is no administrator
* that can override the normal operation of this smart contract instance. Note that if it is created with no
* admin keys, then there is no administrator to authorize changing the admin keys, so
* there can never be any admin keys for that instance.
* Sets the state of the instance and its fields can be modified arbitrarily if this key signs a transaction
* to modify it. If this is null, then such modifications are not possible, and there is no administrator
* that can override the normal operation of this smart contract instance. Note that if it is created with no
* admin keys, then there is no administrator to authorize changing the admin keys, so
* there can never be any admin keys for that instance.
*/
func (transaction *ContractCreateTransaction) SetAdminKey(adminKey Key) *ContractCreateTransaction {
transaction.requireNotFrozen()
Expand Down
20 changes: 18 additions & 2 deletions crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,24 @@ func TestSigning(t *testing.T) {
assert.True(t, ed25519.Verify(pubKey.Bytes(), []byte("this is the test data to sign"), signature))
}

func TestGeneratedMnemonicToWorkingPrivateKey(t *testing.T) {
mnemonic, err := GenerateMnemonic()
func TestGenerated24MnemonicToWorkingPrivateKey(t *testing.T) {
mnemonic, err := GenerateMnemonic24()

assert.NoError(t, err)

privateKey, err := mnemonic.ToPrivateKey("")

assert.NoError(t, err)

message := []byte("this is a test message")

signature := privateKey.Sign(message)

assert.True(t, ed25519.Verify(privateKey.PublicKey().Bytes(), message, signature))
}

func TestGenerated12MnemonicToWorkingPrivateKey(t *testing.T) {
mnemonic, err := GenerateMnemonic12()

assert.NoError(t, err)

Expand Down
25 changes: 19 additions & 6 deletions examples/generate_key_with_mnemonic/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,33 @@ import (
)

func main() {
mnemonic, err := hedera.GenerateMnemonic()
mnemonic24, err := hedera.GenerateMnemonic24()
if err != nil {
panic(err)
}
mnemonic12, err := hedera.GenerateMnemonic12()
if err != nil {
panic(err)
}

fmt.Printf("mnemonic = %v\n", mnemonic)
fmt.Printf("mnemonic 24 word = %v\n", mnemonic24)
fmt.Printf("mnemonic 12 word = %v\n", mnemonic12)

privateKey, err := mnemonic.ToPrivateKey( /* passphrase */ "")
privateKey24, err := mnemonic24.ToPrivateKey( /* passphrase */ "")
if err != nil {
panic(err)
}
privateKey12, err := mnemonic12.ToPrivateKey( /* passphrase */ "")
if err != nil {
panic(err)
}

publicKey24 := privateKey24.PublicKey()
publicKey12 := privateKey12.PublicKey()

publicKey := privateKey.PublicKey()
fmt.Printf("private 24 word = %v\n", privateKey24)
fmt.Printf("public 24 word = %v\n", publicKey24)

fmt.Printf("private = %v\n", privateKey)
fmt.Printf("public = %v\n", publicKey)
fmt.Printf("private 12 word = %v\n", privateKey12)
fmt.Printf("public 12 word = %v\n", publicKey12)
}
2 changes: 1 addition & 1 deletion live_hash_add_transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestSerializeLiveHashAddTransaction(t *testing.T) {

tx.Sign(newKey)

assert.Equal(t, `bodyBytes:"\n\016\n\010\010\334\311\007\020\333\237\t\022\002\030\003\022\002\030\003\030\200\302\327/\"\002\010xR\n\032\010\n\002\030\003*\002\010\036"sigMap:<sigPair:<pubKeyPrefix:"\344\361\300\353L}\315\303\347\353\021p\263\010\212=\022\242\227\364\243\353\342\362\205\003\375g5F\355\216"ed25519:"\245@\347` + "`" + `\254r\036G\016\314\266V\242\275\245\272p\224\371'\022%?\364\337u\343\303\031\253k\363\017\346\263\241\017U\304!4N)\034\251\345\335\005z\033\365\236\203\240\273\010\310\255\243q6*[\005">>transactionID:<transactionValidStart:<seconds:124124nanos:151515>accountID:<accountNum:3>>nodeAccountID:<accountNum:3>transactionFee:100000000transactionValidDuration:<seconds:120>cryptoAddLiveHash:<liveHash:<accountId:<accountNum:3>duration:<seconds:30>>>`, strings.ReplaceAll(strings.ReplaceAll(tx.String(), " ", ""), "\n", ""))
assert.Equal(t, `bodyBytes:"\n\016\n\010\010\334\311\007\020\333\237\t\022\002\030\003\022\002\030\003\030\200\302\327/\"\002\010xR\n\032\010\n\002\030\003*\002\010\036"sigMap:<sigPair:<pubKeyPrefix:"\344\361\300\353L}\315\303\347\353\021p\263\010\212=\022\242\227\364\243\353\342\362\205\003\375g5F\355\216"ed25519:"\245@\347`+"`"+`\254r\036G\016\314\266V\242\275\245\272p\224\371'\022%?\364\337u\343\303\031\253k\363\017\346\263\241\017U\304!4N)\034\251\345\335\005z\033\365\236\203\240\273\010\310\255\243q6*[\005">>transactionID:<transactionValidStart:<seconds:124124nanos:151515>accountID:<accountNum:3>>nodeAccountID:<accountNum:3>transactionFee:100000000transactionValidDuration:<seconds:120>cryptoAddLiveHash:<liveHash:<accountId:<accountNum:3>duration:<seconds:30>>>`, strings.ReplaceAll(strings.ReplaceAll(tx.String(), " ", ""), "\n", ""))
}

func TestLiveHashAddTransaction_Execute(t *testing.T) {
Expand Down
31 changes: 25 additions & 6 deletions mnemonic.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (m Mnemonic) ToPrivateKey(passPhrase string) (PrivateKey, error) {
}

// GenerateMnemonic generates a random 24-word mnemonic
func GenerateMnemonic() (Mnemonic, error) {
func GenerateMnemonic24() (Mnemonic, error) {
entropy, err := bip39.NewEntropy(256)

if err != nil {
Expand All @@ -34,6 +34,25 @@ func GenerateMnemonic() (Mnemonic, error) {
return Mnemonic{mnemonic}, nil
}

func GenerateMnemonic12() (Mnemonic, error) {
entropy, err := bip39.NewEntropy(128)

if err != nil {
// It is only possible for there to be an error if the operating
// system's rng is unreadable
return Mnemonic{}, fmt.Errorf("could not retrieve random bytes from the operating system")
}

mnemonic, err := bip39.NewMnemonic(entropy)

// Note that this should never actually fail since it is being provided by library generated mnemonic
if err != nil {
return Mnemonic{}, err
}

return Mnemonic{mnemonic}, nil
}

// MnemonicFromString creates a mnemonic from a string of 24 words separated by spaces
//
// Keys are lazily generated
Expand All @@ -53,11 +72,11 @@ func (m Mnemonic) Words() []string {
//
// Keys are lazily generated
func NewMnemonic(words []string) (Mnemonic, error) {
if len(words) != 24 {
if len(words) == 24 || len(words) == 12 {
return Mnemonic{
words: strings.Join(words, " "),
}, nil
} else {
return Mnemonic{}, fmt.Errorf("invalid mnemonic string")
}

return Mnemonic{
words: strings.Join(words, " "),
}, nil
}
42 changes: 37 additions & 5 deletions mnemonic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ import (
"github.com/stretchr/testify/assert"
)

func TestGenerateMnemonic(t *testing.T) {
mnemonic, err := GenerateMnemonic()
func TestGenerate24WordMnemonic(t *testing.T) {
mnemonic, err := GenerateMnemonic24()
assert.NoError(t, err)

assert.Equal(t, 24, len(mnemonic.Words()))
}

func TestGenerate12WordMnemonic(t *testing.T) {
mnemonic, err := GenerateMnemonic24()
assert.NoError(t, err)

assert.Equal(t, 24, len(mnemonic.Words()))
Expand All @@ -22,8 +29,33 @@ func TestMnemonicFromString(t *testing.T) {
assert.Equal(t, 24, len(mnemonic.Words()))
}

func TestNewMnemonicFromGeneratedMnemonic(t *testing.T) {
generatedMnemonic, err := GenerateMnemonic()
func TestNew24MnemonicFromGeneratedMnemonic(t *testing.T) {
generatedMnemonic, err := GenerateMnemonic24()
assert.NoError(t, err)

mnemonicFromSlice, err := NewMnemonic(generatedMnemonic.Words())
assert.NoError(t, err)
assert.Equal(t, generatedMnemonic.words, mnemonicFromSlice.words)

mnemonicFromString, err := MnemonicFromString(generatedMnemonic.String())
assert.NoError(t, err)
assert.Equal(t, generatedMnemonic, mnemonicFromString)

gKey, err := generatedMnemonic.ToPrivateKey(passphrase)
assert.NoError(t, err)

slKey, err := generatedMnemonic.ToPrivateKey(passphrase)
assert.NoError(t, err)

stKey, err := generatedMnemonic.ToPrivateKey(passphrase)
assert.NoError(t, err)

assert.Equal(t, gKey.keyData, slKey.keyData)
assert.Equal(t, gKey.keyData, stKey.keyData)
}

func TestNew12MnemonicFromGeneratedMnemonic(t *testing.T) {
generatedMnemonic, err := GenerateMnemonic12()
assert.NoError(t, err)

mnemonicFromSlice, err := NewMnemonic(generatedMnemonic.Words())
Expand All @@ -49,7 +81,7 @@ func TestNewMnemonicFromGeneratedMnemonic(t *testing.T) {

func TestMnemonicBreaksWithBadLength(t *testing.T) {
// note this mnemonic is probably invalid and is only used to test breakage based on length
shortMnemonic := "inmate flip alley wear offer often piece magnet surge toddler submit right"
shortMnemonic := "inmate flip alley wear offer often piece magnet surge toddler submit right business"

_, err := MnemonicFromString(shortMnemonic)
assert.Error(t, err)
Expand Down

0 comments on commit 0cd5896

Please sign in to comment.