diff --git a/aead/xchacha20poly1305/key.go b/aead/xchacha20poly1305/key.go index 7e29590..e67d7d0 100644 --- a/aead/xchacha20poly1305/key.go +++ b/aead/xchacha20poly1305/key.go @@ -18,6 +18,7 @@ import ( "bytes" "fmt" + "github.com/tink-crypto/tink-go/v2/internal/internalapi" "github.com/tink-crypto/tink-go/v2/internal/outputprefix" "github.com/tink-crypto/tink-go/v2/key" "github.com/tink-crypto/tink-go/v2/secretdata" @@ -161,3 +162,22 @@ func (k *Key) Equal(other key.Key) bool { k.idRequirement == that.idRequirement && k.keyBytes.Equal(that.keyBytes) } + +func createKey(p key.Parameters, idRequirement uint32) (key.Key, error) { + xChaCha20Poly1305Params, ok := p.(*Parameters) + if !ok { + return nil, fmt.Errorf("key is of type %T; needed %T", p, (*Parameters)(nil)) + } + keyBytes, err := secretdata.NewBytesFromRand(uint32(32)) + if err != nil { + return nil, err + } + return NewKey(keyBytes, idRequirement, xChaCha20Poly1305Params) +} + +// KeyCreator returns a key creator function. +// +// It is *NOT* part of the public API. +func KeyCreator(t internalapi.Token) func(p key.Parameters, idRequirement uint32) (key.Key, error) { + return createKey +} diff --git a/aead/xchacha20poly1305/key_test.go b/aead/xchacha20poly1305/key_test.go index 6b4f026..90ff75a 100644 --- a/aead/xchacha20poly1305/key_test.go +++ b/aead/xchacha20poly1305/key_test.go @@ -18,9 +18,11 @@ import ( "bytes" "testing" + "github.com/google/go-cmp/cmp" "github.com/tink-crypto/tink-go/v2/aead/xchacha20poly1305" "github.com/tink-crypto/tink-go/v2/core/cryptofmt" "github.com/tink-crypto/tink-go/v2/insecuresecretdataaccess" + "github.com/tink-crypto/tink-go/v2/internal/internalapi" "github.com/tink-crypto/tink-go/v2/secretdata" ) @@ -315,3 +317,28 @@ func TestKeyEqualReturnsFalseIfDifferent(t *testing.T) { }) } } + +func TestKeyCreator(t *testing.T) { + keyCreator := xchacha20poly1305.KeyCreator(internalapi.Token{}) + params, err := xchacha20poly1305.NewParameters(xchacha20poly1305.VariantTink) + if err != nil { + t.Fatalf("xchacha20poly1305.NewParameters() err = %v, want nil", err) + } + + key, err := keyCreator(params, 123) + if err != nil { + t.Fatalf("keyCreator(%v, 123) err = %v, want nil", params, err) + } + xChaCha20Poly1305, ok := key.(*xchacha20poly1305.Key) + if !ok { + t.Fatalf("keyCreator(%v, 123) returned key of type %T, want %T", params, key, (*xchacha20poly1305.Key)(nil)) + } + + idRequirement, hasIDRequirement := xChaCha20Poly1305.IDRequirement() + if !hasIDRequirement || idRequirement != 123 { + t.Errorf("xChaCha20Poly1305.IDRequirement() (%v, %v), want (%v, %v)", idRequirement, hasIDRequirement, 123, true) + } + if diff := cmp.Diff(xChaCha20Poly1305.Parameters(), params); diff != "" { + t.Errorf("xChaCha20Poly1305.Parameters() diff (-want +got):\n%s", diff) + } +} diff --git a/internal/keygenconfig/v0.go b/internal/keygenconfig/v0.go index 7b90d93..ae73cc2 100644 --- a/internal/keygenconfig/v0.go +++ b/internal/keygenconfig/v0.go @@ -23,6 +23,7 @@ import ( "github.com/tink-crypto/tink-go/v2/aead/aesgcmsiv" "github.com/tink-crypto/tink-go/v2/aead/chacha20poly1305" "github.com/tink-crypto/tink-go/v2/aead/xaesgcm" + "github.com/tink-crypto/tink-go/v2/aead/xchacha20poly1305" "github.com/tink-crypto/tink-go/v2/internal/internalapi" ) @@ -46,6 +47,9 @@ func mustCreateConfigV0() Config { if err := config.RegisterKeyCreator(reflect.TypeFor[*xaesgcm.Parameters](), xaesgcm.KeyCreator(internalapi.Token{})); err != nil { panic(fmt.Sprintf("keygenconfig: failed to register XAES-GCM: %v", err)) } + if err := config.RegisterKeyCreator(reflect.TypeFor[*xchacha20poly1305.Parameters](), xchacha20poly1305.KeyCreator(internalapi.Token{})); err != nil { + panic(fmt.Sprintf("keygenconfig: failed to register XChaCha20-Poly1305: %v", err)) + } return *config } diff --git a/internal/keygenconfig/v0_test.go b/internal/keygenconfig/v0_test.go index dabe647..887a64d 100644 --- a/internal/keygenconfig/v0_test.go +++ b/internal/keygenconfig/v0_test.go @@ -23,6 +23,7 @@ import ( "github.com/tink-crypto/tink-go/v2/aead/aesgcmsiv" "github.com/tink-crypto/tink-go/v2/aead/chacha20poly1305" "github.com/tink-crypto/tink-go/v2/aead/xaesgcm" + "github.com/tink-crypto/tink-go/v2/aead/xchacha20poly1305" "github.com/tink-crypto/tink-go/v2/internal/keygenconfig" "github.com/tink-crypto/tink-go/v2/key" ) @@ -84,6 +85,15 @@ func mustCreateXAESGCMParams(t *testing.T, variant xaesgcm.Variant) *xaesgcm.Par return params } +func mustCreateXChaCha20Poly1305Params(t *testing.T, variant xchacha20poly1305.Variant) *xchacha20poly1305.Parameters { + t.Helper() + params, err := xchacha20poly1305.NewParameters(variant) + if err != nil { + t.Fatalf("xchacha20poly1305.NewParameters() err = %v, want nil", err) + } + return params +} + func tryCast[T any](k key.Key) error { if _, ok := k.(T); !ok { return fmt.Errorf("key is of type %T; want %T", k, (*T)(nil)) @@ -159,6 +169,18 @@ func TestV0(t *testing.T) { idRequirement: 0, tryCast: tryCast[*xaesgcm.Key], }, + { + name: "XChaCha20Poly1305-TINK", + p: mustCreateXChaCha20Poly1305Params(t, xchacha20poly1305.VariantTink), + idRequirement: 123, + tryCast: tryCast[*xchacha20poly1305.Key], + }, + { + name: "XChaCha20Poly1305-NO_PREFIX", + p: mustCreateXChaCha20Poly1305Params(t, xchacha20poly1305.VariantNoPrefix), + idRequirement: 0, + tryCast: tryCast[*xchacha20poly1305.Key], + }, } { t.Run(tc.name, func(t *testing.T) { key, err := config.CreateKey(tc.p, tc.idRequirement)