mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 23:03:04 +00:00
Added Mnemonic{Length,Word,Checksum}Exception and tests for each case.
This commit is contained in:
parent
69f52c1b8a
commit
5cd10a537a
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Ken Sedgwick
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.bitcoin.crypto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a list of MnemonicCode words fails the checksum check.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class MnemonicChecksumException extends Exception {
|
||||||
|
public MnemonicChecksumException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MnemonicChecksumException(Exception e) {
|
||||||
|
super(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MnemonicChecksumException(String msg, Exception e) {
|
||||||
|
super(msg, e);
|
||||||
|
}
|
||||||
|
}
|
@ -86,12 +86,12 @@ public class MnemonicCode {
|
|||||||
/**
|
/**
|
||||||
* Encodes a 128, 192 or 256 bit seed into a list of words.
|
* Encodes a 128, 192 or 256 bit seed into a list of words.
|
||||||
*/
|
*/
|
||||||
public List<String> encode(byte[] seed) throws IllegalArgumentException {
|
public List<String> encode(byte[] seed) throws MnemonicLengthException {
|
||||||
|
|
||||||
// 2. Make sure its length (L) is 128, 192 or 256 bits.
|
// 2. Make sure its length (L) is 128, 192 or 256 bits.
|
||||||
int len = seed.length * 8;
|
int len = seed.length * 8;
|
||||||
if (len != 128 && len != 192 && len != 256)
|
if (len != 128 && len != 192 && len != 256)
|
||||||
throw new IllegalArgumentException("seed not 128, 192 or 256 bits");
|
throw new MnemonicLengthException("seed not 128, 192 or 256 bits");
|
||||||
|
|
||||||
// 3. Encrypt input data 10000x with Rijndael (ECB mode).
|
// 3. Encrypt input data 10000x with Rijndael (ECB mode).
|
||||||
// Set key to SHA256 hash of string ("mnemonic" + user_password).
|
// Set key to SHA256 hash of string ("mnemonic" + user_password).
|
||||||
@ -134,12 +134,12 @@ public class MnemonicCode {
|
|||||||
/**
|
/**
|
||||||
* Decodes a list of words into a seed value.
|
* Decodes a list of words into a seed value.
|
||||||
*/
|
*/
|
||||||
public byte[] decode(List<String> words) throws IllegalArgumentException {
|
public byte[] decode(List<String> words) throws MnemonicLengthException, MnemonicWordException, MnemonicChecksumException {
|
||||||
int nwords = words.size();
|
int nwords = words.size();
|
||||||
|
|
||||||
// 2. Make sure the number of words is 12, 18 or 24.
|
// 2. Make sure the number of words is 12, 18 or 24.
|
||||||
if (nwords != 12 && nwords != 18 && nwords != 24)
|
if (nwords != 12 && nwords != 18 && nwords != 24)
|
||||||
throw new IllegalArgumentException("Mnemonic code not 12, 18 or 24 words");
|
throw new MnemonicLengthException("Mnemonic code not 12, 18 or 24 words");
|
||||||
|
|
||||||
// 3. Figure out word indexes in a dictionary and output them as binary stream E.
|
// 3. Figure out word indexes in a dictionary and output them as binary stream E.
|
||||||
int len = nwords * 11;
|
int len = nwords * 11;
|
||||||
@ -149,7 +149,7 @@ public class MnemonicCode {
|
|||||||
// Find the words index in the wordlist.
|
// Find the words index in the wordlist.
|
||||||
int ndx = Collections.binarySearch(this.wordList, word);
|
int ndx = Collections.binarySearch(this.wordList, word);
|
||||||
if (ndx < 0)
|
if (ndx < 0)
|
||||||
throw new IllegalArgumentException("\"" + word + "\" invalid");
|
throw new MnemonicWordException("\"" + word + "\" invalid", word);
|
||||||
|
|
||||||
// Set the next 11 bits to the value of the index.
|
// Set the next 11 bits to the value of the index.
|
||||||
for (int ii = 0; ii < 11; ++ii)
|
for (int ii = 0; ii < 11; ++ii)
|
||||||
@ -172,7 +172,7 @@ public class MnemonicCode {
|
|||||||
// 6. Make sure C is the checksum of B (using the step 5 from the above paragraph).
|
// 6. Make sure C is the checksum of B (using the step 5 from the above paragraph).
|
||||||
boolean[] chksum = checksum(bb);
|
boolean[] chksum = checksum(bb);
|
||||||
if (!Arrays.equals(chksum, cc))
|
if (!Arrays.equals(chksum, cc))
|
||||||
throw new IllegalArgumentException("checksum error");
|
throw new MnemonicChecksumException("checksum error");
|
||||||
|
|
||||||
// 8. Treat B as binary data.
|
// 8. Treat B as binary data.
|
||||||
byte[] outdata = new byte[bblen / 8];
|
byte[] outdata = new byte[bblen / 8];
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Ken Sedgwick
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.bitcoin.crypto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when an argument to MnemonicCode is the wrong length.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class MnemonicLengthException extends Exception {
|
||||||
|
public MnemonicLengthException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MnemonicLengthException(Exception e) {
|
||||||
|
super(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MnemonicLengthException(String msg, Exception e) {
|
||||||
|
super(msg, e);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Ken Sedgwick
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.bitcoin.crypto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a word is encountered which is not in the MnemonicCode's word list.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class MnemonicWordException extends Exception {
|
||||||
|
/** Contains the word that was not found in the word list. */
|
||||||
|
public String badWord;
|
||||||
|
|
||||||
|
public MnemonicWordException(String msg, String badWord) {
|
||||||
|
super(msg);
|
||||||
|
this.badWord = badWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MnemonicWordException(String badWord, Exception e) {
|
||||||
|
super(e);
|
||||||
|
this.badWord = badWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MnemonicWordException(String msg, String badWord, Exception e) {
|
||||||
|
super(msg, e);
|
||||||
|
this.badWord = badWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBadWord() {
|
||||||
|
return badWord;
|
||||||
|
}
|
||||||
|
}
|
@ -127,18 +127,30 @@ public class MnemonicCodeTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = MnemonicLengthException.class)
|
||||||
public void testBadSeedLength() throws Exception {
|
public void testBadSeedLength() throws Exception {
|
||||||
byte[] seed = Hex.decode("7f7f7f7f7f7f7f7f7f7f7f7f7f7f");
|
byte[] seed = Hex.decode("7f7f7f7f7f7f7f7f7f7f7f7f7f7f");
|
||||||
mc.encode(seed);
|
mc.encode(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = MnemonicLengthException.class)
|
||||||
public void testBadWordsLength() throws Exception {
|
public void testBadLength() throws Exception {
|
||||||
List<String> words = split("risk tiger venture dinner age assume float denial penalty");
|
List<String> words = split("risk tiger venture dinner age assume float denial penalty");
|
||||||
mc.decode(words);
|
mc.decode(words);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = MnemonicWordException.class)
|
||||||
|
public void testBadWord() throws Exception {
|
||||||
|
List<String> words = split("risk tiger venture dinner xyzzy assume float denial penalty hello game wing");
|
||||||
|
mc.decode(words);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = MnemonicChecksumException.class)
|
||||||
|
public void testBadChecksum() throws Exception {
|
||||||
|
List<String> words = split("risk tiger venture dinner age assume float denial penalty hello game game");
|
||||||
|
mc.decode(words);
|
||||||
|
}
|
||||||
|
|
||||||
static public List<String> split(String words) {
|
static public List<String> split(String words) {
|
||||||
return new ArrayList<String>(Arrays.asList(words.split("\\s+")));
|
return new ArrayList<String>(Arrays.asList(words.split("\\s+")));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user