Skip to content
Open
Show file tree
Hide file tree
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
Expand Up @@ -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
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/binary"
"errors"
"fmt"

"github.com/drand/kyber"
"github.com/drand/kyber/group/mod"
"github.com/drand/kyber/pairing"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand All @@ -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
}
Expand All @@ -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)
}
Expand Down Expand Up @@ -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.
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down
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
Expand Down
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=
Expand All @@ -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=
Expand All @@ -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=
Expand All @@ -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=
Expand Down
2 changes: 1 addition & 1 deletion pairing/bn254/gfp_decl.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

var hasBMI2 = cpu.X86.HasBMI2

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

//go:noescape
Expand Down
19 changes: 12 additions & 7 deletions pairing/bn254/point.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down
64 changes: 64 additions & 0 deletions pairing/bn254/point_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"testing"

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

Expand Down Expand Up @@ -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
Expand Up @@ -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)
}
Expand Down
1 change: 1 addition & 0 deletions pairing/bn254/twist.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func (c *twistPoint) MakeAffine() {
g.x.SetZero()
g.y.SetOne()
g.t.SetZero()
c.Set(g)
return
}

Expand Down
Loading
Loading