diff --git a/thresholdkey.go b/thresholdkey.go index 41dd3e8..83f8ac6 100644 --- a/thresholdkey.go +++ b/thresholdkey.go @@ -97,8 +97,14 @@ func (tk *ThresholdPublicKey) updateCprime(cprime, lambda *big.Int, share *Parti return new(big.Int).Mod(ret, tk.GetNSquare()) } +// We use `exp` from `updateCprime` to raise decryption share to the power of lambda +// parameter. Since lambda can be a negative number and we do discrete math here, +// we need to apply multiplicative inverse modulo in this case. +// +// For instance, for b = -18: +// b^{−18} = (b^−1)^18, where b^{−1} is the multiplicative inverse modulo c. func (tk *ThresholdPublicKey) exp(a, b, c *big.Int) *big.Int { - if b.Cmp(ZERO) == -1 { + if b.Cmp(ZERO) == -1 { // b < 0 ? ret := new(big.Int).Exp(a, new(big.Int).Neg(b), c) return new(big.Int).ModInverse(ret, c) } diff --git a/thresholdkey_test.go b/thresholdkey_test.go index 698f3ab..b610a85 100644 --- a/thresholdkey_test.go +++ b/thresholdkey_test.go @@ -24,6 +24,22 @@ func TestDelta(t *testing.T) { } } +func TestExp(t *testing.T) { + tk := new(ThresholdPublicKey) + + if exp := tk.exp(big.NewInt(720), big.NewInt(10), big.NewInt(49)); 43 != n(exp) { + t.Error("Unexpected exponent. Expected 43 but got", exp) + } + + if exp := tk.exp(big.NewInt(720), big.NewInt(0), big.NewInt(49)); 1 != n(exp) { + t.Error("Unexpected exponent. Expected 0 but got", exp) + } + + if exp := tk.exp(big.NewInt(720), big.NewInt(-10), big.NewInt(49)); 8 != n(exp) { + t.Error("Unexpected exponent. Expected 8 but got", exp) + } +} + func TestCombineSharesConstant(t *testing.T) { tk := new(ThresholdPublicKey) tk.N = big.NewInt(101 * 103)