Expose token.T in json + fix issue with new auth protocol #55
|
@ -10,7 +10,6 @@ import (
|
||||||
"git.openprivacy.ca/openprivacy/connectivity"
|
"git.openprivacy.ca/openprivacy/connectivity"
|
||||||
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -78,7 +77,7 @@ func TestTokenBoardApp(t *testing.T) {
|
||||||
builder.WithSocksPort(9059).WithControlPort(9060).WithHashedPassword("tapir-integration-test").Build("./tor/torrc")
|
builder.WithSocksPort(9059).WithControlPort(9060).WithHashedPassword("tapir-integration-test").Build("./tor/torrc")
|
||||||
torDataDir := ""
|
torDataDir := ""
|
||||||
var err error
|
var err error
|
||||||
if torDataDir, err = ioutil.TempDir("./tor/", "data-dir-"); err != nil {
|
if torDataDir, err = os.MkdirTemp("./tor/", "data-dir-"); err != nil {
|
||||||
t.Fatalf("could not create data dir")
|
t.Fatalf("could not create data dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ type State struct {
|
||||||
Messages []Message
|
Messages []Message
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
const (
|
const (
|
||||||
auditableDataStoreProtocol = "auditable-data-store"
|
auditableDataStoreProtocol = "auditable-data-store"
|
||||||
newMessage = "new-message"
|
newMessage = "new-message"
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
// Transcript provides a consistent transcript primitive for our protocols
|
// Transcript provides a consistent transcript primitive for our protocols
|
||||||
//
|
//
|
||||||
// We have the following goals:
|
// We have the following goals:
|
||||||
// - Allow sequential proofs over a common transcript (ensuring a single proof cannot be extracted standalone)
|
// - Allow sequential proofs over a common transcript (ensuring a single proof cannot be extracted standalone)
|
||||||
// - be able to produce a human-readable transcript for auditing.
|
// - be able to produce a human-readable transcript for auditing.
|
||||||
//
|
//
|
||||||
// The design of this API was inspired by Merlin: https://docs.rs/crate/merlin/
|
// The design of this API was inspired by Merlin: https://docs.rs/crate/merlin/
|
||||||
type Transcript struct {
|
type Transcript struct {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// DLEQProof encapsulates a Chaum-Pedersen DLEQ Proof
|
// DLEQProof encapsulates a Chaum-Pedersen DLEQ Proof
|
||||||
//gut In Ernest F. Brickell, editor,CRYPTO’92,volume 740 ofLNCS, pages 89–105. Springer, Heidelberg,August 1993
|
// gut In Ernest F. Brickell, editor,CRYPTO’92,volume 740 ofLNCS, pages 89–105. Springer, Heidelberg,August 1993
|
||||||
type DLEQProof struct {
|
type DLEQProof struct {
|
||||||
C *ristretto.Scalar
|
C *ristretto.Scalar
|
||||||
S *ristretto.Scalar
|
S *ristretto.Scalar
|
||||||
|
@ -16,10 +16,11 @@ type DLEQProof struct {
|
||||||
// DiscreteLogEquivalenceProof constructs a valid DLEQProof for the given parameters and transcript
|
// DiscreteLogEquivalenceProof constructs a valid DLEQProof for the given parameters and transcript
|
||||||
// Given Y = kX & Q = kP
|
// Given Y = kX & Q = kP
|
||||||
// Peggy: t := choose randomly from Zq
|
// Peggy: t := choose randomly from Zq
|
||||||
// A := tX
|
//
|
||||||
// B := tP
|
// A := tX
|
||||||
// c := H(transcript(X,Y,P,Q,A,B))
|
// B := tP
|
||||||
// s := (t + ck) mod q
|
// c := H(transcript(X,Y,P,Q,A,B))
|
||||||
|
// s := (t + ck) mod q
|
||||||
//
|
//
|
||||||
// Sends c,s to Vicky
|
// Sends c,s to Vicky
|
||||||
func DiscreteLogEquivalenceProof(k *ristretto.Scalar, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) DLEQProof {
|
func DiscreteLogEquivalenceProof(k *ristretto.Scalar, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) DLEQProof {
|
||||||
|
@ -47,12 +48,14 @@ func DiscreteLogEquivalenceProof(k *ristretto.Scalar, X *ristretto.Element, Y *r
|
||||||
// VerifyDiscreteLogEquivalenceProof verifies the DLEQ for the given parameters and transcript
|
// VerifyDiscreteLogEquivalenceProof verifies the DLEQ for the given parameters and transcript
|
||||||
// Given Y = kX & Q = kP and Proof = (c,s)
|
// Given Y = kX & Q = kP and Proof = (c,s)
|
||||||
// Vicky: X' := sX
|
// Vicky: X' := sX
|
||||||
// Y' := cY
|
//
|
||||||
// P' := sP
|
// Y' := cY
|
||||||
// Q' := cQ
|
// P' := sP
|
||||||
// A' = X'+Y' == sX + cY ?= sG + ckG == (s+ck)X == tX == A
|
// Q' := cQ
|
||||||
// B' = P'+Q' == sP + cQ ?= sP + ckP == (s+ck)P == tP == B
|
// A' = X'+Y' == sX + cY ?= sG + ckG == (s+ck)X == tX == A
|
||||||
// c' := H(transcript(X,Y,P,Q,A',B'))
|
// B' = P'+Q' == sP + cQ ?= sP + ckP == (s+ck)P == tP == B
|
||||||
|
// c' := H(transcript(X,Y,P,Q,A',B'))
|
||||||
|
//
|
||||||
// Tests c ?= c
|
// Tests c ?= c
|
||||||
func VerifyDiscreteLogEquivalenceProof(dleq DLEQProof, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) bool {
|
func VerifyDiscreteLogEquivalenceProof(dleq DLEQProof, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) bool {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package privacypass
|
||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.openprivacy.ca/cwtch.im/tapir/primitives/core"
|
"git.openprivacy.ca/cwtch.im/tapir/primitives/core"
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
|
@ -122,3 +123,16 @@ func UnblindSignedTokenBatch(tokens []*Token, blindedTokens []BlindedToken, sign
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON - in order to store tokens in a serialized form we need to expose the private, unexported value
|
||||||
|
// `t`. Note that `r` is not needed to spend the token, and as such we effectively destroy it when we serialize.
|
||||||
|
// Ideally, go would let us do this with an annotation, alas.
|
||||||
|
func (t Token) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(struct {
|
||||||
|
T []byte `json:"t"`
|
||||||
|
W *ristretto.Element
|
||||||
|
}{
|
||||||
|
T: t.t,
|
||||||
|
W: t.W,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
"golang.org/x/crypto/ed25519"
|
"golang.org/x/crypto/ed25519"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
@ -69,7 +68,7 @@ func TestTapir(t *testing.T) {
|
||||||
|
|
||||||
torDataDir := ""
|
torDataDir := ""
|
||||||
var err error
|
var err error
|
||||||
if torDataDir, err = ioutil.TempDir("./tor/", "data-dir-"); err != nil {
|
if torDataDir, err = os.MkdirTemp("./tor/", "data-dir-"); err != nil {
|
||||||
t.Fatalf("could not create data dir")
|
t.Fatalf("could not create data dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +142,10 @@ func connectclient(t *testing.T, client tapir.Service, key ed25519.PublicKey, gr
|
||||||
conn, _ := client.GetConnection(torProvider.GetTorV3Hostname(key))
|
conn, _ := client.GetConnection(torProvider.GetTorV3Hostname(key))
|
||||||
log.Debugf("Client has Auth: %v", conn.HasCapability(applications.AuthCapability))
|
log.Debugf("Client has Auth: %v", conn.HasCapability(applications.AuthCapability))
|
||||||
|
|
||||||
|
if conn.HasCapability(applications.AuthCapability) == false {
|
||||||
|
t.Errorf("tapir auth failed")
|
||||||
|
}
|
||||||
|
|
||||||
// attempt to send a message that is too long
|
// attempt to send a message that is too long
|
||||||
var long [8195]byte
|
var long [8195]byte
|
||||||
err := conn.Send(long[:])
|
err := conn.Send(long[:])
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
"golang.org/x/crypto/ed25519"
|
"golang.org/x/crypto/ed25519"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -30,7 +29,7 @@ func TestTapirMaliciousRemote(t *testing.T) {
|
||||||
|
|
||||||
torDataDir := ""
|
torDataDir := ""
|
||||||
var err error
|
var err error
|
||||||
if torDataDir, err = ioutil.TempDir("./tor/", "data-dir-"); err != nil {
|
if torDataDir, err = os.MkdirTemp("./tor/", "data-dir-"); err != nil {
|
||||||
t.Fatalf("could not create data dir")
|
t.Fatalf("could not create data dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,16 @@ func EDH(privateKey ed25519.PrivateKey, remotePublicKey ed25519.PublicKey) ([]by
|
||||||
var curve25519priv [32]byte
|
var curve25519priv [32]byte
|
||||||
|
|
||||||
PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes)
|
PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes)
|
||||||
curve25519pub, err := ed25519PublicKeyToCurve25519(remotePublicKey)
|
remoteCurve25519pub, err := ed25519PublicKeyToCurve25519New(remotePublicKey)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
return nil, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
secret, err := curve25519.X25519(curve25519priv[:], curve25519pub[:])
|
secret, err := curve25519.X25519(curve25519priv[:], remoteCurve25519pub[:])
|
||||||
return secret, err
|
return secret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// reproduced from https://github.com/FiloSottile/age/blob/main/agessh/agessh.go#L190
|
// reproduced from https://github.com/FiloSottile/age/blob/main/agessh/agessh.go#L190
|
||||||
func ed25519PublicKeyToCurve25519(pk ed25519.PublicKey) ([]byte, error) {
|
func ed25519PublicKeyToCurve25519New(pk ed25519.PublicKey) ([]byte, error) {
|
||||||
// See https://blog.filippo.io/using-ed25519-keys-for-encryption and
|
// See https://blog.filippo.io/using-ed25519-keys-for-encryption and
|
||||||
// https://pkg.go.dev/filippo.io/edwards25519#Point.BytesMontgomery.
|
// https://pkg.go.dev/filippo.io/edwards25519#Point.BytesMontgomery.
|
||||||
p, err := new(edwards25519.Point).SetBytes(pk)
|
p, err := new(edwards25519.Point).SetBytes(pk)
|
||||||
|
|
Loading…
Reference in New Issue