csidh: test vectors

这个提交包含在:
Henry Case 2019-01-30 20:30:11 +00:00
父节点 7227d565a9
当前提交 16f0f5b588
共有 8 个文件被更改,包括 226 次插入26 次删除

查看文件

@ -33,7 +33,7 @@ $(BUILD_DIR)/%.o: %.s
case $@ in */*) f=$@; mkdir -p $${f%/*} ;; esac case $@ in */*) f=$@; mkdir -p $${f%/*} ;; esac
$(CC) -c -o $@ $< $(CFLAGS) $(CC) -c -o $@ $< $(CFLAGS)
all: libcsidh torturer all: libcsidh torturer vector-creator
libcsidh: $(CODE_OBJ) libcsidh: $(CODE_OBJ)
mkdir -p $(PRJ_DIR)/$(BIN_DIR) mkdir -p $(PRJ_DIR)/$(BIN_DIR)
@ -48,6 +48,9 @@ clean:
torturer: $(BUILD_DIR)/.ok torturer: $(BUILD_DIR)/.ok
GOPATH=$(GOPATH_LOCAL) $(GO) install $(IMPORT_PATH)/cmd/$@ GOPATH=$(GOPATH_LOCAL) $(GO) install $(IMPORT_PATH)/cmd/$@
vector-creator: $(BUILD_DIR)/.ok
GOPATH=$(GOPATH_LOCAL) $(GO) install $(IMPORT_PATH)/cmd/$@
$(BUILD_DIR)/.ok: $(BUILD_DIR)/.ok:
mkdir -p "$(dir $(BUILD_DIR)/src/$(IMPORT_PATH))" mkdir -p "$(dir $(BUILD_DIR)/src/$(IMPORT_PATH))"
ln -s `pwd` "$(BUILD_DIR)/src/$(IMPORT_PATH)" ln -s `pwd` "$(BUILD_DIR)/src/$(IMPORT_PATH)"

查看文件

@ -10,16 +10,10 @@ import (
"github.com/henrydcase/nobs/dh/csidh" "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() { func TestSS() {
var r wrapper.Ref var r wrapper.Ref
var ssRef [SsSz]byte var ssRef [csidh.SharedSecretSize]byte
var ss [SsSz]byte var ss [csidh.SharedSecretSize]byte
// Go types // Go types
prA := r.KeygenPrv() prA := r.KeygenPrv()
@ -48,8 +42,8 @@ func TestSS() {
func TestKeyImport() { func TestKeyImport() {
var r wrapper.Ref var r wrapper.Ref
var ssRef [SsSz]byte var ssRef [csidh.SharedSecretSize]byte
var ss [SsSz]byte var ss [csidh.SharedSecretSize]byte
// Go types // Go types
prA := r.KeygenPrv() prA := r.KeygenPrv()
@ -75,8 +69,8 @@ func TestKeyImport() {
func TestKeyGeneration() { func TestKeyGeneration() {
var r wrapper.Ref var r wrapper.Ref
var ssRef [SsSz]byte var ssRef [csidh.SharedSecretSize]byte
var ss [SsSz]byte var ss [csidh.SharedSecretSize]byte
// Go types // Go types
prA := csidh.NewPrivateKey() prA := csidh.NewPrivateKey()
@ -110,6 +104,7 @@ func main() {
fmt.Printf("| TestName |Go | C |\n") fmt.Printf("| TestName |Go | C |\n")
fmt.Printf("|------------------|----------|----------|\n") fmt.Printf("|------------------|----------|----------|\n")
// OZAPTF: make configurable
// for i:=0; i<100; i++ { // for i:=0; i<100; i++ {
for { for {
TestSS() TestSS()

查看文件

@ -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; i<csidh.SharedSecretSize; i++ {
var newSs [csidh.SharedSecretSize]byte
copy(newSs[:], ss[:])
newSs[i] = ss[i]^ss[(i+1)%csidh.SharedSecretSize]
if bytes.Equal(newSs[:], ss) {
tv.Status = StatusValues[Valid]
} else {
tv.Status = StatusValues[InvalidSharedSecret]
}
tv.Ss = hex.EncodeToString(newSs[:])
tv.Id = n + i
vectors.Vectors = append(vectors.Vectors, tv)
}
}
// Public key validation fails
func createNegativePk2(vectors *TestVectors) {
n := len(vectors.Vectors)
tv := createValid(n)
pk, err := hex.DecodeString(tv.Pk2)
if err != nil {
panic("Can't decode public key 2")
}
for i:=0; i<csidh.PublicKeySize; i++ {
var newPk [csidh.PublicKeySize]byte
// Modify good public key so it's probably no longer valid
copy(newPk[:], pk[:])
newPk[i] = pk[i]^pk[(i+1)%csidh.PublicKeySize]
// Try to validate and set the status
if R.Validate(newPk[:]) {
tv.Status = StatusValues[Valid]
} else {
tv.Status = StatusValues[InvalidPublicKey2]
}
tv.Pk2 = hex.EncodeToString(newPk[:])
tv.Id = n + i
vectors.Vectors = append(vectors.Vectors, tv)
}
}
// Private key doesn't correspond to public key
func createNegativePrivateKey(vectors *TestVectors, num int) {
n := len(vectors.Vectors)
for i:=0; i<num; i++ {
var tv TestVector
var pkBytes1 [csidh.PublicKeySize]byte
var pkBytes2 [csidh.PublicKeySize]byte
var prBytes [csidh.PrivateKeySize]byte
pr1 := R.KeygenPrv()
pk1 := R.KeygenPub(&pr1)
// Store private key 1
pr1.Export(prBytes[:])
tv.Pr1 = hex.EncodeToString(prBytes[:])
// Generate public key which doesn't correspond to pr1
pr2 := R.KeygenPrv()
pk2 := R.KeygenPub(&pr2)
pk1.Export(pkBytes1[:])
pk2.Export(pkBytes2[:])
if bytes.Equal(pkBytes1[:], pkBytes2[:]) {
tv.Status = StatusValues[Valid]
} else {
tv.Status = StatusValues[InvalidPublicKey1]
}
tv.Id = n + i
tv.Pk1 = hex.EncodeToString(pkBytes2[:])
vectors.Vectors = append(vectors.Vectors, tv)
}
}
func main() {
var vectors TestVectors
for i:=0; i<10; i++ {
vectors.Vectors = append(vectors.Vectors, createValid(i))
}
createNegativeSharedSecret(&vectors)
createNegativePrivateKey(&vectors, 10)
createNegativePk2(&vectors)
marshalled, err := json.MarshalIndent(vectors, "", " ")
if err != nil {
panic("Error occured while Marshalling")
}
ioutil.WriteFile("testvectors.dat", marshalled, 0644)
}

查看文件

@ -230,18 +230,14 @@ 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) {
for (size_t i=0; i<64; i++) { for (size_t i=0; i<64; i++) {
size_t j = i / 8; size_t j = i / 8;
size_t k = i%8; size_t k = i%8;
uint64_t tmp = out[i]; uint64_t tmp = out[i];
pub->A.x.c[j] |= tmp << (8*k); pub->A.x.c[j] |= tmp << (8*k);
} }
if (validate(pub)) { return validate(pub);
printf("DUPA");
}
// TODO: should validate it
} }
void export_private(uint8_t *out, const private_key *prv) { 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); csidh(&ss, &pub, &prv);
export_public(&result[0], &ss); 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);
}

查看文件

@ -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 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 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 export_private(uint8_t *out, const private_key *prv);
void import_private(private_key *prv, const uint8_t *out); void import_private(private_key *prv, const uint8_t *out);
int is_valid(const uint8_t *a);
#endif #endif

查看文件

@ -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]) 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)))) 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
}

查看文件

@ -87,18 +87,28 @@ static bool testImportExport() {
return fp_cmp(&pub1.A, &pub2.A); return fp_cmp(&pub1.A, &pub2.A);
} }
// special cases:
// * diag 0
// * only 0
static void validator() { static void validator() {
uint8_t rnd[64] = {0}; uint8_t rnd[64] = {0};
public_key pub = {0}; private_key prA = {0};
for (size_t i=0; i<100; i++) { public_key pubA={0};
randombytes(rnd, sizeof(rnd));
printf("%llu=", i); csidh_private(&prA);
import_public(&pub, rnd); csidh(&pubA, &base, &prA);
printf("\n"); 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() { int main() {
// validator();
return !( return !(
testImportExport() && testImportExport() &&
testLoopRef()); testLoopRef());

1
csidh/vendor/github.com/henrydcase/nobs 自动生成的 vendored 符号链接
查看文件

@ -0,0 +1 @@
/home/hdc/repos/nobs/