func SplitSecret()

in client/internal/secret_sharing/internal/shamirgeneric/shamir_generic.go [27:76]


func SplitSecret(metadata secrets.Metadata, secret []byte, gf field.GaloisField) (secrets.Split, error) {
	if err := validateSplitInput(metadata, secret, gf); err != nil {
		return secrets.Split{}, err
	}
	threshold := metadata.Threshold
	numShares := metadata.NumShares
	// The `secret` can be an arbitrary length byte array, but each element in a field is of
	// a finite size, hence the `secret` is split into a set of elements in the field.
	subsecrets := gf.DecodeElements(secret)
	shares := make([]secrets.Share, numShares)

	// For each subsecret we build a polynomial of degree N, where N is `threshold`.
	// Each subsecret is the constant coefficient in the polynomial and every other coefficient
	// is selected as a random field element:
	// subsecret + R_1 * x^1 + R_2 * X^2 + ... + R_N * X^N
	for _, subsecret := range subsecrets {
		coefficients := make([]field.Element, threshold, threshold)
		coefficients[0] = subsecret
		for i := 1; i < threshold; i++ {
			var err error
			if coefficients[i], err = gf.NewRandomNonZero(); err != nil {
				return secrets.Split{}, err
			}
		}
		for i := 0; i < numShares; i++ {
			// We create each sub-share by evaluating each polynomial for a subsecret
			// at a specific value `X`, this gives us the point (X, Y).
			xi, err := gf.CreateElement(i + 1)
			if err != nil {
				return secrets.Split{}, err
			}
			subshare, err := evaluatePolynomial(coefficients, xi, gf)
			if err != nil {
				return secrets.Split{}, err
			}
			// shares is a set of encoded field elements. Each field element is the evaluation of a
			// different polynomial where the constant term of each polynomial represents a subsecrets.
			// shares[0] = 			[ F1(1), F2(1), ..., FN(1) ]
			// shares[1] = 			[ F1(2), F2(2), ..., FN(2) ]
			// shares[N - 1] = 	[ F1(N), F2(N), ..., FN(N) ]
			shares[i].Value = append(shares[i].Value, subshare.Bytes()...)
			shares[i].X = i + 1
		}
	}
	return secrets.Split{
		Shares:    shares,
		Metadata:  metadata,
		SecretLen: len(secret),
	}, nil
}