// ImportPrivateKey imports a private key in SIPA format func ImportPrivateKey(keydata string, testnet bool) (*ecc.PrivateKey, error) { // decode and check data data, err := Base58Decode(keydata) if err != nil { return nil, err } if testnet { if data[0] != 0xEF { msg := fmt.Sprintf("Invalid key version: %d (testnet)\n", int(data[0])) return nil, errors.New(msg) } } else { if data[0] != 0x80 { msg := fmt.Sprintf("Invalid key version: %d\n", int(data[0])) return nil, errors.New(msg) } } // copy key data var k, c []byte if len(data) == 37 { // uncompressed public key k = data[1:33] c = data[33:37] } else if len(data) == 38 { // compressed public key k = data[1:34] c = data[34:38] if data[33] != 1 { msg := fmt.Sprintf("Invalid key compression indicator: %d\n", int(data[33])) return nil, errors.New(msg) } } else { return nil, errors.New("Invalid key format") } // recompute and verify checksum var t []byte t = append(t, data[0]) t = append(t, k...) cs := Hash256(t) if bytes.Compare(c, cs[:4]) != 0 { return nil, errors.New("Invalid key data") } // return key return ecc.PrivateKeyFromBytes(k) }
func TestAddress(t *testing.T) { for _, d := range data { idhex, err := hex.DecodeString(d.IDhex) if err != nil { t.Fatal("test data failure") } idaddr, err := Base58Decode(d.IDaddr) if err != nil { t.Fatal("test data failure") } if !bytes.Equal(idaddr[1:len(idhex)+1], idhex) { t.Fatal("test data mismatch") } pub, err := hex.DecodeString(d.PubHex) if err != nil { t.Fatal("test data failure") } pubkey, err := ecc.PublicKeyFromBytes(pub) if err != nil { t.Fatal("test data failure") } if !ecc.IsOnCurve(pubkey.Q) { t.Fatal("public point not on curve") } addr := MakeTestAddress(pubkey) addr = MakeAddress(pubkey) if string(addr) != d.IDaddr { t.Fatal("makeaddress failed") } pubkeyhex := hex.EncodeToString(pubkey.Bytes()) if pubkeyhex != d.SerPubHex[90:] { t.Fatal("pubkey mismatch") } if d.Chain != d.SerPubHex[26:90] { t.Fatal("chain mismatch") } if versionMainPublic != d.SerPubHex[:8] { t.Fatal("version mismatch") } b, err := hex.DecodeString(d.SerPubHex) if err != nil { t.Fatal("test data failure") } b = append(b, prefix(b)...) pubser := Base58Encode(b) if pubser != d.SerPubB58 { t.Fatal("test data failure") } prv, err := hex.DecodeString(d.SerPrvHex[90:]) if err != nil { t.Fatal("test data failure") } if len(prv) == 33 { if prv[0] != 0 { t.Fatal("no leading zero") } prv = prv[1:] } prvkey, err := ecc.PrivateKeyFromBytes(prv) if err != nil { t.Fatal("privatekeyfrombytes failed") } q := ecc.ScalarMultBase(prvkey.D) if !ecc.IsEqual(q, pubkey.Q) { t.Fatal("pub/private mismatch") } if d.Chain != d.SerPubHex[26:90] { t.Fatal("chain mismatch") } if versionMainPrivate != d.SerPrvHex[:8] { t.Fatal("version mismatch") } b, err = hex.DecodeString(d.SerPrvHex) if err != nil { t.Fatal("test data failure") } b = append(b, prefix(b)...) prvser := Base58Encode(b) if prvser != d.SerPrvB58 { t.Fatal("test data failure") } } }