From 0e10aa3074fcb728479ff35b183b59eecfa395ae Mon Sep 17 00:00:00 2001 From: Henry Jewell Date: Thu, 16 Jan 2025 18:26:49 +0000 Subject: [PATCH 1/4] add minimal KAT data for appentry_test re AB#10216 --- logverification/app/appentry_test.go | 42 +++++++++++++---------- logverification/fetchmassif_not_test.go | 44 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 logverification/fetchmassif_not_test.go diff --git a/logverification/app/appentry_test.go b/logverification/app/appentry_test.go index 0337936..7dc1a7b 100644 --- a/logverification/app/appentry_test.go +++ b/logverification/app/appentry_test.go @@ -2,6 +2,7 @@ package app import ( "crypto/sha256" + "encoding/binary" "fmt" "testing" @@ -39,30 +40,37 @@ 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("tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0"), + []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("tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0"), + []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 } +// TODO: Test inclusion proofs using the AppEntry methods with the KAT data. + // TestNewAppEntry tests: // // 1. we can get all non derived fields for the app entry getter diff --git a/logverification/fetchmassif_not_test.go b/logverification/fetchmassif_not_test.go new file mode 100644 index 0000000..7b55cce --- /dev/null +++ b/logverification/fetchmassif_not_test.go @@ -0,0 +1,44 @@ +package logverification + +import ( + "context" + "fmt" + "testing" + + "github.com/datatrails/go-datatrails-common/azblob" + "github.com/datatrails/go-datatrails-common/logger" + "github.com/datatrails/go-datatrails-merklelog/massifs" + "github.com/stretchr/testify/assert" +) + +func TestFetchMassif(t *testing.T) { + logger.New("NOOP") + + reader, err := azblob.NewReaderNoAuth( + "https://app.qa.stage.datatrails.ai/verifiabledata", + azblob.WithContainer("merklelogs"), + ) + assert.NoError(t, err) + + massifReader := massifs.NewMassifReader(logger.Sugar, reader) + + massifContext, err := massifReader.GetFirstMassif(context.Background(), "tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0") + assert.NoError(t, err) + + var i uint64 + for i = 0; i < 10; i++ { + mmrEntry, err := massifContext.Get(i) + assert.NoError(t, err) + + trieEntry, err := massifContext.GetTrieEntry(i) + assert.NoError(t, err) + + fmt.Printf("MMR Index %d ------- \n", i) + fmt.Println("MMR Entry:") + fmt.Println(mmrEntry) + fmt.Println("ExtraBytes:") + fmt.Println(massifs.GetExtraBytes(trieEntry, 0, 0)) + fmt.Println("IDTimestamp:") + fmt.Println(massifs.GetIdtimestamp(trieEntry, 0, 0)) + } +} From 6fc422c344a38cbeb867d9d95186c63ab997b61b Mon Sep 17 00:00:00 2001 From: Henry Jewell Date: Fri, 17 Jan 2025 11:16:53 +0000 Subject: [PATCH 2/4] add tests for inclusion proofs re AB#10216 --- logverification/app/appentry_test.go | 63 ++++++++++++++++++++++---- logverification/app/consts_test.go | 68 ++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 8 deletions(-) diff --git a/logverification/app/appentry_test.go b/logverification/app/appentry_test.go index 7dc1a7b..f1ee922 100644 --- a/logverification/app/appentry_test.go +++ b/logverification/app/appentry_test.go @@ -3,20 +3,22 @@ package app import ( "crypto/sha256" "encoding/binary" + "encoding/json" "fmt" "testing" "github.com/datatrails/go-datatrails-merklelog/massifs" + "github.com/datatrails/go-datatrails-serialization/eventsv1" + "github.com/datatrails/go-datatrails-simplehash/simplehash" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/zeebo/bencode" ) // testMassifContext generates a massif context with 2 entries // // 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{ @@ -150,14 +152,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 }, }, } @@ -174,3 +175,49 @@ 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) + + v3event, err := simplehash.V3FromEventJSON([]byte(logVersion0Event)) + assert.NoError(t, err) + + eventJson, err := json.Marshal(v3event) + assert.NoError(t, err) + + var jsonAny any + err = json.Unmarshal(eventJson, &jsonAny) + assert.NoError(t, err) + + serializedBytes, err := bencode.EncodeBytes(jsonAny) + assert.NoError(t, err) + + 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" + } +} + ` ) From d66b3ef455904b354758b79ee7a38f4abc8f78d6 Mon Sep 17 00:00:00 2001 From: Henry Jewell Date: Fri, 17 Jan 2025 12:32:03 +0000 Subject: [PATCH 3/4] fixup! add tests for inclusion proofs --- logverification/app/appentry_test.go | 22 ++----------- logverification/fetchmassif_not_test.go | 44 ------------------------- 2 files changed, 3 insertions(+), 63 deletions(-) delete mode 100644 logverification/fetchmassif_not_test.go diff --git a/logverification/app/appentry_test.go b/logverification/app/appentry_test.go index f1ee922..b605994 100644 --- a/logverification/app/appentry_test.go +++ b/logverification/app/appentry_test.go @@ -3,16 +3,13 @@ package app import ( "crypto/sha256" "encoding/binary" - "encoding/json" "fmt" "testing" "github.com/datatrails/go-datatrails-merklelog/massifs" "github.com/datatrails/go-datatrails-serialization/eventsv1" - "github.com/datatrails/go-datatrails-simplehash/simplehash" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zeebo/bencode" ) // testMassifContext generates a massif context with 2 entries @@ -49,7 +46,7 @@ func testMassifContext(t *testing.T) *massifs.MassifContext { 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("tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0"), + []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}, ) @@ -60,7 +57,7 @@ func testMassifContext(t *testing.T) *massifs.MassifContext { 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("tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0"), + []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}, ) @@ -71,8 +68,6 @@ func testMassifContext(t *testing.T) *massifs.MassifContext { return testMassifContext } -// TODO: Test inclusion proofs using the AppEntry methods with the KAT data. - // TestNewAppEntry tests: // // 1. we can get all non derived fields for the app entry getter @@ -199,18 +194,7 @@ func TestAppEntry_VerifyInclusionLogVersion1(t *testing.T) { func TestAppEntry_VerifyInclusionLogVersion0(t *testing.T) { testMassifContext := testMassifContext(t) - v3event, err := simplehash.V3FromEventJSON([]byte(logVersion0Event)) - assert.NoError(t, err) - - eventJson, err := json.Marshal(v3event) - assert.NoError(t, err) - - var jsonAny any - err = json.Unmarshal(eventJson, &jsonAny) - assert.NoError(t, err) - - serializedBytes, err := bencode.EncodeBytes(jsonAny) - assert.NoError(t, err) + serializedBytes := []byte(logVersion0Event) ae := &AppEntry{ mmrIndex: 0, diff --git a/logverification/fetchmassif_not_test.go b/logverification/fetchmassif_not_test.go deleted file mode 100644 index 7b55cce..0000000 --- a/logverification/fetchmassif_not_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package logverification - -import ( - "context" - "fmt" - "testing" - - "github.com/datatrails/go-datatrails-common/azblob" - "github.com/datatrails/go-datatrails-common/logger" - "github.com/datatrails/go-datatrails-merklelog/massifs" - "github.com/stretchr/testify/assert" -) - -func TestFetchMassif(t *testing.T) { - logger.New("NOOP") - - reader, err := azblob.NewReaderNoAuth( - "https://app.qa.stage.datatrails.ai/verifiabledata", - azblob.WithContainer("merklelogs"), - ) - assert.NoError(t, err) - - massifReader := massifs.NewMassifReader(logger.Sugar, reader) - - massifContext, err := massifReader.GetFirstMassif(context.Background(), "tenant/112758ce-a8cb-4924-8df8-fcba1e31f8b0") - assert.NoError(t, err) - - var i uint64 - for i = 0; i < 10; i++ { - mmrEntry, err := massifContext.Get(i) - assert.NoError(t, err) - - trieEntry, err := massifContext.GetTrieEntry(i) - assert.NoError(t, err) - - fmt.Printf("MMR Index %d ------- \n", i) - fmt.Println("MMR Entry:") - fmt.Println(mmrEntry) - fmt.Println("ExtraBytes:") - fmt.Println(massifs.GetExtraBytes(trieEntry, 0, 0)) - fmt.Println("IDTimestamp:") - fmt.Println(massifs.GetIdtimestamp(trieEntry, 0, 0)) - } -} From 5f4d1deae0dc5c0c6b4a9427578ec7bd1fdf1a33 Mon Sep 17 00:00:00 2001 From: Henry Jewell Date: Fri, 17 Jan 2025 12:34:51 +0000 Subject: [PATCH 4/4] fixup! fixup! add tests for inclusion proofs --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) 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=