diff --git a/go.mod b/go.mod index 275f7af..64a5f78 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/datatrails/go-datatrails-merklelog/massifs v0.3.1 github.com/datatrails/go-datatrails-merklelog/mmr v0.1.1 github.com/datatrails/go-datatrails-merklelog/mmrtesting v0.1.0 + github.com/datatrails/go-datatrails-serialization/eventsv1 v0.0.2 github.com/datatrails/go-datatrails-simplehash v0.0.5 github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.10.0 diff --git a/go.sum b/go.sum index 8c05b44..0fad33c 100644 --- a/go.sum +++ b/go.sum @@ -50,6 +50,8 @@ github.com/datatrails/go-datatrails-merklelog/mmr v0.1.1 h1:Ro2fYdDYxGGcPmudYuvP github.com/datatrails/go-datatrails-merklelog/mmr v0.1.1/go.mod h1:B/Kkz4joZTiTz0q/9FFAgHR+Tcn6UxtphMuCzamAc9Q= github.com/datatrails/go-datatrails-merklelog/mmrtesting v0.1.0 h1:q9RXtAGydXKSJjARnFObNu743cbfIOfERTXiiVa2tF4= github.com/datatrails/go-datatrails-merklelog/mmrtesting v0.1.0/go.mod h1:rWFjeK1NU7qnhl9+iKdjASpw/CkPwDAOPHsERYR7uEQ= +github.com/datatrails/go-datatrails-serialization/eventsv1 v0.0.2 h1:yEk+0KvWkn/xYbf3WgdFCAZNkLE4pze9ySqeCr6Pnos= +github.com/datatrails/go-datatrails-serialization/eventsv1 v0.0.2/go.mod h1:9i6Tip2lIXwSZ3SxP7XEhU2eQ9zkpxhEBmPmlOGqv/8= github.com/datatrails/go-datatrails-simplehash v0.0.5 h1:igu4QRYO87RQXrJlqSm3fgMA2Q0F4jglWqBlfvKrXKQ= github.com/datatrails/go-datatrails-simplehash v0.0.5/go.mod h1:XuOwViwdL+dyz7fGYIjaByS1ElMFsrVI0goKX0bNimA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/logverification/app/appentry_test.go b/logverification/app/appentry_test.go index 0337936..b605994 100644 --- a/logverification/app/appentry_test.go +++ b/logverification/app/appentry_test.go @@ -2,10 +2,12 @@ package app import ( "crypto/sha256" + "encoding/binary" "fmt" "testing" "github.com/datatrails/go-datatrails-merklelog/massifs" + "github.com/datatrails/go-datatrails-serialization/eventsv1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -14,8 +16,6 @@ import ( // // the first entry is a known log version 0 entry // the seconds entry is a known log version 1 entry -// -// TODO: Add actual KAT data func testMassifContext(t *testing.T) *massifs.MassifContext { start := massifs.MassifStart{ @@ -39,27 +39,32 @@ func testMassifContext(t *testing.T) *massifs.MassifContext { hasher := sha256.New() - idtimestampStr := "0x01931acb7b14043b00" - - // convert idtimestamp from bytes to uint64 - idTimestamp, _, err := massifs.SplitIDTimestampHex(idtimestampStr) + // KAT Data taken from an actual merklelog. + + // Log Version 0 (AssetsV2) + _, err = testMassifContext.AddHashedLeaf( + hasher, + binary.BigEndian.Uint64([]byte{148, 111, 227, 95, 198, 1, 121, 0}), + []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + []byte("112758ce-a8cb-4924-8df8-fcba1e31f8b0"), // Tenant UUID + []byte("assets/899e00a2-29bc-4316-bf70-121ce2044472/events/450dce94-065e-4f6a-bf69-7b59f28716b6"), + []byte{97, 231, 1, 42, 127, 20, 181, 70, 122, 134, 84, 231, 174, 117, 200, 148, 171, 205, 57, 146, 174, 48, 34, 30, 152, 215, 77, 3, 204, 14, 202, 57}, + ) require.NoError(t, err) - extraBytes := []byte{1, // app domain - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7} // 23 remaining bytes - - mmrEntry := []byte{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, // 32 byte hash - } - - _, err = testMassifContext.AddHashedLeaf(hasher, idTimestamp, extraBytes, []byte("test"), []byte("events/1234"), mmrEntry) + // Log Version 1 (EventsV1) + _, err = testMassifContext.AddHashedLeaf( + hasher, + binary.BigEndian.Uint64([]byte{148, 112, 0, 54, 17, 1, 121, 0}), + []byte{1, 17, 39, 88, 206, 168, 203, 73, 36, 141, 248, 252, 186, 30, 49, 248, 176, 0, 0, 0, 0, 0, 0, 0}, + []byte("112758ce-a8cb-4924-8df8-fcba1e31f8b0"), // Tenant UUID + []byte("events/01947000-3456-780f-bfa9-29881e3bac88"), + []byte{215, 191, 107, 210, 134, 10, 40, 56, 226, 71, 136, 164, 9, 118, 166, 159, 86, 31, 175, 135, 202, 115, 37, 151, 174, 118, 115, 113, 25, 16, 144, 250}, + ) require.NoError(t, err) + // Intermediate Node Skipped + return testMassifContext } @@ -142,14 +147,13 @@ func TestAppEntry_MMRSalt(t *testing.T) { { name: "positive kat", fields: fields{ - mmrIndex: 0, + mmrIndex: 1, // Corresponds to a log version 1 entry }, expected: []byte{ - 0x1, // app domain - 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, - 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, - 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, // remaining bytes - 0x93, 0x1a, 0xcb, 0x7b, 0x14, 0x4, 0x3b, 0x0, // idtimestamp + 1, // App Domain + 17, 39, 88, 206, 168, 203, 73, 36, 141, 248, 252, 186, 30, 49, 248, 176, // ExtraBytes + 0, 0, 0, 0, 0, 0, 0, // ExtraBytes (padding) + 148, 112, 0, 54, 17, 1, 121, 0, // IDTimestamp }, }, } @@ -166,3 +170,38 @@ func TestAppEntry_MMRSalt(t *testing.T) { }) } } + +// TestAppEntry_VerifyInclusionLogVersion1 verifies that a proof can be generated and verified successfully +// for log version 1 +func TestAppEntry_VerifyInclusionLogVersion1(t *testing.T) { + testMassifContext := testMassifContext(t) + + serializedBytes, err := eventsv1.SerializeEventFromJson([]byte(logVersion1Event)) + assert.NoError(t, err) + + ae := &AppEntry{ + mmrIndex: 1, + mmrEntryFields: NewMMREntryFields(0x0, serializedBytes), + } + + inclusionVerified, err := ae.VerifyInclusion(testMassifContext) + assert.NoError(t, err) + assert.True(t, inclusionVerified) +} + +// TestAppEntry_VerifyInclusionLogVersion0 verifies that a proof can be generated and verified successfully +// for log version 0 +func TestAppEntry_VerifyInclusionLogVersion0(t *testing.T) { + testMassifContext := testMassifContext(t) + + serializedBytes := []byte(logVersion0Event) + + ae := &AppEntry{ + mmrIndex: 0, + mmrEntryFields: NewMMREntryFields(0x0, serializedBytes), + } + + inclusionVerified, err := ae.VerifyInclusion(testMassifContext) + assert.NoError(t, err) + assert.True(t, inclusionVerified) +} diff --git a/logverification/app/consts_test.go b/logverification/app/consts_test.go index 43b0992..3c4bf3a 100644 --- a/logverification/app/consts_test.go +++ b/logverification/app/consts_test.go @@ -48,4 +48,72 @@ const ( } } ` + + logVersion0Event = ` + { + "identity": "assets/899e00a2-29bc-4316-bf70-121ce2044472/events/450dce94-065e-4f6a-bf69-7b59f28716b6", + "asset_identity": "assets/899e00a2-29bc-4316-bf70-121ce2044472", + "event_attributes": {}, + "asset_attributes": { + "arc_display_name": "Default asset", + "default": "true", + "arc_description": "Collection for Events not specifically associated with any specific Asset" + }, + "operation": "NewAsset", + "behaviour": "AssetCreator", + "timestamp_declared": "2025-01-16T16:12:38Z", + "timestamp_accepted": "2025-01-16T16:12:38Z", + "timestamp_committed": "2025-01-16T16:12:38.576970217Z", + "principal_declared": { + "issuer": "https://accounts.google.com", + "subject": "105632894023856861149", + "display_name": "Henry SocialTest", + "email": "henry.socialtest@gmail.com" + }, + "principal_accepted": { + "issuer": "https://accounts.google.com", + "subject": "105632894023856861149", + "display_name": "Henry SocialTest", + "email": "henry.socialtest@gmail.com" + }, + "confirmation_status": "CONFIRMED", + "transaction_id": "", + "block_number": 0, + "transaction_index": 0, + "from": "0x412bB2Ecd6f2bDf26D64de834Fa17167192F4c0d", + "tenant_identity": "tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0", + "merklelog_entry": { + "commit": { + "index": "0", + "idtimestamp": "01946fe35fc6017900" + }, + "confirm": { + "mmr_size": "1", + "root": "YecBKn8UtUZ6hlTnrnXIlKvNOZKuMCIemNdNA8wOyjk=", + "timestamp": "1737043961154", + "idtimestamp": "", + "signed_tree_head": "" + }, + "unequivocal": null + } +} + ` + + logVersion1Event = ` + { + "identity": "events/01947000-3456-780f-bfa9-29881e3bac88", + "attributes": { + "foo": "bar" + }, + "trails": [], + "origin_tenant": "tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0", + "created_by": "2ef471c2-f997-4503-94c8-60b5c929a3c3", + "created_at": 1737045849174, + "confirmation_status": "CONFIRMED", + "merklelog_commit": { + "index": "1", + "idtimestamp": "019470003611017900" + } +} + ` )