Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Darc ECDSA #2484

Open
wants to merge 11 commits into
base: darc_identity_test
Choose a base branch
from
197 changes: 105 additions & 92 deletions calypso/api_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package calypso

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/binary"
"go.dedis.ch/kyber/v3/util/key"
"testing"
"time"

"go.dedis.ch/kyber/v3/sign/schnorr"
"go.dedis.ch/kyber/v3/util/key"

"github.com/stretchr/testify/require"
"go.dedis.ch/cothority/v3"
Expand Down Expand Up @@ -167,7 +170,6 @@ func TestClient_Calypso(t *testing.T) {
_, err = calypsoClient.SpawnDarc(admin, adminCt, gDarc, *darc2, 10)
adminCt++
require.NoError(t, err)

//Create a secret key
key1 := []byte("secret key 1")
//Create a Write instance
Expand Down Expand Up @@ -223,122 +225,133 @@ func TestClient_Calypso(t *testing.T) {
// Tests the Calypso system with a simple write/read scenario.
// But it does the signing outside of the `Read` and `Write` methods for
// integration of the MPC signing by OneKey.
func TestClient_Calypso_Simple(t *testing.T) {
func BenchmarkClient_Calypso_Simple(b *testing.B) {
b.StopTimer()
l := onet.NewTCPTest(cothority.Suite)
_, roster, _ := l.GenTree(3, true)
defer l.CloseAll()

//create an example public key
random := rand.Reader
p, err := ecdsa.GenerateKey(elliptic.P256(), random)
require.NoError(b, err)

admin := darc.NewSignerEd25519(nil, nil)
adminCt := uint64(1)
user := darc.NewSignerEd25519(nil, nil)
user := darc.NewIdentityTSM(p.PublicKey)
// Initialise the genesis message and send it to the service.
// The admin has the privilege to spawn darcs
msg, err := byzcoin.DefaultGenesisMsg(byzcoin.CurrentVersion, roster,
[]string{"spawn:" + ContractLongTermSecretID},
admin.Identity())

msg.BlockInterval = 500 * time.Millisecond
require.NoError(t, err)
require.NoError(b, err)
// The darc inside it should be valid.
gDarc := msg.GenesisDarc
require.Nil(t, gDarc.Verify(true))
require.Nil(b, gDarc.Verify(true))
//Create Ledger
c, _, err := byzcoin.NewLedger(msg, false)
require.NoError(t, err)
require.NoError(b, err)
//Create a Calypso Client (Byzcoin + Onet)
calypsoClient := NewClient(c)

//Create the LTS
for _, who := range roster.List {
err := calypsoClient.Authorize(who, c.ID)
require.NoError(t, err)
require.NoError(b, err)
}
ltsReply, err := calypsoClient.CreateLTS(roster, gDarc.GetBaseID(), []darc.Signer{admin}, []uint64{adminCt})
adminCt++
require.NoError(t, err)
require.NoError(b, err)
//If no error, assign it
calypsoClient.ltsReply = ltsReply

//calypsoClient.ltsReply = ltsReply
b.StartTimer()
//Create a signer darc
userDarc := darc.NewDarc(darc.InitRules([]darc.Identity{user.Identity()},
[]darc.Identity{user.Identity()}), []byte("Provider1"))
// user can read and write.
// This can be changed to two different public keys.
err = userDarc.Rules.AddRule(darc.Action("spawn:"+ContractWriteID),
expression.InitOrExpr(user.Identity().String()))
require.NoError(t, err)
err = userDarc.Rules.AddRule(darc.Action("spawn:"+ContractReadID),
expression.InitOrExpr(user.Identity().String()))
require.NoError(t, err)
require.NotNil(t, userDarc)
_, err = calypsoClient.SpawnDarc(admin, adminCt, gDarc, *userDarc, 10)
adminCt++
require.NoError(t, err)

data := []byte("Some secret data - or the user's private key")
// Create a Write structure
write1, err := NewWriteData(cothority.Suite,
calypsoClient.ltsReply.InstanceID,
userDarc.GetBaseID(), calypsoClient.ltsReply.X, data)
require.NoError(t, err)

// Create a write-instance and send it to Byzcoin - here
// the instruction and the transaction is created manually,
// so that an external signer can sign the hash of the instruction.
wrInst, err := ContractWriteSpawnInstruction(write1, userDarc)
require.NoError(t, err)
wrInst.SignerCounter = []uint64{1}
wrInst.SignerIdentities = []darc.Identity{user.Identity()}
wrTx, err := calypsoClient.bcClient.CreateTransaction(*wrInst)
require.NoError(t, err)
digest := wrTx.Instructions.Hash()

// This signature can be replaced by an external signature.
signature, err := user.Sign(digest)
require.NoError(t, err)
wrTx.Instructions[0].Signatures = [][]byte{signature}

// Send the transaction to ByzCoin
_, err = calypsoClient.bcClient.AddTransactionAndWait(wrTx, 10)
require.NoError(t, err)
wrID := wrTx.Instructions[0].DeriveID("")
proofWr, err := calypsoClient.WaitProof(wrID, time.Second, nil)
require.NoError(t, err)

// Create a read-instance and send it to ByzCoin.
ephemeral := key.NewKeyPair(cothority.Suite)
readInst, err := ContractReadSpawnInstruction(wrID, ephemeral.Public)
require.NoError(t, err)
readInst.SignerCounter = []uint64{2}
readInst.SignerIdentities = []darc.Identity{user.Identity()}
readTx, err := calypsoClient.bcClient.CreateTransaction(*readInst)
require.NoError(t, err)
digest = readTx.Instructions.Hash()

// This signature can be replaced by an external signature
signature, err = user.Sign(digest)
require.NoError(t, err)
readTx.Instructions[0].Signatures = [][]byte{signature}
readID := readTx.Instructions[0].DeriveID("")

// Send the transaction to ByzCoin
_, err = calypsoClient.bcClient.AddTransactionAndWait(readTx, 10)
require.NoError(t, err)
proofRd, err := calypsoClient.WaitProof(readID, time.Second,
nil)
require.NoError(t, err)

// Make sure you can actually decrypt
dk, err := calypsoClient.DecryptKey(&DecryptKey{Read: *proofRd,
Write: *proofWr})
require.NoError(t, err)
require.True(t, dk.X.Equal(calypsoClient.ltsReply.X))
keyCopy, err := dk.RecoverKey(ephemeral.Private)
require.NoError(t, err)
var wrCopy Write
require.NoError(t, proofWr.VerifyAndDecode(cothority.Suite, ContractWriteID,
&wrCopy))
dataDecrypt, err := wrCopy.Decrypt(keyCopy)
require.NoError(t, err)
require.Equal(t, data, dataDecrypt)
for n := 0; n < b.N; n++ {

userDarc := darc.NewDarc(darc.InitRules([]darc.Identity{user},
[]darc.Identity{user}), []byte("Provider1"))
// user can read and write.
// This can be changed to two different public keys.
err = userDarc.Rules.AddRule(darc.Action("spawn:"+ContractWriteID),
expression.InitOrExpr(user.String()))
require.NoError(b, err)
err = userDarc.Rules.AddRule(darc.Action("spawn:"+ContractReadID),
expression.InitOrExpr(user.String()))
require.NoError(b, err)
require.NotNil(b, userDarc)
_, err = calypsoClient.SpawnDarc(admin, adminCt, gDarc, *userDarc, 10)
adminCt++
require.NoError(b, err)

data := []byte("johns_private_key")
// Create a Write structure
write1, err := NewWriteData(cothority.Suite,
ltsReply.InstanceID,
userDarc.GetBaseID(), ltsReply.X, data)
require.NoError(b, err)

// Create a write-instance and send it to Byzcoin - here
// the instruction and the transaction is created manually,
// so that an external signer can sign the hash of the instruction.
wrInst, err := ContractWriteSpawnInstruction(write1, userDarc)
require.NoError(b, err)
wrInst.SignerCounter = []uint64{1}
wrInst.SignerIdentities = []darc.Identity{user}
wrTx, err := calypsoClient.bcClient.CreateTransaction(*wrInst)
require.NoError(b, err)
digest := wrTx.Instructions.Hash()

// This signature can be replaced by an external signature.
//TODO add sepior signature of digest here
signature, err := ecdsa.SignASN1(random, p, digest)
require.NoError(b, err)
wrTx.Instructions[0].Signatures = [][]byte{signature}

// Send the transaction to ByzCoin
_, err = calypsoClient.bcClient.AddTransactionAndWait(wrTx, 10)
require.NoError(b, err)
wrID := wrTx.Instructions[0].DeriveID("")
proofWr, err := calypsoClient.WaitProof(wrID, time.Second, nil)
require.NoError(b, err)

// Create a read-instance and send it to ByzCoin.
ephemeral := key.NewKeyPair(cothority.Suite)
readInst, err := ContractReadSpawnInstruction(wrID, ephemeral.Public)
require.NoError(b, err)
readInst.SignerCounter = []uint64{2}
readInst.SignerIdentities = []darc.Identity{user}
readTx, err := calypsoClient.bcClient.CreateTransaction(*readInst)
require.NoError(b, err)
digest = readTx.Instructions.Hash()

// This signature can be replaced by an external signature
// TODO add signature on digest from MPC nodes
signature, err = ecdsa.SignASN1(random, p, digest)
require.NoError(b, err)
readTx.Instructions[0].Signatures = [][]byte{signature}
readID := readTx.Instructions[0].DeriveID("")

// Send the transaction to ByzCoin
_, err = calypsoClient.bcClient.AddTransactionAndWait(readTx, 10)
require.NoError(b, err)
proofRd, err := calypsoClient.WaitProof(readID, time.Second,
nil)
require.NoError(b, err)

// Make sure you can actually decrypt
dk, err := calypsoClient.DecryptKey(&DecryptKey{Read: *proofRd,
Write: *proofWr})
require.NoError(b, err)
require.True(b, dk.X.Equal(ltsReply.X))
keyCopy, err := dk.RecoverKey(ephemeral.Private)
require.NoError(b, err)
var wrCopy Write
require.NoError(b, proofWr.VerifyAndDecode(cothority.Suite, ContractWriteID,
&wrCopy))
dataDecrypt, err := wrCopy.Decrypt(keyCopy)
require.NoError(b, err)
require.Equal(b, data, dataDecrypt)
}
}
2 changes: 1 addition & 1 deletion calypso/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package calypso

import (
"fmt"
"go.dedis.ch/kyber/v3"
"strings"

"go.dedis.ch/cothority/v3"
"go.dedis.ch/cothority/v3/byzcoin"
"go.dedis.ch/cothority/v3/darc"
"go.dedis.ch/kyber/v3"
"go.dedis.ch/onet/v3"
"go.dedis.ch/onet/v3/log"
"go.dedis.ch/onet/v3/network"
Expand Down
3 changes: 2 additions & 1 deletion calypso/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"crypto/rand"
"crypto/sha256"
"fmt"
"io"

"go.dedis.ch/cothority/v3"
"go.dedis.ch/cothority/v3/byzcoin"
"go.dedis.ch/cothority/v3/darc"
Expand All @@ -15,7 +17,6 @@ import (
"go.dedis.ch/kyber/v3/xof/keccak"
"go.dedis.ch/onet/v3/network"
"golang.org/x/xerrors"
"io"
)

func init() {
Expand Down
Loading