Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tss/rsa: Fixes RSA signature size. #395

Merged
merged 1 commit into from Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions tss/rsa/keyshare.go
Expand Up @@ -23,6 +23,11 @@ type KeyShare struct {
Threshold uint
}

func (kshare KeyShare) String() string {
return fmt.Sprintf("(t,n): (%v,%v) index: %v si: 0x%v",
kshare.Threshold, kshare.Players, kshare.Index, kshare.si.Text(16))
}

// MarshalBinary encodes a KeyShare into a byte array in a format readable by UnmarshalBinary.
// Note: Only Index's up to math.MaxUint16 are supported
func (kshare *KeyShare) MarshalBinary() ([]byte, error) {
Expand Down
20 changes: 16 additions & 4 deletions tss/rsa/rsa_threshold.go
Expand Up @@ -199,22 +199,34 @@ func CombineSignShares(pub *rsa.PublicKey, shares []SignShare, msg []byte) (Sign
// e′a + eb = 1
a := big.Int{}
b := big.Int{}
e := big.NewInt(int64(pub.E))
tmp := big.Int{}
tmp.GCD(&a, &b, &eprime, big.NewInt(int64(pub.E)))
tmp.GCD(&a, &b, &eprime, e)

// TODO You can compute a earlier and multiply a into the exponents used when computing w.
// w^a
wa := big.Int{}
wa.Exp(w, &a, pub.N) // TODO justification
// x^b
x := big.Int{}
x.SetBytes(msg)
xb := big.Int{}
xb.SetBytes(msg)
xb.Exp(&xb, &b, pub.N) // TODO justification
xb.Exp(&x, &b, pub.N) // TODO justification
// y = w^a * x^b
y := big.Int{}
y.Mul(&wa, &xb).Mod(&y, pub.N)

return y.Bytes(), nil
// verify that signature is valid by checking x == y^e.
ye := big.Int{}
ye.Exp(&y, e, pub.N)
if ye.Cmp(&x) != 0 {
return nil, errors.New("rsa: internal error")
}

// ensure signature has the right size.
sig := y.FillBytes(make([]byte, pub.Size()))

return sig, nil
}

// computes lagrange Interpolation for the shares
Expand Down
26 changes: 15 additions & 11 deletions tss/rsa/rsa_threshold_test.go
Expand Up @@ -159,10 +159,9 @@ const (
PSS = 1
)

func testIntegration(t *testing.T, algo crypto.Hash, pub *rsa.PublicKey, threshold uint, keys []KeyShare, padScheme int) {
t.Logf("dealt %d keys", len(keys))

func testIntegration(t *testing.T, algo crypto.Hash, priv *rsa.PrivateKey, threshold uint, keys []KeyShare, padScheme int) {
msg := []byte("hello")
pub := &priv.PublicKey

var padder Padder
if padScheme == PKS1v15 {
Expand Down Expand Up @@ -190,14 +189,13 @@ func testIntegration(t *testing.T, algo crypto.Hash, pub *rsa.PublicKey, thresho
}
}

t.Logf("signed with %d keys", len(signshares))

sig, err := CombineSignShares(pub, signshares, msgPH)
if err != nil {
t.Fatal(err)
}

t.Log("combined sign shares")
if len(sig) != pub.Size() {
t.Fatal("bad signature size")
}

h := algo.New()
h.Write(msg)
Expand All @@ -212,6 +210,14 @@ func testIntegration(t *testing.T, algo crypto.Hash, pub *rsa.PublicKey, thresho
}

if err != nil {
t.Logf("d: %v p: %v q: %v\n", priv.D.Text(16), priv.Primes[0].Text(16), priv.Primes[1].Text(16))
for i, k := range keys {
t.Logf("keys[%v]: %v\n", i, k)
}
for i, s := range signshares {
t.Logf("signShares[%v]: %v\n", i, s)
}
t.Logf("sig: %x\n", sig)
t.Fatal(err)
}
}
Expand All @@ -223,15 +229,14 @@ func TestIntegrationStdRsaKeyGenerationPKS1v15(t *testing.T) {
const algo = crypto.SHA256

key, err := rsa.GenerateKey(rand.Reader, bits)
pub := key.PublicKey
if err != nil {
t.Fatal(err)
}
keys, err := Deal(rand.Reader, players, threshold, key, false)
if err != nil {
t.Fatal(err)
}
testIntegration(t, algo, &pub, threshold, keys, PKS1v15)
testIntegration(t, algo, key, threshold, keys, PKS1v15)
}

func TestIntegrationStdRsaKeyGenerationPSS(t *testing.T) {
Expand All @@ -241,15 +246,14 @@ func TestIntegrationStdRsaKeyGenerationPSS(t *testing.T) {
const algo = crypto.SHA256

key, err := rsa.GenerateKey(rand.Reader, bits)
pub := key.PublicKey
if err != nil {
t.Fatal(err)
}
keys, err := Deal(rand.Reader, players, threshold, key, false)
if err != nil {
t.Fatal(err)
}
testIntegration(t, algo, &pub, threshold, keys, PSS)
testIntegration(t, algo, key, threshold, keys, PSS)
}

// nolint: unparam
Expand Down
5 changes: 5 additions & 0 deletions tss/rsa/signShare.go
Expand Up @@ -17,6 +17,11 @@ type SignShare struct {
Threshold uint
}

func (s SignShare) String() string {
return fmt.Sprintf("(t,n): (%v,%v) index: %v xi: 0x%v",
s.Threshold, s.Players, s.Index, s.xi.Text(16))
}

// MarshalBinary encodes SignShare into a byte array in a format readable by UnmarshalBinary.
// Note: Only Index's up to math.MaxUint16 are supported
func (s *SignShare) MarshalBinary() ([]byte, error) {
Expand Down