reorganised crypto key stuff and implemented interface for libp2p

This commit is contained in:
херетик
2023-04-10 19:48:22 +01:00
parent ed11d79117
commit 3a96c29b3c
8 changed files with 126 additions and 24 deletions

View File

@@ -18,7 +18,7 @@ import (
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
fails = log.E.Chk
)
const Charset = "abcdefghijklmnopqrstuvwxyz234679"

View File

@@ -4,11 +4,14 @@ import (
"crypto/rand"
"encoding/base32"
"encoding/hex"
"fmt"
"sync"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
"github.com/gookit/color"
"github.com/libp2p/go-libp2p/core/crypto"
crypto_pb "github.com/libp2p/go-libp2p/core/crypto/pb"
"git-indra.lan/indra-labs/indra"
"git-indra.lan/indra-labs/indra/pkg/b32/based32"
@@ -162,6 +165,105 @@ type (
PubBytes [PubKeyLen]byte
)
var _ crypto.Key = &Prv{}
var _ crypto.Key = &Pub{}
var _ crypto.PrivKey = &Prv{}
func (p *Prv) Equals(key crypto.Key) (eq bool) {
var e error
var rawA, rawB []byte
if rawA, e = key.Raw(); fails(e) {
return
}
if rawB, e = p.Raw(); fails(e) {
return
}
if len(rawA) != len(rawB) {
return
}
for i := range rawA {
if rawA[i] != rawB[i] {
for j := range rawA {
rawA[j], rawB[j] = 0, 0
}
return
}
}
return true
}
func (p *Prv) Raw() ([]byte, error) {
b := p.ToBytes()
return b[:], nil
}
func (p *Prv) Type() crypto_pb.KeyType {
return crypto_pb.KeyType_Secp256k1
}
func (p *Prv) Sign(bytes []byte) ([]byte, error) {
hash := sha256.Single(bytes)
s, e := Sign(p, hash)
return s[:], e
}
func (p *Prv) GetPublic() crypto.PubKey {
if p == nil {
return nil
}
return DerivePub(p)
}
var _ crypto.PubKey = &Pub{}
func (k *Pub) Verify(data []byte, sigBytes []byte) (is bool,
e error) {
var s SigBytes
if len(sigBytes) != len(s) {
return false, fmt.Errorf("length mismatch")
}
copy(s[:], sigBytes[:])
hash := sha256.Single(data)
var pk *Pub
if pk, e = s.Recover(hash); fails(e) {
return false, e
}
return pk.ToBytes().Equals(k.ToBytes()), nil
}
func (k *Pub) Equals(key crypto.Key) (eq bool) {
var e error
var rawA, rawB []byte
if rawA, e = key.Raw(); fails(e) {
return
}
if rawB, e = k.Raw(); fails(e) {
return
}
if len(rawA) != len(rawB) {
return
}
for i := range rawA {
if rawA[i] != rawB[i] {
for j := range rawA {
rawA[j], rawB[j] = 0, 0
}
return
}
}
return true
}
func (k *Pub) Raw() ([]byte, error) {
b := k.ToBytes()
return b[:], nil
}
func (k *Pub) Type() crypto_pb.KeyType {
return crypto_pb.KeyType_Secp256k1
}
func (pb PubBytes) String() (s string) {
var e error
if s, e = based32.Codec.Encode(pb[:]); fails(e) {
@@ -243,10 +345,10 @@ func (k *Pub) ToPublicKey() *secp256k1.PublicKey {
return (*secp256k1.PublicKey)(k)
}
// Equals returns true if two public keys are the same.
func (k *Pub) Equals(pub2 *Pub) bool {
return k.ToPublicKey().IsEqual(pub2.ToPublicKey())
}
// // Equals returns true if two public keys are the same.
// func (k *Pub) Equals(pub2 *Pub) bool {
// return k.ToPublicKey().IsEqual(pub2.ToPublicKey())
// }
// SigLen is the length of the signatures used in Indra, compact keys that can have
// the public key extracted from them.

View File

@@ -23,7 +23,7 @@ func (id ID) String() string {
// NewID returns a random 8 byte nonce to be used as identifiers.
func NewID() (t ID) {
if read, e := rand.Read(t[:]); check(e) && read != IDLen {
if read, e := rand.Read(t[:]); fails(e) && read != IDLen {
}
return
}

View File

@@ -6,14 +6,14 @@ package nonce
import (
"crypto/aes"
"crypto/rand"
"git-indra.lan/indra-labs/indra"
log2 "git-indra.lan/indra-labs/indra/pkg/proc/log"
)
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
fails = log.E.Chk
)
const IVLen = aes.BlockSize
@@ -22,7 +22,7 @@ type IV [IVLen]byte
// New reads a nonce from a cryptographically secure random number source
func New() (n IV) {
if c, e := rand.Read(n[:]); check(e) && c != IDLen {
if c, e := rand.Read(n[:]); fails(e) && c != IDLen {
}
return
}

View File

@@ -11,7 +11,7 @@ func TestBase32(t *testing.T) {
for i := 0; i < 10000; i++ {
var k *Prv
var e error
if k, e = GeneratePrvKey(); check(e) {
if k, e = GeneratePrvKey(); fails(e) {
t.Error(e)
t.FailNow()
}

View File

@@ -19,7 +19,7 @@ const (
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
fails = log.E.Chk
)
var enc = base32.NewEncoding(Charset).EncodeToString

View File

@@ -19,16 +19,16 @@ func TestSignRecover(t *testing.T) {
}
var prv1 *Prv
var pub1, rec1 *Pub
if prv1, e = GeneratePrvKey(); check(e) {
if prv1, e = GeneratePrvKey(); fails(e) {
t.Error(e)
}
pub1 = DerivePub(prv1)
var s SigBytes
hash := sha256.Single(payload)
if s, e = Sign(prv1, hash); check(e) {
if s, e = Sign(prv1, hash); fails(e) {
t.Error(e)
}
if rec1, e = s.Recover(hash); check(e) {
if rec1, e = s.Recover(hash); fails(e) {
t.Error(e)
}
if !pub1.Equals(rec1) {
@@ -46,18 +46,18 @@ func TestSignRecoverFail(t *testing.T) {
}
var prv1 *Prv
var pub1, rec1 *Pub
if prv1, e = GeneratePrvKey(); check(e) {
if prv1, e = GeneratePrvKey(); fails(e) {
t.Error(e)
}
pub1 = DerivePub(prv1)
var s SigBytes
hash := sha256.Single(payload)
if s, e = Sign(prv1, hash); check(e) {
if s, e = Sign(prv1, hash); fails(e) {
t.Error(e)
}
copy(payload, make([]byte, 10))
hash2 := sha256.Single(payload)
if rec1, e = s.Recover(hash2); check(e) {
if rec1, e = s.Recover(hash2); fails(e) {
t.Error(e)
}
if pub1.Equals(rec1) {

View File

@@ -11,11 +11,11 @@ import (
func TestKeySet_Next(t *testing.T) {
for rounds := 0; rounds < 1000; rounds++ {
key, ks, e := NewSigner()
if check(e) {
if fails(e) {
t.FailNow()
}
var hx PubBytes
if hx = DerivePub(key).ToBytes(); check(e) {
if hx = DerivePub(key).ToBytes(); fails(e) {
t.Error(e)
}
oddness := hx[0]
@@ -34,7 +34,7 @@ func TestKeySet_Next(t *testing.T) {
func BenchmarkKeySet_Next(b *testing.B) {
_, ks, e := NewSigner()
if check(e) {
if fails(e) {
b.FailNow()
}
for n := 0; n < b.N; n++ {
@@ -44,7 +44,7 @@ func BenchmarkKeySet_Next(b *testing.B) {
func BenchmarkKeySet_Next_Derive(b *testing.B) {
_, ks, e := NewSigner()
if check(e) {
if fails(e) {
b.FailNow()
}
for n := 0; n < b.N; n++ {
@@ -56,7 +56,7 @@ func BenchmarkKeySet_Next_Derive(b *testing.B) {
func GenerateTestMessage(msgSize int) (msg []byte, hash sha256.Hash, e error) {
msg = make([]byte, msgSize)
var n int
if n, e = rand.Read(msg); check(e) && n != msgSize {
if n, e = rand.Read(msg); fails(e) && n != msgSize {
return
}
copy(msg, "payload")
@@ -66,7 +66,7 @@ func GenerateTestMessage(msgSize int) (msg []byte, hash sha256.Hash, e error) {
func BenchmarkKeySet_Next_Sign(b *testing.B) {
_, ks, e := NewSigner()
if check(e) {
if fails(e) {
b.FailNow()
}
var msg []byte
@@ -75,7 +75,7 @@ func BenchmarkKeySet_Next_Sign(b *testing.B) {
for n := 0; n < b.N; n++ {
k := ks.Next()
hash := sha256.Single(msg)
if _, e = Sign(k, hash); check(e) {
if _, e = Sign(k, hash); fails(e) {
b.Error("failed to sign")
}
}