Comparar commits

...

Autor SHA1 Mensaje Fecha
  Henry Case 3ed0199d4f makes GeneratePublicKey method of PrivateKey hace 6 años
  Henry Case b4df092ecd cleanup: move from/to bytes conversion to single function hace 6 años
  Henry Case 08f780b0f5 Adds install target hace 6 años
  Kris Kwiatkowski 3479e45558 cleanup: removes PrimeFieldElement inversion hace 6 años
  Henry Case 571611c9f7 makefile: improvements hace 6 años
  Henry Case 1c2c27017e cleanup: removes PrimeFieldElement::square method hace 6 años
  Henry Case 0e6db56864 cleanup: removes unused PrimeFieldElement methods hace 6 años
  Henry Case 1336c8ff50 cleanup: removes ProjectivePrimeFieldPoint hace 6 años
Se han modificado 10 ficheros con 112 adiciones y 482 borrados
Dividir vista
  1. +1
    -0
      .travis.yml
  2. +30
    -14
      Makefile
  3. +0
    -38
      p751toolbox/curve.go
  4. +46
    -187
      p751toolbox/field.go
  5. +12
    -159
      p751toolbox/field_test.go
  6. +2
    -53
      p751toolbox/print_test.go
  7. +6
    -11
      sidh/api.go
  8. +6
    -11
      sidh/sidh_test.go
  9. +3
    -3
      sike/sike.go
  10. +6
    -6
      sike/sike_test.go

+ 1
- 0
.travis.yml Ver fichero

@@ -8,6 +8,7 @@ matrix:
fast_finish: true

script:
- make test
- make bench
- make cover
- NOASM=1 make cover-sidh


+ 30
- 14
Makefile Ver fichero

@@ -3,42 +3,58 @@ 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
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))

install-%: prep_targets
GOPATH=$(GOPATH_LOCAL) go install $(OPTS) $(GOPATH_DIR)/$*

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
rm coverage_$*.txt

test: $(addprefix test-, $(TARGETS))
bench: $(addprefix bench-, $(TARGETS))
cover: $(addprefix cover-, $(TARGETS))
bench: $(addprefix bench-, $(TARGETS))
cover: $(addprefix cover-, $(TARGETS))
install: $(addprefix install-, $(TARGETS))
test: $(addprefix test-, $(TARGETS))

+ 0
- 38
p751toolbox/curve.go Ver fichero

@@ -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()
@@ -158,34 +149,17 @@ 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
}

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 +167,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


+ 46
- 187
p751toolbox/field.go Ver fichero

@@ -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.
@@ -142,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
@@ -243,8 +236,27 @@ 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
var aR fp751X2

// convert from montgomery domain
copy(aR[:], x.A[:]) // = a*R
fp751MontgomeryReduce(&a, &aR) // = a mod p in [0, 2p)
fp751StrongReduce(&a) // = a mod p in [0, p)
copy(aR[:], x.B[:])
fp751MontgomeryReduce(&b, &aR)
fp751StrongReduce(&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.
@@ -254,8 +266,20 @@ 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)
}

// convert to montgomery domain
var aRR fp751X2
fp751Mul(&aRR, &x.A, &montgomeryRsq) // = a*R*R
fp751MontgomeryReduce(&x.A, &aRR) // = a*R mod p
fp751Mul(&aRR, &x.B, &montgomeryRsq) // = a*R*R
fp751MontgomeryReduce(&x.B, &aRR) // = a*R mod p
}

//------------------------------------------------------------------------------
@@ -277,35 +301,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.
@@ -328,104 +323,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 = -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.
//
// 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.P34(dest) // dest = (x^2)^((p-3)/4) = x^((p-3)/2)
dest.Square(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.
@@ -448,7 +353,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)
@@ -498,49 +403,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))
}
}

+ 12
- 159
p751toolbox/field_test.go Ver fichero

@@ -35,9 +35,13 @@ func radix64ToBigInt(x []uint64) *big.Int {
return val
}

func (x *PrimeFieldElement) toBigInt() *big.Int {
func VartimeEq(x,y *PrimeFieldElement) bool {
return x.A.vartimeEq(y.A)
}

func (x *Fp751Element) toBigInt() *big.Int {
// Convert from Montgomery form
return x.A.toBigIntFromMontgomeryForm()
return x.toBigIntFromMontgomeryForm()
}

func (x *Fp751Element) toBigIntFromMontgomeryForm() *big.Int {
@@ -64,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())
}
}

@@ -121,7 +125,6 @@ func TestOneExtensionFieldToBytes(t *testing.T) {

x.One()
x.ToBytes(xBytes[:])

if xBytes[0] != 1 {
t.Error("Expected 1, got", xBytes[0])
}
@@ -249,101 +252,16 @@ 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)
z.Inv(&x)

// Now z = (1/x), so (z * x) * x == x
z.Mul(z, &x).Mul(z, &x)

return z.VartimeEq(&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 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 {
z := new(PrimeFieldElement)
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 {
@@ -357,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
@@ -370,26 +288,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
@@ -452,51 +350,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)
}
}

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)

for n := 0; n < b.N; n++ {
w.Square(z)
}
}

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) {


+ 2
- 53
p751toolbox/print_test.go Ver fichero

@@ -3,68 +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 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++ {
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")
}

+ 6
- 11
sidh/api.go Ver fichero

@@ -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


+ 6
- 11
sidh/sidh_test.go Ver fichero

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



+ 3
- 3
sike/sike.go Ver fichero

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


+ 6
- 6
sike/sike_test.go Ver fichero

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



Cargando…
Cancelar
Guardar