Encrypted Word Searches Using Golang and Kryptology

We give away too much information. Let’s say I want to search a database for a customer’s name. For this I would probably have to expose…

Photo by Glen Carrie on Unsplash

Encrypted Word Searches Using Golang and Kryptology

We give away too much information. Let’s say I want to search a database for a customer’s name. For this I would probably have to expose the names in plaintext, and which leaves it open for a data breach. An improved method is to encrypt search terms and then match a search term to these. In this case, we will implement the following [paper]:

First, we have two curves (G1 and G2) and initially, we define a large prime number (q). First, a trust server selects a point on the G2 curve (P), and generates a using a random number (s):

Alice creates a public key with:

Next Trent creates a random value (r) and creates:

Trent hashes the word to search (M) to the G2 curve:

And creates the pairing of:

If Bob wants to search for W2, he matches to:

and where:

Here’s an outline of crypto pairing:

Coding

The outline coding using the library from the Kryptography library is [here]:

package main
import (
"crypto/rand"
"fmt"
"math/big"
"os"
	"crypto/sha256"
	bls12381 "github.com/coinbase/kryptology/pkg/core/curves/native/bls12-381"
)
func main() {
	m := "hello"
tof := "hello"
	argCount := len(os.Args[1:])
	if argCount > 0 {
m = os.Args[1]
}
if argCount > 1 {
tof = os.Args[2]
}
	fmt.Printf("Encrypted word: %s\n\n", m)
fmt.Printf("Word to find: %s\n\n", tof)
	bls := bls12381.NewEngine()
g1, g2 := bls.G1, bls.G2
gt := bls.GT()
	msg := []byte(m)
tofind := []byte(tof)
	HW, _ := g1.HashToCurve(sha256.New, msg, []byte(""))
ToF, _ := g1.HashToCurve(sha256.New, tofind, []byte(""))
	r := make([]byte, 32)
rand.Read(r)
rval := new(big.Int).SetBytes(r)
	s := make([]byte, 32)
rand.Read(s)
sval := new(big.Int).SetBytes(s)
	G2 := g2.One()
sP := g2.New()
rP := g2.New()
	sToF := g1.New()
	g2.MulScalar(sP, G2, sval)
g2.MulScalar(rP, G2, rval)
	g1.MulScalar(sToF, ToF, sval)
	fmt.Printf("s = %x\n", s)
fmt.Printf("r = %x\n\n", r)
	e0, _ := bls.AddPair(HW, sP).Result()
gt.Exp(e0, e0, rval)
	e1, _ := bls.AddPair(sToF, rP).Result()
	fmt.Printf("First part of e0 pairing: %+v\n", e0[0][0][0])
fmt.Printf("First part of e1 pairing: %+v\n", e1[0][0][0])
	if e0.Equal(e1) {
fmt.Printf("We have found it...")
} else {
fmt.Printf("Cannot find!")
}
}

A sample run is [here]:

Encrypted word: Hello
Word to find: Hello
s = 1229b2836a548cca3bc9ac238cd0c634635535f3a5b6f12aac78fd5fa096a77c
r = 2fce640d56121d278b20dedd00ecc442e3a1c536de98209f4f10f551b15072e9
First part of e0 pairing: [5509936851070022305 4957573568693525133 3532086020062769437 5031641048332977130 18248703594105518599 657243605775503017]
First part of e1 pairing: [5509936851070022305 4957573568693525133 3532086020062769437 5031641048332977130 18248703594105518599 657243605775503017]
We have found it...

and a false search [here]:

Encrypted word: Hello
Word to find: Hello123
s = 3398a4ecba24cc114291082613ed0f49a5e482ee72d829cdd33fefd404f91ca6
r = cf2c6448553df07deb10b4e70dd0e2e113a4d3318d87d1c08d735528f9754dde
First part of e0 pairing: [9433419437807457542 14827067878769968193 9757426493516444139 5593213596321565194 10129867375955106600 81638192315469051]
First part of e1 pairing: [9963009439914925460 13665328121908137426 1398638186177370014 5695327681334410247 16635414863332113065 1808470817875180072]
Cannot find!

Conclusions

Wouldn’t it be great to have encrypted search terms, and then protect the private of the search terms?

If you are interested in the Kryptology:

https://asecuritysite.com/kryptology

and with crypto pairings:

https://asecuritysite.com/pairing/