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

Updating our dependencies and patching a bug in bn254/twist #62

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: '1.18'
go-version: '1.22.10'

- name: Run tests
run: make test
44 changes: 27 additions & 17 deletions encrypt/ibe/ibe.go
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import (
"encoding/binary"
"errors"
"fmt"

"github.com/drand/kyber"
"github.com/drand/kyber/group/mod"
"github.com/drand/kyber/pairing"
@@ -70,7 +71,7 @@ func EncryptCCAonG1(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphe
return nil, err
}
// 4. Compute U = rP
U := s.G1().Point().Mul(r, s.G1().Point().Base())
U := s.G1().Point().Mul(r, nil)

// 5. Compute V = sigma XOR H2(rGid)
rGid := Gid.Mul(r, Gid) // even in Gt, it's additive notation
@@ -124,7 +125,7 @@ func DecryptCCAonG1(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte
if err != nil {
return nil, err
}
rP := s.G1().Point().Mul(r, s.G1().Point().Base())
rP := s.G1().Point().Mul(r, nil)
if !rP.Equal(c.U) {
return nil, fmt.Errorf("invalid proof: rP check failed")
}
@@ -165,11 +166,13 @@ func EncryptCCAonG2(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphe
return nil, err
}
// 4. Compute U = rP
U := s.G2().Point().Mul(r, s.G2().Point().Base())
U := s.G2().Point().Mul(r, nil)

// 5. Compute V = sigma XOR H2(rGid)
rGid := Gid.Mul(r, Gid) // even in Gt, it's additive notation

hrGid, err := gtToHash(s, rGid, len(msg))

if err != nil {
return nil, err
}
@@ -197,6 +200,7 @@ func DecryptCCAonG2(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte

// 1. Compute sigma = V XOR H2(e(rP,private))
rGid := s.Pair(private, c.U)

hrGid, err := gtToHash(s, rGid, len(c.W))
if err != nil {
return nil, err
@@ -219,9 +223,9 @@ func DecryptCCAonG2(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte
if err != nil {
return nil, err
}
rP := s.G2().Point().Mul(r, s.G2().Point().Base())
rP := s.G2().Point().Mul(r, nil)
if !rP.Equal(c.U) {
return nil, fmt.Errorf("invalid proof: rP check failed")
return nil, fmt.Errorf("invalid proof: rP check failed on msg %s, r %x", msg, r)
}
return msg, nil
}
@@ -230,6 +234,10 @@ func DecryptCCAonG2(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte
func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) {
h := s.Hash()

if h.Size() != s.G1().ScalarLen() {
return nil, fmt.Errorf("hash size mismatch with scalar length %d != %d", h.Size(), s.G1().ScalarLen())
}

if _, err := h.Write(H3Tag()); err != nil {
return nil, fmt.Errorf("err hashing h3 tag: %v", err)
}
@@ -265,9 +273,10 @@ func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) {
} else {
hashed[len(hashed)-1] = hashed[len(hashed)-1] >> toMask
}

// NOTE: Here we unmarshal as a test if the buffer is within the modulo
// because we know unmarshal does this test. This implementation
// is almost generic if not for this line. TO make it truly generic
// is almost generic if not for this line. To make it truly generic
// we would need to add methods to create a scalar from bytes without
// reduction and a method to check if it is within the modulo on the
// Scalar interface.
@@ -288,9 +297,8 @@ func h4(s pairing.Suite, sigma []byte, length int) ([]byte, error) {
if _, err := h4.Write(sigma); err != nil {
return nil, fmt.Errorf("err writing sigma to h4: %v", err)
}
h4sigma := h4.Sum(nil)[:length]

return h4sigma, nil
return h4.Sum(nil)[:length], nil
}

func gtToHash(s pairing.Suite, gt kyber.Point, length int) ([]byte, error) {
@@ -339,13 +347,15 @@ type CiphertextCPA struct {
// H1: {0,1}^n -> G1
// H2: GT -> {0,1}^n
// ID: Qid = H1(ID) = xP \in G2
// secret did = s*Qid \in G2
//
// secret did = s*Qid \in G2
//
// Encrypt:
// - random r scalar
// - Gid = e(Ppub, r*Qid) == e(P, P)^(x*s*r) \in GT
// = GidT
// - U = rP \in G1,
// - V = M XOR H2(Gid)) = M XOR H2(GidT) \in {0,1}^n
// - random r scalar
// - Gid = e(Ppub, r*Qid) == e(P, P)^(x*s*r) \in GT
// = GidT
// - U = rP \in G1,
// - V = M XOR H2(Gid)) = M XOR H2(GidT) \in {0,1}^n
func EncryptCPAonG1(s pairing.Suite, basePoint, public kyber.Point, ID, msg []byte) (*CiphertextCPA, error) {
if len(msg)>>16 > 0 {
// we're using blake2 as XOF which only outputs 2^16-1 length
@@ -382,9 +392,9 @@ func EncryptCPAonG1(s pairing.Suite, basePoint, public kyber.Point, ID, msg []by
// SigGroup = G2 (large secret identities)
// KeyGroup = G1 (short master public keys)
// Decrypt:
// - V XOR H2(e(U, did)) = V XOR H2(e(rP, s*Qid))
// = V XOR H2(e(P, P)^(r*s*x))
// = V XOR H2(GidT) = M
// - V XOR H2(e(U, did)) = V XOR H2(e(rP, s*Qid))
// = V XOR H2(e(P, P)^(r*s*x))
// = V XOR H2(GidT) = M
func DecryptCPAonG1(s pairing.Suite, private kyber.Point, c *CiphertextCPA) ([]byte, error) {
GidT := s.Pair(c.RP, private)
hGidT, err := gtToHash(s, GidT, len(c.C))
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
module github.com/drand/kyber

go 1.18
go 1.22.10

require (
github.com/cloudflare/circl v1.3.7
github.com/consensys/gnark-crypto v0.12.1
github.com/cloudflare/circl v1.5.0
github.com/consensys/gnark-crypto v0.14.0
github.com/drand/kyber-bls12381 v0.3.1
github.com/jonboulle/clockwork v0.4.0
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
go.dedis.ch/fixbuf v1.0.3
go.dedis.ch/protobuf v1.0.11
golang.org/x/crypto v0.21.0
golang.org/x/sys v0.18.0
golang.org/x/crypto v0.30.0
golang.org/x/sys v0.28.0
)

require (
github.com/bits-and-blooms/bitset v1.13.0 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/bits-and-blooms/bitset v1.19.1 // indirect
github.com/consensys/bavard v0.1.22 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kilic/bls12-381 v0.1.0 // indirect
github.com/kr/text v0.2.0 // indirect
33 changes: 18 additions & 15 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/bits-and-blooms/bitset v1.19.1 h1:mv2yVhy96D2CuskLPXnc58oJNMs5PCWjAZuyYU0p12M=
github.com/bits-and-blooms/bitset v1.19.1/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A=
github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs=
github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E=
github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -18,9 +18,11 @@ github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK
github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4=
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=
github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c=
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
@@ -30,8 +32,8 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw=
go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ=
@@ -42,14 +44,15 @@ go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI
go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo=
go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4=
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
2 changes: 1 addition & 1 deletion pairing/bn254/gfp_decl.go
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import (

var hasBMI2 = cpu.X86.HasBMI2

// go:noescape
//go:noescape
func gfpNeg(c, a *gfP)

//go:noescape
19 changes: 12 additions & 7 deletions pairing/bn254/point.go
Original file line number Diff line number Diff line change
@@ -193,7 +193,7 @@ func (p *pointG1) ElementSize() int {
}

func (p *pointG1) String() string {
return "bn254.G1" + p.g.String()
return "bn254.G1(DST: " + string(p.dst) + ")" + p.g.String()
}

func (p *pointG1) Hash(m []byte) kyber.Point {
@@ -342,16 +342,21 @@ func (p *pointG2) Equal(q kyber.Point) bool {
return subtle.ConstantTimeCompare(x, y) == 1
}

// Null returns the point p set to Infinity on G2. Be careful: it mutates p.
// Consider using Clone if you're using this in a comparison.
func (p *pointG2) Null() kyber.Point {
p.g.SetInfinity()
return p
}

// Base returns the point p set to the generator on G2. Be careful: it mutates p.
// Consider using Clone first if you're using this in a comparison.
func (p *pointG2) Base() kyber.Point {
p.g.Set(twistGen)
return p
}

// Pick returns the point p set to a random point on G2. Be careful: it mutates p.
func (p *pointG2) Pick(rand cipher.Stream) kyber.Point {
s := mod.NewInt64(0, Order).Pick(rand)
p.Base()
@@ -524,16 +529,16 @@ func (p *pointGT) Equal(q kyber.Point) bool {
return subtle.ConstantTimeCompare(x, y) == 1
}

var nullGT = newPointGT().Pair(newPointG1(nil).Null(), newPointG2(nil).Null())

func (p *pointGT) Null() kyber.Point {
// TODO: This can be a precomputed constant
p.Pair(newPointG1([]byte{}).Null(), newPointG2([]byte{}).Null())
return p
return nullGT.Clone()
}

var baseGT = newPointGT().Pair(newPointG1(nil).Base(), newPointG2(nil).Base())

func (p *pointGT) Base() kyber.Point {
// TODO: This can be a precomputed constant
p.Pair(newPointG1([]byte{}).Base(), newPointG2([]byte{}).Base())
return p
return baseGT.Clone()
}

func (p *pointGT) Pick(rand cipher.Stream) kyber.Point {
64 changes: 64 additions & 0 deletions pairing/bn254/point_test.go
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import (
"errors"
"testing"

"github.com/drand/kyber"
"golang.org/x/crypto/sha3"
)

@@ -206,3 +207,66 @@ func min(a, b int) int {
}
return b
}

func Test_pointG1_Equal(t *testing.T) {
tests := []struct {
name string
p1 kyber.Point
p2 kyber.Point
want bool
}{
{
"g1 inf",
newPointG1(nil).Null(),
newPointG1(nil).Null(),
true,
}, {
"g1 base",
newPointG1(nil).Base(),
newPointG1(nil).Base(),
true,
}, {
"g1 base!=inf",
newPointG1(nil).Base(),
newPointG1(nil).Null(),
false,
}, {
"g2 base!=inf",
newPointG2(nil).Base(),
newPointG2(nil).Null(),
false,
}, {
"g2 inf",
newPointG2(nil).Null(),
newPointG2(nil).Null(),
true,
}, {
"g2 base",
newPointG2(nil).Base(),
newPointG2(nil).Base(),
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := tt.p1
if got := p.Equal(tt.p2); got != tt.want {
t.Errorf("Equal() = %v, want %v", got, tt.want)
}
})
}
}

func Test_pointGT_Null(t *testing.T) {
inf := newPointGT().Pair(newPointG1([]byte{}).Null(), newPointG2([]byte{}).Null())
if !inf.Equal(newPointGT().Null()) {
t.Fatal("Null isn't the same null")
}
}

func Test_pointGT_Base(t *testing.T) {
base := newPointGT().Pair(newPointG1([]byte{}).Base(), newPointG2([]byte{}).Base())
if !base.Equal(newPointGT().Base()) {
t.Fatal("Null isn't the same null")
}
}
2 changes: 1 addition & 1 deletion pairing/bn254/suite.go
Original file line number Diff line number Diff line change
@@ -198,7 +198,7 @@ func (c *commonSuite) Hash() hash.Hash {
return sha3.NewLegacyKeccak256()
}

// XOF returns a newlly instantiated blake2xb XOF function.
// XOF returns a newly instantiated blake2xb XOF function.
func (c *commonSuite) XOF(seed []byte) kyber.XOF {
return blake2xb.New(seed)
}
1 change: 1 addition & 0 deletions pairing/bn254/twist.go
Original file line number Diff line number Diff line change
@@ -186,6 +186,7 @@ func (c *twistPoint) MakeAffine() {
g.x.SetZero()
g.y.SetOne()
g.t.SetZero()
c.Set(g)
return
}

Loading