mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-01 21:57:03 +00:00
move go-crypto files pre-keys merge
This commit is contained in:
+193
@@ -0,0 +1,193 @@
|
||||
Tendermint Go-Crypto
|
||||
Copyright (C) 2015 Tendermint
|
||||
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
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
|
||||
|
||||
https://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.
|
||||
@@ -0,0 +1,9 @@
|
||||
.PHONY: docs
|
||||
REPO:=github.com/tendermint/go-crypto
|
||||
|
||||
docs:
|
||||
@go get github.com/davecheney/godoc2md
|
||||
godoc2md $(REPO) > README.md
|
||||
|
||||
test:
|
||||
go test `glide novendor`
|
||||
@@ -0,0 +1,837 @@
|
||||
|
||||
|
||||
# crypto
|
||||
`import "github.com/tendermint/go-crypto"`
|
||||
|
||||
* [Overview](#pkg-overview)
|
||||
* [Index](#pkg-index)
|
||||
* [Subdirectories](#pkg-subdirectories)
|
||||
|
||||
## <a name="pkg-overview">Overview</a>
|
||||
|
||||
|
||||
|
||||
## <a name="pkg-index">Index</a>
|
||||
* [Constants](#pkg-constants)
|
||||
* [func CRandBytes(numBytes int) []byte](#CRandBytes)
|
||||
* [func CRandHex(numDigits int) string](#CRandHex)
|
||||
* [func CReader() io.Reader](#CReader)
|
||||
* [func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error)](#DecodeArmor)
|
||||
* [func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error)](#DecryptSymmetric)
|
||||
* [func EncodeArmor(blockType string, headers map[string]string, data []byte) string](#EncodeArmor)
|
||||
* [func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte)](#EncryptSymmetric)
|
||||
* [func MixEntropy(seedBytes []byte)](#MixEntropy)
|
||||
* [func Ripemd160(bytes []byte) []byte](#Ripemd160)
|
||||
* [func Sha256(bytes []byte) []byte](#Sha256)
|
||||
* [type PrivKey](#PrivKey)
|
||||
* [func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error)](#PrivKeyFromBytes)
|
||||
* [type PrivKeyEd25519](#PrivKeyEd25519)
|
||||
* [func GenPrivKeyEd25519() PrivKeyEd25519](#GenPrivKeyEd25519)
|
||||
* [func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519](#GenPrivKeyEd25519FromSecret)
|
||||
* [func (privKey PrivKeyEd25519) Bytes() []byte](#PrivKeyEd25519.Bytes)
|
||||
* [func (privKey PrivKeyEd25519) Equals(other PrivKey) bool](#PrivKeyEd25519.Equals)
|
||||
* [func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519](#PrivKeyEd25519.Generate)
|
||||
* [func (p PrivKeyEd25519) MarshalJSON() ([]byte, error)](#PrivKeyEd25519.MarshalJSON)
|
||||
* [func (privKey PrivKeyEd25519) PubKey() PubKey](#PrivKeyEd25519.PubKey)
|
||||
* [func (privKey PrivKeyEd25519) Sign(msg []byte) Signature](#PrivKeyEd25519.Sign)
|
||||
* [func (privKey PrivKeyEd25519) String() string](#PrivKeyEd25519.String)
|
||||
* [func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte](#PrivKeyEd25519.ToCurve25519)
|
||||
* [func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error](#PrivKeyEd25519.UnmarshalJSON)
|
||||
* [type PrivKeyS](#PrivKeyS)
|
||||
* [func (p PrivKeyS) Empty() bool](#PrivKeyS.Empty)
|
||||
* [func (p PrivKeyS) MarshalJSON() ([]byte, error)](#PrivKeyS.MarshalJSON)
|
||||
* [func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error)](#PrivKeyS.UnmarshalJSON)
|
||||
* [type PrivKeySecp256k1](#PrivKeySecp256k1)
|
||||
* [func GenPrivKeySecp256k1() PrivKeySecp256k1](#GenPrivKeySecp256k1)
|
||||
* [func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1](#GenPrivKeySecp256k1FromSecret)
|
||||
* [func (privKey PrivKeySecp256k1) Bytes() []byte](#PrivKeySecp256k1.Bytes)
|
||||
* [func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool](#PrivKeySecp256k1.Equals)
|
||||
* [func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error)](#PrivKeySecp256k1.MarshalJSON)
|
||||
* [func (privKey PrivKeySecp256k1) PubKey() PubKey](#PrivKeySecp256k1.PubKey)
|
||||
* [func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature](#PrivKeySecp256k1.Sign)
|
||||
* [func (privKey PrivKeySecp256k1) String() string](#PrivKeySecp256k1.String)
|
||||
* [func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error](#PrivKeySecp256k1.UnmarshalJSON)
|
||||
* [type PubKey](#PubKey)
|
||||
* [func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error)](#PubKeyFromBytes)
|
||||
* [type PubKeyEd25519](#PubKeyEd25519)
|
||||
* [func (pubKey PubKeyEd25519) Address() []byte](#PubKeyEd25519.Address)
|
||||
* [func (pubKey PubKeyEd25519) Bytes() []byte](#PubKeyEd25519.Bytes)
|
||||
* [func (pubKey PubKeyEd25519) Equals(other PubKey) bool](#PubKeyEd25519.Equals)
|
||||
* [func (pubKey PubKeyEd25519) KeyString() string](#PubKeyEd25519.KeyString)
|
||||
* [func (p PubKeyEd25519) MarshalJSON() ([]byte, error)](#PubKeyEd25519.MarshalJSON)
|
||||
* [func (pubKey PubKeyEd25519) String() string](#PubKeyEd25519.String)
|
||||
* [func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte](#PubKeyEd25519.ToCurve25519)
|
||||
* [func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error](#PubKeyEd25519.UnmarshalJSON)
|
||||
* [func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool](#PubKeyEd25519.VerifyBytes)
|
||||
* [type PubKeyS](#PubKeyS)
|
||||
* [func (p PubKeyS) Empty() bool](#PubKeyS.Empty)
|
||||
* [func (p PubKeyS) MarshalJSON() ([]byte, error)](#PubKeyS.MarshalJSON)
|
||||
* [func (p *PubKeyS) UnmarshalJSON(data []byte) (err error)](#PubKeyS.UnmarshalJSON)
|
||||
* [type PubKeySecp256k1](#PubKeySecp256k1)
|
||||
* [func (pubKey PubKeySecp256k1) Address() []byte](#PubKeySecp256k1.Address)
|
||||
* [func (pubKey PubKeySecp256k1) Bytes() []byte](#PubKeySecp256k1.Bytes)
|
||||
* [func (pubKey PubKeySecp256k1) Equals(other PubKey) bool](#PubKeySecp256k1.Equals)
|
||||
* [func (pubKey PubKeySecp256k1) KeyString() string](#PubKeySecp256k1.KeyString)
|
||||
* [func (p PubKeySecp256k1) MarshalJSON() ([]byte, error)](#PubKeySecp256k1.MarshalJSON)
|
||||
* [func (pubKey PubKeySecp256k1) String() string](#PubKeySecp256k1.String)
|
||||
* [func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error](#PubKeySecp256k1.UnmarshalJSON)
|
||||
* [func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool](#PubKeySecp256k1.VerifyBytes)
|
||||
* [type Signature](#Signature)
|
||||
* [func SignatureFromBytes(sigBytes []byte) (sig Signature, err error)](#SignatureFromBytes)
|
||||
* [type SignatureEd25519](#SignatureEd25519)
|
||||
* [func (sig SignatureEd25519) Bytes() []byte](#SignatureEd25519.Bytes)
|
||||
* [func (sig SignatureEd25519) Equals(other Signature) bool](#SignatureEd25519.Equals)
|
||||
* [func (sig SignatureEd25519) IsZero() bool](#SignatureEd25519.IsZero)
|
||||
* [func (p SignatureEd25519) MarshalJSON() ([]byte, error)](#SignatureEd25519.MarshalJSON)
|
||||
* [func (sig SignatureEd25519) String() string](#SignatureEd25519.String)
|
||||
* [func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error](#SignatureEd25519.UnmarshalJSON)
|
||||
* [type SignatureS](#SignatureS)
|
||||
* [func (p SignatureS) Empty() bool](#SignatureS.Empty)
|
||||
* [func (p SignatureS) MarshalJSON() ([]byte, error)](#SignatureS.MarshalJSON)
|
||||
* [func (p *SignatureS) UnmarshalJSON(data []byte) (err error)](#SignatureS.UnmarshalJSON)
|
||||
* [type SignatureSecp256k1](#SignatureSecp256k1)
|
||||
* [func (sig SignatureSecp256k1) Bytes() []byte](#SignatureSecp256k1.Bytes)
|
||||
* [func (sig SignatureSecp256k1) Equals(other Signature) bool](#SignatureSecp256k1.Equals)
|
||||
* [func (sig SignatureSecp256k1) IsZero() bool](#SignatureSecp256k1.IsZero)
|
||||
* [func (p SignatureSecp256k1) MarshalJSON() ([]byte, error)](#SignatureSecp256k1.MarshalJSON)
|
||||
* [func (sig SignatureSecp256k1) String() string](#SignatureSecp256k1.String)
|
||||
* [func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error](#SignatureSecp256k1.UnmarshalJSON)
|
||||
|
||||
|
||||
#### <a name="pkg-files">Package files</a>
|
||||
[armor.go](/src/github.com/tendermint/go-crypto/armor.go) [hash.go](/src/github.com/tendermint/go-crypto/hash.go) [priv_key.go](/src/github.com/tendermint/go-crypto/priv_key.go) [pub_key.go](/src/github.com/tendermint/go-crypto/pub_key.go) [random.go](/src/github.com/tendermint/go-crypto/random.go) [signature.go](/src/github.com/tendermint/go-crypto/signature.go) [symmetric.go](/src/github.com/tendermint/go-crypto/symmetric.go)
|
||||
|
||||
|
||||
## <a name="pkg-constants">Constants</a>
|
||||
``` go
|
||||
const (
|
||||
TypeEd25519 = byte(0x01)
|
||||
TypeSecp256k1 = byte(0x02)
|
||||
NameEd25519 = "ed25519"
|
||||
NameSecp256k1 = "secp256k1"
|
||||
)
|
||||
```
|
||||
Types of implementations
|
||||
|
||||
|
||||
|
||||
|
||||
## <a name="CRandBytes">func</a> [CRandBytes](/src/target/random.go?s=698:734#L28)
|
||||
``` go
|
||||
func CRandBytes(numBytes int) []byte
|
||||
```
|
||||
This uses the OS and the Seed(s).
|
||||
|
||||
|
||||
|
||||
## <a name="CRandHex">func</a> [CRandHex](/src/target/random.go?s=924:959#L38)
|
||||
``` go
|
||||
func CRandHex(numDigits int) string
|
||||
```
|
||||
RandHex(24) gives 96 bits of randomness, strong enough for most purposes.
|
||||
|
||||
|
||||
|
||||
## <a name="CReader">func</a> [CReader](/src/target/random.go?s=1078:1102#L43)
|
||||
``` go
|
||||
func CReader() io.Reader
|
||||
```
|
||||
Returns a crand.Reader mixed with user-supplied entropy
|
||||
|
||||
|
||||
|
||||
## <a name="DecodeArmor">func</a> [DecodeArmor](/src/target/armor.go?s=596:699#L18)
|
||||
``` go
|
||||
func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error)
|
||||
```
|
||||
|
||||
|
||||
## <a name="DecryptSymmetric">func</a> [DecryptSymmetric](/src/target/symmetric.go?s=1048:1133#L23)
|
||||
``` go
|
||||
func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error)
|
||||
```
|
||||
secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
|
||||
The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
|
||||
|
||||
|
||||
|
||||
## <a name="EncodeArmor">func</a> [EncodeArmor](/src/target/armor.go?s=125:206#L1)
|
||||
``` go
|
||||
func EncodeArmor(blockType string, headers map[string]string, data []byte) string
|
||||
```
|
||||
|
||||
|
||||
## <a name="EncryptSymmetric">func</a> [EncryptSymmetric](/src/target/symmetric.go?s=356:430#L6)
|
||||
``` go
|
||||
func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte)
|
||||
```
|
||||
secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
|
||||
The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
|
||||
NOTE: call crypto.MixEntropy() first.
|
||||
|
||||
|
||||
|
||||
## <a name="MixEntropy">func</a> [MixEntropy](/src/target/random.go?s=407:440#L13)
|
||||
``` go
|
||||
func MixEntropy(seedBytes []byte)
|
||||
```
|
||||
Mix additional bytes of randomness, e.g. from hardware, user-input, etc.
|
||||
It is OK to call it multiple times. It does not diminish security.
|
||||
|
||||
|
||||
|
||||
## <a name="Ripemd160">func</a> [Ripemd160](/src/target/hash.go?s=185:220#L4)
|
||||
``` go
|
||||
func Ripemd160(bytes []byte) []byte
|
||||
```
|
||||
|
||||
|
||||
## <a name="Sha256">func</a> [Sha256](/src/target/hash.go?s=78:110#L1)
|
||||
``` go
|
||||
func Sha256(bytes []byte) []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="PrivKey">type</a> [PrivKey](/src/target/priv_key.go?s=326:435#L5)
|
||||
``` go
|
||||
type PrivKey interface {
|
||||
Bytes() []byte
|
||||
Sign(msg []byte) Signature
|
||||
PubKey() PubKey
|
||||
Equals(PrivKey) bool
|
||||
}
|
||||
```
|
||||
PrivKey is part of PrivAccount and state.PrivValidator.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyFromBytes">func</a> [PrivKeyFromBytes](/src/target/priv_key.go?s=1302:1373#L50)
|
||||
``` go
|
||||
func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## <a name="PrivKeyEd25519">type</a> [PrivKeyEd25519](/src/target/priv_key.go?s=1502:1530#L58)
|
||||
``` go
|
||||
type PrivKeyEd25519 [64]byte
|
||||
```
|
||||
Implements PrivKey
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="GenPrivKeyEd25519">func</a> [GenPrivKeyEd25519](/src/target/priv_key.go?s=3003:3042#L116)
|
||||
``` go
|
||||
func GenPrivKeyEd25519() PrivKeyEd25519
|
||||
```
|
||||
|
||||
### <a name="GenPrivKeyEd25519FromSecret">func</a> [GenPrivKeyEd25519FromSecret](/src/target/priv_key.go?s=3290:3352#L125)
|
||||
``` go
|
||||
func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519
|
||||
```
|
||||
NOTE: secret should be the output of a KDF like bcrypt,
|
||||
if it's derived from user input.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.Bytes">func</a> (PrivKeyEd25519) [Bytes](/src/target/priv_key.go?s=1532:1576#L60)
|
||||
``` go
|
||||
func (privKey PrivKeyEd25519) Bytes() []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.Equals">func</a> (PrivKeyEd25519) [Equals](/src/target/priv_key.go?s=1973:2029#L75)
|
||||
``` go
|
||||
func (privKey PrivKeyEd25519) Equals(other PrivKey) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.Generate">func</a> (PrivKeyEd25519) [Generate](/src/target/priv_key.go?s=2761:2825#L106)
|
||||
``` go
|
||||
func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519
|
||||
```
|
||||
Deterministically generates new priv-key bytes from key.
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.MarshalJSON">func</a> (PrivKeyEd25519) [MarshalJSON](/src/target/priv_key.go?s=2156:2209#L83)
|
||||
``` go
|
||||
func (p PrivKeyEd25519) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.PubKey">func</a> (PrivKeyEd25519) [PubKey](/src/target/priv_key.go?s=1826:1871#L70)
|
||||
``` go
|
||||
func (privKey PrivKeyEd25519) PubKey() PubKey
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.Sign">func</a> (PrivKeyEd25519) [Sign](/src/target/priv_key.go?s=1635:1691#L64)
|
||||
``` go
|
||||
func (privKey PrivKeyEd25519) Sign(msg []byte) Signature
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.String">func</a> (PrivKeyEd25519) [String](/src/target/priv_key.go?s=2613:2658#L101)
|
||||
``` go
|
||||
func (privKey PrivKeyEd25519) String() string
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.ToCurve25519">func</a> (PrivKeyEd25519) [ToCurve25519](/src/target/priv_key.go?s=2399:2453#L94)
|
||||
``` go
|
||||
func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyEd25519.UnmarshalJSON">func</a> (\*PrivKeyEd25519) [UnmarshalJSON](/src/target/priv_key.go?s=2250:2306#L87)
|
||||
``` go
|
||||
func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="PrivKeyS">type</a> [PrivKeyS](/src/target/priv_key.go?s=929:962#L30)
|
||||
``` go
|
||||
type PrivKeyS struct {
|
||||
PrivKey
|
||||
}
|
||||
```
|
||||
PrivKeyS add json serialization to PrivKey
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyS.Empty">func</a> (PrivKeyS) [Empty](/src/target/priv_key.go?s=1241:1271#L46)
|
||||
``` go
|
||||
func (p PrivKeyS) Empty() bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyS.MarshalJSON">func</a> (PrivKeyS) [MarshalJSON](/src/target/priv_key.go?s=964:1011#L34)
|
||||
``` go
|
||||
func (p PrivKeyS) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeyS.UnmarshalJSON">func</a> (\*PrivKeyS) [UnmarshalJSON](/src/target/priv_key.go?s=1057:1114#L38)
|
||||
``` go
|
||||
func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="PrivKeySecp256k1">type</a> [PrivKeySecp256k1](/src/target/priv_key.go?s=3635:3665#L136)
|
||||
``` go
|
||||
type PrivKeySecp256k1 [32]byte
|
||||
```
|
||||
Implements PrivKey
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="GenPrivKeySecp256k1">func</a> [GenPrivKeySecp256k1](/src/target/priv_key.go?s=5071:5114#L194)
|
||||
``` go
|
||||
func GenPrivKeySecp256k1() PrivKeySecp256k1
|
||||
```
|
||||
|
||||
### <a name="GenPrivKeySecp256k1FromSecret">func</a> [GenPrivKeySecp256k1FromSecret](/src/target/priv_key.go?s=5436:5502#L204)
|
||||
``` go
|
||||
func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1
|
||||
```
|
||||
NOTE: secret should be the output of a KDF like bcrypt,
|
||||
if it's derived from user input.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeySecp256k1.Bytes">func</a> (PrivKeySecp256k1) [Bytes](/src/target/priv_key.go?s=3667:3713#L138)
|
||||
``` go
|
||||
func (privKey PrivKeySecp256k1) Bytes() []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeySecp256k1.Equals">func</a> (PrivKeySecp256k1) [Equals](/src/target/priv_key.go?s=4235:4293#L158)
|
||||
``` go
|
||||
func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeySecp256k1.MarshalJSON">func</a> (PrivKeySecp256k1) [MarshalJSON](/src/target/priv_key.go?s=4426:4481#L166)
|
||||
``` go
|
||||
func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeySecp256k1.PubKey">func</a> (PrivKeySecp256k1) [PubKey](/src/target/priv_key.go?s=4032:4079#L151)
|
||||
``` go
|
||||
func (privKey PrivKeySecp256k1) PubKey() PubKey
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeySecp256k1.Sign">func</a> (PrivKeySecp256k1) [Sign](/src/target/priv_key.go?s=3772:3830#L142)
|
||||
``` go
|
||||
func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeySecp256k1.String">func</a> (PrivKeySecp256k1) [String](/src/target/priv_key.go?s=4673:4720#L177)
|
||||
``` go
|
||||
func (privKey PrivKeySecp256k1) String() string
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PrivKeySecp256k1.UnmarshalJSON">func</a> (\*PrivKeySecp256k1) [UnmarshalJSON](/src/target/priv_key.go?s=4522:4580#L170)
|
||||
``` go
|
||||
func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="PubKey">type</a> [PubKey](/src/target/pub_key.go?s=361:506#L7)
|
||||
``` go
|
||||
type PubKey interface {
|
||||
Address() []byte
|
||||
Bytes() []byte
|
||||
KeyString() string
|
||||
VerifyBytes(msg []byte, sig Signature) bool
|
||||
Equals(PubKey) bool
|
||||
}
|
||||
```
|
||||
PubKey is part of Account and Validator.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyFromBytes">func</a> [PubKeyFromBytes](/src/target/pub_key.go?s=1203:1270#L45)
|
||||
``` go
|
||||
func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## <a name="PubKeyEd25519">type</a> [PubKeyEd25519](/src/target/pub_key.go?s=1396:1423#L53)
|
||||
``` go
|
||||
type PubKeyEd25519 [32]byte
|
||||
```
|
||||
Implements PubKey
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.Address">func</a> (PubKeyEd25519) [Address](/src/target/pub_key.go?s=1425:1469#L55)
|
||||
``` go
|
||||
func (pubKey PubKeyEd25519) Address() []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.Bytes">func</a> (PubKeyEd25519) [Bytes](/src/target/pub_key.go?s=1789:1831#L68)
|
||||
``` go
|
||||
func (pubKey PubKeyEd25519) Bytes() []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.Equals">func</a> (PubKeyEd25519) [Equals](/src/target/pub_key.go?s=3064:3117#L119)
|
||||
``` go
|
||||
func (pubKey PubKeyEd25519) Equals(other PubKey) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.KeyString">func</a> (PubKeyEd25519) [KeyString](/src/target/pub_key.go?s=2983:3029#L115)
|
||||
``` go
|
||||
func (pubKey PubKeyEd25519) KeyString() string
|
||||
```
|
||||
Must return the full bytes in hex.
|
||||
Used for map keying, etc.
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.MarshalJSON">func</a> (PubKeyEd25519) [MarshalJSON](/src/target/pub_key.go?s=2279:2331#L87)
|
||||
``` go
|
||||
func (p PubKeyEd25519) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.String">func</a> (PubKeyEd25519) [String](/src/target/pub_key.go?s=2823:2866#L109)
|
||||
``` go
|
||||
func (pubKey PubKeyEd25519) String() string
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.ToCurve25519">func</a> (PubKeyEd25519) [ToCurve25519](/src/target/pub_key.go?s=2585:2637#L100)
|
||||
``` go
|
||||
func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte
|
||||
```
|
||||
For use with golang/crypto/nacl/box
|
||||
If error, returns nil.
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.UnmarshalJSON">func</a> (\*PubKeyEd25519) [UnmarshalJSON](/src/target/pub_key.go?s=2372:2427#L91)
|
||||
``` go
|
||||
func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyEd25519.VerifyBytes">func</a> (PubKeyEd25519) [VerifyBytes](/src/target/pub_key.go?s=1888:1960#L72)
|
||||
``` go
|
||||
func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="PubKeyS">type</a> [PubKeyS](/src/target/pub_key.go?s=841:872#L25)
|
||||
``` go
|
||||
type PubKeyS struct {
|
||||
PubKey
|
||||
}
|
||||
```
|
||||
PubKeyS add json serialization to PubKey
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyS.Empty">func</a> (PubKeyS) [Empty](/src/target/pub_key.go?s=1144:1173#L41)
|
||||
``` go
|
||||
func (p PubKeyS) Empty() bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyS.MarshalJSON">func</a> (PubKeyS) [MarshalJSON](/src/target/pub_key.go?s=874:920#L29)
|
||||
``` go
|
||||
func (p PubKeyS) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeyS.UnmarshalJSON">func</a> (\*PubKeyS) [UnmarshalJSON](/src/target/pub_key.go?s=964:1020#L33)
|
||||
``` go
|
||||
func (p *PubKeyS) UnmarshalJSON(data []byte) (err error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="PubKeySecp256k1">type</a> [PubKeySecp256k1](/src/target/pub_key.go?s=3401:3430#L132)
|
||||
``` go
|
||||
type PubKeySecp256k1 [33]byte
|
||||
```
|
||||
Implements PubKey.
|
||||
Compressed pubkey (just the x-cord),
|
||||
prefixed with 0x02 or 0x03, depending on the y-cord.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.Address">func</a> (PubKeySecp256k1) [Address](/src/target/pub_key.go?s=3497:3543#L135)
|
||||
``` go
|
||||
func (pubKey PubKeySecp256k1) Address() []byte
|
||||
```
|
||||
Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.Bytes">func</a> (PubKeySecp256k1) [Bytes](/src/target/pub_key.go?s=3774:3818#L145)
|
||||
``` go
|
||||
func (pubKey PubKeySecp256k1) Bytes() []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.Equals">func</a> (PubKeySecp256k1) [Equals](/src/target/pub_key.go?s=4897:4952#L192)
|
||||
``` go
|
||||
func (pubKey PubKeySecp256k1) Equals(other PubKey) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.KeyString">func</a> (PubKeySecp256k1) [KeyString](/src/target/pub_key.go?s=4814:4862#L188)
|
||||
``` go
|
||||
func (pubKey PubKeySecp256k1) KeyString() string
|
||||
```
|
||||
Must return the full bytes in hex.
|
||||
Used for map keying, etc.
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.MarshalJSON">func</a> (PubKeySecp256k1) [MarshalJSON](/src/target/pub_key.go?s=4405:4459#L171)
|
||||
``` go
|
||||
func (p PubKeySecp256k1) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.String">func</a> (PubKeySecp256k1) [String](/src/target/pub_key.go?s=4650:4695#L182)
|
||||
``` go
|
||||
func (pubKey PubKeySecp256k1) String() string
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.UnmarshalJSON">func</a> (\*PubKeySecp256k1) [UnmarshalJSON](/src/target/pub_key.go?s=4500:4557#L175)
|
||||
``` go
|
||||
func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="PubKeySecp256k1.VerifyBytes">func</a> (PubKeySecp256k1) [VerifyBytes](/src/target/pub_key.go?s=3875:3949#L149)
|
||||
``` go
|
||||
func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="Signature">type</a> [Signature](/src/target/signature.go?s=204:304#L3)
|
||||
``` go
|
||||
type Signature interface {
|
||||
Bytes() []byte
|
||||
IsZero() bool
|
||||
String() string
|
||||
Equals(Signature) bool
|
||||
}
|
||||
```
|
||||
Signature is a part of Txs and consensus Votes.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureFromBytes">func</a> [SignatureFromBytes](/src/target/signature.go?s=1031:1098#L40)
|
||||
``` go
|
||||
func SignatureFromBytes(sigBytes []byte) (sig Signature, err error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## <a name="SignatureEd25519">type</a> [SignatureEd25519](/src/target/signature.go?s=1221:1251#L48)
|
||||
``` go
|
||||
type SignatureEd25519 [64]byte
|
||||
```
|
||||
Implements Signature
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureEd25519.Bytes">func</a> (SignatureEd25519) [Bytes](/src/target/signature.go?s=1253:1295#L50)
|
||||
``` go
|
||||
func (sig SignatureEd25519) Bytes() []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureEd25519.Equals">func</a> (SignatureEd25519) [Equals](/src/target/signature.go?s=1520:1576#L58)
|
||||
``` go
|
||||
func (sig SignatureEd25519) Equals(other Signature) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureEd25519.IsZero">func</a> (SignatureEd25519) [IsZero](/src/target/signature.go?s=1352:1393#L54)
|
||||
``` go
|
||||
func (sig SignatureEd25519) IsZero() bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureEd25519.MarshalJSON">func</a> (SignatureEd25519) [MarshalJSON](/src/target/signature.go?s=1701:1756#L66)
|
||||
``` go
|
||||
func (p SignatureEd25519) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureEd25519.String">func</a> (SignatureEd25519) [String](/src/target/signature.go?s=1420:1463#L56)
|
||||
``` go
|
||||
func (sig SignatureEd25519) String() string
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureEd25519.UnmarshalJSON">func</a> (\*SignatureEd25519) [UnmarshalJSON](/src/target/signature.go?s=1797:1855#L70)
|
||||
``` go
|
||||
func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="SignatureS">type</a> [SignatureS](/src/target/signature.go?s=648:685#L20)
|
||||
``` go
|
||||
type SignatureS struct {
|
||||
Signature
|
||||
}
|
||||
```
|
||||
SignatureS add json serialization to Signature
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureS.Empty">func</a> (SignatureS) [Empty](/src/target/signature.go?s=966:998#L36)
|
||||
``` go
|
||||
func (p SignatureS) Empty() bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureS.MarshalJSON">func</a> (SignatureS) [MarshalJSON](/src/target/signature.go?s=687:736#L24)
|
||||
``` go
|
||||
func (p SignatureS) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureS.UnmarshalJSON">func</a> (\*SignatureS) [UnmarshalJSON](/src/target/signature.go?s=780:839#L28)
|
||||
``` go
|
||||
func (p *SignatureS) UnmarshalJSON(data []byte) (err error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## <a name="SignatureSecp256k1">type</a> [SignatureSecp256k1](/src/target/signature.go?s=2013:2043#L80)
|
||||
``` go
|
||||
type SignatureSecp256k1 []byte
|
||||
```
|
||||
Implements Signature
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureSecp256k1.Bytes">func</a> (SignatureSecp256k1) [Bytes](/src/target/signature.go?s=2045:2089#L82)
|
||||
``` go
|
||||
func (sig SignatureSecp256k1) Bytes() []byte
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureSecp256k1.Equals">func</a> (SignatureSecp256k1) [Equals](/src/target/signature.go?s=2318:2376#L90)
|
||||
``` go
|
||||
func (sig SignatureSecp256k1) Equals(other Signature) bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureSecp256k1.IsZero">func</a> (SignatureSecp256k1) [IsZero](/src/target/signature.go?s=2146:2189#L86)
|
||||
``` go
|
||||
func (sig SignatureSecp256k1) IsZero() bool
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureSecp256k1.MarshalJSON">func</a> (SignatureSecp256k1) [MarshalJSON](/src/target/signature.go?s=2502:2559#L97)
|
||||
``` go
|
||||
func (p SignatureSecp256k1) MarshalJSON() ([]byte, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureSecp256k1.String">func</a> (SignatureSecp256k1) [String](/src/target/signature.go?s=2216:2261#L88)
|
||||
``` go
|
||||
func (sig SignatureSecp256k1) String() string
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <a name="SignatureSecp256k1.UnmarshalJSON">func</a> (\*SignatureSecp256k1) [UnmarshalJSON](/src/target/signature.go?s=2597:2657#L101)
|
||||
``` go
|
||||
func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- - -
|
||||
Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
|
||||
@@ -0,0 +1,39 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"golang.org/x/crypto/openpgp/armor"
|
||||
)
|
||||
|
||||
func EncodeArmor(blockType string, headers map[string]string, data []byte) string {
|
||||
buf := new(bytes.Buffer)
|
||||
w, err := armor.Encode(buf, blockType, headers)
|
||||
if err != nil {
|
||||
PanicSanity("Error encoding ascii armor: " + err.Error())
|
||||
}
|
||||
_, err = w.Write(data)
|
||||
if err != nil {
|
||||
PanicSanity("Error encoding ascii armor: " + err.Error())
|
||||
}
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
PanicSanity("Error encoding ascii armor: " + err.Error())
|
||||
}
|
||||
return string(buf.Bytes())
|
||||
}
|
||||
|
||||
func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error) {
|
||||
buf := bytes.NewBufferString(armorStr)
|
||||
block, err := armor.Decode(buf)
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
}
|
||||
data, err = ioutil.ReadAll(block.Body)
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
}
|
||||
return block.Type, block.Header, data, nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSimpleArmor(t *testing.T) {
|
||||
blockType := "MINT TEST"
|
||||
data := []byte("somedata")
|
||||
armorStr := EncodeArmor(blockType, nil, data)
|
||||
|
||||
// Decode armorStr and test for equivalence.
|
||||
blockType2, _, data2, err := DecodeArmor(armorStr)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.Equal(t, blockType, blockType2)
|
||||
assert.Equal(t, data, data2)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bcrypt
|
||||
|
||||
import "encoding/base64"
|
||||
|
||||
const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
|
||||
var bcEncoding = base64.NewEncoding(alphabet)
|
||||
|
||||
func base64Encode(src []byte) []byte {
|
||||
n := bcEncoding.EncodedLen(len(src))
|
||||
dst := make([]byte, n)
|
||||
bcEncoding.Encode(dst, src)
|
||||
for dst[n-1] == '=' {
|
||||
n--
|
||||
}
|
||||
return dst[:n]
|
||||
}
|
||||
|
||||
func base64Decode(src []byte) ([]byte, error) {
|
||||
numOfEquals := 4 - (len(src) % 4)
|
||||
for i := 0; i < numOfEquals; i++ {
|
||||
src = append(src, '=')
|
||||
}
|
||||
|
||||
dst := make([]byte, bcEncoding.DecodedLen(len(src)))
|
||||
n, err := bcEncoding.Decode(dst, src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dst[:n], nil
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
package bcrypt
|
||||
|
||||
// MODIFIED BY TENDERMINT TO EXPOSE NONCE
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
|
||||
// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
|
||||
|
||||
// The code is a port of Provos and Mazières's C implementation.
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/blowfish"
|
||||
)
|
||||
|
||||
const (
|
||||
MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
|
||||
MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
|
||||
DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
|
||||
)
|
||||
|
||||
// The error returned from CompareHashAndPassword when a password and hash do
|
||||
// not match.
|
||||
var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash is too short to
|
||||
// be a bcrypt hash.
|
||||
var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash was created with
|
||||
// a bcrypt algorithm newer than this implementation.
|
||||
type HashVersionTooNewError byte
|
||||
|
||||
func (hv HashVersionTooNewError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
|
||||
}
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
|
||||
type InvalidHashPrefixError byte
|
||||
|
||||
func (ih InvalidHashPrefixError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
|
||||
}
|
||||
|
||||
type InvalidCostError int
|
||||
|
||||
func (ic InvalidCostError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
|
||||
}
|
||||
|
||||
const (
|
||||
majorVersion = '2'
|
||||
minorVersion = 'a'
|
||||
maxSaltSize = 16
|
||||
maxCryptedHashSize = 23
|
||||
encodedSaltSize = 22
|
||||
encodedHashSize = 31
|
||||
minHashSize = 59
|
||||
)
|
||||
|
||||
// magicCipherData is an IV for the 64 Blowfish encryption calls in
|
||||
// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
|
||||
var magicCipherData = []byte{
|
||||
0x4f, 0x72, 0x70, 0x68,
|
||||
0x65, 0x61, 0x6e, 0x42,
|
||||
0x65, 0x68, 0x6f, 0x6c,
|
||||
0x64, 0x65, 0x72, 0x53,
|
||||
0x63, 0x72, 0x79, 0x44,
|
||||
0x6f, 0x75, 0x62, 0x74,
|
||||
}
|
||||
|
||||
type hashed struct {
|
||||
hash []byte
|
||||
salt []byte
|
||||
cost int // allowed range is MinCost to MaxCost
|
||||
major byte
|
||||
minor byte
|
||||
}
|
||||
|
||||
// GenerateFromPassword returns the bcrypt hash of the password at the given
|
||||
// cost. If the cost given is less than MinCost, the cost will be set to
|
||||
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
|
||||
// to compare the returned hashed password with its cleartext version.
|
||||
func GenerateFromPassword(salt []byte, password []byte, cost int) ([]byte, error) {
|
||||
if len(salt) != maxSaltSize {
|
||||
return nil, fmt.Errorf("Salt len must be %v", maxSaltSize)
|
||||
}
|
||||
p, err := newFromPassword(salt, password, cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.Hash(), nil
|
||||
}
|
||||
|
||||
// CompareHashAndPassword compares a bcrypt hashed password with its possible
|
||||
// plaintext equivalent. Returns nil on success, or an error on failure.
|
||||
func CompareHashAndPassword(hashedPassword, password []byte) error {
|
||||
p, err := newFromHash(hashedPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
otherHash, err := bcrypt(password, p.cost, p.salt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
|
||||
if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ErrMismatchedHashAndPassword
|
||||
}
|
||||
|
||||
// Cost returns the hashing cost used to create the given hashed
|
||||
// password. When, in the future, the hashing cost of a password system needs
|
||||
// to be increased in order to adjust for greater computational power, this
|
||||
// function allows one to establish which passwords need to be updated.
|
||||
func Cost(hashedPassword []byte) (int, error) {
|
||||
p, err := newFromHash(hashedPassword)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return p.cost, nil
|
||||
}
|
||||
|
||||
func newFromPassword(salt []byte, password []byte, cost int) (*hashed, error) {
|
||||
if cost < MinCost {
|
||||
cost = DefaultCost
|
||||
}
|
||||
p := new(hashed)
|
||||
p.major = majorVersion
|
||||
p.minor = minorVersion
|
||||
|
||||
err := checkCost(cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.cost = cost
|
||||
|
||||
p.salt = base64Encode(salt)
|
||||
hash, err := bcrypt(password, p.cost, p.salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.hash = hash
|
||||
return p, err
|
||||
}
|
||||
|
||||
func newFromHash(hashedSecret []byte) (*hashed, error) {
|
||||
if len(hashedSecret) < minHashSize {
|
||||
return nil, ErrHashTooShort
|
||||
}
|
||||
p := new(hashed)
|
||||
n, err := p.decodeVersion(hashedSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hashedSecret = hashedSecret[n:]
|
||||
n, err = p.decodeCost(hashedSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hashedSecret = hashedSecret[n:]
|
||||
|
||||
// The "+2" is here because we'll have to append at most 2 '=' to the salt
|
||||
// when base64 decoding it in expensiveBlowfishSetup().
|
||||
p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
|
||||
copy(p.salt, hashedSecret[:encodedSaltSize])
|
||||
|
||||
hashedSecret = hashedSecret[encodedSaltSize:]
|
||||
p.hash = make([]byte, len(hashedSecret))
|
||||
copy(p.hash, hashedSecret)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
|
||||
cipherData := make([]byte, len(magicCipherData))
|
||||
copy(cipherData, magicCipherData)
|
||||
|
||||
c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < 24; i += 8 {
|
||||
for j := 0; j < 64; j++ {
|
||||
c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
|
||||
}
|
||||
}
|
||||
|
||||
// Bug compatibility with C bcrypt implementations. We only encode 23 of
|
||||
// the 24 bytes encrypted.
|
||||
hsh := base64Encode(cipherData[:maxCryptedHashSize])
|
||||
return hsh, nil
|
||||
}
|
||||
|
||||
func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
|
||||
|
||||
csalt, err := base64Decode(salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Bug compatibility with C bcrypt implementations. They use the trailing
|
||||
// NULL in the key string during expansion.
|
||||
ckey := append(key, 0)
|
||||
|
||||
c, err := blowfish.NewSaltedCipher(ckey, csalt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var i, rounds uint64
|
||||
rounds = 1 << cost
|
||||
for i = 0; i < rounds; i++ {
|
||||
blowfish.ExpandKey(ckey, c)
|
||||
blowfish.ExpandKey(csalt, c)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (p *hashed) Hash() []byte {
|
||||
arr := make([]byte, 60)
|
||||
arr[0] = '$'
|
||||
arr[1] = p.major
|
||||
n := 2
|
||||
if p.minor != 0 {
|
||||
arr[2] = p.minor
|
||||
n = 3
|
||||
}
|
||||
arr[n] = '$'
|
||||
n += 1
|
||||
copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
|
||||
n += 2
|
||||
arr[n] = '$'
|
||||
n += 1
|
||||
copy(arr[n:], p.salt)
|
||||
n += encodedSaltSize
|
||||
copy(arr[n:], p.hash)
|
||||
n += encodedHashSize
|
||||
return arr[:n]
|
||||
}
|
||||
|
||||
func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
|
||||
if sbytes[0] != '$' {
|
||||
return -1, InvalidHashPrefixError(sbytes[0])
|
||||
}
|
||||
if sbytes[1] > majorVersion {
|
||||
return -1, HashVersionTooNewError(sbytes[1])
|
||||
}
|
||||
p.major = sbytes[1]
|
||||
n := 3
|
||||
if sbytes[2] != '$' {
|
||||
p.minor = sbytes[2]
|
||||
n++
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// sbytes should begin where decodeVersion left off.
|
||||
func (p *hashed) decodeCost(sbytes []byte) (int, error) {
|
||||
cost, err := strconv.Atoi(string(sbytes[0:2]))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
err = checkCost(cost)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
p.cost = cost
|
||||
return 3, nil
|
||||
}
|
||||
|
||||
func (p *hashed) String() string {
|
||||
return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
|
||||
}
|
||||
|
||||
func checkCost(cost int) error {
|
||||
if cost < MinCost || cost > MaxCost {
|
||||
return InvalidCostError(cost)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package crypto
|
||||
|
||||
// Types of implementations
|
||||
const (
|
||||
TypeEd25519 = byte(0x01)
|
||||
TypeSecp256k1 = byte(0x02)
|
||||
NameEd25519 = "ed25519"
|
||||
NameSecp256k1 = "secp256k1"
|
||||
)
|
||||
@@ -0,0 +1,91 @@
|
||||
package crypto_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
)
|
||||
|
||||
type PubName struct {
|
||||
PubNameInner
|
||||
}
|
||||
|
||||
type PubNameInner interface {
|
||||
AssertIsPubNameInner()
|
||||
String() string
|
||||
}
|
||||
|
||||
func (p PubName) MarshalJSON() ([]byte, error) {
|
||||
return pubNameMapper.ToJSON(p.PubNameInner)
|
||||
}
|
||||
|
||||
func (p *PubName) UnmarshalJSON(data []byte) error {
|
||||
parsed, err := pubNameMapper.FromJSON(data)
|
||||
if err == nil && parsed != nil {
|
||||
p.PubNameInner = parsed.(PubNameInner)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var pubNameMapper = data.NewMapper(PubName{}).
|
||||
RegisterImplementation(PubNameFoo{}, "foo", 1).
|
||||
RegisterImplementation(PubNameBar{}, "bar", 2)
|
||||
|
||||
func (f PubNameFoo) AssertIsPubNameInner() {}
|
||||
func (f PubNameBar) AssertIsPubNameInner() {}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
type PubNameFoo struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (f PubNameFoo) String() string { return "Foo: " + f.Name }
|
||||
|
||||
type PubNameBar struct {
|
||||
Age int
|
||||
}
|
||||
|
||||
func (b PubNameBar) String() string { return fmt.Sprintf("Bar #%d", b.Age) }
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// TestEncodeDemo tries the various strategies to encode the objects
|
||||
func TestEncodeDemo(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
cases := []struct {
|
||||
in, out PubNameInner
|
||||
expected string
|
||||
}{
|
||||
{PubName{PubNameFoo{"pub-foo"}}, &PubName{}, "Foo: pub-foo"},
|
||||
{PubName{PubNameBar{7}}, &PubName{}, "Bar #7"},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
|
||||
// Make sure it is proper to start
|
||||
require.Equal(tc.expected, tc.in.String())
|
||||
|
||||
// Try to encode as binary
|
||||
b, err := data.ToWire(tc.in)
|
||||
if assert.Nil(err, "%d: %#v", i, tc.in) {
|
||||
err := data.FromWire(b, tc.out)
|
||||
if assert.Nil(err) {
|
||||
assert.Equal(tc.expected, tc.out.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Try to encode it as json
|
||||
j, err := data.ToJSON(tc.in)
|
||||
if assert.Nil(err, "%d: %#v", i, tc.in) {
|
||||
err := data.FromJSON(j, tc.out)
|
||||
if assert.Nil(err) {
|
||||
assert.Equal(tc.expected, tc.out.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
type byter interface {
|
||||
Bytes() []byte
|
||||
}
|
||||
|
||||
// go to wire encoding and back
|
||||
func checkWire(t *testing.T, in byter, reader interface{}, typ byte, size int) {
|
||||
// test to and from binary
|
||||
bin, err := data.ToWire(in)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.Equal(t, typ, bin[0])
|
||||
// make sure this is compatible with current (Bytes()) encoding
|
||||
assert.Equal(t, in.Bytes(), bin)
|
||||
// make sure we have the expected length
|
||||
assert.Equal(t, size, len(bin))
|
||||
|
||||
err = data.FromWire(bin, reader)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
}
|
||||
|
||||
// go to json encoding and back
|
||||
func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) {
|
||||
// test to and from binary
|
||||
js, err := data.ToJSON(in)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
styp := `"` + typ + `"`
|
||||
assert.True(t, strings.Contains(string(js), styp))
|
||||
|
||||
err = data.FromJSON(js, reader)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
|
||||
// also check text format
|
||||
text, err := data.ToText(in)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
parts := strings.Split(text, ":")
|
||||
require.Equal(t, 2, len(parts))
|
||||
// make sure the first part is the typ string
|
||||
assert.Equal(t, typ, parts[0])
|
||||
// and the data is also present in the json
|
||||
assert.True(t, strings.Contains(string(js), parts[1]))
|
||||
}
|
||||
|
||||
// make sure go-wire json can still figure this out...
|
||||
func checkWireJSON(t *testing.T, in interface{}, reader interface{}, typ byte) {
|
||||
// test to and from binary
|
||||
var err error
|
||||
js := wire.JSONBytes(in)
|
||||
btyp := fmt.Sprintf("[%d,", typ)
|
||||
assert.True(t, strings.HasPrefix(string(js), btyp), string(js))
|
||||
|
||||
wire.ReadJSON(reader, js, &err)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
}
|
||||
|
||||
func TestKeyEncodings(t *testing.T) {
|
||||
cases := []struct {
|
||||
privKey PrivKey
|
||||
keyType byte
|
||||
keyName string
|
||||
// 1 (type byte) + size of byte array
|
||||
privSize, pubSize int
|
||||
}{
|
||||
{
|
||||
privKey: GenPrivKeyEd25519().Wrap(),
|
||||
keyType: TypeEd25519,
|
||||
keyName: NameEd25519,
|
||||
privSize: 65,
|
||||
pubSize: 33,
|
||||
},
|
||||
{
|
||||
privKey: GenPrivKeySecp256k1().Wrap(),
|
||||
keyType: TypeSecp256k1,
|
||||
keyName: NameSecp256k1,
|
||||
privSize: 33,
|
||||
pubSize: 34,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
// check (de/en)codings of private key
|
||||
var priv2, priv3, priv4 PrivKey
|
||||
checkWire(t, tc.privKey, &priv2, tc.keyType, tc.privSize)
|
||||
assert.EqualValues(t, tc.privKey, priv2)
|
||||
checkJSON(t, tc.privKey, &priv3, tc.keyName)
|
||||
assert.EqualValues(t, tc.privKey, priv3)
|
||||
checkWireJSON(t, tc.privKey, &priv4, tc.keyType)
|
||||
assert.EqualValues(t, tc.privKey, priv4)
|
||||
|
||||
// check (de/en)codings of public key
|
||||
pubKey := tc.privKey.PubKey()
|
||||
var pub2, pub3, pub4 PubKey
|
||||
checkWire(t, pubKey, &pub2, tc.keyType, tc.pubSize)
|
||||
assert.EqualValues(t, pubKey, pub2)
|
||||
checkJSON(t, pubKey, &pub3, tc.keyName)
|
||||
assert.EqualValues(t, pubKey, pub3)
|
||||
checkWireJSON(t, pubKey, &pub4, tc.keyType)
|
||||
assert.EqualValues(t, pubKey, pub4)
|
||||
}
|
||||
}
|
||||
|
||||
func toFromJSON(t *testing.T, in interface{}, recvr interface{}) {
|
||||
js, err := data.ToJSON(in)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
err = data.FromJSON(js, recvr)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
}
|
||||
|
||||
func TestNilEncodings(t *testing.T) {
|
||||
// make sure sigs are okay with nil
|
||||
var a, b Signature
|
||||
toFromJSON(t, a, &b)
|
||||
assert.EqualValues(t, a, b)
|
||||
|
||||
// make sure sigs are okay with nil
|
||||
var c, d PubKey
|
||||
toFromJSON(t, c, &d)
|
||||
assert.EqualValues(t, c, d)
|
||||
|
||||
// make sure sigs are okay with nil
|
||||
var e, f PrivKey
|
||||
toFromJSON(t, e, &f)
|
||||
assert.EqualValues(t, e, f)
|
||||
|
||||
}
|
||||
|
||||
type SigMessage struct {
|
||||
Key PubKey
|
||||
Sig Signature
|
||||
}
|
||||
|
||||
func (s SigMessage) Bytes() []byte {
|
||||
return wire.BinaryBytes(s)
|
||||
}
|
||||
|
||||
func TestEmbededWireEncodings(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cases := []struct {
|
||||
privKey PrivKey
|
||||
keyType byte
|
||||
keyName string
|
||||
size int // pub + sig size
|
||||
}{
|
||||
{
|
||||
privKey: GenPrivKeyEd25519().Wrap(),
|
||||
keyType: TypeEd25519,
|
||||
keyName: NameEd25519,
|
||||
size: 2 + 32 + 64,
|
||||
},
|
||||
// {
|
||||
// privKey: GenPrivKeySecp256k1().Wrap(),
|
||||
// keyType: TypeSecp256k1,
|
||||
// keyName: NameSecp256k1,
|
||||
// size: 2 + 33 + 72, // ugh, either 72 or 73 depending....
|
||||
// },
|
||||
}
|
||||
|
||||
payload := randBytes(20)
|
||||
for i, tc := range cases {
|
||||
pubKey := tc.privKey.PubKey()
|
||||
sig := tc.privKey.Sign(payload)
|
||||
assert.True(pubKey.VerifyBytes(payload, sig), "%d", i)
|
||||
|
||||
msg := SigMessage{
|
||||
Key: pubKey,
|
||||
Sig: sig,
|
||||
}
|
||||
var msg2 SigMessage
|
||||
checkWire(t, msg, &msg2, tc.keyType, tc.size)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package: github.com/tendermint/go-crypto
|
||||
import:
|
||||
- package: github.com/btcsuite/btcd
|
||||
subpackages:
|
||||
- btcec
|
||||
- package: github.com/btcsuite/btcutil
|
||||
subpackages:
|
||||
- base58
|
||||
- package: github.com/tendermint/ed25519
|
||||
subpackages:
|
||||
- extra25519
|
||||
- package: github.com/tendermint/tmlibs
|
||||
version: unstable
|
||||
- package: github.com/tendermint/go-wire
|
||||
version: unstable
|
||||
- package: golang.org/x/crypto
|
||||
subpackages:
|
||||
- blowfish
|
||||
- nacl/secretbox
|
||||
- openpgp/armor
|
||||
- ripemd160
|
||||
testImport:
|
||||
- package: github.com/mndrix/btcutil
|
||||
- package: github.com/stretchr/testify
|
||||
version: ^1.1.4
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
- package: github.com/tyler-smith/go-bip32
|
||||
- package: github.com/tyler-smith/go-bip39
|
||||
@@ -0,0 +1,18 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
func Sha256(bytes []byte) []byte {
|
||||
hasher := sha256.New()
|
||||
hasher.Write(bytes)
|
||||
return hasher.Sum(nil)
|
||||
}
|
||||
|
||||
func Ripemd160(bytes []byte) []byte {
|
||||
hasher := ripemd160.New()
|
||||
hasher.Write(bytes)
|
||||
return hasher.Sum(nil)
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
package hd
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"log"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcutil/base58"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
func ComputeAddress(pubKeyHex string, chainHex string, path string, index int32) string {
|
||||
pubKeyBytes := DerivePublicKeyForPath(
|
||||
HexDecode(pubKeyHex),
|
||||
HexDecode(chainHex),
|
||||
fmt.Sprintf("%v/%v", path, index),
|
||||
)
|
||||
return AddrFromPubKeyBytes(pubKeyBytes)
|
||||
}
|
||||
|
||||
func ComputePrivateKey(mprivHex string, chainHex string, path string, index int32) string {
|
||||
privKeyBytes := DerivePrivateKeyForPath(
|
||||
HexDecode(mprivHex),
|
||||
HexDecode(chainHex),
|
||||
fmt.Sprintf("%v/%v", path, index),
|
||||
)
|
||||
return HexEncode(privKeyBytes)
|
||||
}
|
||||
|
||||
func ComputeAddressForPrivKey(privKey string) string {
|
||||
pubKeyBytes := PubKeyBytesFromPrivKeyBytes(HexDecode(privKey), true)
|
||||
return AddrFromPubKeyBytes(pubKeyBytes)
|
||||
}
|
||||
|
||||
func SignMessage(privKey string, message string, compress bool) string {
|
||||
prefixBytes := []byte("Bitcoin Signed Message:\n")
|
||||
messageBytes := []byte(message)
|
||||
bytes := []byte{}
|
||||
bytes = append(bytes, byte(len(prefixBytes)))
|
||||
bytes = append(bytes, prefixBytes...)
|
||||
bytes = append(bytes, byte(len(messageBytes)))
|
||||
bytes = append(bytes, messageBytes...)
|
||||
privKeyBytes := HexDecode(privKey)
|
||||
x, y := btcec.S256().ScalarBaseMult(privKeyBytes)
|
||||
ecdsaPubKey := ecdsa.PublicKey{
|
||||
Curve: btcec.S256(),
|
||||
X: x,
|
||||
Y: y,
|
||||
}
|
||||
ecdsaPrivKey := &btcec.PrivateKey{
|
||||
PublicKey: ecdsaPubKey,
|
||||
D: new(big.Int).SetBytes(privKeyBytes),
|
||||
}
|
||||
sigbytes, err := btcec.SignCompact(btcec.S256(), ecdsaPrivKey, crypto.Sha256(crypto.Sha256(bytes)), compress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(sigbytes)
|
||||
}
|
||||
|
||||
// returns MPK, Chain, and master secret in hex.
|
||||
func ComputeMastersFromSeed(seed string) (string, string, string, string) {
|
||||
secret, chain := I64([]byte("Bitcoin seed"), []byte(seed))
|
||||
pubKeyBytes := PubKeyBytesFromPrivKeyBytes(secret, true)
|
||||
return HexEncode(pubKeyBytes), HexEncode(secret), HexEncode(chain), HexEncode(secret)
|
||||
}
|
||||
|
||||
func ComputeWIF(privKey string, compress bool) string {
|
||||
return WIFFromPrivKeyBytes(HexDecode(privKey), compress)
|
||||
}
|
||||
|
||||
func ComputeTxId(rawTxHex string) string {
|
||||
return HexEncode(ReverseBytes(CalcHash256(HexDecode(rawTxHex))))
|
||||
}
|
||||
|
||||
// Private methods...
|
||||
|
||||
func printKeyInfo(privKeyBytes []byte, pubKeyBytes []byte, chain []byte) {
|
||||
if pubKeyBytes == nil {
|
||||
pubKeyBytes = PubKeyBytesFromPrivKeyBytes(privKeyBytes, true)
|
||||
}
|
||||
addr := AddrFromPubKeyBytes(pubKeyBytes)
|
||||
log.Println("\nprikey:\t%v\npubKeyBytes:\t%v\naddr:\t%v\nchain:\t%v",
|
||||
HexEncode(privKeyBytes),
|
||||
HexEncode(pubKeyBytes),
|
||||
addr,
|
||||
HexEncode(chain))
|
||||
}
|
||||
|
||||
func DerivePrivateKeyForPath(privKeyBytes []byte, chain []byte, path string) []byte {
|
||||
data := privKeyBytes
|
||||
parts := strings.Split(path, "/")
|
||||
for _, part := range parts {
|
||||
prime := part[len(part)-1:] == "'"
|
||||
// prime == private derivation. Otherwise public.
|
||||
if prime {
|
||||
part = part[:len(part)-1]
|
||||
}
|
||||
i, err := strconv.Atoi(part)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if i < 0 {
|
||||
panic(errors.New("index too large."))
|
||||
}
|
||||
data, chain = DerivePrivateKey(data, chain, uint32(i), prime)
|
||||
//printKeyInfo(data, nil, chain)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func DerivePublicKeyForPath(pubKeyBytes []byte, chain []byte, path string) []byte {
|
||||
data := pubKeyBytes
|
||||
parts := strings.Split(path, "/")
|
||||
for _, part := range parts {
|
||||
prime := part[len(part)-1:] == "'"
|
||||
if prime {
|
||||
panic(errors.New("cannot do a prime derivation from public key"))
|
||||
}
|
||||
i, err := strconv.Atoi(part)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if i < 0 {
|
||||
panic(errors.New("index too large."))
|
||||
}
|
||||
data, chain = DerivePublicKey(data, chain, uint32(i))
|
||||
//printKeyInfo(nil, data, chain)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func DerivePrivateKey(privKeyBytes []byte, chain []byte, i uint32, prime bool) ([]byte, []byte) {
|
||||
data := []byte{}
|
||||
if prime {
|
||||
i = i | 0x80000000
|
||||
data = append([]byte{byte(0)}, privKeyBytes...)
|
||||
} else {
|
||||
public := PubKeyBytesFromPrivKeyBytes(privKeyBytes, true)
|
||||
data = public
|
||||
}
|
||||
data = append(data, uint32ToBytes(i)...)
|
||||
data2, chain2 := I64(chain, data)
|
||||
x := addScalars(privKeyBytes, data2)
|
||||
return x, chain2
|
||||
}
|
||||
|
||||
func DerivePublicKey(pubKeyBytes []byte, chain []byte, i uint32) ([]byte, []byte) {
|
||||
data := []byte{}
|
||||
data = append(data, pubKeyBytes...)
|
||||
data = append(data, uint32ToBytes(i)...)
|
||||
data2, chain2 := I64(chain, data)
|
||||
data2p := PubKeyBytesFromPrivKeyBytes(data2, true)
|
||||
return addPoints(pubKeyBytes, data2p), chain2
|
||||
}
|
||||
|
||||
func addPoints(a []byte, b []byte) []byte {
|
||||
ap, err := btcec.ParsePubKey(a, btcec.S256())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bp, err := btcec.ParsePubKey(b, btcec.S256())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sumX, sumY := btcec.S256().Add(ap.X, ap.Y, bp.X, bp.Y)
|
||||
sum := (*btcec.PublicKey)(&btcec.PublicKey{
|
||||
Curve: btcec.S256(),
|
||||
X: sumX,
|
||||
Y: sumY,
|
||||
})
|
||||
return sum.SerializeCompressed()
|
||||
}
|
||||
|
||||
func addScalars(a []byte, b []byte) []byte {
|
||||
aInt := new(big.Int).SetBytes(a)
|
||||
bInt := new(big.Int).SetBytes(b)
|
||||
sInt := new(big.Int).Add(aInt, bInt)
|
||||
x := sInt.Mod(sInt, btcec.S256().N).Bytes()
|
||||
x2 := [32]byte{}
|
||||
copy(x2[32-len(x):], x)
|
||||
return x2[:]
|
||||
}
|
||||
|
||||
func uint32ToBytes(i uint32) []byte {
|
||||
b := [4]byte{}
|
||||
binary.BigEndian.PutUint32(b[:], i)
|
||||
return b[:]
|
||||
}
|
||||
|
||||
func HexEncode(b []byte) string {
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
func HexDecode(str string) []byte {
|
||||
b, _ := hex.DecodeString(str)
|
||||
return b
|
||||
}
|
||||
|
||||
func I64(key []byte, data []byte) ([]byte, []byte) {
|
||||
mac := hmac.New(sha512.New, key)
|
||||
mac.Write(data)
|
||||
I := mac.Sum(nil)
|
||||
return I[:32], I[32:]
|
||||
}
|
||||
|
||||
// This returns a Bitcoin-like address.
|
||||
func AddrFromPubKeyBytes(pubKeyBytes []byte) string {
|
||||
prefix := byte(0x00) // TODO Make const or configurable
|
||||
h160 := CalcHash160(pubKeyBytes)
|
||||
h160 = append([]byte{prefix}, h160...)
|
||||
checksum := CalcHash256(h160)
|
||||
b := append(h160, checksum[:4]...)
|
||||
return base58.Encode(b)
|
||||
}
|
||||
|
||||
func AddrBytesFromPubKeyBytes(pubKeyBytes []byte) (addrBytes []byte, checksum []byte) {
|
||||
prefix := byte(0x00) // TODO Make const or configurable
|
||||
h160 := CalcHash160(pubKeyBytes)
|
||||
_h160 := append([]byte{prefix}, h160...)
|
||||
checksum = CalcHash256(_h160)[:4]
|
||||
return h160, checksum
|
||||
}
|
||||
|
||||
func WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string {
|
||||
prefix := byte(0x80) // TODO Make const or configurable
|
||||
bytes := append([]byte{prefix}, privKeyBytes...)
|
||||
if compress {
|
||||
bytes = append(bytes, byte(1))
|
||||
}
|
||||
checksum := CalcHash256(bytes)
|
||||
bytes = append(bytes, checksum[:4]...)
|
||||
return base58.Encode(bytes)
|
||||
}
|
||||
|
||||
func PubKeyBytesFromPrivKeyBytes(privKeyBytes []byte, compress bool) (pubKeyBytes []byte) {
|
||||
x, y := btcec.S256().ScalarBaseMult(privKeyBytes)
|
||||
pub := (*btcec.PublicKey)(&btcec.PublicKey{
|
||||
Curve: btcec.S256(),
|
||||
X: x,
|
||||
Y: y,
|
||||
})
|
||||
|
||||
if compress {
|
||||
return pub.SerializeCompressed()
|
||||
}
|
||||
return pub.SerializeUncompressed()
|
||||
}
|
||||
|
||||
// Calculate the hash of hasher over buf.
|
||||
func CalcHash(buf []byte, hasher hash.Hash) []byte {
|
||||
hasher.Write(buf)
|
||||
return hasher.Sum(nil)
|
||||
}
|
||||
|
||||
// calculate hash160 which is ripemd160(sha256(data))
|
||||
func CalcHash160(buf []byte) []byte {
|
||||
return CalcHash(CalcHash(buf, sha256.New()), ripemd160.New())
|
||||
}
|
||||
|
||||
// calculate hash256 which is sha256(sha256(data))
|
||||
func CalcHash256(buf []byte) []byte {
|
||||
return CalcHash(CalcHash(buf, sha256.New()), sha256.New())
|
||||
}
|
||||
|
||||
// calculate sha512(data)
|
||||
func CalcSha512(buf []byte) []byte {
|
||||
return CalcHash(buf, sha512.New())
|
||||
}
|
||||
|
||||
func ReverseBytes(buf []byte) []byte {
|
||||
res := []byte{}
|
||||
for i := len(buf) - 1; i >= 0; i-- {
|
||||
res = append(res, buf[i])
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package hd
|
||||
|
||||
/*
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestManual(t *testing.T) {
|
||||
bytes, _ := hex.DecodeString("dfac699f1618c9be4df2befe94dc5f313946ebafa386756bd4926a1ecfd7cf2438426ede521d1ee6512391bc200b7910bcbea593e68d52b874c29bdc5a308ed1")
|
||||
fmt.Println(bytes)
|
||||
puk, prk, ch, se := ComputeMastersFromSeed(string(bytes))
|
||||
fmt.Println(puk, ch, se)
|
||||
|
||||
pubBytes2 := DerivePublicKeyForPath(
|
||||
HexDecode(puk),
|
||||
HexDecode(ch),
|
||||
//"44'/118'/0'/0/0",
|
||||
"0/0",
|
||||
)
|
||||
fmt.Printf("PUB2 %X\n", pubBytes2)
|
||||
|
||||
privBytes := DerivePrivateKeyForPath(
|
||||
HexDecode(prk),
|
||||
HexDecode(ch),
|
||||
//"44'/118'/0'/0/0",
|
||||
//"0/0",
|
||||
"44'/118'/0'/0/0",
|
||||
)
|
||||
fmt.Printf("PRIV %X\n", privBytes)
|
||||
pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true)
|
||||
fmt.Printf("PUB %X\n", pubBytes)
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,189 @@
|
||||
package hd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha512"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tyler-smith/go-bip39"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcutil/hdkeychain"
|
||||
"github.com/mndrix/btcutil"
|
||||
"github.com/tyler-smith/go-bip32"
|
||||
|
||||
"github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
type addrData struct {
|
||||
Mnemonic string
|
||||
Master string
|
||||
Seed string
|
||||
Priv string
|
||||
Pub string
|
||||
Addr string
|
||||
}
|
||||
|
||||
// NOTE: atom fundraiser address
|
||||
var hdPath string = "m/44'/118'/0'/0/0"
|
||||
var hdToAddrTable []addrData
|
||||
|
||||
func init() {
|
||||
|
||||
b, err := ioutil.ReadFile("test.json")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &hdToAddrTable)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHDToAddr(t *testing.T) {
|
||||
|
||||
for i, d := range hdToAddrTable {
|
||||
privB, _ := hex.DecodeString(d.Priv)
|
||||
pubB, _ := hex.DecodeString(d.Pub)
|
||||
addrB, _ := hex.DecodeString(d.Addr)
|
||||
seedB, _ := hex.DecodeString(d.Seed)
|
||||
masterB, _ := hex.DecodeString(d.Master)
|
||||
|
||||
seed := bip39.NewSeed(d.Mnemonic, "")
|
||||
|
||||
fmt.Println("================================")
|
||||
fmt.Println("ROUND:", i, "MNEMONIC:", d.Mnemonic)
|
||||
|
||||
// master, priv, pub := tylerSmith(seed)
|
||||
// master, priv, pub := btcsuite(seed)
|
||||
master, priv, pub := gocrypto(seed)
|
||||
|
||||
fmt.Printf("\tNODEJS GOLANG\n")
|
||||
fmt.Printf("SEED \t%X %X\n", seedB, seed)
|
||||
fmt.Printf("MSTR \t%X %X\n", masterB, master)
|
||||
fmt.Printf("PRIV \t%X %X\n", privB, priv)
|
||||
fmt.Printf("PUB \t%X %X\n", pubB, pub)
|
||||
_, _ = priv, privB
|
||||
|
||||
assert.Equal(t, master, masterB, fmt.Sprintf("Expected masters to match for %d", i))
|
||||
assert.Equal(t, priv, privB, "Expected priv keys to match")
|
||||
assert.Equal(t, pub, pubB, fmt.Sprintf("Expected pub keys to match for %d", i))
|
||||
|
||||
var pubT crypto.PubKeySecp256k1
|
||||
copy(pubT[:], pub)
|
||||
addr := pubT.Address()
|
||||
fmt.Printf("ADDR \t%X %X\n", addrB, addr)
|
||||
assert.Equal(t, addr, addrB, fmt.Sprintf("Expected addresses to match %d", i))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func ifExit(err error, n int) {
|
||||
if err != nil {
|
||||
fmt.Println(n, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func gocrypto(seed []byte) ([]byte, []byte, []byte) {
|
||||
|
||||
_, priv, ch, _ := ComputeMastersFromSeed(string(seed))
|
||||
|
||||
privBytes := DerivePrivateKeyForPath(
|
||||
HexDecode(priv),
|
||||
HexDecode(ch),
|
||||
"44'/118'/0'/0/0",
|
||||
)
|
||||
|
||||
pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true)
|
||||
|
||||
return HexDecode(priv), privBytes, pubBytes
|
||||
}
|
||||
|
||||
func btcsuite(seed []byte) ([]byte, []byte, []byte) {
|
||||
fmt.Println("HD")
|
||||
masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
hmac := hmac.New(sha512.New, []byte("Bitcoin seed"))
|
||||
hmac.Write([]byte(seed))
|
||||
intermediary := hmac.Sum(nil)
|
||||
|
||||
curve := btcutil.Secp256k1()
|
||||
curveParams := curve.Params()
|
||||
|
||||
// Split it into our key and chain code
|
||||
keyBytes := intermediary[:32]
|
||||
fmt.Printf("\t%X\n", keyBytes)
|
||||
fmt.Printf("\t%X\n", curveParams.N.Bytes())
|
||||
keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes))
|
||||
fmt.Printf("\t%d\n", keyInt)
|
||||
}
|
||||
fh := hdkeychain.HardenedKeyStart
|
||||
k, err := masterKey.Child(uint32(fh + 44))
|
||||
ifExit(err, 44)
|
||||
k, err = k.Child(uint32(fh + 118))
|
||||
ifExit(err, 118)
|
||||
k, err = k.Child(uint32(fh + 0))
|
||||
ifExit(err, 1)
|
||||
k, err = k.Child(uint32(0))
|
||||
ifExit(err, 2)
|
||||
k, err = k.Child(uint32(0))
|
||||
ifExit(err, 3)
|
||||
ecpriv, err := k.ECPrivKey()
|
||||
ifExit(err, 10)
|
||||
ecpub, err := k.ECPubKey()
|
||||
ifExit(err, 11)
|
||||
|
||||
priv := ecpriv.Serialize()
|
||||
pub := ecpub.SerializeCompressed()
|
||||
mkey, _ := masterKey.ECPrivKey()
|
||||
return mkey.Serialize(), priv, pub
|
||||
}
|
||||
|
||||
// return priv and pub
|
||||
func tylerSmith(seed []byte) ([]byte, []byte, []byte) {
|
||||
masterKey, err := bip32.NewMasterKey(seed)
|
||||
if err != nil {
|
||||
hmac := hmac.New(sha512.New, []byte("Bitcoin seed"))
|
||||
hmac.Write([]byte(seed))
|
||||
intermediary := hmac.Sum(nil)
|
||||
|
||||
curve := btcutil.Secp256k1()
|
||||
curveParams := curve.Params()
|
||||
|
||||
// Split it into our key and chain code
|
||||
keyBytes := intermediary[:32]
|
||||
fmt.Printf("\t%X\n", keyBytes)
|
||||
fmt.Printf("\t%X\n", curveParams.N.Bytes())
|
||||
keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes))
|
||||
fmt.Printf("\t%d\n", keyInt)
|
||||
|
||||
}
|
||||
ifExit(err, 0)
|
||||
fh := bip32.FirstHardenedChild
|
||||
k, err := masterKey.NewChildKey(fh + 44)
|
||||
ifExit(err, 44)
|
||||
k, err = k.NewChildKey(fh + 118)
|
||||
ifExit(err, 118)
|
||||
k, err = k.NewChildKey(fh + 0)
|
||||
ifExit(err, 1)
|
||||
k, err = k.NewChildKey(0)
|
||||
ifExit(err, 2)
|
||||
k, err = k.NewChildKey(0)
|
||||
ifExit(err, 3)
|
||||
|
||||
priv := k.Key
|
||||
pub := k.PublicKey().Key
|
||||
return masterKey.Key, priv, pub
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,237 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
secp256k1 "github.com/btcsuite/btcd/btcec"
|
||||
"github.com/tendermint/ed25519"
|
||||
"github.com/tendermint/ed25519/extra25519"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) {
|
||||
err = wire.ReadBinaryBytes(privKeyBytes, &privKey)
|
||||
return
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
type PrivKey struct {
|
||||
PrivKeyInner `json:"unwrap"`
|
||||
}
|
||||
|
||||
// DO NOT USE THIS INTERFACE.
|
||||
// You probably want to use PubKey
|
||||
type PrivKeyInner interface {
|
||||
AssertIsPrivKeyInner()
|
||||
Bytes() []byte
|
||||
Sign(msg []byte) Signature
|
||||
PubKey() PubKey
|
||||
Equals(PrivKey) bool
|
||||
Wrap() PrivKey
|
||||
}
|
||||
|
||||
func (p PrivKey) MarshalJSON() ([]byte, error) {
|
||||
return privKeyMapper.ToJSON(p.PrivKeyInner)
|
||||
}
|
||||
|
||||
func (p *PrivKey) UnmarshalJSON(data []byte) (err error) {
|
||||
parsed, err := privKeyMapper.FromJSON(data)
|
||||
if err == nil && parsed != nil {
|
||||
p.PrivKeyInner = parsed.(PrivKeyInner)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Unwrap recovers the concrete interface safely (regardless of levels of embeds)
|
||||
func (p PrivKey) Unwrap() PrivKeyInner {
|
||||
pk := p.PrivKeyInner
|
||||
for wrap, ok := pk.(PrivKey); ok; wrap, ok = pk.(PrivKey) {
|
||||
pk = wrap.PrivKeyInner
|
||||
}
|
||||
return pk
|
||||
}
|
||||
|
||||
func (p PrivKey) Empty() bool {
|
||||
return p.PrivKeyInner == nil
|
||||
}
|
||||
|
||||
var privKeyMapper = data.NewMapper(PrivKey{}).
|
||||
RegisterImplementation(PrivKeyEd25519{}, NameEd25519, TypeEd25519).
|
||||
RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1)
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
var _ PrivKeyInner = PrivKeyEd25519{}
|
||||
|
||||
// Implements PrivKey
|
||||
type PrivKeyEd25519 [64]byte
|
||||
|
||||
func (privKey PrivKeyEd25519) AssertIsPrivKeyInner() {}
|
||||
|
||||
func (privKey PrivKeyEd25519) Bytes() []byte {
|
||||
return wire.BinaryBytes(PrivKey{privKey})
|
||||
}
|
||||
|
||||
func (privKey PrivKeyEd25519) Sign(msg []byte) Signature {
|
||||
privKeyBytes := [64]byte(privKey)
|
||||
signatureBytes := ed25519.Sign(&privKeyBytes, msg)
|
||||
return SignatureEd25519(*signatureBytes).Wrap()
|
||||
}
|
||||
|
||||
func (privKey PrivKeyEd25519) PubKey() PubKey {
|
||||
privKeyBytes := [64]byte(privKey)
|
||||
pubBytes := *ed25519.MakePublicKey(&privKeyBytes)
|
||||
return PubKeyEd25519(pubBytes).Wrap()
|
||||
}
|
||||
|
||||
func (privKey PrivKeyEd25519) Equals(other PrivKey) bool {
|
||||
if otherEd, ok := other.Unwrap().(PrivKeyEd25519); ok {
|
||||
return bytes.Equal(privKey[:], otherEd[:])
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (p PrivKeyEd25519) MarshalJSON() ([]byte, error) {
|
||||
return data.Encoder.Marshal(p[:])
|
||||
}
|
||||
|
||||
func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error {
|
||||
var ref []byte
|
||||
err := data.Encoder.Unmarshal(&ref, enc)
|
||||
copy(p[:], ref)
|
||||
return err
|
||||
}
|
||||
|
||||
func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte {
|
||||
keyCurve25519 := new([32]byte)
|
||||
privKeyBytes := [64]byte(privKey)
|
||||
extra25519.PrivateKeyToCurve25519(keyCurve25519, &privKeyBytes)
|
||||
return keyCurve25519
|
||||
}
|
||||
|
||||
func (privKey PrivKeyEd25519) String() string {
|
||||
return Fmt("PrivKeyEd25519{*****}")
|
||||
}
|
||||
|
||||
// Deterministically generates new priv-key bytes from key.
|
||||
func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 {
|
||||
newBytes := wire.BinarySha256(struct {
|
||||
PrivKey [64]byte
|
||||
Index int
|
||||
}{privKey, index})
|
||||
var newKey [64]byte
|
||||
copy(newKey[:], newBytes)
|
||||
return PrivKeyEd25519(newKey)
|
||||
}
|
||||
|
||||
func (privKey PrivKeyEd25519) Wrap() PrivKey {
|
||||
return PrivKey{privKey}
|
||||
}
|
||||
|
||||
func GenPrivKeyEd25519() PrivKeyEd25519 {
|
||||
privKeyBytes := new([64]byte)
|
||||
copy(privKeyBytes[:32], CRandBytes(32))
|
||||
ed25519.MakePublicKey(privKeyBytes)
|
||||
return PrivKeyEd25519(*privKeyBytes)
|
||||
}
|
||||
|
||||
// NOTE: secret should be the output of a KDF like bcrypt,
|
||||
// if it's derived from user input.
|
||||
func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 {
|
||||
privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes.
|
||||
privKeyBytes := new([64]byte)
|
||||
copy(privKeyBytes[:32], privKey32)
|
||||
ed25519.MakePublicKey(privKeyBytes)
|
||||
return PrivKeyEd25519(*privKeyBytes)
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
var _ PrivKeyInner = PrivKeySecp256k1{}
|
||||
|
||||
// Implements PrivKey
|
||||
type PrivKeySecp256k1 [32]byte
|
||||
|
||||
func (privKey PrivKeySecp256k1) AssertIsPrivKeyInner() {}
|
||||
|
||||
func (privKey PrivKeySecp256k1) Bytes() []byte {
|
||||
return wire.BinaryBytes(PrivKey{privKey})
|
||||
}
|
||||
|
||||
func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature {
|
||||
priv__, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
|
||||
sig__, err := priv__.Sign(Sha256(msg))
|
||||
if err != nil {
|
||||
PanicSanity(err)
|
||||
}
|
||||
return SignatureSecp256k1(sig__.Serialize()).Wrap()
|
||||
}
|
||||
|
||||
func (privKey PrivKeySecp256k1) PubKey() PubKey {
|
||||
_, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
|
||||
var pub PubKeySecp256k1
|
||||
copy(pub[:], pub__.SerializeCompressed())
|
||||
return pub.Wrap()
|
||||
}
|
||||
|
||||
func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool {
|
||||
if otherSecp, ok := other.Unwrap().(PrivKeySecp256k1); ok {
|
||||
return bytes.Equal(privKey[:], otherSecp[:])
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error) {
|
||||
return data.Encoder.Marshal(p[:])
|
||||
}
|
||||
|
||||
func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error {
|
||||
var ref []byte
|
||||
err := data.Encoder.Unmarshal(&ref, enc)
|
||||
copy(p[:], ref)
|
||||
return err
|
||||
}
|
||||
|
||||
func (privKey PrivKeySecp256k1) String() string {
|
||||
return Fmt("PrivKeySecp256k1{*****}")
|
||||
}
|
||||
|
||||
func (privKey PrivKeySecp256k1) Wrap() PrivKey {
|
||||
return PrivKey{privKey}
|
||||
}
|
||||
|
||||
/*
|
||||
// Deterministically generates new priv-key bytes from key.
|
||||
func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 {
|
||||
newBytes := wire.BinarySha256(struct {
|
||||
PrivKey [64]byte
|
||||
Index int
|
||||
}{key, index})
|
||||
var newKey [64]byte
|
||||
copy(newKey[:], newBytes)
|
||||
return PrivKeySecp256k1(newKey)
|
||||
}
|
||||
*/
|
||||
|
||||
func GenPrivKeySecp256k1() PrivKeySecp256k1 {
|
||||
privKeyBytes := [32]byte{}
|
||||
copy(privKeyBytes[:], CRandBytes(32))
|
||||
priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKeyBytes[:])
|
||||
copy(privKeyBytes[:], priv.Serialize())
|
||||
return PrivKeySecp256k1(privKeyBytes)
|
||||
}
|
||||
|
||||
// NOTE: secret should be the output of a KDF like bcrypt,
|
||||
// if it's derived from user input.
|
||||
func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 {
|
||||
privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes.
|
||||
priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey32)
|
||||
privKeyBytes := [32]byte{}
|
||||
copy(privKeyBytes[:], priv.Serialize())
|
||||
return PrivKeySecp256k1(privKeyBytes)
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
|
||||
secp256k1 "github.com/btcsuite/btcd/btcec"
|
||||
"github.com/tendermint/ed25519"
|
||||
"github.com/tendermint/ed25519/extra25519"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/go-wire"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) {
|
||||
err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey)
|
||||
return
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
type PubKey struct {
|
||||
PubKeyInner `json:"unwrap"`
|
||||
}
|
||||
|
||||
// DO NOT USE THIS INTERFACE.
|
||||
// You probably want to use PubKey
|
||||
type PubKeyInner interface {
|
||||
AssertIsPubKeyInner()
|
||||
Address() []byte
|
||||
Bytes() []byte
|
||||
KeyString() string
|
||||
VerifyBytes(msg []byte, sig Signature) bool
|
||||
Equals(PubKey) bool
|
||||
Wrap() PubKey
|
||||
}
|
||||
|
||||
func (pk PubKey) MarshalJSON() ([]byte, error) {
|
||||
return pubKeyMapper.ToJSON(pk.PubKeyInner)
|
||||
}
|
||||
|
||||
func (pk *PubKey) UnmarshalJSON(data []byte) (err error) {
|
||||
parsed, err := pubKeyMapper.FromJSON(data)
|
||||
if err == nil && parsed != nil {
|
||||
pk.PubKeyInner = parsed.(PubKeyInner)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Unwrap recovers the concrete interface safely (regardless of levels of embeds)
|
||||
func (pk PubKey) Unwrap() PubKeyInner {
|
||||
pkI := pk.PubKeyInner
|
||||
for wrap, ok := pkI.(PubKey); ok; wrap, ok = pkI.(PubKey) {
|
||||
pkI = wrap.PubKeyInner
|
||||
}
|
||||
return pkI
|
||||
}
|
||||
|
||||
func (p PubKey) Empty() bool {
|
||||
return p.PubKeyInner == nil
|
||||
}
|
||||
|
||||
var pubKeyMapper = data.NewMapper(PubKey{}).
|
||||
RegisterImplementation(PubKeyEd25519{}, NameEd25519, TypeEd25519).
|
||||
RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1)
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
var _ PubKeyInner = PubKeyEd25519{}
|
||||
|
||||
// Implements PubKeyInner
|
||||
type PubKeyEd25519 [32]byte
|
||||
|
||||
func (pubKey PubKeyEd25519) AssertIsPubKeyInner() {}
|
||||
|
||||
func (pubKey PubKeyEd25519) Address() []byte {
|
||||
w, n, err := new(bytes.Buffer), new(int), new(error)
|
||||
wire.WriteBinary(pubKey[:], w, n, err)
|
||||
if *err != nil {
|
||||
PanicCrisis(*err)
|
||||
}
|
||||
// append type byte
|
||||
encodedPubkey := append([]byte{TypeEd25519}, w.Bytes()...)
|
||||
hasher := ripemd160.New()
|
||||
hasher.Write(encodedPubkey) // does not error
|
||||
return hasher.Sum(nil)
|
||||
}
|
||||
|
||||
func (pubKey PubKeyEd25519) Bytes() []byte {
|
||||
return wire.BinaryBytes(PubKey{pubKey})
|
||||
}
|
||||
|
||||
func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
|
||||
// make sure we use the same algorithm to sign
|
||||
sig, ok := sig_.Unwrap().(SignatureEd25519)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
pubKeyBytes := [32]byte(pubKey)
|
||||
sigBytes := [64]byte(sig)
|
||||
return ed25519.Verify(&pubKeyBytes, msg, &sigBytes)
|
||||
}
|
||||
|
||||
func (p PubKeyEd25519) MarshalJSON() ([]byte, error) {
|
||||
return data.Encoder.Marshal(p[:])
|
||||
}
|
||||
|
||||
func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error {
|
||||
var ref []byte
|
||||
err := data.Encoder.Unmarshal(&ref, enc)
|
||||
copy(p[:], ref)
|
||||
return err
|
||||
}
|
||||
|
||||
// For use with golang/crypto/nacl/box
|
||||
// If error, returns nil.
|
||||
func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte {
|
||||
keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey)
|
||||
ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return keyCurve25519
|
||||
}
|
||||
|
||||
func (pubKey PubKeyEd25519) String() string {
|
||||
return Fmt("PubKeyEd25519{%X}", pubKey[:])
|
||||
}
|
||||
|
||||
// Must return the full bytes in hex.
|
||||
// Used for map keying, etc.
|
||||
func (pubKey PubKeyEd25519) KeyString() string {
|
||||
return Fmt("%X", pubKey[:])
|
||||
}
|
||||
|
||||
func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
|
||||
if otherEd, ok := other.Unwrap().(PubKeyEd25519); ok {
|
||||
return bytes.Equal(pubKey[:], otherEd[:])
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (pubKey PubKeyEd25519) Wrap() PubKey {
|
||||
return PubKey{pubKey}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
var _ PubKeyInner = PubKeySecp256k1{}
|
||||
|
||||
// Implements PubKey.
|
||||
// Compressed pubkey (just the x-cord),
|
||||
// prefixed with 0x02 or 0x03, depending on the y-cord.
|
||||
type PubKeySecp256k1 [33]byte
|
||||
|
||||
func (pubKey PubKeySecp256k1) AssertIsPubKeyInner() {}
|
||||
|
||||
// Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
|
||||
func (pubKey PubKeySecp256k1) Address() []byte {
|
||||
hasherSHA256 := sha256.New()
|
||||
hasherSHA256.Write(pubKey[:]) // does not error
|
||||
sha := hasherSHA256.Sum(nil)
|
||||
|
||||
hasherRIPEMD160 := ripemd160.New()
|
||||
hasherRIPEMD160.Write(sha) // does not error
|
||||
return hasherRIPEMD160.Sum(nil)
|
||||
}
|
||||
|
||||
func (pubKey PubKeySecp256k1) Bytes() []byte {
|
||||
return wire.BinaryBytes(PubKey{pubKey})
|
||||
}
|
||||
|
||||
func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool {
|
||||
// and assert same algorithm to sign and verify
|
||||
sig, ok := sig_.Unwrap().(SignatureSecp256k1)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return sig__.Verify(Sha256(msg), pub__)
|
||||
}
|
||||
|
||||
func (p PubKeySecp256k1) MarshalJSON() ([]byte, error) {
|
||||
return data.Encoder.Marshal(p[:])
|
||||
}
|
||||
|
||||
func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error {
|
||||
var ref []byte
|
||||
err := data.Encoder.Unmarshal(&ref, enc)
|
||||
copy(p[:], ref)
|
||||
return err
|
||||
}
|
||||
|
||||
func (pubKey PubKeySecp256k1) String() string {
|
||||
return Fmt("PubKeySecp256k1{%X}", pubKey[:])
|
||||
}
|
||||
|
||||
// Must return the full bytes in hex.
|
||||
// Used for map keying, etc.
|
||||
func (pubKey PubKeySecp256k1) KeyString() string {
|
||||
return Fmt("%X", pubKey[:])
|
||||
}
|
||||
|
||||
func (pubKey PubKeySecp256k1) Equals(other PubKey) bool {
|
||||
if otherSecp, ok := other.Unwrap().(PubKeySecp256k1); ok {
|
||||
return bytes.Equal(pubKey[:], otherSecp[:])
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (pubKey PubKeySecp256k1) Wrap() PubKey {
|
||||
return PubKey{pubKey}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcutil/base58"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type keyData struct {
|
||||
priv string
|
||||
pub string
|
||||
addr string
|
||||
}
|
||||
|
||||
var secpDataTable = []keyData{
|
||||
{
|
||||
priv: "a96e62ed3955e65be32703f12d87b6b5cf26039ecfa948dc5107a495418e5330",
|
||||
pub: "02950e1cdfcb133d6024109fd489f734eeb4502418e538c28481f22bce276f248c",
|
||||
addr: "1CKZ9Nx4zgds8tU7nJHotKSDr4a9bYJCa3",
|
||||
},
|
||||
}
|
||||
|
||||
func TestPubKeySecp256k1Address(t *testing.T) {
|
||||
for _, d := range secpDataTable {
|
||||
privB, _ := hex.DecodeString(d.priv)
|
||||
pubB, _ := hex.DecodeString(d.pub)
|
||||
addrB, _, _ := base58.CheckDecode(d.addr)
|
||||
|
||||
var priv PrivKeySecp256k1
|
||||
copy(priv[:], privB)
|
||||
|
||||
pubT := priv.PubKey().Unwrap().(PubKeySecp256k1)
|
||||
pub := pubT[:]
|
||||
addr := priv.PubKey().Address()
|
||||
|
||||
assert.Equal(t, pub, pubB, "Expected pub keys to match")
|
||||
assert.Equal(t, addr, addrB, "Expected addresses to match")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
crand "crypto/rand"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
var gRandInfo *randInfo
|
||||
|
||||
func init() {
|
||||
gRandInfo = &randInfo{}
|
||||
gRandInfo.MixEntropy(randBytes(32)) // Init
|
||||
}
|
||||
|
||||
// Mix additional bytes of randomness, e.g. from hardware, user-input, etc.
|
||||
// It is OK to call it multiple times. It does not diminish security.
|
||||
func MixEntropy(seedBytes []byte) {
|
||||
gRandInfo.MixEntropy(seedBytes)
|
||||
}
|
||||
|
||||
// This only uses the OS's randomness
|
||||
func randBytes(numBytes int) []byte {
|
||||
b := make([]byte, numBytes)
|
||||
_, err := crand.Read(b)
|
||||
if err != nil {
|
||||
PanicCrisis(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// This uses the OS and the Seed(s).
|
||||
func CRandBytes(numBytes int) []byte {
|
||||
b := make([]byte, numBytes)
|
||||
_, err := gRandInfo.Read(b)
|
||||
if err != nil {
|
||||
PanicCrisis(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// RandHex(24) gives 96 bits of randomness, strong enough for most purposes.
|
||||
func CRandHex(numDigits int) string {
|
||||
return hex.EncodeToString(CRandBytes(numDigits / 2))
|
||||
}
|
||||
|
||||
// Returns a crand.Reader mixed with user-supplied entropy
|
||||
func CReader() io.Reader {
|
||||
return gRandInfo
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
type randInfo struct {
|
||||
mtx sync.Mutex
|
||||
seedBytes [32]byte
|
||||
cipherAES256 cipher.Block
|
||||
streamAES256 cipher.Stream
|
||||
reader io.Reader
|
||||
}
|
||||
|
||||
// You can call this as many times as you'd like.
|
||||
// XXX TODO review
|
||||
func (ri *randInfo) MixEntropy(seedBytes []byte) {
|
||||
ri.mtx.Lock()
|
||||
defer ri.mtx.Unlock()
|
||||
// Make new ri.seedBytes
|
||||
hashBytes := Sha256(seedBytes)
|
||||
hashBytes32 := [32]byte{}
|
||||
copy(hashBytes32[:], hashBytes)
|
||||
ri.seedBytes = xorBytes32(ri.seedBytes, hashBytes32)
|
||||
// Create new cipher.Block
|
||||
var err error
|
||||
ri.cipherAES256, err = aes.NewCipher(ri.seedBytes[:])
|
||||
if err != nil {
|
||||
PanicSanity("Error creating AES256 cipher: " + err.Error())
|
||||
}
|
||||
// Create new stream
|
||||
ri.streamAES256 = cipher.NewCTR(ri.cipherAES256, randBytes(aes.BlockSize))
|
||||
// Create new reader
|
||||
ri.reader = &cipher.StreamReader{S: ri.streamAES256, R: crand.Reader}
|
||||
}
|
||||
|
||||
func (ri *randInfo) Read(b []byte) (n int, err error) {
|
||||
ri.mtx.Lock()
|
||||
defer ri.mtx.Unlock()
|
||||
return ri.reader.Read(b)
|
||||
}
|
||||
|
||||
func xorBytes32(bytesA [32]byte, bytesB [32]byte) (res [32]byte) {
|
||||
for i, b := range bytesA {
|
||||
res[i] = b ^ bytesB[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) {
|
||||
err = wire.ReadBinaryBytes(sigBytes, &sig)
|
||||
return
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
type Signature struct {
|
||||
SignatureInner `json:"unwrap"`
|
||||
}
|
||||
|
||||
// DO NOT USE THIS INTERFACE.
|
||||
// You probably want to use Signature.
|
||||
type SignatureInner interface {
|
||||
AssertIsSignatureInner()
|
||||
Bytes() []byte
|
||||
IsZero() bool
|
||||
String() string
|
||||
Equals(Signature) bool
|
||||
Wrap() Signature
|
||||
}
|
||||
|
||||
func (sig Signature) MarshalJSON() ([]byte, error) {
|
||||
return sigMapper.ToJSON(sig.SignatureInner)
|
||||
}
|
||||
|
||||
func (sig *Signature) UnmarshalJSON(data []byte) (err error) {
|
||||
parsed, err := sigMapper.FromJSON(data)
|
||||
if err == nil && parsed != nil {
|
||||
sig.SignatureInner = parsed.(SignatureInner)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Unwrap recovers the concrete interface safely (regardless of levels of embeds)
|
||||
func (sig Signature) Unwrap() SignatureInner {
|
||||
pk := sig.SignatureInner
|
||||
for wrap, ok := pk.(Signature); ok; wrap, ok = pk.(Signature) {
|
||||
pk = wrap.SignatureInner
|
||||
}
|
||||
return pk
|
||||
}
|
||||
|
||||
func (sig Signature) Empty() bool {
|
||||
return sig.SignatureInner == nil
|
||||
}
|
||||
|
||||
var sigMapper = data.NewMapper(Signature{}).
|
||||
RegisterImplementation(SignatureEd25519{}, NameEd25519, TypeEd25519).
|
||||
RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1)
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
var _ SignatureInner = SignatureEd25519{}
|
||||
|
||||
// Implements Signature
|
||||
type SignatureEd25519 [64]byte
|
||||
|
||||
func (sig SignatureEd25519) AssertIsSignatureInner() {}
|
||||
|
||||
func (sig SignatureEd25519) Bytes() []byte {
|
||||
return wire.BinaryBytes(Signature{sig})
|
||||
}
|
||||
|
||||
func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }
|
||||
|
||||
func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) }
|
||||
|
||||
func (sig SignatureEd25519) Equals(other Signature) bool {
|
||||
if otherEd, ok := other.Unwrap().(SignatureEd25519); ok {
|
||||
return bytes.Equal(sig[:], otherEd[:])
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (sig SignatureEd25519) MarshalJSON() ([]byte, error) {
|
||||
return data.Encoder.Marshal(sig[:])
|
||||
}
|
||||
|
||||
func (sig *SignatureEd25519) UnmarshalJSON(enc []byte) error {
|
||||
var ref []byte
|
||||
err := data.Encoder.Unmarshal(&ref, enc)
|
||||
copy(sig[:], ref)
|
||||
return err
|
||||
}
|
||||
|
||||
func (sig SignatureEd25519) Wrap() Signature {
|
||||
return Signature{sig}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
var _ SignatureInner = SignatureSecp256k1{}
|
||||
|
||||
// Implements Signature
|
||||
type SignatureSecp256k1 []byte
|
||||
|
||||
func (sig SignatureSecp256k1) AssertIsSignatureInner() {}
|
||||
|
||||
func (sig SignatureSecp256k1) Bytes() []byte {
|
||||
return wire.BinaryBytes(Signature{sig})
|
||||
}
|
||||
|
||||
func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 }
|
||||
|
||||
func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) }
|
||||
|
||||
func (sig SignatureSecp256k1) Equals(other Signature) bool {
|
||||
if otherEd, ok := other.Unwrap().(SignatureSecp256k1); ok {
|
||||
return bytes.Equal(sig[:], otherEd[:])
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
func (sig SignatureSecp256k1) MarshalJSON() ([]byte, error) {
|
||||
return data.Encoder.Marshal(sig)
|
||||
}
|
||||
|
||||
func (sig *SignatureSecp256k1) UnmarshalJSON(enc []byte) error {
|
||||
return data.Encoder.Unmarshal((*[]byte)(sig), enc)
|
||||
}
|
||||
|
||||
func (sig SignatureSecp256k1) Wrap() Signature {
|
||||
return Signature{sig}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/ed25519"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
)
|
||||
|
||||
func TestSignAndValidateEd25519(t *testing.T) {
|
||||
|
||||
privKey := GenPrivKeyEd25519()
|
||||
pubKey := privKey.PubKey()
|
||||
|
||||
msg := CRandBytes(128)
|
||||
sig := privKey.Sign(msg)
|
||||
|
||||
// Test the signature
|
||||
assert.True(t, pubKey.VerifyBytes(msg, sig))
|
||||
|
||||
// Mutate the signature, just one bit.
|
||||
sigEd := sig.Unwrap().(SignatureEd25519)
|
||||
sigEd[7] ^= byte(0x01)
|
||||
sig = sigEd.Wrap()
|
||||
|
||||
assert.False(t, pubKey.VerifyBytes(msg, sig))
|
||||
}
|
||||
|
||||
func TestSignAndValidateSecp256k1(t *testing.T) {
|
||||
privKey := GenPrivKeySecp256k1()
|
||||
pubKey := privKey.PubKey()
|
||||
|
||||
msg := CRandBytes(128)
|
||||
sig := privKey.Sign(msg)
|
||||
|
||||
assert.True(t, pubKey.VerifyBytes(msg, sig))
|
||||
|
||||
// Mutate the signature, just one bit.
|
||||
sigEd := sig.Unwrap().(SignatureSecp256k1)
|
||||
sigEd[3] ^= byte(0x01)
|
||||
sig = sigEd.Wrap()
|
||||
|
||||
assert.False(t, pubKey.VerifyBytes(msg, sig))
|
||||
}
|
||||
|
||||
func TestSignatureEncodings(t *testing.T) {
|
||||
cases := []struct {
|
||||
privKey PrivKey
|
||||
sigSize int
|
||||
sigType byte
|
||||
sigName string
|
||||
}{
|
||||
{
|
||||
privKey: GenPrivKeyEd25519().Wrap(),
|
||||
sigSize: ed25519.SignatureSize,
|
||||
sigType: TypeEd25519,
|
||||
sigName: NameEd25519,
|
||||
},
|
||||
{
|
||||
privKey: GenPrivKeySecp256k1().Wrap(),
|
||||
sigSize: 0, // unknown
|
||||
sigType: TypeSecp256k1,
|
||||
sigName: NameSecp256k1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
// note we embed them from the beginning....
|
||||
pubKey := tc.privKey.PubKey()
|
||||
|
||||
msg := CRandBytes(128)
|
||||
sig := tc.privKey.Sign(msg)
|
||||
|
||||
// store as wire
|
||||
bin, err := data.ToWire(sig)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
if tc.sigSize != 0 {
|
||||
assert.Equal(t, tc.sigSize+1, len(bin))
|
||||
}
|
||||
assert.Equal(t, tc.sigType, bin[0])
|
||||
|
||||
// and back
|
||||
sig2 := Signature{}
|
||||
err = data.FromWire(bin, &sig2)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.EqualValues(t, sig, sig2)
|
||||
assert.True(t, pubKey.VerifyBytes(msg, sig2))
|
||||
|
||||
// store as json
|
||||
js, err := data.ToJSON(sig)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.True(t, strings.Contains(string(js), tc.sigName))
|
||||
|
||||
// and back
|
||||
sig3 := Signature{}
|
||||
err = data.FromJSON(js, &sig3)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.EqualValues(t, sig, sig3)
|
||||
assert.True(t, pubKey.VerifyBytes(msg, sig3))
|
||||
|
||||
// and make sure we can textify it
|
||||
text, err := data.ToText(sig)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.True(t, strings.HasPrefix(text, tc.sigName))
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrapping(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
// construct some basic constructs
|
||||
msg := CRandBytes(128)
|
||||
priv := GenPrivKeyEd25519()
|
||||
pub := priv.PubKey()
|
||||
sig := priv.Sign(msg)
|
||||
|
||||
// do some wrapping
|
||||
pubs := []PubKey{
|
||||
PubKey{nil},
|
||||
pub.Wrap(),
|
||||
pub.Wrap().Wrap().Wrap(),
|
||||
PubKey{PubKey{PubKey{pub}}}.Wrap(),
|
||||
}
|
||||
for _, p := range pubs {
|
||||
_, ok := p.PubKeyInner.(PubKey)
|
||||
assert.False(ok)
|
||||
}
|
||||
|
||||
sigs := []Signature{
|
||||
Signature{nil},
|
||||
sig.Wrap(),
|
||||
sig.Wrap().Wrap().Wrap(),
|
||||
Signature{Signature{Signature{sig}}}.Wrap(),
|
||||
}
|
||||
for _, s := range sigs {
|
||||
_, ok := s.SignatureInner.(Signature)
|
||||
assert.False(ok)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"golang.org/x/crypto/nacl/secretbox"
|
||||
)
|
||||
|
||||
const nonceLen = 24
|
||||
const secretLen = 32
|
||||
|
||||
// secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
|
||||
// The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
|
||||
// NOTE: call crypto.MixEntropy() first.
|
||||
func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) {
|
||||
if len(secret) != secretLen {
|
||||
PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
|
||||
}
|
||||
nonce := CRandBytes(nonceLen)
|
||||
nonceArr := [nonceLen]byte{}
|
||||
copy(nonceArr[:], nonce)
|
||||
secretArr := [secretLen]byte{}
|
||||
copy(secretArr[:], secret)
|
||||
ciphertext = make([]byte, nonceLen+secretbox.Overhead+len(plaintext))
|
||||
copy(ciphertext, nonce)
|
||||
secretbox.Seal(ciphertext[nonceLen:nonceLen], plaintext, &nonceArr, &secretArr)
|
||||
return ciphertext
|
||||
}
|
||||
|
||||
// secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
|
||||
// The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
|
||||
func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error) {
|
||||
if len(secret) != secretLen {
|
||||
PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
|
||||
}
|
||||
if len(ciphertext) <= secretbox.Overhead+nonceLen {
|
||||
return nil, errors.New("Ciphertext is too short")
|
||||
}
|
||||
nonce := ciphertext[:nonceLen]
|
||||
nonceArr := [nonceLen]byte{}
|
||||
copy(nonceArr[:], nonce)
|
||||
secretArr := [secretLen]byte{}
|
||||
copy(secretArr[:], secret)
|
||||
plaintext = make([]byte, len(ciphertext)-nonceLen-secretbox.Overhead)
|
||||
_, ok := secretbox.Open(plaintext[:0], ciphertext[nonceLen:], &nonceArr, &secretArr)
|
||||
if !ok {
|
||||
return nil, errors.New("Ciphertext decryption failed")
|
||||
}
|
||||
return plaintext, nil
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func TestSimple(t *testing.T) {
|
||||
|
||||
MixEntropy([]byte("someentropy"))
|
||||
|
||||
plaintext := []byte("sometext")
|
||||
secret := []byte("somesecretoflengththirtytwo===32")
|
||||
ciphertext := EncryptSymmetric(plaintext, secret)
|
||||
plaintext2, err := DecryptSymmetric(ciphertext, secret)
|
||||
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.Equal(t, plaintext, plaintext2)
|
||||
}
|
||||
|
||||
func TestSimpleWithKDF(t *testing.T) {
|
||||
|
||||
MixEntropy([]byte("someentropy"))
|
||||
|
||||
plaintext := []byte("sometext")
|
||||
secretPass := []byte("somesecret")
|
||||
secret, err := bcrypt.GenerateFromPassword(secretPass, 12)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
secret = Sha256(secret)
|
||||
|
||||
ciphertext := EncryptSymmetric(plaintext, secret)
|
||||
plaintext2, err := DecryptSymmetric(ciphertext, secret)
|
||||
|
||||
require.Nil(t, err, "%+v", err)
|
||||
assert.Equal(t, plaintext, plaintext2)
|
||||
}
|
||||
Reference in New Issue
Block a user