@@ -76,3 +76,4 @@ local.properties | |||
/work/ | |||
/rt/ | |||
/docker/ | |||
/scratch/ |
@@ -0,0 +1,3 @@ | |||
https://wiki.gnupg.org/ECC | |||
https://gnupg.org/documentation/manuals/gcrypt.pdf (p.46) |
@@ -25,7 +25,7 @@ func main() { | |||
if err != nil || n != 32 { | |||
panic(err) | |||
} | |||
prv := crypto.EdDSAPrivateKeyFromSeed(seed) | |||
prv := crypto.PrivateKeyFromSeed(seed) | |||
pub := prv.Public().Bytes() | |||
id := util.EncodeBinaryToString(pub) | |||
for _, p := range prefixes { | |||
@@ -19,18 +19,18 @@ type Peer interface { | |||
*/ | |||
type Peer struct { | |||
pub *crypto.EdDSAPublicKey | |||
pub *crypto.PublicKey | |||
idString string | |||
addrList []*util.Address | |||
prv *crypto.EdDSAPrivateKey // long-term signing key | |||
ephPrv *crypto.EdDSAPrivateKey // ephemeral signing key | |||
prv *crypto.PrivateKey // long-term signing key | |||
ephPrv *crypto.PrivateKey // ephemeral signing key | |||
ephMsg *message.EphemeralKeyMsg // ephemeral signing key message | |||
} | |||
func NewPeer(data []byte, local bool) (p *Peer, err error) { | |||
p = new(Peer) | |||
if local { | |||
p.prv = crypto.EdDSAPrivateKeyFromSeed(data) | |||
p.prv = crypto.PrivateKeyFromSeed(data) | |||
p.pub = p.prv.Public() | |||
p.ephPrv, p.ephMsg, err = message.NewEphemeralKey(p.pub.Bytes(), p.prv) | |||
if err != nil { | |||
@@ -38,7 +38,7 @@ func NewPeer(data []byte, local bool) (p *Peer, err error) { | |||
} | |||
} else { | |||
p.prv = nil | |||
p.pub = crypto.NewEdDSAPublicKey(data) | |||
p.pub = crypto.NewPublicKey(data) | |||
} | |||
p.idString = util.EncodeBinaryToString(p.pub.Bytes()) | |||
p.addrList = make([]*util.Address, 0) | |||
@@ -53,15 +53,15 @@ func (p *Peer) SetEphKeyMsg(msg *message.EphemeralKeyMsg) { | |||
p.ephMsg = msg | |||
} | |||
func (p *Peer) EphPrvKey() *crypto.EdDSAPrivateKey { | |||
func (p *Peer) EphPrvKey() *crypto.PrivateKey { | |||
return p.ephPrv | |||
} | |||
func (p *Peer) PrvKey() *crypto.EdDSAPrivateKey { | |||
func (p *Peer) PrvKey() *crypto.PrivateKey { | |||
return p.prv | |||
} | |||
func (p *Peer) PubKey() *crypto.EdDSAPublicKey { | |||
func (p *Peer) PubKey() *crypto.PublicKey { | |||
return p.pub | |||
} | |||
@@ -81,13 +81,13 @@ func (p *Peer) AddAddress(a *util.Address) { | |||
p.addrList = append(p.addrList, a) | |||
} | |||
func (p *Peer) Sign(msg []byte) ([]byte, error) { | |||
func (p *Peer) Sign(msg []byte) (*crypto.Signature, error) { | |||
if p.prv == nil { | |||
return nil, fmt.Errorf("No private key") | |||
} | |||
return p.prv.Sign(msg) | |||
} | |||
func (p *Peer) Verify(msg, sig []byte) bool { | |||
func (p *Peer) Verify(msg []byte, sig *crypto.Signature) bool { | |||
return p.pub.Verify(msg, sig) | |||
} |
@@ -1,7 +0,0 @@ | |||
package crypto | |||
import () | |||
func SharedSecret(prv *EdDSAPrivateKey, pub *EdDSAPublicKey) ([]byte, error) { | |||
return nil, nil | |||
} |
@@ -1,99 +0,0 @@ | |||
package crypto | |||
import ( | |||
"crypto" | |||
"crypto/rand" | |||
"crypto/sha512" | |||
"errors" | |||
"gnunet/util" | |||
"gnunet/crypto/ed25519" | |||
) | |||
// Error codes | |||
var ( | |||
ErrInvalidEdDSAPrivateKeyData = errors.New("Invalid Ed25519 private key data") | |||
) | |||
//---------------------------------------------------------------------- | |||
// Public key | |||
//---------------------------------------------------------------------- | |||
// EdDSAPublicKey is a Ed25519 public key. | |||
type EdDSAPublicKey struct { | |||
key ed25519.PublicKey | |||
} | |||
// NewEdDSAPublicKey sets the binary representation of a public key. | |||
// The value is not checked for validity! | |||
func NewEdDSAPublicKey(data []byte) *EdDSAPublicKey { | |||
return &EdDSAPublicKey{ | |||
key: util.Clone(data), | |||
} | |||
} | |||
// Bytes returns the binary representation of a public key. | |||
func (pub *EdDSAPublicKey) Bytes() []byte { | |||
return []byte(pub.key) | |||
} | |||
// Verify checks a signature of a data block. | |||
func (pub *EdDSAPublicKey) Verify(data, sig []byte) bool { | |||
h := sha512.New() | |||
h.Write(data) | |||
hv := h.Sum(nil) | |||
return ed25519.Verify(pub.key, hv, sig) | |||
} | |||
//---------------------------------------------------------------------- | |||
// Private Key | |||
//---------------------------------------------------------------------- | |||
// EdDSAPrivateKey is a Ed25519 private key. | |||
type EdDSAPrivateKey struct { | |||
key ed25519.PrivateKey // private key data (seed||public_key) | |||
d []byte // HACK! "real" private key | |||
} | |||
// EdDSAPrivateKeyFromSeed returns a private key for a given seed. | |||
func EdDSAPrivateKeyFromSeed(seed []byte) *EdDSAPrivateKey { | |||
k := &EdDSAPrivateKey{ | |||
key: ed25519.NewKeyFromSeed(seed), | |||
} | |||
// HACK! Save the "real" private key 'd' for later use | |||
md := sha512.Sum512(seed) | |||
k.d = util.Reverse(md[:32]) | |||
k.d[0] = (k.d[0] & 0x3f) | 0x40 | |||
k.d[31] &= 0xf8 | |||
return k | |||
} | |||
// D returns the "real" private key (HACK!) | |||
func (prv *EdDSAPrivateKey) D() []byte { | |||
return util.Clone(prv.d) | |||
} | |||
// Public returns the public key for a private key. | |||
func (prv *EdDSAPrivateKey) Public() *EdDSAPublicKey { | |||
return &EdDSAPublicKey{ | |||
key: util.Clone(prv.key[ed25519.PublicKeySize:]), | |||
} | |||
} | |||
// Sign creates a signature for a data block. | |||
func (prv *EdDSAPrivateKey) Sign(data []byte) ([]byte, error) { | |||
h := sha512.New() | |||
h.Write(data) | |||
hv := h.Sum(nil) | |||
return prv.key.Sign(rand.Reader, hv, crypto.Hash(0)) | |||
} | |||
// NewPeerKeypair creates a new Ed25519 key pair. | |||
func EdDSAKeypair() (*EdDSAPublicKey, *EdDSAPrivateKey, error) { | |||
pub, prv, err := ed25519.GenerateKey(rand.Reader) | |||
if err != nil { | |||
return nil, nil, err | |||
} | |||
return &EdDSAPublicKey{key: pub}, &EdDSAPrivateKey{key: prv}, nil | |||
} |
@@ -0,0 +1,7 @@ | |||
package crypto | |||
import () | |||
func SharedSecret(prv *PrivateKey, pub *PublicKey) ([]byte, error) { | |||
return nil, nil | |||
} |
@@ -0,0 +1,100 @@ | |||
package crypto | |||
import ( | |||
"crypto" | |||
"crypto/rand" | |||
"crypto/sha512" | |||
"fmt" | |||
"math/big" | |||
"gnunet/crypto/ed25519" | |||
"gnunet/util" | |||
) | |||
// Error codes | |||
var ( | |||
ErrInvalidPrivateKeyData = fmt.Errorf("Invalid private key data") | |||
) | |||
//---------------------------------------------------------------------- | |||
// Public key | |||
//---------------------------------------------------------------------- | |||
// PublicKey is a Ed25519 public key. | |||
type PublicKey struct { | |||
key ed25519.PublicKey | |||
} | |||
// NewPublicKey sets the binary representation of a public key. | |||
// The value is not checked for validity! | |||
func NewPublicKey(data []byte) *PublicKey { | |||
if l := len(data); l != ed25519.PublicKeySize { | |||
panic(fmt.Sprintf("NewPublicKey: invalid key size (%d)", l)) | |||
} | |||
return &PublicKey{ | |||
key: util.Clone(data), | |||
} | |||
} | |||
// Bytes returns the binary representation of a public key. | |||
func (pub *PublicKey) Bytes() []byte { | |||
return []byte(pub.key) | |||
} | |||
// Verify checks a signature of a message. | |||
func (pub *PublicKey) Verify(msg []byte, sig *Signature) bool { | |||
hv := sha512.Sum512(msg) | |||
return ed25519.Verify(pub.key, hv[:], sig.Bytes()) | |||
} | |||
//---------------------------------------------------------------------- | |||
// Private Key | |||
//---------------------------------------------------------------------- | |||
// PrivateKey is a Ed25519 private key. | |||
type PrivateKey struct { | |||
key ed25519.PrivateKey // private key data (seed||public_key) | |||
d *big.Int // HACK! "real" private key | |||
} | |||
// PrivateKeyFromSeed returns a private key for a given seed. | |||
func PrivateKeyFromSeed(seed []byte) *PrivateKey { | |||
k := &PrivateKey{ | |||
key: ed25519.NewKeyFromSeed(seed), | |||
} | |||
// HACK! Save the "real" private key 'd' for later use | |||
md := sha512.Sum512(seed) | |||
d := util.Reverse(md[:32]) | |||
d[0] = (d[0] & 0x3f) | 0x40 | |||
d[31] &= 0xf8 | |||
k.d = new(big.Int).SetBytes(d) | |||
return k | |||
} | |||
// D returns the "real" private key (HACK!) | |||
func (prv *PrivateKey) D() *big.Int { | |||
return prv.d | |||
} | |||
// Public returns the public key for a private key. | |||
func (prv *PrivateKey) Public() *PublicKey { | |||
return &PublicKey{ | |||
key: util.Clone(prv.key[ed25519.PublicKeySize:]), | |||
} | |||
} | |||
// Sign creates a signature for a message. | |||
func (prv *PrivateKey) Sign(msg []byte) (*Signature, error) { | |||
hv := sha512.Sum512(msg) | |||
sig, err := prv.key.Sign(rand.Reader, hv[:], crypto.Hash(0)) | |||
return NewSignatureFromBytes(sig), err | |||
} | |||
// NewKeypair creates a new Ed25519 key pair. | |||
func NewKeypair() (*PublicKey, *PrivateKey, error) { | |||
pub, prv, err := ed25519.GenerateKey(rand.Reader) | |||
if err != nil { | |||
return nil, nil, err | |||
} | |||
return &PublicKey{key: pub}, &PrivateKey{key: prv}, nil | |||
} |
@@ -73,13 +73,13 @@ var ( | |||
}, | |||
*/ | |||
} | |||
prv *EdDSAPrivateKey | |||
pub *EdDSAPublicKey | |||
prv *PrivateKey | |||
pub *PublicKey | |||
) | |||
func TestEdDSAPrvKey(t *testing.T) { | |||
func TestPrvKey(t *testing.T) { | |||
prv = EdDSAPrivateKeyFromSeed(seed) | |||
prv = PrivateKeyFromSeed(seed) | |||
if testing.Verbose() { | |||
prvB := prv.key[:32] | |||
fmt.Printf("PRIVATE = %s\n", hex.EncodeToString(prvB)) | |||
@@ -100,16 +100,18 @@ func TestEdDSAPrvKey(t *testing.T) { | |||
} | |||
} | |||
func TestEdDSASign(t *testing.T) { | |||
func TestSign(t *testing.T) { | |||
for i := range data { | |||
sigT, err := prv.Sign(data[i]) | |||
if err != nil { | |||
t.Fatal(err) | |||
} | |||
sigX := sigT.Bytes() | |||
if testing.Verbose() { | |||
fmt.Printf("SIG(%d)=%s\n", i, hex.EncodeToString(sigT)) | |||
fmt.Printf("SIG(%d)=%s\n", i, hex.EncodeToString(sigX)) | |||
} | |||
if bytes.Compare(sigT, sig[i]) != 0 { | |||
if bytes.Compare(sigX, sig[i]) != 0 { | |||
t.Logf("SIG! = %s\n", hex.EncodeToString(sig[i])) | |||
t.Fatal(fmt.Sprintf("Signature mismatch (%d)", i)) | |||
} | |||
@@ -1,6 +1,8 @@ | |||
package crypto | |||
import () | |||
import ( | |||
"gnunet/util" | |||
) | |||
// Signature purpose constants | |||
const ( | |||
@@ -34,3 +36,22 @@ const ( | |||
SIG_GNUID_TICKET // GNUid Ticket. | |||
SIG_CREDENTIAL // GNUnet credential. | |||
) | |||
//---------------------------------------------------------------------- | |||
// Signature | |||
//---------------------------------------------------------------------- | |||
type Signature struct { | |||
// internal | |||
data []byte | |||
} | |||
func NewSignatureFromBytes(data []byte) *Signature { | |||
return &Signature{ | |||
data: util.Clone(data), | |||
} | |||
} | |||
func (s *Signature) Bytes() []byte { | |||
return s.data[:] | |||
} |
@@ -27,20 +27,19 @@ type EphemeralKeyMsg struct { | |||
} | |||
func NewEphemeralKeyMsg() *EphemeralKeyMsg { | |||
b := &EphKeyBlock{ | |||
SignSize: 88, | |||
SigPurpose: crypto.SIG_ECC_KEY, | |||
CreateTime: util.GetAbsoluteTimeNow(), | |||
ExpireTime: util.GetAbsoluteTimeOffset(12 * time.Hour), | |||
EphemeralKey: make([]byte, 32), | |||
PeerID: make([]byte, 32), | |||
} | |||
return &EphemeralKeyMsg{ | |||
MsgSize: 160, | |||
MsgType: CORE_EPHEMERAL_KEY, | |||
SenderStatus: 1, | |||
Signature: make([]byte, 64), | |||
SignedBlock: b, | |||
SignedBlock: &EphKeyBlock{ | |||
SignSize: 88, | |||
SigPurpose: crypto.SIG_ECC_KEY, | |||
CreateTime: util.GetAbsoluteTimeNow(), | |||
ExpireTime: util.GetAbsoluteTimeOffset(12 * time.Hour), | |||
EphemeralKey: make([]byte, 32), | |||
PeerID: make([]byte, 32), | |||
}, | |||
} | |||
} | |||
@@ -52,25 +51,25 @@ func (m *EphemeralKeyMsg) String() string { | |||
m.SenderStatus) | |||
} | |||
func (m *EphemeralKeyMsg) Public() *crypto.EdDSAPublicKey { | |||
return crypto.NewEdDSAPublicKey(m.SignedBlock.PeerID) | |||
func (m *EphemeralKeyMsg) Public() *crypto.PublicKey { | |||
return crypto.NewPublicKey(m.SignedBlock.PeerID) | |||
} | |||
func (m *EphemeralKeyMsg) Verify(pub *crypto.EdDSAPublicKey) bool { | |||
func (m *EphemeralKeyMsg) Verify(pub *crypto.PublicKey) bool { | |||
data, err := Marshal(m.SignedBlock) | |||
if err != nil { | |||
fmt.Printf("Verify: %s\n", err) | |||
return false | |||
} | |||
return pub.Verify(data, m.Signature) | |||
sig := crypto.NewSignatureFromBytes(m.Signature) | |||
return pub.Verify(data, sig) | |||
} | |||
func NewEphemeralKey(peerId []byte, ltPrv *crypto.EdDSAPrivateKey) (*crypto.EdDSAPrivateKey, *EphemeralKeyMsg, error) { | |||
func NewEphemeralKey(peerId []byte, ltPrv *crypto.PrivateKey) (*crypto.PrivateKey, *EphemeralKeyMsg, error) { | |||
msg := NewEphemeralKeyMsg() | |||
copy(msg.SignedBlock.PeerID, peerId) | |||
seed := make([]byte, 32) | |||
util.RndArray(seed) | |||
prv := crypto.EdDSAPrivateKeyFromSeed(seed) | |||
seed := util.NewRndArray(32) | |||
prv := crypto.PrivateKeyFromSeed(seed) | |||
copy(msg.SignedBlock.EphemeralKey, prv.Public().Bytes()) | |||
data, err := Marshal(msg.SignedBlock) | |||
@@ -81,7 +80,7 @@ func NewEphemeralKey(peerId []byte, ltPrv *crypto.EdDSAPrivateKey) (*crypto.EdDS | |||
if err != nil { | |||
return nil, nil, err | |||
} | |||
msg.Signature = sig | |||
copy(msg.Signature, sig.Bytes()) | |||
return prv, msg, nil | |||
} |
@@ -105,7 +105,7 @@ func (m *TransportPongMsg) String() string { | |||
return fmt.Sprintf("TransportPongMsg{<unkown>,%d}", m.Challenge) | |||
} | |||
func (m *TransportPongMsg) Sign(prv *crypto.EdDSAPrivateKey) error { | |||
func (m *TransportPongMsg) Sign(prv *crypto.PrivateKey) error { | |||
data, err := Marshal(m.SignedBlock) | |||
if err != nil { | |||
fmt.Printf("Sign: %s\n", err) | |||
@@ -116,17 +116,18 @@ func (m *TransportPongMsg) Sign(prv *crypto.EdDSAPrivateKey) error { | |||
fmt.Printf("Sign: %s\n", err) | |||
return err | |||
} | |||
m.Signature = sig | |||
copy(m.Signature, sig.Bytes()) | |||
return nil | |||
} | |||
func (m *TransportPongMsg) Verify(pub *crypto.EdDSAPublicKey) bool { | |||
func (m *TransportPongMsg) Verify(pub *crypto.PublicKey) bool { | |||
data, err := Marshal(m.SignedBlock) | |||
if err != nil { | |||
fmt.Printf("Verify: %s\n", err) | |||
return false | |||
} | |||
return pub.Verify(data, m.Signature) | |||
sig := crypto.NewSignatureFromBytes(m.Signature) | |||
return pub.Verify(data, sig) | |||
} | |||
//---------------------------------------------------------------------- | |||
@@ -10,6 +10,12 @@ func RndArray(b []byte) { | |||
rand.Read(b) | |||
} | |||
func NewRndArray(size int) []byte { | |||
b := make([]byte, size) | |||
rand.Read(b) | |||
return b | |||
} | |||
func RndUInt64() uint64 { | |||
b := make([]byte, 8) | |||
RndArray(b) | |||