mirror of
https://github.com/tlsnotary/server.git
synced 2026-01-09 11:57:54 -05:00
simplify commit-reveal: only client sends commitment
streamline http handling and decrease RAM usage
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package evaluator
|
package evaluator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
|
||||||
"notary/meta"
|
"notary/meta"
|
||||||
u "notary/utils"
|
u "notary/utils"
|
||||||
)
|
)
|
||||||
@@ -13,26 +12,22 @@ type Evaluator struct {
|
|||||||
// they are meant to be read-only for evaluator
|
// they are meant to be read-only for evaluator
|
||||||
meta []*meta.Circuit
|
meta []*meta.Circuit
|
||||||
ttBlobs [][]byte // truth table blobs for each circuit
|
ttBlobs [][]byte // truth table blobs for each circuit
|
||||||
olBlobs [][]byte // output labels blobs for each circuit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Evaluator) Init(circuits []*meta.Circuit, c6Count int) {
|
func (e *Evaluator) Init(circuits []*meta.Circuit, c6Count int) {
|
||||||
e.C6Count = c6Count
|
e.C6Count = c6Count
|
||||||
e.meta = circuits
|
e.meta = circuits
|
||||||
e.ttBlobs = make([][]byte, len(e.meta))
|
e.ttBlobs = make([][]byte, len(e.meta))
|
||||||
e.olBlobs = make([][]byte, len(e.meta))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate evaluates a circuit number cNo
|
// Evaluate evaluates a circuit number cNo
|
||||||
func (e *Evaluator) Evaluate(cNo int, notaryLabels, clientLabels,
|
func (e *Evaluator) Evaluate(cNo int, notaryLabels, clientLabels,
|
||||||
truthTables, decodingTable []byte) []byte {
|
truthTables []byte) []byte {
|
||||||
type batch_t struct {
|
type batch_t struct {
|
||||||
// wl is wire labels
|
// wl is wire labels
|
||||||
wl *[][]byte
|
wl *[][]byte
|
||||||
// tt is truth tables
|
// tt is truth tables
|
||||||
tt *[]byte
|
tt *[]byte
|
||||||
// dt is decoding table
|
|
||||||
dt *[]byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c := (e.meta)[cNo]
|
c := (e.meta)[cNo]
|
||||||
@@ -40,7 +35,6 @@ func (e *Evaluator) Evaluate(cNo int, notaryLabels, clientLabels,
|
|||||||
nlBatch := u.SplitIntoChunks(notaryLabels, c.NotaryInputSize*16)
|
nlBatch := u.SplitIntoChunks(notaryLabels, c.NotaryInputSize*16)
|
||||||
clBatch := u.SplitIntoChunks(clientLabels, c.ClientInputSize*16)
|
clBatch := u.SplitIntoChunks(clientLabels, c.ClientInputSize*16)
|
||||||
ttBatch := u.SplitIntoChunks(truthTables, c.AndGateCount*48)
|
ttBatch := u.SplitIntoChunks(truthTables, c.AndGateCount*48)
|
||||||
dtBatch := u.SplitIntoChunks(decodingTable, int(math.Ceil(float64(c.OutputSize)/8)))
|
|
||||||
|
|
||||||
// exeCount is how many executions of this circuit we need
|
// exeCount is how many executions of this circuit we need
|
||||||
exeCount := []int{0, 1, 1, 1, 1, 1, e.C6Count, 1}[cNo]
|
exeCount := []int{0, 1, 1, 1, 1, 1, e.C6Count, 1}[cNo]
|
||||||
@@ -49,41 +43,17 @@ func (e *Evaluator) Evaluate(cNo int, notaryLabels, clientLabels,
|
|||||||
// put all input labels into wire labels
|
// put all input labels into wire labels
|
||||||
wireLabels := make([][]byte, c.WireCount)
|
wireLabels := make([][]byte, c.WireCount)
|
||||||
copy(wireLabels, u.SplitIntoChunks(u.Concat(nlBatch[r], clBatch[r]), 16))
|
copy(wireLabels, u.SplitIntoChunks(u.Concat(nlBatch[r], clBatch[r]), 16))
|
||||||
batch[r] = batch_t{&wireLabels, &ttBatch[r], &dtBatch[r]}
|
batch[r] = batch_t{&wireLabels, &ttBatch[r]}
|
||||||
}
|
}
|
||||||
|
|
||||||
var output []byte
|
encodedOutput := make([][]byte, exeCount)
|
||||||
for r := 0; r < exeCount; r++ {
|
for r := 0; r < exeCount; r++ {
|
||||||
plaintext := evaluate(c, batch[r].wl, batch[r].tt, batch[r].dt)
|
encodedOutput[r] = evaluate(c, batch[r].wl, batch[r].tt)
|
||||||
// plaintext has a padding in MSB to make it a multiple of 8 bits. We
|
|
||||||
// decompose into bits and drop the padding
|
|
||||||
outBits := u.BytesToBits(plaintext)[0:c.OutputSize]
|
|
||||||
// reverse output bits so that the values of the output be placed in
|
|
||||||
// the same order as they appear in the *.casm files
|
|
||||||
outBytes := e.parseOutputBits(cNo, outBits)
|
|
||||||
output = append(output, outBytes...)
|
|
||||||
}
|
}
|
||||||
return output
|
return u.Concat(encodedOutput...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseOutputBits converts the output bits of the circuit into a flat slice
|
func evaluate(c *meta.Circuit, wireLabels *[][]byte, truthTables *[]byte) []byte {
|
||||||
// of bytes so that output values are in the same order as they appear in the *.casm files
|
|
||||||
func (e *Evaluator) parseOutputBits(cNo int, outBits []int) []byte {
|
|
||||||
o := 0 // offset
|
|
||||||
var outBytes []byte
|
|
||||||
for _, v := range (e.meta)[cNo].OutputsSizes {
|
|
||||||
output := u.BitsToBytes(outBits[o : o+v])
|
|
||||||
outBytes = append(outBytes, output...)
|
|
||||||
o += v
|
|
||||||
}
|
|
||||||
if o != (e.meta)[cNo].OutputSize {
|
|
||||||
panic("o != e.g.Cs[cNo].OutputSize")
|
|
||||||
}
|
|
||||||
return outBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
func evaluate(c *meta.Circuit, wireLabels *[][]byte, truthTables *[]byte,
|
|
||||||
decodingTable *[]byte) []byte {
|
|
||||||
andGateIdx := 0
|
andGateIdx := 0
|
||||||
// gate type XOR==0 AND==1 INV==2
|
// gate type XOR==0 AND==1 INV==2
|
||||||
for i := 0; i < len(c.Gates); i++ {
|
for i := 0; i < len(c.Gates); i++ {
|
||||||
@@ -99,16 +69,12 @@ func evaluate(c *meta.Circuit, wireLabels *[][]byte, truthTables *[]byte,
|
|||||||
panic("Unknown gate")
|
panic("Unknown gate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// return encoded output
|
||||||
// decode output labels
|
|
||||||
// get decoding table: LSB of label0 for each output wire
|
|
||||||
outLSBs := make([]int, c.OutputSize)
|
outLSBs := make([]int, c.OutputSize)
|
||||||
for i := 0; i < c.OutputSize; i++ {
|
for i := 0; i < c.OutputSize; i++ {
|
||||||
outLSBs[i] = int((*wireLabels)[c.WireCount-c.OutputSize+i][15]) & 1
|
outLSBs[i] = int((*wireLabels)[c.WireCount-c.OutputSize+i][15]) & 1
|
||||||
}
|
}
|
||||||
encodings := u.BitsToBytes(outLSBs)
|
return u.BitsToBytes(outLSBs)
|
||||||
plaintext := u.XorBytes(*decodingTable, encodings)
|
|
||||||
return plaintext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func evaluateAnd(g meta.Gate, wireLabels *[][]byte, truthTables *[]byte, andGateIdx int) {
|
func evaluateAnd(g meta.Gate, wireLabels *[][]byte, truthTables *[]byte, andGateIdx int) {
|
||||||
|
|||||||
@@ -25,16 +25,16 @@ type gc struct {
|
|||||||
// Blob is what is returned when gc is read from disk
|
// Blob is what is returned when gc is read from disk
|
||||||
type Blob struct {
|
type Blob struct {
|
||||||
Il *[]byte
|
Il *[]byte
|
||||||
// we dont return bytes of tt and dt because we gonna be streaming the file
|
// we dont return bytes of tt because we gonna be streaming the file
|
||||||
// directly into the HTTP response to save memory
|
// directly into the HTTP response to save memory
|
||||||
TtFile *os.File
|
TtFile *os.File
|
||||||
DtFile *os.File
|
Dt *[]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type GarbledPool struct {
|
type GarbledPool struct {
|
||||||
// gPDirPath is full path to the garbled pool dir
|
// gPDirPath is full path to the garbled pool dir
|
||||||
gPDirPath string
|
gPDirPath string
|
||||||
// AES-GCM keys to encrypt/authenticate circuits' labels.
|
// AES-GCM keys to encrypt/authenticate circuits' blob.
|
||||||
// We need to encrypt them in case we want to store them outside the enclave.
|
// We need to encrypt them in case we want to store them outside the enclave.
|
||||||
// When the encryption key changes, older keys are kept because we still
|
// When the encryption key changes, older keys are kept because we still
|
||||||
// have labels on disk encrypted with old keys.
|
// have labels on disk encrypted with old keys.
|
||||||
@@ -55,7 +55,7 @@ type GarbledPool struct {
|
|||||||
// the amount of c5 circuits will be poolSize*100 because on average one
|
// the amount of c5 circuits will be poolSize*100 because on average one
|
||||||
// session needs that many garbled c5 circuits
|
// session needs that many garbled c5 circuits
|
||||||
poolSize int
|
poolSize int
|
||||||
// Circuits's count starts from 1
|
// Circuits contains metainfo for each circuit. Circuit count starts from 1
|
||||||
Circuits []*meta.Circuit
|
Circuits []*meta.Circuit
|
||||||
grb garbler.Garbler
|
grb garbler.Garbler
|
||||||
// noSandbox is set to true when not running in a sandboxed environment
|
// noSandbox is set to true when not running in a sandboxed environment
|
||||||
@@ -112,12 +112,13 @@ func (g *GarbledPool) Init(noSandbox bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns 1 garbling of each circuit and c5Count garblings for circuit 5
|
// returns 1 garbling of each circuit and c5Count garblings for circuit 5
|
||||||
func (g *GarbledPool) GetBlobs(c6Count int) []Blob {
|
func (g *GarbledPool) GetBlobs(c6Count int) [][]Blob {
|
||||||
if c6Count > 1026 {
|
if c6Count > 1026 {
|
||||||
panic("c6Count > 1026")
|
panic("c6Count > 1026")
|
||||||
}
|
}
|
||||||
var allBlobs []Blob
|
|
||||||
|
|
||||||
|
// we don't use index 0 for clarity, count starts from 1
|
||||||
|
allBlobs := make([][]Blob, len(g.Circuits))
|
||||||
// fetch blobs
|
// fetch blobs
|
||||||
for i := 1; i < len(g.Circuits); i++ {
|
for i := 1; i < len(g.Circuits); i++ {
|
||||||
iStr := strconv.Itoa(i)
|
iStr := strconv.Itoa(i)
|
||||||
@@ -140,7 +141,7 @@ func (g *GarbledPool) GetBlobs(c6Count int) []Blob {
|
|||||||
g.pool[iStr] = g.pool[iStr][1:]
|
g.pool[iStr] = g.pool[iStr][1:]
|
||||||
g.Unlock()
|
g.Unlock()
|
||||||
blob := g.fetchBlob(iStr, gc)
|
blob := g.fetchBlob(iStr, gc)
|
||||||
allBlobs = append(allBlobs, blob)
|
allBlobs[i] = append(allBlobs[i], blob)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allBlobs
|
return allBlobs
|
||||||
@@ -244,12 +245,16 @@ func (g *GarbledPool) monitor() {
|
|||||||
|
|
||||||
func (g *GarbledPool) saveBlob(path string, il *[]byte, tt *[]byte, dt *[]byte) {
|
func (g *GarbledPool) saveBlob(path string, il *[]byte, tt *[]byte, dt *[]byte) {
|
||||||
var ilToWrite *[]byte
|
var ilToWrite *[]byte
|
||||||
// we only encrypt input labels
|
var dtToWrite *[]byte
|
||||||
|
// we encrypt input labels and decoding table
|
||||||
if !g.noSandbox {
|
if !g.noSandbox {
|
||||||
ilEnc := u.AESGCMencrypt(g.key, *il)
|
ilEnc := u.AESGCMencrypt(g.key, *il)
|
||||||
ilToWrite = &ilEnc
|
ilToWrite = &ilEnc
|
||||||
|
dtEnc := u.AESGCMencrypt(g.key, *dt)
|
||||||
|
dtToWrite = &dtEnc
|
||||||
} else {
|
} else {
|
||||||
ilToWrite = il
|
ilToWrite = il
|
||||||
|
dtToWrite = dt
|
||||||
}
|
}
|
||||||
err := os.WriteFile(path+"_il", *ilToWrite, 0644)
|
err := os.WriteFile(path+"_il", *ilToWrite, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -259,13 +264,14 @@ func (g *GarbledPool) saveBlob(path string, il *[]byte, tt *[]byte, dt *[]byte)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
err = os.WriteFile(path+"_dt", *dt, 0644)
|
err = os.WriteFile(path+"_dt", *dtToWrite, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetches the blob from disk and deletes it
|
// fetches the blob from disk and deletes il and dt. tt will be deleted later
|
||||||
|
// by the caller.
|
||||||
func (g *GarbledPool) fetchBlob(circuitNo string, c gc) Blob {
|
func (g *GarbledPool) fetchBlob(circuitNo string, c gc) Blob {
|
||||||
fullPath := filepath.Join(g.gPDirPath, "c"+circuitNo, c.id)
|
fullPath := filepath.Join(g.gPDirPath, "c"+circuitNo, c.id)
|
||||||
il, err := os.ReadFile(fullPath + "_il")
|
il, err := os.ReadFile(fullPath + "_il")
|
||||||
@@ -276,7 +282,16 @@ func (g *GarbledPool) fetchBlob(circuitNo string, c gc) Blob {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
// only the file handle of truth tables and decoding tables is returned,
|
dt, err2 := os.ReadFile(fullPath + "_dt")
|
||||||
|
if err2 != nil {
|
||||||
|
panic(err2)
|
||||||
|
}
|
||||||
|
err = os.Remove(fullPath + "_dt")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// only the file handle of truth tables is returned,
|
||||||
// so that the file could be streamed (avoiding a full copy into memory)
|
// so that the file could be streamed (avoiding a full copy into memory)
|
||||||
// The session which receives this handle will be responsible for
|
// The session which receives this handle will be responsible for
|
||||||
// deleting the file
|
// deleting the file
|
||||||
@@ -284,17 +299,16 @@ func (g *GarbledPool) fetchBlob(circuitNo string, c gc) Blob {
|
|||||||
if err3 != nil {
|
if err3 != nil {
|
||||||
panic(err3)
|
panic(err3)
|
||||||
}
|
}
|
||||||
dtFile, err4 := os.Open(fullPath + "_dt")
|
|
||||||
if err4 != nil {
|
|
||||||
panic(err4)
|
|
||||||
}
|
|
||||||
var ilToReturn = &il
|
var ilToReturn = &il
|
||||||
|
var dtToReturn = &dt
|
||||||
if !g.noSandbox {
|
if !g.noSandbox {
|
||||||
// decrypt data from disk when in a sandbox
|
// decrypt data from disk when in a sandbox
|
||||||
ilDec := u.AESGCMdecrypt(g.keys[c.keyIdx], il)
|
ilDec := u.AESGCMdecrypt(g.keys[c.keyIdx], il)
|
||||||
ilToReturn = &ilDec
|
ilToReturn = &ilDec
|
||||||
|
dtDec := u.AESGCMdecrypt(g.keys[c.keyIdx], dt)
|
||||||
|
dtToReturn = &dtDec
|
||||||
}
|
}
|
||||||
return Blob{ilToReturn, ttFile, dtFile}
|
return Blob{ilToReturn, ttFile, dtToReturn}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the circuits from the "Bristol fashion" format into a compact
|
// Convert the circuits from the "Bristol fashion" format into a compact
|
||||||
|
|||||||
@@ -16,34 +16,32 @@ type Garbler struct {
|
|||||||
Cs []CData
|
Cs []CData
|
||||||
}
|
}
|
||||||
|
|
||||||
// CData is circuit's data
|
// CData is data for one circuit
|
||||||
type CData struct {
|
type CData struct {
|
||||||
Il []byte // input labels
|
// Il contains a flat slice of all input labels for all executions of
|
||||||
// InputBits start with least input bit at index [0]
|
// one circuit
|
||||||
InputBits []int // notary's input for this circuit
|
Il []byte
|
||||||
Masks [][]byte
|
// InputBits is notary's input for this circuit. Starts with the least
|
||||||
Meta *meta.Circuit
|
// input bit at index [0].
|
||||||
|
InputBits []int
|
||||||
|
// Masks are notary's masks. They are inputs to the circuit. Their purpose
|
||||||
|
// is to mask the circuit's output. Mask numbering starts with 1 for
|
||||||
|
// convenience. Consult circuits/*.casm files for description of what each
|
||||||
|
// mask does.
|
||||||
|
Masks [][]byte
|
||||||
|
Meta *meta.Circuit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init puts input labels into correspondign circuits and creates masks for
|
// Init puts input labels into correspondign circuits and creates masks for
|
||||||
// notary's inputs to the circuits.
|
// notary's inputs to the circuits.
|
||||||
// ilBlobs contains slices of input labels for each execution
|
// il contains input labels for each execution of each circuit
|
||||||
func (g *Garbler) Init(ilBlobs []*[]byte, circuits []*meta.Circuit, c6Count int) {
|
func (g *Garbler) Init(il [][][]byte, circuits []*meta.Circuit, c6Count int) {
|
||||||
g.C6Count = c6Count
|
g.C6Count = c6Count
|
||||||
g.Cs = make([]CData, len(circuits))
|
g.Cs = make([]CData, len(circuits))
|
||||||
for i := 1; i < len(g.Cs); i++ {
|
for i := 1; i < len(g.Cs); i++ {
|
||||||
if i < 6 {
|
g.Cs[i].Il = u.Concat(il[i]...)
|
||||||
g.Cs[i].Il = *ilBlobs[i-1]
|
|
||||||
} else if i == 6 {
|
|
||||||
g.Cs[i].Il = u.ConcatP(ilBlobs[5 : 5+c6Count]...)
|
|
||||||
} else if i > 6 {
|
|
||||||
g.Cs[i].Il = *ilBlobs[c6Count-1+i-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
g.Cs[i].Meta = circuits[i]
|
g.Cs[i].Meta = circuits[i]
|
||||||
|
|
||||||
// mask numbering starts at 1 for convenience
|
|
||||||
// consult circuits/*.casm files for what each mask does
|
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
g.Cs[i].Masks = make([][]byte, 2)
|
g.Cs[i].Masks = make([][]byte, 2)
|
||||||
g.Cs[i].Masks[1] = u.GetRandom(32)
|
g.Cs[i].Masks[1] = u.GetRandom(32)
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import (
|
|||||||
|
|
||||||
type KeyManager struct {
|
type KeyManager struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
// Blob contains validFrom|validUntil|pubkey|signature
|
// KeyData contains validFrom|validUntil|pubkey|signature
|
||||||
// the client will verify the signature (made with the masterKey)
|
// the client will verify the signature (made with the masterKey)
|
||||||
Blob []byte
|
KeyData []byte
|
||||||
// PrivKey is the ephemeral key used to sign a session. Also used
|
// PrivKey is the ephemeral key used to sign a session. Also used
|
||||||
// in ECDH with the the client to derive symmetric keys to encrypt the communication
|
// in ECDH with the the client to derive symmetric keys to encrypt the communication
|
||||||
PrivKey *ecdsa.PrivateKey
|
PrivKey *ecdsa.PrivateKey
|
||||||
@@ -40,6 +40,19 @@ func (k *KeyManager) Init() {
|
|||||||
go k.rotateEphemeralKeys()
|
go k.rotateEphemeralKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetActiveKey returns the currently active signing key as well as KeyData
|
||||||
|
// associated with it
|
||||||
|
func (k *KeyManager) GetActiveKey() (ecdsa.PrivateKey, []byte) {
|
||||||
|
// copying data so that it doesn't change from under us if
|
||||||
|
// ephemeral key happens to change while this session is running
|
||||||
|
k.Lock()
|
||||||
|
keyData := make([]byte, len(k.KeyData))
|
||||||
|
copy(keyData, k.KeyData)
|
||||||
|
key := *k.PrivKey
|
||||||
|
k.Unlock()
|
||||||
|
return key, keyData
|
||||||
|
}
|
||||||
|
|
||||||
// generateMasterKey generates a P-256 master key. The corresponding public key
|
// generateMasterKey generates a P-256 master key. The corresponding public key
|
||||||
// in PEM format is written to disk
|
// in PEM format is written to disk
|
||||||
func (k *KeyManager) generateMasterKey() {
|
func (k *KeyManager) generateMasterKey() {
|
||||||
@@ -94,7 +107,7 @@ func (k *KeyManager) rotateEphemeralKeys() {
|
|||||||
signature := u.ECDSASign(k.masterKey, validFrom, validUntil, pubkey)
|
signature := u.ECDSASign(k.masterKey, validFrom, validUntil, pubkey)
|
||||||
blob := u.Concat(validFrom, validUntil, pubkey, signature)
|
blob := u.Concat(validFrom, validUntil, pubkey, signature)
|
||||||
k.Lock()
|
k.Lock()
|
||||||
k.Blob = blob
|
k.KeyData = blob
|
||||||
k.PrivKey = newKey
|
k.PrivKey = newKey
|
||||||
k.Unlock()
|
k.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
412
src/notary.go
412
src/notary.go
@@ -67,49 +67,43 @@ func destroyOnPanic(s *session.Session) {
|
|||||||
s.DestroyChan <- s.Sid
|
s.DestroyChan <- s.Sid
|
||||||
}
|
}
|
||||||
|
|
||||||
func init1(w http.ResponseWriter, req *http.Request) {
|
func httpHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Println("in init1", req.RemoteAddr)
|
// sessionId is the part of the URL after ?
|
||||||
s := sm.AddSession(string(req.URL.RawQuery))
|
sessionId := string(req.URL.RawQuery)
|
||||||
|
// command is URL path without the leading /
|
||||||
|
command := req.URL.Path[1:]
|
||||||
|
log.Println("got request ", command, " from ", req.RemoteAddr)
|
||||||
|
var out []byte
|
||||||
|
if command == "init1" {
|
||||||
|
s := sm.AddSession(sessionId)
|
||||||
|
s.Gp = gp
|
||||||
|
key, keyData := km.GetActiveKey()
|
||||||
|
s.SigningKey = key
|
||||||
|
// keyData is sent to Client unencrypted
|
||||||
|
out = append(out, keyData...)
|
||||||
|
}
|
||||||
|
s := sm.GetSession(sessionId)
|
||||||
defer destroyOnPanic(s)
|
defer destroyOnPanic(s)
|
||||||
|
method := sm.GetMethod(command, sessionId)
|
||||||
body := readBody(req)
|
body := readBody(req)
|
||||||
s.Gp = gp
|
out = append(out, method(body)...)
|
||||||
// copying data so that it doesn't change from under us if
|
|
||||||
// ephemeral key happens to change while this session is running
|
|
||||||
km.Lock()
|
|
||||||
blob := make([]byte, len(km.Blob))
|
|
||||||
copy(blob, km.Blob)
|
|
||||||
key := *km.PrivKey
|
|
||||||
km.Unlock()
|
|
||||||
out := s.Init1(body, blob, key)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in init2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Init2(body)
|
|
||||||
writeResponse(out, w)
|
writeResponse(out, w)
|
||||||
|
if command == "commitHash" {
|
||||||
|
// this was the final message of the session. Destroying the session...
|
||||||
|
s.DestroyChan <- s.Sid
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getBlob is called when user wants to download garbled circuits
|
||||||
func getBlob(w http.ResponseWriter, req *http.Request) {
|
func getBlob(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Println("in getBlob", req.RemoteAddr)
|
log.Println("in getBlob", req.RemoteAddr)
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
s := sm.GetSession(string(req.URL.RawQuery))
|
||||||
defer destroyOnPanic(s)
|
defer destroyOnPanic(s)
|
||||||
body := readBody(req)
|
body := readBody(req)
|
||||||
tt, dt := s.GetBlob(body)
|
fileHandles := s.GetBlob(body)
|
||||||
// send headers first
|
|
||||||
writeResponse(nil, w)
|
writeResponse(nil, w)
|
||||||
// stream decoding table directly from file
|
// stream directly from file
|
||||||
for _, f := range dt {
|
for _, f := range fileHandles {
|
||||||
_, err := io.Copy(w, f)
|
|
||||||
if err != nil {
|
|
||||||
panic("err != nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// stream decoding table directly from file
|
|
||||||
for _, f := range tt {
|
|
||||||
_, err := io.Copy(w, f)
|
_, err := io.Copy(w, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("err != nil")
|
panic("err != nil")
|
||||||
@@ -117,6 +111,7 @@ func getBlob(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setBlob is called when user wants to upload garbled circuits
|
||||||
func setBlob(w http.ResponseWriter, req *http.Request) {
|
func setBlob(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Println("in setBlob", req.RemoteAddr)
|
log.Println("in setBlob", req.RemoteAddr)
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
s := sm.GetSession(string(req.URL.RawQuery))
|
||||||
@@ -125,298 +120,9 @@ func setBlob(w http.ResponseWriter, req *http.Request) {
|
|||||||
writeResponse(out, w)
|
writeResponse(out, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUploadProgress(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in getUploadProgress", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
out := s.GetUploadProgress()
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func step3(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in step3", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Step3(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func step4(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in step4", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Step4(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c1_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c1_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C1_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c1_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c1_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C1_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c1_step3(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c1_step3", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C1_step3(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c1_step4(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c1_step4", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C1_step4(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c1_step5(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c1_step5", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C1_step5(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c2_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c2_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C2_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c2_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c2_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C2_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c2_step3(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c2_step3", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C2_step3(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c2_step4(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c2_step4", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C2_step4(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c3_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c3_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C3_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c3_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c3_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C3_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c4_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c4_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C4_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c4_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c4_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C4_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c4_step3(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c4_step3", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C4_step3(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c5_pre1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c5_pre1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C5_pre1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c5_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c5_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C5_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c5_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c5_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C5_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c5_step3(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c5_step3", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C5_step3(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c6_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c6_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C6_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c6_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c6_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C6_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c7_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c7_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C7_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c7_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in c7_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.C7_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkC7Commit(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in checkC7Commit", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.CheckC7Commit(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ghash_step1(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in ghash_step1", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Ghash_step1(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ghash_step2(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in ghash_step2", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Ghash_step2(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ghash_step3(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in ghash_step3", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.Ghash_step3(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func commitHash(w http.ResponseWriter, req *http.Request) {
|
|
||||||
log.Println("in commitHash", req.RemoteAddr)
|
|
||||||
s := sm.GetSession(string(req.URL.RawQuery))
|
|
||||||
defer destroyOnPanic(s)
|
|
||||||
body := readBody(req)
|
|
||||||
out := s.CommitHash(body)
|
|
||||||
writeResponse(out, w)
|
|
||||||
s.DestroyChan <- s.Sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// when notary starts we expect the admin to upload a URLFetcher document
|
// when notary starts we expect the admin to upload a URLFetcher document
|
||||||
// it can be uploaded e.g. with:
|
// it can be uploaded e.g. with:
|
||||||
// curl --data-binary '@URLFetcherDoc' 127.0.0.1:10012/setURLFetcherDoc
|
// curl --data-binary '@URLFetcherDoc' 127.0.0.1:10012/setURLFetcherDoc
|
||||||
|
|
||||||
func awaitURLFetcherDoc() {
|
func awaitURLFetcherDoc() {
|
||||||
serverMux := http.NewServeMux()
|
serverMux := http.NewServeMux()
|
||||||
srv := &http.Server{Addr: ":10012", Handler: serverMux}
|
srv := &http.Server{Addr: ":10012", Handler: serverMux}
|
||||||
@@ -443,7 +149,7 @@ func getPubKey(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initially the circuits are in the human-readable c*.casm format; assemble.js
|
// initially the circuits are in the human-readable c*.casm format; assemble.js
|
||||||
// converts them into a "Bristol fashion" format and write to disk c*.out files
|
// converts them into a "Bristol fashion" format and writes to disk c*.out files
|
||||||
func assembleCircuits() {
|
func assembleCircuits() {
|
||||||
curDir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
|
curDir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||||
baseDir := filepath.Dir(curDir)
|
baseDir := filepath.Dir(curDir)
|
||||||
@@ -457,11 +163,16 @@ func assembleCircuits() {
|
|||||||
log.Println("Error. Could not run: node assemble.js. Please make sure that node is installed on your system.")
|
log.Println("Error. Could not run: node assemble.js. Please make sure that node is installed on your system.")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
log.Println("Finished assembling circuits.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// uncomment the below to profile the process's RAM usage
|
// uncomment the below to profile the process's RAM usage
|
||||||
|
// install with: go get github.com/pkg/profile
|
||||||
|
// then run: curl http://localhost:8080/debug/pprof/heap > heap
|
||||||
|
// go tool pprof -png heap
|
||||||
|
|
||||||
// defer profile.Start(profile.MemProfile).Stop()
|
// defer profile.Start(profile.MemProfile).Stop()
|
||||||
// go func() {
|
// go func() {
|
||||||
// http.ListenAndServe(":8080", nil)
|
// http.ListenAndServe(":8080", nil)
|
||||||
@@ -487,64 +198,11 @@ func main() {
|
|||||||
// can be useful when debugging sandboxed notary
|
// can be useful when debugging sandboxed notary
|
||||||
http.HandleFunc("/getPubKey", getPubKey)
|
http.HandleFunc("/getPubKey", getPubKey)
|
||||||
|
|
||||||
http.HandleFunc("/init1", init1)
|
|
||||||
http.HandleFunc("/init2", init2)
|
|
||||||
http.HandleFunc("/getBlob", getBlob)
|
http.HandleFunc("/getBlob", getBlob)
|
||||||
http.HandleFunc("/setBlob", setBlob)
|
http.HandleFunc("/setBlob", setBlob)
|
||||||
http.HandleFunc("/getUploadProgress", getUploadProgress)
|
|
||||||
|
|
||||||
// step1 thru step4 deal with Paillier 2PC
|
// all the other request will end up in the httpHandler
|
||||||
http.HandleFunc("/step1", step1)
|
http.HandleFunc("/", httpHandler)
|
||||||
http.HandleFunc("/step2", step2)
|
|
||||||
http.HandleFunc("/step3", step3)
|
|
||||||
http.HandleFunc("/step4", step4)
|
|
||||||
|
|
||||||
// c1_step1 thru c1_step1 deal with TLS Handshake
|
|
||||||
http.HandleFunc("/c1_step1", c1_step1)
|
|
||||||
http.HandleFunc("/c1_step2", c1_step2)
|
|
||||||
http.HandleFunc("/c1_step3", c1_step3)
|
|
||||||
http.HandleFunc("/c1_step4", c1_step4)
|
|
||||||
http.HandleFunc("/c1_step5", c1_step5)
|
|
||||||
|
|
||||||
// c2_step1 thru c2_step4 deal with TLS Handshake
|
|
||||||
http.HandleFunc("/c2_step1", c2_step1)
|
|
||||||
http.HandleFunc("/c2_step2", c2_step2)
|
|
||||||
http.HandleFunc("/c2_step3", c2_step3)
|
|
||||||
http.HandleFunc("/c2_step4", c2_step4)
|
|
||||||
|
|
||||||
// c3_step1 thru c4_step3 deal with TLS Handshake and also prepare data
|
|
||||||
// needed to send Client Finished
|
|
||||||
http.HandleFunc("/c3_step1", c3_step1)
|
|
||||||
http.HandleFunc("/c3_step2", c3_step2)
|
|
||||||
|
|
||||||
http.HandleFunc("/c4_step1", c4_step1)
|
|
||||||
http.HandleFunc("/c4_step2", c4_step2)
|
|
||||||
http.HandleFunc("/c4_step3", c4_step3)
|
|
||||||
|
|
||||||
// c5_pre1 thru c5_step3 check Server Finished
|
|
||||||
http.HandleFunc("/c5_pre1", c5_pre1)
|
|
||||||
http.HandleFunc("/c5_step1", c5_step1)
|
|
||||||
http.HandleFunc("/c5_step2", c5_step2)
|
|
||||||
http.HandleFunc("/c5_step3", c5_step3)
|
|
||||||
|
|
||||||
// c6_step1 thru c6_step2 prepare encrypted counter blocks for the
|
|
||||||
// client's request to the webserver
|
|
||||||
http.HandleFunc("/c6_step1", c6_step1)
|
|
||||||
http.HandleFunc("/c6_step2", c6_step2)
|
|
||||||
|
|
||||||
// c7_step1 thru c7_step2 prepare the GCTR block needed to compute the MAC
|
|
||||||
// for the client's request
|
|
||||||
http.HandleFunc("/c7_step1", c7_step1)
|
|
||||||
http.HandleFunc("/c7_step2", c7_step2)
|
|
||||||
http.HandleFunc("/checkC7Commit", checkC7Commit)
|
|
||||||
|
|
||||||
// steps ghash_step1 thru ghash_step3 compute the GHASH output needed to
|
|
||||||
// compute the MAC for the client's request
|
|
||||||
http.HandleFunc("/ghash_step1", ghash_step1)
|
|
||||||
http.HandleFunc("/ghash_step2", ghash_step2)
|
|
||||||
http.HandleFunc("/ghash_step3", ghash_step3)
|
|
||||||
|
|
||||||
http.HandleFunc("/commitHash", commitHash)
|
|
||||||
|
|
||||||
http.ListenAndServe("0.0.0.0:10011", nil)
|
http.ListenAndServe("0.0.0.0:10011", nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"notary/evaluator"
|
"notary/evaluator"
|
||||||
"notary/garbled_pool"
|
"notary/garbled_pool"
|
||||||
@@ -72,8 +71,8 @@ type Session struct {
|
|||||||
notaryKey []byte
|
notaryKey []byte
|
||||||
// clientKey is a symmetric key used to decrypt messages FROM the client
|
// clientKey is a symmetric key used to decrypt messages FROM the client
|
||||||
clientKey []byte
|
clientKey []byte
|
||||||
// signingKey is an ephemeral key used to sign the notarization session
|
// SigningKey is an ephemeral key used to sign the notarization session
|
||||||
signingKey *ecdsa.PrivateKey
|
SigningKey ecdsa.PrivateKey
|
||||||
// StorageDir is where the blobs from the client are stored
|
// StorageDir is where the blobs from the client are stored
|
||||||
StorageDir string
|
StorageDir string
|
||||||
// msgsSeen contains a list of all messages seen from the client
|
// msgsSeen contains a list of all messages seen from the client
|
||||||
@@ -84,16 +83,21 @@ type Session struct {
|
|||||||
PmsOuterHashState []byte
|
PmsOuterHashState []byte
|
||||||
// MsOuterHashState is the state of the outer hash of HMAC needed to compute the MS
|
// MsOuterHashState is the state of the outer hash of HMAC needed to compute the MS
|
||||||
MsOuterHashState []byte
|
MsOuterHashState []byte
|
||||||
// Commitment is the hash of plaintext output for each circuit
|
// hisCommitment is client's salted commitment for each circuit
|
||||||
Commitment [][]byte
|
hisCommitment [][]byte
|
||||||
// Salt is used to salt Commitment before sending it to the client
|
// encodedOutput is notary's encoded output for each circuit
|
||||||
Salt [][]byte
|
encodedOutput [][]byte
|
||||||
|
// c6CheckValue is encoded outputs and decoding table which must the sent to
|
||||||
|
// Client as part of dual execution garbling. We store it here until Client
|
||||||
|
// sends her commitment. Then we send it out.
|
||||||
|
c6CheckValue []byte
|
||||||
// meta contains information about circuits
|
// meta contains information about circuits
|
||||||
meta []*meta.Circuit
|
meta []*meta.Circuit
|
||||||
// Tt/Dt are file handles for truth tables/decoding tables which are used
|
// Tt are file handles for truth tables which are used
|
||||||
// to stream directly to the HTTP response (saving memory)
|
// to stream directly to the HTTP response (saving memory)
|
||||||
Dt []*os.File
|
Tt [][]*os.File
|
||||||
Tt []*os.File
|
// dt are decoding tables for each execution of each garbled circuit
|
||||||
|
dt [][][]byte
|
||||||
// streamCounter is used when client uploads his blob to the notary
|
// streamCounter is used when client uploads his blob to the notary
|
||||||
streamCounter *StreamCounter
|
streamCounter *StreamCounter
|
||||||
// Gp is used to access the garbled pool
|
// Gp is used to access the garbled pool
|
||||||
@@ -108,7 +112,7 @@ type Session struct {
|
|||||||
|
|
||||||
// Init1 is the first message from the client. It starts Oblivious Transfer
|
// Init1 is the first message from the client. It starts Oblivious Transfer
|
||||||
// setup and we also initialize all of Session's structures.
|
// setup and we also initialize all of Session's structures.
|
||||||
func (s *Session) Init1(body, blob []byte, signingKey ecdsa.PrivateKey) []byte {
|
func (s *Session) Init1(body []byte) []byte {
|
||||||
s.sequenceCheck(1)
|
s.sequenceCheck(1)
|
||||||
s.g = new(garbler.Garbler)
|
s.g = new(garbler.Garbler)
|
||||||
s.e = new(evaluator.Evaluator)
|
s.e = new(evaluator.Evaluator)
|
||||||
@@ -116,10 +120,9 @@ func (s *Session) Init1(body, blob []byte, signingKey ecdsa.PrivateKey) []byte {
|
|||||||
s.otR = new(ot.OTReceiver)
|
s.otR = new(ot.OTReceiver)
|
||||||
s.p2pc = new(paillier2pc.Paillier2PC)
|
s.p2pc = new(paillier2pc.Paillier2PC)
|
||||||
s.ghash = new(ghash.GHASH)
|
s.ghash = new(ghash.GHASH)
|
||||||
s.signingKey = &signingKey
|
|
||||||
// the first 64 bytes are client pubkey for ECDH
|
// the first 64 bytes are client pubkey for ECDH
|
||||||
o := 0
|
o := 0
|
||||||
s.clientKey, s.notaryKey = s.getSymmetricKeys(body[o:o+64], &signingKey)
|
s.clientKey, s.notaryKey = s.getSymmetricKeys(body[o:o+64], &s.SigningKey)
|
||||||
o += 64
|
o += 64
|
||||||
c6Count := int(new(big.Int).SetBytes(body[o : o+2]).Uint64())
|
c6Count := int(new(big.Int).SetBytes(body[o : o+2]).Uint64())
|
||||||
o += 2
|
o += 2
|
||||||
@@ -153,26 +156,33 @@ func (s *Session) Init1(body, blob []byte, signingKey ecdsa.PrivateKey) []byte {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get already garbled circuits
|
// get already garbled circuits ...
|
||||||
blobs := s.Gp.GetBlobs(c6Count)
|
blobs := s.Gp.GetBlobs(c6Count)
|
||||||
// separate into input labels, truth tables, decoding table
|
// and separate into input labels, truth tables, decoding table
|
||||||
il := make([]*[]byte, len(blobs))
|
il := make([][][]byte, len(s.Gp.Circuits))
|
||||||
s.Tt = make([]*os.File, len(blobs))
|
s.Tt = make([][]*os.File, len(s.Gp.Circuits))
|
||||||
s.Dt = make([]*os.File, len(blobs))
|
s.dt = make([][][]byte, len(s.Gp.Circuits))
|
||||||
for i := 0; i < len(blobs); i++ {
|
// depending on the number of circuit executions, there may be more than
|
||||||
il[i] = blobs[i].Il
|
// one Blob for every circuit
|
||||||
s.Tt[i] = blobs[i].TtFile
|
for i := 1; i < len(s.Gp.Circuits); i++ {
|
||||||
s.Dt[i] = blobs[i].DtFile
|
il[i] = make([][]byte, len(blobs[i]))
|
||||||
|
s.Tt[i] = make([]*os.File, len(blobs[i]))
|
||||||
|
s.dt[i] = make([][]byte, len(blobs[i]))
|
||||||
|
for j, blob := range blobs[i] {
|
||||||
|
il[i][j] = *blob.Il
|
||||||
|
s.Tt[i][j] = blob.TtFile
|
||||||
|
s.dt[i][j] = *blob.Dt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.meta = s.Gp.Circuits
|
s.meta = s.Gp.Circuits
|
||||||
s.g.Init(il, s.meta, c6Count)
|
s.g.Init(il, s.meta, c6Count)
|
||||||
s.e.Init(s.meta, c6Count)
|
s.e.Init(s.meta, c6Count)
|
||||||
s.Salt = make([][]byte, len(s.g.Cs))
|
s.hisCommitment = make([][]byte, len(s.g.Cs))
|
||||||
s.Commitment = make([][]byte, len(s.g.Cs))
|
s.encodedOutput = make([][]byte, len(s.g.Cs))
|
||||||
|
|
||||||
s.p2pc.Init()
|
s.p2pc.Init()
|
||||||
return u.Concat(blob, s.encryptToClient(u.Concat(A, seedCommit, allBs,
|
return s.encryptToClient(u.Concat(A, seedCommit, allBs, senderSeedShare))
|
||||||
senderSeedShare)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue initialization. Setting up the Oblivious Transfer.
|
// continue initialization. Setting up the Oblivious Transfer.
|
||||||
@@ -201,10 +211,18 @@ func (s *Session) Init2(encrypted []byte) []byte {
|
|||||||
return s.encryptToClient(u.Concat(encryptedColumns, receiverSeedShare, x, t))
|
return s.encryptToClient(u.Concat(encryptedColumns, receiverSeedShare, x, t))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlobChunk returns file handles to truth tables and decoding table
|
// GetBlob returns file handles to truth tables
|
||||||
func (s *Session) GetBlob(encrypted []byte) ([]*os.File, []*os.File) {
|
func (s *Session) GetBlob(encrypted []byte) []*os.File {
|
||||||
s.sequenceCheck(3)
|
s.sequenceCheck(3)
|
||||||
return s.Tt, s.Dt
|
// flatten into one slice
|
||||||
|
var flat []*os.File
|
||||||
|
for _, sliceOfFiles := range s.Tt {
|
||||||
|
if len(sliceOfFiles) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
flat = append(flat, sliceOfFiles...)
|
||||||
|
}
|
||||||
|
return flat
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBlobChunk stores a blob from the client.
|
// SetBlobChunk stores a blob from the client.
|
||||||
@@ -224,7 +242,7 @@ func (s *Session) SetBlob(respBody io.ReadCloser) []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) GetUploadProgress() []byte {
|
func (s *Session) GetUploadProgress(dummy []byte) []byte {
|
||||||
// special case. This message may be repeated many times
|
// special case. This message may be repeated many times
|
||||||
s.sequenceCheck(100)
|
s.sequenceCheck(100)
|
||||||
bytes := make([]byte, 4)
|
bytes := make([]byte, 4)
|
||||||
@@ -273,22 +291,18 @@ func (s *Session) C1_step1(encrypted []byte) []byte {
|
|||||||
func (s *Session) C1_step2(encrypted []byte) []byte {
|
func (s *Session) C1_step2(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(10)
|
s.sequenceCheck(10)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
ttBlob, dtBlob := s.RetrieveBlobsForNotary(1)
|
return s.encryptToClient(s.common_step2(1, body))
|
||||||
notaryLabels, clientLabels := s.c_step2(1, body)
|
|
||||||
output := s.e.Evaluate(1, notaryLabels, clientLabels, ttBlob, dtBlob)
|
|
||||||
s.Commitment[1] = u.Sha256(output)
|
|
||||||
s.Salt[1] = u.GetRandom(32)
|
|
||||||
hash := u.Sha256(u.Concat(s.Commitment[1], s.Salt[1]))
|
|
||||||
// unmask the output
|
|
||||||
s.PmsOuterHashState = u.XorBytes(output[0:32], s.g.Cs[1].Masks[1])
|
|
||||||
return s.encryptToClient(hash)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// [REF 1] Step 4. N computes a1 and passes it to C.
|
// [REF 1] Step 4. N computes a1 and passes it to C.
|
||||||
func (s *Session) C1_step3(encrypted []byte) []byte {
|
func (s *Session) C1_step3(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(11)
|
s.sequenceCheck(11)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
a1 := u.FinishHash(s.PmsOuterHashState, body)
|
output := s.processDecommit(1, body[:len(body)-32])
|
||||||
|
hisInnerHash := body[len(body)-32:]
|
||||||
|
// unmask the output
|
||||||
|
s.PmsOuterHashState = u.XorBytes(output[0:32], s.g.Cs[1].Masks[1])
|
||||||
|
a1 := u.FinishHash(s.PmsOuterHashState, hisInnerHash)
|
||||||
return s.encryptToClient(a1)
|
return s.encryptToClient(a1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,23 +335,19 @@ func (s *Session) C2_step1(encrypted []byte) []byte {
|
|||||||
func (s *Session) C2_step2(encrypted []byte) []byte {
|
func (s *Session) C2_step2(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(15)
|
s.sequenceCheck(15)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
ttBlob, olBlob := s.RetrieveBlobsForNotary(2)
|
return s.encryptToClient(s.common_step2(2, body))
|
||||||
notaryLabels, clientLabels := s.c_step2(2, body)
|
|
||||||
output := s.e.Evaluate(2, notaryLabels, clientLabels, ttBlob, olBlob)
|
|
||||||
s.Commitment[2] = u.Sha256(output)
|
|
||||||
s.Salt[2] = u.GetRandom(32)
|
|
||||||
hash := u.Sha256(u.Concat(s.Commitment[2], s.Salt[2]))
|
|
||||||
// unmask the output
|
|
||||||
s.MsOuterHashState = u.XorBytes(output[0:32], s.g.Cs[2].Masks[1])
|
|
||||||
return s.encryptToClient(hash)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// [REF 1] Step 14 and Step 21. N computes a1 and a1 and sends it to C.
|
// [REF 1] Step 14 and Step 21. N computes a1 and a1 and sends it to C.
|
||||||
func (s *Session) C2_step3(encrypted []byte) []byte {
|
func (s *Session) C2_step3(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(16)
|
s.sequenceCheck(16)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
a1inner := body[:32]
|
output := s.processDecommit(2, body[:len(body)-64])
|
||||||
a1inner_vd := body[32:64]
|
a1inner := body[len(body)-64 : len(body)-32]
|
||||||
|
a1inner_vd := body[len(body)-32:]
|
||||||
|
// unmask the output
|
||||||
|
s.MsOuterHashState = u.XorBytes(output[0:32], s.g.Cs[2].Masks[1])
|
||||||
a1 := u.FinishHash(s.MsOuterHashState, a1inner)
|
a1 := u.FinishHash(s.MsOuterHashState, a1inner)
|
||||||
a1_vd := u.FinishHash(s.MsOuterHashState, a1inner_vd)
|
a1_vd := u.FinishHash(s.MsOuterHashState, a1inner_vd)
|
||||||
return s.encryptToClient(u.Concat(a1, a1_vd))
|
return s.encryptToClient(u.Concat(a1, a1_vd))
|
||||||
@@ -380,21 +390,20 @@ func (s *Session) C3_step1(encrypted []byte) []byte {
|
|||||||
func (s *Session) C3_step2(encrypted []byte) []byte {
|
func (s *Session) C3_step2(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(19)
|
s.sequenceCheck(19)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
ttBlob, olBlob := s.RetrieveBlobsForNotary(3)
|
return s.encryptToClient(s.common_step2(3, body))
|
||||||
notaryLabels, clientLabels := s.c_step2(3, body)
|
|
||||||
output := s.e.Evaluate(3, notaryLabels, clientLabels, ttBlob, olBlob)
|
|
||||||
// notary doesn't need to parse the output of the circuit, since we
|
|
||||||
// already know what out TLS key shares are
|
|
||||||
s.Commitment[3] = u.Sha256(output)
|
|
||||||
s.Salt[3] = u.GetRandom(32)
|
|
||||||
hash := u.Sha256(u.Concat(s.Commitment[3], s.Salt[3]))
|
|
||||||
return s.encryptToClient(hash)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// [REF 1] Step 18.
|
// [REF 1] Step 18.
|
||||||
func (s *Session) C4_step1(encrypted []byte) []byte {
|
func (s *Session) C4_step1(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(20)
|
s.sequenceCheck(20)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
|
// to save a round-trip, circuit 3 piggy-backs on this message to parse the
|
||||||
|
// decommitment. Notary doesn't need to parse the output of the circuit,
|
||||||
|
// since we already know what out TLS key shares are
|
||||||
|
decommitSize := len(s.encodedOutput[3]) + len(u.Concat(s.dt[3]...)) + 32
|
||||||
|
s.processDecommit(3, body[:decommitSize])
|
||||||
|
|
||||||
|
body = body[decommitSize:]
|
||||||
g := s.g
|
g := s.g
|
||||||
s.setCircuitInputs(4,
|
s.setCircuitInputs(4,
|
||||||
s.swkShare,
|
s.swkShare,
|
||||||
@@ -404,14 +413,14 @@ func (s *Session) C4_step1(encrypted []byte) []byte {
|
|||||||
g.Cs[4].Masks[1],
|
g.Cs[4].Masks[1],
|
||||||
g.Cs[4].Masks[2])
|
g.Cs[4].Masks[2])
|
||||||
|
|
||||||
hisOtReq := s.c_step1A(4, body)
|
hisOtReq := body
|
||||||
// instead of the usual c_step1B, we have a special case
|
// instead of the usual c_step1B, we have a special case
|
||||||
otResp, encryptedLabels := s.c4_step1B(hisOtReq)
|
otResp, encryptedLabels := s.c4_step1A(hisOtReq)
|
||||||
out := s.c_step1C(4, otResp)
|
out := s.c_step1B(4, otResp)
|
||||||
return s.encryptToClient(u.Concat(out, encryptedLabels))
|
return s.encryptToClient(u.Concat(out, encryptedLabels))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) c4_step1B(hisOtReq []byte) ([]byte, []byte) {
|
func (s *Session) c4_step1A(hisOtReq []byte) ([]byte, []byte) {
|
||||||
// We need to make sure that the same input labels which we give
|
// We need to make sure that the same input labels which we give
|
||||||
// to the client for c4's client_write_key (cwk) and client_write_iv
|
// to the client for c4's client_write_key (cwk) and client_write_iv
|
||||||
// (civ) will also be given for all invocations of circuit 6. This ensures
|
// (civ) will also be given for all invocations of circuit 6. This ensures
|
||||||
@@ -492,20 +501,11 @@ func (s *Session) c4_step1B(hisOtReq []byte) ([]byte, []byte) {
|
|||||||
return newOtResp, encryptedLabels
|
return newOtResp, encryptedLabels
|
||||||
}
|
}
|
||||||
|
|
||||||
// [REF 1] Step 18. Notary doesn't need to parse the circuit's output because
|
// [REF 1] Step 18.
|
||||||
// the masks that he inputted become his TLS keys' shares.
|
|
||||||
func (s *Session) C4_step2(encrypted []byte) []byte {
|
func (s *Session) C4_step2(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(21)
|
s.sequenceCheck(21)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
ttBlob, olBlob := s.RetrieveBlobsForNotary(4)
|
return s.encryptToClient(s.common_step2(4, body))
|
||||||
notaryLabels, clientLabels := s.c_step2(4, body)
|
|
||||||
output := s.e.Evaluate(4, notaryLabels, clientLabels, ttBlob, olBlob)
|
|
||||||
// notary doesn't need to parse the output of the circuit, since we
|
|
||||||
// already know what out TLS key shares are
|
|
||||||
s.Commitment[4] = u.Sha256(output)
|
|
||||||
s.Salt[4] = u.GetRandom(32)
|
|
||||||
hash := u.Sha256(u.Concat(s.Commitment[4], s.Salt[4]))
|
|
||||||
return s.encryptToClient(hash)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute MAC for Client_Finished using Oblivious Transfer
|
// compute MAC for Client_Finished using Oblivious Transfer
|
||||||
@@ -514,9 +514,11 @@ func (s *Session) C4_step2(encrypted []byte) []byte {
|
|||||||
func (s *Session) C4_step3(encrypted []byte) []byte {
|
func (s *Session) C4_step3(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(22)
|
s.sequenceCheck(22)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
|
// Notary doesn't need to parse circuit's 4 output because
|
||||||
|
// the masks that he inputted become his TLS keys' shares.
|
||||||
|
s.processDecommit(4, body[:len(body)-(16+33)])
|
||||||
|
body = body[len(body)-(16+33):]
|
||||||
g := s.g
|
g := s.g
|
||||||
u.Assert(len(body) == 16+33)
|
|
||||||
|
|
||||||
o := 0
|
o := 0
|
||||||
encCF := body[o : o+16]
|
encCF := body[o : o+16]
|
||||||
o += 16
|
o += 16
|
||||||
@@ -578,14 +580,13 @@ func (s *Session) C5_pre1(encrypted []byte) []byte {
|
|||||||
func (s *Session) C5_step1(encrypted []byte) []byte {
|
func (s *Session) C5_step1(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(24)
|
s.sequenceCheck(24)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
g := s.g
|
|
||||||
s.setCircuitInputs(5,
|
s.setCircuitInputs(5,
|
||||||
s.MsOuterHashState,
|
s.MsOuterHashState,
|
||||||
s.swkShare,
|
s.swkShare,
|
||||||
s.sivShare,
|
s.sivShare,
|
||||||
g.Cs[5].Masks[1],
|
s.g.Cs[5].Masks[1],
|
||||||
g.Cs[5].Masks[2])
|
s.g.Cs[5].Masks[2])
|
||||||
u.Assert(len(g.Cs[5].InputBits)/8 == 84)
|
u.Assert(len(s.g.Cs[5].InputBits)/8 == 84)
|
||||||
out := s.c_step1(5, body)
|
out := s.c_step1(5, body)
|
||||||
return s.encryptToClient(out)
|
return s.encryptToClient(out)
|
||||||
}
|
}
|
||||||
@@ -594,13 +595,7 @@ func (s *Session) C5_step1(encrypted []byte) []byte {
|
|||||||
func (s *Session) C5_step2(encrypted []byte) []byte {
|
func (s *Session) C5_step2(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(25)
|
s.sequenceCheck(25)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
ttBlob, olBlob := s.RetrieveBlobsForNotary(5)
|
return s.encryptToClient(s.common_step2(5, body))
|
||||||
notaryLabels, clientLabels := s.c_step2(5, body)
|
|
||||||
output := s.e.Evaluate(5, notaryLabels, clientLabels, ttBlob, olBlob)
|
|
||||||
s.Commitment[5] = u.Sha256(output)
|
|
||||||
s.Salt[5] = u.GetRandom(32)
|
|
||||||
hash := u.Sha256(u.Concat(s.Commitment[5], s.Salt[5]))
|
|
||||||
return s.encryptToClient(hash)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute MAC for Server_Finished using Oblivious Transfer
|
// compute MAC for Server_Finished using Oblivious Transfer
|
||||||
@@ -608,9 +603,9 @@ func (s *Session) C5_step2(encrypted []byte) []byte {
|
|||||||
func (s *Session) C5_step3(encrypted []byte) []byte {
|
func (s *Session) C5_step3(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(26)
|
s.sequenceCheck(26)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
|
s.processDecommit(5, body[:len(body)-(16+33)])
|
||||||
|
body = body[len(body)-(16+33):]
|
||||||
g := s.g
|
g := s.g
|
||||||
u.Assert(len(body) == 16+33)
|
|
||||||
|
|
||||||
o := 0
|
o := 0
|
||||||
encSF := body[o : o+16]
|
encSF := body[o : o+16]
|
||||||
o += 16
|
o += 16
|
||||||
@@ -657,7 +652,7 @@ func (s *Session) C6_step1(encrypted []byte) []byte {
|
|||||||
}
|
}
|
||||||
s.setCircuitInputs(6, allInputs...)
|
s.setCircuitInputs(6, allInputs...)
|
||||||
|
|
||||||
hisOtReq := s.c_step1A(6, body)
|
hisOtReq := body
|
||||||
// ---------------------------------------
|
// ---------------------------------------
|
||||||
// instead of the usual c_step1B, we have a special case:
|
// instead of the usual c_step1B, we have a special case:
|
||||||
// we need to remove all the labels corresponding to client_write_key
|
// we need to remove all the labels corresponding to client_write_key
|
||||||
@@ -674,25 +669,34 @@ func (s *Session) C6_step1(encrypted []byte) []byte {
|
|||||||
// proceed with the regular step1 flow
|
// proceed with the regular step1 flow
|
||||||
// ---------------------------------------
|
// ---------------------------------------
|
||||||
otResp := s.otS.ProcessRequest(hisOtReq, labels)
|
otResp := s.otS.ProcessRequest(hisOtReq, labels)
|
||||||
out := s.c_step1C(6, otResp)
|
out := s.c_step1B(6, otResp)
|
||||||
return s.encryptToClient(out)
|
return s.encryptToClient(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) C6_step2(encrypted []byte) []byte {
|
func (s *Session) C6_pre2(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(28)
|
s.sequenceCheck(28)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
ttBlob, olBlob := s.RetrieveBlobsForNotary(6)
|
// add a dummy 32-byte commitment to keep common_step2() happy
|
||||||
notaryLabels, clientLabels := s.c_step2(6, body)
|
body = append(body, make([]byte, 32)...)
|
||||||
output := s.e.Evaluate(6, notaryLabels, clientLabels, ttBlob, olBlob)
|
s.c6CheckValue = s.common_step2(6, body)
|
||||||
s.Commitment[6] = u.Sha256(output)
|
// do not send c6CheckValue until Client sends his commitment
|
||||||
s.Salt[6] = u.GetRandom(32)
|
return nil
|
||||||
hash := u.Sha256(u.Concat(s.Commitment[6], s.Salt[6]))
|
}
|
||||||
return s.encryptToClient(hash)
|
|
||||||
|
func (s *Session) C6_step2(encrypted []byte) []byte {
|
||||||
|
s.sequenceCheck(29)
|
||||||
|
body := s.decryptFromClient(encrypted)
|
||||||
|
u.Assert(len(body) == 32)
|
||||||
|
s.hisCommitment[6] = body
|
||||||
|
return s.encryptToClient(s.c6CheckValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) C7_step1(encrypted []byte) []byte {
|
func (s *Session) C7_step1(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(29)
|
s.sequenceCheck(30)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
|
decommitSize := len(s.encodedOutput[6]) + len(u.Concat(s.dt[6]...)) + 32
|
||||||
|
s.processDecommit(6, body[:decommitSize])
|
||||||
|
body = body[decommitSize:]
|
||||||
g := s.g
|
g := s.g
|
||||||
var allInputs [][]byte
|
var allInputs [][]byte
|
||||||
allInputs = append(allInputs, s.cwkShare)
|
allInputs = append(allInputs, s.cwkShare)
|
||||||
@@ -706,32 +710,18 @@ func (s *Session) C7_step1(encrypted []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) C7_step2(encrypted []byte) []byte {
|
func (s *Session) C7_step2(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(30)
|
|
||||||
body := s.decryptFromClient(encrypted)
|
|
||||||
ttBlob, olBlob := s.RetrieveBlobsForNotary(7)
|
|
||||||
notaryLabels, clientLabels := s.c_step2(7, body)
|
|
||||||
output := s.e.Evaluate(7, notaryLabels, clientLabels, ttBlob, olBlob)
|
|
||||||
s.Commitment[7] = u.Sha256(output)
|
|
||||||
s.Salt[7] = u.GetRandom(32)
|
|
||||||
hash := u.Sha256(u.Concat(s.Commitment[7], s.Salt[7]))
|
|
||||||
return s.encryptToClient(hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
// one extra communication round trip to check the hash
|
|
||||||
func (s *Session) CheckC7Commit(encrypted []byte) []byte {
|
|
||||||
s.sequenceCheck(31)
|
s.sequenceCheck(31)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
hisCommit := body
|
return s.encryptToClient(s.common_step2(7, body))
|
||||||
if !bytes.Equal(hisCommit, s.Commitment[7]) {
|
|
||||||
panic("commit hash doesn't match")
|
|
||||||
}
|
|
||||||
return s.encryptToClient(s.Salt[7])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute MAC for client's request using Oblivious Transfer
|
// compute MAC for client's request using Oblivious Transfer
|
||||||
func (s *Session) Ghash_step1(encrypted []byte) []byte {
|
func (s *Session) Ghash_step1(encrypted []byte) []byte {
|
||||||
s.sequenceCheck(32)
|
s.sequenceCheck(32)
|
||||||
body := s.decryptFromClient(encrypted)
|
body := s.decryptFromClient(encrypted)
|
||||||
|
decommitSize := len(s.encodedOutput[7]) + len(u.Concat(s.dt[7]...)) + 32
|
||||||
|
s.processDecommit(7, body[:decommitSize])
|
||||||
|
body = body[decommitSize:]
|
||||||
o := 0
|
o := 0
|
||||||
mpnBytes := body[o : o+2]
|
mpnBytes := body[o : o+2]
|
||||||
o += 2
|
o += 2
|
||||||
@@ -814,7 +804,7 @@ func (s *Session) CommitHash(encrypted []byte) []byte {
|
|||||||
hisPMSShareHash := body[64:96]
|
hisPMSShareHash := body[64:96]
|
||||||
timeBytes := make([]byte, 8)
|
timeBytes := make([]byte, 8)
|
||||||
binary.BigEndian.PutUint64(timeBytes, uint64(time.Now().Unix()))
|
binary.BigEndian.PutUint64(timeBytes, uint64(time.Now().Unix()))
|
||||||
signature := u.ECDSASign(s.signingKey,
|
signature := u.ECDSASign(&s.SigningKey,
|
||||||
hisCommitHash,
|
hisCommitHash,
|
||||||
hisKeyShareHash,
|
hisKeyShareHash,
|
||||||
hisPMSShareHash,
|
hisPMSShareHash,
|
||||||
@@ -895,75 +885,51 @@ func (s *Session) sequenceCheck(seqNo int) {
|
|||||||
s.msgsSeen = append(s.msgsSeen, seqNo)
|
s.msgsSeen = append(s.msgsSeen, seqNo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns truth tables and decoding tables for the circuit number cNo from the
|
// returns truth tables for the circuit number cNo from the
|
||||||
// blob which we received earlier from the client
|
// blob which we received earlier from the client
|
||||||
func (s *Session) RetrieveBlobsForNotary(cNo int) ([]byte, []byte) {
|
func (s *Session) RetrieveBlobsForNotary(cNo int) []byte {
|
||||||
off, ttSize, dtSize := s.getCircuitBlobOffset(cNo)
|
off, ttSize := s.getCircuitBlobOffset(cNo)
|
||||||
path := filepath.Join(s.StorageDir, "blobForNotary")
|
path := filepath.Join(s.StorageDir, "blobForNotary")
|
||||||
file, err := os.Open(path)
|
file, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
buffer := make([]byte, ttSize+dtSize)
|
buffer := make([]byte, ttSize)
|
||||||
_, err = file.ReadAt(buffer, int64(off))
|
_, err = file.ReadAt(buffer, int64(off))
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
tt := buffer[:ttSize]
|
tt := buffer[:ttSize]
|
||||||
dt := buffer[ttSize:]
|
return tt
|
||||||
return tt, dt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCircuitBlobOffset finds the offset and size of the tt+dt blob for circuit cNo
|
// GetCircuitBlobOffset finds the offset and size of the tt+dt blob for circuit cNo
|
||||||
// in the blob of all circuits
|
// in the blob of all circuits
|
||||||
func (s *Session) getCircuitBlobOffset(cNo int) (int, int, int) {
|
func (s *Session) getCircuitBlobOffset(cNo int) (int, int) {
|
||||||
offset := 0
|
offset := 0
|
||||||
ttLen := 0
|
ttLen := 0
|
||||||
dtLen := 0
|
|
||||||
for i := 1; i < len(s.g.Cs); i++ {
|
for i := 1; i < len(s.g.Cs); i++ {
|
||||||
offset += ttLen + dtLen
|
offset += ttLen
|
||||||
ttLen = s.g.Cs[i].Meta.AndGateCount * 48
|
ttLen = s.g.Cs[i].Meta.AndGateCount * 48
|
||||||
dtLen = int(math.Ceil(float64(s.g.Cs[i].Meta.OutputSize) / 8))
|
|
||||||
if i == 6 {
|
if i == 6 {
|
||||||
ttLen = s.g.C6Count * ttLen
|
ttLen = s.g.C6Count * ttLen
|
||||||
dtLen = s.g.C6Count * dtLen
|
|
||||||
}
|
}
|
||||||
if i == cNo {
|
if i == cNo {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return offset, ttLen, dtLen
|
return offset, ttLen
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) c_step1A(cNo int, body []byte) []byte {
|
func (s *Session) c_step1A(cNo int, hisOtReq []byte) []byte {
|
||||||
o := 0
|
|
||||||
// check client's commitment to the previous circuit's output
|
|
||||||
if cNo > 1 {
|
|
||||||
hisCommit := body[:32]
|
|
||||||
o += 32
|
|
||||||
if !bytes.Equal(hisCommit, s.Commitment[cNo-1]) {
|
|
||||||
panic("commitments don't match")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hisOtReq := body[o:]
|
|
||||||
return hisOtReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) c_step1B(cNo int, hisOtReq []byte) []byte {
|
|
||||||
otResp := s.otS.ProcessRequest(hisOtReq, s.g.GetClientLabels(cNo))
|
otResp := s.otS.ProcessRequest(hisOtReq, s.g.GetClientLabels(cNo))
|
||||||
return otResp
|
return otResp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) c_step1C(cNo int, otResp []byte) []byte {
|
func (s *Session) c_step1B(cNo int, otResp []byte) []byte {
|
||||||
inputLabels := s.g.GetNotaryLabels(cNo)
|
inputLabels := s.g.GetNotaryLabels(cNo)
|
||||||
myOtReq := s.otR.CreateRequest(s.g.Cs[cNo].InputBits)
|
myOtReq := s.otR.CreateRequest(s.g.Cs[cNo].InputBits)
|
||||||
// send salt for the previous circuit's commitment
|
|
||||||
var salt []byte = nil
|
|
||||||
if cNo > 1 {
|
|
||||||
salt = s.Salt[cNo-1]
|
|
||||||
}
|
|
||||||
return u.Concat(
|
return u.Concat(
|
||||||
salt,
|
|
||||||
inputLabels,
|
inputLabels,
|
||||||
otResp,
|
otResp,
|
||||||
myOtReq)
|
myOtReq)
|
||||||
@@ -971,13 +937,12 @@ func (s *Session) c_step1C(cNo int, otResp []byte) []byte {
|
|||||||
|
|
||||||
// c_step1 is common for all circuits
|
// c_step1 is common for all circuits
|
||||||
func (s *Session) c_step1(cNo int, body []byte) []byte {
|
func (s *Session) c_step1(cNo int, body []byte) []byte {
|
||||||
hisOtReq := s.c_step1A(cNo, body)
|
hisOtReq := body
|
||||||
// because of the dual execution, both client and notary need to
|
// because of the dual execution, both client and notary need to
|
||||||
// receive their input labels via OT.
|
// receive their input labels via OT.
|
||||||
// we process client's OT request and create a notary's OT request.
|
// we process client's OT request and create a notary's OT request.
|
||||||
otResp := s.c_step1B(cNo, hisOtReq)
|
otResp := s.c_step1A(cNo, hisOtReq)
|
||||||
out := s.c_step1C(cNo, otResp)
|
return s.c_step1B(cNo, otResp)
|
||||||
return out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// given a slice of circuit inputs in the same order as expected by the c*.casm file,
|
// given a slice of circuit inputs in the same order as expected by the c*.casm file,
|
||||||
@@ -988,15 +953,93 @@ func (s *Session) setCircuitInputs(cNo int, inputs ...[]byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// c_step2 is common for all circuits. Returns notary's and client's input
|
// common_step2 is Step2 which is the same for all circuits. Returns a value
|
||||||
|
// which must be sent to the Client as part of dual execution garbling.
|
||||||
|
func (s *Session) common_step2(cNo int, body []byte) []byte {
|
||||||
|
ttBlob := s.RetrieveBlobsForNotary(cNo)
|
||||||
|
notaryLabels, clientLabels, clientCommitment := s.parse_step2(cNo, body)
|
||||||
|
s.hisCommitment[cNo] = clientCommitment
|
||||||
|
s.encodedOutput[cNo] = s.e.Evaluate(cNo, notaryLabels, clientLabels, ttBlob)
|
||||||
|
return u.Concat(s.encodedOutput[cNo], u.Concat(s.dt[cNo]...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse_step2 is common for all circuits. Returns notary's and client's input
|
||||||
// labels for the circuit number cNo.
|
// labels for the circuit number cNo.
|
||||||
// Notary is acting as the evaluator. Client sent its input labels in the clear
|
// Notary is acting as the evaluator. Client sent his input labels in the clear
|
||||||
// and also sent notary's input labels via OT.
|
// and he also sent notary's input labels via OT.
|
||||||
func (s *Session) c_step2(cNo int, body []byte) ([]byte, []byte) {
|
func (s *Session) parse_step2(cNo int, body []byte) ([]byte, []byte, []byte) {
|
||||||
|
o := 0
|
||||||
// exeCount is how many executions of this circuit we need
|
// exeCount is how many executions of this circuit we need
|
||||||
exeCount := []int{0, 1, 1, 1, 1, 1, s.g.C6Count, 1}[cNo]
|
exeCount := []int{0, 1, 1, 1, 1, 1, s.g.C6Count, 1}[cNo]
|
||||||
otResp := body[:s.g.Cs[cNo].Meta.NotaryInputSize*32*exeCount]
|
allNotaryOtSize := s.g.Cs[cNo].Meta.NotaryInputSize * 32 * exeCount
|
||||||
clientLabels := body[s.g.Cs[cNo].Meta.NotaryInputSize*32*exeCount:]
|
otResp := body[o : o+allNotaryOtSize]
|
||||||
|
o += allNotaryOtSize
|
||||||
|
allClientLabelsSize := s.g.Cs[cNo].Meta.ClientInputSize * 16 * exeCount
|
||||||
|
clientLabels := body[o : o+allClientLabelsSize]
|
||||||
|
o += allClientLabelsSize
|
||||||
|
clientCommitment := body[o : o+32]
|
||||||
|
o += 32
|
||||||
|
u.Assert(o == len(body))
|
||||||
notaryLabels := s.otR.ParseResponse(s.g.Cs[cNo].InputBits, otResp)
|
notaryLabels := s.otR.ParseResponse(s.g.Cs[cNo].InputBits, otResp)
|
||||||
return notaryLabels, clientLabels
|
return notaryLabels, clientLabels, clientCommitment
|
||||||
|
}
|
||||||
|
|
||||||
|
// processDecommit processes Client's decommitment, makes sure it matches the
|
||||||
|
// commitment, decodes and parses the Notary's circuit output.
|
||||||
|
// Client committed first, then Notary revealed his encoded outputs and
|
||||||
|
// decoding table and now the Client decommits.
|
||||||
|
func (s *Session) processDecommit(cNo int, decommit []byte) []byte {
|
||||||
|
o := 0
|
||||||
|
hisEncodedOutput := decommit[o : o+len(s.encodedOutput[cNo])]
|
||||||
|
o += len(s.encodedOutput[cNo])
|
||||||
|
myDecodingTable := u.Concat(s.dt[cNo]...)
|
||||||
|
hisDecodingTable := decommit[o : o+len(myDecodingTable)]
|
||||||
|
o += len(myDecodingTable)
|
||||||
|
hisSalt := decommit[o : o+32]
|
||||||
|
o += 32
|
||||||
|
u.Assert(o == len(decommit))
|
||||||
|
u.Assert(bytes.Equal(s.hisCommitment[cNo], u.Sha256(u.Concat(
|
||||||
|
hisEncodedOutput, hisDecodingTable, hisSalt))))
|
||||||
|
// decode his output, my output and compare them
|
||||||
|
hisPlaintext := u.XorBytes(myDecodingTable, hisEncodedOutput)
|
||||||
|
myPlaintext := u.XorBytes(hisDecodingTable, s.encodedOutput[cNo])
|
||||||
|
u.Assert(bytes.Equal(hisPlaintext, myPlaintext))
|
||||||
|
output := s.parsePlaintextOutput(cNo, myPlaintext)
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsePlaintextOutput parses the plaintext of each circuit execution into
|
||||||
|
// output bit and converts the output bits into a flat slice of bytes so that
|
||||||
|
// output values are in the same order as they appear in the *.casm files
|
||||||
|
func (s *Session) parsePlaintextOutput(cNo int, ptBytes []byte) []byte {
|
||||||
|
c := (s.meta)[cNo]
|
||||||
|
exeCount := []int{0, 1, 1, 1, 1, 1, s.g.C6Count, 1}[cNo]
|
||||||
|
chunks := u.SplitIntoChunks(ptBytes, len(ptBytes)/exeCount)
|
||||||
|
var output []byte
|
||||||
|
for i := 0; i < exeCount; i++ {
|
||||||
|
// plaintext has a padding in MSB to make it a multiple of 8 bits. We
|
||||||
|
// decompose into bits and drop the padding
|
||||||
|
outBits := u.BytesToBits(chunks[i])[0:c.OutputSize]
|
||||||
|
// reverse output bits so that the values of the output be placed in
|
||||||
|
// the same order as they appear in the *.casm files
|
||||||
|
outBytes := s.parseOutputBits(cNo, outBits)
|
||||||
|
output = append(output, outBytes...)
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseOutputBits converts the output bits of the circuit into a flat slice
|
||||||
|
// of bytes so that output values are in the same order as they appear in the *.casm files
|
||||||
|
func (s *Session) parseOutputBits(cNo int, outBits []int) []byte {
|
||||||
|
o := 0 // offset
|
||||||
|
var outBytes []byte
|
||||||
|
for _, v := range (s.meta)[cNo].OutputsSizes {
|
||||||
|
output := u.BitsToBytes(outBits[o : o+v])
|
||||||
|
outBytes = append(outBytes, output...)
|
||||||
|
o += v
|
||||||
|
}
|
||||||
|
if o != (s.meta)[cNo].OutputSize {
|
||||||
|
panic("o != e.g.Cs[cNo].OutputSize")
|
||||||
|
}
|
||||||
|
return outBytes
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type method func([]byte) []byte
|
||||||
|
|
||||||
// smItem is stored internally by SessionManager
|
// smItem is stored internally by SessionManager
|
||||||
type smItem struct {
|
type smItem struct {
|
||||||
session *session.Session
|
session *session.Session
|
||||||
|
// methodLookup is a map used to look up the session's method by its name
|
||||||
|
methodLookup map[string]method
|
||||||
lastSeen int64 // timestamp of last activity
|
lastSeen int64 // timestamp of last activity
|
||||||
creationTime int64 // timestamp
|
creationTime int64 // timestamp
|
||||||
}
|
}
|
||||||
@@ -41,9 +45,67 @@ func (sm *SessionManager) AddSession(key string) *session.Session {
|
|||||||
s.Sid = key
|
s.Sid = key
|
||||||
s.DestroyChan = sm.destroyChan
|
s.DestroyChan = sm.destroyChan
|
||||||
now := int64(time.Now().UnixNano() / 1e9)
|
now := int64(time.Now().UnixNano() / 1e9)
|
||||||
|
methodLookup := map[string]method{
|
||||||
|
"init1": s.Init1,
|
||||||
|
"init2": s.Init2,
|
||||||
|
|
||||||
|
"getUploadProgress": s.GetUploadProgress,
|
||||||
|
|
||||||
|
// step1 thru step4 deal with Paillier 2PC
|
||||||
|
"step1": s.Step1,
|
||||||
|
"step2": s.Step2,
|
||||||
|
"step3": s.Step3,
|
||||||
|
"step4": s.Step4,
|
||||||
|
|
||||||
|
// // c1_step1 thru c1_step1 deal with TLS Handshake
|
||||||
|
"c1_step1": s.C1_step1,
|
||||||
|
"c1_step2": s.C1_step2,
|
||||||
|
"c1_step3": s.C1_step3,
|
||||||
|
"c1_step4": s.C1_step4,
|
||||||
|
"c1_step5": s.C1_step5,
|
||||||
|
|
||||||
|
// // c2_step1 thru c2_step4 deal with TLS Handshake
|
||||||
|
"c2_step1": s.C2_step1,
|
||||||
|
"c2_step2": s.C2_step2,
|
||||||
|
"c2_step3": s.C2_step3,
|
||||||
|
"c2_step4": s.C2_step4,
|
||||||
|
|
||||||
|
// // c3_step1 thru c4_step3 deal with TLS Handshake and also prepare data
|
||||||
|
// // needed to send Client Finished
|
||||||
|
"c3_step1": s.C3_step1,
|
||||||
|
"c3_step2": s.C3_step2,
|
||||||
|
"c4_step1": s.C4_step1,
|
||||||
|
"c4_step2": s.C4_step2,
|
||||||
|
"c4_step3": s.C4_step3,
|
||||||
|
|
||||||
|
// // c5_pre1 thru c5_step3 check Server Finished
|
||||||
|
"c5_pre1": s.C5_pre1,
|
||||||
|
"c5_step1": s.C5_step1,
|
||||||
|
"c5_step2": s.C5_step2,
|
||||||
|
"c5_step3": s.C5_step3,
|
||||||
|
|
||||||
|
// // c6_step1 thru c6_step2 prepare encrypted counter blocks for the
|
||||||
|
// // client's request to the webserver
|
||||||
|
"c6_step1": s.C6_step1,
|
||||||
|
"c6_pre2": s.C6_pre2,
|
||||||
|
"c6_step2": s.C6_step2,
|
||||||
|
|
||||||
|
// // c7_step1 thru c7_step2 prepare the GCTR block needed to compute the MAC
|
||||||
|
// // for the client's request
|
||||||
|
"c7_step1": s.C7_step1,
|
||||||
|
"c7_step2": s.C7_step2,
|
||||||
|
|
||||||
|
// // steps ghash_step1 thru ghash_step3 compute the GHASH output needed to
|
||||||
|
// // compute the MAC for the client's request
|
||||||
|
"ghash_step1": s.Ghash_step1,
|
||||||
|
"ghash_step2": s.Ghash_step2,
|
||||||
|
"ghash_step3": s.Ghash_step3,
|
||||||
|
|
||||||
|
"commitHash": s.CommitHash,
|
||||||
|
}
|
||||||
sm.Lock()
|
sm.Lock()
|
||||||
defer sm.Unlock()
|
defer sm.Unlock()
|
||||||
sm.sessions[key] = &smItem{s, now, now}
|
sm.sessions[key] = &smItem{s, methodLookup, now, now}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +121,22 @@ func (sm *SessionManager) GetSession(key string) *session.Session {
|
|||||||
return val.session
|
return val.session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMethod looks up and return Session's method corresponding to the method
|
||||||
|
// string
|
||||||
|
func (sm *SessionManager) GetMethod(methodStr string, key string) method {
|
||||||
|
val, ok := sm.sessions[key]
|
||||||
|
if !ok {
|
||||||
|
log.Println("Error: the requested session does not exist ", key)
|
||||||
|
panic("Error: the requested session does not exist")
|
||||||
|
}
|
||||||
|
f, ok2 := val.methodLookup[methodStr]
|
||||||
|
if !ok2 {
|
||||||
|
log.Println("Error: the requested method does not exist ", key)
|
||||||
|
panic("Error: the requested method does not exist")
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
// removeSession removes the session and associated storage data
|
// removeSession removes the session and associated storage data
|
||||||
func (sm *SessionManager) removeSession(key string) {
|
func (sm *SessionManager) removeSession(key string) {
|
||||||
s, ok := sm.sessions[key]
|
s, ok := sm.sessions[key]
|
||||||
@@ -70,18 +148,13 @@ func (sm *SessionManager) removeSession(key string) {
|
|||||||
log.Println("Error while removing session ", key)
|
log.Println("Error while removing session ", key)
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
for _, f := range s.session.Tt {
|
for _, sliceOfFiles := range s.session.Tt {
|
||||||
err = os.Remove(f.Name())
|
for _, f := range sliceOfFiles {
|
||||||
if err != nil {
|
err = os.Remove(f.Name())
|
||||||
log.Println("Error while removing session ", key)
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println("Error while removing session ", key)
|
||||||
}
|
log.Println(err)
|
||||||
}
|
}
|
||||||
for _, f := range s.session.Dt {
|
|
||||||
err = os.Remove(f.Name())
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Error while removing session ", key)
|
|
||||||
log.Println(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sm.Lock()
|
sm.Lock()
|
||||||
|
|||||||
Reference in New Issue
Block a user