From 16f0f5b588032b5aa8f1362f2d32b634c74afec4 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Wed, 30 Jan 2019 20:30:11 +0000 Subject: [PATCH] csidh: test vectors --- csidh/Makefile | 5 +- csidh/cmd/torturer/main.go | 19 +-- csidh/cmd/vector-creator/main.go | 182 ++++++++++++++++++++++++ csidh/ref/csidh/csidh.c | 14 +- csidh/ref/csidh/csidh.h | 3 +- csidh/ref/go-wrapper/wrapper.go | 6 + csidh/ref/test/main.c | 22 ++- csidh/vendor/github.com/henrydcase/nobs | 1 + 8 files changed, 226 insertions(+), 26 deletions(-) create mode 100644 csidh/cmd/vector-creator/main.go create mode 120000 csidh/vendor/github.com/henrydcase/nobs diff --git a/csidh/Makefile b/csidh/Makefile index e9e8e86..19e2057 100644 --- a/csidh/Makefile +++ b/csidh/Makefile @@ -33,7 +33,7 @@ $(BUILD_DIR)/%.o: %.s case $@ in */*) f=$@; mkdir -p $${f%/*} ;; esac $(CC) -c -o $@ $< $(CFLAGS) -all: libcsidh torturer +all: libcsidh torturer vector-creator libcsidh: $(CODE_OBJ) mkdir -p $(PRJ_DIR)/$(BIN_DIR) @@ -48,6 +48,9 @@ clean: torturer: $(BUILD_DIR)/.ok GOPATH=$(GOPATH_LOCAL) $(GO) install $(IMPORT_PATH)/cmd/$@ +vector-creator: $(BUILD_DIR)/.ok + GOPATH=$(GOPATH_LOCAL) $(GO) install $(IMPORT_PATH)/cmd/$@ + $(BUILD_DIR)/.ok: mkdir -p "$(dir $(BUILD_DIR)/src/$(IMPORT_PATH))" ln -s `pwd` "$(BUILD_DIR)/src/$(IMPORT_PATH)" diff --git a/csidh/cmd/torturer/main.go b/csidh/cmd/torturer/main.go index bbf345b..783fb85 100644 --- a/csidh/cmd/torturer/main.go +++ b/csidh/cmd/torturer/main.go @@ -10,16 +10,10 @@ import ( "github.com/henrydcase/nobs/dh/csidh" ) -const ( - PrvSz = 37 // PrvSz is a size of private key in bytes. - PubSz = 64 // PubSz is a size of public key in bytes. - SsSz = 64 // SsSz is a size of shared secret in bytes. -) - func TestSS() { var r wrapper.Ref - var ssRef [SsSz]byte - var ss [SsSz]byte + var ssRef [csidh.SharedSecretSize]byte + var ss [csidh.SharedSecretSize]byte // Go types prA := r.KeygenPrv() @@ -48,8 +42,8 @@ func TestSS() { func TestKeyImport() { var r wrapper.Ref - var ssRef [SsSz]byte - var ss [SsSz]byte + var ssRef [csidh.SharedSecretSize]byte + var ss [csidh.SharedSecretSize]byte // Go types prA := r.KeygenPrv() @@ -75,8 +69,8 @@ func TestKeyImport() { func TestKeyGeneration() { var r wrapper.Ref - var ssRef [SsSz]byte - var ss [SsSz]byte + var ssRef [csidh.SharedSecretSize]byte + var ss [csidh.SharedSecretSize]byte // Go types prA := csidh.NewPrivateKey() @@ -110,6 +104,7 @@ func main() { fmt.Printf("| TestName |Go | C |\n") fmt.Printf("|------------------|----------|----------|\n") + // OZAPTF: make configurable // for i:=0; i<100; i++ { for { TestSS() diff --git a/csidh/cmd/vector-creator/main.go b/csidh/cmd/vector-creator/main.go new file mode 100644 index 0000000..e7130b2 --- /dev/null +++ b/csidh/cmd/vector-creator/main.go @@ -0,0 +1,182 @@ +package main + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "io/ioutil" + + "github.com/henrydcase/nobs/dh/csidh" + "github.com/henrydcase/sidh_torture/csidh/ref/go-wrapper" +) + +// Possible values for "Status" +const ( + Valid = iota // Indicates that shared secret must be agreed correctly + InvalidSharedSecret // Calculated shared secret must be different than test vector + InvalidPublicKey1 // Public key 1 generated from private key must be different than test vector + InvalidPublicKey2 // Public key 2 must fail validation +) + +var StatusValues = map[int]string{ + Valid: "valid", + InvalidSharedSecret: "invalid_shared_secret", + InvalidPublicKey1: "invalid_public_key1", + InvalidPublicKey2: "invalid_public_key2", +} + +type TestVector struct { + Id int `json:"Id"` + Pk1 string `json:"Pk1"` + Pr1 string `json:"Pr1"` + Pk2 string `json:"Pk2"` + Ss string `json:"Ss"` + Status string `json:"status"` +} + +type TestVectors struct { + Vectors []TestVector `json:"Vectors"` +} + +// R is a reference to C implementation. +var R wrapper.Ref + +// createValid creates 'num' of TestVector's. Each vector contains +// valid data. +func createValid(num int) TestVector { + var tv TestVector + var ss [csidh.SharedSecretSize]byte + var pk [csidh.PublicKeySize]byte + var pr [csidh.PrivateKeySize]byte + + prA := R.KeygenPrv() + pkA := R.KeygenPub(&prA) + prB := R.KeygenPrv() + pkB := R.KeygenPub(&prB) + + R.Derive(ss[:], &pkB, &prA) + + tv.Id = num + tv.Status = StatusValues[Valid] + + tv.Ss = hex.EncodeToString(ss[:]) + + prA.Export(pr[:]) + tv.Pr1 = hex.EncodeToString(pr[:]) + + pkA.Export(pk[:]) + tv.Pk1 = hex.EncodeToString(pk[:]) + + for i, _ := range pk { + pk[i] = 0 + } + + pkB.Export(pk[:]) + tv.Pk2 = hex.EncodeToString(pk[:]) + + return tv +} + +func createNegativeSharedSecret(vectors *TestVectors) { + n := len(vectors.Vectors) + tv := createValid(n) + ss, err := hex.DecodeString(tv.Ss) + if err != nil { + panic("Can't decode shared secret") + } + + for i:=0; iA.x.c[j] |= tmp << (8*k); } - if (validate(pub)) { - printf("DUPA"); - } - // TODO: should validate it - + return validate(pub); } void export_private(uint8_t *out, const private_key *prv) { @@ -281,3 +277,9 @@ void derive(uint8_t result[64], const uint8_t public[64], const uint8_t private[ csidh(&ss, &pub, &prv); export_public(&result[0], &ss); } + +// returns 1 if valid 0 otherwise +int is_valid(const uint8_t *a) { + public_key pub = {0}; + return import_public(&pub, a); +} diff --git a/csidh/ref/csidh/csidh.h b/csidh/ref/csidh/csidh.h index 1a2c2ad..d84017b 100644 --- a/csidh/ref/csidh/csidh.h +++ b/csidh/ref/csidh/csidh.h @@ -28,7 +28,8 @@ void keygen_pub(uint8_t public[64], const uint8_t private[37]); void derive(uint8_t result[64], const uint8_t public[64], const uint8_t private_key[37]); void export_public(uint8_t *out, const public_key *pub); -void import_public(public_key *pub, const uint8_t *out); +bool import_public(public_key *pub, const uint8_t *out); void export_private(uint8_t *out, const private_key *prv); void import_private(private_key *prv, const uint8_t *out); +int is_valid(const uint8_t *a); #endif diff --git a/csidh/ref/go-wrapper/wrapper.go b/csidh/ref/go-wrapper/wrapper.go index fda94f8..ee92d0d 100644 --- a/csidh/ref/go-wrapper/wrapper.go +++ b/csidh/ref/go-wrapper/wrapper.go @@ -72,3 +72,9 @@ func (c Ref) Derive(ss []byte, pub *csidh.PublicKey, prv *csidh.PrivateKey) { C.derive(&ss_c_buf[0], &pub_c_buf[0], &prv_c_buf[0]) copy(ss, C.GoBytes(unsafe.Pointer(&ss_c_buf[0]), C.int(len(ss_c_buf)))) } + +func (c Ref) Validate(a []byte) bool { + var pub_c_buf [PubSz]C.uchar + c.toBytes(pub_c_buf[:], a[:]) + return C.is_valid(&pub_c_buf[0]) != 0 +} diff --git a/csidh/ref/test/main.c b/csidh/ref/test/main.c index 0a5f624..d49bf83 100644 --- a/csidh/ref/test/main.c +++ b/csidh/ref/test/main.c @@ -87,18 +87,28 @@ static bool testImportExport() { return fp_cmp(&pub1.A, &pub2.A); } +// special cases: +// * diag 0 +// * only 0 static void validator() { uint8_t rnd[64] = {0}; - public_key pub = {0}; - for (size_t i=0; i<100; i++) { - randombytes(rnd, sizeof(rnd)); - printf("%llu=", i); - import_public(&pub, rnd); - printf("\n"); + private_key prA = {0}; + public_key pubA={0}; + + csidh_private(&prA); + csidh(&pubA, &base, &prA); + export_public(rnd, &pubA); + + for (size_t i=0; i<64; i++) { + uint8_t r[64] = {0}; + memcpy(r, rnd, sizeof(r)); + r[i]=0x01; + printf("%u -> ", import_public(&pubA, r)); } } int main() { +// validator(); return !( testImportExport() && testLoopRef()); diff --git a/csidh/vendor/github.com/henrydcase/nobs b/csidh/vendor/github.com/henrydcase/nobs new file mode 120000 index 0000000..4487b00 --- /dev/null +++ b/csidh/vendor/github.com/henrydcase/nobs @@ -0,0 +1 @@ +/home/hdc/repos/nobs/ \ No newline at end of file