@ -44,21 +44,40 @@ func init() {
Ed25519SignatureAminoRoute , nil )
}
// Implements crypto.PrivKey
// PrivKeyEd25519 implements crypto.PrivKey.
type PrivKeyEd25519 [ 64 ] byte
// Bytes marshals the privkey using amino encoding.
func ( privKey PrivKeyEd25519 ) Bytes ( ) [ ] byte {
return cdc . MustMarshalBinaryBare ( privKey )
}
// Sign produces a signature on the provided message.
func ( privKey PrivKeyEd25519 ) Sign ( msg [ ] byte ) ( crypto . Signature , error ) {
privKeyBytes := [ 64 ] byte ( privKey )
signatureBytes := ed25519 . Sign ( & privKeyBytes , msg )
return SignatureEd25519 ( * signatureBytes ) , nil
}
// PubKey gets the corresponding public key from the private key.
func ( privKey PrivKeyEd25519 ) PubKey ( ) crypto . PubKey {
privKeyBytes := [ 64 ] byte ( privKey )
initialized := false
// If the latter 32 bytes of the privkey are all zero, compute the pubkey
// otherwise privkey is initialized and we can use the cached value inside
// of the private key.
for _ , v := range privKeyBytes [ 32 : ] {
if v != 0 {
initialized = true
break
}
}
if initialized {
var pubkeyBytes [ PubKeyEd25519Size ] byte
copy ( pubkeyBytes [ : ] , privKeyBytes [ 32 : ] )
return PubKeyEd25519 ( pubkeyBytes )
}
pubBytes := * ed25519 . MakePublicKey ( & privKeyBytes )
return PubKeyEd25519 ( pubBytes )
}
@ -73,53 +92,74 @@ func (privKey PrivKeyEd25519) Equals(other crypto.PrivKey) bool {
}
}
func ( privKey PrivKeyEd25519 ) ToCurve25519 ( ) * [ 32 ] byte {
// ToCurve25519 takes a private key and returns its representation on
// Curve25519. Curve25519 is birationally equivalent to Edwards25519,
// which Ed25519 uses internally. This method is intended for use in
// an X25519 Diffie Hellman key exchange.
func ( privKey PrivKeyEd25519 ) ToCurve25519 ( ) * [ PubKeyEd25519Size ] byte {
keyCurve25519 := new ( [ 32 ] byte )
privKeyBytes := [ 64 ] byte ( privKey )
extra25519 . PrivateKeyToCurve25519 ( keyCurve25519 , & privKeyBytes )
return keyCurve25519
}
// Deterministically generates new priv-key bytes from key.
// Generate deterministically derives a new priv-key bytes from key.
// The privkey is generated as Sha256(amino_encode({privkey, index}))
// Note that we append the public key to the private key, the same way
// that golang/x/crypto/ed25519 does. See
// https://github.com/tendermint/ed25519/blob/master/ed25519.go#L39 for
// further details.
func ( privKey PrivKeyEd25519 ) Generate ( index int ) PrivKeyEd25519 {
bz , err := cdc . MarshalBinaryBare ( struct {
bz := cdc . Must MarshalBinaryBare( struct {
PrivKey [ 64 ] byte
Index int
} { privKey , index } )
if err != nil {
panic ( err )
}
newBytes := crypto . Sha256 ( bz )
newKey := new ( [ 64 ] byte )
copy ( newKey [ : 32 ] , newBytes )
// ed25519.MakePublicKey(newKey) alters the last 32 bytes of newKey.
// It places the pubkey in the last 32 bytes of newKey, and returns the
// public key.
ed25519 . MakePublicKey ( newKey )
return PrivKeyEd25519 ( * newKey )
}
// GenPrivKeyEd25519 generates a new ed25519 private key.
// It uses OS randomness in conjunction with the current global random seed
// in tendermint/libs/common to generate the private key.
func GenPrivKeyEd25519 ( ) PrivKeyEd25519 {
privKeyBytes := new ( [ 64 ] byte )
copy ( privKeyBytes [ : 32 ] , crypto . CRandBytes ( 32 ) )
ed25519 . MakePublicKey ( privKeyBytes )
return PrivKeyEd25519 ( * privKeyBytes )
privKey := new ( [ 64 ] byte )
copy ( privKey [ : 32 ] , crypto . CRandBytes ( 32 ) )
// ed25519.MakePublicKey(privKey) alters the last 32 bytes of privKey.
// It places the pubkey in the last 32 bytes of privKey, and returns the
// public key.
ed25519 . MakePublicKey ( privKey )
return PrivKeyEd25519 ( * privKey )
}
// GenPrivKeyEd25519FromSecret hashes the secret with SHA2, and uses
// that 32 byte output to create the private key.
// NOTE: secret should be the output of a KDF like bcrypt,
// if it's derived from user input.
func GenPrivKeyEd25519FromSecret ( secret [ ] byte ) PrivKeyEd25519 {
privKey32 := crypto . Sha256 ( secret ) // Not Ripemd160 because we want 32 bytes.
privKeyBytes := new ( [ 64 ] byte )
copy ( privKeyBytes [ : 32 ] , privKey32 )
ed25519 . MakePublicKey ( privKeyBytes )
return PrivKeyEd25519 ( * privKeyBytes )
privKey := new ( [ 64 ] byte )
copy ( privKey [ : 32 ] , privKey32 )
// ed25519.MakePublicKey(privKey) alters the last 32 bytes of privKey.
// It places the pubkey in the last 32 bytes of privKey, and returns the
// public key.
ed25519 . MakePublicKey ( privKey )
return PrivKeyEd25519 ( * privKey )
}
//-------------------------------------
var _ crypto . PubKey = PubKeyEd25519 { }
// PubKeyEd25519Size is the number of bytes in an Ed25519 signature.
const PubKeyEd25519Size = 32
// Implements PubKeyInner
// PubKeyEd25519 implements crypto.PubKey for the Ed25519 signature scheme.
type PubKeyEd25519 [ PubKeyEd25519Size ] byte
// Address is the SHA256-20 of the raw pubkey bytes.
@ -127,6 +167,7 @@ func (pubKey PubKeyEd25519) Address() crypto.Address {
return crypto . Address ( tmhash . Sum ( pubKey [ : ] ) )
}
// Bytes marshals the PubKey using amino encoding.
func ( pubKey PubKeyEd25519 ) Bytes ( ) [ ] byte {
bz , err := cdc . MarshalBinaryBare ( pubKey )
if err != nil {
@ -146,8 +187,12 @@ func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ crypto.Signature) bool
return ed25519 . Verify ( & pubKeyBytes , msg , & sigBytes )
}
// For use with golang/crypto/nacl/box
// If error, returns nil.
// ToCurve25519 takes a public key and returns its representation on
// Curve25519. Curve25519 is birationally equivalent to Edwards25519,
// which Ed25519 uses internally. This method is intended for use in
// an X25519 Diffie Hellman key exchange.
//
// If there is an error, then this function returns nil.
func ( pubKey PubKeyEd25519 ) ToCurve25519 ( ) * [ PubKeyEd25519Size ] byte {
keyCurve25519 , pubKeyBytes := new ( [ PubKeyEd25519Size ] byte ) , [ PubKeyEd25519Size ] byte ( pubKey )
ok := extra25519 . PublicKeyToCurve25519 ( keyCurve25519 , & pubKeyBytes )
@ -161,6 +206,7 @@ func (pubKey PubKeyEd25519) String() string {
return fmt . Sprintf ( "PubKeyEd25519{%X}" , pubKey [ : ] )
}
// nolint: golint
func ( pubKey PubKeyEd25519 ) Equals ( other crypto . PubKey ) bool {
if otherEd , ok := other . ( PubKeyEd25519 ) ; ok {
return bytes . Equal ( pubKey [ : ] , otherEd [ : ] )
@ -173,9 +219,11 @@ func (pubKey PubKeyEd25519) Equals(other crypto.PubKey) bool {
var _ crypto . Signature = SignatureEd25519 { }
// Size of an Edwards25519 signature. Namely the size of a compressed
// Edwards25519 point, and a field element. Both of which are 32 bytes.
const SignatureEd25519Size = 64
// I mplements crypto.Signature
// SignatureEd25519 i mplements crypto.Signature
type SignatureEd25519 [ SignatureEd25519Size ] byte
func ( sig SignatureEd25519 ) Bytes ( ) [ ] byte {