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
64 changes: 49 additions & 15 deletions encrypt/ibe/ibe.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ func H4Tag() []byte {
// - the Ciphertext.U point will be on G1
// - ID is the ID towards which we encrypt the message
// - msg is the actual message
// - seed is the random seed to generate the random element (sigma) of the encryption
// - additionalData is optional additional data bound via commitment (nil for backward compatibility)
// The suite must produce points which implements the `HashablePoint` interface.
func EncryptCCAonG1(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphertext, error) {
func EncryptCCAonG1(s pairing.Suite, master kyber.Point, ID, msg, additionalData []byte) (*Ciphertext, error) {
if len(msg) > s.Hash().Size() {
return nil, errors.New("plaintext too long for the hash function provided")
}
Expand All @@ -65,8 +65,8 @@ func EncryptCCAonG1(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphe
if _, err := rand.Read(sigma); err != nil {
return nil, fmt.Errorf("err reading rand sigma: %v", err)
}
// 3. Derive r from sigma and msg
r, err := h3(s, sigma, msg)
// 3. Derive r from sigma, msg, and optional additionalData
r, err := h3WithAD(s, sigma, msg, additionalData)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -96,7 +96,8 @@ func EncryptCCAonG1(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphe
}

// DecryptCCAonG1 decrypts ciphertexts encrypted using EncryptCCAonG1 given a G2 "private" point
func DecryptCCAonG1(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte, error) {
// - additionalData is optional additional data that must match the encryption context (nil for backward compatibility)
func DecryptCCAonG1(s pairing.Suite, private kyber.Point, c *Ciphertext, additionalData []byte) ([]byte, error) {
if len(c.W) > s.Hash().Size() {
return nil, errors.New("ciphertext too long for the hash function provided")
}
Expand All @@ -120,8 +121,8 @@ func DecryptCCAonG1(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte

msg := xor(hsigma, c.W)

// 3. Check U = rP
r, err := h3(s, sigma, msg)
// 3. Check U = rP with optional additionalData
r, err := h3WithAD(s, sigma, msg, additionalData)
if err != nil {
return nil, err
}
Expand All @@ -132,6 +133,18 @@ func DecryptCCAonG1(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte
return msg, nil
}

// EncryptCCAonG1WithAD encrypts with additional data bound via commitment.
// different AD values produce different ciphertexts for replay attack prevention.
func EncryptCCAonG1WithAD(s pairing.Suite, master kyber.Point, ID, msg, additionalData []byte) (*Ciphertext, error) {
Comment thread
alienx5499 marked this conversation as resolved.
return EncryptCCAonG1(s, master, ID, msg, additionalData)
}

// DecryptCCAonG1WithAD decrypts with additional data verification.
// wrong AD causes cryptographic failure at rP check.
func DecryptCCAonG1WithAD(s pairing.Suite, private kyber.Point, c *Ciphertext, additionalData []byte) ([]byte, error) {
return DecryptCCAonG1(s, private, c, additionalData)
}

// EncryptCCAonG2 implements the CCA identity-based encryption scheme from
// https://crypto.stanford.edu/~dabo/pubs/papers/bfibe.pdf for more information
// about the scheme.
Expand All @@ -140,9 +153,9 @@ func DecryptCCAonG1(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte
// - the Ciphertext.U point will be on G2
// - ID is the ID towards which we encrypt the message
// - msg is the actual message
// - seed is the random seed to generate the random element (sigma) of the encryption
// - additionalData is optional additional data bound via commitment (nil for backward compatibility)
// The suite must produce points which implements the `HashablePoint` interface.
func EncryptCCAonG2(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphertext, error) {
func EncryptCCAonG2(s pairing.Suite, master kyber.Point, ID, msg, additionalData []byte) (*Ciphertext, error) {
if len(msg) > s.Hash().Size() {
return nil, errors.New("plaintext too long for the hash function provided")
}
Expand All @@ -160,8 +173,8 @@ func EncryptCCAonG2(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphe
if _, err := rand.Read(sigma); err != nil {
return nil, fmt.Errorf("err reading rand sigma: %v", err)
}
// 3. Derive r from sigma and msg
r, err := h3(s, sigma, msg)
// 3. Derive r from sigma, msg, and optional additionalData
r, err := h3WithAD(s, sigma, msg, additionalData)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -191,7 +204,8 @@ func EncryptCCAonG2(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphe
}

// DecryptCCAonG2 decrypts ciphertexts encrypted using EncryptCCAonG2 given a G1 "private" point
func DecryptCCAonG2(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte, error) {
// - additionalData is optional additional data that must match the encryption context (nil for backward compatibility)
func DecryptCCAonG2(s pairing.Suite, private kyber.Point, c *Ciphertext, additionalData []byte) ([]byte, error) {
if len(c.W) > s.Hash().Size() {
return nil, errors.New("ciphertext too long for the hash function provided")
}
Expand All @@ -215,8 +229,8 @@ func DecryptCCAonG2(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte

msg := xor(hsigma, c.W)

// 3. Check U = rP
r, err := h3(s, sigma, msg)
// 3. Check U = rP with optional additionalData
r, err := h3WithAD(s, sigma, msg, additionalData)
if err != nil {
return nil, err
}
Expand All @@ -227,8 +241,25 @@ func DecryptCCAonG2(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte
return msg, nil
}

// EncryptCCAonG2WithAD encrypts with additional data bound via commitment.
// different AD values produce different ciphertexts for replay attack prevention.
func EncryptCCAonG2WithAD(s pairing.Suite, master kyber.Point, ID, msg, additionalData []byte) (*Ciphertext, error) {
return EncryptCCAonG2(s, master, ID, msg, additionalData)
}

// DecryptCCAonG2WithAD decrypts with additional data verification.
// wrong AD causes cryptographic failure at rP check.
func DecryptCCAonG2WithAD(s pairing.Suite, private kyber.Point, c *Ciphertext, additionalData []byte) ([]byte, error) {
return DecryptCCAonG2(s, private, c, additionalData)
}

// hash sigma and msg to get r
func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) {
return h3WithAD(s, sigma, msg, nil)
}

// h3WithAD includes additional data in the hash for r generation
func h3WithAD(s pairing.Suite, sigma, msg, additionalData []byte) (kyber.Scalar, error) {
h := s.Hash()

if h.Size() != s.G1().ScalarLen() {
Expand All @@ -242,7 +273,10 @@ func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) {
return nil, fmt.Errorf("err hashing sigma: %v", err)
}
_, _ = h.Write(msg)
// we hash it a first time: buffer = hash("IBE-H3" || sigma || msg)
if len(additionalData) > 0 {
_, _ = h.Write(additionalData)
}
// hash("IBE-H3" || sigma || msg || additionalData)
buffer := h.Sum(nil)

hashable, ok := s.G1().Scalar().(*mod.Int)
Expand Down
Loading