diff --git a/csidh/Makefile b/csidh/Makefile index 4554561..e9e8e86 100644 --- a/csidh/Makefile +++ b/csidh/Makefile @@ -1,11 +1,18 @@ objify = $(patsubst %.c,$(BUILD_DIR)/%.$2,$(patsubst %.s,$(BUILD_DIR)/%.$2,$1)) +BUILD_DIR=build +BIN_DIR=bin +MK_FILE_PATH = $(lastword $(MAKEFILE_LIST)) +PRJ_DIR = $(abspath $(dir $(MK_FILE_PATH))) +GOPATH_LOCAL = $(PRJ_DIR)/$(BUILD_DIR)/ + CFLAGS=-Wall -Wextra -Wpedantic -O3 -funroll-loops LDFLAGS= -BUILD_DIR=build AR=ar rcs RANLIB=ranlib -GOPATH=/home/hdc/repos/nobs/build +GOPATH=$(BUILD_DIR) +GO=go +IMPORT_PATH:=github.com/henrydcase/sidh_torture/csidh CODE_SRC_C = \ ref/csidh/rng.c \ @@ -26,14 +33,24 @@ $(BUILD_DIR)/%.o: %.s case $@ in */*) f=$@; mkdir -p $${f%/*} ;; esac $(CC) -c -o $@ $< $(CFLAGS) -all: $(CODE_OBJ) - $(AR) $(BUILD_DIR)/libcsidh.a $^ - $(RANLIB) $(BUILD_DIR)/libcsidh.a - $(CC) -o $(BUILD_DIR)/test_ref test/main.c -L$(BUILD_DIR) -lcsidh +all: libcsidh torturer -run: all - $(BUILD_DIR)/test_ref - GOPATH=$(GOPATH) go run test/torturer.go +libcsidh: $(CODE_OBJ) + mkdir -p $(PRJ_DIR)/$(BIN_DIR) + $(AR) $(BIN_DIR)/libcsidh.a $^ + $(RANLIB) $(BIN_DIR)/libcsidh.a + $(CC) -o $(BIN_DIR)/test_ref ref/test/main.c -L$(BIN_DIR) -lcsidh clean: rm -rf build + rm -rf bin + +torturer: $(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)" + mkdir -p bin + ln -s `pwd`/bin $(BUILD_DIR)/bin + touch $@ diff --git a/csidh/cmd/torturer/main.go b/csidh/cmd/torturer/main.go new file mode 100644 index 0000000..bbf345b --- /dev/null +++ b/csidh/cmd/torturer/main.go @@ -0,0 +1,119 @@ +package main + +import ( + "bytes" + "fmt" + "time" + "crypto/rand" + + "github.com/henrydcase/sidh_torture/csidh/ref/go-wrapper" + "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 + + // Go types + prA := r.KeygenPrv() + pkA := r.KeygenPub(&prA) + prB := csidh.NewPrivateKey() + pkB := csidh.NewPublicKey() + + prB.Generate(rand.Reader) + pkB.Generate(&prB) + + s1 := time.Now() + // Generate with Go + pkB.DeriveSecret(ss[:], &pkA, &prB) + s2 := time.Since(s1) + + // Generate with C + s1 = time.Now() + r.Derive(ssRef[:], &pkB, &prA) + s3 := time.Since(s1) + fmt.Printf("|TestSharedSecret | %.8s | %.8s |\n", s2, s3) + + if !bytes.Equal(ss[:], ssRef[:]) { + panic("TestSS") + } +} + +func TestKeyImport() { + var r wrapper.Ref + var ssRef [SsSz]byte + var ss [SsSz]byte + + // Go types + prA := r.KeygenPrv() + pkA := r.KeygenPub(&prA) + prB := r.KeygenPrv() + pkB := r.KeygenPub(&prB) + + s1 := time.Now() + // Generate with Go + pkB.DeriveSecret(ss[:], &pkA, &prB) + s2 := time.Since(s1) + + // Generate with C + s1 = time.Now() + r.Derive(ssRef[:], &pkB, &prA) + s3 := time.Since(s1) + fmt.Printf("|TestKeyImport | %.8s | %.8s |\n", s2, s3) + + if !bytes.Equal(ss[:], ssRef[:]) { + panic("TestKeyImport") + } +} + +func TestKeyGeneration() { + var r wrapper.Ref + var ssRef [SsSz]byte + var ss [SsSz]byte + + // Go types + prA := csidh.NewPrivateKey() + pkA := csidh.NewPublicKey() + prB := csidh.NewPrivateKey() + pkB := csidh.NewPublicKey() + + + prA.Generate(rand.Reader) + pkA.Generate(&prA) + prB.Generate(rand.Reader) + pkB.Generate(&prB) + + s1 := time.Now() + // Generate with Go + r.Derive(ss[:], &pkA, &prB) + s2 := time.Since(s1) + + // Generate with C + s1 = time.Now() + r.Derive(ssRef[:], &pkB, &prA) + s3 := time.Since(s1) + fmt.Printf("|TestKeyGeneration | %.8s | %.8s |\n", s2, s3) + + if !bytes.Equal(ss[:], ssRef[:]) { + panic("TestKeyGeneration") + } +} + +func main() { + fmt.Printf("| TestName |Go | C |\n") + fmt.Printf("|------------------|----------|----------|\n") + + // for i:=0; i<100; i++ { + for { + TestSS() + TestKeyImport() + TestKeyGeneration() + } +} diff --git a/csidh/ref/csidh/csidh.c b/csidh/ref/csidh/csidh.c index 7e3e19c..1adf6eb 100644 --- a/csidh/ref/csidh/csidh.c +++ b/csidh/ref/csidh/csidh.c @@ -237,6 +237,11 @@ void import_public(public_key *pub, const uint8_t *out) { uint64_t tmp = out[i]; pub->A.x.c[j] |= tmp << (8*k); } + if (validate(pub)) { + printf("DUPA"); + } + // TODO: should validate it + } void export_private(uint8_t *out, const private_key *prv) { diff --git a/csidh/ref/go-wrapper/wrapper.go b/csidh/ref/go-wrapper/wrapper.go new file mode 100644 index 0000000..fda94f8 --- /dev/null +++ b/csidh/ref/go-wrapper/wrapper.go @@ -0,0 +1,74 @@ +package wrapper + +/* +#cgo CFLAGS: -I../../ref/csidh +#cgo LDFLAGS: -L../../bin -lcsidh +#include +*/ +import "C" +import ( + "unsafe" + + csidh "github.com/henrydcase/nobs/dh/csidh" +) + +const ( + PrvSz = 37 + PubSz = 64 + SsSz = 64 +) + +type Ref struct {} + +// Converts Golang's byte array to C's unsigned char. 'c' must +// have same size as byte +func (Ref) toBytes(c []C.uchar, b []byte) { + if len(c) != len(b) { + panic("len c!= len b") + } + for i,v := range(b) { + c[i] = C.uchar(v) + } +} + +func (Ref) KeygenPrv() (prv csidh.PrivateKey) { + var buf [PrvSz]C.uchar + C.keygen_prv(&buf[0]) + prv.Import(C.GoBytes(unsafe.Pointer(&buf[0]), C.int(len(buf)))) + return +} + +func (c Ref) KeygenPub(prv *csidh.PrivateKey) (pub csidh.PublicKey) { + var prv_c_buf [PrvSz]C.uchar + var pub_c_buf [PubSz]C.uchar + var prv_g_buf [PrvSz]byte + + if !prv.Export(prv_g_buf[:]) { + panic("Can't export private key") + } + c.toBytes(prv_c_buf[:], prv_g_buf[:]) + C.keygen_pub(&pub_c_buf[0], &prv_c_buf[0]) + pub.Import(C.GoBytes(unsafe.Pointer(&pub_c_buf[0]), C.int(len(pub_c_buf)))) + return +} + +func (c Ref) Derive(ss []byte, pub *csidh.PublicKey, prv *csidh.PrivateKey) { + var prv_c_buf [PrvSz]C.uchar + var pub_c_buf [PubSz]C.uchar + var prv_g_buf [PrvSz]byte + var pub_g_buf [PubSz]byte + var ss_c_buf [SsSz]C.uchar + + if !pub.Export(pub_g_buf[:]) { + panic("Can't export public key") + } + + if !prv.Export(prv_g_buf[:]) { + panic("Can't export private key") + } + + c.toBytes(pub_c_buf[:], pub_g_buf[:]) + c.toBytes(prv_c_buf[:], prv_g_buf[:]) + 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)))) +} diff --git a/csidh/test/main.c b/csidh/ref/test/main.c similarity index 86% rename from csidh/test/main.c rename to csidh/ref/test/main.c index 8ef2254..0a5f624 100644 --- a/csidh/test/main.c +++ b/csidh/ref/test/main.c @@ -1,7 +1,8 @@ #include #include #include -#include "../ref/csidh/csidh.h" +#include "../csidh/csidh.h" +#include "../csidh/rng.h" static void u512_print(u512 const *x) { @@ -86,6 +87,17 @@ static bool testImportExport() { return fp_cmp(&pub1.A, &pub2.A); } +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"); + } +} + int main() { return !( testImportExport() &&