Skip to content
Snippets Groups Projects
Commit 9aa8857f authored by Jake Taylor's avatar Jake Taylor :lips:
Browse files

Merge branch 'XX-3076/ContactFP' into 'agile/EphemeralReception'

Add Fingerprint for Contact and tests

See merge request !503
parents 24dc0141 3e3eb68f
No related branches found
No related tags found
No related merge requests found
...@@ -9,6 +9,8 @@ package contact ...@@ -9,6 +9,8 @@ package contact
import ( import (
"bytes" "bytes"
"crypto"
"encoding/base64"
"encoding/binary" "encoding/binary"
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
...@@ -17,6 +19,7 @@ import ( ...@@ -17,6 +19,7 @@ import (
) )
const sizeByteLength = 2 const sizeByteLength = 2
const fingerprintLength = 15
// Contact implements the Contact interface defined in interface/contact.go, // Contact implements the Contact interface defined in interface/contact.go,
// in go, the structure is meant to be edited directly, the functions are for // in go, the structure is meant to be edited directly, the functions are for
...@@ -77,6 +80,22 @@ func (c Contact) Marshal() []byte { ...@@ -77,6 +80,22 @@ func (c Contact) Marshal() []byte {
return buff.Bytes() return buff.Bytes()
} }
// Creates a 15 character long fingerprint of contact
// off of the ID and DH public key
func (c Contact) GetFingerprint() string {
// Generate hash
sha := crypto.SHA256
h := sha.New()
// Hash Id and public key
h.Write(c.ID.Bytes())
h.Write(c.DhPubKey.Bytes())
data := h.Sum(nil)
// Encode hash and truncate
return base64.StdEncoding.EncodeToString(data[:])[:fingerprintLength]
}
// Unmarshal decodes the byte slice produced by Contact.Marshal into a Contact. // Unmarshal decodes the byte slice produced by Contact.Marshal into a Contact.
func Unmarshal(b []byte) (Contact, error) { func Unmarshal(b []byte) (Contact, error) {
if len(b) < sizeByteLength*3+id.ArrIDLen { if len(b) < sizeByteLength*3+id.ArrIDLen {
......
///////////////////////////////////////////////////////////////////////////////
// Copyright © 2020 xx network SEZC //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file //
///////////////////////////////////////////////////////////////////////////////
package contact package contact
import ( import (
"crypto"
"encoding/base64"
"encoding/json" "encoding/json"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/primitives/fact" "gitlab.com/elixxir/primitives/fact"
...@@ -9,6 +18,7 @@ import ( ...@@ -9,6 +18,7 @@ import (
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"math/rand" "math/rand"
"reflect" "reflect"
"strings"
"testing" "testing"
) )
...@@ -88,6 +98,82 @@ func TestContact_Marshal_Size(t *testing.T) { ...@@ -88,6 +98,82 @@ func TestContact_Marshal_Size(t *testing.T) {
} }
} }
// Unit test of getFingerprint
func TestContact_GetFingerprint(t *testing.T) {
c := Contact{
ID: id.NewIdFromString("Samwise", id.User, t),
DhPubKey: getCycInt(512),
}
contactString := c.GetFingerprint()
if len(contactString) != fingerprintLength {
t.Errorf("Unexpected length for fingerprint."+
"\n\tExpected length: %d"+
"\n\tReceived length: %d", len(contactString), fingerprintLength)
}
// Generate hash
sha := crypto.SHA256
h := sha.New()
// Hash Id and public key
h.Write(c.ID.Bytes())
h.Write(c.DhPubKey.Bytes())
data := h.Sum(nil)
expectedFP := base64.StdEncoding.EncodeToString(data[:])[:fingerprintLength]
if strings.Compare(contactString, expectedFP) != 0 {
t.Errorf("Fingerprint outputted is not expected."+
"\n\tExpected: %s"+
"\n\tReceived: %s", contactString, expectedFP)
}
}
// Consistency test for changes in underlying dependencies
func TestContact_GetFingerprint_Consistency(t *testing.T) {
expected := []string{
"rBUw1n4jtH4uEYq",
"Z/Jm1OUwDaql5cd",
"+vHLzY+yH96zAiy",
"cZm5Iz78ViOIlnh",
"9LqrcbFEIV4C4LX",
"ll4eykGpMWYlxw+",
"6YQshWJhdPL6ajx",
"Y6gTPVEzow4IHOm",
"6f/rT2vWxDC9tdt",
"rwqbDT+PoeA6Iww",
"YN4IFijP/GZ172O",
"ScbHVQc2T9SXQ2m",
"50mfbCXQ+LIqiZn",
"cyRYdMKXByiFdtC",
"7g6ujy7iIbJVl4F",
}
numTest := 15
output := make([]string, 0)
for i := 0; i < numTest; i++ {
c := Contact{
ID: id.NewIdFromUInt(uint64(i), id.User, t),
DhPubKey: getGroup().NewInt(25),
}
contactString := c.GetFingerprint()
output = append(output, contactString)
}
for i := 0; i < numTest; i++ {
if strings.Compare(output[i], expected[i]) != 0 {
t.Errorf("Fingerprint outputted is not expected."+
"\n\tReceived: %s"+
"\n\tExpected: %s", output[i], expected[i])
}
}
}
func getCycInt(size int) *cyclic.Int { func getCycInt(size int) *cyclic.Int {
var primeString = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + var primeString = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
...@@ -119,3 +205,21 @@ func getCycInt(size int) *cyclic.Int { ...@@ -119,3 +205,21 @@ func getCycInt(size int) *cyclic.Int {
grp := cyclic.NewGroup(large.NewIntFromString(primeString, 16), large.NewInt(2)).NewIntFromBytes(buff) grp := cyclic.NewGroup(large.NewIntFromString(primeString, 16), large.NewInt(2)).NewIntFromBytes(buff)
return grp return grp
} }
func getGroup() *cyclic.Group {
return cyclic.NewGroup(
large.NewIntFromString("E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D4941"+
"3394C049B7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688"+
"B55B3DD2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861"+
"575E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC"+
"718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FF"+
"B1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBC"+
"A23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD"+
"161C7738F32BF29A841698978825B4111B4BC3E1E198455095958333D776D8B2B"+
"EEED3A1A1A221A6E37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C"+
"4F50D7D7803D2D4F278DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F"+
"1390B5D3FEACAF1696015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F"+
"96789C38E89D796138E6319BE62E35D87B1048CA28BE389B575E994DCA7554715"+
"84A09EC723742DC35873847AEF49F66E43873", 16),
large.NewIntFromString("2", 16))
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment