Skip to content

Commit ae87c6b

Browse files
matteoszK1li4nLAnomalRoil
authored
Bls12381 (#505)
* Added circl and kilic implementation of bls12381 + benchmarks * Added deserialization tests compressed vectors +more comments * Fix IBE in the drand merge (#514) * Add ByteOrder() function + constant from int.go * Update circl_bls12381 and edwards25519 scalars * Add Order() to the scalar interface * Adapt IBE to make it general * Fix dkg bug (#515) * BugFix: use array index instead of node index * Fix endianess bool * Add tests for endianess * Fixed deserialization tests + circl issue * Removed groupchecker iface * Added back circl deserialization test (cloudflare/circl#499) * Since Go 1.21 go mod tidy require the go directive to match the highest of our dependencies --------- Co-authored-by: Kilian <79536516+K1li4nL@users.noreply.github.com> Co-authored-by: Yolan Romailler <anomalroil@users.noreply.github.com>
1 parent 4485f5d commit ae87c6b

File tree

66 files changed

+1947
-555
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1947
-555
lines changed

encrypt/ibe/ibe.go

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package ibe
22

3-
/*
4-
53
import (
64
"bytes"
75
"crypto/rand"
@@ -10,7 +8,6 @@ import (
108
"fmt"
119

1210
"go.dedis.ch/kyber/v4"
13-
"go.dedis.ch/kyber/v4/group/mod"
1411
"go.dedis.ch/kyber/v4/pairing"
1512
"go.dedis.ch/kyber/v4/util/random"
1613
)
@@ -243,12 +240,9 @@ func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) {
243240
// we hash it a first time: buffer = hash("IBE-H3" || sigma || msg)
244241
buffer := h.Sum(nil)
245242

246-
hashable, ok := s.G1().Scalar().(*mod.Int)
247-
if !ok {
248-
return nil, fmt.Errorf("unable to instantiate scalar as a mod.Int")
249-
}
243+
hashable := s.G1().Scalar()
250244
canonicalBitLen := hashable.MarshalSize() * 8
251-
actualBitLen := hashable.M.BitLen()
245+
actualBitLen := hashable.GroupOrder().BitLen()
252246
toMask := canonicalBitLen - actualBitLen
253247

254248
for i := uint16(1); i < 65535; i++ {
@@ -263,7 +257,7 @@ func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) {
263257
// We then apply masking to our resulting bytes at the bit level
264258
// but we assume that toMask is a few bits, at most 8.
265259
// For instance when using BLS12-381 toMask == 1.
266-
if hashable.BO == mod.BigEndian {
260+
if hashable.ByteOrder() == kyber.BigEndian {
267261
hashed[0] = hashed[0] >> toMask
268262
} else {
269263
hashed[len(hashed)-1] = hashed[len(hashed)-1] >> toMask
@@ -399,4 +393,3 @@ func DecryptCPAonG1(s pairing.Suite, private kyber.Point, c *CiphertextCPA) ([]b
399393
}
400394
return xor(c.C, hGidT), nil
401395
}
402-
*/

encrypt/ibe/ibe_test.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package ibe
22

3-
/*
4-
53
import (
64
"encoding/hex"
75
"strings"
@@ -10,7 +8,7 @@ import (
108
"github.com/stretchr/testify/require"
119
"go.dedis.ch/kyber/v4"
1210
"go.dedis.ch/kyber/v4/pairing"
13-
bls "go.dedis.ch/kyber/v4/pairing/circl_bls12381"
11+
circl "go.dedis.ch/kyber/v4/pairing/bls12381/circl"
1412
"go.dedis.ch/kyber/v4/util/random"
1513
)
1614

@@ -23,7 +21,7 @@ func newSetting(i uint) (
2321
panic("invalid test")
2422
}
2523
if i == 1 {
26-
suite := bls.NewSuiteBLS12381()
24+
suite := circl.NewSuiteBLS12381()
2725
P := suite.G1().Point().Base()
2826
s := suite.G1().Scalar().Pick(random.New())
2927
Ppub := suite.G1().Point().Mul(s, P)
@@ -35,7 +33,7 @@ func newSetting(i uint) (
3533
return suite, Ppub, ID, sQid, EncryptCCAonG1, DecryptCCAonG1
3634
}
3735
// i == 2
38-
suite := bls.NewSuiteBLS12381()
36+
suite := circl.NewSuiteBLS12381()
3937
P := suite.G2().Point().Base()
4038
s := suite.G2().Scalar().Pick(random.New())
4139
Ppub := suite.G2().Point().Mul(s, P)
@@ -246,7 +244,7 @@ func TestBackwardsInteropWithTypescript(t *testing.T) {
246244
}
247245

248246
func TestCPAEncryptOnG1(t *testing.T) {
249-
suite := bls.NewSuiteBLS12381()
247+
suite := circl.NewSuiteBLS12381()
250248
P := suite.G1().Point().Pick(random.New())
251249
s := suite.G1().Scalar().Pick(random.New())
252250
Ppub := suite.G1().Point().Mul(s, P)
@@ -261,4 +259,3 @@ func TestCPAEncryptOnG1(t *testing.T) {
261259
require.NoError(t, err)
262260
require.Equal(t, msg, msg2)
263261
}
264-
*/

go.mod

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
module go.dedis.ch/kyber/v4
22

3-
go 1.20
3+
go 1.21
44

55
require (
6-
github.com/cloudflare/circl v1.3.7
6+
github.com/cloudflare/circl v1.3.9
77
github.com/consensys/gnark-crypto v0.12.1
88
github.com/jonboulle/clockwork v0.4.0
9+
github.com/kilic/bls12-381 v0.1.0
910
github.com/stretchr/testify v1.9.0
1011
go.dedis.ch/fixbuf v1.0.3
1112
go.dedis.ch/protobuf v1.0.11
1213
golang.org/x/crypto v0.21.0
1314
golang.org/x/sys v0.18.0
15+
gopkg.in/yaml.v3 v3.0.1
1416
)
1517

1618
require (
@@ -21,6 +23,5 @@ require (
2123
github.com/mmcloughlin/addchain v0.4.0 // indirect
2224
github.com/pmezard/go-difflib v1.0.0 // indirect
2325
github.com/rogpeppe/go-internal v1.9.0 // indirect
24-
gopkg.in/yaml.v3 v3.0.1 // indirect
2526
rsc.io/tmplfunc v0.0.3 // indirect
2627
)

go.sum

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
22
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
3-
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
4-
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
3+
github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
4+
github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
55
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
66
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
77
github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
@@ -13,10 +13,14 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
1313
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
1414
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
1515
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
16+
github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4=
17+
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
1618
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
19+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
1720
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
1821
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
1922
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
23+
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
2024
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
2125
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
2226
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
@@ -41,10 +45,12 @@ golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnf
4145
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
4246
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
4347
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
48+
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4449
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
4550
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
4651
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
4752
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
53+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
4854
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
4955
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
5056
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=

group.go

+28-11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ package kyber
22

33
import (
44
"crypto/cipher"
5+
"math/big"
6+
)
7+
8+
// ByteOrder denotes the endianness of the operation.
9+
type ByteOrder bool
10+
11+
const (
12+
// LittleEndian endianness
13+
LittleEndian ByteOrder = true
14+
// BigEndian endianness
15+
BigEndian ByteOrder = false
516
)
617

718
// Scalar represents a scalar value by which
@@ -56,6 +67,12 @@ type Scalar interface {
5667
// The endianess of the byte-slice is determined by the
5768
// implementation.
5869
SetBytes([]byte) Scalar
70+
71+
// ByteOrder return the byte representation type (big or little endian)
72+
ByteOrder() ByteOrder
73+
74+
// GroupOrder returns the order of the underlying group
75+
GroupOrder() *big.Int
5976
}
6077

6178
// Point represents an element of a public-key cryptographic Group.
@@ -112,17 +129,6 @@ type Point interface {
112129
Mul(s Scalar, p Point) Point
113130
}
114131

115-
// SubGroupElement allows to verify if a Point is in the correct group or not.
116-
// For curves which don't have a prime order, we need to only consider the
117-
// points lying in the subgroup of prime order. That check returns true if the
118-
// point is correct or not. If the curve forms already a prime order// group,
119-
// then this method should be implemented as a nop returning true, to be able to
120-
// use the Schnorr signature scheme for example.
121-
type SubGroupElement interface {
122-
Point
123-
IsInCorrectGroup() bool
124-
}
125-
126132
// AllowsVarTime allows callers to determine if a given kyber.Scalar
127133
// or kyber.Point supports opting-in to variable time operations. If
128134
// an object implements AllowsVarTime, then the caller can use
@@ -174,3 +180,14 @@ type Group interface {
174180
PointLen() int // Max length of point in bytes
175181
Point() Point // Create new point
176182
}
183+
184+
// SubGroupElement allows to verify if a Point is in the correct group or not.
185+
// For curves which don't have a prime order, we need to only consider the
186+
// points lying in the subgroup of prime order. That check returns true if the
187+
// point is correct or not. If the curve forms already a prime order// group,
188+
// then this method should be implemented as a nop returning true, to be able to
189+
// use the Schnorr signature scheme for example.
190+
type SubGroupElement interface {
191+
Point
192+
IsInCorrectGroup() bool
193+
}

group/edwards25519/scalar.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
// The scalars are GF(2^252 + 27742317777372353535851937790883648493).
2525

2626
var marshalScalarID = [8]byte{'e', 'd', '.', 's', 'c', 'a', 'l', 'a'}
27+
var defaultEndianess = kyber.LittleEndian
2728

2829
type scalar struct {
2930
v [32]byte
@@ -60,7 +61,7 @@ func (s *scalar) SetInt64(v int64) kyber.Scalar {
6061
}
6162

6263
func (s *scalar) toInt() *mod.Int {
63-
return mod.NewIntBytes(s.v[:], primeOrder, mod.LittleEndian)
64+
return mod.NewIntBytes(s.v[:], primeOrder, defaultEndianess)
6465
}
6566

6667
// Set to the additive identity (0)
@@ -140,7 +141,17 @@ func (s *scalar) Pick(rand cipher.Stream) kyber.Scalar {
140141

141142
// SetBytes s to b, interpreted as a little endian integer.
142143
func (s *scalar) SetBytes(b []byte) kyber.Scalar {
143-
return s.setInt(mod.NewIntBytes(b, primeOrder, mod.LittleEndian))
144+
return s.setInt(mod.NewIntBytes(b, primeOrder, defaultEndianess))
145+
}
146+
147+
// ByteOrder return the byte representation type (big or little endian)
148+
func (s *scalar) ByteOrder() kyber.ByteOrder {
149+
return defaultEndianess
150+
}
151+
152+
// GroupOrder returns the order of the underlying group
153+
func (s *scalar) GroupOrder() *big.Int {
154+
return big.NewInt(0).SetBytes(primeOrder.Bytes())
144155
}
145156

146157
// String returns the string representation of this scalar (fixed length of 32 bytes, little endian).

group/mod/int.go

+21-21
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@ var one = big.NewInt(1)
1818
var two = big.NewInt(2)
1919
var marshalScalarID = [8]byte{'m', 'o', 'd', '.', 'i', 'n', 't', ' '}
2020

21-
// ByteOrder denotes the endianness of the operation.
22-
type ByteOrder bool
23-
24-
const (
25-
// LittleEndian endianness
26-
LittleEndian ByteOrder = true
27-
// BigEndian endianness
28-
BigEndian ByteOrder = false
29-
)
30-
3121
// Int is a generic implementation of finite field arithmetic
3222
// on integer finite fields with a given constant modulus,
3323
// built using Go's built-in big.Int package.
@@ -47,9 +37,9 @@ const (
4737
// For efficiency the modulus field M is a pointer,
4838
// whose target is assumed never to change.
4939
type Int struct {
50-
V big.Int // Integer value from 0 through M-1
51-
M *big.Int // Modulus for finite field arithmetic
52-
BO ByteOrder // Endianness which will be used on input and output
40+
V big.Int // Integer value from 0 through M-1
41+
M *big.Int // Modulus for finite field arithmetic
42+
BO kyber.ByteOrder // Endianness which will be used on input and output
5343
}
5444

5545
// NewInt creaters a new Int with a given big.Int and a big.Int modulus.
@@ -64,7 +54,7 @@ func NewInt64(v int64, M *big.Int) *Int {
6454

6555
// NewIntBytes creates a new Int with a given slice of bytes and a big.Int
6656
// modulus.
67-
func NewIntBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int {
57+
func NewIntBytes(a []byte, m *big.Int, byteOrder kyber.ByteOrder) *Int {
6858
return new(Int).InitBytes(a, m, byteOrder)
6959
}
7060

@@ -78,21 +68,21 @@ func NewIntString(n, d string, base int, m *big.Int) *Int {
7868
// Note that the value is copied; the modulus is not.
7969
func (i *Int) Init(V *big.Int, m *big.Int) *Int {
8070
i.M = m
81-
i.BO = BigEndian
71+
i.BO = kyber.BigEndian
8272
i.V.Set(V).Mod(&i.V, m)
8373
return i
8474
}
8575

8676
// Init64 creates an Int with an int64 value and big.Int modulus.
8777
func (i *Int) Init64(v int64, m *big.Int) *Int {
8878
i.M = m
89-
i.BO = BigEndian
79+
i.BO = kyber.BigEndian
9080
i.V.SetInt64(v).Mod(&i.V, m)
9181
return i
9282
}
9383

9484
// InitBytes init the Int to a number represented in a big-endian byte string.
95-
func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int {
85+
func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder kyber.ByteOrder) *Int {
9686
i.M = m
9787
i.BO = byteOrder
9888
i.SetBytes(a)
@@ -103,7 +93,7 @@ func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int {
10393
// specified with a pair of strings in a given base.
10494
func (i *Int) InitString(n, d string, base int, m *big.Int) *Int {
10595
i.M = m
106-
i.BO = BigEndian
96+
i.BO = kyber.BigEndian
10797
if _, succ := i.SetString(n, d, base); !succ {
10898
panic("InitString: invalid fraction representation")
10999
}
@@ -302,6 +292,16 @@ func (i *Int) Pick(rand cipher.Stream) kyber.Scalar {
302292
return i
303293
}
304294

295+
// ByteOrder return the byte representation type (big or little endian)
296+
func (i *Int) ByteOrder() kyber.ByteOrder {
297+
return i.BO
298+
}
299+
300+
// GroupOrder returns the order of the underlying group
301+
func (i *Int) GroupOrder() *big.Int {
302+
return big.NewInt(0).Set(i.M)
303+
}
304+
305305
// MarshalSize returns the length in bytes of encoded integers with modulus M.
306306
// The length of encoded Ints depends only on the size of the modulus,
307307
// and not on the the value of the encoded integer,
@@ -317,7 +317,7 @@ func (i *Int) MarshalBinary() ([]byte, error) {
317317
b := i.V.Bytes() // may be shorter than l
318318
offset := l - len(b)
319319

320-
if i.BO == LittleEndian {
320+
if i.BO == kyber.LittleEndian {
321321
return i.LittleEndian(l, l), nil
322322
}
323323

@@ -342,7 +342,7 @@ func (i *Int) UnmarshalBinary(buf []byte) error {
342342
return errors.New("UnmarshalBinary: wrong size buffer")
343343
}
344344
// Still needed here because of the comparison with the modulo
345-
if i.BO == LittleEndian {
345+
if i.BO == kyber.LittleEndian {
346346
buf = reverse(nil, buf)
347347
}
348348
i.V.SetBytes(buf)
@@ -384,7 +384,7 @@ func (i *Int) BigEndian(min, max int) []byte {
384384
// Endianness depends on the endianess set in i.
385385
func (i *Int) SetBytes(a []byte) kyber.Scalar {
386386
var buff = a
387-
if i.BO == LittleEndian {
387+
if i.BO == kyber.LittleEndian {
388388
buff = reverse(nil, a)
389389
}
390390
i.V.SetBytes(buff).Mod(&i.V, i.M)

0 commit comments

Comments
 (0)