From e82f8ce1574a1b1fb97baaac67c23a8ca55e2b1f Mon Sep 17 00:00:00 2001
From: Nik <njunger@uwaterloo.ca>
Date: Tue, 3 Feb 2015 15:20:04 -0500
Subject: [PATCH] Added Then* methods, updated documentation

---
 doc.go                  |  5 ++--
 element.go              |  8 ++++++
 element_arith_simple.go | 64 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 2 deletions(-)
 create mode 100644 element_arith_simple.go

diff --git a/doc.go b/doc.go
index f6b7427..07ea9d9 100644
--- a/doc.go
+++ b/doc.go
@@ -17,8 +17,9 @@
 	maximize performance.
 
 	Since this library provides low-level access to pairing primitives, it is
-	very easy to construct insecure systems. This library is intended to be used
-	by cryptographers or to implement well-analyzed cryptosystems.
+	very easy to accidentally construct insecure systems. This library is
+	intended to be used by cryptographers or to implement well-analyzed
+	cryptosystems.
 
 	Pairings
 
diff --git a/element.go b/element.go
index 5408cd9..0b9005a 100644
--- a/element.go
+++ b/element.go
@@ -25,6 +25,14 @@ import "runtime"
 //
 // This assigns x = ((a+b)*c)^2.
 //
+// This technique is useful because it allows the target of operations to be
+// different than the operands. However, several convenience functions have
+// been provided to improve the readability of chained calls. These functions
+// are of the form Then*, and implicitly specify the target as the first
+// operand. The above example can be rewritten as:
+//
+// 	x.Add(a, b).ThenMul(c).ThenSquare()
+//
 // Whenever possible, the methods defined on Element use the same names as
 // those in the math/big package.
 //
diff --git a/element_arith_simple.go b/element_arith_simple.go
new file mode 100644
index 0000000..dae9ff8
--- /dev/null
+++ b/element_arith_simple.go
@@ -0,0 +1,64 @@
+package pbc
+
+import "math/big"
+
+// ThenAdd is an alias for el.Add(el, y).
+//
+// Requirements:
+// el and y must be from the same algebraic structure.
+func (el *Element) ThenAdd(y *Element) *Element { return el.Add(el, y) }
+
+// ThenSub is an alias for el.Sub(el, y).
+//
+// Requirements:
+// el and y must be from the same algebraic structure.
+func (el *Element) ThenSub(y *Element) *Element { return el.Sub(el, y) }
+
+// ThenMul is an alias for el.Mul(el, y).
+//
+// Requirements:
+// el and y must be from the same algebraic structure.
+func (el *Element) ThenMul(y *Element) *Element { return el.Mul(el, y) }
+
+// ThenMulBig is an alias for el.MulBig(el, i).
+func (el *Element) ThenMulBig(i *big.Int) *Element { return el.MulBig(el, i) }
+
+// ThenMulInt32 is an alias for el.MulInt32(el, i).
+func (el *Element) ThenMulInt32(i int32) *Element { return el.MulInt32(el, i) }
+
+// ThenMulZn is an alias for el.MulZn(el, i).
+//
+// Requirements:
+// i must be an element of an integer mod ring (e.g., Zn for some n).
+func (el *Element) ThenMulZn(i *Element) *Element { return el.MulZn(el, i) }
+
+// ThenDiv is an alias for el.Div(el, y).
+//
+// Requirements:
+// el and y must be from the same algebraic structure.
+func (el *Element) ThenDiv(y *Element) *Element { return el.Div(el, y) }
+
+// ThenDouble is an alias for el.Double(el).
+func (el *Element) ThenDouble() *Element { return el.Double(el) }
+
+// ThenHalve is an alias for el.Halve(el).
+func (el *Element) ThenHalve() *Element { return el.Halve(el) }
+
+// ThenSquare is an alias for el.Square(el).
+func (el *Element) ThenSquare() *Element { return el.Square(el) }
+
+// ThenNeg is an alias for el.Neg(el).
+func (el *Element) ThenNeg() *Element { return el.Neg(el) }
+
+// ThenInvert is an alias for el.Invert(el).
+func (el *Element) ThenInvert() *Element { return el.Invert(el) }
+
+// ThenPowBig is an alias for el.PowBig(el, i).
+func (el *Element) ThenPowBig(i *big.Int) *Element { return el.PowBig(el, i) }
+
+// ThenPowZn is an alias for el.PowZn(el, i).
+//
+// Requirements:
+// i must be an element of an integer mod ring (e.g., Zn for some n, typically
+// the order of the algebraic structure that el lies in).
+func (el *Element) ThenPowZn(i *Element) *Element { return el.PowZn(el, i) }
-- 
GitLab