client/internal/secret_sharing/shamir/shamir.go (37 lines of code) (raw):
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package shamir encapsulates all of the logic needed to perform t-of-n [Shamir
// Secret Sharing] (SSS) on arbitrary-size secrets over
// a finite field. SSS is based on the Lagrange interpolation theorem, which
// states that `k` points are enough to uniquely determine a polynomial of
// degree less than or equal to `k - 1`.
//
// This scheme is secure under the following assumptions:
// - The scheme requires a trusted dealer to generate the shares. Participants
// must trust the dealer with access to the secret and to properly generate the
// shares.
// - The scheme assumes a passive adversary which can observe (n - t) shares
// without being able to reconstruct the secrets. However, this scheme
// assumes the adversary isn't allowed to participate in the `reconstruct` step by
// providing a chosen share.
// Examples of this attack: https://crypto.stackexchange.com/q/41994/76875
//
// [Shamir Secret Sharing]: https://web.mit.edu/6.857/OldStuff/Fall03/ref/Shamir-HowToShareAsecrets.pdf
package shamir
import (
"fmt"
"github.com/GoogleCloudPlatform/stet/client/internal/secret_sharing/finitefield"
"github.com/GoogleCloudPlatform/stet/client/internal/secret_sharing/internal/field"
"github.com/GoogleCloudPlatform/stet/client/internal/secret_sharing/internal/field/gf32"
"github.com/GoogleCloudPlatform/stet/client/internal/secret_sharing/internal/field/gf8"
"github.com/GoogleCloudPlatform/stet/client/internal/secret_sharing/internal/shamirgeneric"
"github.com/GoogleCloudPlatform/stet/client/internal/secret_sharing/secrets"
)
func createField(fieldID finitefield.ID) (field.GaloisField, error) {
switch fieldID {
case finitefield.GF32:
return gf32.New(), nil
case finitefield.GF8:
return gf8.New(), nil
default:
return nil, fmt.Errorf("invalid field: %q", fieldID)
}
}
// SplitSecret splits a secret into metadata.NumShares shares where metadata.Threshold
// or more shares can be combined to reconstruct the original secret.
func SplitSecret(metadata secrets.Metadata, secret []byte) (secrets.Split, error) {
f, err := createField(metadata.Field)
if err != nil {
return secrets.Split{}, err
}
return shamirgeneric.SplitSecret(metadata, secret, f)
}
// Reconstruct reconstructs the secret from secretSplit.
//
// The number of shares provided must meet the threshold specified when the
// shares were created by [SplitSecret].
//
// Reconstruct will not detect bogus or corrupted shares.
func Reconstruct(secretSplit secrets.Split) ([]byte, error) {
if len(secretSplit.Shares) == 0 {
return nil, fmt.Errorf("no shares provided")
}
f, err := createField(secretSplit.Metadata.Field)
if err != nil {
return nil, err
}
return shamirgeneric.Reconstruct(secretSplit, f)
}