From b63ee49f173d377363ae5eee02f15be65a0b7ed4 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Fri, 31 Aug 2018 15:01:20 +0100 Subject: [PATCH 01/12] removes ZERO_AX_WITHOUT_CLOBBERING_FLAGS Go 1.10 correctly translates MOVQ pseudo-instruction to MOV. It was fixed in: https://github.com/golang/go/commit/7b773946c09e075ed50c49e76e08f61c16616ee4 We don't expect this library to compile with older version than Go 1.10 --- p751toolbox/field_amd64.s | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/p751toolbox/field_amd64.s b/p751toolbox/field_amd64.s index 4596d8f..daadf6a 100644 --- a/p751toolbox/field_amd64.s +++ b/p751toolbox/field_amd64.s @@ -39,30 +39,6 @@ #define REG_P2 SI #define REG_P3 DX -// We can't write MOVQ $0, AX because Go's assembler incorrectly -// optimizes this to XOR AX, AX, which clobbers the carry flags. -// -// This bug was defined to be "correct" behaviour (cf. -// https://github.com/golang/go/issues/12405 ) by declaring that the MOV -// pseudo-instruction clobbers flags, although this fact is mentioned -// nowhere in the documentation for the Go assembler. -// -// Defining MOVQ to clobber flags has the effect that it is never safe -// to interleave MOVQ with ADCQ and SBBQ instructions. Since this is -// required to write a carry chain longer than registers' working set, -// all of the below code therefore relies on the unspecified and -// undocumented behaviour that MOV won't clobber flags, except in the -// case of the above-mentioned bug. -// -// However, there's also no specification of which instructions -// correspond to machine instructions, and which are -// pseudo-instructions (i.e., no specification of what the assembler -// actually does), so this doesn't seem much worse than usual. -// -// Avoid the bug by dropping the bytes for `mov eax, 0` in directly: - -#define ZERO_AX_WITHOUT_CLOBBERING_FLAGS BYTE $0xB8; BYTE $0; BYTE $0; BYTE $0; BYTE $0; - TEXT ·fp751StrongReduce(SB), NOSPLIT, $0-8 MOVQ x+0(FP), REG_P1 @@ -322,7 +298,7 @@ TEXT ·fp751AddReduced(SB), NOSPLIT, $0-24 MOVQ R8, (72)(REG_P3) MOVQ R9, (80)(REG_P3) MOVQ R10, (88)(REG_P3) - ZERO_AX_WITHOUT_CLOBBERING_FLAGS + MOVQ $0, AX SBBQ $0, AX MOVQ P751X2_0, SI @@ -425,7 +401,7 @@ TEXT ·fp751SubReduced(SB), NOSPLIT, $0-24 MOVQ (88)(REG_P1), AX SBBQ (88)(REG_P2), AX MOVQ AX, (88)(REG_P3) - ZERO_AX_WITHOUT_CLOBBERING_FLAGS + MOVQ $0, AX SBBQ $0, AX MOVQ P751X2_0, SI @@ -2244,7 +2220,7 @@ TEXT ·fp751X2SubLazy(SB), NOSPLIT, $0-24 MOVQ DI, (184)(REG_P3) // Now the carry flag is 1 if x-y < 0. If so, add p*2^768. - ZERO_AX_WITHOUT_CLOBBERING_FLAGS + MOVQ $0, AX SBBQ $0, AX // Load p into registers: From c19b2f034a2d0f5ba7f98c4e2583a464b2b69b24 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Thu, 30 Aug 2018 18:21:00 +0100 Subject: [PATCH 02/12] cleanup: removes ProjectivePrimeFieldPoint --- p751toolbox/curve.go | 32 -------------------------------- p751toolbox/print_test.go | 4 ---- 2 files changed, 36 deletions(-) diff --git a/p751toolbox/curve.go b/p751toolbox/curve.go index 2ebd089..ead6162 100644 --- a/p751toolbox/curve.go +++ b/p751toolbox/curve.go @@ -28,15 +28,6 @@ type ProjectivePoint struct { Z ExtensionFieldElement } -// A point on the projective line P^1(F_p). -// -// This represents a point on the (Kummer line) of the prime-field subgroup of -// the base curve E_0(F_p), defined by E_0 : y^2 = x^3 + x. -type ProjectivePrimeFieldPoint struct { - X PrimeFieldElement - Z PrimeFieldElement -} - func (params *ProjectiveCurveParameters) FromAffine(a *ExtensionFieldElement) { params.A = *a params.C.One() @@ -169,23 +160,12 @@ func (point *ProjectivePoint) FromAffine(x *ExtensionFieldElement) { point.Z = oneExtensionField } -func (point *ProjectivePrimeFieldPoint) FromAffine(x *PrimeFieldElement) { - point.X = *x - point.Z = onePrimeField -} - func (point *ProjectivePoint) ToAffine() *ExtensionFieldElement { affine_x := new(ExtensionFieldElement) affine_x.Inv(&point.Z).Mul(affine_x, &point.X) return affine_x } -func (point *ProjectivePrimeFieldPoint) ToAffine() *PrimeFieldElement { - affine_x := new(PrimeFieldElement) - affine_x.Inv(&point.Z).Mul(affine_x, &point.X) - return affine_x -} - func (lhs *ProjectivePoint) VartimeEq(rhs *ProjectivePoint) bool { var t0, t1 ExtensionFieldElement t0.Mul(&lhs.X, &rhs.Z) @@ -193,23 +173,11 @@ func (lhs *ProjectivePoint) VartimeEq(rhs *ProjectivePoint) bool { return t0.VartimeEq(&t1) } -func (lhs *ProjectivePrimeFieldPoint) VartimeEq(rhs *ProjectivePrimeFieldPoint) bool { - var t0, t1 PrimeFieldElement - t0.Mul(&lhs.X, &rhs.Z) - t1.Mul(&lhs.Z, &rhs.X) - return t0.VartimeEq(&t1) -} - func ProjectivePointConditionalSwap(xP, xQ *ProjectivePoint, choice uint8) { ExtensionFieldConditionalSwap(&xP.X, &xQ.X, choice) ExtensionFieldConditionalSwap(&xP.Z, &xQ.Z, choice) } -func ProjectivePrimeFieldPointConditionalSwap(xP, xQ *ProjectivePrimeFieldPoint, choice uint8) { - PrimeFieldConditionalSwap(&xP.X, &xQ.X, choice) - PrimeFieldConditionalSwap(&xP.Z, &xQ.Z, choice) -} - // Combined coordinate doubling and differential addition. Takes projective points // P,Q,Q-P and (A+2C)/4C curve E coefficient. Returns 2*P and P+Q calculated on E. // Function is used only by RightToLeftLadder. Corresponds to Algorithm 5 of SIKE diff --git a/p751toolbox/print_test.go b/p751toolbox/print_test.go index 9fae61d..8b565a8 100644 --- a/p751toolbox/print_test.go +++ b/p751toolbox/print_test.go @@ -38,10 +38,6 @@ func (point ProjectivePoint) String() string { return fmt.Sprintf("X:\n%sZ:\n%s", point.X.String(), point.Z.String()) } -func (point ProjectivePrimeFieldPoint) String() string { - return fmt.Sprintf("X:\n%sZ:\n%s", point.X.String(), point.Z.String()) -} - func (point Fp751Element) PrintHex() { fmt.Printf("\t") for i := 0; i < fp751NumWords/2; i++ { From 555439a49d12abd232a6e6a6f60e044292571fc7 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Thu, 30 Aug 2018 21:37:54 +0100 Subject: [PATCH 03/12] cleanup: removes unused PrimeFieldElement methods --- p751toolbox/curve.go | 6 -- p751toolbox/field.go | 98 ------------------------------- p751toolbox/field_test.go | 119 ++------------------------------------ 3 files changed, 5 insertions(+), 218 deletions(-) diff --git a/p751toolbox/curve.go b/p751toolbox/curve.go index ead6162..be12de3 100644 --- a/p751toolbox/curve.go +++ b/p751toolbox/curve.go @@ -149,12 +149,6 @@ func (cparams *ProjectiveCurveParameters) RecoverCurveCoefficients4(coefEq *Curv return } -func (point *ProjectivePoint) FromAffinePrimeField(x *PrimeFieldElement) { - point.X.A = x.A - point.X.B = zeroExtensionField.B - point.Z = oneExtensionField -} - func (point *ProjectivePoint) FromAffine(x *ExtensionFieldElement) { point.X = *x point.Z = oneExtensionField diff --git a/p751toolbox/field.go b/p751toolbox/field.go index cfd6cee..8894c6d 100644 --- a/p751toolbox/field.go +++ b/p751toolbox/field.go @@ -105,16 +105,6 @@ func (dest *ExtensionFieldElement) Mul(lhs, rhs *ExtensionFieldElement) *Extensi return dest } -// Set dest = -x -// -// Allowed to overlap dest with x. -// -// Returns dest to allow chaining operations. -func (dest *ExtensionFieldElement) Neg(x *ExtensionFieldElement) *ExtensionFieldElement { - dest.Sub(&zeroExtensionField, x) - return dest -} - // Set dest = 1/x // // Allowed to overlap dest with x. @@ -277,35 +267,6 @@ var onePrimeField = PrimeFieldElement{ A: Fp751Element{0x249ad, 0x0, 0x0, 0x0, 0x0, 0x8310000000000000, 0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x2d5b24bce5e2}, } -// Set dest = 0. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) Zero() *PrimeFieldElement { - *dest = zeroPrimeField - return dest -} - -// Set dest = 1. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) One() *PrimeFieldElement { - *dest = onePrimeField - return dest -} - -// Set dest to x. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) SetUint64(x uint64) *PrimeFieldElement { - var xRR fp751X2 - dest.A = Fp751Element{} // = 0 - dest.A[0] = x // = x - fp751Mul(&xRR, &dest.A, &montgomeryRsq) // = x*R*R - fp751MontgomeryReduce(&dest.A, &xRR) // = x*R mod p - - return dest -} - // Set dest = lhs * rhs. // // Allowed to overlap lhs or rhs with dest. @@ -352,65 +313,6 @@ func (dest *PrimeFieldElement) Square(x *PrimeFieldElement) *PrimeFieldElement { return dest } -// Set dest = -x -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) Neg(x *PrimeFieldElement) *PrimeFieldElement { - dest.Sub(&zeroPrimeField, x) - return dest -} - -// Set dest = lhs + rhs. -// -// Allowed to overlap lhs or rhs with dest. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) Add(lhs, rhs *PrimeFieldElement) *PrimeFieldElement { - fp751AddReduced(&dest.A, &lhs.A, &rhs.A) - - return dest -} - -// Set dest = lhs - rhs. -// -// Allowed to overlap lhs or rhs with dest. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) Sub(lhs, rhs *PrimeFieldElement) *PrimeFieldElement { - fp751SubReduced(&dest.A, &lhs.A, &rhs.A) - - return dest -} - -// Returns true if lhs = rhs. Takes variable time. -func (lhs *PrimeFieldElement) VartimeEq(rhs *PrimeFieldElement) bool { - return lhs.A.vartimeEq(rhs.A) -} - -// If choice = 1u8, set (x,y) = (y,x). If choice = 0u8, set (x,y) = (x,y). -// -// Returns dest to allow chaining operations. -func PrimeFieldConditionalSwap(x, y *PrimeFieldElement, choice uint8) { - fp751ConditionalSwap(&x.A, &y.A, choice) -} - -// Set dest = sqrt(x), if x is a square. If x is nonsquare dest is undefined. -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) Sqrt(x *PrimeFieldElement) *PrimeFieldElement { - tmp_x := *x // Copy x in case dest == x - // Since x is assumed to be square, x = y^2 - dest.P34(x) // dest = (y^2)^((p-3)/4) = y^((p-3)/2) - dest.Mul(dest, &tmp_x) // dest = y^2 * y^((p-3)/2) = y^((p+1)/2) - // Now dest^2 = y^(p+1) = y^2 = x, so dest = sqrt(x) - - return dest -} - // Set dest = 1/x. // // Allowed to overlap x with dest. diff --git a/p751toolbox/field_test.go b/p751toolbox/field_test.go index f56300b..0427c33 100644 --- a/p751toolbox/field_test.go +++ b/p751toolbox/field_test.go @@ -35,6 +35,10 @@ func radix64ToBigInt(x []uint64) *big.Int { return val } +func VartimeEq(x,y *PrimeFieldElement) bool { + return x.A.vartimeEq(y.A) +} + func (x *PrimeFieldElement) toBigInt() *big.Int { // Convert from Montgomery form return x.A.toBigIntFromMontgomeryForm() @@ -249,52 +253,6 @@ func TestExtensionFieldElementBatch3Inv(t *testing.T) { //------------------------------------------------------------------------------ // Prime Field //------------------------------------------------------------------------------ - -func TestPrimeFieldElementSetUint64VersusBigInt(t *testing.T) { - setUint64RoundTrips := func(x uint64) bool { - z := new(PrimeFieldElement).SetUint64(x).toBigInt().Uint64() - return x == z - } - - if err := quick.Check(setUint64RoundTrips, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestPrimeFieldElementAddVersusBigInt(t *testing.T) { - addMatchesBigInt := func(x, y PrimeFieldElement) bool { - z := new(PrimeFieldElement) - z.Add(&x, &y) - - check := new(big.Int) - check.Add(x.toBigInt(), y.toBigInt()) - check.Mod(check, cln16prime) - - return check.Cmp(z.toBigInt()) == 0 - } - - if err := quick.Check(addMatchesBigInt, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestPrimeFieldElementSubVersusBigInt(t *testing.T) { - subMatchesBigInt := func(x, y PrimeFieldElement) bool { - z := new(PrimeFieldElement) - z.Sub(&x, &y) - - check := new(big.Int) - check.Sub(x.toBigInt(), y.toBigInt()) - check.Mod(check, cln16prime) - - return check.Cmp(z.toBigInt()) == 0 - } - - if err := quick.Check(subMatchesBigInt, quickCheckConfig); err != nil { - t.Error(err) - } -} - func TestPrimeFieldElementInv(t *testing.T) { inverseIsCorrect := func(x PrimeFieldElement) bool { z := new(PrimeFieldElement) @@ -303,7 +261,7 @@ func TestPrimeFieldElementInv(t *testing.T) { // Now z = (1/x), so (z * x) * x == x z.Mul(z, &x).Mul(z, &x) - return z.VartimeEq(&x) + return VartimeEq(z, &x) } // This is more expensive; run fewer tests @@ -313,26 +271,6 @@ func TestPrimeFieldElementInv(t *testing.T) { } } -func TestPrimeFieldElementSqrt(t *testing.T) { - inverseIsCorrect := func(x PrimeFieldElement) bool { - // Construct y = x^2 so we're sure y is square. - y := new(PrimeFieldElement) - y.Square(&x) - - z := new(PrimeFieldElement) - z.Sqrt(y) - - // Now z = sqrt(y), so z^2 == y - z.Square(z) - return z.VartimeEq(y) - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (8 + quickCheckScaleFactor))} - if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { - t.Error(err) - } -} func TestPrimeFieldElementMulVersusBigInt(t *testing.T) { mulMatchesBigInt := func(x, y PrimeFieldElement) bool { @@ -370,26 +308,6 @@ func TestPrimeFieldElementP34VersusBigInt(t *testing.T) { } } -func TestFp751ElementConditionalSwap(t *testing.T) { - var one = Fp751Element{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - var two = Fp751Element{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} - - var x = one - var y = two - - fp751ConditionalSwap(&x, &y, 0) - - if !(x == one && y == two) { - t.Error("Found", x, "expected", one) - } - - fp751ConditionalSwap(&x, &y, 1) - - if !(x == two && y == one) { - t.Error("Found", x, "expected", two) - } -} - // Package-level storage for this field element is intended to deter // compiler optimizations. var benchmarkFp751Element Fp751Element @@ -461,15 +379,6 @@ func BenchmarkPrimeFieldElementInv(b *testing.B) { } } -func BenchmarkPrimeFieldElementSqrt(b *testing.B) { - z := &PrimeFieldElement{A: bench_x} - w := new(PrimeFieldElement) - - for n := 0; n < b.N; n++ { - w.Sqrt(z) - } -} - func BenchmarkPrimeFieldElementSquare(b *testing.B) { z := &PrimeFieldElement{A: bench_x} w := new(PrimeFieldElement) @@ -479,24 +388,6 @@ func BenchmarkPrimeFieldElementSquare(b *testing.B) { } } -func BenchmarkPrimeFieldElementAdd(b *testing.B) { - z := &PrimeFieldElement{A: bench_x} - w := new(PrimeFieldElement) - - for n := 0; n < b.N; n++ { - w.Add(z, z) - } -} - -func BenchmarkPrimeFieldElementSub(b *testing.B) { - z := &PrimeFieldElement{A: bench_x} - w := new(PrimeFieldElement) - - for n := 0; n < b.N; n++ { - w.Sub(z, z) - } -} - // --- field operation functions func BenchmarkFp751Multiply(b *testing.B) { From 7707a477925b785f65ade9b892fde188411da1b9 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Fri, 31 Aug 2018 11:11:27 +0100 Subject: [PATCH 04/12] cleanup: removes PrimeFieldElement::square method The method is implemented in exactly same way as multiplication. Currently there is no explenation for it's existance. Benchmarking shows no change --- p751toolbox/field.go | 26 +++++--------------------- p751toolbox/field_test.go | 9 --------- 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/p751toolbox/field.go b/p751toolbox/field.go index 8894c6d..1a16f6a 100644 --- a/p751toolbox/field.go +++ b/p751toolbox/field.go @@ -289,30 +289,14 @@ func (dest *PrimeFieldElement) Mul(lhs, rhs *PrimeFieldElement) *PrimeFieldEleme // // Returns dest to allow chaining operations. func (dest *PrimeFieldElement) Pow2k(x *PrimeFieldElement, k uint8) *PrimeFieldElement { - dest.Square(x) + dest.Mul(x, x) for i := uint8(1); i < k; i++ { - dest.Square(dest) + dest.Mul(dest, dest) } return dest } -// Set dest = x^2 -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) Square(x *PrimeFieldElement) *PrimeFieldElement { - a := &x.A // = a*R - b := &x.A // = b*R - - var ab fp751X2 - fp751Mul(&ab, a, b) // = a*b*R*R - fp751MontgomeryReduce(&dest.A, &ab) // = a*b*R mod p - - return dest -} - // Set dest = 1/x. // // Allowed to overlap x with dest. @@ -320,9 +304,9 @@ func (dest *PrimeFieldElement) Square(x *PrimeFieldElement) *PrimeFieldElement { // Returns dest to allow chaining operations. func (dest *PrimeFieldElement) Inv(x *PrimeFieldElement) *PrimeFieldElement { tmp_x := *x // Copy x in case dest == x - dest.Square(x) // dest = x^2 + dest.Mul(x, x) // dest = x^2 dest.P34(dest) // dest = (x^2)^((p-3)/4) = x^((p-3)/2) - dest.Square(dest) // dest = x^(p-3) + dest.Mul(dest, dest) // dest = x^(p-3) dest.Mul(dest, &tmp_x) // dest = x^(p-2) return dest @@ -350,7 +334,7 @@ func (dest *PrimeFieldElement) P34(x *PrimeFieldElement) *PrimeFieldElement { // Build a lookup table of odd multiples of x. lookup := [16]PrimeFieldElement{} xx := &PrimeFieldElement{} - xx.Square(x) // Set xx = x^2 + xx.Mul(x, x) // Set xx = x^2 lookup[0] = *x for i := 1; i < 16; i++ { lookup[i].Mul(&lookup[i-1], xx) diff --git a/p751toolbox/field_test.go b/p751toolbox/field_test.go index 0427c33..0ee2da2 100644 --- a/p751toolbox/field_test.go +++ b/p751toolbox/field_test.go @@ -379,15 +379,6 @@ func BenchmarkPrimeFieldElementInv(b *testing.B) { } } -func BenchmarkPrimeFieldElementSquare(b *testing.B) { - z := &PrimeFieldElement{A: bench_x} - w := new(PrimeFieldElement) - - for n := 0; n < b.N; n++ { - w.Square(z) - } -} - // --- field operation functions func BenchmarkFp751Multiply(b *testing.B) { From 7bf83bb613ddaf927c1f5dff71816a6f314e86cd Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Fri, 31 Aug 2018 11:01:51 +0100 Subject: [PATCH 05/12] makefile: improvements --- .travis.yml | 1 + Makefile | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index c3c1dbe..677ae1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ matrix: fast_finish: true script: + - make test - make bench - make cover - NOASM=1 make cover-sidh diff --git a/Makefile b/Makefile index 0444f84..5a9bd93 100644 --- a/Makefile +++ b/Makefile @@ -3,37 +3,48 @@ MK_FILE_PATH = $(lastword $(MAKEFILE_LIST)) PRJ_DIR = $(abspath $(dir $(MK_FILE_PATH))) GOPATH_LOCAL = $(PRJ_DIR)/build GOPATH_DIR = github.com/cloudflare/p751sidh -CSHAKE_PKG = github.com/henrydcase/nobs/hash/sha3 +CSHAKE_PKG ?= github.com/henrydcase/nobs/hash/sha3 TARGETS = p751toolbox sidh sike GOARCH ?= OPTS_GCCGO ?= -compiler gccgo -O2 -g -OPTS_TAGS ?= -tags=noasm OPTS ?= +OPTS_TAGS ?= -tags=noasm NOASM ?= +# -run="NonExistent" is set to make sure tests are not run before benchmarking +BENCH_OPTS ?= -bench=. -run="NonExistent" +# whether to be verbose +V ?= 1 ifeq ($(NOASM),1) OPTS+=$(OPTS_TAGS) endif +ifeq ($(V),1) + OPTS += -v # Be verbose + BENCH_OPTS += -gcflags=-m # Show results from inlining +endif + clean: rm -rf $(GOPATH_LOCAL) rm -rf coverage*.txt -prep: +build_env: GOPATH=$(GOPATH_LOCAL) go get $(CSHAKE_PKG) mkdir -p $(GOPATH_LOCAL)/src/$(GOPATH_DIR) - cp -rf p751toolbox $(GOPATH_LOCAL)/src/$(GOPATH_DIR) - cp -rf sidh $(GOPATH_LOCAL)/src/$(GOPATH_DIR) - cp -rf sike $(GOPATH_LOCAL)/src/$(GOPATH_DIR) cp -rf etc $(GOPATH_LOCAL)/src/$(GOPATH_DIR) -test-%: prep - GOPATH=$(GOPATH_LOCAL) go test -v $(OPTS) $(GOPATH_DIR)/$* +copy-target-%: + cp -rf $* $(GOPATH_LOCAL)/src/$(GOPATH_DIR) + +prep_targets: build_env $(addprefix copy-target-, $(TARGETS)) + +test-%: prep_targets + GOPATH=$(GOPATH_LOCAL) go test $(OPTS) $(GOPATH_DIR)/$* -bench-%: prep - cd $*; GOPATH=$(GOPATH_LOCAL) go test -v $(OPTS) -bench=. +bench-%: prep_targets + cd $*; GOPATH=$(GOPATH_LOCAL) go test $(OPTS) $(BENCH_OPTS) -cover-%: prep +cover-%: prep_targets GOPATH=$(GOPATH_LOCAL) go test \ -race -coverprofile=coverage_$*.txt -covermode=atomic $(OPTS) $(GOPATH_DIR)/$* cat coverage_$*.txt >> coverage.txt From 580d1ae0b96e4e63ac7ec84be387c1ba81b671fd Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Fri, 31 Aug 2018 12:40:37 +0100 Subject: [PATCH 06/12] cleanup: removes PrimeFieldElement inversion --- p751toolbox/field.go | 28 ++++++++-------------------- p751toolbox/field_test.go | 28 ---------------------------- 2 files changed, 8 insertions(+), 48 deletions(-) diff --git a/p751toolbox/field.go b/p751toolbox/field.go index 1a16f6a..234d35e 100644 --- a/p751toolbox/field.go +++ b/p751toolbox/field.go @@ -132,18 +132,21 @@ func (dest *ExtensionFieldElement) Inv(x *ExtensionFieldElement) *ExtensionField fp751MontgomeryReduce(&asq_plus_bsq.A, &asq) // = (a^2 + b^2)*R mod p // Now asq_plus_bsq = a^2 + b^2 - var asq_plus_bsq_inv PrimeFieldElement - asq_plus_bsq_inv.Inv(&asq_plus_bsq) - c := &asq_plus_bsq_inv.A + // Invert asq_plus_bsq + inv := asq_plus_bsq + inv.Mul(&asq_plus_bsq, &asq_plus_bsq) + inv.P34(&inv) + inv.Mul(&inv, &inv) + inv.Mul(&inv, &asq_plus_bsq) var ac fp751X2 - fp751Mul(&ac, a, c) + fp751Mul(&ac, a, &inv.A) fp751MontgomeryReduce(&dest.A, &ac) var minus_b Fp751Element fp751SubReduced(&minus_b, &minus_b, b) var minus_bc fp751X2 - fp751Mul(&minus_bc, &minus_b, c) + fp751Mul(&minus_bc, &minus_b, &inv.A) fp751MontgomeryReduce(&dest.B, &minus_bc) return dest @@ -297,21 +300,6 @@ func (dest *PrimeFieldElement) Pow2k(x *PrimeFieldElement, k uint8) *PrimeFieldE return dest } -// Set dest = 1/x. -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *PrimeFieldElement) Inv(x *PrimeFieldElement) *PrimeFieldElement { - tmp_x := *x // Copy x in case dest == x - dest.Mul(x, x) // dest = x^2 - dest.P34(dest) // dest = (x^2)^((p-3)/4) = x^((p-3)/2) - dest.Mul(dest, dest) // dest = x^(p-3) - dest.Mul(dest, &tmp_x) // dest = x^(p-2) - - return dest -} - // Set dest = x^((p-3)/4). If x is square, this is 1/sqrt(x). // // Allowed to overlap x with dest. diff --git a/p751toolbox/field_test.go b/p751toolbox/field_test.go index 0ee2da2..edff4dc 100644 --- a/p751toolbox/field_test.go +++ b/p751toolbox/field_test.go @@ -253,25 +253,6 @@ func TestExtensionFieldElementBatch3Inv(t *testing.T) { //------------------------------------------------------------------------------ // Prime Field //------------------------------------------------------------------------------ -func TestPrimeFieldElementInv(t *testing.T) { - inverseIsCorrect := func(x PrimeFieldElement) bool { - z := new(PrimeFieldElement) - z.Inv(&x) - - // Now z = (1/x), so (z * x) * x == x - z.Mul(z, &x).Mul(z, &x) - - return VartimeEq(z, &x) - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (8 + quickCheckScaleFactor))} - if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { - t.Error(err) - } -} - - func TestPrimeFieldElementMulVersusBigInt(t *testing.T) { mulMatchesBigInt := func(x, y PrimeFieldElement) bool { z := new(PrimeFieldElement) @@ -370,15 +351,6 @@ func BenchmarkPrimeFieldElementMul(b *testing.B) { } } -func BenchmarkPrimeFieldElementInv(b *testing.B) { - z := &PrimeFieldElement{A: bench_x} - w := new(PrimeFieldElement) - - for n := 0; n < b.N; n++ { - w.Inv(z) - } -} - // --- field operation functions func BenchmarkFp751Multiply(b *testing.B) { From d663dd88646e96ae71d4e555c0671e4850c0d0e7 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Sat, 1 Sep 2018 21:56:46 +0100 Subject: [PATCH 07/12] Adds install target --- Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5a9bd93..eafa175 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,9 @@ copy-target-%: prep_targets: build_env $(addprefix copy-target-, $(TARGETS)) +install-%: prep_targets + GOPATH=$(GOPATH_LOCAL) go install $(OPTS) $(GOPATH_DIR)/$* + test-%: prep_targets GOPATH=$(GOPATH_LOCAL) go test $(OPTS) $(GOPATH_DIR)/$* @@ -50,6 +53,7 @@ cover-%: prep_targets cat coverage_$*.txt >> coverage.txt rm coverage_$*.txt -test: $(addprefix test-, $(TARGETS)) -bench: $(addprefix bench-, $(TARGETS)) -cover: $(addprefix cover-, $(TARGETS)) \ No newline at end of file +bench: $(addprefix bench-, $(TARGETS)) +cover: $(addprefix cover-, $(TARGETS)) +install: $(addprefix install-, $(TARGETS)) +test: $(addprefix test-, $(TARGETS)) From 1131231b8be1bfc65f006804ef3ef4983e193091 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Sun, 2 Sep 2018 11:57:59 +0100 Subject: [PATCH 08/12] cleanup: moves from/to bytes conversion From/to bytes conversion will be refactored when p503 is introduced. Patch splits part that uses field specific functions from part that converts Fp element to bytes. Patch also removes some testing helpers which are no longer needed. --- p751toolbox/field.go | 107 ++++++++++++++++++++------------------ p751toolbox/field_test.go | 17 +++--- p751toolbox/print_test.go | 51 +----------------- 3 files changed, 67 insertions(+), 108 deletions(-) diff --git a/p751toolbox/field.go b/p751toolbox/field.go index 234d35e..40a4cc2 100644 --- a/p751toolbox/field.go +++ b/p751toolbox/field.go @@ -236,8 +236,20 @@ func (x *ExtensionFieldElement) ToBytes(output []byte) { if len(output) < 188 { panic("output byte slice too short, need 188 bytes") } - x.A.toBytesFromMontgomeryForm(output[0:94]) - x.B.toBytesFromMontgomeryForm(output[94:188]) + + var a,b Fp751Element + FromMontgomery(x, &a, &b) + + // convert to bytes in little endian form. 8*12 = 96, but we drop the last two bytes + // since p is 751 < 752=94*8 bits. + for i := 0; i < 94; i++ { + // set i = j*8 + k + j := i / 8 + k := uint64(i % 8) + + output[i] = byte(a[j] >> (8 * k)) + output[i+94] = byte(b[j] >> (8 * k)) + } } // Read 188 bytes into the given ExtensionFieldElement. @@ -247,8 +259,49 @@ func (x *ExtensionFieldElement) FromBytes(input []byte) { if len(input) < 188 { panic("input byte slice too short, need 188 bytes") } - x.A.montgomeryFormFromBytes(input[:94]) - x.B.montgomeryFormFromBytes(input[94:188]) + + for i:=0; i<94; i++ { + j := i / 8 + k := uint64(i % 8) + x.A[j] |= uint64(input[i]) << (8 * k) + x.B[j] |= uint64(input[i+94]) << (8 * k) + } + + ToMontgomery(x) +} + +// Converts values in x.A and x.B to Montgomery domain +// x.A = x.A * R mod p +// x.B = x.B * R mod p +func ToMontgomery(x *ExtensionFieldElement) { + var aRR fp751X2 + + // convert to montgomery domain + fp751Mul(&aRR, &x.A, &montgomeryRsq) // = a*R*R + fp751MontgomeryReduce(&x.A, &aRR) // = a*R mod p + fp751Mul(&aRR, &x.B, &montgomeryRsq) + fp751MontgomeryReduce(&x.B, &aRR) +} + +// Converts values in x.A and x.B from Montgomery domain +// a = x.A mod p +// b = x.B mod p +// +// After returning from the call x is not modified. +func FromMontgomery(x *ExtensionFieldElement, a,b *Fp751Element) { + var aR fp751X2 + + // convert from montgomery domain + copy(aR[:], x.A[:]) + fp751MontgomeryReduce(a, &aR) // = a mod p in [0, 2p) + fp751StrongReduce(a) // = a mod p in [0, p) + + for i:=range(aR) { + aR[i] = 0 + } + copy(aR[:], x.B[:]) + fp751MontgomeryReduce(b, &aR) + fp751StrongReduce(b) } //------------------------------------------------------------------------------ @@ -372,49 +425,3 @@ func (x Fp751Element) vartimeEq(y Fp751Element) bool { return eq } - -// Read an Fp751Element from little-endian bytes and convert to Montgomery form. -// -// The input byte slice must be at least 94 bytes long. -func (x *Fp751Element) montgomeryFormFromBytes(input []byte) { - if len(input) < 94 { - panic("input byte slice too short") - } - - var a Fp751Element - for i := 0; i < 94; i++ { - // set i = j*8 + k - j := i / 8 - k := uint64(i % 8) - a[j] |= uint64(input[i]) << (8 * k) - } - - var aRR fp751X2 - fp751Mul(&aRR, &a, &montgomeryRsq) // = a*R*R - fp751MontgomeryReduce(x, &aRR) // = a*R mod p -} - -// Given an Fp751Element in Montgomery form, convert to little-endian bytes. -// -// The output byte slice must be at least 94 bytes long. -func (x *Fp751Element) toBytesFromMontgomeryForm(output []byte) { - if len(output) < 94 { - panic("output byte slice too short") - } - - var a Fp751Element - var aR fp751X2 - copy(aR[:], x[:]) // = a*R - fp751MontgomeryReduce(&a, &aR) // = a mod p in [0, 2p) - fp751StrongReduce(&a) // = a mod p in [0, p) - - // 8*12 = 96, but we drop the last two bytes since p is 751 < 752=94*8 bits. - for i := 0; i < 94; i++ { - // set i = j*8 + k - j := i / 8 - k := uint64(i % 8) - // Need parens because Go's operator precedence would interpret - // a[j] >> 8*k as (a[j] >> 8) * k - output[i] = byte(a[j] >> (8 * k)) - } -} diff --git a/p751toolbox/field_test.go b/p751toolbox/field_test.go index edff4dc..250f197 100644 --- a/p751toolbox/field_test.go +++ b/p751toolbox/field_test.go @@ -39,9 +39,9 @@ func VartimeEq(x,y *PrimeFieldElement) bool { return x.A.vartimeEq(y.A) } -func (x *PrimeFieldElement) toBigInt() *big.Int { +func (x *Fp751Element) toBigInt() *big.Int { // Convert from Montgomery form - return x.A.toBigIntFromMontgomeryForm() + return x.toBigIntFromMontgomeryForm() } func (x *Fp751Element) toBigIntFromMontgomeryForm() *big.Int { @@ -68,8 +68,8 @@ func TestPrimeFieldElementToBigInt(t *testing.T) { // sage: assert(xR < 2*p) // sage: (xR / R) % p xBig, _ := new(big.Int).SetString("4469946751055876387821312289373600189787971305258234719850789711074696941114031433609871105823930699680637820852699269802003300352597419024286385747737509380032982821081644521634652750355306547718505685107272222083450567982240", 10) - if xBig.Cmp(x.toBigInt()) != 0 { - t.Error("Expected", xBig, "found", x.toBigInt()) + if xBig.Cmp(x.A.toBigInt()) != 0 { + t.Error("Expected", xBig, "found", x.A.toBigInt()) } } @@ -125,7 +125,6 @@ func TestOneExtensionFieldToBytes(t *testing.T) { x.One() x.ToBytes(xBytes[:]) - if xBytes[0] != 1 { t.Error("Expected 1, got", xBytes[0]) } @@ -259,10 +258,10 @@ func TestPrimeFieldElementMulVersusBigInt(t *testing.T) { z.Mul(&x, &y) check := new(big.Int) - check.Mul(x.toBigInt(), y.toBigInt()) + check.Mul(x.A.toBigInt(), y.A.toBigInt()) check.Mod(check, cln16prime) - return check.Cmp(z.toBigInt()) == 0 + return check.Cmp(z.A.toBigInt()) == 0 } if err := quick.Check(mulMatchesBigInt, quickCheckConfig); err != nil { @@ -276,10 +275,10 @@ func TestPrimeFieldElementP34VersusBigInt(t *testing.T) { z := new(PrimeFieldElement) z.P34(&x) - check := x.toBigInt() + check := x.A.toBigInt() check.Exp(check, p34, cln16prime) - return check.Cmp(z.toBigInt()) == 0 + return check.Cmp(z.A.toBigInt()) == 0 } // This is more expensive; run fewer tests diff --git a/p751toolbox/print_test.go b/p751toolbox/print_test.go index 8b565a8..04ba57b 100644 --- a/p751toolbox/print_test.go +++ b/p751toolbox/print_test.go @@ -3,64 +3,17 @@ package p751toolbox // Tools used for testing and debugging import ( - "bytes" "fmt" ) -func printHex(vector []byte) (out string) { - var buffer bytes.Buffer - buffer.WriteString("0x") - len := len(vector) - for i := len - 1; i >= 0; i-- { - buffer.WriteString(fmt.Sprintf("%02x", vector[i])) - } - buffer.WriteString("\n") - return buffer.String() -} - -func (element Fp751Element) String() string { - var out [94]byte - element.toBytesFromMontgomeryForm(out[:]) - return fmt.Sprintf("%s", printHex(out[:])) -} - func (primeElement PrimeFieldElement) String() string { - return fmt.Sprintf("%s", primeElement.A.String()) + return fmt.Sprintf("%X", primeElement.A.toBigInt().String()) } func (extElement ExtensionFieldElement) String() string { - var out [188]byte - extElement.ToBytes(out[:]) - return fmt.Sprintf("A: %sB: %s", printHex(out[:94]), printHex(out[94:])) + return fmt.Sprintf("\nA: %X\nB: %X", extElement.A.toBigInt().String(), extElement.B.toBigInt().String()) } func (point ProjectivePoint) String() string { return fmt.Sprintf("X:\n%sZ:\n%s", point.X.String(), point.Z.String()) } - -func (point Fp751Element) PrintHex() { - fmt.Printf("\t") - for i := 0; i < fp751NumWords/2; i++ { - fmt.Printf("0x%0.16X, ", point[i]) - } - fmt.Printf("\n\t\t") - for i := fp751NumWords / 2; i < fp751NumWords; i++ { - fmt.Printf("0x%0.16X, ", point[i]) - } - fmt.Printf("\n") -} - -func (extElement ExtensionFieldElement) PrintHex() { - fmt.Printf("\t[r]: ") - extElement.A.PrintHex() - fmt.Printf("\t[u]: ") - extElement.B.PrintHex() -} - -func (point ProjectivePoint) PrintHex() { - fmt.Printf("X:") - point.X.PrintHex() - fmt.Printf("Z:") - point.X.PrintHex() - fmt.Printf("\n") -} From 14dba93b7a3e7613e610cb698ccc62599a8faf9c Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Sun, 2 Sep 2018 14:49:01 +0100 Subject: [PATCH 09/12] makes GeneratePublicKey method of PrivateKey It makes a little bit more sense to have GeneratePublicKey as a method of PrivateKey. In this case code doesn't need to check if caller provided pointer is nil. Object was created by NewPrivateKey(), so it code can assume object was correctly initialized. The old GeneratePublicKey was returning an error when caller provided pointer was nil. As this possibility is now removed, method doesn't return error anymore. --- sidh/api.go | 17 ++++++----------- sidh/sidh_test.go | 17 ++++++----------- sike/sike.go | 6 +++--- sike/sike_test.go | 12 ++++++------ 4 files changed, 21 insertions(+), 31 deletions(-) diff --git a/sidh/api.go b/sidh/api.go index 628a677..5e34fcd 100644 --- a/sidh/api.go +++ b/sidh/api.go @@ -164,19 +164,14 @@ func (prv *PrivateKey) Generate(rand io.Reader) error { return err } -// Generates public key corresponding to prv. KeyVariant of generated public key -// is same as PrivateKey. Fails only if prv was wrongly initialized. -// Constant time for properly initialzied PrivateKey -func GeneratePublicKey(prv *PrivateKey) (*PublicKey, error) { - if prv == nil { - return nil, errors.New("sidh: invalid arguments") - } - +// Generates public key. +// +// Constant time. +func (prv *PrivateKey) GeneratePublicKey() (*PublicKey) { if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A { - return publicKeyGenA(prv), nil - } else { - return publicKeyGenB(prv), nil + return publicKeyGenA(prv) } + return publicKeyGenB(prv) } // Computes a shared secret which is a j-invariant. Function requires that pub has diff --git a/sidh/sidh_test.go b/sidh/sidh_test.go index d6f10d3..5300731 100644 --- a/sidh/sidh_test.go +++ b/sidh/sidh_test.go @@ -93,10 +93,8 @@ func testKeygen(s *SidhParams, t *testing.T) { expPubA := convToPub(PkA, KeyVariant_SIDH_A) expPubB := convToPub(PkB, KeyVariant_SIDH_B) - pubA, err := GeneratePublicKey(alicePrivate) - checkErr(t, err, "public key A generation failed") - pubB, err := GeneratePublicKey(bobPrivate) - checkErr(t, err, "public key B generation failed") + pubA := alicePrivate.GeneratePublicKey() + pubB := bobPrivate.GeneratePublicKey() if !bytes.Equal(pubA.Export(), expPubA.Export()) { t.Fatalf("unexpected value of public key A") @@ -119,11 +117,8 @@ func testRoundtrip(s *SidhParams, t *testing.T) { checkErr(t, err, "key generation failed") // Generate public keys - pubA, err := GeneratePublicKey(prvA) - checkErr(t, err, "") - - pubB, err := GeneratePublicKey(prvB) - checkErr(t, err, "") + pubA := prvA.GeneratePublicKey() + pubB := prvB.GeneratePublicKey() // Derive shared secret s1, err := DeriveSecret(prvB, pubA) @@ -317,7 +312,7 @@ func BenchmarkAliceKeyGenPub(b *testing.B) { prv := NewPrivateKey(params.Id, KeyVariant_SIDH_A) prv.Generate(rand.Reader) for n := 0; n < b.N; n++ { - GeneratePublicKey(prv) + prv.GeneratePublicKey() } } @@ -325,7 +320,7 @@ func BenchmarkBobKeyGenPub(b *testing.B) { prv := NewPrivateKey(params.Id, KeyVariant_SIDH_B) prv.Generate(rand.Reader) for n := 0; n < b.N; n++ { - GeneratePublicKey(prv) + prv.GeneratePublicKey() } } diff --git a/sike/sike.go b/sike/sike.go index a8b76b3..be033aa 100644 --- a/sike/sike.go +++ b/sike/sike.go @@ -71,7 +71,7 @@ func Encrypt(rng io.Reader, pub *PublicKey, ptext []byte) ([]byte, error) { return nil, err } - pkA, _ := GeneratePublicKey(skA) // Never fails + pkA := skA.GeneratePublicKey() return encrypt(skA, pkA, pub, ptext) } @@ -152,7 +152,7 @@ func Encapsulate(rng io.Reader, pub *PublicKey) (ctext []byte, secret []byte, er return nil, nil, err } - pkA, _ := GeneratePublicKey(skA) // Never fails + pkA := skA.GeneratePublicKey() ctext, err = encrypt(skA, pkA, pub, ptext) if err != nil { return nil, nil, err @@ -197,7 +197,7 @@ func Decapsulate(prv *PrivateKey, pub *PublicKey, ctext []byte) ([]byte, error) skA.Import(r) // Never fails - pkA, _ := GeneratePublicKey(skA) + pkA := skA.GeneratePublicKey() c0 := pkA.Export() h = cshake.NewCShake256(nil, H) diff --git a/sike/sike_test.go b/sike/sike_test.go index 106e8bf..b3765a7 100644 --- a/sike/sike_test.go +++ b/sike/sike_test.go @@ -77,7 +77,7 @@ func TestPKEKeyGeneration(t *testing.T) { sk := NewPrivateKey(params.Id, KeyVariant_SIKE) err = sk.Generate(rand.Reader) checkErr(t, err, "PEK key generation") - pk, _ := GeneratePublicKey(sk) + pk := sk.GeneratePublicKey() // Try to encrypt ct, err := Encrypt(rand.Reader, pk, msg[:]) @@ -99,7 +99,7 @@ func TestNegativePKE(t *testing.T) { err = sk.Generate(rand.Reader) checkErr(t, err, "key generation") - pk, _ := GeneratePublicKey(sk) + pk := sk.GeneratePublicKey() ct, err := Encrypt(rand.Reader, pk, msg[:39]) if err == nil { @@ -152,7 +152,7 @@ func TestKEMKeyGeneration(t *testing.T) { // Generate key sk := NewPrivateKey(params.Id, KeyVariant_SIKE) checkErr(t, sk.Generate(rand.Reader), "error: key generation") - pk, _ := GeneratePublicKey(sk) + pk := sk.GeneratePublicKey() // calculated shared secret ct, ss_e, err := Encapsulate(rand.Reader, pk) @@ -168,7 +168,7 @@ func TestKEMKeyGeneration(t *testing.T) { func TestNegativeKEM(t *testing.T) { sk := NewPrivateKey(params.Id, KeyVariant_SIKE) checkErr(t, sk.Generate(rand.Reader), "error: key generation") - pk, _ := GeneratePublicKey(sk) + pk := sk.GeneratePublicKey() ct, ss_e, err := Encapsulate(rand.Reader, pk) checkErr(t, err, "pre-requisite for a test failed") @@ -201,7 +201,7 @@ func TestNegativeKEM(t *testing.T) { func TestNegativeKEMSameWrongResult(t *testing.T) { sk := NewPrivateKey(params.Id, KeyVariant_SIKE) checkErr(t, sk.Generate(rand.Reader), "error: key generation") - pk, _ := GeneratePublicKey(sk) + pk := sk.GeneratePublicKey() ct, encSs, err := Encapsulate(rand.Reader, pk) checkErr(t, err, "pre-requisite for a test failed") @@ -261,7 +261,7 @@ func testKeygen(pk, sk []byte) bool { } // Generate public key - pubKey, _ := GeneratePublicKey(prvKey) + pubKey := prvKey.GeneratePublicKey() return bytes.Equal(pubKey.Export(), pk) } From 78e8ac1b6b77b9e0333b88d0d9c3989b05239fac Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Tue, 4 Sep 2018 09:39:37 +0100 Subject: [PATCH 10/12] cleanup: FromAffine already sets Z in projective point to 1 --- sidh/sidh.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/sidh/sidh.go b/sidh/sidh.go index 12109dd..cb4e211 100644 --- a/sidh/sidh.go +++ b/sidh/sidh.go @@ -231,19 +231,13 @@ func publicKeyGenA(prv *PrivateKey) (pub *PublicKey) { // Load points for A xPA.FromAffine(&prv.params.A.Affine_P) - xPA.Z.One() xQA.FromAffine(&prv.params.A.Affine_Q) - xQA.Z.One() xRA.FromAffine(&prv.params.A.Affine_R) - xRA.Z.One() // Load points for B xRB.FromAffine(&prv.params.B.Affine_R) - xRB.Z.One() xQB.FromAffine(&prv.params.B.Affine_Q) - xQB.Z.One() xPB.FromAffine(&prv.params.B.Affine_P) - xPB.Z.One() // Find isogeny kernel tmp.A.Zero() @@ -279,19 +273,13 @@ func publicKeyGenB(prv *PrivateKey) (pub *PublicKey) { // Load points for B xRB.FromAffine(&prv.params.B.Affine_R) - xRB.Z.One() xQB.FromAffine(&prv.params.B.Affine_Q) - xQB.Z.One() xPB.FromAffine(&prv.params.B.Affine_P) - xPB.Z.One() // Load points for A xPA.FromAffine(&prv.params.A.Affine_P) - xPA.Z.One() xQA.FromAffine(&prv.params.A.Affine_Q) - xQA.Z.One() xRA.FromAffine(&prv.params.A.Affine_R) - xRA.Z.One() tmp.A.Zero() tmp.C.One() From 70f5a2b94056f7753462aa17887f76f041ff05a4 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Thu, 13 Sep 2018 13:07:01 +0100 Subject: [PATCH 11/12] makes possible to specify go on cmd line --- Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index eafa175..fe00ab9 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ GOPATH_LOCAL = $(PRJ_DIR)/build GOPATH_DIR = github.com/cloudflare/p751sidh CSHAKE_PKG ?= github.com/henrydcase/nobs/hash/sha3 TARGETS = p751toolbox sidh sike +GO ?= go GOARCH ?= OPTS_GCCGO ?= -compiler gccgo -O2 -g OPTS ?= @@ -29,7 +30,7 @@ clean: rm -rf coverage*.txt build_env: - GOPATH=$(GOPATH_LOCAL) go get $(CSHAKE_PKG) + GOPATH=$(GOPATH_LOCAL) $(GO) get $(CSHAKE_PKG) mkdir -p $(GOPATH_LOCAL)/src/$(GOPATH_DIR) cp -rf etc $(GOPATH_LOCAL)/src/$(GOPATH_DIR) @@ -39,16 +40,16 @@ copy-target-%: prep_targets: build_env $(addprefix copy-target-, $(TARGETS)) install-%: prep_targets - GOPATH=$(GOPATH_LOCAL) go install $(OPTS) $(GOPATH_DIR)/$* + GOPATH=$(GOPATH_LOCAL) $(GO) install $(OPTS) $(GOPATH_DIR)/$* test-%: prep_targets - GOPATH=$(GOPATH_LOCAL) go test $(OPTS) $(GOPATH_DIR)/$* + GOPATH=$(GOPATH_LOCAL) $(GO) test $(OPTS) $(GOPATH_DIR)/$* bench-%: prep_targets - cd $*; GOPATH=$(GOPATH_LOCAL) go test $(OPTS) $(BENCH_OPTS) + cd $*; GOPATH=$(GOPATH_LOCAL) $(GO) test $(OPTS) $(BENCH_OPTS) cover-%: prep_targets - GOPATH=$(GOPATH_LOCAL) go test \ + GOPATH=$(GOPATH_LOCAL) $(GO) test \ -race -coverprofile=coverage_$*.txt -covermode=atomic $(OPTS) $(GOPATH_DIR)/$* cat coverage_$*.txt >> coverage.txt rm coverage_$*.txt From d2e292553d9de6dd6a22f0a91e78d4933cef2db9 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Thu, 13 Sep 2018 15:20:31 +0100 Subject: [PATCH 12/12] adds 'go vet' to test target --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index fe00ab9..c19149f 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ install-%: prep_targets GOPATH=$(GOPATH_LOCAL) $(GO) install $(OPTS) $(GOPATH_DIR)/$* test-%: prep_targets + GOPATH=$(GOPATH_LOCAL) $(GO) vet $(GOPATH_DIR)/$* GOPATH=$(GOPATH_LOCAL) $(GO) test $(OPTS) $(GOPATH_DIR)/$* bench-%: prep_targets