From 9e72b533e81574b5bcc588dc42938be6bfcc9669 Mon Sep 17 00:00:00 2001 From: pcampones Date: Wed, 24 Jul 2024 17:28:06 +0100 Subject: [PATCH] Create method SetIntString in the Scalar interface to allow the creation of a large Scalar from a string. Previously, to create arbitrary numbers the methods SetInt64 or SetBytes had to be used. SetInt64 only allows the creation of 64 bit integers, while SetBytes requires the byte array representation of the number, which is inconvenient. --- group.go | 3 +++ group/edwards25519/scalar.go | 8 ++++++++ group/mod/int.go | 10 ++++++++++ pairing/bls12381/circl/scalar.go | 9 +++++++++ share/vss/pedersen/vss_test.go | 19 +++++++++++++++++-- 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/group.go b/group.go index 538300ffe..130cb57fe 100644 --- a/group.go +++ b/group.go @@ -35,6 +35,9 @@ type Scalar interface { // SetInt64 sets the receiver to a small integer value. SetInt64(v int64) Scalar + // SetIntString sets the receiver to a string encoded integer value. + SetIntString(v string) (Scalar, error) + // Set to the additive identity (0). Zero() Scalar diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index c295a5d5f..2a44b9ac7 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -59,6 +59,14 @@ func (s *scalar) SetInt64(v int64) kyber.Scalar { return s.setInt(mod.NewInt64(v, primeOrder)) } +func (s *scalar) SetIntString(v string) (kyber.Scalar, error) { + i, ok := new(big.Int).SetString(v, 0) + if !ok { + return nil, errors.New("invalid scalar string") + } + return s.setInt(mod.NewInt(i, primeOrder)), nil +} + func (s *scalar) toInt() *mod.Int { return mod.NewIntBytes(s.v[:], primeOrder, defaultEndianess) } diff --git a/group/mod/int.go b/group/mod/int.go index 741b5ca0e..a8d969414 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -6,6 +6,7 @@ import ( "crypto/cipher" "encoding/hex" "errors" + "fmt" "io" "math/big" @@ -173,6 +174,15 @@ func (i *Int) SetInt64(v int64) kyber.Scalar { return i } +func (i *Int) SetIntString(v string) (kyber.Scalar, error) { + bigV := new(big.Int) + bigV, ok := bigV.SetString(v, 0) + if !ok { + return nil, fmt.Errorf("unable to set string number: %v", v) + } + return i.Init(bigV, i.M), nil +} + // Int64 returns the int64 representation of the value. // If the value is not representable in an int64 the result is undefined. func (i *Int) Int64() int64 { diff --git a/pairing/bls12381/circl/scalar.go b/pairing/bls12381/circl/scalar.go index 17046ae44..f4d7e284f 100644 --- a/pairing/bls12381/circl/scalar.go +++ b/pairing/bls12381/circl/scalar.go @@ -2,6 +2,7 @@ package circl import ( "crypto/cipher" + "fmt" "io" "math/big" @@ -62,6 +63,14 @@ func (s *Scalar) SetInt64(v int64) kyber.Scalar { return s } +func (s *Scalar) SetIntString(v string) (kyber.Scalar, error) { + err := s.inner.SetString(v) + if err != nil { + return nil, fmt.Errorf("unable to set string number: %v", err) + } + return s, nil +} + func (s *Scalar) Zero() kyber.Scalar { s.inner.SetUint64(0); return s } func (s *Scalar) Add(a, b kyber.Scalar) kyber.Scalar { diff --git a/share/vss/pedersen/vss_test.go b/share/vss/pedersen/vss_test.go index ec903bbea..697e48a4e 100644 --- a/share/vss/pedersen/vss_test.go +++ b/share/vss/pedersen/vss_test.go @@ -64,7 +64,10 @@ func TestMinimumT(t *testing.T) { func TestVSSWhole(t *testing.T) { dealer, verifiers := genAll() + vssWhole(t, dealer, verifiers, secret) +} +func vssWhole(t *testing.T, dealer *Dealer, verifiers []*Verifier, secret kyber.Scalar) { // 1. dispatch deal resps := make([]*Response, nbVerifiers) encDeals, err := dealer.EncryptedDeals() @@ -591,6 +594,15 @@ func TestVSSContext(t *testing.T) { assert.Len(t, c, suite.Hash().Size()) } +func TestDeterministicStringSecret(t *testing.T) { + deterministicSec, err := suite.Scalar().SetIntString("0x123456789abcdef") + require.NoError(t, err) + dealer, err := NewDealer(suite, dealerSec, deterministicSec, verifiersPub, vssThreshold) + require.NoError(t, err) + verifiers := genVerifiers() + vssWhole(t, dealer, verifiers, deterministicSec) +} + func genPair() (kyber.Scalar, kyber.Point) { secret := suite.Scalar().Pick(suite.RandomStream()) public := suite.Point().Mul(secret, nil) @@ -612,13 +624,16 @@ func genDealer() *Dealer { } func genAll() (*Dealer, []*Verifier) { - dealer := genDealer() + return genDealer(), genVerifiers() +} + +func genVerifiers() []*Verifier { var verifiers = make([]*Verifier, nbVerifiers) for i := 0; i < nbVerifiers; i++ { v, _ := NewVerifier(suite, verifiersSec[i], dealerPub, verifiersPub) verifiers[i] = v } - return dealer, verifiers + return verifiers } func randomBytes(n int) []byte {