diff options
authorVasudev Kamath <>2018-08-28 20:42:33 +0530
committerVasudev Kamath <>2018-08-28 20:49:37 +0530
commit939257c9d68e669cc03737de7be55e2ef50b619e (patch)
parentf8013f56eaba9eb0ea269fc74191a4d8075679ff (diff)
Draft post on group implementation
1 files changed, 122 insertions, 0 deletions
diff --git a/content/development/golang_spake2_groups.rst b/content/development/golang_spake2_groups.rst
new file mode 100644
index 0000000..b1a496a
--- /dev/null
+++ b/content/development/golang_spake2_groups.rst
@@ -0,0 +1,122 @@
+SPAKE2 in Golang: Implementing Groups in Golang
+:date: 2018-08-28 14:12 +0530
+:slug: golang_spake2_5
+:tags: go, golang, spake2, cryptography
+:author: copyninja
+:status: draft
+:summary: Fifth post in "SPAKE2 in Golang" series. This post is my
+ implementation notes for groups in Golang
+In my `previous post <>`_ I
+talked about SPAKE2 protocol and Ed25519 Curve group. This post is mostly
+implementation notes and decisions taken during implementing EC groups and
+number groups in Golang.
+In the Beginning ...
+Like always I had too many question on how to do? what to do? etc. etc. Well
+there is no definitive answer, you have to experiment to get the answer. So as a
+first step I had to decide what I need. Looking at Python implementation of
+SPAKE2 I noticed some basic group operations common for all groups. Some of them
+are group operations listed below.
+* Element Addition for the group
+* Scalar Multiplication for the group
+* Scalar Multiplication with Base point/Generator of group
+Along with this I noticed some other functions which are needed, these are not
+exactly group related operations, but are needed in SPAKE2 calculation.
+* Convert password into Scalar of the group (Scalar is nothing but big integer
+ in the group)
+* Generate a Random scalar for the group.
+* Constants M, N and S.
+* Converting group element to bytes and creating element from bytes.
+* Element Size for the group.
+Now you might be wondering what `S` might be, as I only talked about `M` and `N`
+while explaining SPAKE2. Brian has created a special mode called **Symmetric
+Mode**. This is a special mode created by Brian Warner with help from other
+cryptographic folks for **magic-wormhole** use case. This mode removes the
+side/identity from the SPAKE2 protocol above (A, B) and makes both side
+identical. This will reduce additional exchanges that had to be done to setup
+side/identities for both peers.
+Next question was whether SPAKE2 implementation is going to be Ed25519 group
+specific or whether I plan to introduce other groups as well?. This was
+important decision I had to make, since Python version also has some integer
+groups I decided to make groups configurable in Golang as well.
+Defininig Group Interface
+To make group as configurable in SPAKE2 package I had to define a generic type.
+Though Golang does not have generics, we can define *interface type* to get some
+flexibility. As a first try I defined **Group** interface as follows
+.. code:: go
+ type Group interface {
+ ConstM() Group
+ ConstN() Group
+ ConstS() Group
+ RandomScalar() (*big.Int, error)
+ PasswordToScalar(pw []byte) *big.Int
+ ElementToBytes(ele Group) []byte
+ ElementFromBytes(b []byte) Group
+ BasePointMult(s *big.Int) Group
+ Add(other Group) Group
+ ScalarMult(s *big.Int) Group
+ ElementSize() int
+ }
+Remember this was not final version which I reached but initial version. I kept
+this under `group.go` file. I also thought it would be better to keep group
+package outside SPAKE2. So I created SPAKE2 as
+`` and Ed25519 group operations under
+I hit my first road block with this representation. I created a type `Ed25519`
+in `ed25519group` package and implemented all above function but definitions
+were returning/accepting type `Ed25519` wherever `Group` was needed. My
+expectation was this should work because `Ed25519` confirms to `Group` interface
+but Go compiler thought otherwise!. Go compiler refused to agree `Ed25519` type
+implemented `Group` interface and told the defintion of functions do not match.
+It said for ConstM, **expected return value of Group but found Ed25519**. I did
+not get why this does not work but from my understanding of compilers, I think
+when Go compiler scans ConstM line it still does not know that type `Ed25519`
+implements `Group` interface. I could have asked in forums but frankly I did not
+know how to phrase this question :). If you are a gopher and know the answer
+please do let me know :).
+So once I hit the road block I modified definition to look like
+.. code:: go
+ type Group interface {
+ ConstM() interface{}
+ ConstN() interface{}
+ ConstS() interface{}
+ RandomScalar() (*big.Int, error)
+ PasswordToScalar(pw []byte) *big.Int
+ ElementToBytes(ele interface{}) []byte
+ ElementFromBytes(b []byte) interface{}
+ BasePointMult(s *big.Int) interface{}
+ Add(other interface{}) interface{}
+ ScalarMult(s *big.Int) interface{}
+ ElementSize() int
+ }
+So now compiler is happy because `interface{}` means any type.