FAME and Enhanced Attributed-Based Security
With CP-ABE (Cipher Policy — Attributed-Based Encryption), we can generate an encryption key based on a policy and a set of attributes. One method is FAME: Fast Attribute-based Message Encryption and created by Shashank Agrawal and Melissa Chase [1] [here]:
FAME uses Type-III pairing groups (such as BNS256 [here]), and which are the most efficient of cryptography pairings. It has the key features of [1]:
- No restriction on the size of policies or attribute sets.
- Allow any arbitrary string to be used as an attribute.
- Requires just a small number of pairings for decryption.
- Satisfy the natural security requirement under a standard hardness assumption.
With this, we can create a cipher policy, along with a public key pair:
a := abe.NewFAME()
// Key Pair
pk, sk, err := a.GenerateMasterKeys()
Next, we can implement our policy to produce an MSP (monotone span programs):
policy:="((Edinburgh AND NHS) OR (Glasgow AND SOCIAL)) AND GOV"
msp, err := abe.BooleanToMSP(policy, false)
In this case, we need to prove we are in Edinburgh and part of the NHS, or that we are in Glasgow and part of social care (SOCIAL). Along with this, we need to prove we are part of the government (GOV). We can then encrypt a message (msg) with the public key and the policy:
cipher, err := a.Encrypt(msg, msp, pk)
This ciphertext will only decrypted with the private key and the correct attributes:
gamma := strings.Split(attributes, " ")
keys, err := a.GenerateAttribKeys(gamma, sk)
msgCheck, err := a.Decrypt(cipher, keys, pk)
The full code is [here]:
package main
import (
"fmt"
"os"
"github.com/fentec-project/gofe/abe"
"strings"
)
func main() {
policy:="((Edinburgh AND NHS) OR (Glasgow AND SOCIAL)) AND GOV"
attributes:="Edinburgh NHS Glasgow GOV"
msg:="Hello"
argCount := len(os.Args[1:])
if (argCount>0) { msg= (os.Args[1]) }
if (argCount>1) { policy= (os.Args[2]) }
if (argCount>2) { attributes= (os.Args[3]) }
a := abe.NewFAME()
// Key Pair
pk, sk, err := a.GenerateMasterKeys()
if err != nil {
fmt.Printf("Failed to generate master keys: %v", err)
}
msp, err := abe.BooleanToMSP(policy, false)
if err != nil {
fmt.Printf("Failed to generate the policy: %v", err)
}
cipher, err := a.Encrypt(msg, msp, pk)
if err != nil {
fmt.Printf("Failed to encrypt: %v", err)
}
gamma := strings.Split(attributes, " ")
// generate keys for decryption for an entity with attributes
keys, err := a.GenerateAttribKeys(gamma, sk)
if err != nil {
fmt.Printf("Failed to generate keys: %v", err)
}
// decrypt the ciphertext
msgRecovered, err := a.Decrypt(cipher, keys, pk)
if err != nil {
fmt.Printf("Failed to decrypt: %v", err)
}
fmt.Printf("Attributes: %v\nPolicy %v\n\n",attributes,policy)
fmt.Printf("Message: %v\nRecovered %v",msg, msgRecovered)
}
For the correct attributes, we get [here]:
Attributes: Edinburgh Glasgow GOV
Policy (Edinburgh OR Glasgow) AND GOV
Message: Hello
Recovered Hello
For the incorrect attributes [here]:
Failed to decrypt: provided key is not sufficient for decryption
Attributes: Edinburgh Glasgow
Policy (Edinburgh OR Glasgow) AND GOV
Message: Hello
Recovered
Here are some other examples:
- Msg: “Hello”, Attributes: [Edinburgh Glasgow GOV] Policy: (Edinburgh OR Glasgow) AND GOV Try!
- Msg: “Hello”, Attributes: [Edinburgh Glasgow] Policy: (Edinburgh OR Glasgow) AND GOV Try!
- Msg: “Hello”, Attributes: [Bob Production] Policy: (Bob AND Production) OR (Alice AND SALES) Try!
- Msg: “Hello”, Attributes: [Bob SALES] Policy: (Bob AND Production) OR (Alice AND SALES) Try!
- Msg: “Hello”, Attributes: [Alice SALES] Policy: (Bob AND Production) OR (Alice AND SALES) Try!
References
[1] Agrawal, S., & Chase, M. (2017, October). FAME: Fast attribute-based message encryption. In Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security (pp. 665–682).