Skip to content

Commit

Permalink
Decryption of data now takes ciphertexts to use and find k from
Browse files Browse the repository at this point in the history
Previously decryption of entry/assignment data would take locCiphertexts
and dlocCiphertexts (respectively), derive k, and decrypt the data.
After doing some more testing, it seems that if we attempt to find a k
value (via interpolation) on a set of points P, where P contains > 1
points with the same x-value (i.e. same user hash), the method fails to
find k. The method even fails if you pass another point on the same line
(but different x-value).

When do we run into this case in the protocol? We run into this when the
same user submits two distinct entries of the same perp. Even if there
is a match on the same perp with a different user, the function fails to
find k as described above.

Clearly, the root of the problem is interpolation. I believe a simpler
fix than this commit would be to follow the interpolation/decryption
algorithm mentioned in the paper and try two shares at a time and
decrypt as many ciphertexts as possible. That change would require a
slight refactor/redesign of how loc.go is setup (order of operations,
etc.) However, for time constraints, I'm choosing to delay doing this.
See issue #5 for the tracking of this.

For now, this commit solves the problem explained above by utilizing an
earlier change done in matching.go. matching.go now returns a filtered
list of matched tuples with unique user IDs. We now pass this list into
loc.go and use this list to find k, while the greater superset (includes
multiple entries on same perp from same user) is used for decryption of
entry/assignment data. The current implemenation is slightly bad because
we actually decrypt ciphertexts more than once--we do it once for the
designated k-ciphertexts and another for the entire universe. We can fix
this by doing a union first and marking which ciphertexts are designated
for deriving k; however, at this point we might as well just solve #5
and do a better design of loc.go. Again, for time constraint reasons we
are keeping this quick solution for now.

This commit fixes the problem above because the filtered list to find k
only contains ciphertexts from distinct users.
  • Loading branch information
ymarcus93 committed Apr 11, 2020
1 parent 9666173 commit 1224cb2
Showing 1 changed file with 48 additions and 20 deletions.
68 changes: 48 additions & 20 deletions protocol/loc.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,49 @@ import (
"github.com/ymarcus93/gallisto/types"
)

func decryptDLOCCiphertextsAndValidate(dlocCiphertexts [][]byte, dlocPrivateKey *rsa.PrivateKey) ([]types.LOCData, error) {
// Decrypt dloc ciphertexts
dlocData, err := decryptLOCCiphertexts(dlocCiphertexts, dlocPrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to decrypt DLOC ciphertexts: %v", err)
}

// Validate
if !validateLOCData(dlocData, types.Director) {
return nil, fmt.Errorf("decrypted DLOC ciphertexts but found non-Director data")
}

return dlocData, nil
}

// DecryptAssignmentData decrypts a list of encrypted assignment data. It does
// this by finding a common k value amongst matched dlocData and attempting to
// decrypt encrypted assignment keys with this k. It then uses the decrypted
// assignment keys to decrypt all assignment data.
func DecryptAssignmentData(dlocCiphertexts [][]byte, encryptedAssignmentData []encryption.GCMCiphertext, dlocPrivateKey *rsa.PrivateKey) ([]types.AssignmentData, error) {
func DecryptAssignmentData(dlocCiphertextsToFindKFrom [][]byte, dlocCiphertexts [][]byte, encryptedAssignmentData []encryption.GCMCiphertext, dlocPrivateKey *rsa.PrivateKey) ([]types.AssignmentData, error) {
if len(dlocCiphertexts) != len(encryptedAssignmentData) {
return nil, fmt.Errorf("mismatch length between dlocCiphertexts and encrypted assignment data")
}

// Decrypt dloc ciphertexts
dlocData, err := decryptLOCCiphertexts(dlocCiphertexts, dlocPrivateKey)
dlocDataToDecrypt, err := decryptDLOCCiphertextsAndValidate(dlocCiphertexts, dlocPrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to decrypt DLOC ciphertexts: %v", err)
return nil, fmt.Errorf("failed to decrypt dlocCiphertexts: %v", err)
}

// Validate
if !validateLOCData(dlocData, types.Director) {
return nil, fmt.Errorf("decrypted DLOC ciphertexts but found non-Director data")
dlocDataToFindKFrom, err := decryptDLOCCiphertextsAndValidate(dlocCiphertextsToFindKFrom, dlocPrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to decrypt dlocCiphertextsToFindKFrom: %v", err)
}

// Find k
kAsBytes, err := findKValueFromLOCData(dlocData)
kAsBytes, err := findKValueFromLOCData(dlocDataToFindKFrom)
if err != nil {
return nil, fmt.Errorf("failed to find k value from DLOC ciphertexts: %v", err)
}

// Decrypt assignment data
assignmentDatas := make([]types.AssignmentData, len(dlocData))
for i, d := range dlocData {
assignmentDatas := make([]types.AssignmentData, len(dlocDataToDecrypt))
for i, d := range dlocDataToDecrypt {
k_a, err := encryption.DecryptAES(kAsBytes, d.EncryptedKey())
if err != nil {
return nil, fmt.Errorf("failed to decrypt EncryptedAssignmentDataKey at index %v: %v", i, err)
Expand All @@ -57,35 +71,49 @@ func DecryptAssignmentData(dlocCiphertexts [][]byte, encryptedAssignmentData []e
return assignmentDatas, nil
}

func decryptLOCCiphertextsAndValidate(locCiphertexts [][]byte, locPrivateKey *rsa.PrivateKey) ([]types.LOCData, error) {
// Decrypt loc ciphertexts
locData, err := decryptLOCCiphertexts(locCiphertexts, locPrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to decrypt LOC ciphertexts: %v", err)
}

// Validate
if !validateLOCData(locData, types.Counselor) {
return nil, fmt.Errorf("decrypted LOC ciphertexts but found non-Counselor data")
}

return locData, nil
}

// DecryptEntryData decrypts a list of encrypted entry data. It does this by
// finding a common k value amongst matched locData and attempting to decrypt
// encrypted entry keys with this k. It then uses the decrypted entry keys to
// decrypt all entry data.
func DecryptEntryData(locCiphertexts [][]byte, encryptedEntryData []encryption.GCMCiphertext, locPrivateKey *rsa.PrivateKey) ([]types.EntryData, error) {
func DecryptEntryData(locCiphertextsToFindKFrom [][]byte, locCiphertexts [][]byte, encryptedEntryData []encryption.GCMCiphertext, locPrivateKey *rsa.PrivateKey) ([]types.EntryData, error) {
if len(locCiphertexts) != len(encryptedEntryData) {
return nil, fmt.Errorf("mismatch length between locCiphertexts and encrypted entry data")
}

// Decrypt loc ciphertexts
locData, err := decryptLOCCiphertexts(locCiphertexts, locPrivateKey)
locDataToDecrypt, err := decryptLOCCiphertextsAndValidate(locCiphertexts, locPrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to decrypt LOC ciphertexts: %v", err)
return nil, fmt.Errorf("failed to decrypt locCiphertexts: %v", err)
}

// Validate
if !validateLOCData(locData, types.Counselor) {
return nil, fmt.Errorf("decrypted LOC ciphertexts but found non-Counselor data")
locDataToFindKFrom, err := decryptLOCCiphertextsAndValidate(locCiphertextsToFindKFrom, locPrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to decrypt locCiphertextsToFindKFrom: %v", err)
}

// Find k
kAsBytes, err := findKValueFromLOCData(locData)
kAsBytes, err := findKValueFromLOCData(locDataToFindKFrom)
if err != nil {
return nil, fmt.Errorf("failed to find k value from LOC ciphertexts: %v", err)
}

// Decrypt entry data
entryDatas := make([]types.EntryData, len(locData))
for i, d := range locData {
entryDatas := make([]types.EntryData, len(locDataToDecrypt))
for i, d := range locDataToDecrypt {
k_e, err := encryption.DecryptAES(kAsBytes, d.EncryptedKey())
if err != nil {
return nil, fmt.Errorf("failed to decrypt EncryptedEntryDataKey at index %v: %v", i, err)
Expand Down

0 comments on commit 1224cb2

Please sign in to comment.