From 9f4aa7388dcfc79042535455bf96d3c6a3454b73 Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sat, 3 Jun 2017 10:17:12 +0200 Subject: [PATCH 01/31] Add SetVarTime methods to Point and Scalar interfaces, add preliminary support to standard mod.Int and edwards25519 --- group.go | 20 ++++++++++++++++---- group/edwards25519/point.go | 20 +++++++++++++------- group/mod/int.go | 8 ++++++++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/group.go b/group.go index 693f494fc..0a7345877 100644 --- a/group.go +++ b/group.go @@ -53,11 +53,17 @@ type Scalar interface { // Set to a fresh random or pseudo-random scalar Pick(rand cipher.Stream) Scalar - // SetBytes will take bytes and create a scalar out of it + // SetBytes sets the scalar from a big-endian byte-slice SetBytes([]byte) Scalar - // Bytes returns the raw internal representation + // Bytes returns a big-Endian representation of the scalar Bytes() []byte + + // Allow or disallow use of faster variable-time implementations + // of operations on this Point, returning the old flag value. + // This flag always defaults to false (constant-time only) + // in implementations that can provide constant-time operations. + SetVarTime(varTime bool) bool } /* @@ -111,9 +117,15 @@ type Point interface { // Set to the negation of point a Neg(a Point) Point - // Encrypt point p by multiplying with scalar s. - // If p == nil, encrypt the standard base point Base(). + // Multiply point p by the scalar s. + // If p == nil, multiply with the standard base point Base(). Mul(s Scalar, p Point) Point + + // Allow or disallow use of faster variable-time implementations + // of operations on this Point. Returns the old flag value. + // This flag always defaults to false (constant-time only) + // in implementations that can provide constant-time operations. + SetVarTime(varTime bool) bool } /* diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index 730e2994b..912374918 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -29,6 +29,7 @@ import ( type point struct { ge extendedGroupElement + varTime bool } func (P *point) String() string { @@ -229,14 +230,23 @@ func (P *point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { if A == nil { geScalarMultBase(&P.ge, &a) } else { - geScalarMult(&P.ge, &a, &A.(*point).ge) - //geScalarMultVartime(&P.ge, &a, &A.(*point).ge) + if P.varTime { + geScalarMultVartime(&P.ge, &a, &A.(*point).ge) + } else { + geScalarMult(&P.ge, &a, &A.(*point).ge) + } } return P } -// Curve represents an Ed25519. +func (P *point) SetVarTime(varTime bool) bool { + old := P.varTime + P.varTime = varTime + return old +} + +// Curve represents the Ed25519 group. // There are no parameters and no initialization is required // because it supports only this one specific curve. type Curve struct { @@ -299,7 +309,3 @@ func (s *Curve) NewKey(stream cipher.Stream) kyber.Scalar { return secret } -// Initialize the curve. -//func (c *Curve) Init(fullGroup bool) { -// c.FullGroup = fullGroup -//} diff --git a/group/mod/int.go b/group/mod/int.go index 0bfbfd7c0..d555793ee 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -473,3 +473,11 @@ func (i *Int) HideDecode(buf []byte) { i.V.SetBytes(buf) i.V.Mod(&i.V, i.M) } + +// Allow or disallow variable-time implementation. +// This implementation unfortunately provices only variable-time operations, +// so the flag is hard-coded to true. +func (i *Int) SetVarTime(varTime bool) bool { + return true +} + From bb3867e2110d6fe842b6c7601d7959573644de39 Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sat, 3 Jun 2017 19:25:27 +0200 Subject: [PATCH 02/31] new scalar code partly working, but not fully --- group.go | 3 +- group/edwards25519/const.go | 5 +- group/edwards25519/curve.go | 72 +++ group/edwards25519/point.go | 85 +-- group/edwards25519/scalar.go | 1038 ++++++++++++++++++++++++++++++++++ group/mod/int.go | 9 +- util/test/test.go | 19 +- 7 files changed, 1147 insertions(+), 84 deletions(-) create mode 100644 group/edwards25519/curve.go diff --git a/group.go b/group.go index 0a7345877..e37c4890e 100644 --- a/group.go +++ b/group.go @@ -53,7 +53,8 @@ type Scalar interface { // Set to a fresh random or pseudo-random scalar Pick(rand cipher.Stream) Scalar - // SetBytes sets the scalar from a big-endian byte-slice + // SetBytes sets the scalar from a big-endian byte-slice, + // reducing if necessary to the appropriate modulus. SetBytes([]byte) Scalar // Bytes returns a big-Endian representation of the scalar diff --git a/group/edwards25519/const.go b/group/edwards25519/const.go index 97b15e938..8e68f6222 100644 --- a/group/edwards25519/const.go +++ b/group/edwards25519/const.go @@ -14,13 +14,14 @@ import ( var prime, _ = new(big.Int).SetString("57896044618658097711785492504343953926634992332820282019728792003956564819949", 10) // prime order of base point = 2^252 + 27742317777372353535851937790883648493 +// XXX this should probably just be a big.Int var primeOrder, _ = new(mod.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250989", "", 10) // cofactor of the curve, as a ModInt -var cofactor = mod.NewInt64(8, &primeOrder.V) +var cofactor = (&scalar{}).SetInt64(8) // order of the full curve including the cofactor -var fullOrder = new(big.Int).Mul(&primeOrder.V, &cofactor.V) +//var fullOrder = new(big.Int).Mul(&primeOrder.V, &cofactor.V) // identity point var nullPoint = new(point).Null() diff --git a/group/edwards25519/curve.go b/group/edwards25519/curve.go new file mode 100644 index 000000000..8c27930f0 --- /dev/null +++ b/group/edwards25519/curve.go @@ -0,0 +1,72 @@ +package edwards25519 + +import ( + "crypto/cipher" + "crypto/sha512" + + "gopkg.in/dedis/kyber.v1" + //"gopkg.in/dedis/kyber.v1/group/mod" + "gopkg.in/dedis/kyber.v1/util/random" +) + +// Curve represents the Ed25519 group. +// There are no parameters and no initialization is required +// because it supports only this one specific curve. +type Curve struct { + + // Set to true to use the full group of order 8Q, + // or false to use the prime-order subgroup of order Q. + // FullGroup bool +} + +func (c *Curve) PrimeOrder() bool { + return true +} + +// Return the name of the curve, "Ed25519". +func (c *Curve) String() string { + return "Ed25519" +} + +// Returns 32, the size in bytes of an encoded Scalar for the Ed25519 curve. +func (c *Curve) ScalarLen() int { + return 32 +} + +// Create a new Scalar for the Ed25519 curve. +func (c *Curve) Scalar() kyber.Scalar { + //i := mod.NewInt64(0, &primeOrder.V) + //i.BO = mod.LittleEndian + //return i + + return &scalar{} +} + +// Returns 32, the size in bytes of an encoded Point on the Ed25519 curve. +func (c *Curve) PointLen() int { + return 32 +} + +// Create a new Point on the Ed25519 curve. +func (c *Curve) Point() kyber.Point { + P := new(point) + //P.c = c + return P +} + +// NewKey returns a formatted Ed25519 key (avoiding subgroup attack by requiring +// it to be a multiple of 8) +func (s *Curve) NewKey(stream cipher.Stream) kyber.Scalar { + if stream == nil { + stream = random.Stream + } + buffer := random.NonZeroBytes(32, stream) + scalar := sha512.Sum512(buffer) + scalar[0] &= 0xf8 + scalar[31] &= 0x3f + scalar[31] |= 0x40 + + secret := s.Scalar().SetBytes(scalar[:32]) + return secret +} + diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index 912374918..ffde7fbc7 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -16,15 +16,12 @@ package edwards25519 import ( "crypto/cipher" - "crypto/sha512" "encoding/hex" "errors" "io" "gopkg.in/dedis/kyber.v1" - "gopkg.in/dedis/kyber.v1/group/mod" "gopkg.in/dedis/kyber.v1/util/marshalling" - "gopkg.in/dedis/kyber.v1/util/random" ) type point struct { @@ -220,20 +217,21 @@ func (P *point) Neg(A kyber.Point) kyber.Point { func (P *point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { // Convert the scalar to fixed-length little-endian form. - sb := s.(*mod.Int).V.Bytes() - shi := len(sb) - 1 - var a [32]byte - for i := range sb { - a[shi-i] = sb[i] - } + //sb := s.(*mod.Int).V.Bytes() + //shi := len(sb) - 1 + //var a [32]byte + //for i := range sb { + // a[shi-i] = sb[i] + //} + a := &s.(*scalar).v if A == nil { - geScalarMultBase(&P.ge, &a) + geScalarMultBase(&P.ge, a) } else { if P.varTime { - geScalarMultVartime(&P.ge, &a, &A.(*point).ge) + geScalarMultVartime(&P.ge, a, &A.(*point).ge) } else { - geScalarMult(&P.ge, &a, &A.(*point).ge) + geScalarMult(&P.ge, a, &A.(*point).ge) } } @@ -246,66 +244,3 @@ func (P *point) SetVarTime(varTime bool) bool { return old } -// Curve represents the Ed25519 group. -// There are no parameters and no initialization is required -// because it supports only this one specific curve. -type Curve struct { - - // Set to true to use the full group of order 8Q, - // or false to use the prime-order subgroup of order Q. - // FullGroup bool -} - -func (c *Curve) PrimeOrder() bool { - return true -} - -// Return the name of the curve, "Ed25519". -func (c *Curve) String() string { - return "Ed25519" -} - -// Returns 32, the size in bytes of an encoded Scalar for the Ed25519 curve. -func (c *Curve) ScalarLen() int { - return 32 -} - -// Create a new Scalar for the Ed25519 curve. -func (c *Curve) Scalar() kyber.Scalar { - // if c.FullGroup { - // return mod.NewInt(0, fullOrder) - // } else { - i := mod.NewInt64(0, &primeOrder.V) - i.BO = mod.LittleEndian - return i - // } -} - -// Returns 32, the size in bytes of an encoded Point on the Ed25519 curve. -func (c *Curve) PointLen() int { - return 32 -} - -// Create a new Point on the Ed25519 curve. -func (c *Curve) Point() kyber.Point { - P := new(point) - //P.c = c - return P -} - -// NewKey returns a formatted Ed25519 key (avoiding subgroup attack by requiring -// it to be a multiple of 8) -func (s *Curve) NewKey(stream cipher.Stream) kyber.Scalar { - if stream == nil { - stream = random.Stream - } - buffer := random.NonZeroBytes(32, stream) - scalar := sha512.Sum512(buffer) - scalar[0] &= 0xf8 - scalar[31] &= 0x3f - scalar[31] |= 0x40 - - secret := s.Scalar().SetBytes(scalar[:32]) - return secret -} - diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 4a17d3fca..1804815e7 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -4,11 +4,180 @@ package edwards25519 +import ( + "io" + "errors" + "crypto/cipher" + + "gopkg.in/dedis/kyber.v1" + "gopkg.in/dedis/kyber.v1/group/mod" + "gopkg.in/dedis/kyber.v1/util/bytes" + "gopkg.in/dedis/kyber.v1/util/subtle" + "gopkg.in/dedis/kyber.v1/util/marshalling" + "gopkg.in/dedis/kyber.v1/util/random" +) + // This code is a port of the public domain, "ref10" implementation of ed25519 // from SUPERCOP. // The scalars are GF(2^252 + 27742317777372353535851937790883648493). + +type scalar struct { + v [32]byte + varTime bool +} + +// Equality test for two Scalars derived from the same Group +func (s *scalar) Equal(s2 kyber.Scalar) bool { + v1 := s.v[:] + v2 := s2.(*scalar).v[:] + return subtle.ConstantTimeCompare(v1,v2) != 0 +} + +// Set equal to another Scalar a +func (s *scalar) Set(a kyber.Scalar) kyber.Scalar { + s.v = a.(*scalar).v + return s +} + +func (s *scalar) Clone() kyber.Scalar { + s2 := *s + return &s2 +} + +func (s *scalar) setInt(i *mod.Int) kyber.Scalar { + b := i.LittleEndian(32, 32) + copy(s.v[:], b) + return s +} + +// Set to a small integer value +func (s *scalar) SetInt64(v int64) kyber.Scalar { + return s.setInt(mod.NewInt64(v, &primeOrder.V)) +} + +func (s *scalar) toInt() *mod.Int { + return mod.NewIntBytes(s.v[:], &primeOrder.V, mod.LittleEndian) +} + +// Set to the additive identity (0) +func (s *scalar) Zero() kyber.Scalar { + s.v = [32]byte{0} + return s +} + +// Set to the multiplicative identity (1) +func (s *scalar) One() kyber.Scalar { + s.v = [32]byte{1} + return s +} + +// Set to the modular sum of scalars a and b +func (s *scalar) Add(a, b kyber.Scalar) kyber.Scalar { + scAdd(&s.v, &a.(*scalar).v, &b.(*scalar).v) + return s +} + +// Set to the modular difference a - b +func (s *scalar) Sub(a, b kyber.Scalar) kyber.Scalar { + panic("Sub not yet implemented") +} + +// Set to the modular negation of scalar a +func (s *scalar) Neg(a kyber.Scalar) kyber.Scalar { + panic("Neg not yet implemented") +} + +// Set to the modular product of scalars a and b +func (s *scalar) Mul(a, b kyber.Scalar) kyber.Scalar { + scMul(&s.v, &a.(*scalar).v, &b.(*scalar).v) + return s +} + +// Set to the modular division of scalar a by scalar b +func (s *scalar) Div(a, b kyber.Scalar) kyber.Scalar { + panic("Div not yet implemented") +} + +// Set to the modular inverse of scalar a +// XXX not yet constant-time implementation; should be fixed +func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { + i := a.(*scalar).toInt() + println("A"+ i.String()) + i.Inv(i) + println("B"+ i.String()) + i.Inv(i) + println("C"+ i.String()) + i.Inv(i) + println("D"+ i.String()) + i.Inv(i) + return s.setInt(i) +} + +// Set to a fresh random or pseudo-random scalar +func (s *scalar) Pick(rand cipher.Stream) kyber.Scalar { + i := mod.NewInt(random.Int(&primeOrder.V, rand), &primeOrder.V) + return s.setInt(i) +} + +// SetBytes sets the scalar from a big-endian byte-slice +func (s *scalar) SetBytes(b []byte) kyber.Scalar { + // XXX handle simple and scReduce cases appropriately + return s.setInt(mod.NewIntBytes(b, &primeOrder.V, mod.BigEndian)) +} + +// Bytes returns a big-Endian representation of the scalar +func (s *scalar) Bytes() []byte { + var buf = s.v + bytes.Reverse(buf[:], buf[:]) + var i int + for i = 0; i < 32; i++ { + if buf[i] != 0 { + break + } + } + return buf[i:] +} + +func (s *scalar) String() string { + return s.toInt().String() +} + +// Encoded length of this object in bytes. +func (s *scalar) MarshalSize() int { + return 32 +} + +func (s *scalar) MarshalBinary() ([]byte, error) { + buf := s.v + return buf[:], nil +} + +func (s *scalar) UnmarshalBinary(buf []byte) error { + if len(buf) != 32 { + return errors.New("wrong size buffer") + } + copy(s.v[:], buf) + return nil +} + +func (s *scalar) MarshalTo(w io.Writer) (int, error) { + return marshalling.ScalarMarshalTo(s, w) +} + +func (s *scalar) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.ScalarUnmarshalFrom(s, r) +} + +func (s *scalar) SetVarTime(varTime bool) bool { + old := s.varTime + s.varTime = varTime + return old +} + + + // Input: // a[0]+256*a[1]+...+256^31*a[31] = a // b[0]+256*b[1]+...+256^31*b[31] = b @@ -442,6 +611,875 @@ func scMulAdd(s, a, b, c *[32]byte) { s[31] = byte(s11 >> 17) } +// Hacky scAdd cobbled together rather sub-optimally from scMulAdd. +// +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (a+c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +// +func scAdd(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := int64(1) + b1 := int64(0) + b2 := int64(0) + b3 := int64(0) + b4 := int64(0) + b5 := int64(0) + b6 := int64(0) + b7 := int64(0) + b8 := int64(0) + b9 := int64(0) + b10 := int64(0) + b11 := int64(0) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + var carry [23]int64 + + s0 := c0 + a0*b0 + s1 := c1 + a0*b1 + a1*b0 + s2 := c2 + a0*b2 + a1*b1 + a2*b0 + s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 + s20 := a9*b11 + a10*b10 + a11*b9 + s21 := a10*b11 + a11*b10 + s22 := a11 * b11 + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + +// Hacky scMul cobbled together rather sub-optimally from scMulAdd. +// +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// b[0]+256*b[1]+...+256^31*b[31] = b +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (ab) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +func scMul(s, a, b *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := 2097151 & load3(b[:]) + b1 := 2097151 & (load4(b[2:]) >> 5) + b2 := 2097151 & (load3(b[5:]) >> 2) + b3 := 2097151 & (load4(b[7:]) >> 7) + b4 := 2097151 & (load4(b[10:]) >> 4) + b5 := 2097151 & (load3(b[13:]) >> 1) + b6 := 2097151 & (load4(b[15:]) >> 6) + b7 := 2097151 & (load3(b[18:]) >> 3) + b8 := 2097151 & load3(b[21:]) + b9 := 2097151 & (load4(b[23:]) >> 5) + b10 := 2097151 & (load3(b[26:]) >> 2) + b11 := (load4(b[28:]) >> 7) + c0 := int64(0) + c1 := int64(0) + c2 := int64(0) + c3 := int64(0) + c4 := int64(0) + c5 := int64(0) + c6 := int64(0) + c7 := int64(0) + c8 := int64(0) + c9 := int64(0) + c10 := int64(0) + c11 := int64(0) + var carry [23]int64 + + s0 := c0 + a0*b0 + s1 := c1 + a0*b1 + a1*b0 + s2 := c2 + a0*b2 + a1*b1 + a2*b0 + s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 + s20 := a9*b11 + a10*b10 + a11*b9 + s21 := a10*b11 + a11*b10 + s22 := a11 * b11 + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + // Input: // s[0]+256*s[1]+...+256^63*s[63] = s // diff --git a/group/mod/int.go b/group/mod/int.go index d555793ee..dcb105f40 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -60,8 +60,8 @@ func NewInt64(v int64, M *big.Int) *Int { // NewIntBytes creates a new Int with a given slice of bytes and a big.Int // modulus. -func NewIntBytes(a []byte, m *big.Int) *Int { - return new(Int).InitBytes(a, m) +func NewIntBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { + return new(Int).InitBytes(a, m, byteOrder) } // NewIntString creates a new Int with a given string and a big.Int modulus. @@ -88,9 +88,10 @@ func (i *Int) Init64(v int64, m *big.Int) *Int { } // Initialize to a number represented in a big-endian byte string. -func (i *Int) InitBytes(a []byte, m *big.Int) *Int { +// XXX either delete or add an endianness parameter +func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { i.M = m - i.BO = BigEndian + i.BO = byteOrder i.V.SetBytes(a).Mod(&i.V, i.M) return i } diff --git a/util/test/test.go b/util/test/test.go index 670dff579..a8c373754 100644 --- a/util/test/test.go +++ b/util/test/test.go @@ -140,20 +140,35 @@ func testGroup(g kyber.Group, rand cipher.Stream) []kyber.Point { gen := g.Point().Base() points = append(points, gen) + // Sanity-check relationship between addition and multiplication + p1 := g.Point().Add(gen, gen) + p2 := g.Point().Mul(stmp.SetInt64(2), nil) + if !p1.Equal(p2) { + panic("oops, multiply by two doesn't work") + } + p1.Add(p1, p1) + p2.Mul(stmp.SetInt64(4), nil) + if !p1.Equal(p2) { + panic("oops, multiply by four doesn't work") + } + points = append(points, p1) + // Verify additive and multiplicative identities of the generator. ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen) if !ptmp.Equal(pzero) { panic("oops, generator additive identity doesn't work") } if g.PrimeOrder() { // secret.Inv works only in prime-order groups + println("gen", gen.String()) ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp) + println("after", ptmp.String()) if !ptmp.Equal(gen) { panic("oops, generator multiplicative identity doesn't work") } } - p1 := g.Point().Mul(s1, gen) - p2 := g.Point().Mul(s2, gen) + p1.Mul(s1, gen) + p2.Mul(s2, gen) if p1.Equal(p2) { panic("uh-oh, encryption isn't producing unique points!") } From bce2b8949085a7badd8b39031b75bc5275ea848a Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sat, 3 Jun 2017 19:37:20 +0200 Subject: [PATCH 03/31] fix primeOrder, cofactor, etc to be plain big.Ints normally instead of mod.Ints --- group/edwards25519/const.go | 14 ++++++++------ group/edwards25519/curve.go | 4 ++-- group/edwards25519/point.go | 4 ++-- group/edwards25519/scalar.go | 14 ++++++++++---- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/group/edwards25519/const.go b/group/edwards25519/const.go index 8e68f6222..7800d53c0 100644 --- a/group/edwards25519/const.go +++ b/group/edwards25519/const.go @@ -6,8 +6,6 @@ package edwards25519 import ( "math/big" - - "gopkg.in/dedis/kyber.v1/group/mod" ) // prime modulus of underlying field = 2^255 - 19 @@ -15,13 +13,17 @@ var prime, _ = new(big.Int).SetString("57896044618658097711785492504343953926634 // prime order of base point = 2^252 + 27742317777372353535851937790883648493 // XXX this should probably just be a big.Int -var primeOrder, _ = new(mod.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250989", "", 10) +var primeOrder, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250989", 10) // cofactor of the curve, as a ModInt -var cofactor = (&scalar{}).SetInt64(8) +var cofactor = new(big.Int).SetInt64(8) + +// order of the full group including the cofactor +var fullOrder = new(big.Int).Mul(primeOrder, cofactor) -// order of the full curve including the cofactor -//var fullOrder = new(big.Int).Mul(&primeOrder.V, &cofactor.V) +// scalar versions of these, usable for multiplication +var primeOrderScalar = newScalarInt(primeOrder) +var cofactorScalar = newScalarInt(primeOrder) // identity point var nullPoint = new(point).Null() diff --git a/group/edwards25519/curve.go b/group/edwards25519/curve.go index 8c27930f0..e336e0550 100644 --- a/group/edwards25519/curve.go +++ b/group/edwards25519/curve.go @@ -33,9 +33,9 @@ func (c *Curve) ScalarLen() int { return 32 } -// Create a new Scalar for the Ed25519 curve. +// Create a new Scalar for the prime-order subgroup of the Ed25519 curve. func (c *Curve) Scalar() kyber.Scalar { - //i := mod.NewInt64(0, &primeOrder.V) + //i := mod.NewInt64(0, primeOrder) //i.BO = mod.LittleEndian //return i diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index ffde7fbc7..9a4077a9c 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -138,7 +138,7 @@ func (P *point) Embed(data []byte, rand cipher.Stream) kyber.Point { // we can convert our point into one in the subgroup // simply by multiplying it by the cofactor. if data == nil { - P.Mul(cofactor, P) // multiply by cofactor + P.Mul(cofactorScalar, P) // multiply by cofactor if P.Equal(nullPoint) { continue // unlucky; try again } @@ -149,7 +149,7 @@ func (P *point) Embed(data []byte, rand cipher.Stream) kyber.Point { // we must simply check if the point is in the subgroup // and retry point generation until it is. var Q point - Q.Mul(primeOrder, P) + Q.Mul(primeOrderScalar, P) if Q.Equal(nullPoint) { return P // success } diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 1804815e7..3b63d136c 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -8,6 +8,7 @@ import ( "io" "errors" "crypto/cipher" + "math/big" "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/group/mod" @@ -54,11 +55,11 @@ func (s *scalar) setInt(i *mod.Int) kyber.Scalar { // Set to a small integer value func (s *scalar) SetInt64(v int64) kyber.Scalar { - return s.setInt(mod.NewInt64(v, &primeOrder.V)) + return s.setInt(mod.NewInt64(v, primeOrder)) } func (s *scalar) toInt() *mod.Int { - return mod.NewIntBytes(s.v[:], &primeOrder.V, mod.LittleEndian) + return mod.NewIntBytes(s.v[:], primeOrder, mod.LittleEndian) } // Set to the additive identity (0) @@ -117,14 +118,14 @@ func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { // Set to a fresh random or pseudo-random scalar func (s *scalar) Pick(rand cipher.Stream) kyber.Scalar { - i := mod.NewInt(random.Int(&primeOrder.V, rand), &primeOrder.V) + i := mod.NewInt(random.Int(primeOrder, rand), primeOrder) return s.setInt(i) } // SetBytes sets the scalar from a big-endian byte-slice func (s *scalar) SetBytes(b []byte) kyber.Scalar { // XXX handle simple and scReduce cases appropriately - return s.setInt(mod.NewIntBytes(b, &primeOrder.V, mod.BigEndian)) + return s.setInt(mod.NewIntBytes(b, primeOrder, mod.BigEndian)) } // Bytes returns a big-Endian representation of the scalar @@ -176,6 +177,11 @@ func (s *scalar) SetVarTime(varTime bool) bool { return old } +func newScalarInt(i *big.Int) *scalar { + s := scalar{} + s.setInt(mod.NewInt(i, fullOrder)) + return &s +} // Input: From 6eaf519a71f3fe79bed950d973abc2f23ff907a5 Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sun, 4 Jun 2017 10:49:48 +0200 Subject: [PATCH 04/31] fixed endianness loss bug in mod.Int.InitBytes --- group/edwards25519/scalar.go | 9 ++------- group/mod/int.go | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 3b63d136c..0e479082d 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -9,6 +9,8 @@ import ( "errors" "crypto/cipher" "math/big" + //"encoding/hex" + //"runtime/debug" "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/group/mod" @@ -105,13 +107,6 @@ func (s *scalar) Div(a, b kyber.Scalar) kyber.Scalar { // XXX not yet constant-time implementation; should be fixed func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { i := a.(*scalar).toInt() - println("A"+ i.String()) - i.Inv(i) - println("B"+ i.String()) - i.Inv(i) - println("C"+ i.String()) - i.Inv(i) - println("D"+ i.String()) i.Inv(i) return s.setInt(i) } diff --git a/group/mod/int.go b/group/mod/int.go index dcb105f40..163f38345 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -92,7 +92,7 @@ func (i *Int) Init64(v int64, m *big.Int) *Int { func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { i.M = m i.BO = byteOrder - i.V.SetBytes(a).Mod(&i.V, i.M) + i.SetBytes(a) return i } From a1133fc3e0c1310c3aaec02d1e6bdaa8b32b3959 Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sun, 4 Jun 2017 11:57:30 +0200 Subject: [PATCH 05/31] constant-time sub prototyped but not yet working --- group/edwards25519/scalar.go | 451 ++++++++++++++++++++++++++++++++++- 1 file changed, 449 insertions(+), 2 deletions(-) diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 0e479082d..2258ffdf2 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -9,7 +9,7 @@ import ( "errors" "crypto/cipher" "math/big" - //"encoding/hex" + "encoding/hex" //"runtime/debug" "gopkg.in/dedis/kyber.v1" @@ -84,7 +84,19 @@ func (s *scalar) Add(a, b kyber.Scalar) kyber.Scalar { // Set to the modular difference a - b func (s *scalar) Sub(a, b kyber.Scalar) kyber.Scalar { - panic("Sub not yet implemented") + + println("sub i1: ", hex.EncodeToString(a.(*scalar).v[:])) + println("sub i2: ", hex.EncodeToString(b.(*scalar).v[:])) + + var t1,t2 scalar + t1.Zero() + t2.Zero() + scSub(&s.v, &t1.v, &t2.v) + println("sub 0-0: ", hex.EncodeToString(s.v[:])) + + scSub(&s.v, &a.(*scalar).v, &b.(*scalar).v) + println("sub o: ", hex.EncodeToString(s.v[:])) + return s } // Set to the modular negation of scalar a @@ -1047,6 +1059,441 @@ func scAdd(s, a, c *[32]byte) { s[31] = byte(s11 >> 17) } +// Hacky scSub cobbled together rather sub-optimally from scMulAdd. +// +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (a-c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +// +func scSub(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := int64(1) + b1 := int64(0) + b2 := int64(0) + b3 := int64(0) + b4 := int64(0) + b5 := int64(0) + b6 := int64(0) + b7 := int64(0) + b8 := int64(0) + b9 := int64(0) + b10 := int64(0) + b11 := int64(0) + c0 := (2097151 & load3(c[:])) ^ 2097151 // one's complement + c1 := (2097151 & (load4(c[2:]) >> 5)) ^ 2097151 + c2 := (2097151 & (load3(c[5:]) >> 2)) ^ 2097151 + c3 := (2097151 & (load4(c[7:]) >> 7)) ^ 2097151 + c4 := (2097151 & (load4(c[10:]) >> 4)) ^ 2097151 + c5 := (2097151 & (load3(c[13:]) >> 1)) ^ 2097151 + c6 := (2097151 & (load4(c[15:]) >> 6)) ^ 2097151 + c7 := (2097151 & (load3(c[18:]) >> 3)) ^ 2097151 + c8 := (2097151 & load3(c[21:])) ^ 2097151 + c9 := (2097151 & (load4(c[23:]) >> 5)) ^ 2097151 + c10 := (2097151 & (load3(c[26:]) >> 2)) ^ 2097151 + c11 := (load4(c[28:]) >> 7) ^ 33554431 + var carry [23]int64 + + s0 := 486116 + c0 + a0*b0 + s1 := 1334163 + c1 + a0*b1 + a1*b0 + s2 := 673011 + c2 + a0*b2 + a1*b1 + a2*b0 + s3 := 287006 + c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + s4 := 47304 + c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + s5 := 1869906 + c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + s6 := 4 + c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + s7 := 0 + c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + s8 := 0 + c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + s9 := 0 + c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + s10 := 0 + c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + s11 := 0 + c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + s12 := 15 + a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 + s20 := a9*b11 + a10*b10 + a11*b9 + s21 := a10*b11 + a11*b10 + s22 := a11 * b11 + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + // Hacky scMul cobbled together rather sub-optimally from scMulAdd. // // Input: From 51b50f6306e61e4d4621703bffc900a9430d23e4 Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sun, 4 Jun 2017 15:45:48 +0200 Subject: [PATCH 06/31] got new constant-time scalars working it seems --- group/edwards25519/const.go | 2 +- group/edwards25519/scalar.go | 74 +++++++++++++++++------------------- group/mod/int.go | 4 +- util/test/test.go | 2 - 4 files changed, 37 insertions(+), 45 deletions(-) diff --git a/group/edwards25519/const.go b/group/edwards25519/const.go index 7800d53c0..6d58e7fe0 100644 --- a/group/edwards25519/const.go +++ b/group/edwards25519/const.go @@ -23,7 +23,7 @@ var fullOrder = new(big.Int).Mul(primeOrder, cofactor) // scalar versions of these, usable for multiplication var primeOrderScalar = newScalarInt(primeOrder) -var cofactorScalar = newScalarInt(primeOrder) +var cofactorScalar = newScalarInt(cofactor) // identity point var nullPoint = new(point).Null() diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 2258ffdf2..bbb2d3592 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -9,8 +9,6 @@ import ( "errors" "crypto/cipher" "math/big" - "encoding/hex" - //"runtime/debug" "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/group/mod" @@ -84,24 +82,16 @@ func (s *scalar) Add(a, b kyber.Scalar) kyber.Scalar { // Set to the modular difference a - b func (s *scalar) Sub(a, b kyber.Scalar) kyber.Scalar { - - println("sub i1: ", hex.EncodeToString(a.(*scalar).v[:])) - println("sub i2: ", hex.EncodeToString(b.(*scalar).v[:])) - - var t1,t2 scalar - t1.Zero() - t2.Zero() - scSub(&s.v, &t1.v, &t2.v) - println("sub 0-0: ", hex.EncodeToString(s.v[:])) - scSub(&s.v, &a.(*scalar).v, &b.(*scalar).v) - println("sub o: ", hex.EncodeToString(s.v[:])) return s } // Set to the modular negation of scalar a func (s *scalar) Neg(a kyber.Scalar) kyber.Scalar { - panic("Neg not yet implemented") + var z scalar + z.Zero() + scSub(&s.v, &z.v, &a.(*scalar).v) + return s } // Set to the modular product of scalars a and b @@ -111,8 +101,12 @@ func (s *scalar) Mul(a, b kyber.Scalar) kyber.Scalar { } // Set to the modular division of scalar a by scalar b +// XXX not yet constant-time implementation; should be fixed func (s *scalar) Div(a, b kyber.Scalar) kyber.Scalar { - panic("Div not yet implemented") + var i scalar + i.Inv(b) + scMul(&s.v, &a.(*scalar).v, &i.v) + return s } // Set to the modular inverse of scalar a @@ -1094,33 +1088,33 @@ func scSub(s, a, c *[32]byte) { b9 := int64(0) b10 := int64(0) b11 := int64(0) - c0 := (2097151 & load3(c[:])) ^ 2097151 // one's complement - c1 := (2097151 & (load4(c[2:]) >> 5)) ^ 2097151 - c2 := (2097151 & (load3(c[5:]) >> 2)) ^ 2097151 - c3 := (2097151 & (load4(c[7:]) >> 7)) ^ 2097151 - c4 := (2097151 & (load4(c[10:]) >> 4)) ^ 2097151 - c5 := (2097151 & (load3(c[13:]) >> 1)) ^ 2097151 - c6 := (2097151 & (load4(c[15:]) >> 6)) ^ 2097151 - c7 := (2097151 & (load3(c[18:]) >> 3)) ^ 2097151 - c8 := (2097151 & load3(c[21:])) ^ 2097151 - c9 := (2097151 & (load4(c[23:]) >> 5)) ^ 2097151 - c10 := (2097151 & (load3(c[26:]) >> 2)) ^ 2097151 - c11 := (load4(c[28:]) >> 7) ^ 33554431 + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) var carry [23]int64 - s0 := 486116 + c0 + a0*b0 - s1 := 1334163 + c1 + a0*b1 + a1*b0 - s2 := 673011 + c2 + a0*b2 + a1*b1 + a2*b0 - s3 := 287006 + c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 - s4 := 47304 + c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 - s5 := 1869906 + c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 - s6 := 4 + c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 - s7 := 0 + c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 - s8 := 0 + c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 - s9 := 0 + c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 - s10 := 0 + c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 - s11 := 0 + c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 - s12 := 15 + a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + s0 := 1916624 - c0 + a0*b0 + s1 := 863866 - c1 + a0*b1 + a1*b0 + s2 := 18828 - c2 + a0*b2 + a1*b1 + a2*b0 + s3 := 1284811 - c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + s4 := 2007799 - c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + s5 := 456654 - c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + s6 := 5 - c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + s7 := 0 - c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + s8 := 0 - c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + s9 := 0 - c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + s10 := 0 - c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + s11 := 0 - c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + s12 := 16 + a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 diff --git a/group/mod/int.go b/group/mod/int.go index 163f38345..9bccdf7b2 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -2,7 +2,6 @@ package mod import ( "crypto/cipher" - "encoding/hex" "errors" "io" "math/big" @@ -109,7 +108,8 @@ func (i *Int) InitString(n, d string, base int, m *big.Int) *Int { // Return the Int's integer value in decimal string representation. func (i *Int) String() string { - return hex.EncodeToString(i.V.Bytes()) + return i.V.String() + //return hex.EncodeToString(i.V.Bytes()) } // Set value to a rational fraction n/d represented by a pair of strings. diff --git a/util/test/test.go b/util/test/test.go index a8c373754..93bb9e241 100644 --- a/util/test/test.go +++ b/util/test/test.go @@ -159,9 +159,7 @@ func testGroup(g kyber.Group, rand cipher.Stream) []kyber.Point { panic("oops, generator additive identity doesn't work") } if g.PrimeOrder() { // secret.Inv works only in prime-order groups - println("gen", gen.String()) ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp) - println("after", ptmp.String()) if !ptmp.Equal(gen) { panic("oops, generator multiplicative identity doesn't work") } From 6bb64f703b0b4b813781f35b13d3ae7cfd8d54a5 Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sun, 4 Jun 2017 16:08:47 +0200 Subject: [PATCH 07/31] fixed arithmetic-in-place bug in projective edwards code --- group/curve25519/el1.go | 2 +- group/curve25519/el2.go | 2 +- group/curve25519/ext.go | 6 ++++++ group/curve25519/proj.go | 34 ++++++++++++++++++++++++---------- group/mod/int_test.go | 6 +++--- group/nist/curve.go | 6 ++++++ group/nist/residue.go | 7 +++++++ 7 files changed, 48 insertions(+), 15 deletions(-) diff --git a/group/curve25519/el1.go b/group/curve25519/el1.go index f561a0c77..870850338 100644 --- a/group/curve25519/el1.go +++ b/group/curve25519/el1.go @@ -89,7 +89,7 @@ func (el *el1param) HideDecode(P point, rep []byte) { b := make([]byte, l) copy(b, rep) b[0] &^= el.padmask() // mask off the padding bits - t.InitBytes(b, &ec.P) + t.InitBytes(b, &ec.P, mod.BigEndian) // u = (1-t)/(1+t) u.Div(t1.Sub(&ec.one, &t), t2.Add(&ec.one, &t)) diff --git a/group/curve25519/el2.go b/group/curve25519/el2.go index a682656f9..b932301cf 100644 --- a/group/curve25519/el2.go +++ b/group/curve25519/el2.go @@ -123,7 +123,7 @@ func (el *el2param) HideDecode(P point, rep []byte) { buf := make([]byte, l) copy(buf, rep) buf[0] &^= el.padmask() // mask off the padding bits - r.InitBytes(buf, &ec.P) + r.InitBytes(buf, &ec.P, mod.BigEndian) // v = -A/(1+ur^2) v.Mul(&r, &r).Mul(&el.u, &v).Add(&ec.one, &v).Div(&el.negA, &v) diff --git a/group/curve25519/ext.go b/group/curve25519/ext.go index 3151f0516..4d70127d3 100644 --- a/group/curve25519/ext.go +++ b/group/curve25519/ext.go @@ -267,6 +267,12 @@ func (P *extPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { return P } +// This implementation only supports variable-time operations +func (P *extPoint) SetVarTime(varTime bool) bool { + return true +} + + // ExtendedCurve implements Twisted Edwards curves // using projective coordinate representation (X:Y:Z), // satisfying the identities x = X/Z, y = Y/Z. diff --git a/group/curve25519/proj.go b/group/curve25519/proj.go index 1ca2beea7..dfefdb550 100644 --- a/group/curve25519/proj.go +++ b/group/curve25519/proj.go @@ -148,8 +148,7 @@ func (P *projPoint) Add(CP1, CP2 kyber.Point) kyber.Point { P2 := CP2.(*projPoint) X1, Y1, Z1 := &P1.X, &P1.Y, &P1.Z X2, Y2, Z2 := &P2.X, &P2.Y, &P2.Z - X3, Y3, Z3 := &P.X, &P.Y, &P.Z - var A, B, C, D, E, F, G mod.Int + var A, B, C, D, E, F, G, X3, Y3, Z3 mod.Int A.Mul(Z1, Z2) B.Mul(&A, &A) @@ -158,10 +157,15 @@ func (P *projPoint) Add(CP1, CP2 kyber.Point) kyber.Point { E.Mul(&C, &D).Mul(&P.c.d, &E) F.Sub(&B, &E) G.Add(&B, &E) - X3.Add(X1, Y1).Mul(X3, Z3.Add(X2, Y2)).Sub(X3, &C).Sub(X3, &D). - Mul(&F, X3).Mul(&A, X3) - Y3.Mul(&P.c.a, &C).Sub(&D, Y3).Mul(&G, Y3).Mul(&A, Y3) + X3.Add(X1, Y1).Mul(&X3, Z3.Add(X2, Y2)).Sub(&X3, &C).Sub(&X3, &D). + Mul(&F, &X3).Mul(&A, &X3) + Y3.Mul(&P.c.a, &C).Sub(&D, &Y3).Mul(&G, &Y3).Mul(&A, &Y3) Z3.Mul(&F, &G) + + P.c = P1.c + P.X.Set(&X3) + P.Y.Set(&Y3) + P.Z.Set(&Z3) return P } @@ -171,8 +175,7 @@ func (P *projPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { P2 := CP2.(*projPoint) X1, Y1, Z1 := &P1.X, &P1.Y, &P1.Z X2, Y2, Z2 := &P2.X, &P2.Y, &P2.Z - X3, Y3, Z3 := &P.X, &P.Y, &P.Z - var A, B, C, D, E, F, G mod.Int + var A, B, C, D, E, F, G, X3, Y3, Z3 mod.Int A.Mul(Z1, Z2) B.Mul(&A, &A) @@ -181,10 +184,15 @@ func (P *projPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { E.Mul(&C, &D).Mul(&P.c.d, &E) F.Add(&B, &E) G.Sub(&B, &E) - X3.Add(X1, Y1).Mul(X3, Z3.Sub(Y2, X2)).Add(X3, &C).Sub(X3, &D). - Mul(&F, X3).Mul(&A, X3) - Y3.Mul(&P.c.a, &C).Add(&D, Y3).Mul(&G, Y3).Mul(&A, Y3) + X3.Add(X1, Y1).Mul(&X3, Z3.Sub(Y2, X2)).Add(&X3, &C).Sub(&X3, &D). + Mul(&F, &X3).Mul(&A, &X3) + Y3.Mul(&P.c.a, &C).Add(&D, &Y3).Mul(&G, &Y3).Mul(&A, &Y3) Z3.Mul(&F, &G) + + P.c = P1.c + P.X.Set(&X3) + P.Y.Set(&Y3) + P.Z.Set(&Z3) return P } @@ -238,6 +246,12 @@ func (P *projPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { return P } +// This implementation only supports variable-time operations +func (P *projPoint) SetVarTime(varTime bool) bool { + return true +} + + // ProjectiveCurve implements Twisted Edwards curves // using projective coordinate representation (X:Y:Z), // satisfying the identities x = X/Z, y = Y/Z. diff --git a/group/mod/int_test.go b/group/mod/int_test.go index aa15ceca8..d60773aa2 100644 --- a/group/mod/int_test.go +++ b/group/mod/int_test.go @@ -59,7 +59,7 @@ func TestIntEndianBytes(t *testing.T) { v, err := hex.DecodeString("10") assert.Nil(t, err) - i := new(Int).InitBytes(v, moduloI) + i := new(Int).InitBytes(v, moduloI, BigEndian) assert.Equal(t, 2, i.MarshalSize()) assert.NotPanics(t, func() { i.LittleEndian(2, 2) }) @@ -69,7 +69,7 @@ func TestInits(t *testing.T) { i1 := NewInt64(int64(65500), big.NewInt(65535)) i2 := NewInt(&i1.V, i1.M) assert.True(t, i1.Equal(i2)) - i3 := NewIntBytes(i1.Bytes(), i1.M) + i3 := NewIntBytes(i1.Bytes(), i1.M, BigEndian) assert.True(t, i1.Equal(i3)) i4 := NewIntString(i1.String(), "", 16, i1.M) assert.True(t, i1.Equal(i4)) @@ -77,7 +77,7 @@ func TestInits(t *testing.T) { func TestIntClone(t *testing.T) { moduloI := new(big.Int).SetBytes([]byte{0x10, 0}) - base := new(Int).InitBytes([]byte{0x10}, moduloI) + base := new(Int).InitBytes([]byte{0x10}, moduloI, BigEndian) clone := base.Clone() clone.Add(clone, clone) diff --git a/group/nist/curve.go b/group/nist/curve.go index c6a928662..8edf683b5 100644 --- a/group/nist/curve.go +++ b/group/nist/curve.go @@ -212,6 +212,12 @@ func (p *curvePoint) UnmarshalFrom(r io.Reader) (int, error) { return marshalling.PointUnmarshalFrom(p, r) } +// This implementation only supports variable-time operations +func (P *curvePoint) SetVarTime(varTime bool) bool { + return true +} + + // interface for curve-specifc mathematical functions type curveOps interface { sqrt(y *big.Int) *big.Int diff --git a/group/nist/residue.go b/group/nist/residue.go index 396b38db5..9708de803 100644 --- a/group/nist/residue.go +++ b/group/nist/residue.go @@ -164,6 +164,13 @@ func (p *residuePoint) UnmarshalFrom(r io.Reader) (int, error) { return marshalling.PointUnmarshalFrom(p, r) } +// This implementation only supports variable-time operations +func (P *residuePoint) SetVarTime(varTime bool) bool { + return true +} + + + /* A ResidueGroup represents a DSA-style modular integer arithmetic group, defined by two primes P and Q and an integer R, such that P = Q*R+1. From bad113518b2799d2bd2f74d2ca46a5697d3ad7bd Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sun, 4 Jun 2017 16:23:16 +0200 Subject: [PATCH 08/31] simplify the scalar code just a bit --- group/edwards25519/scalar.go | 116 ++++++++++++++--------------------- 1 file changed, 46 insertions(+), 70 deletions(-) diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index bbb2d3592..13f51d719 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -641,18 +641,6 @@ func scAdd(s, a, c *[32]byte) { a9 := 2097151 & (load4(a[23:]) >> 5) a10 := 2097151 & (load3(a[26:]) >> 2) a11 := (load4(a[28:]) >> 7) - b0 := int64(1) - b1 := int64(0) - b2 := int64(0) - b3 := int64(0) - b4 := int64(0) - b5 := int64(0) - b6 := int64(0) - b7 := int64(0) - b8 := int64(0) - b9 := int64(0) - b10 := int64(0) - b11 := int64(0) c0 := 2097151 & load3(c[:]) c1 := 2097151 & (load4(c[2:]) >> 5) c2 := 2097151 & (load3(c[5:]) >> 2) @@ -667,29 +655,29 @@ func scAdd(s, a, c *[32]byte) { c11 := (load4(c[28:]) >> 7) var carry [23]int64 - s0 := c0 + a0*b0 - s1 := c1 + a0*b1 + a1*b0 - s2 := c2 + a0*b2 + a1*b1 + a2*b0 - s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 - s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 - s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 - s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 - s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 - s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 - s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 - s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 - s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 - s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 - s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 - s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 - s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 - s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 - s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 - s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 - s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 - s20 := a9*b11 + a10*b10 + a11*b9 - s21 := a10*b11 + a11*b10 - s22 := a11 * b11 + s0 := c0 + a0 + s1 := c1 + a1 + s2 := c2 + a2 + s3 := c3 + a3 + s4 := c4 + a4 + s5 := c5 + a5 + s6 := c6 + a6 + s7 := c7 + a7 + s8 := c8 + a8 + s9 := c9 + a9 + s10 := c10 + a10 + s11 := c11 + a11 + s12 := int64(0) + s13 := int64(0) + s14 := int64(0) + s15 := int64(0) + s16 := int64(0) + s17 := int64(0) + s18 := int64(0) + s19 := int64(0) + s20 := int64(0) + s21 := int64(0) + s22 := int64(0) s23 := int64(0) carry[0] = (s0 + (1 << 20)) >> 21 @@ -1076,18 +1064,6 @@ func scSub(s, a, c *[32]byte) { a9 := 2097151 & (load4(a[23:]) >> 5) a10 := 2097151 & (load3(a[26:]) >> 2) a11 := (load4(a[28:]) >> 7) - b0 := int64(1) - b1 := int64(0) - b2 := int64(0) - b3 := int64(0) - b4 := int64(0) - b5 := int64(0) - b6 := int64(0) - b7 := int64(0) - b8 := int64(0) - b9 := int64(0) - b10 := int64(0) - b11 := int64(0) c0 := 2097151 & load3(c[:]) c1 := 2097151 & (load4(c[2:]) >> 5) c2 := 2097151 & (load3(c[5:]) >> 2) @@ -1102,29 +1078,29 @@ func scSub(s, a, c *[32]byte) { c11 := (load4(c[28:]) >> 7) var carry [23]int64 - s0 := 1916624 - c0 + a0*b0 - s1 := 863866 - c1 + a0*b1 + a1*b0 - s2 := 18828 - c2 + a0*b2 + a1*b1 + a2*b0 - s3 := 1284811 - c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 - s4 := 2007799 - c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 - s5 := 456654 - c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 - s6 := 5 - c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 - s7 := 0 - c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 - s8 := 0 - c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 - s9 := 0 - c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 - s10 := 0 - c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 - s11 := 0 - c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 - s12 := 16 + a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 - s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 - s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 - s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 - s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 - s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 - s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 - s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 - s20 := a9*b11 + a10*b10 + a11*b9 - s21 := a10*b11 + a11*b10 - s22 := a11 * b11 + s0 := 1916624 - c0 + a0 + s1 := 863866 - c1 + a1 + s2 := 18828 - c2 + a2 + s3 := 1284811 - c3 + a3 + s4 := 2007799 - c4 + a4 + s5 := 456654 - c5 + a5 + s6 := 5 - c6 + a6 + s7 := 0 - c7 + a7 + s8 := 0 - c8 + a8 + s9 := 0 - c9 + a9 + s10 := 0 - c10 + a10 + s11 := 0 - c11 + a11 + s12 := int64(16) + s13 := int64(0) + s14 := int64(0) + s15 := int64(0) + s16 := int64(0) + s17 := int64(0) + s18 := int64(0) + s19 := int64(0) + s20 := int64(0) + s21 := int64(0) + s22 := int64(0) s23 := int64(0) carry[0] = (s0 + (1 << 20)) >> 21 From 31a5cbb501101408aaa248da89711665dbcd1013 Mon Sep 17 00:00:00 2001 From: Bryan Ford Date: Sun, 4 Jun 2017 16:29:49 +0200 Subject: [PATCH 09/31] fix Clone state sharing bugs --- group/curve25519/ext.go | 14 +++++++------- group/curve25519/proj.go | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/group/curve25519/ext.go b/group/curve25519/ext.go index 4d70127d3..5425e4c6a 100644 --- a/group/curve25519/ext.go +++ b/group/curve25519/ext.go @@ -102,13 +102,13 @@ func (P *extPoint) Set(CP2 kyber.Point) kyber.Point { } func (P *extPoint) Clone() kyber.Point { - return &extPoint{ - c: P.c, - X: P.X, - Y: P.Y, - Z: P.Z, - T: P.T, - } + P2 := extPoint{} + P2.c = P.c + P2.X.Set(&P.X) + P2.Y.Set(&P.Y) + P2.Z.Set(&P.Z) + P2.T.Set(&P.T) + return &P2 } func (P *extPoint) Null() kyber.Point { diff --git a/group/curve25519/proj.go b/group/curve25519/proj.go index dfefdb550..a24b9ad5f 100644 --- a/group/curve25519/proj.go +++ b/group/curve25519/proj.go @@ -92,12 +92,12 @@ func (P *projPoint) Set(CP2 kyber.Point) kyber.Point { } func (P *projPoint) Clone() kyber.Point { - return &projPoint{ - c: P.c, - X: P.X, - Y: P.Y, - Z: P.Z, - } + P2 := projPoint{} + P2.c = P.c + P2.X.Set(&P.X) + P2.Y.Set(&P.Y) + P2.Z.Set(&P.Z) + return &P2 } func (P *projPoint) Null() kyber.Point { From c6cdb8094d99ba9d4f388496cbb28bdabe0157ca Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Tue, 13 Jun 2017 17:31:18 +0200 Subject: [PATCH 10/31] constant time inversion --- group/edwards25519/const.go | 7 +++++++ group/edwards25519/scalar.go | 37 ++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/group/edwards25519/const.go b/group/edwards25519/const.go index 6d58e7fe0..59a0b54bb 100644 --- a/group/edwards25519/const.go +++ b/group/edwards25519/const.go @@ -15,6 +15,13 @@ var prime, _ = new(big.Int).SetString("57896044618658097711785492504343953926634 // XXX this should probably just be a big.Int var primeOrder, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250989", 10) +// `l_minus_2` is the order of base point minus two, i.e. 2^252 + +// 27742317777372353535851937790883648493 - 2, in little-endian form +// This is needed to compute constant time modular inversion of scalars. +var l_minus_2_big, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250987", 10) + +//var l_minus_2, _ = hex.DecodeString("1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3eb") + // cofactor of the curve, as a ModInt var cofactor = new(big.Int).SetInt64(8) diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 13f51d719..2e431b1a9 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -5,17 +5,17 @@ package edwards25519 import ( - "io" - "errors" "crypto/cipher" + "errors" + "io" "math/big" "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/group/mod" "gopkg.in/dedis/kyber.v1/util/bytes" - "gopkg.in/dedis/kyber.v1/util/subtle" "gopkg.in/dedis/kyber.v1/util/marshalling" "gopkg.in/dedis/kyber.v1/util/random" + "gopkg.in/dedis/kyber.v1/util/subtle" ) // This code is a port of the public domain, "ref10" implementation of ed25519 @@ -23,9 +23,8 @@ import ( // The scalars are GF(2^252 + 27742317777372353535851937790883648493). - type scalar struct { - v [32]byte + v [32]byte varTime bool } @@ -33,7 +32,7 @@ type scalar struct { func (s *scalar) Equal(s2 kyber.Scalar) bool { v1 := s.v[:] v2 := s2.(*scalar).v[:] - return subtle.ConstantTimeCompare(v1,v2) != 0 + return subtle.ConstantTimeCompare(v1, v2) != 0 } // Set equal to another Scalar a @@ -101,7 +100,6 @@ func (s *scalar) Mul(a, b kyber.Scalar) kyber.Scalar { } // Set to the modular division of scalar a by scalar b -// XXX not yet constant-time implementation; should be fixed func (s *scalar) Div(a, b kyber.Scalar) kyber.Scalar { var i scalar i.Inv(b) @@ -110,11 +108,27 @@ func (s *scalar) Div(a, b kyber.Scalar) kyber.Scalar { } // Set to the modular inverse of scalar a -// XXX not yet constant-time implementation; should be fixed func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { - i := a.(*scalar).toInt() - i.Inv(i) - return s.setInt(i) + var res scalar + res.One() + ac := a.(*scalar) + // Modular inversion in a multiplicative group is a^(phi(m)-1) = a^-1 mod m + // Since m is prime, phi(m) = m - 1 => a^(m-2) = a^-1 mod m. + // The inverse is computed using the exponentation-and-square algorithm. + // Implementation is constant time regarding the value a, it only depends on + // the modulo. + for i := 255; i >= 0; i-- { + //var bit = b & (1 << uint(8-i)) + bit := l_minus_2_big.Bit(i) + // square step + scMul(&res.v, &res.v, &res.v) + if bit == 1 { + // multiply step + scMul(&res.v, &res.v, &ac.v) + } + } + s.v = res.v + return s } // Set to a fresh random or pseudo-random scalar @@ -184,7 +198,6 @@ func newScalarInt(i *big.Int) *scalar { return &s } - // Input: // a[0]+256*a[1]+...+256^31*a[31] = a // b[0]+256*b[1]+...+256^31*b[31] = b From 9e83790e2d8267ea7ab1debac514a4425b68eeec Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Wed, 14 Jun 2017 09:22:46 +0200 Subject: [PATCH 11/31] .travis.yml changed import path to gopkg.in/dedis/kyber.v1 --- .travis.yml | 3 +++ group/edwards25519/scalar.go | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a1d421bd8..2c1b3ac6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,14 @@ language: go go: - tip +go_import_path: gopkg.in/dedis/kyber.v1 + install: - go get -t ./... - go get golang.org/x/tools/cmd/cover - go get github.com/mattn/goveralls + script: - make test diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 2e431b1a9..c714be1e0 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -118,7 +118,6 @@ func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { // Implementation is constant time regarding the value a, it only depends on // the modulo. for i := 255; i >= 0; i-- { - //var bit = b & (1 << uint(8-i)) bit := l_minus_2_big.Bit(i) // square step scMul(&res.v, &res.v, &res.v) From 7d5f0fd2ba45932774ab9b6f6a00459e417496f8 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Wed, 14 Jun 2017 09:33:17 +0200 Subject: [PATCH 12/31] flag added on nist/ and curve25519/ --- group/curve25519/basic.go | 2 +- group/curve25519/basic_test.go | 2 +- group/curve25519/curve.go | 2 ++ group/curve25519/curve_test.go | 2 ++ group/curve25519/el1.go | 2 ++ group/curve25519/el2.go | 2 ++ group/curve25519/ext.go | 3 ++- group/curve25519/param.go | 3 +++ group/curve25519/proj.go | 3 ++- group/curve25519/suite.go | 2 ++ group/nist/curve.go | 3 ++- group/nist/doc.go | 5 +++++ group/nist/group_test.go | 2 ++ group/nist/p256.go | 2 ++ group/nist/qrsuite.go | 2 ++ group/nist/residue.go | 4 ++-- group/nist/suite.go | 2 ++ 17 files changed, 36 insertions(+), 7 deletions(-) diff --git a/group/curve25519/basic.go b/group/curve25519/basic.go index 5f7356668..d8cf26a10 100644 --- a/group/curve25519/basic.go +++ b/group/curve25519/basic.go @@ -1,4 +1,4 @@ -// +build experimental +// +build experimental vartime package curve25519 diff --git a/group/curve25519/basic_test.go b/group/curve25519/basic_test.go index cc301a789..19bc030f2 100644 --- a/group/curve25519/basic_test.go +++ b/group/curve25519/basic_test.go @@ -1,4 +1,4 @@ -// +build experimental +// +build experimental vartime package curve25519 diff --git a/group/curve25519/curve.go b/group/curve25519/curve.go index 685a17518..0fbc8de26 100644 --- a/group/curve25519/curve.go +++ b/group/curve25519/curve.go @@ -1,3 +1,5 @@ +// +build vartime + package curve25519 import ( diff --git a/group/curve25519/curve_test.go b/group/curve25519/curve_test.go index 47e4ec8a9..4022bea52 100644 --- a/group/curve25519/curve_test.go +++ b/group/curve25519/curve_test.go @@ -1,3 +1,5 @@ +// +build vartime + package curve25519 import ( diff --git a/group/curve25519/el1.go b/group/curve25519/el1.go index 870850338..4e7ed3985 100644 --- a/group/curve25519/el1.go +++ b/group/curve25519/el1.go @@ -1,3 +1,5 @@ +// +build vartime + package curve25519 import ( diff --git a/group/curve25519/el2.go b/group/curve25519/el2.go index b932301cf..a3f16cae5 100644 --- a/group/curve25519/el2.go +++ b/group/curve25519/el2.go @@ -1,3 +1,5 @@ +// +build vartime + package curve25519 import ( diff --git a/group/curve25519/ext.go b/group/curve25519/ext.go index 5425e4c6a..f0089202e 100644 --- a/group/curve25519/ext.go +++ b/group/curve25519/ext.go @@ -1,3 +1,5 @@ +// +build vartime + package curve25519 import ( @@ -272,7 +274,6 @@ func (P *extPoint) SetVarTime(varTime bool) bool { return true } - // ExtendedCurve implements Twisted Edwards curves // using projective coordinate representation (X:Y:Z), // satisfying the identities x = X/Z, y = Y/Z. diff --git a/group/curve25519/param.go b/group/curve25519/param.go index cacd2910d..699d25183 100644 --- a/group/curve25519/param.go +++ b/group/curve25519/param.go @@ -12,6 +12,9 @@ // For details see Bernstein et al, "Twisted Edwards Curves", // http://eprint.iacr.org/2008/013.pdf // + +// +build vartime + package curve25519 import ( diff --git a/group/curve25519/proj.go b/group/curve25519/proj.go index a24b9ad5f..e35785fd2 100644 --- a/group/curve25519/proj.go +++ b/group/curve25519/proj.go @@ -1,3 +1,5 @@ +// +build vartime + package curve25519 import ( @@ -251,7 +253,6 @@ func (P *projPoint) SetVarTime(varTime bool) bool { return true } - // ProjectiveCurve implements Twisted Edwards curves // using projective coordinate representation (X:Y:Z), // satisfying the identities x = X/Z, y = Y/Z. diff --git a/group/curve25519/suite.go b/group/curve25519/suite.go index c36af9ab6..6220e29c6 100644 --- a/group/curve25519/suite.go +++ b/group/curve25519/suite.go @@ -1,3 +1,5 @@ +// +build vartime + package curve25519 import ( diff --git a/group/nist/curve.go b/group/nist/curve.go index 8edf683b5..0743ca516 100644 --- a/group/nist/curve.go +++ b/group/nist/curve.go @@ -1,3 +1,5 @@ +// +build vartime + package nist import ( @@ -217,7 +219,6 @@ func (P *curvePoint) SetVarTime(varTime bool) bool { return true } - // interface for curve-specifc mathematical functions type curveOps interface { sqrt(y *big.Int) *big.Int diff --git a/group/nist/doc.go b/group/nist/doc.go index baf872e11..da708f7a9 100644 --- a/group/nist/doc.go +++ b/group/nist/doc.go @@ -1,3 +1,8 @@ // Package nist implements cryptographic groups and ciphersuites // based on the NIST standards, using Go's built-in crypto library. +// Since that package does not implements constant time arithmetic operations +// yet, it must be compiled with the "vartime" compilation flag. + +// +build vartime + package nist diff --git a/group/nist/group_test.go b/group/nist/group_test.go index 4de29fa7a..2f9f67894 100644 --- a/group/nist/group_test.go +++ b/group/nist/group_test.go @@ -1,3 +1,5 @@ +// build vartime + package nist import ( diff --git a/group/nist/p256.go b/group/nist/p256.go index 68bca915f..8a2b23870 100644 --- a/group/nist/p256.go +++ b/group/nist/p256.go @@ -1,3 +1,5 @@ +// +build vartime + package nist import ( diff --git a/group/nist/qrsuite.go b/group/nist/qrsuite.go index 2c2fd832c..07c3d58a9 100644 --- a/group/nist/qrsuite.go +++ b/group/nist/qrsuite.go @@ -1,3 +1,5 @@ +// +build vartime + package nist import ( diff --git a/group/nist/residue.go b/group/nist/residue.go index 9708de803..24bc5251e 100644 --- a/group/nist/residue.go +++ b/group/nist/residue.go @@ -1,3 +1,5 @@ +// +build vartime + package nist import ( @@ -169,8 +171,6 @@ func (P *residuePoint) SetVarTime(varTime bool) bool { return true } - - /* A ResidueGroup represents a DSA-style modular integer arithmetic group, defined by two primes P and Q and an integer R, such that P = Q*R+1. diff --git a/group/nist/suite.go b/group/nist/suite.go index 8c3876d60..d2860cbf0 100644 --- a/group/nist/suite.go +++ b/group/nist/suite.go @@ -1,3 +1,5 @@ +// +build vartime + package nist import ( From a76faaf0aa519c35b6486b3866700a64e9fc8b73 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 15 Jun 2017 13:26:23 +0200 Subject: [PATCH 13/31] removing vartime method from Scalar --- group.go | 6 ------ group/edwards25519/scalar.go | 9 +-------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/group.go b/group.go index e37c4890e..c53b3d74f 100644 --- a/group.go +++ b/group.go @@ -59,12 +59,6 @@ type Scalar interface { // Bytes returns a big-Endian representation of the scalar Bytes() []byte - - // Allow or disallow use of faster variable-time implementations - // of operations on this Point, returning the old flag value. - // This flag always defaults to false (constant-time only) - // in implementations that can provide constant-time operations. - SetVarTime(varTime bool) bool } /* diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index c714be1e0..195b2fd50 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -24,8 +24,7 @@ import ( // The scalars are GF(2^252 + 27742317777372353535851937790883648493). type scalar struct { - v [32]byte - varTime bool + v [32]byte } // Equality test for two Scalars derived from the same Group @@ -185,12 +184,6 @@ func (s *scalar) UnmarshalFrom(r io.Reader) (int, error) { return marshalling.ScalarUnmarshalFrom(s, r) } -func (s *scalar) SetVarTime(varTime bool) bool { - old := s.varTime - s.varTime = varTime - return old -} - func newScalarInt(i *big.Int) *scalar { s := scalar{} s.setInt(mod.NewInt(i, fullOrder)) From f36ae2e9f135c8da791586dd1c6b895df4001468 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 15 Jun 2017 13:43:28 +0200 Subject: [PATCH 14/31] adding vartime to curve25519 test --- group/nist/group_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/group/nist/group_test.go b/group/nist/group_test.go index 2f9f67894..303380817 100644 --- a/group/nist/group_test.go +++ b/group/nist/group_test.go @@ -1,4 +1,4 @@ -// build vartime +// +build vartime package nist From 59a897fc4c51c40c8567c81b27d2f0db0e85b1a1 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 15 Jun 2017 14:58:02 +0200 Subject: [PATCH 15/31] changing to ed25519 example + fixing endianness in ed25519 scalar --- examples/dh_test.go | 4 +- examples/enc_test.go | 4 +- examples/sig_test.go | 12 +-- group/edwards25519/scalar.go | 8 +- group/edwards25519/suite.go | 4 + proof/deniable_test.go | 4 +- proof/hash_test.go | 82 ++++++++----------- proof/proof_test.go | 48 +++++------- sign/anon/enc_test.go | 43 +++++----- sign/anon/sig_test.go | 148 ++++++++++++++++------------------- 10 files changed, 161 insertions(+), 196 deletions(-) diff --git a/examples/dh_test.go b/examples/dh_test.go index 023f365bb..197bf15f8 100644 --- a/examples/dh_test.go +++ b/examples/dh_test.go @@ -1,7 +1,7 @@ package examples import ( - "gopkg.in/dedis/kyber.v1/group/nist" + "gopkg.in/dedis/kyber.v1/group/edwards25519" "gopkg.in/dedis/kyber.v1/util/random" ) @@ -15,7 +15,7 @@ simply by changing the first line that picks the suite. func Example_diffieHellman() { // Crypto setup: NIST-standardized P256 curve with AES-128 and SHA-256 - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) // Alice's public/private keypair a := suite.Scalar().Pick(random.Stream) // Alice's private key diff --git a/examples/enc_test.go b/examples/enc_test.go index 4d82b5a20..b171d18a2 100644 --- a/examples/enc_test.go +++ b/examples/enc_test.go @@ -2,7 +2,7 @@ package examples import ( "gopkg.in/dedis/kyber.v1" - "gopkg.in/dedis/kyber.v1/group/nist" + "gopkg.in/dedis/kyber.v1/group/edwards25519" "gopkg.in/dedis/kyber.v1/util/random" ) @@ -58,7 +58,7 @@ see for example anon.Encrypt, which encrypts a message for one of several possible receivers forming an explicit anonymity set. */ func Example_elGamalEncryption() { - group := nist.NewAES128SHA256P256() + group := edwards25519.NewAES128SHA256Ed25519(false) // Create a public/private keypair a := group.Scalar().Pick(random.Stream) // Alice's private key diff --git a/examples/sig_test.go b/examples/sig_test.go index 23fe6b6f1..384f8d27c 100644 --- a/examples/sig_test.go +++ b/examples/sig_test.go @@ -8,7 +8,7 @@ import ( "fmt" "gopkg.in/dedis/kyber.v1" - "gopkg.in/dedis/kyber.v1/group/nist" + "gopkg.in/dedis/kyber.v1/group/edwards25519" ) type Suite interface { @@ -89,7 +89,7 @@ func SchnorrVerify(suite Suite, message []byte, publicKey kyber.Point, // Example of using Schnorr func ExampleSchnorr() { // Crypto setup - group := nist.NewAES128SHA256P256() + group := edwards25519.NewAES128SHA256Ed25519(false) rand := group.Cipher([]byte("example")) // Create a public/private keypair (X,x) @@ -110,9 +110,9 @@ func ExampleSchnorr() { // Output: // Signature: - // 00000000 c1 7a 91 74 06 48 5d 53 d4 92 27 71 58 07 eb d5 |.z.t.H]S..'qX...| - // 00000010 75 a5 89 92 78 67 fc b1 eb 36 55 63 d1 32 12 20 |u...xg...6Uc.2. | - // 00000020 2c 78 84 81 04 0d 2a a8 fa 80 d0 e8 c3 14 65 e3 |,x....*.......e.| - // 00000030 7f f2 7c 55 c5 d2 c6 70 51 89 40 cd 63 50 bf c6 |..|U...pQ.@.cP..| + // 00000000 d4 64 bd ac 8a 06 d9 71 f4 ae a1 da e1 c5 55 d5 |.d.....q......U.| + // 00000010 f7 89 50 10 a5 d9 99 52 b0 c4 f2 ba f9 37 67 02 |..P....R.....7g.| + // 00000020 35 3e 9b ac e6 dd d1 98 f6 19 88 37 4d e3 4f 5c |5>.........7M.O\| + // 00000030 36 de a7 bf b9 f0 06 2b 72 6f 81 b7 59 19 c6 00 |6......+ro..Y...| // Signature verified against correct message. } diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 195b2fd50..765a50f37 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -135,10 +135,9 @@ func (s *scalar) Pick(rand cipher.Stream) kyber.Scalar { return s.setInt(i) } -// SetBytes sets the scalar from a big-endian byte-slice func (s *scalar) SetBytes(b []byte) kyber.Scalar { // XXX handle simple and scReduce cases appropriately - return s.setInt(mod.NewIntBytes(b, primeOrder, mod.BigEndian)) + return s.setInt(mod.NewIntBytes(b, primeOrder, mod.LittleEndian)) } // Bytes returns a big-Endian representation of the scalar @@ -164,8 +163,9 @@ func (s *scalar) MarshalSize() int { } func (s *scalar) MarshalBinary() ([]byte, error) { - buf := s.v - return buf[:], nil + return s.toInt().MarshalBinary() + //buf := s.v + //return buf[:], nil } func (s *scalar) UnmarshalBinary(buf []byte) error { diff --git a/group/edwards25519/suite.go b/group/edwards25519/suite.go index e7c995bb5..e0e9a943c 100644 --- a/group/edwards25519/suite.go +++ b/group/edwards25519/suite.go @@ -9,6 +9,7 @@ import ( "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/cipher/sha3" + "gopkg.in/dedis/kyber.v1/util/random" ) type SuiteEd25519 struct { @@ -38,6 +39,9 @@ func (s *SuiteEd25519) New(t reflect.Type) interface{} { } func (s *SuiteEd25519) NewKey(r cipher.Stream) kyber.Scalar { + if r == nil { + r = random.Stream + } return s.Curve.Scalar().Pick(r) } diff --git a/proof/deniable_test.go b/proof/deniable_test.go index 9f015111a..b2c7e57c5 100644 --- a/proof/deniable_test.go +++ b/proof/deniable_test.go @@ -5,11 +5,11 @@ import ( "testing" //"encoding/hex" "gopkg.in/dedis/kyber.v1" - "gopkg.in/dedis/kyber.v1/group/nist" + "gopkg.in/dedis/kyber.v1/group/edwards25519" "gopkg.in/dedis/kyber.v1/util/random" ) -var testSuite = nist.NewAES128SHA256P256() +var testSuite = edwards25519.NewAES128SHA256Ed25519(false) type node struct { i int diff --git a/proof/hash_test.go b/proof/hash_test.go index b8157adea..80221a88a 100644 --- a/proof/hash_test.go +++ b/proof/hash_test.go @@ -5,7 +5,7 @@ import ( "fmt" "gopkg.in/dedis/kyber.v1" - "gopkg.in/dedis/kyber.v1/group/nist" + "gopkg.in/dedis/kyber.v1/group/edwards25519" ) // This example shows how to build classic ElGamal-style digital signatures @@ -13,7 +13,7 @@ import ( func ExampleHashProve_1() { // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point @@ -46,13 +46,10 @@ func ExampleHashProve_1() { // Output: // Signature: - // 00000000 04 23 62 b1 f9 cb f4 a2 6d 7f 3e 69 cb b6 77 ab |.#b.....m.>i..w.| - // 00000010 90 fc 7c db a0 c6 e8 12 f2 0a d4 40 a4 b6 c4 de |..|........@....| - // 00000020 9e e8 61 88 5e 50 fd 03 a9 ff 9c a3 c4 29 f7 18 |..a.^P.......)..| - // 00000030 49 ad 31 0e f9 17 15 1e 3b 8d 0e 2f b2 c4 28 32 |I.1.....;../..(2| - // 00000040 4a 5c 64 ca 04 eb 33 db a9 75 9b 01 6b 12 01 ae |J\d...3..u..k...| - // 00000050 4e de 7c 6b 53 85 f8 a5 76 ba eb 7e 2e 61 2c a5 |N.|kS...v..~.a,.| - // 00000060 e8 |.| + // 00000000 27 fd 13 c3 6e e6 df a5 00 aa 0c 93 a7 b8 21 4b |'...n.........!K| + // 00000010 a5 cf 26 c2 a0 99 68 b0 a0 36 9d 7a de 92 95 7a |..&...h..6.z...z| + // 00000020 1f 46 d8 67 4a 71 49 c9 7c d2 8f 2b 75 8c cc 83 |.F.gJqI.|..+u...| + // 00000030 b4 31 0c 6f 6c 2e 75 70 cd 8b 8e 04 b0 54 4f 07 |.1.ol.up.....TO.| // Signature verified against correct message M. // Signature verify against wrong message: invalid proof: commit mismatch } @@ -80,7 +77,7 @@ func ExampleHashProve_1() { func ExampleHashProve_2() { // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point @@ -115,7 +112,7 @@ func ExampleHashProve_2() { preds[i] = And(Rep(name, "x", "B"), Rep("T", "x", "BT")) } pred := Or(preds...) // make a big Or predicate - fmt.Printf("Linkable Ring Signature Predicate:\n\t%s\n", pred.String()) + fmt.Printf("Linkable Ring Signature Predicate:\n%s\n", pred.String()) // The prover needs to know which Or branch (mine) is actually true. choice := make(map[Predicate]int) @@ -137,44 +134,31 @@ func ExampleHashProve_2() { // Output: // Linkable Ring Signature Predicate: - // (X[0]=x*B && T=x*BT) || (X[1]=x*B && T=x*BT) || (X[2]=x*B && T=x*BT) + // (X[0]=x*B && T=x*BT) || (X[1]=x*B && T=x*BT) || (X[2]=x*B && T=x*BT) // Linkable Ring Signature: - // 00000000 04 56 81 70 79 e2 f6 ea 5b 06 a5 f5 72 5d f5 e0 |.V.py...[...r]..| - // 00000010 b6 e6 d3 90 52 af 84 7a b1 78 a9 03 f3 29 1e a2 |....R..z.x...)..| - // 00000020 1a 59 50 28 9b 6c d7 ca 72 25 83 67 2d fe f7 f0 |.YP(.l..r%.g-...| - // 00000030 96 e9 ae 9b 9e a0 eb 76 7f 74 6d bc 42 18 a1 d1 |.......v.tm.B...| - // 00000040 0e 04 d8 28 10 ae b9 25 87 e9 a1 c4 fa 1b ff 88 |...(...%........| - // 00000050 96 bd da 4a 7f 58 c9 b5 57 57 7f 8b ee 4e 00 40 |...J.X..WW...N.@| - // 00000060 fa 2c 6a 49 74 41 9a c6 7d ac 78 fa 58 35 84 40 |.,jItA..}.x.X5.@| - // 00000070 2a 95 62 8c 05 5c 75 57 4e 74 22 a9 5f 78 48 22 |*.b..\uWNt"._xH"| - // 00000080 1f 97 04 f7 a8 0d ec 81 39 31 fb 8b 8b 12 09 74 |........91.....t| - // 00000090 46 9f 46 22 e9 69 cc 25 c5 b6 23 5b 2a 4b 3d 4c |F.F".i.%..#[*K=L| - // 000000a0 10 f7 73 e0 22 00 f3 99 28 be ad 07 8c ef 44 a6 |..s."...(.....D.| - // 000000b0 d8 e0 ee 5e 04 c7 d1 60 b4 f0 8d e3 bd b3 31 8e |...^...`......1.| - // 000000c0 19 9a 56 04 9f da 0c 05 3f 04 42 e4 d3 e3 78 00 |..V.....?.B...x.| - // 000000d0 d8 bc 31 c2 00 fd 29 64 63 65 e5 9a 1c 5f b4 01 |..1...)dce..._..| - // 000000e0 ca 14 c5 48 bc 73 60 31 9e 18 7d 93 c8 69 cc c9 |...H.s`1..}..i..| - // 000000f0 a4 c7 72 e0 c2 a8 2e 47 f5 fa e8 1f de c0 14 52 |..r....G.......R| - // 00000100 9f 7a a7 5b 04 2e b4 bb d5 a1 8a 80 4e 48 1e 07 |.z.[........NH..| - // 00000110 20 e0 f8 9a 6a 9c 5a b7 8b 08 9c 6d c7 0e 9c 9f | ...j.Z....m....| - // 00000120 3f 6b d3 34 7e 50 91 6b 87 03 d5 54 b6 87 f1 2d |?k.4~P.k...T...-| - // 00000130 4c d6 9e df fe 1b 7f 07 be 5e d5 88 7f 2b b0 58 |L........^...+.X| - // 00000140 e2 12 62 15 00 04 d8 45 d5 c4 91 77 0c 74 5c 54 |..b....E...w.t\T| - // 00000150 89 e9 cd 75 9b c5 20 67 26 d8 e4 e8 ed 68 96 51 |...u.. g&....h.Q| - // 00000160 6f 39 e5 62 e5 c5 24 15 5e 45 69 91 c0 83 2c 6b |o9.b..$.^Ei...,k| - // 00000170 33 fe af 75 c2 23 ca 88 b2 a8 c8 be f2 4f f0 e9 |3..u.#.......O..| - // 00000180 65 af e6 b1 7e e6 eb 40 46 de 61 2f 08 8d 9a 04 |e...~..@F.a/....| - // 00000190 09 d7 a1 62 83 48 e3 cc 09 af 64 26 df df da d6 |...b.H....d&....| - // 000001a0 51 62 5d e6 2b 56 b2 b5 3a e1 c8 8c f7 29 8a 13 |Qb].+V..:....)..| - // 000001b0 75 59 98 ea ce f4 6d d5 d0 62 85 51 8e fe d9 4a |uY....m..b.Q...J| - // 000001c0 02 1f 35 03 33 d3 0e 4e 6b b8 fc f9 c9 92 4d e9 |..5.3..Nk.....M.| - // 000001d0 c3 1c 35 ec 19 43 7c 25 1b b4 70 09 30 08 e3 a1 |..5..C|%..p.0...| - // 000001e0 e1 42 ed 92 0d 82 63 d3 5a 0e 97 78 e6 74 ce a0 |.B....c.Z..x.t..| - // 000001f0 24 34 c1 66 7d af 32 9e 59 22 f2 9a 67 3c ea e5 |$4.f}.2.Y"..g<..| - // 00000200 4f 54 6d 3e 07 f1 1e 6d 18 7f 8b 95 e3 c4 b9 33 |OTm>...m.......3| - // 00000210 ad 94 69 b5 b4 13 b8 51 2f 24 a7 98 e4 06 f4 b2 |..i....Q/$......| - // 00000220 f3 ee e8 73 de 78 d1 ab ff 11 e3 6e df 3d a8 b5 |...s.x.....n.=..| - // 00000230 13 86 b6 a5 86 f9 a6 ef ca 77 46 df 8d 3b eb fb |.........wF..;..| - // 00000240 00 c8 61 cc fd 7a |..a..z| + // 00000000 45 85 60 73 be bc 55 10 0e 40 44 59 99 ce 5c 76 |E.`s..U..@DY..\v| + // 00000010 f5 ac 0e 6c e6 00 b0 93 01 41 5b e9 9c 39 fe d0 |...l.....A[..9..| + // 00000020 65 71 9c 31 f7 b9 ce 81 57 b3 6b 47 41 54 2b d7 |eq.1....W.kGAT+.| + // 00000030 f8 15 b6 a2 bc 2d b3 e0 fe c2 77 09 6d 93 b4 69 |.....-....w.m..i| + // 00000040 2f ab 85 4d 65 b1 b6 eb d8 16 96 5f ae 47 38 1d |/..Me......_.G8.| + // 00000050 a7 69 cf 0e 24 04 ff 0a ec 54 24 4e 09 c0 ec d5 |.i..$....T$N....| + // 00000060 c7 e9 cd 3c 93 2b 52 f7 f6 ba bc 89 03 0e bd 2d |...<.+R........-| + // 00000070 bc be 3a d9 b0 5f cf ba a8 f7 a7 38 57 e3 67 d0 |..:.._.....8W.g.| + // 00000080 ef de 78 87 05 20 9a d2 43 2a ff 77 36 62 6a 1a |..x.. ..C*.w6bj.| + // 00000090 53 07 d4 34 a9 d5 b4 39 7d 0b 99 c8 23 76 2e b9 |S..4...9}...#v..| + // 000000a0 48 e3 19 0e 76 69 14 0e 9a 6a ef 6c be 4a df af |H...vi...j.l.J..| + // 000000b0 7c 6b 00 8c 7d a0 e4 33 b2 91 cc b4 18 69 ca c0 ||k..}..3.....i..| + // 000000c0 fd 83 93 4f ca fa ed 2f b6 43 27 e3 a5 4b a1 0c |...O.../.C'..K..| + // 000000d0 b3 fb 4b 2c 82 2e 32 a0 83 12 34 f6 c6 8b 93 03 |..K,..2...4.....| + // 000000e0 ee f3 b2 f4 06 e4 98 a7 24 2f 51 b8 13 b4 b5 69 |........$/Q....i| + // 000000f0 94 ad 33 b9 c4 e3 95 8b 7f 18 6d 1e f1 07 3e 0d |..3.......m...>.| + // 00000100 c3 86 a1 24 1b 3e e1 59 d5 bd 70 a1 ff f9 7c 07 |...$.>.Y..p...|.| + // 00000110 8c 9c 52 f7 47 34 46 c9 1a 05 4b 68 57 49 c7 0e |..R.G4F...KhWI..| + // 00000120 31 68 8d ca 3f 6a 85 a1 0d f1 cf 9d 21 05 83 f2 |1h..?j......!...| + // 00000130 35 63 b0 65 a8 50 a5 ee ec 95 f8 fd 78 de 73 08 |5c.e.P......x.s.| + // 00000140 35 e7 59 fa 2b 41 20 f8 b6 48 43 62 91 f1 c6 99 |5.Y.+A ..HCb....| + // 00000150 0e 64 9c 2c 06 fe 84 75 4f ca 03 7f 28 b5 6d 0c |.d.,...uO...(.m.| + // 00000160 1d 63 e5 73 26 c4 9f 61 62 5b 5c 34 70 66 d0 e4 |.c.s&..ab[\4pf..| + // 00000170 ec ca b8 ee 9a 50 07 6b 0c 75 5a a6 77 b3 20 0f |.....P.k.uZ.w. .| // Linkable Ring Signature verified. } diff --git a/proof/proof_test.go b/proof/proof_test.go index 7b5826498..be7eece54 100644 --- a/proof/proof_test.go +++ b/proof/proof_test.go @@ -6,11 +6,11 @@ import ( "testing" "gopkg.in/dedis/kyber.v1" - "gopkg.in/dedis/kyber.v1/group/nist" + "gopkg.in/dedis/kyber.v1/group/edwards25519" ) func TestRep(t *testing.T) { - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher(kyber.RandomKey) x := suite.Scalar().Pick(rand) @@ -85,7 +85,7 @@ func ExampleRep_2() { fmt.Println(pred.String()) // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point @@ -111,13 +111,10 @@ func ExampleRep_2() { // Output: // X=x*B // Proof: - // 00000000 04 23 62 b1 f9 cb f4 a2 6d 7f 3e 69 cb b6 77 ab |.#b.....m.>i..w.| - // 00000010 90 fc 7c db a0 c6 e8 12 f2 0a d4 40 a4 b6 c4 de |..|........@....| - // 00000020 9e e8 61 88 5e 50 fd 03 a9 ff 9c a3 c4 29 f7 18 |..a.^P.......)..| - // 00000030 49 ad 31 0e f9 17 15 1e 3b 8d 0e 2f b2 c4 28 32 |I.1.....;../..(2| - // 00000040 4a 20 ba b2 9d 3a 40 ae 0f 28 16 a2 ad 44 76 d2 |J ...:@..(...Dv.| - // 00000050 83 f2 09 4d b8 a5 d0 f6 5e 5d ff 6e b7 9a 0f 1b |...M....^].n....| - // 00000060 9a |.| + // 00000000 27 fd 13 c3 6e e6 df a5 00 aa 0c 93 a7 b8 21 4b |'...n.........!K| + // 00000010 a5 cf 26 c2 a0 99 68 b0 a0 36 9d 7a de 92 95 7a |..&...h..6.z...z| + // 00000020 c2 f0 69 05 69 f1 14 15 b1 38 3d 9c 49 bd c5 89 |..i.i....8=.I...| + // 00000030 55 05 56 9a 44 31 52 12 c2 37 77 5d 37 13 fa 05 |U.V.D1R..7w]7...| // Proof verified. } @@ -199,7 +196,7 @@ func ExampleOr_2() { fmt.Println("Predicate: " + pred.String()) // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point @@ -233,22 +230,17 @@ func ExampleOr_2() { // Output: // Predicate: X=x*B || Y=y*B // Proof: - // 00000000 04 af 84 ed e5 86 04 cf 81 e4 18 17 84 0c 39 ab |..............9.| - // 00000010 fe 5c bc cc 00 85 e0 a2 ee aa d5 22 18 dd c4 a1 |.\........."....| - // 00000020 5b 85 52 d4 dd 72 9b d2 2b e2 02 d2 5f 6f cb 10 |[.R..r..+..._o..| - // 00000030 b5 1b 18 c3 02 1e 2f dd 50 54 9d 4c 19 aa 30 80 |....../.PT.L..0.| - // 00000040 4a 04 f8 26 2f 55 ed b3 00 ad 38 ba f9 0f d6 fb |J..&/U....8.....| - // 00000050 0a d1 0e 56 be dd 71 7d 1d a9 36 2f 1f 20 b8 98 |...V..q}..6/. ..| - // 00000060 a6 3f d0 fa dc 52 ca 57 8d 7e 37 aa ac e5 8c 4c |.?...R.W.~7....L| - // 00000070 2a eb d9 5c 0c 68 c8 e8 ac 99 7f b4 96 56 cf 59 |*..\.h.......V.Y| - // 00000080 79 6f c5 c2 0a 9f 1f 3b 34 61 0f 9b b7 50 00 b7 |yo.....;4a...P..| - // 00000090 29 02 8e d5 41 9a 92 95 6b 4e 18 5b 89 a5 93 1e |)...A...kN.[....| - // 000000a0 42 cd 32 17 7d 53 c5 e4 48 79 49 b2 3e 1e e2 62 |B.2.}S..HyI.>..b| - // 000000b0 39 08 13 d5 2e f8 c5 e9 c1 28 09 91 7a 95 c9 12 |9........(..z...| - // 000000c0 17 85 49 9e b0 3c fe fc 5d 5b 73 b1 d2 bf f9 59 |..I..<..][s....Y| - // 000000d0 5b 5f 10 12 cb 9c d0 c6 bc 2c 75 fb 52 9c 66 c5 |[_.......,u.R.f.| - // 000000e0 17 cb 93 8b c6 f6 34 12 83 a0 32 2e 82 2c 4b fb |......4...2..,K.| - // 000000f0 b3 0c a1 4b a5 e3 27 43 b6 2f ed fa ca 4f 93 83 |...K..'C./...O..| - // 00000100 fd 56 |.V| + // 00000000 b6 8f 24 dc d3 c0 86 67 42 1d c3 c8 5a 28 62 4d |..$....gB...Z(bM| + // 00000010 86 3b c9 69 7c 88 7f 52 9e b3 93 25 2d e6 58 0e |.;.i|..R...%-.X.| + // 00000020 2e 49 39 eb a7 6d a0 65 9e 45 f7 c8 98 e9 bd db |.I9..m.e.E......| + // 00000030 af 83 ac 80 ed 21 7c c9 ce d1 2d 45 43 05 3e 55 |.....!|...-EC.>U| + // 00000040 95 3f 7d f5 a8 a4 48 2d 9a 2c 40 27 1c 2c d5 75 |.?}...H-.,@'.,.u| + // 00000050 f6 57 a9 03 b2 bf ec 8d e1 8c 59 5b 56 af 59 00 |.W........Y[V.Y.| + // 00000060 2d 17 6e d0 98 15 24 7e c6 9e ad c2 55 9e ba 0e |-.n...$~....U...| + // 00000070 1f a9 fe 92 47 24 31 a2 a0 88 72 9a 16 2f ab 05 |....G$1...r../..| + // 00000080 b4 9c 73 96 b3 03 44 c9 3c 8f 6b dd fa 15 d0 dc |..s...D.<.k.....| + // 00000090 76 28 8d 01 33 0a 3f 70 e2 72 4d e1 86 d8 07 00 |v(..3.?p.rM.....| + // 000000a0 ee f3 b2 f4 06 e4 98 a7 24 2f 51 b8 13 b4 b5 69 |........$/Q....i| + // 000000b0 94 ad 33 b9 c4 e3 95 8b 7f 18 6d 1e f1 07 3e 0d |..3.......m...>.| // Proof verified. } diff --git a/sign/anon/enc_test.go b/sign/anon/enc_test.go index d3fc98d9e..b22c8a587 100644 --- a/sign/anon/enc_test.go +++ b/sign/anon/enc_test.go @@ -7,13 +7,13 @@ import ( "encoding/hex" "gopkg.in/dedis/kyber.v1" - "gopkg.in/dedis/kyber.v1/group/nist" + "gopkg.in/dedis/kyber.v1/group/edwards25519" ) func ExampleEncrypt_1() { // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) // Create a public/private keypair (X[mine],x) @@ -39,21 +39,20 @@ func ExampleEncrypt_1() { // Output: // Encryption of 'Hello World!': - // 00000000 04 23 62 b1 f9 cb f4 a2 6d 7f 3e 69 cb b6 77 ab |.#b.....m.>i..w.| - // 00000010 90 fc 7c db a0 c6 e8 12 f2 0a d4 40 a4 b6 c4 de |..|........@....| - // 00000020 9e e8 61 88 5e 50 fd 03 a9 ff 9c a3 c4 29 f7 18 |..a.^P.......)..| - // 00000030 49 ad 31 0e f9 17 15 1e 3b 8d 0e 2f b2 c4 28 32 |I.1.....;../..(2| - // 00000040 4a a4 16 00 51 da 5e d5 3a df f3 02 fe 77 0d 11 |J...Q.^.:....w..| - // 00000050 27 7b 29 b4 a0 47 7a 82 8f 0a 98 4f fe fe 1e 5d |'{)..Gz....O...]| - // 00000060 cf d2 08 9a e5 f0 d9 3c 6b 0d 83 35 6d 15 b1 93 |........n..| + // 00000070 0a 8f 6c f7 42 34 3e 3a eb 0d 9c 2d 20 19 86 1f |..l.B4>:...- ...| + // 00000080 55 fd 56 ca 1d 92 f8 1e e1 f3 39 4d bf 02 7c 14 |U.V.......9M..|.| + // 00000090 4a d4 67 90 74 34 c8 4e 0c b5 cf ef |J.g.t4.N....| // Decrypted: 'Hello World!' } diff --git a/sign/anon/sig_test.go b/sign/anon/sig_test.go index 3ab8e8b1f..a7adf60f8 100644 --- a/sign/anon/sig_test.go +++ b/sign/anon/sig_test.go @@ -8,7 +8,6 @@ import ( "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/group/edwards25519" - "gopkg.in/dedis/kyber.v1/group/nist" "gopkg.in/dedis/kyber.v1/util/random" ) @@ -21,7 +20,7 @@ import ( func ExampleSign_1() { // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) // Create a public/private keypair (X[mine],x) @@ -55,10 +54,10 @@ func ExampleSign_1() { // Output: // Signature: - // 00000000 0d 3a d5 66 4d cd 8a bc ee ae 4a 92 12 e7 63 68 |.:.fM.....J...ch| - // 00000010 c3 61 9f b0 65 ce f1 d9 83 a7 40 4f e0 7b 58 f5 |.a..e.....@O.{X.| - // 00000020 5c 64 ca 04 eb 33 db a9 75 9b 01 6b 12 01 ae 4e |\d...3..u..k...N| - // 00000030 de 7c 6b 53 85 f8 a5 76 ba eb 7e 2e 61 2c a5 e8 |.|kS...v..~.a,..| + // 00000000 be db 1a 8e 63 21 a2 96 68 17 85 05 e7 aa dc fd |....c!..h.......| + // 00000010 09 d8 36 e6 00 39 f8 98 69 4a 70 dc 4e a2 07 07 |..6..9..iJp.N...| + // 00000020 1f 46 d8 67 4a 71 49 c9 7c d2 8f 2b 75 8c cc 83 |.F.gJqI.|..+u...| + // 00000030 b4 31 0c 6f 6c 2e 75 70 cd 8b 8e 04 b0 54 4f 07 |.1.ol.up.....TO.| // Signature verified against correct message. // Verifying against wrong message: invalid signature } @@ -69,7 +68,7 @@ func ExampleSign_1() { func ExampleSign_anonSet() { // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) // Create an anonymity set of random "public keys" @@ -108,14 +107,14 @@ func ExampleSign_anonSet() { // Output: // Signature: - // 00000000 eb 16 0d c9 1e 19 f5 da f7 9b 77 7d 52 0b f1 82 |..........w}R...| - // 00000010 4b e3 dd 6c 44 f3 6f fe c3 c1 1a 6e 1f a8 43 26 |K..lD.o....n..C&| - // 00000020 63 d3 5a 0e 97 78 e6 74 ce a0 24 34 c1 66 7d af |c.Z..x.t..$4.f}.| - // 00000030 32 9e 59 22 f2 9a 67 3c ea e5 4f 54 6d 3e 07 f1 |2.Y"..g<..OTm>..| - // 00000040 63 10 77 96 09 a3 c1 e4 85 f8 d9 97 0c 47 dc 73 |c.w..........G.s| - // 00000050 da 6c d8 11 8a 2e 00 a7 f2 01 45 e0 91 4e 28 d6 |.l........E..N(.| - // 00000060 b2 b5 3a e1 c8 8c f7 29 8a 13 75 59 98 ea ce f4 |..:....)..uY....| - // 00000070 6d d5 d0 62 85 51 8e fe d9 4a 02 1f 35 03 33 d3 |m..b.Q...J..5.3.| + // 00000000 a4 00 4d 45 a6 cd f6 b4 1b e0 d1 12 54 49 ee c3 |..ME........TI..| + // 00000010 d6 8a bd c5 7d 16 b4 a8 ec 6e b2 ce 51 5c fc 0a |....}....n..Q\..| + // 00000020 31 68 8d ca 3f 6a 85 a1 0d f1 cf 9d 21 05 83 f2 |1h..?j......!...| + // 00000030 35 63 b0 65 a8 50 a5 ee ec 95 f8 fd 78 de 73 08 |5c.e.P......x.s.| + // 00000040 a7 89 3b ae 4d cb 44 c0 19 49 11 63 25 21 13 ce |..;.M.D..I.c%!..| + // 00000050 0e d3 d3 e3 89 af db cd 23 8f 3f 60 06 1b a1 0e |........#.?`....| + // 00000060 ee f3 b2 f4 06 e4 98 a7 24 2f 51 b8 13 b4 b5 69 |........$/Q....i| + // 00000070 94 ad 33 b9 c4 e3 95 8b 7f 18 6d 1e f1 07 3e 0d |..3.......m...>.| // Signature verified against correct message. // Verifying against wrong message: invalid signature } @@ -128,7 +127,7 @@ func ExampleSign_anonSet() { func ExampleSign_linkable() { // Crypto setup - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) // Create an anonymity set of random "public keys" @@ -185,65 +184,54 @@ func ExampleSign_linkable() { // Output: // Signature 0: - // 00000000 c6 e9 27 a5 00 5d 22 40 d2 a2 5d 08 44 2b ec 2e |..'..]"@..].D+..| - // 00000010 e2 01 a6 85 70 70 b4 73 2c 18 24 f1 46 44 22 09 |....pp.s,.$.FD".| - // 00000020 1e 6d 18 7f 8b 95 e3 c4 b9 33 ad 94 69 b5 b4 13 |.m.......3..i...| - // 00000030 b8 51 2f 24 a7 98 e4 06 f4 b2 f3 ee e8 73 de 78 |.Q/$.........s.x| - // 00000040 a3 9d 4b 1c 74 6f 3a 50 89 c9 10 cc bb b0 5c a7 |..K.to:P......\.| - // 00000050 09 a9 23 47 0f 36 08 a4 f3 46 ad 14 2d f0 9d c1 |..#G.6...F..-...| - // 00000060 63 d3 5a 0e 97 78 e6 74 ce a0 24 34 c1 66 7d af |c.Z..x.t..$4.f}.| - // 00000070 32 9e 59 22 f2 9a 67 3c ea e5 4f 54 6d 3e 07 f1 |2.Y"..g<..OTm>..| - // 00000080 04 00 33 42 ee 88 9f 5d fa 2e be 6a 72 fd 67 22 |..3B...]...jr.g"| - // 00000090 c1 e0 ed 35 69 d7 e4 67 df 92 e7 ca 75 2f e6 72 |...5i..g....u/.r| - // 000000a0 79 3a 32 e2 8b 45 61 e8 7d e5 95 5b 0a 30 35 e9 |y:2..Ea.}..[.05.| - // 000000b0 af 3c 41 48 59 d9 e2 73 68 77 31 f3 36 cc ee 78 |..\...| + // 00000060 31 68 8d ca 3f 6a 85 a1 0d f1 cf 9d 21 05 83 f2 |1h..?j......!...| + // 00000070 35 63 b0 65 a8 50 a5 ee ec 95 f8 fd 78 de 73 08 |5c.e.P......x.s.| + // 00000080 7e 2d ef 97 ca b0 fb e5 69 ce 41 59 e0 2d 8c 0b |~-......i.AY.-..| + // 00000090 0e 12 b2 9d bb 24 ca 03 d3 98 ea ff 30 3e a6 c9 |.....$......0>..| // Signature 1: - // 00000000 69 4c 29 32 cb 9c f6 ca 80 72 f6 25 e0 ef 44 0b |iL)2.....r.%..D.| - // 00000010 f2 0b e3 ab 98 c4 62 a3 10 13 09 02 9a f1 f1 00 |......b.........| - // 00000020 7f 03 ca 4f 75 84 fe 06 2c 9c 64 0e 99 c6 f1 91 |...Ou...,.d.....| - // 00000030 62 43 48 b6 f8 20 41 2b fa 59 e7 35 be f8 4c 1b |bCH.. A+.Y.5..L.| - // 00000040 f0 d8 af 83 ad 9a 87 55 ca be 46 f9 42 a2 dd 18 |.......U..F.B...| - // 00000050 18 83 f1 f5 6d 82 e5 38 49 bf 24 9e 80 a4 12 eb |....m..8I.$.....| - // 00000060 56 c5 3f 08 bb 99 6d 7d 0a f8 ac c5 29 e8 94 54 |V.?...m}....)..T| - // 00000070 3e 4d fb ca b5 1d 9a 29 56 a0 09 f9 ec 6d b5 28 |>M.....)V....m.(| - // 00000080 04 00 33 42 ee 88 9f 5d fa 2e be 6a 72 fd 67 22 |..3B...]...jr.g"| - // 00000090 c1 e0 ed 35 69 d7 e4 67 df 92 e7 ca 75 2f e6 72 |...5i..g....u/.r| - // 000000a0 79 3a 32 e2 8b 45 61 e8 7d e5 95 5b 0a 30 35 e9 |y:2..Ea.}..[.05.| - // 000000b0 af 3c 41 48 59 d9 e2 73 68 77 31 f3 36 cc ee 78 |..| + // 00000040 fa 2d e2 ef c0 67 ff 24 14 aa a5 99 01 ab de 14 |.-...g.$........| + // 00000050 1b 12 c3 d2 8c 9e 4f e7 b5 f8 b9 49 2f de e2 0b |......O....I/...| + // 00000060 fe e8 5c 0c 56 18 63 19 e2 f4 4d 6f b4 5d 1c ea |..\.V.c...Mo.]..| + // 00000070 5d 37 8b 13 9b 2c 7f c6 64 21 5e 38 93 27 f4 06 |]7...,..d!^8.'..| + // 00000080 7e 2d ef 97 ca b0 fb e5 69 ce 41 59 e0 2d 8c 0b |~-......i.AY.-..| + // 00000090 0e 12 b2 9d bb 24 ca 03 d3 98 ea ff 30 3e a6 c9 |.....$......0>..| // Signature 2: - // 00000000 94 d0 51 98 05 a1 79 6c 16 4e 7f f2 58 c8 09 b8 |..Q...yl.N..X...| - // 00000010 32 12 a5 dc be f3 cf 08 a8 77 8f 7e a7 32 dd 2b |2........w.~.2.+| - // 00000020 8b 48 7e 5a 4f eb 1d 1f c8 6c 96 e6 38 86 a9 50 |.H~ZO....l..8..P| - // 00000030 dc 69 e8 2d c9 ed 41 51 38 9d 5c 5f 9b e6 93 aa |.i.-..AQ8.\_....| - // 00000040 1c f7 7d 2f d1 ad 5c cd 4d ab 3a ed 2f 29 08 81 |..}/..\.M.:./)..| - // 00000050 55 61 40 8d 86 88 cd e6 62 be 28 b4 90 9c ae 69 |Ua@.....b.(....i| - // 00000060 54 1a 20 09 f3 84 ad 29 dc a8 64 cf c6 ec 92 f0 |T. ....)..d.....| - // 00000070 76 0f 36 28 66 88 81 2b 59 43 0c 69 6f f2 7a 8e |v.6(f..+YC.io.z.| - // 00000080 04 80 18 09 20 80 e9 9b 39 bc 17 47 55 13 8f c9 |.... ...9..GU...| - // 00000090 b4 9d 11 78 7b 56 0f f6 db 38 5f b4 f1 4f 3f 93 |...x{V...8_..O?.| - // 000000a0 63 9c 33 ea 86 f6 e1 54 79 c9 14 9f 45 b6 88 59 |c.3....Ty...E..Y| - // 000000b0 49 b6 76 99 c7 0c 84 6d 1a 9e 05 b0 30 c1 48 f2 |I.v....m....0.H.| - // 000000c0 9a |.| + // 00000000 37 26 60 71 58 f7 87 ec c3 fa aa 36 e8 04 fe cf |7&`qX......6....| + // 00000010 f5 3f f9 34 0d 6f 2a 5c 4b 28 43 dd 31 8a 72 02 |.?.4.o*\K(C.1.r.| + // 00000020 58 c9 50 76 f9 f8 e5 7b 54 fc dd 89 5c 64 54 7c |X.Pv...{T...\dT|| + // 00000030 52 21 d9 30 0d b5 9b 13 3d 4b 5e d4 c4 fe f5 06 |R!.0....=K^.....| + // 00000040 1e 91 e3 7b 4b 6a 9d f8 82 d3 42 19 1a bf 94 80 |...{Kj....B.....| + // 00000050 33 92 bd 73 47 09 71 38 0f 06 23 d7 9e 8e 96 0b |3..sG.q8..#.....| + // 00000060 b3 e7 76 d6 ed 60 37 a7 98 38 87 9d 59 bc 7b 82 |..v..`7..8..Y.{.| + // 00000070 f7 c5 79 f9 1d aa c3 17 5a 13 95 59 de 44 95 02 |..y.....Z..Y.D..| + // 00000080 30 54 cf 20 49 73 89 56 22 e5 e3 1f b8 27 e2 72 |0T. Is.V"....'.r| + // 00000090 06 c7 38 48 98 ee 03 1d f4 7b c7 7e 2c d8 a7 0a |..8H.....{.~,...| // Signature 3: - // 00000000 1a 64 49 4a ff 66 bc 88 93 54 30 e9 96 89 34 76 |.dIJ.f...T0...4v| - // 00000010 f6 95 e0 a9 84 8a a2 6e f4 5e 7f db 58 d9 8a 48 |.......n.^..X..H| - // 00000020 84 bd 96 a9 6b 6e c2 47 03 9f 18 33 73 a5 2b ee |....kn.G...3s.+.| - // 00000030 11 e1 99 36 bf 44 42 26 5e f8 cc 25 1e 8a 97 2b |...6.DB&^..%...+| - // 00000040 7f 57 93 33 c5 fb 27 9f 24 e9 d4 3f 1c 16 67 4c |.W.3..'.$..?..gL| - // 00000050 50 0b d1 0b 08 9b 0f 3f cb ac 96 e8 92 3c a5 3d |P......?.....<.=| - // 00000060 d4 83 2c dd c6 6d e4 68 67 b7 dc 39 68 77 de 3d |..,..m.hg..9hw.=| - // 00000070 8c 83 0d b2 24 4b d6 17 e4 ce 78 7a 63 b7 f0 bb |....$K....xzc...| - // 00000080 04 80 18 09 20 80 e9 9b 39 bc 17 47 55 13 8f c9 |.... ...9..GU...| - // 00000090 b4 9d 11 78 7b 56 0f f6 db 38 5f b4 f1 4f 3f 93 |...x{V...8_..O?.| - // 000000a0 63 9c 33 ea 86 f6 e1 54 79 c9 14 9f 45 b6 88 59 |c.3....Ty...E..Y| - // 000000b0 49 b6 76 99 c7 0c 84 6d 1a 9e 05 b0 30 c1 48 f2 |I.v....m....0.H.| - // 000000c0 9a |.| - // Sig0 tag: 04003342ee889f5dfa2ebe6a72fd6722c1e0ed3569d7e467df92e7ca752fe672793a32e28b4561e87de5955b0a3035e9af3c414859d9e273687731f336ccee78ab - // Sig1 tag: 04003342ee889f5dfa2ebe6a72fd6722c1e0ed3569d7e467df92e7ca752fe672793a32e28b4561e87de5955b0a3035e9af3c414859d9e273687731f336ccee78ab - // Sig2 tag: 048018092080e99b39bc174755138fc9b49d11787b560ff6db385fb4f14f3f93639c33ea86f6e15479c9149f45b6885949b67699c70c846d1a9e05b030c148f29a - // Sig3 tag: 048018092080e99b39bc174755138fc9b49d11787b560ff6db385fb4f14f3f93639c33ea86f6e15479c9149f45b6885949b67699c70c846d1a9e05b030c148f29a + // 00000000 ce 35 b2 a9 19 c9 e7 92 25 4a 9b ae c0 c7 85 19 |.5......%J......| + // 00000010 e6 04 1a 72 42 e3 c7 85 1b b6 a1 df d7 bd 88 0b |...rB...........| + // 00000020 45 a7 41 99 c3 ef 1f db 80 40 47 1a 19 b1 57 cd |E.A......@G...W.| + // 00000030 19 df c9 a2 db 38 bb 14 b6 1d 64 3f 3e e2 36 03 |.....8....d?>.6.| + // 00000040 55 66 b1 9c a7 5b ca 61 ba c8 c6 5c 9e 04 80 85 |Uf...[.a...\....| + // 00000050 e4 64 7f 81 e7 38 6d 97 92 83 65 02 e7 a4 81 05 |.d...8m...e.....| + // 00000060 f9 aa 40 fd 37 04 ab b7 e3 5d 84 79 4f 45 3b 1f |..@.7....].yOE;.| + // 00000070 2b 8a d3 74 9b 91 8c 9a 8d dd f4 4a 44 a0 ea 08 |+..t.......JD...| + // 00000080 30 54 cf 20 49 73 89 56 22 e5 e3 1f b8 27 e2 72 |0T. Is.V"....'.r| + // 00000090 06 c7 38 48 98 ee 03 1d f4 7b c7 7e 2c d8 a7 0a |..8H.....{.~,...| + // Sig0 tag: 7e2def97cab0fbe569ce4159e02d8c0b0e12b29dbb24ca03d398eaff303ea6c9 + // Sig1 tag: 7e2def97cab0fbe569ce4159e02d8c0b0e12b29dbb24ca03d398eaff303ea6c9 + // Sig2 tag: 3054cf204973895622e5e31fb827e27206c7384898ee031df47bc77e2cd8a70a + // Sig3 tag: 3054cf204973895622e5e31fb827e27206c7384898ee031df47bc77e2cd8a70a + } var benchMessage = []byte("Hello World!") @@ -277,10 +265,10 @@ func benchGenKeys(g kyber.Group, } func benchGenKeysOpenSSL(nkeys int) ([]kyber.Point, kyber.Scalar) { - return benchGenKeys(nist.NewAES128SHA256P256(), nkeys) + return benchGenKeys(edwards25519.NewAES128SHA256Ed25519(false), nkeys) } func benchGenSigOpenSSL(nkeys int) []byte { - suite := nist.NewAES128SHA256P256() + suite := edwards25519.NewAES128SHA256Ed25519(false) rand := suite.Cipher([]byte("example")) return Sign(suite, rand, benchMessage, Set(benchPubOpenSSL[:nkeys]), nil, @@ -317,28 +305,28 @@ func benchVerify(suite Suite, pub []kyber.Point, } func BenchmarkSign1OpenSSL(b *testing.B) { - benchSign(nist.NewAES128SHA256P256(), + benchSign(edwards25519.NewAES128SHA256Ed25519(false), benchPubOpenSSL[:1], benchPriOpenSSL, b.N) } func BenchmarkSign10OpenSSL(b *testing.B) { - benchSign(nist.NewAES128SHA256P256(), + benchSign(edwards25519.NewAES128SHA256Ed25519(false), benchPubOpenSSL[:10], benchPriOpenSSL, b.N) } func BenchmarkSign100OpenSSL(b *testing.B) { - benchSign(nist.NewAES128SHA256P256(), + benchSign(edwards25519.NewAES128SHA256Ed25519(false), benchPubOpenSSL[:100], benchPriOpenSSL, b.N) } func BenchmarkVerify1OpenSSL(b *testing.B) { - benchVerify(nist.NewAES128SHA256P256(), + benchVerify(edwards25519.NewAES128SHA256Ed25519(false), benchPubOpenSSL[:1], benchSig1OpenSSL, b.N) } func BenchmarkVerify10OpenSSL(b *testing.B) { - benchVerify(nist.NewAES128SHA256P256(), + benchVerify(edwards25519.NewAES128SHA256Ed25519(false), benchPubOpenSSL[:10], benchSig10OpenSSL, b.N) } func BenchmarkVerify100OpenSSL(b *testing.B) { - benchVerify(nist.NewAES128SHA256P256(), + benchVerify(edwards25519.NewAES128SHA256Ed25519(false), benchPubOpenSSL[:100], benchSig100OpenSSL, b.N) } From 2d953ffe74ebe286f332f1b9aed4266f94e2627e Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 15 Jun 2017 15:11:21 +0200 Subject: [PATCH 16/31] no more bugs ;) --- group/mod/int.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/group/mod/int.go b/group/mod/int.go index 9bccdf7b2..6eb5f498e 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -2,6 +2,7 @@ package mod import ( "crypto/cipher" + "encoding/hex" "errors" "io" "math/big" @@ -87,7 +88,6 @@ func (i *Int) Init64(v int64, m *big.Int) *Int { } // Initialize to a number represented in a big-endian byte string. -// XXX either delete or add an endianness parameter func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { i.M = m i.BO = byteOrder @@ -108,8 +108,8 @@ func (i *Int) InitString(n, d string, base int, m *big.Int) *Int { // Return the Int's integer value in decimal string representation. func (i *Int) String() string { - return i.V.String() - //return hex.EncodeToString(i.V.Bytes()) + //return i.V.String() + return hex.EncodeToString(i.V.Bytes()) } // Set value to a rational fraction n/d represented by a pair of strings. @@ -481,4 +481,3 @@ func (i *Int) HideDecode(buf []byte) { func (i *Int) SetVarTime(varTime bool) bool { return true } - From 6b77576c8e75b5104139cf359726ab4010514870 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 15 Jun 2017 15:13:35 +0200 Subject: [PATCH 17/31] back to SetVarTime for scalar --- group.go | 6 ++++++ group/edwards25519/scalar.go | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/group.go b/group.go index c53b3d74f..e37c4890e 100644 --- a/group.go +++ b/group.go @@ -59,6 +59,12 @@ type Scalar interface { // Bytes returns a big-Endian representation of the scalar Bytes() []byte + + // Allow or disallow use of faster variable-time implementations + // of operations on this Point, returning the old flag value. + // This flag always defaults to false (constant-time only) + // in implementations that can provide constant-time operations. + SetVarTime(varTime bool) bool } /* diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 765a50f37..a60c9f628 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -140,6 +140,10 @@ func (s *scalar) SetBytes(b []byte) kyber.Scalar { return s.setInt(mod.NewIntBytes(b, primeOrder, mod.LittleEndian)) } +func (s *scalar) SetVarTime(varTime bool) bool { + return false +} + // Bytes returns a big-Endian representation of the scalar func (s *scalar) Bytes() []byte { var buf = s.v From b3da6d252dcab8eee250d0d77dcd04f60acac480 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 15 Jun 2017 15:35:16 +0200 Subject: [PATCH 18/31] fixing curve25519 (wrong branch, supposed to be in v1) --- group/curve25519/basic.go | 29 ++++++++++++++++++++++++----- group/curve25519/basic_test.go | 8 ++++---- group/curve25519/suite.go | 9 +++++++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/group/curve25519/basic.go b/group/curve25519/basic.go index d8cf26a10..b616cbd01 100644 --- a/group/curve25519/basic.go +++ b/group/curve25519/basic.go @@ -86,6 +86,12 @@ func (P *basicPoint) Set(P2 kyber.Point) kyber.Point { return P } +func (P *basicPoint) Clone() kyber.Point { + p2 := new(basicPoint) + p2.Set(P) + return p2 +} + // Set to the neutral element, which is (0,1) for twisted Edwards curves. func (P *basicPoint) Null() kyber.Point { P.Set(&P.c.null) @@ -98,12 +104,17 @@ func (P *basicPoint) Base() kyber.Point { return P } -func (P *basicPoint) PickLen() int { - return P.c.pickLen() +func (P *basicPoint) EmbedLen() int { + return P.c.embedLen() +} + +func (P *basicPoint) Embed(data []byte, rand cipher.Stream) kyber.Point { + P.c.embed(P, data, rand) + return P } -func (P *basicPoint) Pick(data []byte, rand cipher.Stream) (kyber.Point, []byte) { - return P, P.c.pickPoint(P, data, rand) +func (P *basicPoint) Pick(rand cipher.Stream) kyber.Point { + return P.Embed(nil, rand) } // Extract embedded data from a point group element @@ -111,6 +122,10 @@ func (P *basicPoint) Data() ([]byte, error) { return P.c.data(&P.x, &P.y) } +func (P *basicPoint) SetVarTime(varTime bool) bool { + return true +} + // Add two points using the basic unified addition laws for Edwards curves: // // x' = ((x1*y2 + x2*y1) / (1 + d*x1*x2*y1*y2)) @@ -167,7 +182,7 @@ func (P *basicPoint) Neg(A kyber.Point) kyber.Point { func (P *basicPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { v := s.(*mod.Int).V if G == nil { - return P.Base().Mul(P, s) + return P.Base().Mul(s, P) } T := P if G == P { // Must use temporary in case G == P @@ -206,6 +221,10 @@ func (c *BasicCurve) Point() kyber.Point { return P } +func (c *BasicCurve) NewKey(r cipher.Stream) kyber.Scalar { + return c.Scalar().Pick(r) +} + // Initialize the curve with given parameters. func (c *BasicCurve) Init(p *Param, fullGroup bool) *BasicCurve { c.curve.init(c, p, fullGroup, &c.null, &c.base) diff --git a/group/curve25519/basic_test.go b/group/curve25519/basic_test.go index 19bc030f2..b07e9f774 100644 --- a/group/curve25519/basic_test.go +++ b/group/curve25519/basic_test.go @@ -24,7 +24,7 @@ func TestCompareBasicProjective25519(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite, + test.TestCompareGroups(testSuite.Cipher, new(BasicCurve).Init(Param25519(), false), new(ProjectiveCurve).Init(Param25519(), false)) } @@ -34,7 +34,7 @@ func TestCompareBasicProjectiveE382(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite, + test.TestCompareGroups(testSuite.Cipher, new(BasicCurve).Init(ParamE382(), false), new(ProjectiveCurve).Init(ParamE382(), false)) } @@ -44,7 +44,7 @@ func TestCompareBasicProjective41417(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite, + test.TestCompareGroups(testSuite.Cipher, new(BasicCurve).Init(Param41417(), false), new(ProjectiveCurve).Init(Param41417(), false)) } @@ -54,7 +54,7 @@ func TestCompareBasicProjectiveE521(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite, + test.TestCompareGroups(testSuite.Cipher, new(BasicCurve).Init(ParamE521(), false), new(ProjectiveCurve).Init(ParamE521(), false)) } diff --git a/group/curve25519/suite.go b/group/curve25519/suite.go index 6220e29c6..7d6c42e98 100644 --- a/group/curve25519/suite.go +++ b/group/curve25519/suite.go @@ -3,6 +3,7 @@ package curve25519 import ( + "crypto/cipher" "crypto/sha256" "hash" "io" @@ -10,6 +11,7 @@ import ( "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/cipher/sha3" + "gopkg.in/dedis/kyber.v1/util/random" ) type SuiteEd25519 struct { @@ -41,6 +43,13 @@ func (s *SuiteEd25519) New(t reflect.Type) interface{} { return kyber.SuiteNew(s, t) } +func (s *SuiteEd25519) NewKey(r cipher.Stream) kyber.Scalar { + if r == nil { + r = random.Stream + } + return s.Scalar().Pick(r) +} + // Ciphersuite based on AES-128, SHA-256, and the Ed25519 curve. func NewAES128SHA256Ed25519(fullGroup bool) *SuiteEd25519 { suite := new(SuiteEd25519) From 294eef9c61334f34432e76dcf7760476f222c4e2 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 15 Jun 2017 15:39:00 +0200 Subject: [PATCH 19/31] comments from @ineiti --- group/edwards25519/point.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index 9a4077a9c..eb3eeb1b3 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -25,7 +25,7 @@ import ( ) type point struct { - ge extendedGroupElement + ge extendedGroupElement varTime bool } @@ -212,17 +212,8 @@ func (P *point) Neg(A kyber.Point) kyber.Point { } // Multiply point p by scalar s using the repeated doubling method. -// XXX This is vartime; for our general-purpose Mul operator -// it would be far preferable for security to do this constant-time. func (P *point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { - // Convert the scalar to fixed-length little-endian form. - //sb := s.(*mod.Int).V.Bytes() - //shi := len(sb) - 1 - //var a [32]byte - //for i := range sb { - // a[shi-i] = sb[i] - //} a := &s.(*scalar).v if A == nil { @@ -243,4 +234,3 @@ func (P *point) SetVarTime(varTime bool) bool { P.varTime = varTime return old } - From f5608affcc32aeb98584efbfbe394152fce87c93 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Fri, 16 Jun 2017 11:32:48 +0200 Subject: [PATCH 20/31] ineiti's comments round #2 --- group/curve25519/suite.go | 3 +++ group/nist/doc.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/group/curve25519/suite.go b/group/curve25519/suite.go index 7d6c42e98..d364103b6 100644 --- a/group/curve25519/suite.go +++ b/group/curve25519/suite.go @@ -1,3 +1,6 @@ +// Since that package does not implement constant time arithmetic operations +// yet, it must be compiled with the "vartime" compilation flag. + // +build vartime package curve25519 diff --git a/group/nist/doc.go b/group/nist/doc.go index da708f7a9..2d3774a70 100644 --- a/group/nist/doc.go +++ b/group/nist/doc.go @@ -1,6 +1,6 @@ // Package nist implements cryptographic groups and ciphersuites // based on the NIST standards, using Go's built-in crypto library. -// Since that package does not implements constant time arithmetic operations +// Since that package does not implement constant time arithmetic operations // yet, it must be compiled with the "vartime" compilation flag. // +build vartime From f5f7ebb3f124702885e010f53aa5f479455385fd Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Fri, 16 Jun 2017 14:16:16 +0200 Subject: [PATCH 21/31] Panicking in mod.Int if variable time is false --- group/mod/int.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/group/mod/int.go b/group/mod/int.go index 6eb5f498e..cb396036d 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -479,5 +479,8 @@ func (i *Int) HideDecode(buf []byte) { // This implementation unfortunately provices only variable-time operations, // so the flag is hard-coded to true. func (i *Int) SetVarTime(varTime bool) bool { + if !varTime { + panic("mod.Int: support only variable time arithmetic operations") + } return true } From e72ba4d4e92f7e498fe11fe88c730ba9ec67e22e Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Mon, 19 Jun 2017 13:53:24 +0200 Subject: [PATCH 22/31] removed comment XXX big.int + benchs --- group/edwards25519/const.go | 3 - group/edwards25519/scalar_test.go | 147 ++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 group/edwards25519/scalar_test.go diff --git a/group/edwards25519/const.go b/group/edwards25519/const.go index 59a0b54bb..91ef334fe 100644 --- a/group/edwards25519/const.go +++ b/group/edwards25519/const.go @@ -12,7 +12,6 @@ import ( var prime, _ = new(big.Int).SetString("57896044618658097711785492504343953926634992332820282019728792003956564819949", 10) // prime order of base point = 2^252 + 27742317777372353535851937790883648493 -// XXX this should probably just be a big.Int var primeOrder, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250989", 10) // `l_minus_2` is the order of base point minus two, i.e. 2^252 + @@ -20,8 +19,6 @@ var primeOrder, _ = new(big.Int).SetString("723700557733226221397318656304299424 // This is needed to compute constant time modular inversion of scalars. var l_minus_2_big, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250987", 10) -//var l_minus_2, _ = hex.DecodeString("1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3eb") - // cofactor of the curve, as a ModInt var cofactor = new(big.Int).SetInt64(8) diff --git a/group/edwards25519/scalar_test.go b/group/edwards25519/scalar_test.go new file mode 100644 index 000000000..5c499abff --- /dev/null +++ b/group/edwards25519/scalar_test.go @@ -0,0 +1,147 @@ +package edwards25519 + +import ( + "testing" + + "github.com/dedis/kyber/random" + + kyber "gopkg.in/dedis/kyber.v1" +) + +type SimpleCTScalar struct { + *scalar +} + +func newSimpleCTScalar() kyber.Scalar { + return &SimpleCTScalar{&scalar{}} +} + +var one = new(scalar).SetInt64(1).(*scalar) +var zero = new(scalar).Zero().(*scalar) + +var minus_one = new(scalar).SetBytes([]byte{0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}).(*scalar) + +func (s *SimpleCTScalar) Add(s1, s2 kyber.Scalar) kyber.Scalar { + sc1 := s1.(*SimpleCTScalar) + sc2 := s2.(*SimpleCTScalar) + + // a * b + c = a * 1 + c + scMulAdd(&s.v, &sc1.v, &one.v, &sc2.v) + return s +} + +func (s *SimpleCTScalar) Mul(s1, s2 kyber.Scalar) kyber.Scalar { + sc1 := s1.(*SimpleCTScalar) + sc2 := s2.(*SimpleCTScalar) + + // a * b + c = a * b + 0 + scMulAdd(&s.v, &sc1.v, &sc2.v, &zero.v) + return s +} + +func (s *SimpleCTScalar) Sub(s1, s2 kyber.Scalar) kyber.Scalar { + sc1 := s1.(*SimpleCTScalar) + sc2 := s2.(*SimpleCTScalar) + + // a * b + c = -1 * a + c + scMulAdd(&s.v, &minus_one.v, &sc1.v, &sc2.v) + return s + +} + +func (s *SimpleCTScalar) Equal(s2 kyber.Scalar) bool { + return s.scalar.Equal(s2.(*SimpleCTScalar).scalar) +} + +func TestSimpleCTScalar(t *testing.T) { + s1 := newSimpleCTScalar() + s2 := newSimpleCTScalar() + s3 := newSimpleCTScalar() + + s1.SetInt64(2) + s2.Pick(random.Stream) + + s22 := newSimpleCTScalar().Add(s2, s2) + + if !s3.Mul(s1, s2).Equal(s22) { + t.Fail() + } +} + +func BenchmarkCTScalarSimpleAdd(b *testing.B) { + var seed = testSuite.Cipher([]byte("hello world")) + s1 := newSimpleCTScalar() + s2 := newSimpleCTScalar() + s3 := newSimpleCTScalar() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Add(s1, s2) + } +} + +func BenchmarkCTScalarAdd(b *testing.B) { + var seed = testSuite.Cipher([]byte("hello world")) + s1 := testSuite.Scalar() + s2 := testSuite.Scalar() + s3 := testSuite.Scalar() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Add(s1, s2) + } +} + +func BenchmarkCTScalarSimpleMul(b *testing.B) { + var seed = testSuite.Cipher([]byte("hello world")) + s1 := newSimpleCTScalar() + s2 := newSimpleCTScalar() + s3 := newSimpleCTScalar() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Mul(s1, s2) + } +} + +func BenchmarkCTScalarMul(b *testing.B) { + var seed = testSuite.Cipher([]byte("hello world")) + s1 := testSuite.Scalar() + s2 := testSuite.Scalar() + s3 := testSuite.Scalar() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Mul(s1, s2) + } +} + +func BenchmarkCTScalarSimpleSub(b *testing.B) { + var seed = testSuite.Cipher([]byte("hello world")) + s1 := newSimpleCTScalar() + s2 := newSimpleCTScalar() + s3 := newSimpleCTScalar() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Sub(s1, s2) + } +} + +func BenchmarkCTScalarSub(b *testing.B) { + var seed = testSuite.Cipher([]byte("hello world")) + s1 := testSuite.Scalar() + s2 := testSuite.Scalar() + s3 := testSuite.Scalar() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Sub(s1, s2) + } +} From 20e35452d60ac0d17232260e9c0fb9372ceef7d3 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Tue, 20 Jun 2017 14:26:01 +0200 Subject: [PATCH 23/31] comments from ineiti + linting --- Makefile | 2 +- cipher.go | 8 +- cipher/aead.go | 2 +- cipher/bench/cipher_test.go | 6 +- cipher/bench/doc.go | 2 +- cipher/block.go | 2 +- cipher/cipher.go | 3 + cipher/hash.go | 1 + cipher/sponge.go | 4 +- cipher/stream.go | 9 +- doc.go | 2 +- encoding.go | 11 ++- examples/main.go | 2 +- examples/sig_test.go | 4 +- group.go | 2 +- group/edwards25519/const.go | 2 +- group/edwards25519/curve.go | 15 ++-- group/edwards25519/elligator.go | 2 +- group/edwards25519/ge.go | 132 +++++++++++++++--------------- group/edwards25519/point.go | 2 +- group/edwards25519/scalar.go | 4 +- group/edwards25519/scalar_test.go | 4 +- group/edwards25519/suite.go | 11 ++- group/mod/int.go | 1 - proof/clique.go | 3 +- proof/context.go | 2 +- proof/deniable.go | 4 +- proof/hash.go | 2 +- proof/hash_test.go | 4 +- proof/proof.go | 8 +- proof/proof_test.go | 14 ++-- share/pvss/pvss.go | 6 +- sign/anon/anon.go | 4 +- sign/anon/enc_test.go | 2 +- sign/anon/sig_test.go | 2 +- util/random/rand.go | 1 - 36 files changed, 149 insertions(+), 136 deletions(-) diff --git a/Makefile b/Makefile index e4d295e90..f3344393b 100644 --- a/Makefile +++ b/Makefile @@ -40,4 +40,4 @@ test_verbose: test_goverall: ${GOPATH}/bin/goveralls -service=travis-ci -test: test_goverall +test: test_fmt test_goverall diff --git a/cipher.go b/cipher.go index d4bb3255e..fe8bbc45b 100644 --- a/cipher.go +++ b/cipher.go @@ -132,11 +132,13 @@ type option struct{ name string } func (o *option) String() string { return o.name } -// Pass NoKey to a Cipher constructor to create an unkeyed Cipher. +// NoKey is given to a Cipher constructor to create an unkeyed +// Cipher. var NoKey = []byte{} -// Pass RandomKey to a Cipher constructor to create a randomly seeded Cipher. -var RandomKey []byte = nil +// RandomKey is given to a Cipher constructor to create a +// randomly seeded Cipher. +var RandomKey []byte // Cipher represents a general-purpose symmetric message cipher. // A Cipher instance embodies a scalar that may be used to encrypt/decrypt data diff --git a/cipher/aead.go b/cipher/aead.go index 2ffe53b9b..661ff262c 100644 --- a/cipher/aead.go +++ b/cipher/aead.go @@ -13,7 +13,7 @@ type cipherAEAD struct { kyber.Cipher } -// Wrap an kyber.message Cipher to implement +// NewAEAD wraps an kyber.message Cipher to implement // the Authenticated Encryption with Associated Data (AEAD) interface. func NewAEAD(c kyber.Cipher) cipher.AEAD { return &cipherAEAD{c} diff --git a/cipher/bench/cipher_test.go b/cipher/bench/cipher_test.go index f604f3165..2466234ce 100644 --- a/cipher/bench/cipher_test.go +++ b/cipher/bench/cipher_test.go @@ -5,13 +5,13 @@ import ( "crypto/rc4" "testing" + "golang.org/x/crypto/blowfish" + "golang.org/x/crypto/salsa20" + "golang.org/x/crypto/twofish" "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/cipher/aes" "gopkg.in/dedis/kyber.v1/cipher/norx" "gopkg.in/dedis/kyber.v1/cipher/sha3" - "golang.org/x/crypto/blowfish" - "golang.org/x/crypto/salsa20" - "golang.org/x/crypto/twofish" ) var buf = make([]byte, 1024*1024) diff --git a/cipher/bench/doc.go b/cipher/bench/doc.go index 3b4fe01c7..3af5b201b 100644 --- a/cipher/bench/doc.go +++ b/cipher/bench/doc.go @@ -1,3 +1,3 @@ -// This package exists runs comparative benchmarks +// Package bench runs comparative benchmarks // across several alternative Cipher implementations. package bench diff --git a/cipher/block.go b/cipher/block.go index 39cc33270..03b9c3e12 100644 --- a/cipher/block.go +++ b/cipher/block.go @@ -7,7 +7,7 @@ import ( "gopkg.in/dedis/kyber.v1" ) -// Construct a general message Cipher +// FromBlock constructs a general message Cipher // from a Block cipher and a cryptographic Hash. func FromBlock(newCipher func(key []byte) (cipher.Block, error), newHash func() hash.Hash, blockLen, keyLen, hashLen int, diff --git a/cipher/cipher.go b/cipher/cipher.go index 05418600a..07c6f7555 100644 --- a/cipher/cipher.go +++ b/cipher/cipher.go @@ -4,5 +4,8 @@ import ( "crypto/cipher" ) +// Stream is just an alias for cipher.Stream type Stream cipher.Stream + +// Block is just an alias for cipher.Block type Block cipher.Block diff --git a/cipher/hash.go b/cipher/hash.go index 12a8240f4..f3a88a051 100644 --- a/cipher/hash.go +++ b/cipher/hash.go @@ -20,6 +20,7 @@ type cipherBlockSize interface { BlockSize() int } +// NewHash returns a new cipher-based hash func NewHash(cipher func(key []byte, options ...interface{}) kyber.Cipher, size int) hash.Hash { ch := &cipherHash{} ch.cipher = cipher diff --git a/cipher/sponge.go b/cipher/sponge.go index 3964c7d6f..0a980a7b6 100644 --- a/cipher/sponge.go +++ b/cipher/sponge.go @@ -65,7 +65,7 @@ type spongeCipher struct { pos int } -// SpongeCipher builds a general message Cipher from a Sponge function. +// FromSponge builds a general message Cipher from a Sponge function. func FromSponge(sponge Sponge, key []byte, options ...interface{}) kyber.Cipher { sc := spongeCipher{} sc.sponge = sponge @@ -87,7 +87,7 @@ func FromSponge(sponge Sponge, key []byte, options ...interface{}) kyber.Cipher // Setup normal-case domain-separation byte used for message payloads sc.setDomain(domainPayload, 0) - return kyber.Cipher{&sc} + return kyber.Cipher{CipherState: &sc} } func (sc *spongeCipher) parseOptions(options []interface{}) bool { diff --git a/cipher/stream.go b/cipher/stream.go index fba449f06..0c132b94c 100644 --- a/cipher/stream.go +++ b/cipher/stream.go @@ -27,7 +27,7 @@ const bufLen = 1024 var zeroBytes = make([]byte, bufLen) -// Construct a general message Cipher +// FromStream constructs a general message Cipher // from a Stream cipher and a cryptographic Hash. func FromStream(newStream func(key []byte) cipher.Stream, newHash func() hash.Hash, blockLen, keyLen, hashLen int, @@ -52,7 +52,7 @@ func FromStream(newStream func(key []byte) cipher.Stream, panic("no FromStream options supported yet") } - return kyber.Cipher{&sc} + return kyber.Cipher{CipherState: &sc} } func (sc *streamCipher) Partial(dst, src, key []byte) { @@ -80,10 +80,11 @@ func (sc *streamCipher) Partial(dst, src, key []byte) { // absorb cryptographic input (which may overlap with dst) if key != nil { nkey := ints.Min(n, len(key)) // # key bytes available - sc.h.Write(key[:nkey]) + // XXX check return error ? + _, _ = sc.h.Write(key[:nkey]) if n > nkey { buf := make([]byte, n-nkey) - sc.h.Write(buf) + _, _ = sc.h.Write(buf) } } } diff --git a/doc.go b/doc.go index f4e22eb09..a216f618f 100644 --- a/doc.go +++ b/doc.go @@ -1,5 +1,5 @@ /* -Package crypto provides a toolbox of advanced cryptographic primitives, +Package kyber provides a toolbox of advanced cryptographic primitives, for applications that need more than straightforward signing and encryption. The cornerstone of this toolbox is the 'kyber. sub-package, which defines kyber.interfaces to cryptographic primitives diff --git a/encoding.go b/encoding.go index 1896211e5..3f79018df 100644 --- a/encoding.go +++ b/encoding.go @@ -4,7 +4,6 @@ import ( "crypto/cipher" "encoding" "encoding/binary" - "errors" "fmt" "io" "reflect" @@ -143,7 +142,7 @@ type decoder struct { r io.Reader } -var int32Type reflect.Type = reflect.TypeOf(int32(0)) +var int32Type = reflect.TypeOf(int32(0)) // Read a series of binary objects from an io.Reader. // The objs must be a list of pointers. @@ -217,7 +216,7 @@ func (de *decoder) value(v reflect.Value, depth int) error { var i int32 err := binary.Read(de.r, binary.BigEndian, &i) if err != nil { - return errors.New(fmt.Sprintf("Error converting int to int32 ( %v )", err)) + return fmt.Errorf("Error converting int to int32 ( %v )", err) } v.SetInt(int64(i)) return err @@ -314,7 +313,7 @@ func (en *encoder) value(obj interface{}, depth int) error { return nil } -// Default implementation of reflective constructor for ciphersuites +// SuiteNew is the Default implementation of reflective constructor for ciphersuites func SuiteNew(g Group, t reflect.Type) interface{} { switch t { case tScalar: @@ -325,12 +324,12 @@ func SuiteNew(g Group, t reflect.Type) interface{} { return nil } -// Default implementation of Encoding interface Read for ciphersuites +// SuiteRead is the default implementation of Encoding interface Read for ciphersuites func SuiteRead(s Constructor, r io.Reader, objs ...interface{}) error { return BinaryEncoding{Constructor: s}.Read(r, objs) } -// Default implementation of Encoding interface Write for ciphersuites +// SuiteWrite is the default implementation of Encoding interface Write for ciphersuites func SuiteWrite(s Constructor, w io.Writer, objs ...interface{}) error { return BinaryEncoding{Constructor: s}.Write(w, objs) } diff --git a/examples/main.go b/examples/main.go index 4fe13ef5d..36b9e7b67 100644 --- a/examples/main.go +++ b/examples/main.go @@ -1,4 +1,4 @@ -// This package provides a suite of tests showing how to use the different +// Package examples provides a suite of tests showing how to use the different // abstraction and protocols provided by the dedis/kyber library. To run the // tests, simply do `go test -v`. // diff --git a/examples/sig_test.go b/examples/sig_test.go index 384f8d27c..52752c5e9 100644 --- a/examples/sig_test.go +++ b/examples/sig_test.go @@ -54,7 +54,7 @@ func SchnorrSign(suite Suite, random cipher.Stream, message []byte, // And check that hashElgamal for T and the message == c buf := bytes.Buffer{} sig := basicSig{c, r} - suite.Write(&buf, &sig) + _ = suite.Write(&buf, &sig) return buf.Bytes() } @@ -87,7 +87,7 @@ func SchnorrVerify(suite Suite, message []byte, publicKey kyber.Point, } // Example of using Schnorr -func ExampleSchnorr() { +func Example_schnorr() { // Crypto setup group := edwards25519.NewAES128SHA256Ed25519(false) rand := group.Cipher([]byte("example")) diff --git a/group.go b/group.go index e37c4890e..0d7a507e3 100644 --- a/group.go +++ b/group.go @@ -130,7 +130,7 @@ type Point interface { } /* -This interface represents an kyber.cryptographic group +Group interface represents an kyber.cryptographic group usable for Diffie-Hellman key exchange, ElGamal encryption, and the related body of public-key cryptographic algorithms and zero-knowledge proof methods. diff --git a/group/edwards25519/const.go b/group/edwards25519/const.go index 91ef334fe..2d212d1c2 100644 --- a/group/edwards25519/const.go +++ b/group/edwards25519/const.go @@ -17,7 +17,7 @@ var primeOrder, _ = new(big.Int).SetString("723700557733226221397318656304299424 // `l_minus_2` is the order of base point minus two, i.e. 2^252 + // 27742317777372353535851937790883648493 - 2, in little-endian form // This is needed to compute constant time modular inversion of scalars. -var l_minus_2_big, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250987", 10) +var lMinus2, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250987", 10) // cofactor of the curve, as a ModInt var cofactor = new(big.Int).SetInt64(8) diff --git a/group/edwards25519/curve.go b/group/edwards25519/curve.go index e336e0550..6db614abb 100644 --- a/group/edwards25519/curve.go +++ b/group/edwards25519/curve.go @@ -19,6 +19,7 @@ type Curve struct { // FullGroup bool } +// PrimeOrder implements the kyber.Group interface. func (c *Curve) PrimeOrder() bool { return true } @@ -28,12 +29,13 @@ func (c *Curve) String() string { return "Ed25519" } -// Returns 32, the size in bytes of an encoded Scalar for the Ed25519 curve. +// ScalarLen returns 32, the size in bytes of an encoded Scalar +// for the Ed25519 curve. func (c *Curve) ScalarLen() int { return 32 } -// Create a new Scalar for the prime-order subgroup of the Ed25519 curve. +// Scalar creates a new Scalar for the prime-order subgroup of the Ed25519 curve. func (c *Curve) Scalar() kyber.Scalar { //i := mod.NewInt64(0, primeOrder) //i.BO = mod.LittleEndian @@ -42,12 +44,12 @@ func (c *Curve) Scalar() kyber.Scalar { return &scalar{} } -// Returns 32, the size in bytes of an encoded Point on the Ed25519 curve. +// PointLen returns 32, the size in bytes of an encoded Point on the Ed25519 curve. func (c *Curve) PointLen() int { return 32 } -// Create a new Point on the Ed25519 curve. +// Point creates a new Point on the Ed25519 curve. func (c *Curve) Point() kyber.Point { P := new(point) //P.c = c @@ -56,7 +58,7 @@ func (c *Curve) Point() kyber.Point { // NewKey returns a formatted Ed25519 key (avoiding subgroup attack by requiring // it to be a multiple of 8) -func (s *Curve) NewKey(stream cipher.Stream) kyber.Scalar { +func (c *Curve) NewKey(stream cipher.Stream) kyber.Scalar { if stream == nil { stream = random.Stream } @@ -66,7 +68,6 @@ func (s *Curve) NewKey(stream cipher.Stream) kyber.Scalar { scalar[31] &= 0x3f scalar[31] |= 0x40 - secret := s.Scalar().SetBytes(scalar[:32]) + secret := c.Scalar().SetBytes(scalar[:32]) return secret } - diff --git a/group/edwards25519/elligator.go b/group/edwards25519/elligator.go index 1ffd5949c..1e66e51a0 100644 --- a/group/edwards25519/elligator.go +++ b/group/edwards25519/elligator.go @@ -13,7 +13,7 @@ import ( // equal the result from PublicKeyToCurve25519. func PrivateKeyToCurve25519(curve25519Private *[32]byte, privateKey *[64]byte) { h := sha512.New() - h.Write(privateKey[:32]) + _, _ = h.Write(privateKey[:32]) digest := h.Sum(nil) digest[0] &= 248 diff --git a/group/edwards25519/ge.go b/group/edwards25519/ge.go index c7f10fec7..12530875c 100644 --- a/group/edwards25519/ge.go +++ b/group/edwards25519/ge.go @@ -166,17 +166,17 @@ func (p *extendedGroupElement) String() string { // completedGroupElement methods -func (p *completedGroupElement) ToProjective(r *projectiveGroupElement) { - feMul(&r.X, &p.X, &p.T) - feMul(&r.Y, &p.Y, &p.Z) - feMul(&r.Z, &p.Z, &p.T) +func (c *completedGroupElement) ToProjective(r *projectiveGroupElement) { + feMul(&r.X, &c.X, &c.T) + feMul(&r.Y, &c.Y, &c.Z) + feMul(&r.Z, &c.Z, &c.T) } -func (p *completedGroupElement) ToExtended(r *extendedGroupElement) { - feMul(&r.X, &p.X, &p.T) - feMul(&r.Y, &p.Y, &p.Z) - feMul(&r.Z, &p.Z, &p.T) - feMul(&r.T, &p.X, &p.Y) +func (c *completedGroupElement) ToExtended(r *extendedGroupElement) { + feMul(&r.X, &c.X, &c.T) + feMul(&r.Y, &c.Y, &c.Z) + feMul(&r.Z, &c.Z, &c.T) + feMul(&r.T, &c.X, &c.Y) } func (p *preComputedGroupElement) Zero() { @@ -185,82 +185,82 @@ func (p *preComputedGroupElement) Zero() { feZero(&p.xy2d) } -func (r *completedGroupElement) Add(p *extendedGroupElement, q *cachedGroupElement) { +func (c *completedGroupElement) Add(p *extendedGroupElement, q *cachedGroupElement) { var t0 fieldElement - feAdd(&r.X, &p.Y, &p.X) - feSub(&r.Y, &p.Y, &p.X) - feMul(&r.Z, &r.X, &q.yPlusX) - feMul(&r.Y, &r.Y, &q.yMinusX) - feMul(&r.T, &q.T2d, &p.T) - feMul(&r.X, &p.Z, &q.Z) - feAdd(&t0, &r.X, &r.X) - feSub(&r.X, &r.Z, &r.Y) - feAdd(&r.Y, &r.Z, &r.Y) - feAdd(&r.Z, &t0, &r.T) - feSub(&r.T, &t0, &r.T) + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yPlusX) + feMul(&c.Y, &c.Y, &q.yMinusX) + feMul(&c.T, &q.T2d, &p.T) + feMul(&c.X, &p.Z, &q.Z) + feAdd(&t0, &c.X, &c.X) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feAdd(&c.Z, &t0, &c.T) + feSub(&c.T, &t0, &c.T) } -func (r *completedGroupElement) Sub(p *extendedGroupElement, q *cachedGroupElement) { +func (c *completedGroupElement) Sub(p *extendedGroupElement, q *cachedGroupElement) { var t0 fieldElement - feAdd(&r.X, &p.Y, &p.X) - feSub(&r.Y, &p.Y, &p.X) - feMul(&r.Z, &r.X, &q.yMinusX) - feMul(&r.Y, &r.Y, &q.yPlusX) - feMul(&r.T, &q.T2d, &p.T) - feMul(&r.X, &p.Z, &q.Z) - feAdd(&t0, &r.X, &r.X) - feSub(&r.X, &r.Z, &r.Y) - feAdd(&r.Y, &r.Z, &r.Y) - feSub(&r.Z, &t0, &r.T) - feAdd(&r.T, &t0, &r.T) + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yMinusX) + feMul(&c.Y, &c.Y, &q.yPlusX) + feMul(&c.T, &q.T2d, &p.T) + feMul(&c.X, &p.Z, &q.Z) + feAdd(&t0, &c.X, &c.X) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feSub(&c.Z, &t0, &c.T) + feAdd(&c.T, &t0, &c.T) } -func (r *completedGroupElement) MixedAdd(p *extendedGroupElement, q *preComputedGroupElement) { +func (c *completedGroupElement) MixedAdd(p *extendedGroupElement, q *preComputedGroupElement) { var t0 fieldElement - feAdd(&r.X, &p.Y, &p.X) - feSub(&r.Y, &p.Y, &p.X) - feMul(&r.Z, &r.X, &q.yPlusX) - feMul(&r.Y, &r.Y, &q.yMinusX) - feMul(&r.T, &q.xy2d, &p.T) + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yPlusX) + feMul(&c.Y, &c.Y, &q.yMinusX) + feMul(&c.T, &q.xy2d, &p.T) feAdd(&t0, &p.Z, &p.Z) - feSub(&r.X, &r.Z, &r.Y) - feAdd(&r.Y, &r.Z, &r.Y) - feAdd(&r.Z, &t0, &r.T) - feSub(&r.T, &t0, &r.T) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feAdd(&c.Z, &t0, &c.T) + feSub(&c.T, &t0, &c.T) } -func (r *completedGroupElement) MixedSub(p *extendedGroupElement, q *preComputedGroupElement) { +func (c *completedGroupElement) MixedSub(p *extendedGroupElement, q *preComputedGroupElement) { var t0 fieldElement - feAdd(&r.X, &p.Y, &p.X) - feSub(&r.Y, &p.Y, &p.X) - feMul(&r.Z, &r.X, &q.yMinusX) - feMul(&r.Y, &r.Y, &q.yPlusX) - feMul(&r.T, &q.xy2d, &p.T) + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yMinusX) + feMul(&c.Y, &c.Y, &q.yPlusX) + feMul(&c.T, &q.xy2d, &p.T) feAdd(&t0, &p.Z, &p.Z) - feSub(&r.X, &r.Z, &r.Y) - feAdd(&r.Y, &r.Z, &r.Y) - feSub(&r.Z, &t0, &r.T) - feAdd(&r.T, &t0, &r.T) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feSub(&c.Z, &t0, &c.T) + feAdd(&c.T, &t0, &c.T) } // preComputedGroupElement methods // Set to u conditionally based on b -func (t *preComputedGroupElement) CMove(u *preComputedGroupElement, b int32) { - feCMove(&t.yPlusX, &u.yPlusX, b) - feCMove(&t.yMinusX, &u.yMinusX, b) - feCMove(&t.xy2d, &u.xy2d, b) +func (p *preComputedGroupElement) CMove(u *preComputedGroupElement, b int32) { + feCMove(&p.yPlusX, &u.yPlusX, b) + feCMove(&p.yMinusX, &u.yMinusX, b) + feCMove(&p.xy2d, &u.xy2d, b) } // Set to negative of t -func (r *preComputedGroupElement) Neg(t *preComputedGroupElement) { - feCopy(&r.yPlusX, &t.yMinusX) - feCopy(&r.yMinusX, &t.yPlusX) - feNeg(&r.xy2d, &t.xy2d) +func (p *preComputedGroupElement) Neg(t *preComputedGroupElement) { + feCopy(&p.yPlusX, &t.yMinusX) + feCopy(&p.yMinusX, &t.yPlusX) + feNeg(&p.xy2d, &t.xy2d) } // cachedGroupElement methods @@ -273,11 +273,11 @@ func (r *cachedGroupElement) Zero() { } // Set to u conditionally based on b -func (t *cachedGroupElement) CMove(u *cachedGroupElement, b int32) { - feCMove(&t.yPlusX, &u.yPlusX, b) - feCMove(&t.yMinusX, &u.yMinusX, b) - feCMove(&t.Z, &u.Z, b) - feCMove(&t.T2d, &u.T2d, b) +func (r *cachedGroupElement) CMove(u *cachedGroupElement, b int32) { + feCMove(&r.yPlusX, &u.yPlusX, b) + feCMove(&r.yMinusX, &u.yMinusX, b) + feCMove(&r.Z, &u.Z, b) + feCMove(&r.T2d, &u.T2d, b) } // Set to negative of t diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index eb3eeb1b3..0f5015972 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -1,4 +1,4 @@ -// Package ed25519 provides an optimized Go implementation of a +// Package edwards25519 provides an optimized Go implementation of a // Twisted Edwards curve that is isomorphic to Curve25519. For details see: // http://ed25519.cr.yp.to/. // diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index a60c9f628..00d25b87d 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -117,7 +117,7 @@ func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { // Implementation is constant time regarding the value a, it only depends on // the modulo. for i := 255; i >= 0; i-- { - bit := l_minus_2_big.Bit(i) + bit := lMinus2.Bit(i) // square step scMul(&res.v, &res.v, &res.v) if bit == 1 { @@ -168,8 +168,6 @@ func (s *scalar) MarshalSize() int { func (s *scalar) MarshalBinary() ([]byte, error) { return s.toInt().MarshalBinary() - //buf := s.v - //return buf[:], nil } func (s *scalar) UnmarshalBinary(buf []byte) error { diff --git a/group/edwards25519/scalar_test.go b/group/edwards25519/scalar_test.go index 5c499abff..afc6dfd3f 100644 --- a/group/edwards25519/scalar_test.go +++ b/group/edwards25519/scalar_test.go @@ -19,7 +19,7 @@ func newSimpleCTScalar() kyber.Scalar { var one = new(scalar).SetInt64(1).(*scalar) var zero = new(scalar).Zero().(*scalar) -var minus_one = new(scalar).SetBytes([]byte{0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}).(*scalar) +var minusOne = new(scalar).SetBytes([]byte{0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}).(*scalar) func (s *SimpleCTScalar) Add(s1, s2 kyber.Scalar) kyber.Scalar { sc1 := s1.(*SimpleCTScalar) @@ -44,7 +44,7 @@ func (s *SimpleCTScalar) Sub(s1, s2 kyber.Scalar) kyber.Scalar { sc2 := s2.(*SimpleCTScalar) // a * b + c = -1 * a + c - scMulAdd(&s.v, &minus_one.v, &sc1.v, &sc2.v) + scMulAdd(&s.v, &minusOne.v, &sc1.v, &sc2.v) return s } diff --git a/group/edwards25519/suite.go b/group/edwards25519/suite.go index e0e9a943c..65d84afed 100644 --- a/group/edwards25519/suite.go +++ b/group/edwards25519/suite.go @@ -12,16 +12,18 @@ import ( "gopkg.in/dedis/kyber.v1/util/random" ) +// SuiteEd25519 implements some basic functionalities such as Group, HashFactory +// and CipherFactory. type SuiteEd25519 struct { Curve } -// SHA256 hash function +// Hash return a newly instanciated sha256 hash function func (s *SuiteEd25519) Hash() hash.Hash { return sha256.New() } -// SHA3/SHAKE128 Sponge Cipher +// Cipher returns the SHA3/SHAKE128 Sponge Cipher func (s *SuiteEd25519) Cipher(key []byte, options ...interface{}) kyber.Cipher { return sha3.NewShakeCipher128(key, options...) } @@ -34,10 +36,12 @@ func (s *SuiteEd25519) Write(w io.Writer, objs ...interface{}) error { return kyber.SuiteWrite(s, w, objs) } +// New implements the kyber.Encoding interface func (s *SuiteEd25519) New(t reflect.Type) interface{} { return kyber.SuiteNew(s, t) } +// NewKey implements the kyber.Group interface. func (s *SuiteEd25519) NewKey(r cipher.Stream) kyber.Scalar { if r == nil { r = random.Stream @@ -45,7 +49,8 @@ func (s *SuiteEd25519) NewKey(r cipher.Stream) kyber.Scalar { return s.Curve.Scalar().Pick(r) } -// Ciphersuite based on AES-128, SHA-256, and the Ed25519 curve. +// NewAES128SHA256Ed25519 returns a cipher suite based on AES-128, SHA-256, and +// the Ed25519 curve. func NewAES128SHA256Ed25519(fullGroup bool) *SuiteEd25519 { suite := new(SuiteEd25519) return suite diff --git a/group/mod/int.go b/group/mod/int.go index cb396036d..979d54f50 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -108,7 +108,6 @@ func (i *Int) InitString(n, d string, base int, m *big.Int) *Int { // Return the Int's integer value in decimal string representation. func (i *Int) String() string { - //return i.V.String() return hex.EncodeToString(i.V.Bytes()) } diff --git a/proof/clique.go b/proof/clique.go index ce5b67c6f..d16a082a9 100644 --- a/proof/clique.go +++ b/proof/clique.go @@ -1,3 +1,5 @@ +package proof + // A clique protocol is an kyber.on for a cryptographic protocol // in which every participant knows about and interacts directly // in lock-step with every other participant in the clique. @@ -7,7 +9,6 @@ // The basic clique protocol // assumes that nodes are always "live" and never go offline, // but we can achieve availability via threshold kyber. -package proof import "gopkg.in/dedis/kyber.v1" diff --git a/proof/context.go b/proof/context.go index 4f43b9a00..7904206ac 100644 --- a/proof/context.go +++ b/proof/context.go @@ -39,7 +39,7 @@ type ProverContext interface { PriRand(message ...interface{}) // Get private randomness } -// ProverContext represents the kyber.environment +// VerifierContext represents the kyber.environment // required by the verifier in a Sigma protocol. // // The verifier calls Get() to obtain the prover's message data, diff --git a/proof/deniable.go b/proof/deniable.go index 68b62e888..1351809a8 100644 --- a/proof/deniable.go +++ b/proof/deniable.go @@ -7,7 +7,7 @@ import ( "gopkg.in/dedis/kyber.v1" ) -// Create a Protocol implementing an interactive Sigma-protocol +// DeniableProver is a Protocol implementing an interactive Sigma-protocol // to prove a particular statement to the other participants. // Optionally the Protocol participant can also verify // the Sigma-protocol proofs of any or all of the other participants. @@ -105,7 +105,7 @@ func (dp *deniableProver) initStep() { keylen := dp.prirand.KeySize() key := make([]byte, keylen) // secret random key - dp.prirand.Read(key) + _, _ = dp.prirand.Read(key) dp.key = key msg := make([]byte, keylen) // send commitment to it diff --git a/proof/hash.go b/proof/hash.go index 026a56e56..cff658718 100644 --- a/proof/hash.go +++ b/proof/hash.go @@ -125,7 +125,7 @@ func HashProve(suite Suite, protocolName string, return ctx.Proof(), nil } -// Verifies a hash-based noninteractive proof generated with HashProve. +// HashVerify computes a hash-based noninteractive proof generated with HashProve. // The suite and protocolName must be the same as those given to HashProve. // Returns nil if the proof checks out, or an error on any failure. func HashVerify(suite Suite, protocolName string, diff --git a/proof/hash_test.go b/proof/hash_test.go index 80221a88a..db2cc2530 100644 --- a/proof/hash_test.go +++ b/proof/hash_test.go @@ -10,7 +10,7 @@ import ( // This example shows how to build classic ElGamal-style digital signatures // using the Camenisch/Stadler proof framework and HashProver. -func ExampleHashProve_1() { +func Example_hashProve1() { // Crypto setup suite := edwards25519.NewAES128SHA256Ed25519(false) @@ -74,7 +74,7 @@ func ExampleHashProve_1() { // because it uses the generic HashProver for Fiat-Shamir noninteractivity // instead of Liu/Wei/Wong's customized hash-ring structure. // -func ExampleHashProve_2() { +func Example_hashProve2() { // Crypto setup suite := edwards25519.NewAES128SHA256Ed25519(false) diff --git a/proof/proof.go b/proof/proof.go index 6e2233722..7635a1746 100644 --- a/proof/proof.go +++ b/proof/proof.go @@ -11,6 +11,9 @@ import ( "gopkg.in/dedis/kyber.v1" ) +// Suite defines the functionalities needed for this package to operate +// correctly. It provides a general abstraction to easily change the underlying +// implementations. type Suite interface { kyber.Group kyber.HashFactory @@ -330,7 +333,7 @@ func (rp *repPred) Verifier(suite Suite, type andPred []Predicate -// An And predicate states that all of the constituent sub-predicates are true. +// And predicate states that all of the constituent sub-predicates are true. // And predicates may contain Rep predicates and/or other And predicates. func And(sub ...Predicate) Predicate { and := andPred(sub) @@ -440,10 +443,9 @@ func (ap *andPred) Verifier(suite Suite, type orPred []Predicate -// An Or predicate states that the prover knows +// Or predicate states that the prover knows // at least one of the sub-predicates to be true, // but the proof does not reveal any information about which. - func Or(sub ...Predicate) Predicate { or := orPred(sub) return &or diff --git a/proof/proof_test.go b/proof/proof_test.go index be7eece54..1d58a4610 100644 --- a/proof/proof_test.go +++ b/proof/proof_test.go @@ -71,7 +71,7 @@ func TestRep(t *testing.T) { // with respect to some base B: i.e., X=x*B. // If we take X as a public key and x as its corresponding private key, // then this constitutes a "proof of ownership" of the public key X. -func ExampleRep_1() { +func Example_rep1() { pred := Rep("X", "x", "B") fmt.Println(pred.String()) // Output: X=x*B @@ -80,7 +80,7 @@ func ExampleRep_1() { // This example shows how to generate and verify noninteractive proofs // of the statement in the example above, i.e., // a proof of ownership of public key X. -func ExampleRep_2() { +func Example_rep2() { pred := Rep("X", "x", "B") fmt.Println(pred.String()) @@ -139,7 +139,7 @@ func ExampleRep_2() { // then X does not serve as a useful commitment: // the prover can trivially compute the x1 corresponding to an arbitrary x2. // -func ExampleRep_3() { +func Example_rep3() { pred := Rep("X", "x1", "B1", "x2", "B2") fmt.Println(pred.String()) // Output: X=x1*B1+x2*B2 @@ -151,7 +151,7 @@ func ExampleRep_3() { // and point Y is equal to y*B. // This predicate might be used to prove knowledge of // the private keys corresponding to two public keys X and Y, for example. -func ExampleAnd_1() { +func Example_and1() { pred := And(Rep("X", "x", "B"), Rep("Y", "y", "B")) fmt.Println(pred.String()) // Output: X=x*B && Y=y*B @@ -164,7 +164,7 @@ func ExampleAnd_1() { // Thus, the prover not only proves knowledge of the discrete logarithm // of X1 with respect to B1 and of X2 with respect to B2, // but also proves that those two discrete logarithms are equal. -func ExampleAnd_2() { +func Example_and2() { pred := And(Rep("X1", "x", "B1"), Rep("X2", "x", "B2")) fmt.Println(pred.String()) // Output: X1=x*B1 && X2=x*B2 @@ -176,7 +176,7 @@ func ExampleAnd_2() { // This predicate in essence proves knowledge of the private key // for one of two public keys X or Y, // without revealing which key the prover owns. -func ExampleOr_1() { +func Example_or1() { pred := Or(Rep("X", "x", "B"), Rep("Y", "y", "B")) fmt.Println(pred.String()) // Output: X=x*B || Y=y*B @@ -190,7 +190,7 @@ func ExampleOr_1() { // instead of generating it by scalar multiplication. // (And if the group is cryptographically secure // we won't find be able to find such a y.) -func ExampleOr_2() { +func Example_or2() { // Create an Or predicate. pred := Or(Rep("X", "x", "B"), Rep("Y", "y", "B")) fmt.Println("Predicate: " + pred.String()) diff --git a/share/pvss/pvss.go b/share/pvss/pvss.go index c1881a0d8..883fc44ba 100644 --- a/share/pvss/pvss.go +++ b/share/pvss/pvss.go @@ -22,6 +22,8 @@ import ( "gopkg.in/dedis/kyber.v1/util/random" ) +// Suite describes the functionalities needed by this package in order to +// function correctly. type Suite interface { kyber.Group kyber.HashFactory @@ -75,7 +77,7 @@ func EncShares(suite Suite, H kyber.Point, X []kyber.Point, secret kyber.Scalar, } for i := 0; i < n; i++ { - ps := &share.PubShare{indices[i], sX[i]} + ps := &share.PubShare{I: indices[i], V: sX[i]} encShares[i] = &PubVerShare{*ps, *proofs[i]} } @@ -119,7 +121,7 @@ func DecShare(suite Suite, H kyber.Point, X kyber.Point, sH kyber.Point, x kyber } G := suite.Point().Base() V := suite.Point().Mul(suite.Scalar().Inv(x), encShare.S.V) // decryption: x^{-1} * (xS) - ps := &share.PubShare{encShare.S.I, V} + ps := &share.PubShare{I: encShare.S.I, V: V} P, _, _, err := dleq.NewDLEQProof(suite, G, V, x) if err != nil { return nil, err diff --git a/sign/anon/anon.go b/sign/anon/anon.go index 4a96d4333..6821ee139 100644 --- a/sign/anon/anon.go +++ b/sign/anon/anon.go @@ -11,8 +11,8 @@ type Set []kyber.Point // A private key representing a member of an anonymity set type PriKey struct { - Set // Public key-set - Mine int // Index of the public key I own + Set // Public key-set + Mine int // Index of the public key I own Pri kyber.Scalar // Private key for that public key } diff --git a/sign/anon/enc_test.go b/sign/anon/enc_test.go index b22c8a587..0bcb04479 100644 --- a/sign/anon/enc_test.go +++ b/sign/anon/enc_test.go @@ -10,7 +10,7 @@ import ( "gopkg.in/dedis/kyber.v1/group/edwards25519" ) -func ExampleEncrypt_1() { +func Example_encrypt1() { // Crypto setup suite := edwards25519.NewAES128SHA256Ed25519(false) diff --git a/sign/anon/sig_test.go b/sign/anon/sig_test.go index a7adf60f8..6eff26af9 100644 --- a/sign/anon/sig_test.go +++ b/sign/anon/sig_test.go @@ -17,7 +17,7 @@ import ( // producing traditional ElGamal signatures: // the resulting signatures are exactly the same length // and represent essentially the same computational cost. -func ExampleSign_1() { +func Example_sign1() { // Crypto setup suite := edwards25519.NewAES128SHA256Ed25519(false) diff --git a/util/random/rand.go b/util/random/rand.go index 5744c0a02..7692bb329 100644 --- a/util/random/rand.go +++ b/util/random/rand.go @@ -101,7 +101,6 @@ func NonZeroBytes(n int, rand cipher.Stream) []byte { } } } - return randoms } type randstream struct { From 3baf54d8bb62fff67c1cf2cdd44967845e4ae635 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Wed, 21 Jun 2017 09:47:42 +0200 Subject: [PATCH 24/31] ineiti's comment round #3 --- group/curve25519/ext.go | 3 +++ group/edwards25519/curve.go | 9 --------- group/edwards25519/point.go | 2 +- group/edwards25519/scalar.go | 14 ++++++++++++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/group/curve25519/ext.go b/group/curve25519/ext.go index f0089202e..88ac2596f 100644 --- a/group/curve25519/ext.go +++ b/group/curve25519/ext.go @@ -271,6 +271,9 @@ func (P *extPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { // This implementation only supports variable-time operations func (P *extPoint) SetVarTime(varTime bool) bool { + if !vartime { + panic("constant time implementation not available") + } return true } diff --git a/group/edwards25519/curve.go b/group/edwards25519/curve.go index 6db614abb..95355067d 100644 --- a/group/edwards25519/curve.go +++ b/group/edwards25519/curve.go @@ -13,10 +13,6 @@ import ( // There are no parameters and no initialization is required // because it supports only this one specific curve. type Curve struct { - - // Set to true to use the full group of order 8Q, - // or false to use the prime-order subgroup of order Q. - // FullGroup bool } // PrimeOrder implements the kyber.Group interface. @@ -37,10 +33,6 @@ func (c *Curve) ScalarLen() int { // Scalar creates a new Scalar for the prime-order subgroup of the Ed25519 curve. func (c *Curve) Scalar() kyber.Scalar { - //i := mod.NewInt64(0, primeOrder) - //i.BO = mod.LittleEndian - //return i - return &scalar{} } @@ -52,7 +44,6 @@ func (c *Curve) PointLen() int { // Point creates a new Point on the Ed25519 curve. func (c *Curve) Point() kyber.Point { P := new(point) - //P.c = c return P } diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index 0f5015972..eb3eeb1b3 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -1,4 +1,4 @@ -// Package edwards25519 provides an optimized Go implementation of a +// Package ed25519 provides an optimized Go implementation of a // Twisted Edwards curve that is isomorphic to Curve25519. For details see: // http://ed25519.cr.yp.to/. // diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 00d25b87d..ca2b2daf5 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -19,7 +19,7 @@ import ( ) // This code is a port of the public domain, "ref10" implementation of ed25519 -// from SUPERCOP. +// from SUPERCOP. More information at https://bench.cr.yp.to/supercop.html. // The scalars are GF(2^252 + 27742317777372353535851937790883648493). @@ -40,6 +40,7 @@ func (s *scalar) Set(a kyber.Scalar) kyber.Scalar { return s } +// Clone returns a duplicate of the scalar s. func (s *scalar) Clone() kyber.Scalar { s2 := *s return &s2 @@ -51,7 +52,7 @@ func (s *scalar) setInt(i *mod.Int) kyber.Scalar { return s } -// Set to a small integer value +// SetInt64 sets the scalar to a small integer value. func (s *scalar) SetInt64(v int64) kyber.Scalar { return s.setInt(mod.NewInt64(v, primeOrder)) } @@ -140,6 +141,8 @@ func (s *scalar) SetBytes(b []byte) kyber.Scalar { return s.setInt(mod.NewIntBytes(b, primeOrder, mod.LittleEndian)) } +// SetVarTime returns always false since no variable time implementation is +// available for this scalar. func (s *scalar) SetVarTime(varTime bool) bool { return false } @@ -157,6 +160,7 @@ func (s *scalar) Bytes() []byte { return buf[i:] } +// String returns the string representation of this scalar. func (s *scalar) String() string { return s.toInt().String() } @@ -166,10 +170,12 @@ func (s *scalar) MarshalSize() int { return 32 } +// MarshalBinary returns the binary representation of this scalar. func (s *scalar) MarshalBinary() ([]byte, error) { return s.toInt().MarshalBinary() } +// UnmarshalBinary reads the binary representation of a scalar. func (s *scalar) UnmarshalBinary(buf []byte) error { if len(buf) != 32 { return errors.New("wrong size buffer") @@ -178,10 +184,14 @@ func (s *scalar) UnmarshalBinary(buf []byte) error { return nil } +// MarshalTo writes the binary representation of this scalar to the given +// writer. func (s *scalar) MarshalTo(w io.Writer) (int, error) { return marshalling.ScalarMarshalTo(s, w) } +// UnmarshalFrom reads the binary representation of a scalar from the given +// reader. func (s *scalar) UnmarshalFrom(r io.Reader) (int, error) { return marshalling.ScalarUnmarshalFrom(s, r) } From 1946b384650028d7f298c5f5a6705e536c717015 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Wed, 21 Jun 2017 10:53:16 +0200 Subject: [PATCH 25/31] screduce in own function test --- group/edwards25519/scalar_test.go | 82 +++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/group/edwards25519/scalar_test.go b/group/edwards25519/scalar_test.go index afc6dfd3f..a5416c447 100644 --- a/group/edwards25519/scalar_test.go +++ b/group/edwards25519/scalar_test.go @@ -145,3 +145,85 @@ func BenchmarkCTScalarSub(b *testing.B) { s3.Sub(s1, s2) } } + +func do_carry_uncentered(limbs [24]int64, i int) { + carry := limbs[i] >> 21 + limbs[i+1] += carry + limbs[i] -= carry << 21 +} + +// Carry excess from the `i`-th limb into the `(i+1)`-th limb. +// Postcondition: `-2^20 <= limbs[i] < 2^20`. +func do_carry_centered(limbs [24]int64, i int) { + carry := (limbs[i] + (1 << 20)) >> 21 + limbs[i+1] += carry + limbs[i] -= carry << 21 +} + +func do_reduction(limbs [24]int64, i int) { + limbs[i-12] += limbs[i] * 666643 + limbs[i-11] += limbs[i] * 470296 + limbs[i-10] += limbs[i] * 654183 + limbs[i-9] -= limbs[i] * 997805 + limbs[i-8] += limbs[i] * 136657 + limbs[i-7] -= limbs[i] * 683901 + limbs[i] = 0 +} + +func scReduce(s [24]int64) { + limbs := s + //for i in 0..23 { + for i := 0; i < 23; i++ { + do_carry_centered(limbs, i) + } + //for i in (0..23).filter(|x| x % 2 == 1) { + for i := 1; i < 23; i += 2 { + do_carry_centered(limbs, i) + } + + do_reduction(limbs, 23) + do_reduction(limbs, 22) + do_reduction(limbs, 21) + do_reduction(limbs, 20) + do_reduction(limbs, 19) + do_reduction(limbs, 18) + + //for i in (6..18).filter(|x| x % 2 == 0) { + for i := 6; i < 18; i += 2 { + do_carry_centered(limbs, i) + } + + // for i in (6..16).filter(|x| x % 2 == 1) { + for i := 7; i < 16; i += 2 { + do_carry_centered(limbs, i) + } + do_reduction(limbs, 17) + do_reduction(limbs, 16) + do_reduction(limbs, 15) + do_reduction(limbs, 14) + do_reduction(limbs, 13) + do_reduction(limbs, 12) + + //for i in (0..12).filter(|x| x % 2 == 0) { + for i := 0; i < 12; i += 2 { + do_carry_centered(limbs, i) + } + //for i in (0..12).filter(|x| x % 2 == 1) { + for i := 1; i < 12; i += 2 { + do_carry_centered(limbs, i) + } + + do_reduction(limbs, 12) + + //for i in 0..12 { + for i := 0; i < 12; i++ { + do_carry_uncentered(limbs, i) + } + + do_reduction(limbs, 12) + + //for i in 0..11 { + for i := 0; i < 11; i++ { + do_carry_uncentered(limbs, i) + } +} From 0bcf70ca356d8026189ad24d073a71d5adb2b079 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Wed, 21 Jun 2017 11:37:12 +0200 Subject: [PATCH 26/31] pushing benchmarks implementations details --- group/edwards25519/scalar_test.go | 314 +++++++++++++++++++++++++----- 1 file changed, 260 insertions(+), 54 deletions(-) diff --git a/group/edwards25519/scalar_test.go b/group/edwards25519/scalar_test.go index a5416c447..c4495b300 100644 --- a/group/edwards25519/scalar_test.go +++ b/group/edwards25519/scalar_test.go @@ -3,11 +3,13 @@ package edwards25519 import ( "testing" - "github.com/dedis/kyber/random" + "gopkg.in/dedis/kyber.v1/util/random" kyber "gopkg.in/dedis/kyber.v1" ) +// SimpleCTScalar implements the scalar operations only using `ScMulAdd` by +// plaiying with the parameters. type SimpleCTScalar struct { *scalar } @@ -53,39 +55,69 @@ func (s *SimpleCTScalar) Equal(s2 kyber.Scalar) bool { return s.scalar.Equal(s2.(*SimpleCTScalar).scalar) } +// factoredScalar implements the scalar operations using a factored version or +// `ScReduce` at the end of each operations. +type factoredScalar struct { + *scalar +} + +func newFactoredScalar() kyber.Scalar { + return &factoredScalar{&scalar{}} +} + +func (s *factoredScalar) Add(s1, s2 kyber.Scalar) kyber.Scalar { + sf1 := s1.(*factoredScalar) + sf2 := s2.(*factoredScalar) + scAddFact(&s.v, &sf1.v, &sf2.v) + return s +} + +func (s *factoredScalar) Mul(s1, s2 kyber.Scalar) kyber.Scalar { + sf1 := s1.(*factoredScalar) + sf2 := s2.(*factoredScalar) + scMulFact(&s.v, &sf1.v, &sf2.v) + return s +} + +func (s *factoredScalar) Sub(s1, s2 kyber.Scalar) kyber.Scalar { + sf1 := s1.(*factoredScalar) + sf2 := s2.(*factoredScalar) + scSubFact(&s.v, &sf1.v, &sf2.v) + return s +} + +func (s *factoredScalar) Equal(s2 kyber.Scalar) bool { + return s.scalar.Equal(s2.(*factoredScalar).scalar) +} + +func TestFactoredScalar(t *testing.T) { + testSimple(t, newFactoredScalar) +} + func TestSimpleCTScalar(t *testing.T) { - s1 := newSimpleCTScalar() - s2 := newSimpleCTScalar() - s3 := newSimpleCTScalar() + testSimple(t, newSimpleCTScalar) +} +func testSimple(t *testing.T, new func() kyber.Scalar) { + s1 := new() + s2 := new() + s3 := new() s1.SetInt64(2) s2.Pick(random.Stream) - s22 := newSimpleCTScalar().Add(s2, s2) + s22 := new().Add(s2, s2) if !s3.Mul(s1, s2).Equal(s22) { t.Fail() } -} - -func BenchmarkCTScalarSimpleAdd(b *testing.B) { - var seed = testSuite.Cipher([]byte("hello world")) - s1 := newSimpleCTScalar() - s2 := newSimpleCTScalar() - s3 := newSimpleCTScalar() - s1.Pick(seed) - s2.Pick(seed) - for i := 0; i < b.N; i++ { - s3.Add(s1, s2) - } } -func BenchmarkCTScalarAdd(b *testing.B) { +func benchScalarAdd(b *testing.B, new func() kyber.Scalar) { var seed = testSuite.Cipher([]byte("hello world")) - s1 := testSuite.Scalar() - s2 := testSuite.Scalar() - s3 := testSuite.Scalar() + s1 := new() + s2 := new() + s3 := new() s1.Pick(seed) s2.Pick(seed) @@ -94,11 +126,11 @@ func BenchmarkCTScalarAdd(b *testing.B) { } } -func BenchmarkCTScalarSimpleMul(b *testing.B) { +func benchScalarMul(b *testing.B, new func() kyber.Scalar) { var seed = testSuite.Cipher([]byte("hello world")) - s1 := newSimpleCTScalar() - s2 := newSimpleCTScalar() - s3 := newSimpleCTScalar() + s1 := new() + s2 := new() + s3 := new() s1.Pick(seed) s2.Pick(seed) @@ -107,44 +139,42 @@ func BenchmarkCTScalarSimpleMul(b *testing.B) { } } -func BenchmarkCTScalarMul(b *testing.B) { +func benchScalarSub(b *testing.B, new func() kyber.Scalar) { var seed = testSuite.Cipher([]byte("hello world")) - s1 := testSuite.Scalar() - s2 := testSuite.Scalar() - s3 := testSuite.Scalar() + s1 := new() + s2 := new() + s3 := new() s1.Pick(seed) s2.Pick(seed) for i := 0; i < b.N; i++ { - s3.Mul(s1, s2) + s3.Sub(s1, s2) } } -func BenchmarkCTScalarSimpleSub(b *testing.B) { - var seed = testSuite.Cipher([]byte("hello world")) - s1 := newSimpleCTScalar() - s2 := newSimpleCTScalar() - s3 := newSimpleCTScalar() - s1.Pick(seed) - s2.Pick(seed) +// addition - for i := 0; i < b.N; i++ { - s3.Sub(s1, s2) - } -} +func BenchmarkCTScalarAdd(b *testing.B) { benchScalarAdd(b, testSuite.Scalar) } -func BenchmarkCTScalarSub(b *testing.B) { - var seed = testSuite.Cipher([]byte("hello world")) - s1 := testSuite.Scalar() - s2 := testSuite.Scalar() - s3 := testSuite.Scalar() - s1.Pick(seed) - s2.Pick(seed) +func BenchmarkCTScalarSimpleAdd(b *testing.B) { benchScalarAdd(b, newSimpleCTScalar) } - for i := 0; i < b.N; i++ { - s3.Sub(s1, s2) - } -} +func BenchmarkCTScalarFactoredAdd(b *testing.B) { benchScalarAdd(b, newFactoredScalar) } + +// multiplication + +func BenchmarkCTScalarMul(b *testing.B) { benchScalarMul(b, testSuite.Scalar) } + +func BenchmarkCTScalarSimpleMul(b *testing.B) { benchScalarMul(b, newSimpleCTScalar) } + +func BenchmarkCTScalarFactoredMul(b *testing.B) { benchScalarMul(b, newFactoredScalar) } + +// substraction + +func BenchmarkCTScalarSub(b *testing.B) { benchScalarSub(b, testSuite.Scalar) } + +func BenchmarkCTScalarSimpleSub(b *testing.B) { benchScalarSub(b, newSimpleCTScalar) } + +func BenchmarkCTScalarFactoredSub(b *testing.B) { benchScalarSub(b, newFactoredScalar) } func do_carry_uncentered(limbs [24]int64, i int) { carry := limbs[i] >> 21 @@ -170,8 +200,7 @@ func do_reduction(limbs [24]int64, i int) { limbs[i] = 0 } -func scReduce(s [24]int64) { - limbs := s +func scReduceLimbs(limbs [24]int64) { //for i in 0..23 { for i := 0; i < 23; i++ { do_carry_centered(limbs, i) @@ -227,3 +256,180 @@ func scReduce(s [24]int64) { do_carry_uncentered(limbs, i) } } + +func scAddFact(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + + var limbs [24]int64 + limbs[0] = c0 + a0 + limbs[1] = c1 + a1 + limbs[2] = c2 + a2 + limbs[3] = c3 + a3 + limbs[4] = c4 + a4 + limbs[5] = c5 + a5 + limbs[6] = c6 + a6 + limbs[7] = c7 + a7 + limbs[8] = c8 + a8 + limbs[9] = c9 + a9 + limbs[10] = c10 + a10 + limbs[11] = c11 + a11 + limbs[12] = int64(0) + limbs[13] = int64(0) + limbs[14] = int64(0) + limbs[15] = int64(0) + limbs[16] = int64(0) + limbs[17] = int64(0) + limbs[18] = int64(0) + limbs[19] = int64(0) + limbs[20] = int64(0) + limbs[21] = int64(0) + limbs[22] = int64(0) + limbs[23] = int64(0) + + scReduceLimbs(limbs) +} + +func scMulFact(s, a, b *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := 2097151 & load3(b[:]) + b1 := 2097151 & (load4(b[2:]) >> 5) + b2 := 2097151 & (load3(b[5:]) >> 2) + b3 := 2097151 & (load4(b[7:]) >> 7) + b4 := 2097151 & (load4(b[10:]) >> 4) + b5 := 2097151 & (load3(b[13:]) >> 1) + b6 := 2097151 & (load4(b[15:]) >> 6) + b7 := 2097151 & (load3(b[18:]) >> 3) + b8 := 2097151 & load3(b[21:]) + b9 := 2097151 & (load4(b[23:]) >> 5) + b10 := 2097151 & (load3(b[26:]) >> 2) + b11 := (load4(b[28:]) >> 7) + c0 := int64(0) + c1 := int64(0) + c2 := int64(0) + c3 := int64(0) + c4 := int64(0) + c5 := int64(0) + c6 := int64(0) + c7 := int64(0) + c8 := int64(0) + c9 := int64(0) + c10 := int64(0) + c11 := int64(0) + + var limbs [24]int64 + limbs[0] = c0 + a0*b0 + limbs[1] = c1 + a0*b1 + a1*b0 + limbs[2] = c2 + a0*b2 + a1*b1 + a2*b0 + limbs[3] = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + limbs[4] = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + limbs[5] = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + limbs[6] = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + limbs[7] = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + limbs[8] = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + limbs[9] = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + limbs[10] = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + limbs[11] = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + limbs[12] = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + limbs[13] = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + limbs[14] = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + limbs[15] = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + limbs[16] = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + limbs[17] = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + limbs[18] = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + limbs[19] = a8*b11 + a9*b10 + a10*b9 + a11*b8 + limbs[20] = a9*b11 + a10*b10 + a11*b9 + limbs[21] = a10*b11 + a11*b10 + limbs[22] = a11 * b11 + limbs[23] = int64(0) + + scReduceLimbs(limbs) +} + +func scSubFact(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + + var limbs [24]int64 + limbs[0] = 1916624 - c0 + a0 + limbs[1] = 863866 - c1 + a1 + limbs[2] = 18828 - c2 + a2 + limbs[3] = 1284811 - c3 + a3 + limbs[4] = 2007799 - c4 + a4 + limbs[5] = 456654 - c5 + a5 + limbs[6] = 5 - c6 + a6 + limbs[7] = 0 - c7 + a7 + limbs[8] = 0 - c8 + a8 + limbs[9] = 0 - c9 + a9 + limbs[10] = 0 - c10 + a10 + limbs[11] = 0 - c11 + a11 + limbs[12] = int64(16) + limbs[13] = int64(0) + limbs[14] = int64(0) + limbs[15] = int64(0) + limbs[16] = int64(0) + limbs[17] = int64(0) + limbs[18] = int64(0) + limbs[19] = int64(0) + limbs[20] = int64(0) + limbs[21] = int64(0) + limbs[22] = int64(0) + limbs[23] = int64(0) + + scReduceLimbs(limbs) +} From 0d09f3c53dbb70cb6233921b7e91c75209d338b4 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Wed, 21 Jun 2017 13:46:42 +0200 Subject: [PATCH 27/31] changing setvartime API + implementations --- group.go | 10 ++++++---- group/curve25519/basic.go | 8 ++++++-- group/curve25519/ext.go | 9 +++++---- group/curve25519/proj.go | 8 ++++++-- group/edwards25519/point.go | 5 ++--- group/edwards25519/scalar.go | 7 +++++-- group/mod/int.go | 6 +++--- group/nist/curve.go | 7 +++++-- group/nist/residue.go | 7 +++++-- 9 files changed, 43 insertions(+), 24 deletions(-) diff --git a/group.go b/group.go index 0d7a507e3..a753c262f 100644 --- a/group.go +++ b/group.go @@ -61,10 +61,11 @@ type Scalar interface { Bytes() []byte // Allow or disallow use of faster variable-time implementations - // of operations on this Point, returning the old flag value. + // of operations on this Point. It returns an error if the desired + // implementation is not available for the concrete implementation. // This flag always defaults to false (constant-time only) // in implementations that can provide constant-time operations. - SetVarTime(varTime bool) bool + SetVarTime(varTime bool) error } /* @@ -123,10 +124,11 @@ type Point interface { Mul(s Scalar, p Point) Point // Allow or disallow use of faster variable-time implementations - // of operations on this Point. Returns the old flag value. + // of operations on this Point. It returns an error if the desired + // implementation is not available. // This flag always defaults to false (constant-time only) // in implementations that can provide constant-time operations. - SetVarTime(varTime bool) bool + SetVarTime(varTime bool) error } /* diff --git a/group/curve25519/basic.go b/group/curve25519/basic.go index b616cbd01..63771dda4 100644 --- a/group/curve25519/basic.go +++ b/group/curve25519/basic.go @@ -4,6 +4,7 @@ package curve25519 import ( "crypto/cipher" + "errors" "io" "math/big" @@ -122,8 +123,11 @@ func (P *basicPoint) Data() ([]byte, error) { return P.c.data(&P.x, &P.y) } -func (P *basicPoint) SetVarTime(varTime bool) bool { - return true +func (P *basicPoint) SetVarTime(varTime bool) error { + if !varTime { + return errors.New("curve25519: no constant time implementation available") + } + return nil } // Add two points using the basic unified addition laws for Edwards curves: diff --git a/group/curve25519/ext.go b/group/curve25519/ext.go index 88ac2596f..ffac8fd0c 100644 --- a/group/curve25519/ext.go +++ b/group/curve25519/ext.go @@ -5,6 +5,7 @@ package curve25519 import ( "crypto/cipher" "encoding/hex" + "errors" "io" "math/big" @@ -270,11 +271,11 @@ func (P *extPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { } // This implementation only supports variable-time operations -func (P *extPoint) SetVarTime(varTime bool) bool { - if !vartime { - panic("constant time implementation not available") +func (P *extPoint) SetVarTime(varTime bool) error { + if !varTime { + return errors.New("curve25519: constant time implementation not available") } - return true + return nil } // ExtendedCurve implements Twisted Edwards curves diff --git a/group/curve25519/proj.go b/group/curve25519/proj.go index e35785fd2..42d6fab7a 100644 --- a/group/curve25519/proj.go +++ b/group/curve25519/proj.go @@ -4,6 +4,7 @@ package curve25519 import ( "crypto/cipher" + "errors" "io" "math/big" @@ -249,8 +250,11 @@ func (P *projPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { } // This implementation only supports variable-time operations -func (P *projPoint) SetVarTime(varTime bool) bool { - return true +func (P *projPoint) SetVarTime(varTime bool) error { + if !varTime { + return errors.New("curve25519: no constant time implementation available") + } + return nil } // ProjectiveCurve implements Twisted Edwards curves diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index eb3eeb1b3..666379a1a 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -229,8 +229,7 @@ func (P *point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { return P } -func (P *point) SetVarTime(varTime bool) bool { - old := P.varTime +func (P *point) SetVarTime(varTime bool) error { P.varTime = varTime - return old + return nil } diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index ca2b2daf5..e3dadbdbe 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -143,8 +143,11 @@ func (s *scalar) SetBytes(b []byte) kyber.Scalar { // SetVarTime returns always false since no variable time implementation is // available for this scalar. -func (s *scalar) SetVarTime(varTime bool) bool { - return false +func (s *scalar) SetVarTime(varTime bool) error { + if varTime { + return errors.New("ed25519: no vartime scalar implementation available") + } + return nil } // Bytes returns a big-Endian representation of the scalar diff --git a/group/mod/int.go b/group/mod/int.go index 979d54f50..2b50055ec 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -477,9 +477,9 @@ func (i *Int) HideDecode(buf []byte) { // Allow or disallow variable-time implementation. // This implementation unfortunately provices only variable-time operations, // so the flag is hard-coded to true. -func (i *Int) SetVarTime(varTime bool) bool { +func (i *Int) SetVarTime(varTime bool) error { if !varTime { - panic("mod.Int: support only variable time arithmetic operations") + return errors.New("mod.Int: support only variable time arithmetic operations") } - return true + return nil } diff --git a/group/nist/curve.go b/group/nist/curve.go index 0743ca516..b9b7ca272 100644 --- a/group/nist/curve.go +++ b/group/nist/curve.go @@ -215,8 +215,11 @@ func (p *curvePoint) UnmarshalFrom(r io.Reader) (int, error) { } // This implementation only supports variable-time operations -func (P *curvePoint) SetVarTime(varTime bool) bool { - return true +func (P *curvePoint) SetVarTime(varTime bool) error { + if !varTime { + return errors.New("nist: nist curve point do not provide constant time implementations") + } + return nil } // interface for curve-specifc mathematical functions diff --git a/group/nist/residue.go b/group/nist/residue.go index 24bc5251e..36d454acc 100644 --- a/group/nist/residue.go +++ b/group/nist/residue.go @@ -167,8 +167,11 @@ func (p *residuePoint) UnmarshalFrom(r io.Reader) (int, error) { } // This implementation only supports variable-time operations -func (P *residuePoint) SetVarTime(varTime bool) bool { - return true +func (P *residuePoint) SetVarTime(varTime bool) error { + if !varTime { + return errors.New("nist: curve point do not provide constant time operations") + } + return nil } /* From 28a0871cc488552a56d2ab2d510149dec295de90 Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Wed, 21 Jun 2017 13:47:46 +0200 Subject: [PATCH 28/31] removed XXX comment --- cipher/stream.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cipher/stream.go b/cipher/stream.go index 0c132b94c..4ace92cf6 100644 --- a/cipher/stream.go +++ b/cipher/stream.go @@ -80,7 +80,6 @@ func (sc *streamCipher) Partial(dst, src, key []byte) { // absorb cryptographic input (which may overlap with dst) if key != nil { nkey := ints.Min(n, len(key)) // # key bytes available - // XXX check return error ? _, _ = sc.h.Write(key[:nkey]) if n > nkey { buf := make([]byte, n-nkey) From bc5f664565c52799ce94610372eeb921af2c1da8 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Wed, 21 Jun 2017 13:53:29 +0200 Subject: [PATCH 29/31] Comments --- group/mod/int.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/group/mod/int.go b/group/mod/int.go index 2b50055ec..c5322735e 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -474,9 +474,7 @@ func (i *Int) HideDecode(buf []byte) { i.V.Mod(&i.V, i.M) } -// Allow or disallow variable-time implementation. -// This implementation unfortunately provices only variable-time operations, -// so the flag is hard-coded to true. +// SetVarTime returns an error if we request constant time. func (i *Int) SetVarTime(varTime bool) error { if !varTime { return errors.New("mod.Int: support only variable time arithmetic operations") From ebd24629a8f1e8831083591b8916754575cd5f84 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Wed, 21 Jun 2017 14:13:39 +0200 Subject: [PATCH 30/31] comment-patches --- group.go | 4 ++-- group/curve25519/basic.go | 16 +++++++++------- group/curve25519/ext.go | 2 +- group/curve25519/proj.go | 2 +- group/edwards25519/point.go | 5 +++-- group/edwards25519/scalar.go | 3 +-- group/nist/curve.go | 2 +- group/nist/residue.go | 2 +- 8 files changed, 19 insertions(+), 17 deletions(-) diff --git a/group.go b/group.go index a753c262f..0c7ef5829 100644 --- a/group.go +++ b/group.go @@ -60,7 +60,7 @@ type Scalar interface { // Bytes returns a big-Endian representation of the scalar Bytes() []byte - // Allow or disallow use of faster variable-time implementations + // SetVarTime allows or disallows use of faster variable-time implementations // of operations on this Point. It returns an error if the desired // implementation is not available for the concrete implementation. // This flag always defaults to false (constant-time only) @@ -123,7 +123,7 @@ type Point interface { // If p == nil, multiply with the standard base point Base(). Mul(s Scalar, p Point) Point - // Allow or disallow use of faster variable-time implementations + // SetVarTime allows or disallows use of faster variable-time implementations // of operations on this Point. It returns an error if the desired // implementation is not available. // This flag always defaults to false (constant-time only) diff --git a/group/curve25519/basic.go b/group/curve25519/basic.go index 63771dda4..0fb42ff1d 100644 --- a/group/curve25519/basic.go +++ b/group/curve25519/basic.go @@ -32,7 +32,7 @@ func (P *basicPoint) String() string { return P.c.pointString(&P.x, &P.y) } -// Create a new ModInt representing a coordinate on this curve, +// coord creates a new ModInt representing a coordinate on this curve, // with a given int64 integer value for constant-initialization convenience. func (P *basicPoint) coord(v int64) *mod.Int { return mod.NewInt64(v, &P.c.P) @@ -42,12 +42,12 @@ func (P *basicPoint) MarshalSize() int { return (P.y.M.BitLen() + 7 + 1) / 8 } -// Encode an Edwards curve point. +// MarshalBinary encodew an Edwards curve point. func (P *basicPoint) MarshalBinary() ([]byte, error) { return P.c.encodePoint(&P.x, &P.y), nil } -// Decode an Edwards curve point. +// UnmarshalBinary decodes an Edwards curve point. func (P *basicPoint) UnmarshalBinary(b []byte) error { return P.c.decodePoint(b, &P.x, &P.y) } @@ -72,7 +72,7 @@ func (P *basicPoint) HideDecode(rep []byte) { P.c.hide.HideDecode(P, rep) } -// Equality test for two Points on the same curve +// Equal tests for two Points on the same curve func (P *basicPoint) Equal(P2 kyber.Point) bool { E2 := P2.(*basicPoint) return P.x.Equal(&E2.x) && P.y.Equal(&E2.y) @@ -87,19 +87,20 @@ func (P *basicPoint) Set(P2 kyber.Point) kyber.Point { return P } +// Clone returns the given point func (P *basicPoint) Clone() kyber.Point { p2 := new(basicPoint) p2.Set(P) return p2 } -// Set to the neutral element, which is (0,1) for twisted Edwards curves. +// Null sets to the neutral element, which is (0,1) for twisted Edwards curves. func (P *basicPoint) Null() kyber.Point { P.Set(&P.c.null) return P } -// Set to the standard base point for this curve +// Base sets to the standard base point for this curve func (P *basicPoint) Base() kyber.Point { P.Set(&P.c.base) return P @@ -118,11 +119,12 @@ func (P *basicPoint) Pick(rand cipher.Stream) kyber.Point { return P.Embed(nil, rand) } -// Extract embedded data from a point group element +// Data extracts embedded data from a point group element func (P *basicPoint) Data() ([]byte, error) { return P.c.data(&P.x, &P.y) } +// SetVarTime returns an error if we ask for constant-time implementation. func (P *basicPoint) SetVarTime(varTime bool) error { if !varTime { return errors.New("curve25519: no constant time implementation available") diff --git a/group/curve25519/ext.go b/group/curve25519/ext.go index ffac8fd0c..c0f0c0069 100644 --- a/group/curve25519/ext.go +++ b/group/curve25519/ext.go @@ -270,7 +270,7 @@ func (P *extPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { return P } -// This implementation only supports variable-time operations +// SetVarTime returns an error if we require constant time operations. func (P *extPoint) SetVarTime(varTime bool) error { if !varTime { return errors.New("curve25519: constant time implementation not available") diff --git a/group/curve25519/proj.go b/group/curve25519/proj.go index 42d6fab7a..d0b3c1a04 100644 --- a/group/curve25519/proj.go +++ b/group/curve25519/proj.go @@ -249,7 +249,7 @@ func (P *projPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { return P } -// This implementation only supports variable-time operations +// SetVarTime returns an error if we request constant-time operations. func (P *projPoint) SetVarTime(varTime bool) error { if !varTime { return errors.New("curve25519: no constant time implementation available") diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index 666379a1a..91cf96ae3 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -204,14 +204,14 @@ func (P *point) Sub(P1, P2 kyber.Point) kyber.Point { return P } -// Find the negative of point A. +// Neg finds the negative of point A. // For Edwards curves, the negative of (x,y) is (-x,y). func (P *point) Neg(A kyber.Point) kyber.Point { P.ge.Neg(&A.(*point).ge) return P } -// Multiply point p by scalar s using the repeated doubling method. +// Mul multiplies point p by scalar s using the repeated doubling method. func (P *point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { a := &s.(*scalar).v @@ -229,6 +229,7 @@ func (P *point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { return P } +// SetVarTime allows for optimized, non-constant time implementation. func (P *point) SetVarTime(varTime bool) error { P.varTime = varTime return nil diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index e3dadbdbe..e00b144a2 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -141,8 +141,7 @@ func (s *scalar) SetBytes(b []byte) kyber.Scalar { return s.setInt(mod.NewIntBytes(b, primeOrder, mod.LittleEndian)) } -// SetVarTime returns always false since no variable time implementation is -// available for this scalar. +// SetVarTime returns an error if we request constant-time operations. func (s *scalar) SetVarTime(varTime bool) error { if varTime { return errors.New("ed25519: no vartime scalar implementation available") diff --git a/group/nist/curve.go b/group/nist/curve.go index b9b7ca272..3670e90ce 100644 --- a/group/nist/curve.go +++ b/group/nist/curve.go @@ -214,7 +214,7 @@ func (p *curvePoint) UnmarshalFrom(r io.Reader) (int, error) { return marshalling.PointUnmarshalFrom(p, r) } -// This implementation only supports variable-time operations +// SetVarTime returns an error if we request constant-var operations. func (P *curvePoint) SetVarTime(varTime bool) error { if !varTime { return errors.New("nist: nist curve point do not provide constant time implementations") diff --git a/group/nist/residue.go b/group/nist/residue.go index 36d454acc..f10ce3c26 100644 --- a/group/nist/residue.go +++ b/group/nist/residue.go @@ -166,7 +166,7 @@ func (p *residuePoint) UnmarshalFrom(r io.Reader) (int, error) { return marshalling.PointUnmarshalFrom(p, r) } -// This implementation only supports variable-time operations +// SetVarTime returns an error if we request constant-time operations. func (P *residuePoint) SetVarTime(varTime bool) error { if !varTime { return errors.New("nist: curve point do not provide constant time operations") From 7b0afebdaa0961b2603549f0f2b7f1b2563eb3da Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Thu, 29 Jun 2017 13:14:42 +0200 Subject: [PATCH 31/31] golint is happy. Added exception for NORX code --- Makefile | 2 +- cipher/norx/check/check.go | 3 ++ cipher/norx/norx.go | 3 ++ cipher/norx/sponge.go | 2 +- cipher/norx/utils.go | 3 ++ group/curve25519/basic_test.go | 10 ++--- group/curve25519/curve_test.go | 38 +++++++++--------- group/edwards25519/curve_test.go | 2 +- group/edwards25519/point.go | 2 +- group/edwards25519/scalar_test.go | 50 +++++++++++------------ group/mod/int.go | 66 +++++++++++++++++-------------- group/mod/jacobi.go | 2 +- group/mod/sqrt.go | 4 +- group/nist/group_test.go | 4 +- proof/dleq/dleq.go | 19 ++++----- share/dkg/dkg.go | 23 +++++------ share/dkg/dkg_test.go | 4 +- share/dss/dss.go | 23 +++++------ share/dss/dss_test.go | 2 +- share/poly.go | 12 +++--- share/pvss/pvss.go | 2 +- share/vss/dh.go | 8 ++-- share/vss/vss.go | 29 +++++++------- sign/anon/anon.go | 4 +- sign/anon/sig.go | 15 ++++--- sign/anon/skeme.go | 12 +++--- sign/anon/suite.go | 1 + sign/cosi/cosi_test.go | 4 +- sign/eddsa/eddsa.go | 22 ++++++----- sign/schnorr/schnorr.go | 2 +- util/bytes/doc.go | 2 +- util/bytes/replace.go | 18 +++++---- util/key/key.go | 24 +++++------ util/marshalling/marshal.go | 8 ++-- util/random/rand.go | 22 +++++------ util/test/cipher.go | 32 ++++++++------- util/test/group.go | 28 ++++++++++--- util/test/test.go | 22 +++++------ 38 files changed, 289 insertions(+), 240 deletions(-) diff --git a/Makefile b/Makefile index f3344393b..2c0b99366 100644 --- a/Makefile +++ b/Makefile @@ -40,4 +40,4 @@ test_verbose: test_goverall: ${GOPATH}/bin/goveralls -service=travis-ci -test: test_fmt test_goverall +test: test_fmt test_lint test_goverall diff --git a/cipher/norx/check/check.go b/cipher/norx/check/check.go index 64777b5b7..5d1ab4720 100644 --- a/cipher/norx/check/check.go +++ b/cipher/norx/check/check.go @@ -10,6 +10,9 @@ package check +// XXX hackish way of making golint ignore this file +// Code generated by norx authors. DO NOT EDIT. + import norx "github.com/daeinar/norx-go/aead" import "fmt" diff --git a/cipher/norx/norx.go b/cipher/norx/norx.go index c890d9da2..0a120ac7b 100644 --- a/cipher/norx/norx.go +++ b/cipher/norx/norx.go @@ -10,6 +10,9 @@ package norx +// XXX hackish way of making golint ignore this file +// Code generated by norx authors. DO NOT EDIT. + const ( NORX_W = 64 // wordsize NORX_R = 4 // number of rounds diff --git a/cipher/norx/sponge.go b/cipher/norx/sponge.go index 52950ecf2..265f476c3 100644 --- a/cipher/norx/sponge.go +++ b/cipher/norx/sponge.go @@ -1,4 +1,4 @@ -// Package NORX implements the experimental NORX cipher. +// Package norx implements the experimental NORX cipher. // For details on the NORX cipher see https://norx.io // This package is very experimental and NOT for use in prodution systems. // diff --git a/cipher/norx/utils.go b/cipher/norx/utils.go index 45596db1e..d15dcf7d7 100644 --- a/cipher/norx/utils.go +++ b/cipher/norx/utils.go @@ -10,6 +10,9 @@ package norx +// XXX hackish way of making golint ignore this file +// Code generated by norx authors. DO NOT EDIT. + func LOAD64(x []uint8) uint64 { return (uint64(x[0]) << 0) | (uint64(x[1]) << 8) | diff --git a/group/curve25519/basic_test.go b/group/curve25519/basic_test.go index b07e9f774..61f7a55c0 100644 --- a/group/curve25519/basic_test.go +++ b/group/curve25519/basic_test.go @@ -14,7 +14,7 @@ func TestBasic25519(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestGroup(new(BasicCurve).Init(Param25519(), false)) + test.Group(new(BasicCurve).Init(Param25519(), false)) } } @@ -24,7 +24,7 @@ func TestCompareBasicProjective25519(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(BasicCurve).Init(Param25519(), false), new(ProjectiveCurve).Init(Param25519(), false)) } @@ -34,7 +34,7 @@ func TestCompareBasicProjectiveE382(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(BasicCurve).Init(ParamE382(), false), new(ProjectiveCurve).Init(ParamE382(), false)) } @@ -44,7 +44,7 @@ func TestCompareBasicProjective41417(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(BasicCurve).Init(Param41417(), false), new(ProjectiveCurve).Init(Param41417(), false)) } @@ -54,7 +54,7 @@ func TestCompareBasicProjectiveE521(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } else { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(BasicCurve).Init(ParamE521(), false), new(ProjectiveCurve).Init(ParamE521(), false)) } diff --git a/group/curve25519/curve_test.go b/group/curve25519/curve_test.go index 4022bea52..5827575a2 100644 --- a/group/curve25519/curve_test.go +++ b/group/curve25519/curve_test.go @@ -17,98 +17,98 @@ var testSuite = NewAES128SHA256Ed25519(false) // Test each curve implementation of the Ed25519 curve. func TestProjective25519(t *testing.T) { - test.TestGroup(new(ProjectiveCurve).Init(Param25519(), false)) + test.GroupTest(new(ProjectiveCurve).Init(Param25519(), false)) } func TestExtended25519(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(Param25519(), false)) + test.GroupTest(new(ExtendedCurve).Init(Param25519(), false)) } func TestEd25519(t *testing.T) { - test.TestGroup(new(edwards25519.Curve)) + test.GroupTest(new(edwards25519.Curve)) } // Test the Extended coordinates implementation of each curve. func Test1174(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(Param1174(), false)) + test.GroupTest(new(ExtendedCurve).Init(Param1174(), false)) } func Test25519(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(Param25519(), false)) + test.GroupTest(new(ExtendedCurve).Init(Param25519(), false)) } func TestE382(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(ParamE382(), false)) + test.GroupTest(new(ExtendedCurve).Init(ParamE382(), false)) } func Test4147(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(Param41417(), false)) + test.GroupTest(new(ExtendedCurve).Init(Param41417(), false)) } func TestE521(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(ParamE521(), false)) + test.GroupTest(new(ExtendedCurve).Init(ParamE521(), false)) } // Test the full-group-order Extended coordinates versions of each curve // for which a full-group-order base point is defined. func TestFullOrder1174(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(Param1174(), true)) + test.GroupTest(new(ExtendedCurve).Init(Param1174(), true)) } func TestFullOrder25519(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(Param25519(), true)) + test.GroupTest(new(ExtendedCurve).Init(Param25519(), true)) } func TestFullOrderE382(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(ParamE382(), true)) + test.GroupTest(new(ExtendedCurve).Init(ParamE382(), true)) } func TestFullOrder4147(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(Param41417(), true)) + test.GroupTest(new(ExtendedCurve).Init(Param41417(), true)) } func TestFullOrderE521(t *testing.T) { - test.TestGroup(new(ExtendedCurve).Init(ParamE521(), true)) + test.GroupTest(new(ExtendedCurve).Init(ParamE521(), true)) } // Test ExtendedCurve versus ProjectiveCurve implementations func TestCompareProjectiveExtended25519(t *testing.T) { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(ProjectiveCurve).Init(Param25519(), false), new(ExtendedCurve).Init(Param25519(), false)) } func TestCompareProjectiveExtendedE382(t *testing.T) { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(ProjectiveCurve).Init(ParamE382(), false), new(ExtendedCurve).Init(ParamE382(), false)) } func TestCompareProjectiveExtended41417(t *testing.T) { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(ProjectiveCurve).Init(Param41417(), false), new(ExtendedCurve).Init(Param41417(), false)) } func TestCompareProjectiveExtendedE521(t *testing.T) { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(ProjectiveCurve).Init(ParamE521(), false), new(ExtendedCurve).Init(ParamE521(), false)) } // Test Ed25519 versus ExtendedCurve implementations of Curve25519. func TestCompareEd25519(t *testing.T) { - test.TestCompareGroups(testSuite.Cipher, + test.CompareGroups(testSuite.Cipher, new(ExtendedCurve).Init(Param25519(), false), new(edwards25519.Curve)) } // Test point hiding functionality -func testHiding(g kyber.Group, k int) { +func testHiding(g kyber.GroupTest, k int) { rand := random.Stream // Test conversion from random strings to points and back diff --git a/group/edwards25519/curve_test.go b/group/edwards25519/curve_test.go index 1050cbdbb..ccaf297f5 100644 --- a/group/edwards25519/curve_test.go +++ b/group/edwards25519/curve_test.go @@ -9,7 +9,7 @@ import ( var testSuite = NewAES128SHA256Ed25519(false) var groupBench = test.NewGroupBench(testSuite) -func TestSuite(t *testing.T) { test.TestSuite(testSuite) } +func TestSuite(t *testing.T) { test.SuiteTest(testSuite) } func BenchmarkScalarAdd(b *testing.B) { groupBench.ScalarAdd(b.N) } func BenchmarkScalarSub(b *testing.B) { groupBench.ScalarSub(b.N) } diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index 91cf96ae3..f11401951 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -1,4 +1,4 @@ -// Package ed25519 provides an optimized Go implementation of a +// Package edwards25519 provides an optimized Go implementation of a // Twisted Edwards curve that is isomorphic to Curve25519. For details see: // http://ed25519.cr.yp.to/. // diff --git a/group/edwards25519/scalar_test.go b/group/edwards25519/scalar_test.go index c4495b300..edadf953e 100644 --- a/group/edwards25519/scalar_test.go +++ b/group/edwards25519/scalar_test.go @@ -176,7 +176,7 @@ func BenchmarkCTScalarSimpleSub(b *testing.B) { benchScalarSub(b, newSimpleCTSca func BenchmarkCTScalarFactoredSub(b *testing.B) { benchScalarSub(b, newFactoredScalar) } -func do_carry_uncentered(limbs [24]int64, i int) { +func doCarryUncentered(limbs [24]int64, i int) { carry := limbs[i] >> 21 limbs[i+1] += carry limbs[i] -= carry << 21 @@ -184,13 +184,13 @@ func do_carry_uncentered(limbs [24]int64, i int) { // Carry excess from the `i`-th limb into the `(i+1)`-th limb. // Postcondition: `-2^20 <= limbs[i] < 2^20`. -func do_carry_centered(limbs [24]int64, i int) { +func doCarryCentered(limbs [24]int64, i int) { carry := (limbs[i] + (1 << 20)) >> 21 limbs[i+1] += carry limbs[i] -= carry << 21 } -func do_reduction(limbs [24]int64, i int) { +func doReduction(limbs [24]int64, i int) { limbs[i-12] += limbs[i] * 666643 limbs[i-11] += limbs[i] * 470296 limbs[i-10] += limbs[i] * 654183 @@ -203,57 +203,57 @@ func do_reduction(limbs [24]int64, i int) { func scReduceLimbs(limbs [24]int64) { //for i in 0..23 { for i := 0; i < 23; i++ { - do_carry_centered(limbs, i) + doCarryCentered(limbs, i) } //for i in (0..23).filter(|x| x % 2 == 1) { for i := 1; i < 23; i += 2 { - do_carry_centered(limbs, i) + doCarryCentered(limbs, i) } - do_reduction(limbs, 23) - do_reduction(limbs, 22) - do_reduction(limbs, 21) - do_reduction(limbs, 20) - do_reduction(limbs, 19) - do_reduction(limbs, 18) + doReduction(limbs, 23) + doReduction(limbs, 22) + doReduction(limbs, 21) + doReduction(limbs, 20) + doReduction(limbs, 19) + doReduction(limbs, 18) //for i in (6..18).filter(|x| x % 2 == 0) { for i := 6; i < 18; i += 2 { - do_carry_centered(limbs, i) + doCarryCentered(limbs, i) } // for i in (6..16).filter(|x| x % 2 == 1) { for i := 7; i < 16; i += 2 { - do_carry_centered(limbs, i) + doCarryCentered(limbs, i) } - do_reduction(limbs, 17) - do_reduction(limbs, 16) - do_reduction(limbs, 15) - do_reduction(limbs, 14) - do_reduction(limbs, 13) - do_reduction(limbs, 12) + doReduction(limbs, 17) + doReduction(limbs, 16) + doReduction(limbs, 15) + doReduction(limbs, 14) + doReduction(limbs, 13) + doReduction(limbs, 12) //for i in (0..12).filter(|x| x % 2 == 0) { for i := 0; i < 12; i += 2 { - do_carry_centered(limbs, i) + doCarryCentered(limbs, i) } //for i in (0..12).filter(|x| x % 2 == 1) { for i := 1; i < 12; i += 2 { - do_carry_centered(limbs, i) + doCarryCentered(limbs, i) } - do_reduction(limbs, 12) + doReduction(limbs, 12) //for i in 0..12 { for i := 0; i < 12; i++ { - do_carry_uncentered(limbs, i) + doCarryUncentered(limbs, i) } - do_reduction(limbs, 12) + doReduction(limbs, 12) //for i in 0..11 { for i := 0; i < 11; i++ { - do_carry_uncentered(limbs, i) + doCarryUncentered(limbs, i) } } diff --git a/group/mod/int.go b/group/mod/int.go index c5322735e..6b550e9de 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -16,11 +16,14 @@ import ( var one = big.NewInt(1) var two = big.NewInt(2) +// ByteOrder denotes what is the endianness used to represent an Int. type ByteOrder bool const ( + // LittleEndian endianness LittleEndian ByteOrder = true - BigEndian ByteOrder = false + // BigEndian endianness + BigEndian ByteOrder = false ) // Int is a generic implementation of finite field arithmetic @@ -70,7 +73,7 @@ func NewIntString(n, d string, base int, m *big.Int) *Int { return new(Int).InitString(n, d, base, m) } -// Initialize a Int with a given big.Int value and modulus pointer. +// Init a Int with a given big.Int value and modulus pointer. // Note that the value is copied; the modulus is not. func (i *Int) Init(V *big.Int, m *big.Int) *Int { i.M = m @@ -79,7 +82,7 @@ func (i *Int) Init(V *big.Int, m *big.Int) *Int { return i } -// Initialize a Int with an int64 value and big.Int modulus. +// Init64 creates an Int with an int64 value and big.Int modulus. func (i *Int) Init64(v int64, m *big.Int) *Int { i.M = m i.BO = BigEndian @@ -87,7 +90,7 @@ func (i *Int) Init64(v int64, m *big.Int) *Int { return i } -// Initialize to a number represented in a big-endian byte string. +// InitBytes init the Int to a number represented in a big-endian byte string. func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { i.M = m i.BO = byteOrder @@ -95,7 +98,7 @@ func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { return i } -// Initialize a Int to a rational fraction n/d +// InitString inits the Int to a rational fraction n/d // specified with a pair of strings in a given base. func (i *Int) InitString(n, d string, base int, m *big.Int) *Int { i.M = m @@ -111,7 +114,7 @@ func (i *Int) String() string { return hex.EncodeToString(i.V.Bytes()) } -// Set value to a rational fraction n/d represented by a pair of strings. +// SetString sets the Int to a rational fraction n/d represented by a pair of strings. // If d == "", then the denominator is taken to be 1. // Returns (i,true) on success, or // (nil,false) if either string fails to parse. @@ -130,17 +133,17 @@ func (i *Int) SetString(n, d string, base int) (*Int, bool) { return i, true } -// Compare two Ints for equality or inequality +// Cmp compares two Ints for equality or inequality func (i *Int) Cmp(s2 kyber.Scalar) int { return i.V.Cmp(&s2.(*Int).V) } -// Test two Ints for equality +// Equal returns true if the two Ints are equal func (i *Int) Equal(s2 kyber.Scalar) bool { return i.V.Cmp(&s2.(*Int).V) == 0 } -// Returns true if the integer value is nonzero. +// Nonzero returns true if the integer value is nonzero. func (i *Int) Nonzero() bool { return i.V.Sign() != 0 } @@ -155,51 +158,52 @@ func (i *Int) Set(a kyber.Scalar) kyber.Scalar { return i } +// Clone returns a separate duplicate of this Int. func (i *Int) Clone() kyber.Scalar { ni := new(Int).Init(&i.V, i.M) ni.BO = i.BO return ni } -// Set to the value 0. The modulus must already be initialized. +// Zero set the Int to the value 0. The modulus must already be initialized. func (i *Int) Zero() kyber.Scalar { i.V.SetInt64(0) return i } -// Set to the value 1. The modulus must already be initialized. +// One sets the Int to the value 1. The modulus must already be initialized. func (i *Int) One() kyber.Scalar { i.V.SetInt64(1) return i } -// Set to an arbitrary 64-bit "small integer" value. +// SetInt64 sets the Int to an arbitrary 64-bit "small integer" value. // The modulus must already be initialized. func (i *Int) SetInt64(v int64) kyber.Scalar { i.V.SetInt64(v).Mod(&i.V, i.M) return i } -// Return the int64 representation of the value. +// Int64 returns the int64 representation of the value. // If the value is not representable in an int64 the result is undefined. func (i *Int) Int64() int64 { return i.V.Int64() } -// Set to an arbitrary uint64 value. +// SetUint64 sets the Int to an arbitrary uint64 value. // The modulus must already be initialized. func (i *Int) SetUint64(v uint64) kyber.Scalar { i.V.SetUint64(v).Mod(&i.V, i.M) return i } -// Return the uint64 representation of the value. +// Uint64 returns the uint64 representation of the value. // If the value is not representable in an uint64 the result is undefined. func (i *Int) Uint64() uint64 { return i.V.Uint64() } -// Set target to a + b mod M, where M is a's modulus.. +// Add sets the target to a + b mod M, where M is a's modulus.. func (i *Int) Add(a, b kyber.Scalar) kyber.Scalar { ai := a.(*Int) bi := b.(*Int) @@ -208,7 +212,7 @@ func (i *Int) Add(a, b kyber.Scalar) kyber.Scalar { return i } -// Set target to a - b mod M. +// Sub sets the target to a - b mod M. // Target receives a's modulus. func (i *Int) Sub(a, b kyber.Scalar) kyber.Scalar { ai := a.(*Int) @@ -218,7 +222,7 @@ func (i *Int) Sub(a, b kyber.Scalar) kyber.Scalar { return i } -// Set to -a mod M. +// Neg sets the target to -a mod M. func (i *Int) Neg(a kyber.Scalar) kyber.Scalar { ai := a.(*Int) i.M = ai.M @@ -230,7 +234,7 @@ func (i *Int) Neg(a kyber.Scalar) kyber.Scalar { return i } -// Set to a * b mod M. +// Mul sets the target to a * b mod M. // Target receives a's modulus. func (i *Int) Mul(a, b kyber.Scalar) kyber.Scalar { ai := a.(*Int) @@ -240,7 +244,7 @@ func (i *Int) Mul(a, b kyber.Scalar) kyber.Scalar { return i } -// Set to a * b^-1 mod M, where b^-1 is the modular inverse of b. +// Div sets the target to a * b^-1 mod M, where b^-1 is the modular inverse of b. func (i *Int) Div(a, b kyber.Scalar) kyber.Scalar { ai := a.(*Int) bi := b.(*Int) @@ -251,7 +255,7 @@ func (i *Int) Div(a, b kyber.Scalar) kyber.Scalar { return i } -// Set to the modular inverse of a with respect to modulus M. +// Inv sets the target to the modular inverse of a with respect to modulus M. func (i *Int) Inv(a kyber.Scalar) kyber.Scalar { ai := a.(*Int) i.M = ai.M @@ -259,7 +263,7 @@ func (i *Int) Inv(a kyber.Scalar) kyber.Scalar { return i } -// Set to a^e mod M, +// Exp sets the target to a^e mod M, // where e is an arbitrary big.Int exponent (not necessarily 0 <= e < M). func (i *Int) Exp(a kyber.Scalar, e *big.Int) kyber.Scalar { ai := a.(*Int) @@ -281,7 +285,7 @@ func (i *Int) legendre() int { return v.Sign() } -// Set to the Jacobi symbol of (a/M), which indicates whether a is +// Jacobi computes the Jacobi symbol of (a/M), which indicates whether a is // zero (0), a positive square in M (1), or a non-square in M (-1). func (i *Int) Jacobi(as kyber.Scalar) kyber.Scalar { ai := as.(*Int) @@ -290,7 +294,7 @@ func (i *Int) Jacobi(as kyber.Scalar) kyber.Scalar { return i } -// Compute some square root of a mod M of one exists. +// Sqrt computes some square root of a mod M of one exists. // Assumes the modulus M is an odd prime. // Returns true on success, false if input a is not a square. // (This really should be part of Go's big.Int library.) @@ -307,7 +311,7 @@ func (i *Int) Pick(rand cipher.Stream) kyber.Scalar { return i } -// Return the length in bytes of encoded integers with modulus M. +// MarshalSize returns the length in bytes of encoded integers with modulus M. // The length of encoded Ints depends only on the size of the modulus, // and not on the the value of the encoded integer, // making the encoding is fixed-length for simplicity and security. @@ -315,7 +319,7 @@ func (i *Int) MarshalSize() int { return (i.M.BitLen() + 7) / 8 } -// Encode the value of this Int into a byte-slice exactly Len() bytes long. +// MarshalBinary encodes the value of this Int into a byte-slice exactly Len() bytes long. func (i *Int) MarshalBinary() ([]byte, error) { l := i.MarshalSize() b := i.V.Bytes() // may be shorter than l @@ -333,7 +337,7 @@ func (i *Int) MarshalBinary() ([]byte, error) { return b, nil } -// Attempt to decode a Int from a byte-slice buffer. +// UnmarshalBinary tries to decode a Int from a byte-slice buffer. // Returns an error if the buffer is not exactly Len() bytes long // or if the contents of the buffer represents an out-of-range integer. func (i *Int) UnmarshalBinary(buf []byte) error { @@ -351,15 +355,17 @@ func (i *Int) UnmarshalBinary(buf []byte) error { return nil } +// MarshalTo encodes this Int to the given Writer. func (i *Int) MarshalTo(w io.Writer) (int, error) { return marshalling.ScalarMarshalTo(i, w) } +// UnmarshalFrom tries to decode an Int from the given Reader. func (i *Int) UnmarshalFrom(r io.Reader) (int, error) { return marshalling.ScalarUnmarshalFrom(i, r) } -// Encode the value of this Int into a big-endian byte-slice +// BigEndian encodes the value of this Int into a big-endian byte-slice // at least min bytes but no more than max bytes long. // Panics if max != 0 and the Int cannot be represented in max bytes. func (i *Int) BigEndian(min, max int) []byte { @@ -398,7 +404,7 @@ func (i *Int) Bytes() []byte { return buff } -// Encode the value of this Int into a little-endian byte-slice +// LittleEndian encodes the value of this Int into a little-endian byte-slice // at least min bytes but no more than max bytes long. // Panics if max != 0 and the Int cannot be represented in max bytes. func (i *Int) LittleEndian(min, max int) []byte { @@ -420,7 +426,7 @@ func (i *Int) LittleEndian(min, max int) []byte { return buf } -// Return the length in bytes of a uniform byte-string encoding of this Int, +// HideLen returns the length in bytes of a uniform byte-string encoding of this Int, // satisfying the requirements of the Hiding interface. // For a Int this is always the same length as the normal encoding. func (i *Int) HideLen() int { diff --git a/group/mod/jacobi.go b/group/mod/jacobi.go index a19c1c84c..852d30126 100644 --- a/group/mod/jacobi.go +++ b/group/mod/jacobi.go @@ -4,7 +4,7 @@ import ( "math/big" ) -// Compute the Jacobi symbol of (x/y) using Euclid's algorithm. +// Jacobi computes the Jacobi symbol of (x/y) using Euclid's algorithm. // This is usually much faster modular multiplication via Euler's criterion. func Jacobi(x, y *big.Int) int { diff --git a/group/mod/sqrt.go b/group/mod/sqrt.go index 6475474de..88e533d1a 100644 --- a/group/mod/sqrt.go +++ b/group/mod/sqrt.go @@ -1,4 +1,4 @@ -// Package dissent/math contains big.Int arithmetic functions +// Package mod contains big.Int arithmetic functions // that probably belong in Go's math/big package. package mod @@ -8,7 +8,7 @@ import ( var zero = big.NewInt(0) -// Set z to one of the square roots of a modulo p if a square root exists. +// Sqrt sets z to one of the square roots of a modulo p if a square root exists. // The modulus p must be an odd prime. // Returns true on success, false if input a is not a square modulo p. func Sqrt(z *big.Int, a *big.Int, p *big.Int) bool { diff --git a/group/nist/group_test.go b/group/nist/group_test.go index 303380817..a4a41596b 100644 --- a/group/nist/group_test.go +++ b/group/nist/group_test.go @@ -10,12 +10,12 @@ import ( var testQR512 = NewAES128SHA256QR512() -func TestQR512(t *testing.T) { test.TestSuite(testQR512) } +func TestQR512(t *testing.T) { test.SuiteTest(testQR512) } var testP256 = NewAES128SHA256P256() var benchP256 = test.NewGroupBench(testP256) -func TestP256(t *testing.T) { test.TestSuite(testP256) } +func TestP256(t *testing.T) { test.SuiteTest(testP256) } func BenchmarkScalarAdd(b *testing.B) { benchP256.ScalarAdd(b.N) } func BenchmarkScalarSub(b *testing.B) { benchP256.ScalarSub(b.N) } diff --git a/proof/dleq/dleq.go b/proof/dleq/dleq.go index 6f5acba98..af0eb6947 100644 --- a/proof/dleq/dleq.go +++ b/proof/dleq/dleq.go @@ -1,4 +1,4 @@ -// This package provides functionality to create and verify non-interactive +// Package dleq provides functionality to create and verify non-interactive // zero-knowledge (NIZK) proofs for the equality (EQ) of discrete logarithms (DL). // This means, for two values xG and xH one can check that // log_{G}(xG) == log_{H}(xH) @@ -13,6 +13,7 @@ import ( "gopkg.in/dedis/kyber.v1/util/random" ) +// Suite wraps the functionalities needed by the dleq package. type Suite interface { kyber.Group kyber.HashFactory @@ -22,8 +23,8 @@ type Suite interface { var errorDifferentLengths = errors.New("inputs of different lengths") var errorInvalidProof = errors.New("invalid proof") -// DLEQProof represents a NIZK dlog-equality proof. -type DLEQProof struct { +// Proof represents a NIZK dlog-equality proof. +type Proof struct { C kyber.Scalar // challenge R kyber.Scalar // response VG kyber.Point // public commitment with respect to base point G @@ -35,7 +36,7 @@ type DLEQProof struct { // and then computes the challenge c = H(xG,xH,vG,vH) and response r = v - cx. // Besides the proof, this function also returns the encrypted base points xG // and xH. -func NewDLEQProof(suite Suite, G kyber.Point, H kyber.Point, x kyber.Scalar) (proof *DLEQProof, xG kyber.Point, xH kyber.Point, err error) { +func NewDLEQProof(suite Suite, G kyber.Point, H kyber.Point, x kyber.Scalar) (proof *Proof, xG kyber.Point, xH kyber.Point, err error) { // Encrypt base points with secret xG = suite.Point().Mul(x, G) xH = suite.Point().Mul(x, H) @@ -56,19 +57,19 @@ func NewDLEQProof(suite Suite, G kyber.Point, H kyber.Point, x kyber.Scalar) (pr r := suite.Scalar() r.Mul(x, c).Sub(v, r) - return &DLEQProof{c, r, vG, vH}, xG, xH, nil + return &Proof{c, r, vG, vH}, xG, xH, nil } // NewDLEQProofBatch computes lists of NIZK dlog-equality proofs and of // encrypted base points xG and xH. Note that the challenge is computed over all // input values. -func NewDLEQProofBatch(suite Suite, G []kyber.Point, H []kyber.Point, secrets []kyber.Scalar) (proof []*DLEQProof, xG []kyber.Point, xH []kyber.Point, err error) { +func NewDLEQProofBatch(suite Suite, G []kyber.Point, H []kyber.Point, secrets []kyber.Scalar) (proof []*Proof, xG []kyber.Point, xH []kyber.Point, err error) { if len(G) != len(H) || len(H) != len(secrets) { return nil, nil, nil, errorDifferentLengths } n := len(secrets) - proofs := make([]*DLEQProof, n) + proofs := make([]*Proof, n) v := make([]kyber.Scalar, n) xG = make([]kyber.Point, n) xH = make([]kyber.Point, n) @@ -97,7 +98,7 @@ func NewDLEQProofBatch(suite Suite, G []kyber.Point, H []kyber.Point, secrets [] for i, x := range secrets { r := suite.Scalar() r.Mul(x, c).Sub(v[i], r) - proofs[i] = &DLEQProof{c, r, vG[i], vH[i]} + proofs[i] = &Proof{c, r, vG[i], vH[i]} } return proofs, xG, xH, nil @@ -107,7 +108,7 @@ func NewDLEQProofBatch(suite Suite, G []kyber.Point, H []kyber.Point, secrets [] // The proof is valid if the following two conditions hold: // vG == rG + c(xG) // vH == rH + c(xH) -func (p *DLEQProof) Verify(suite Suite, G kyber.Point, H kyber.Point, xG kyber.Point, xH kyber.Point) error { +func (p *Proof) Verify(suite Suite, G kyber.Point, H kyber.Point, xG kyber.Point, xH kyber.Point) error { rG := suite.Point().Mul(p.R, G) rH := suite.Point().Mul(p.R, H) cxG := suite.Point().Mul(p.C, xG) diff --git a/share/dkg/dkg.go b/share/dkg/dkg.go index 9be8b92a7..9e2205655 100644 --- a/share/dkg/dkg.go +++ b/share/dkg/dkg.go @@ -49,6 +49,7 @@ import ( "gopkg.in/dedis/kyber.v1/share/vss" ) +// Suite wraps the functionalities needed by the dkg package type Suite vss.Suite // DistKeyShare holds the share of a distributed key for a participant. @@ -626,10 +627,10 @@ func (d *DistKeyGenerator) DistKeyShare() (*DistKeyShare, error) { // Hash returns the hash value of this struct used in the signature process. func (sc *SecretCommits) Hash(s Suite) []byte { h := s.Hash() - h.Write([]byte("secretcommits")) - binary.Write(h, binary.LittleEndian, sc.Index) + _, _ = h.Write([]byte("secretcommits")) + _ = binary.Write(h, binary.LittleEndian, sc.Index) for _, p := range sc.Commitments { - p.MarshalTo(h) + _, _ = p.MarshalTo(h) } return h.Sum(nil) } @@ -637,21 +638,21 @@ func (sc *SecretCommits) Hash(s Suite) []byte { // Hash returns the hash value of this struct used in the signature process. func (cc *ComplaintCommits) Hash(s Suite) []byte { h := s.Hash() - h.Write([]byte("commitcomplaint")) - binary.Write(h, binary.LittleEndian, cc.Index) - binary.Write(h, binary.LittleEndian, cc.DealerIndex) + _, _ = h.Write([]byte("commitcomplaint")) + _ = binary.Write(h, binary.LittleEndian, cc.Index) + _ = binary.Write(h, binary.LittleEndian, cc.DealerIndex) buff, _ := cc.Deal.MarshalBinary() - h.Write(buff) + _, _ = h.Write(buff) return h.Sum(nil) } // Hash returns the hash value of this struct used in the signature process. func (rc *ReconstructCommits) Hash(s Suite) []byte { h := s.Hash() - h.Write([]byte("reconstructcommits")) - binary.Write(h, binary.LittleEndian, rc.Index) - binary.Write(h, binary.LittleEndian, rc.DealerIndex) - h.Write(rc.Share.Hash(s)) + _, _ = h.Write([]byte("reconstructcommits")) + _ = binary.Write(h, binary.LittleEndian, rc.Index) + _ = binary.Write(h, binary.LittleEndian, rc.DealerIndex) + _, _ = h.Write(rc.Share.Hash(s)) return h.Sum(nil) } diff --git a/share/dkg/dkg_test.go b/share/dkg/dkg_test.go index fabe092a4..0d1d5d958 100644 --- a/share/dkg/dkg_test.go +++ b/share/dkg/dkg_test.go @@ -489,7 +489,7 @@ func TestDKGReconstructCommits(t *testing.T) { require.Error(t, dkg2.ProcessReconstructCommits(rc)) rc.SessionID = goodSID - dkg2.ProcessReconstructCommits(rc) + _ = dkg2.ProcessReconstructCommits(rc) } assert.True(t, dkg2.reconstructed[uint32(0)]) com := dkg2.commitments[uint32(0)] @@ -596,7 +596,7 @@ func genPair() (kyber.Scalar, kyber.Point) { func randomBytes(n int) []byte { var buff = make([]byte, n) - rand.Read(buff[:]) + _, _ = rand.Read(buff[:]) return buff } func checkDks(dks1, dks2 *DistKeyShare) bool { diff --git a/share/dss/dss.go b/share/dss/dss.go index a96733ed2..c3e77d78f 100644 --- a/share/dss/dss.go +++ b/share/dss/dss.go @@ -1,4 +1,4 @@ -// DSS implements the Distributed Schnorr Signature protocol from the +// Package dss implements the Distributed Schnorr Signature protocol from the // paper "Provably Secure Distributed Schnorr Signatures and a (t, n) // Threshold Scheme for Implicit Certificates". // https://dl.acm.org/citation.cfm?id=678297 @@ -27,6 +27,7 @@ import ( "gopkg.in/dedis/kyber.v1/sign/schnorr" ) +// Suite represents the functionalities needed by the dss package type Suite interface { kyber.Group kyber.HashFactory @@ -179,7 +180,7 @@ func (d *DSS) EnoughPartialSig() bool { // alrogithm. func (d *DSS) Signature() ([]byte, error) { if !d.EnoughPartialSig() { - return nil, errors.New("dkg: not enough partial signatures to sign.") + return nil, errors.New("dkg: not enough partial signatures to sign") } gamma, err := share.RecoverSecret(d.suite, d.partials, d.T, len(d.participants)) if err != nil { @@ -188,8 +189,8 @@ func (d *DSS) Signature() ([]byte, error) { } // RandomPublic || gamma var buff bytes.Buffer - d.random.Public().MarshalTo(&buff) - gamma.MarshalTo(&buff) + _, _ = d.random.Public().MarshalTo(&buff) + _, _ = gamma.MarshalTo(&buff) return buff.Bytes(), nil } @@ -199,9 +200,9 @@ func (d *DSS) hashSig() kyber.Scalar { // * A = distributed public key // * msg = msg to sign h := sha512.New() - d.random.Public().MarshalTo(h) - d.long.Public().MarshalTo(h) - h.Write(d.msg) + _, _ = d.random.Public().MarshalTo(h) + _, _ = d.long.Public().MarshalTo(h) + _, _ = h.Write(d.msg) return d.suite.Scalar().SetBytes(h.Sum(nil)) } @@ -215,8 +216,8 @@ func Verify(public kyber.Point, msg, sig []byte) error { // signature. func (ps *PartialSig) Hash(s Suite) []byte { h := s.Hash() - h.Write(ps.Partial.Hash(s)) - h.Write(ps.SessionID) + _, _ = h.Write(ps.Partial.Hash(s)) + _, _ = h.Write(ps.SessionID) return h.Sum(nil) } @@ -232,11 +233,11 @@ func findPub(list []kyber.Point, i int) (kyber.Point, bool) { func sessionID(s Suite, a, b *dkg.DistKeyShare) []byte { h := s.Hash() for _, p := range a.Commits { - p.MarshalTo(h) + _, _ = p.MarshalTo(h) } for _, p := range b.Commits { - p.MarshalTo(h) + _, _ = p.MarshalTo(h) } return h.Sum(nil) diff --git a/share/dss/dss_test.go b/share/dss/dss_test.go index e95de4156..c57354b78 100644 --- a/share/dss/dss_test.go +++ b/share/dss/dss_test.go @@ -222,6 +222,6 @@ func genPair() (kyber.Scalar, kyber.Point) { func randomBytes(n int) []byte { var buff = make([]byte, n) - rand.Read(buff[:]) + _, _ = rand.Read(buff[:]) return buff } diff --git a/share/poly.go b/share/poly.go index 69de9ae05..7c2a69293 100644 --- a/share/poly.go +++ b/share/poly.go @@ -35,10 +35,11 @@ type PriShare struct { V kyber.Scalar // Value of the private share } +// Hash returns the hash representation of this share func (p *PriShare) Hash(s Suite) []byte { h := s.Hash() - p.V.MarshalTo(h) - binary.Write(h, binary.LittleEndian, p.I) + _, _ = p.V.MarshalTo(h) + _ = binary.Write(h, binary.LittleEndian, p.I) return h.Sum(nil) } @@ -67,7 +68,7 @@ func (p *PriPoly) Threshold() int { return len(p.coeffs) } -// GetSecret returns the shared secret p(0), i.e., the constant term of the polynomial. +// Secret returns the shared secret p(0), i.e., the constant term of the polynomial. func (p *PriPoly) Secret() kyber.Scalar { return p.coeffs[0] } @@ -274,10 +275,11 @@ type PubShare struct { V kyber.Point // Value of the public share } +// Hash returns the hash representation of this share. func (p *PubShare) Hash(s Suite) []byte { h := s.Hash() - p.V.MarshalTo(h) - binary.Write(h, binary.LittleEndian, p.I) + _, _ = p.V.MarshalTo(h) + _ = binary.Write(h, binary.LittleEndian, p.I) return h.Sum(nil) } diff --git a/share/pvss/pvss.go b/share/pvss/pvss.go index 883fc44ba..68a6275ea 100644 --- a/share/pvss/pvss.go +++ b/share/pvss/pvss.go @@ -40,7 +40,7 @@ var errorDecVerification = errors.New("verification of decrypted share failed") // PubVerShare is a public verifiable share. type PubVerShare struct { S share.PubShare // Share - P dleq.DLEQProof // Proof + P dleq.Proof // Proof } // EncShares creates a list of encrypted publicly verifiable PVSS shares for diff --git a/share/vss/dh.go b/share/vss/dh.go index 55e480973..1b5cadea6 100644 --- a/share/vss/dh.go +++ b/share/vss/dh.go @@ -42,11 +42,11 @@ func newAEAD(fn func() hash.Hash, preSharedKey kyber.Point, context []byte) (cip // context returns the context slice to be used when encrypting a share func context(suite Suite, dealer kyber.Point, verifiers []kyber.Point) []byte { h := suite.Hash() - h.Write([]byte("vss-dealer")) - dealer.MarshalTo(h) - h.Write([]byte("vss-verifiers")) + _, _ = h.Write([]byte("vss-dealer")) + _, _ = dealer.MarshalTo(h) + _, _ = h.Write([]byte("vss-verifiers")) for _, v := range verifiers { - v.MarshalTo(h) + _, _ = v.MarshalTo(h) } return h.Sum(nil) } diff --git a/share/vss/vss.go b/share/vss/vss.go index 9c08e5d0f..6fc482379 100644 --- a/share/vss/vss.go +++ b/share/vss/vss.go @@ -195,6 +195,7 @@ func NewDealer(suite Suite, longterm, secret kyber.Scalar, verifiers []kyber.Poi return d, nil } +// PlaintextDeal returns the plaintext version of the deal destined for peer i. func (d *Dealer) PlaintextDeal(i int) (*Deal, error) { if i >= len(d.deals) { return nil, errors.New("dealer: PlaintextDeal given wrong index") @@ -665,10 +666,10 @@ func validT(t int, verifiers []kyber.Point) bool { func deriveH(suite Suite, verifiers []kyber.Point) kyber.Point { var b bytes.Buffer for _, v := range verifiers { - v.MarshalTo(&b) + _, _ = v.MarshalTo(&b) } h := suite.Hash() - h.Write(b.Bytes()) + _, _ = h.Write(b.Bytes()) digest := h.Sum(nil) base := suite.Point().Pick(suite.Cipher(digest)) return base @@ -684,16 +685,16 @@ func findPub(verifiers []kyber.Point, idx uint32) (kyber.Point, bool) { func sessionID(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int) ([]byte, error) { h := suite.Hash() - dealer.MarshalTo(h) + _, _ = dealer.MarshalTo(h) for _, v := range verifiers { - v.MarshalTo(h) + _, _ = v.MarshalTo(h) } for _, c := range commitments { - c.MarshalTo(h) + _, _ = c.MarshalTo(h) } - binary.Write(h, binary.LittleEndian, uint32(t)) + _ = binary.Write(h, binary.LittleEndian, uint32(t)) return h.Sum(nil), nil } @@ -701,10 +702,10 @@ func sessionID(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.P // Hash returns the Hash representation of the Response func (r *Response) Hash(s Suite) []byte { h := s.Hash() - h.Write([]byte("response")) - h.Write(r.SessionID) - binary.Write(h, binary.LittleEndian, r.Index) - binary.Write(h, binary.LittleEndian, r.Status) + _, _ = h.Write([]byte("response")) + _, _ = h.Write(r.SessionID) + _ = binary.Write(h, binary.LittleEndian, r.Index) + _ = binary.Write(h, binary.LittleEndian, r.Status) return h.Sum(nil) } @@ -727,10 +728,10 @@ func (d *Deal) UnmarshalBinary(s Suite, buff []byte) error { // Hash returns the hash of a Justification. func (j *Justification) Hash(s Suite) []byte { h := s.Hash() - h.Write([]byte("justification")) - h.Write(j.SessionID) - binary.Write(h, binary.LittleEndian, j.Index) + _, _ = h.Write([]byte("justification")) + _, _ = h.Write(j.SessionID) + _ = binary.Write(h, binary.LittleEndian, j.Index) buff, _ := j.Deal.MarshalBinary() - h.Write(buff) + _, _ = h.Write(buff) return h.Sum(nil) } diff --git a/sign/anon/anon.go b/sign/anon/anon.go index 6821ee139..1aef593e4 100644 --- a/sign/anon/anon.go +++ b/sign/anon/anon.go @@ -5,11 +5,11 @@ import ( "gopkg.in/dedis/kyber.v1" ) -// An anon.Set represents an explicit anonymity set +// Set represents an explicit anonymity set // as a list of public keys. type Set []kyber.Point -// A private key representing a member of an anonymity set +// PriKey represents a member of an anonymity set type PriKey struct { Set // Public key-set Mine int // Index of the public key I own diff --git a/sign/anon/sig.go b/sign/anon/sig.go index d06f99536..37f9c4b6d 100644 --- a/sign/anon/sig.go +++ b/sign/anon/sig.go @@ -25,9 +25,9 @@ func signH1pre(suite Suite, linkScope []byte, linkTag kyber.Point, message []byte) kyber.Cipher { H1pre := suite.Cipher(message) // m if linkScope != nil { - H1pre.Write(linkScope) // L + _, _ = H1pre.Write(linkScope) // L tag, _ := linkTag.MarshalBinary() - H1pre.Write(tag) // ~y + _, _ = H1pre.Write(tag) // ~y } return H1pre } @@ -35,10 +35,10 @@ func signH1pre(suite Suite, linkScope []byte, linkTag kyber.Point, func signH1(suite Suite, H1pre kyber.Cipher, PG, PH kyber.Point) kyber.Scalar { H1 := H1pre.Clone() PGb, _ := PG.MarshalBinary() - H1.Write(PGb) + _, _ = H1.Write(PGb) if PH != nil { PHb, _ := PH.MarshalBinary() - H1.Write(PHb) + _, _ = H1.Write(PHb) } H1.Message(nil, nil, nil) // finish message absorption return suite.Scalar().Pick(H1) @@ -176,10 +176,10 @@ func Sign(suite Suite, random cipher.Stream, message []byte, buf := bytes.Buffer{} if linkScope != nil { // linkable ring signature sig := lSig{c[0], s, linkTag} - suite.Write(&buf, &sig) + _ = suite.Write(&buf, &sig) } else { // unlinkable ring signature sig := uSig{c[0], s} - suite.Write(&buf, &sig) + _ = suite.Write(&buf, &sig) } return buf.Bytes() } @@ -248,7 +248,6 @@ func Verify(suite Suite, message []byte, anonymitySet Set, if linkScope != nil { tag, _ := linkTag.MarshalBinary() return tag, nil - } else { - return []byte{}, nil } + return []byte{}, nil } diff --git a/sign/anon/skeme.go b/sign/anon/skeme.go index 4e808ec4e..897225326 100644 --- a/sign/anon/skeme.go +++ b/sign/anon/skeme.go @@ -10,7 +10,7 @@ import ( "gopkg.in/dedis/kyber.v1/util/random" ) -// Pairwise anonymous key agreement for point-to-point interactions. +// SKEME is a pairwise anonymous key agreement for point-to-point interactions. // We use the encryption-based SKEME authenticated key exchange protocol, // with the anonymity-set encryption, to authenticate a Diffie-Hellman secret. // The result is a private two-party communication channel, @@ -37,7 +37,7 @@ type SKEME struct { lml, rml int // local,remote message lengths } -// Initialize... +// Init the SKEME func (sk *SKEME) Init(suite Suite, rand cipher.Stream, lpri PriKey, rpub Set, hide bool) { sk.suite = suite @@ -55,11 +55,13 @@ func (sk *SKEME) Init(suite Suite, rand cipher.Stream, sk.lm = Encrypt(suite, rand, sk.lXb, rpub, hide) } -// Return the current message that should be sent (retransmitting if needed) +// ToSend returns the current message that should be sent (retransmitting if needed) func (sk *SKEME) ToSend() []byte { return sk.lm } +// Recv decrypts the message. It returns false if the SKEME expects more data, +// an error if any checks or decryption is invalid, and true otherwise. func (sk *SKEME) Recv(rm []byte) (bool, error) { M, err := Decrypt(sk.suite, rm, sk.lpri.Set, sk.lpri.Mine, sk.lpri.Pri, @@ -112,8 +114,8 @@ func (sk *SKEME) Recv(rm []byte) (bool, error) { func (sk *SKEME) mkmac(masterkey, Xb1, Xb2 []byte) (cipher.Stream, []byte) { keylen := sk.ms.KeySize() hmac := hmac.New(sk.suite.Hash, masterkey) - hmac.Write(Xb1) - hmac.Write(Xb2) + _, _ = hmac.Write(Xb1) + _, _ = hmac.Write(Xb2) key := hmac.Sum(nil)[:keylen] stream := sk.suite.Cipher(key) diff --git a/sign/anon/suite.go b/sign/anon/suite.go index c7b64ff7d..2066454dd 100644 --- a/sign/anon/suite.go +++ b/sign/anon/suite.go @@ -4,6 +4,7 @@ import ( "gopkg.in/dedis/kyber.v1" ) +// Suite represents the set of functionalities needed by the package anon. type Suite interface { kyber.Group kyber.CipherFactory diff --git a/sign/cosi/cosi_test.go b/sign/cosi/cosi_test.go index 57dfee8e4..687ef3ed1 100644 --- a/sign/cosi/cosi_test.go +++ b/sign/cosi/cosi_test.go @@ -148,8 +148,8 @@ func TestCosiSignatureWithMask(t *testing.T) { } -func genKeyPair(nb int) ([]*key.KeyPair, []kyber.Point) { - var kps []*key.KeyPair +func genKeyPair(nb int) ([]*key.Pair, []kyber.Point) { + var kps []*key.Pair var publics []kyber.Point for i := 0; i < nb; i++ { kp := key.NewKeyPair(testSuite) diff --git a/sign/eddsa/eddsa.go b/sign/eddsa/eddsa.go index 40a022baf..3065176e3 100644 --- a/sign/eddsa/eddsa.go +++ b/sign/eddsa/eddsa.go @@ -1,4 +1,4 @@ -// EdDSA implements the EdDSA signature algorithm according to +// Package eddsa implements the EdDSA signature algorithm according to // the RFC https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02 package eddsa @@ -90,8 +90,8 @@ func (e *EdDSA) UnmarshalBinary(buff []byte) error { // https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02 func (e *EdDSA) Sign(msg []byte) ([]byte, error) { hash := sha512.New() - hash.Write(e.prefix) - hash.Write(msg) + _, _ = hash.Write(e.prefix) + _, _ = hash.Write(msg) // deterministic random secret and its commit r := group.Scalar().SetBytes(hash.Sum(nil)) @@ -109,9 +109,9 @@ func (e *EdDSA) Sign(msg []byte) ([]byte, error) { return nil, err } - hash.Write(Rbuff) - hash.Write(Abuff) - hash.Write(msg) + _, _ = hash.Write(Rbuff) + _, _ = hash.Write(Abuff) + _, _ = hash.Write(msg) h := group.Scalar().SetBytes(hash.Sum(nil)) @@ -150,7 +150,9 @@ func Verify(public kyber.Point, msg, sig []byte) error { } s := group.Scalar() - s.UnmarshalBinary(sig[32:]) + if err := s.UnmarshalBinary(sig[32:]); err != nil { + return fmt.Errorf("schnorr: s invalid scalar %s", err) + } // reconstruct h = H(R || Public || Msg) Pbuff, err := public.MarshalBinary() @@ -158,9 +160,9 @@ func Verify(public kyber.Point, msg, sig []byte) error { return err } hash := sha512.New() - hash.Write(sig[:32]) - hash.Write(Pbuff) - hash.Write(msg) + _, _ = hash.Write(sig[:32]) + _, _ = hash.Write(Pbuff) + _, _ = hash.Write(msg) h := group.Scalar().SetBytes(hash.Sum(nil)) // reconstruct S == k*A + R diff --git a/sign/schnorr/schnorr.go b/sign/schnorr/schnorr.go index 64e946eaa..118c91086 100644 --- a/sign/schnorr/schnorr.go +++ b/sign/schnorr/schnorr.go @@ -1,5 +1,5 @@ /* -The schnorr packages implements the vanilla Schnorr signature scheme. +Package schnorr implements the vanilla Schnorr signature scheme. See https://en.wikipedia.org/wiki/Schnorr_signature. The only difference regarding the vanilla reference is the computation of diff --git a/util/bytes/doc.go b/util/bytes/doc.go index 298406df1..08cc234cb 100644 --- a/util/bytes/doc.go +++ b/util/bytes/doc.go @@ -1,4 +1,4 @@ -// Packages bytes provide some utilities to manipulate bytes buffer. It also +// Package bytes provide some utilities to manipulate bytes buffer. It also // contain for the moment a Replacer utility used to replace file's content safely. // package bytes diff --git a/util/bytes/replace.go b/util/bytes/replace.go index 4a40de592..7866c9f46 100644 --- a/util/bytes/replace.go +++ b/util/bytes/replace.go @@ -7,13 +7,15 @@ import ( "path/filepath" ) +// Replacer provides functionalities to replace a file in a safe concurrent way. +// Operations are not carried out until Close is called. type Replacer struct { Name string // Name of the file being replaced Info os.FileInfo // Timestamp of target file before replacement File *os.File // Temporary file used for writing } -var raceErr = errors.New("File was concurrently modified") +var errRace = errors.New("File was concurrently modified") // Open a file to replace an existing file as safely as possible, // attempting to avoid corruption on crash or concurrent writers. @@ -58,7 +60,7 @@ func (r *Replacer) Open(filename string) error { return nil } -// Attempt to commit the temporary replacement file to the target. +// Commit attempts to commit the temporary replacement file to the target. // On success, Close()s the temporary file and atomically renames it // to the target filename saved in the Name field. // @@ -82,7 +84,7 @@ func (r *Replacer) Commit() error { if info.Name() != r.Info.Name() || info.Size() != r.Info.Size() || info.ModTime() != r.Info.ModTime() { - return raceErr + return errRace } } @@ -101,7 +103,7 @@ func (r *Replacer) Commit() error { return nil } -// Commit the temporary replacement file +// ForceCommit the temporary replacement file // without checking for concurrent modifications in the meantime. func (r *Replacer) ForceCommit() error { r.Info = nil @@ -115,15 +117,15 @@ func (r *Replacer) ForceCommit() error { func (r *Replacer) Abort() { if r.File != nil { tmpname := r.File.Name() - r.File.Close() + _ = r.File.Close() r.File = nil - os.Remove(tmpname) + _ = os.Remove(tmpname) } } -// Returns true if an error returned by Commit() indicates +// IsRace returns true if an error returned by Commit() indicates // that the commit failed because a concurrent write was detected // and the force flag was not specified. func IsRace(err error) bool { - return err == raceErr + return err == errRace } diff --git a/util/key/key.go b/util/key/key.go index b356923b8..977aecb71 100644 --- a/util/key/key.go +++ b/util/key/key.go @@ -4,44 +4,46 @@ package key import ( "crypto/cipher" "encoding/base64" - "hash" "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/util/random" ) +// Suite represents the list of functionalities needed by this package. +// XXX HashFactory might be removed in the future, it's only needed to generate +// the PubId. type Suite interface { kyber.Group - Hash() hash.Hash + kyber.HashFactory } -// KeyPair represents a public/private keypair +// Pair represents a public/private keypair // together with the ciphersuite the key was generated from. -type KeyPair struct { +type Pair struct { Suite Suite // Ciphersuite this keypair is for Public kyber.Point // Public key Secret kyber.Scalar // Secret key } // NewKeyPair directly creates a secret/public key pair -func NewKeyPair(suite Suite) *KeyPair { - kp := new(KeyPair) +func NewKeyPair(suite Suite) *Pair { + kp := new(Pair) kp.Gen(suite, random.Stream) return kp } -// Generate a fresh public/private keypair with the given ciphersuite, +// Gen creates a fresh public/private keypair with the given ciphersuite, // using a given source of cryptographic randomness. -func (p *KeyPair) Gen(suite Suite, random cipher.Stream) { +func (p *Pair) Gen(suite Suite, random cipher.Stream) { p.Suite = suite p.Secret = suite.NewKey(random) p.Public = suite.Point().Mul(p.Secret, nil) } -// PubId returns the base64-encoded HashId for this KeyPair's public key. -func (p *KeyPair) PubId() string { +// PubID returns the base64-encoded HashId for this Pair's public key. +func (p *Pair) PubID() string { buf, _ := p.Public.MarshalBinary() hash := p.Suite.Hash() - hash.Write(buf) + _, _ = hash.Write(buf) return base64.RawURLEncoding.EncodeToString(hash.Sum(nil)) } diff --git a/util/marshalling/marshal.go b/util/marshalling/marshal.go index 15248006b..6139e2149 100644 --- a/util/marshalling/marshal.go +++ b/util/marshalling/marshal.go @@ -9,7 +9,7 @@ import ( "gopkg.in/dedis/kyber.v1" ) -// PointEncodeTo provides a generic implementation of Point.EncodeTo +// PointMarshalTo provides a generic implementation of Point.EncodeTo // based on Point.Encode. func PointMarshalTo(p kyber.Point, w io.Writer) (int, error) { buf, err := p.MarshalBinary() @@ -19,7 +19,7 @@ func PointMarshalTo(p kyber.Point, w io.Writer) (int, error) { return w.Write(buf) } -// PointDecodeFrom provides a generic implementation of Point.DecodeFrom, +// PointUnmarshalFrom provides a generic implementation of Point.DecodeFrom, // based on Point.Decode, or Point.Pick if r is a Cipher or cipher.Stream. // The returned byte-count is valid only when decoding from a normal Reader, // not when picking from a pseudorandom source. @@ -36,7 +36,7 @@ func PointUnmarshalFrom(p kyber.Point, r io.Reader) (int, error) { return n, p.UnmarshalBinary(buf) } -// ScalarEncodeTo provides a generic implementation of Scalar.EncodeTo +// ScalarMarshalTo provides a generic implementation of Scalar.EncodeTo // based on Scalar.Encode. func ScalarMarshalTo(s kyber.Scalar, w io.Writer) (int, error) { buf, err := s.MarshalBinary() @@ -46,7 +46,7 @@ func ScalarMarshalTo(s kyber.Scalar, w io.Writer) (int, error) { return w.Write(buf) } -// ScalarDecodeFrom provides a generic implementation of Scalar.DecodeFrom, +// ScalarUnmarshalFrom provides a generic implementation of Scalar.DecodeFrom, // based on Scalar.Decode, or Scalar.Pick if r is a Cipher or cipher.Stream. // The returned byte-count is valid only when decoding from a normal Reader, // not when picking from a pseudorandom source. diff --git a/util/random/rand.go b/util/random/rand.go index 7692bb329..98bb8b793 100644 --- a/util/random/rand.go +++ b/util/random/rand.go @@ -1,4 +1,4 @@ -// Package rand provides facilities for generating +// Package random provides facilities for generating // random or pseudorandom cryptographic objects. // // XXX this package might go away and get subsumed by the @@ -12,7 +12,7 @@ import ( "math/big" ) -// Choose a uniform random BigInt with a given maximum BitLen. +// Bits chooses a uniform random BigInt with a given maximum BitLen. // If 'exact' is true, choose a BigInt with _exactly_ that BitLen, not less func Bits(bitlen uint, exact bool, rand cipher.Stream) []byte { b := make([]byte, (bitlen+7)/8) @@ -31,43 +31,43 @@ func Bits(bitlen uint, exact bool, rand cipher.Stream) []byte { return b } -// Choose a uniform random boolean +// Bool chooses a uniform random boolean func Bool(rand cipher.Stream) bool { b := Bits(8, false, rand) return b[0]&1 != 0 } -// Choose a uniform random byte +// Byte chooses a uniform random byte func Byte(rand cipher.Stream) byte { b := Bits(8, false, rand) return b[0] } -// Choose a uniform random uint8 +// Uint8 chooses a uniform random uint8 func Uint8(rand cipher.Stream) uint8 { b := Bits(8, false, rand) return uint8(b[0]) } -// Choose a uniform random uint16 +// Uint16 chooses a uniform random uint16 func Uint16(rand cipher.Stream) uint16 { b := Bits(16, false, rand) return binary.BigEndian.Uint16(b) } -// Choose a uniform random uint32 +// Uint32 chooses a uniform random uint32 func Uint32(rand cipher.Stream) uint32 { b := Bits(32, false, rand) return binary.BigEndian.Uint32(b) } -// Choose a uniform random uint64 +// Uint64 chooses a uniform random uint64 func Uint64(rand cipher.Stream) uint64 { b := Bits(64, false, rand) return binary.BigEndian.Uint64(b) } -// Choose a uniform random big.Int less than a given modulus +// Int choose a uniform random big.Int less than a given modulus func Int(mod *big.Int, rand cipher.Stream) *big.Int { bitlen := uint(mod.BitLen()) i := new(big.Int) @@ -79,7 +79,7 @@ func Int(mod *big.Int, rand cipher.Stream) *big.Int { } } -// Choose a random n-byte slice +// Bytes chooses a random n-byte slice func Bytes(n int, rand cipher.Stream) []byte { b := make([]byte, n) rand.XORKeyStream(b, b) @@ -126,6 +126,6 @@ func (r *randstream) XORKeyStream(dst, src []byte) { } } -// Standard virtual "stream cipher" that just generates +// Stream is the standard virtual "stream cipher" that just generates // fresh cryptographically strong random bits. var Stream cipher.Stream = new(randstream) diff --git a/util/test/cipher.go b/util/test/cipher.go index f9bf0c5b1..1f8e62d9c 100644 --- a/util/test/cipher.go +++ b/util/test/cipher.go @@ -11,19 +11,20 @@ import ( "gopkg.in/dedis/kyber.v1/util/subtle" ) +// HashBench performs a benchmark on a hash function func HashBench(b *testing.B, hash func() hash.Hash) { b.SetBytes(1024 * 1024) data := make([]byte, 1024) for i := 0; i < b.N; i++ { h := hash() for j := 0; j < 1024; j++ { - h.Write(data) + _, _ = h.Write(data) } h.Sum(nil) } } -// Benchmark a stream cipher. +// StreamCipherBench performs a benchmark on a stream cipher. func StreamCipherBench(b *testing.B, keylen int, cipher func([]byte) cipher.Stream) { key := make([]byte, keylen) @@ -37,7 +38,7 @@ func StreamCipherBench(b *testing.B, keylen int, } } -// Benchmark a block cipher operating in counter mode. +// BlockCipherBench performs a benchmark on a block cipher operating in counter mode. func BlockCipherBench(b *testing.B, keylen int, bcipher func([]byte) cipher.Block) { StreamCipherBench(b, keylen, func(key []byte) cipher.Stream { @@ -47,7 +48,7 @@ func BlockCipherBench(b *testing.B, keylen int, }) } -// Compares the bits between two arrays returning the fraction +// BitDiff compares the bits between two arrays returning the fraction // of differences. If the two arrays are not of the same length // no comparison is made and a -1 is returned. func BitDiff(a, b []byte) float64 { @@ -65,7 +66,7 @@ func BitDiff(a, b []byte) float64 { return float64(count) / float64(len(a)*8) } -// Tests a Cipher can encrypt and decrypt +// CipherHelloWorldHelper test if a Cipher can encrypt and decrypt. func CipherHelloWorldHelper(t *testing.T, newCipher func([]byte, ...interface{}) kyber.Cipher, n int, bitdiff float64) { @@ -80,7 +81,7 @@ func CipherHelloWorldHelper(t *testing.T, for i := range nkeys { nkeys[i] = make([]byte, keysize) - rand.Read(nkeys[i]) + _, _ = rand.Read(nkeys[i]) bc = newCipher(nkeys[i]) ncrypts[i] = make([]byte, cryptsize) bc.Message(ncrypts[i], text, ncrypts[i]) @@ -110,12 +111,12 @@ func CipherHelloWorldHelper(t *testing.T, } } -// Tests a Cipher: -// 1) Encryption / decryption work +// AuthenticateAndEncrypt tests a Cipher if: +// 1) Encryption / decryption works // 2) Encryption / decryption with different key don't work // 3) Changing a bit in the ciphertext or mac results in failed mac check // 4) Different keys produce sufficiently random output -func TestAuthenticateAndEncrypt(t *testing.T, +func AuthenticateAndEncrypt(t *testing.T, newCipher func([]byte, ...interface{}) kyber.Cipher, n int, bitdiff float64, text []byte) { cryptsize := len(text) @@ -133,7 +134,7 @@ func TestAuthenticateAndEncrypt(t *testing.T, // Encrypt / decrypt / mac test for i := range nkeys { nkeys[i] = make([]byte, keysize) - rand.Read(nkeys[i]) + _, _ = rand.Read(nkeys[i]) bc = newCipher(nkeys[i]) ncrypts[i] = make([]byte, cryptsize) bc.Message(ncrypts[i], text, ncrypts[i]) @@ -222,28 +223,29 @@ func TestAuthenticateAndEncrypt(t *testing.T, } } -// Iterate through various sized messages and verify +// CipherAuthenticatedEncryptionHelper iterates through various sized messages and verify // that encryption and authentication work func CipherAuthenticatedEncryptionHelper(t *testing.T, newCipher func([]byte, ...interface{}) kyber.Cipher, n int, bitdiff float64) { // AuthenticateAndEncrypt(t, newCipher, n, bitdiff, []byte{}) - TestAuthenticateAndEncrypt(t, newCipher, n, bitdiff, []byte{'a'}) - TestAuthenticateAndEncrypt(t, newCipher, n, bitdiff, []byte("Hello, World")) + AuthenticateAndEncrypt(t, newCipher, n, bitdiff, []byte{'a'}) + AuthenticateAndEncrypt(t, newCipher, n, bitdiff, []byte("Hello, World")) kb := make([]byte, 2^10) for i := 0; i < len(kb); i++ { kb[i] = byte(i & 256) } - TestAuthenticateAndEncrypt(t, newCipher, n, bitdiff, kb) + AuthenticateAndEncrypt(t, newCipher, n, bitdiff, kb) mb := make([]byte, 2^20) for i := 0; i < len(mb); i++ { mb[i] = byte(i & 256) } - TestAuthenticateAndEncrypt(t, newCipher, n, bitdiff, mb) + AuthenticateAndEncrypt(t, newCipher, n, bitdiff, mb) } +// CipherTest test a Cipher functionalities. func CipherTest(t *testing.T, newCipher func([]byte, ...interface{}) kyber.Cipher) { n := 5 diff --git a/util/test/group.go b/util/test/group.go index 3b617f4f4..4c0045e85 100644 --- a/util/test/group.go +++ b/util/test/group.go @@ -5,7 +5,7 @@ import ( "gopkg.in/dedis/kyber.v1/util/random" ) -// A generic benchmark suite for kyber.groups. +// GroupBench is a generic benchmark suite for kyber.groups. type GroupBench struct { g kyber.Group @@ -16,6 +16,7 @@ type GroupBench struct { Xe []byte // encoded Point } +// NewGroupBench returns a new GroupBench. func NewGroupBench(g kyber.Group) *GroupBench { var gb GroupBench gb.g = g @@ -28,104 +29,121 @@ func NewGroupBench(g kyber.Group) *GroupBench { return &gb } +// ScalarAdd benchmarks the addition operation for scalars func (gb GroupBench) ScalarAdd(iters int) { for i := 1; i < iters; i++ { gb.x.Add(gb.x, gb.y) } } +// ScalarSub benchmarks the substraction operation for scalars func (gb GroupBench) ScalarSub(iters int) { for i := 1; i < iters; i++ { gb.x.Sub(gb.x, gb.y) } } +// ScalarNeg benchmarks the negation operation for scalars func (gb GroupBench) ScalarNeg(iters int) { for i := 1; i < iters; i++ { gb.x.Neg(gb.x) } } +// ScalarMul benchmarks the multiplication operation for scalars func (gb GroupBench) ScalarMul(iters int) { for i := 1; i < iters; i++ { gb.x.Mul(gb.x, gb.y) } } +// ScalarDiv benchmarks the division operation for scalars func (gb GroupBench) ScalarDiv(iters int) { for i := 1; i < iters; i++ { gb.x.Div(gb.x, gb.y) } } +// ScalarInv benchmarks the inverse operation for scalars func (gb GroupBench) ScalarInv(iters int) { for i := 1; i < iters; i++ { gb.x.Inv(gb.x) } } +// ScalarPick benchmarks the Pick operation for scalars func (gb GroupBench) ScalarPick(iters int) { for i := 1; i < iters; i++ { gb.x.Pick(random.Stream) } } +// ScalarEncode benchmarks the marshalling operation for scalars func (gb GroupBench) ScalarEncode(iters int) { for i := 1; i < iters; i++ { - gb.x.MarshalBinary() + _, _ = gb.x.MarshalBinary() } } +// ScalarDecode benchmarks the unmarshalling operation for scalars func (gb GroupBench) ScalarDecode(iters int) { for i := 1; i < iters; i++ { - gb.x.UnmarshalBinary(gb.xe) + _ = gb.x.UnmarshalBinary(gb.xe) } } +// PointAdd benchmarks the addition operation for points func (gb GroupBench) PointAdd(iters int) { for i := 1; i < iters; i++ { gb.X.Add(gb.X, gb.Y) } } +// PointSub benchmarks the substraction operation for points func (gb GroupBench) PointSub(iters int) { for i := 1; i < iters; i++ { gb.X.Sub(gb.X, gb.Y) } } +// PointNeg benchmarks the negation operation for points func (gb GroupBench) PointNeg(iters int) { for i := 1; i < iters; i++ { gb.X.Neg(gb.X) } } +// PointMul benchmarks the multiplication operation for points func (gb GroupBench) PointMul(iters int) { for i := 1; i < iters; i++ { gb.X.Mul(gb.y, gb.X) } } +// PointBaseMul benchmarks the base multiplication operation for points func (gb GroupBench) PointBaseMul(iters int) { for i := 1; i < iters; i++ { gb.X.Mul(gb.y, nil) } } +// PointPick benchmarks the pick-ing operation for points func (gb GroupBench) PointPick(iters int) { for i := 1; i < iters; i++ { gb.X.Pick(random.Stream) } } +// PointEncode benchmarks the encoding operation for points func (gb GroupBench) PointEncode(iters int) { for i := 1; i < iters; i++ { - gb.X.MarshalBinary() + _, _ = gb.X.MarshalBinary() } } +// PointDecode benchmarks the decoding operation for points func (gb GroupBench) PointDecode(iters int) { for i := 1; i < iters; i++ { - gb.X.UnmarshalBinary(gb.Xe) + _ = gb.X.UnmarshalBinary(gb.Xe) } } diff --git a/util/test/test.go b/util/test/test.go index 93bb9e241..d796f6ae3 100644 --- a/util/test/test.go +++ b/util/test/test.go @@ -3,16 +3,16 @@ package test import ( "bytes" "crypto/cipher" - "hash" "gopkg.in/dedis/kyber.v1" "gopkg.in/dedis/kyber.v1/util/random" ) +// Suite represents the functionalities that this package can test type Suite interface { kyber.Group - Hash() hash.Hash - Cipher(key []byte, options ...interface{}) kyber.Cipher + kyber.HashFactory + kyber.CipherFactory } func testEmbed(g kyber.Group, rand cipher.Stream, points *[]kyber.Point, @@ -312,14 +312,14 @@ func testGroup(g kyber.Group, rand cipher.Stream) []kyber.Point { return points } -// Apply a generic set of validation tests to a cryptographic Group. -func TestGroup(g kyber.Group) { +// GroupTest applies a generic set of validation tests to a cryptographic Group. +func GroupTest(g kyber.Group) { testGroup(g, random.Stream) } -// Test two group implementations that are supposed to be equivalent, +// CompareGroups tests two group implementations that are supposed to be equivalent, // and compare their results. -func TestCompareGroups(fn func(key []byte, options ...interface{}) kyber.Cipher, g1, g2 kyber.Group) { +func CompareGroups(fn func(key []byte, options ...interface{}) kyber.Cipher, g1, g2 kyber.Group) { // Produce test results from the same pseudorandom seed r1 := testGroup(g1, fn(kyber.NoKey)) @@ -338,14 +338,14 @@ func TestCompareGroups(fn func(key []byte, options ...interface{}) kyber.Cipher, } } -// Apply a standard set of validation tests to a ciphersuite. -func TestSuite(suite Suite) { +// SuiteTest tests a standard set of validation tests to a ciphersuite. +func SuiteTest(suite Suite) { // Try hashing something h := suite.Hash() l := h.Size() //println("HashLen: ",l) - h.Write([]byte("abc")) + _, _ = h.Write([]byte("abc")) hb := h.Sum(nil) //println("Hash:") //println(hex.Dump(hb)) @@ -385,5 +385,5 @@ func TestSuite(suite Suite) { } // Test the public-key group arithmetic - TestGroup(suite) + GroupTest(suite) }